Runtime-modifiable lifecycle events

Initial discussion at https://github.com/forgojs/forgo/issues/54
Initial proposal by @spiffytech
function MyComponent() {
  return (component: ComponentBuilder) => {
    component.mount(() => {
      const interval = setInterval(doStuff, 1_000);
      component.unmount(() => clearInterval(interval));
      const socket = makeWebsocket();
      component.unmount(() => socket.close());
    });
    component.render(() =>
Hello world
);
  };
}

This style feels good to me. What do we get from nesting the arrow function within MyComponent?
This style starts to feel a bit like SolidJS, which might be a good direction to go. Their approach seems like a logical evolution of what major frameworks have turned into.
I like this style more than trying to add events on top of the existing monolith object API.
We might need to make some multicast and some not and eat that as a documentation issue. transformAttrs would be the same as render - no point in having two of them, you'd really want (manually?) composed functions instead.

Alternative:
function MyComponent() {
  const component = new Component();
  component.mount((props, args) => {
    const interval = setInterval(doStuff, 1_000);
    component.unmount(() => clearInterval(interval));
    const socket = makeWebsocket();
    component.unmount(() => socket.close());
  });
  component.render((props, args) =>
Hello world
);
  return component;
}

Or should we make it even more explicit, and directly expose the delegate arrays (such as component.mount, component.unmount etc)?
Example below. This makes it obvious that these are arrays. They also have full access to the multicast delegates, and can modify the list at runtime.
function MyComponent() {
  const component = new Component();
  component.mount.push((props, args) => {
    const interval = setInterval(doStuff, 1_000);
    component.unmount.push(() => clearInterval(interval));
    const socket = makeWebsocket();
    component.unmount.push(() => socket.close());
  });
  component.render.push((props, args) =>
Hello world
);
  return component;
}

Or we keep the current system, but expose the component (and event handlers) via args.
Here's an example which uses your original snippet with minor modifications.
const MyComponent = () => {
  let socket;
  return {
    mount(_props, args) {
      const interval = setInterval(doStuff, 1_000);
      args.component.unmount.push(() => clearInterval(interval));

      socket = makeWebsocket();
      args.component.unmount.push(() => socket.close());
    },
    render() {...}
  }
}

However, what I like in what I proposed earlier is that returning a component from the MyComponent() component constructor function feels intuitive. In the latest examples, we construct the component with the object based structure that we currently have, and then allow runtime modifications. In the component (builder) approach, everything is runtime.

Or simple allow our static object definitions to be a simple event handler, or to be an array.
function MyComponent() {
  return {
    mount: (props, args) => {
      const interval = setInterval(() => console.log("hello"), 100)
      args.component.unmount.push(() => clearInterval(interval));
    },
    unmount: [],
    render: (props, args) => {
      return
Hello world

    }
  }
}

If unmount doesn't need to be an array:
function MyComponent() {
  return {
    mount: (props, args) => {
      const interval = setInterval(() => console.log("hello"), 100)
      args.component.unmount = () => clearInterval(interval);
    },
    render: (props, args) => {
      return
Hello world

    }
  }
}

Alright, my view has changed. We may not need to do anything except add a "component" property to args. Then the component (and its lifecycle properties) can be modifed at will.
Here's example code from the runtimeLifecycleEvents.tsx test:
function ChildComponent() {
  return {
    mount(props: any, args: ForgoRenderArgs<{}>) {
      args.component.unmount = () => {
        state.hasUnmounted = true;
      };
    },
    render() {
      return
Hello world
;
    },
  };
}

Now what about multiple lifecycle hooks, as you had given in your example? We can do that outside core. The function we'd  attach to say 'unmount' could handle multicast handlers.
For example:
multicastEvents(component.unmount, () => { console.log("added"); });
multicastEvents(component.unmount, () => { console.log("added another"); });

Related PR. #60

The key piece in the PR is this line added:
export type ForgoRenderArgs<TProps> = {
  element: ForgoElementArg;
  update: (props?: any) => RenderResult;
  component: ForgoComponent<TProps> // ADDED NOW
};

Re: PR:
I thought about proposing something like this, but I discarded the idea for a few reasons:

The goal is to create an API that composes easily, but this approach is by default uncomposable, and punts composability to external libs.
It creates a footgun: the stock API is last-assign-wins, and if the programmer doesn't diligently Do The Right Thing they'll get hard-to-spot bugs where they erased previous listeners.
Retaining both the existing monolith lifecycle methods, plus the assignable functions, seems confusing. Which should you use, and when? If you have an unmount() method and also assign args.component.unmount, does one of those just never get called? Do you now have to be aware that because some 3rd-party library assigns to args.component.unmount, you can't use the unmount() method? Do you and third party libs have to agree on what composition technique you're using?
Am I reading correctly that args.component is the object returned by the ctor? Could this whole PR be obviated by just having components reference this while using non-arrow functions?

The only advantage I see to this approach is that we can implement it quickly. But it seems suboptimal at achieving the goal.

The approach you posted in this comment is more what I was thinking of at the end of #54:
function MyComponent() {
  const component = new Component();
  component.mount((props, args) => {
    const interval = setInterval(doStuff, 1_000);
    component.unmount(() => clearInterval(interval));
    const socket = makeWebsocket();
    component.unmount(() => socket.close());
  });
  component.render((props, args) =>
Hello world
);
  return component;
}

Or since new Component() is boilerplate that every component needs, we could pass it in args:
function MyComponent(_props, args) {
  args.component.mount((props, args) => {
    const interval = setInterval(doStuff, 1_000);
    args.component.unmount(() => clearInterval(interval));
    const socket = makeWebsocket();
    args.component.unmount(() => socket.close());
  });
  args.component.render((props, args) =>
Hello world
);
}

This avoids exposing the event-handler array, but we'll have to figure out how we can detach an event-handler from an event.

Can you clarify what's happening that we need to disconnect individual lifecycle events? (vs just throwing away all listeners after the component unmounts)

Good points. Among those, this is probably the biggest problem: Do you now have to be aware that because some 3rd-party library assigns to args.component.unmount, you can't use the unmount() method? Do you and third party libs have to agree on what composition technique/lib you're using?

Am I reading correctly that args.component is the object returned by the ctor? Could we avoid a PR for this approach by just having components reference this while using non-arrow functions?

My view is that the this pointer in JS is very confusing:
a) A parameter representing the this pointer is less ambiguous.
b) It can be anything. When I see a this pointer, I often wonder - what is it?
c) A bit of a misfit for our style of code. But kinda ok if we used OO.
So let me withdraw this PR.
Among the two approaches mentioned at the end of your last response, I am in favor of:
function MyComponent() {
  const component = new Component();
  component.mount((props, args) => {
    const interval = setInterval(doStuff, 1_000);
    component.unmount(() => clearInterval(interval));
    const socket = makeWebsocket();
    component.unmount(() => socket.close());
  });
  component.render((props, args) =>
Hello world
);
  return component;
}

Because:

A function taking just the props is a clean expression. In fact, IDE type checking (at least in earlier versions) got confused if it weren't so.
A component constructor returning a component seems logical, if though it adds a couple of lines.

If we want to avoid the import of Component from forgo, we could do this:
function MyComponent() {
  return (component: ComponentBuilder) => {
    component.mount(() => {
      const interval = setInterval(doStuff, 1_000);
      component.unmount(() => clearInterval(interval));
      const socket = makeWebsocket();
      component.unmount(() => socket.close());
    });
    component.render(() =>
Hello world
);
  };
}

Good points on this. I agree, we ought to avoid it where possible.

I prefer the new Component() style over the arrow function style. It's clear and straightforward what's happening, and the arrow function style creates ambiguity as to which scope is the idiomatic one to put closured variables into.
A couple of thoughts:

Do we still pass args to all of these functions, or should the stuff on args be moved onto the component object? I've been mulling over how we could lift args.update() out of the lifecycle methods and into the closure scope. Technically that's an separate feature discussion, but if we're changing the semantics here I wanted to bring it up. Reasoning: Partly keeping the render function strictly about rendering, partly to make it simple to use logic that needs a rerender in both event handlers and lifecycle methods, and partly for the performance boost of not recreating event handlers every render (I haven't measured the boost for Forgo, but the perf hit is a common trope in React land).
I know I just wrote about the non-composability of function assignments, but it occurs to me that that could be a way to distinguish multicast vs singleton lifecycle handlers. We could do component.thing1(() => ...) for multicast, and component.thing2 = () => ... for singlecast. Thoughts?

Here's what I interpret this whole proposal looking like in a more fleshed-out component, incoporating stuff mentioned here in conjunction with hypothetical / stand-in implementations of contexts & attr transformers. This'll let us see how we feel about the syntax in a larger example, with everything put together.
Lemme know what you think about all this. So far I feel good about this proposal.
const myProjectComponentFactory = () => {
    const component = new Component();
    // Using assign-style here, since we think this wouldn't make sense with multicast
    component.transformAttrs = (key: string, value: unknown) => {
        if (!key.startsWith('on')) return value;
        return () => component.withErrorBoundary(captureExceptions(autoRedraw(value)))
    }
    return component;
}

const setupWebsocket = (component: Component) => {
    const socket = mkSocket();
    // Setting up a lifecycle method inside another lifecycle method
    component.unmount(() => socket.close());
    return socket;
}

const setupInterval(component: Component, cb: () => void, period: number) => {
    component.mount(() => {
        const interval = setInterval(cb, period);
        component.unmount(() => clearInterval(interval))
    })
}

const MyComponent = (_props) => {
    // This is how I'd expect users to apply standardized component
    // patterns across their whole project
    const component = myProjectComponentFactory();

    let valuePulledFromContext: string | null = null;
    let myVariable: unknown[] | null = null;
    let someValue = true;
    const fetchData = async () => {
        myVariable = await doStuff(valuePulledFromContext!);
        component.update();
    }

    // Having `update()` on `component` instead of `args` lets us put the handler
    // out here, only creating it once
    const onClick = () => {
        someValue = !someValue;
        component.update();
    }

    let socket;
    component.mount(async (_props) => {
        socket = setupWebsocket(component);
        await fetchData();
    })
    setupInterval(component, fetchData, 1_000);

    // Testing out the assign style for non-composable lifecycle functions
    component.render = (_props) => {
        // Not sure how I feel about putting the lookup in here. But render() is
        // the only lifecycle method that gets called repeatedly, so it's where
        // retrieving a dynamic value would have to go.
        valuePulledFromContext = libcontext.lookup(component, 'foo');

        if (!myVariable) return
Loading...
;
        return <>

Hello, world! The data is {JSON.stringify(someValue)}

                {myVariable.map(value =>
{value}
)}

        </>
    }
}

I like this proposal (as seen in the code example). I think we're pretty close to an agreement here.

I've been mulling over how we could lift args.update() out of the lifecycle methods and into the closure scope. Technically that's an separate feature discussion, but if we're changing the semantics here I wanted to bring it up.

I think it's a very good idea. component.update() is more meaningful that args.update().

partly to make it simple to use logic that needs a rerender in both event handlers and lifecycle methods, and partly for the performance boost of not recreating event handlers every render

Not sure if I entirely followed this. (Irrespective, we should move update() into component).
Minor: In the code example,  I think you missed returning component from MyComponent() - just making sure this is what you meant.

We could do component.thing1(() => ...) for multicast, and component.thing2 = () => ... for singlecast. The singlecast methods I think avoid all of the caveats from my last past.

Can you provide an example? I am not sure if I fully understood this.
Should we we support multicast and singlecast?

Is component.render singlecast, while component.mount supports multicast? (from the code example)
If component.render is also multicast, do we take the last handler's output, or do we merge the output from all handlers?
It might be a little confusing to have multicast and singlecast, rather than say that all events are multicast.

Should we use an array and expose it?
component.mount.push(async (_props) => {
    socket = setupWebsocket(component);
    await fetchData();
});

Advantages:

handlers can be removed [1]. May not be useful for everyone, but could be for extension authors. I can think of a few usecases (such as in aiding debugging/logging). And FWIW, desktop GUI frameworks usually allow you to do this.

[1]: Example of
component.mount = component.mount.filter(fn => fn !== someFunc);

To make it more relatable and familiar, perhaps we should use addEventListener() and removeEventListener() which are familiar to web devs.
component.addEventListener("mount", (async (_props) => {
  socket = setupWebsocket(component);
  await fetchData();
}));

Or use the very similar NodeJS Emitter semantics.
component.on("mount", (async (_props) => {
  socket = setupWebsocket(component);
  await fetchData();
}));

But given that this is purely a browser framework, addEventListener() and removeEventListener() might be the way to go.

Event Listening is appropriate for "mount", "unmount" etc, while render is like a method().

Hence, I am in favor of:
component.render = (_props) => { /* .... */ }

Which is what you had in your example.

An alternative proposal, if you don't like render() referring to component which is outside its body is:
function render(props, component) {
  return
hello world

}

However, JS allows a function body to refer to a variable which was not available when the function was created. Hence, the code example given earlier works as is.
So the only value I see for render() taking in "component" as the second argument is that it allows the definition of render() outside MyComponent.

partly to make it simple to use logic that needs a rerender in both event handlers and lifecycle methods, and partly for the performance boost of not recreating event handlers every render

Not sure if I entirely followed this. (Irrespective, we should move update() into component).

Simple logic part: in Forgo's current API, imagine you have a data fetch function you want to run on mount, and after some click events. You'd like to declare that function it the closure scope, but in Forgo's current API, that scope doesn't have access to args.element so it can't include the call to rerender(). So you have to come up with workarounds.
Performance part: the idea behind React's useCallback is that, in tight render loops, the cost of redeclaring click handler functions every single render starts to affect performance, so you look for ways to avoid doing that. Lifting args.update() up to component.update() makes that more natural to do in Forgo. Does that perf difference matter all the time? Probably not. But it's a nice bonus if the change improves ergonomics anyway.

Minor: In the code example, I think you missed returning component from MyComponent() - just making sure this is what you meant.

Oh, yep! I meant to return it.

We could do component.thing1(() => ...) for multicast, and component.thing2 = () => ... for singlecast. The singlecast methods I think avoid all of the caveats from my last past.

Can you provide an example? I am not sure if I fully understood this.

Looks like you got on the same train of thought with this comment:

I think a clear separation of what are event listeners, and what are methods could be important.

In the code example I gave, you'll note that I did component.render = ..., but component.mount(() => ...)., to distinguish things that are multicast vs things we want to signal aren't meant to compose. I like your decisions better.

I like the the choice of methods + component.addEventListener(). The event emitter does imply we'd have a component.removeEventListener(), which I don't see a use case for, but leaving it out could be confusing. But maybe not confusing enough to worry about?
Is shouldUpdate() actually unicast? I could see a state library wanting to hook into shouldUpdate(), while the developer also wants to use it. Maybe multicast, with semantics of "component will update if any listeners return a truthy value"?

An alternative proposal, if you don't like render() and other methods/listeners referring to component which is outside its body is to add it as a second parameter

I like passing component to events/methods, regardless of our choice for the closure scope ergonomics.
Re: hoisting:
Pro: I like that the new Component(methods) syntax makes it really easy to type check that we get a well-formed component (i.e., mandatory render method).
Con: hoisting is probably JavaScript's most unintuitive feature; it's tricky to understand what it really does, and makes it harder to read/understand your own code. Plus it opts out of TypeScript's control-flow type inference.
Anything in the closure scope that needs to rerender needs access to the constructed component, and it either gets declared first and hoists the component, or gets declared second and gets hoisted by the component. Both of those feel kinda icky.
Re: naked render purity / testability / reusability: will we get this in the wild? I'm not sure when I'd want a standalone render() function that didn't depend on closure scope for functions/state, without having a reason to make a new component instead.
What about moving method declaration out of the new Component() call and into the ctor's return value, by having the ctor return a tuple? This example avoids hoisting, preserves type safety in what the ctor returns, and still leaves render() as standalone if some case benefits from that.
function MyComponent() {
  const component = new Component();
  component.mount(async (_props, component) => {
    await fetchData();
    component.update();
  });

  let data;
  async function refresh() {
    data = await fetchData();
    component.update();
  }

  const componentMethods: forgo.ComponentMethods = {
    render() {
      return <>
        <button onclick={refresh}>Refresh</button>

{data}

      </>
    };

  return [component, componentMethods];
  }
}

Maybe we can use the spread operator to assign methods to the component?
function MyComponent() {
  // changed from `new Component()` since it now returns an incomplete type
  const component = forgo.createComponent()
  component.mount(async (_props, component) => {
    await fetchData();
    component.update();
  });

  let data;
  async function refresh() {
    data = await fetchData();
    component.update();
  }

  return {
    ...component,
    render() {
      return <>
        <button onclick={refresh}>Refresh</button>

{data}

      </>
    }
  };
}

If forgo.createComponent() returns Omit<Component, 'render'>, then we force the ctor to fill in the mandatory method, and we get one logical component object.

Or we go with a callback?
function MyComponent() {
  return new Component((component => {
    component.mount(async (_props, component) => {
      await fetchData();
      component.update();
    });

    let data;
    async function refresh() {
      data = await fetchData();
      component.update();
    }

    return {
      render() {
        return <>
          <button onclick={refresh}>Refresh</button>

{data}

        </>
      }
    };
  });
}

Disadvantage: now we're back to two closure scopes.
Idunno. All four of these (hoisting, tuple, spread, callback) work, but none of them feel right.

Right now I'm not sure of another way to achieve a type safe return while also dodging the hoisting.

Sorry I may be missing something. If the signature of render is render(props, component), we don't need to worry about hoisting right?
function MyNewComponent(props) {
  function render(props, component) {
    return <button onclick={() => component.update()}></button>;
  }

  // Assume this is unicast for now (will fix)
  function shouldUpdate(props) {
    return true;
  }

  const myNewComponent = new Component({ render, shouldUpdate });
  myNewComponent.addEventListener("mount", () => console.log("mounted"));
  return myNewComponent;
}

render() doesn't need to hoist access to the Component instance, but it does need to hoist access to userland methods that depend on the Component instance.
E.g., if there's a click handler declared in the closure scope that rerenders, you either need: to hoist the click handler
function MyComponent() {
  const component = new Component({
    // Hosting the onclick handler
    render() {
      <button onclick={onclick}>Do Stuff</button>
    }
  });

  const onclick = () => {
    ...
    component.update();
  }
}

Or, you need to hoist the component:
function MyComponent() {

  // Hosting the component
  const onclick = () => {
    ...
    component.update();
  }

  const component = new Component({
    render() {
      <button onclick={onclick}>Do Stuff</button>
    }
  });
}

But you could write clickHandler() inside render.
function render(props, component) {
  function clickHandler() {
    component.update();
  }
  return <button onclick={clickHandler}></button>;
}

But you could write clickHandler inside render.

Ah, sorry. This is what I was getting at at the top of this comment, but I don't think I explained it very well.
Putting event handlers inside render() means those handler's can't be accessed from outside render(). But doing exactly that is a common pattern: fetch some data on mount, maybe poll for updates, and fetch again after clicking a button.
Contrived example with Forgo's existing API:
function MyComponent() {
  let data;
  let doStuff;

  return {
    async mount() {
      await doStuff!();
      setInterval(doStuff!, 10_000);
    },
    render(_props, args) {
      doStuff ||= async () => {
        data = await fetchData();
        args.update();
      }

      return <>
        <button onclick={doStuff}>Do Stuff</button>

{data}

      </>
    }
  };
}

Here, we have a few different places where we want to fetch data and rerender. Because rerendering requires access to args, the doStuff() function has to be declared inside a lifecycle method, then exfiltrated into the closure context so other lifecycle methods can access it.
If we're already rethinking the semantics of the component API, this is something I'd like to improve. If the user has a function that rerenders and needs to it from multiple places, they should be able to declare it in the closure scope, without making + copying + non-null asserting it. As a bonus, declaring it in the closure scope lets it stay right next to the data it modifies.
Improved experience:
function MyComponent() {
  let data;
  const doStuff = async () => {
    data = await fetchData();
    // Doesn't work in existing API, could work with `new Component(); component.update()`.
    args.update();
  }

  return {
    async mount() {
      await doStuff();
      setInterval(doStuff, 10_000);
    },
    render(_props, args) {
      return <>
        <button onclick={doStuff}>Do Stuff</button>

{data}

      </>
    }
  };
}

Putting event handlers inside render() means those handler's can't be accessed from outside render(). But doing exactly that is a common pattern: fetch some data on mount, maybe poll for updates, and fetch again after clicking a button.

It'd need to accept the component as an arg, but is that a problem?
function doStuff(component) {
  console.log("Doing stuff...");
}

function MyNewComponent(props) {
  function render(props, component) {
    function clickHandler() {
      doStuff(component);
    }
    return <button onclick={clickHandler}></button>;
  }

  return new Component({ render });
}

...
Yeah, that'll work.

Minor nit that that requires onclick={() => doStuff(component)} (i.e., the runtime cost of declaring that arrow function on every render), but if that really becomes a performance problem, I think it's fine to ask users to do the aforementioned ||= approach on an as-needed basis. The important parts are colocation of functions + data, and good types ergonomics, which we get from just passing the component around.

Summary of the current proposal:
Pretty sure we're on the same page about:

const component = new Component(); return component
Component() requires as an argument an object containing non-event-y lifecycle methods

render() is mandatory
transformAttrs() would eventually go here

With component instance, event-y lifecycle listeners can be added with component.addEventListener('mount', () => ..). Multiple listeners is okay, all will be executed.

We probably want to guarantee that they run in the order in which they were registered.

An app can register lifecycle listeners from within other listeners, so a mount listener can register its own unmount logic.
The component instance is expected to be passed around in userland. It is the cornerstone of composing + extending a Forgo component.
args.update() becomes component.update()
All events + methods will receive as arguments the props + component instance, in that order

Unclear / undecided:

The component instance becomes the stable identifier anytime userland needs to interact with Forgo, replacing the userland use of args.element.

Stuff like the eventual contexts library would hand the component instance to Forgo to request its parent component, getting back another component instance.

shouldUpdate() becomes multicast, and component will rerender if any shouldUpdate() listener returns truthy.
Does args / ForgoRenderArgs disappear from userland entirely?

Do we move args.element -> component.element, or remove it altogether since we'll have component.update()?

How does that sound? Lots of back and forth, including me having a braindead morning 🙂

The component instance becomes the stable identifier anytime userland needs to interact with Forgo, replacing the userland use of args.element.

I think yes.

shouldUpdate() becomes multicast, and component will rerender if any shouldUpdate() listener returns truthy.

I'm ok with this

Does args / ForgoRenderArgs disappear from userland entirely?

I think it should go.

Do we move args.element -> component.element, or remove it altogether since we'll have component.update()?

We could retain component.element - doesn't seem out of place. But perhaps not discuss it in docs.

Sounds good! I'll start looking into implementation later today.

I've done a first pass conversion of the framework code and have been porting test cases over to the new syntax. I've discovered the delightful fact that if you annotate the types for the ctor, TypeScript only infers the Props generic for the Component if it's immediately returned, but not if you create a local variable, add event listeners, and then return.
// TypeScript complains that the return type doesn't match the declaration because
// the ctor has props but the component can't figure out it should get its props from the
// ctor's annotation
const StatefulComponent: forgo.ForgoComponentCtor<
  forgo.ForgoComponentProps & { key: unknown }
> = () => {
  let state = getRandomString();
  // Component() is really Component<Props extends ForgoComponentProps>().
  // Without an explicit annotation TS has to deduce what that generic parameter's
  // value is. And it fails to do so if you assign the component to a variable instead
  // of immediately returning it.
  const component = new forgo.Component({
    // TS error here that props doesn't include `key` because the component doesn't
    // pick up the ctor's generic parameter
    render({ key }) {
      savedState.set(key, state);
      return (

          Component #{key}

      );
    },
  });
  // Another TS error here about `key`
  component.addEventListener("unmount", ({ key }) => {
    savedState.delete(key);
  });
  return component;
};

// This syntax typechecks just fine because TS can tell that the return value needs to
// conform to the ctor's type signature. But of course now the user doesn't have a
// variable to add event listeners to
const StatefulComponent: forgo.ForgoComponentCtor<
  forgo.ForgoComponentProps & { key: unknown }
> = () => {
  return new forgo.Component({
    render({ key }) {
      savedState.set(key, state);
      return (

          Component #{key}

      );
    },
  });
};

Right now I see three options:

Maybe there's a way to get TS to figure this out and make the whole problem go away. I haven't found that yet. In this case I'm mostly guessing at how I've angered TS and trying incantations to appease it.
Tell users to create a named interface for props. Solves the problem, but it doesn't feel great to make named interfaces for every little thing, especially when each one is only used in one spot in your code.
2a. The current test suite doesn't annotate the ctor, and we could just say "don't annotate the ctor" and then the user is only parameterizing the component and there's no duplication. I don't think that's what we should encourage: it leaves room for errors (e.g., all of the unconverted unit tests typecheck right now because TS doesn't know that the API change broke any of them). And since we pass props to the ctor, the user would want type checking there anyway.
Maybe TS isn't capable of inferring the generic parameter in this API design? I don't know enough to say. But if we can't make (1) work and we don't like (2), we're left with redesigning the API around TypeScript's limitations.

I don't have any concrete thoughts / action steps on this yet, I just want to note it down while it's on my mind:
From an extensibility point of view we need to support multiple shouldUpdate callbacks, but it feels weird to call it an event listener since it has a meaningful return value. But I don't want to go inventing a third way to specify behavior on components.

Just to clarify - in the examples, do you mean the special property "key" that we (and React as well) support?

Adding key to ForgoElementProps kinda makes sense, right?

I've waffled on that for a while. Right now children have access to key, but I haven't teased out whether to consider it a leaky implementation detail or a useful design decision. We keep taking advantage of it in unit tests and sandboxes, but I don't know whether there's a real-world use case for reading the key used in the parent context.
Adding key to ForgoElementProps comes down to whether reading the parent context key is something we want to support + encourage. To date I've leaned in the direction of not making that an official part of the API until we have a compelling reason to, but I'll follow your lead on it.

can you modify the code you posted above so that StatefulComponent also takes in a few props of its own (such as say firstName and lastName)?

Sure thing. That code was copy/pasted out of the first unit test I encountered that needed a props annotation. Here's a modified version that demonstrates the issue a bit more clearly:
const StatefulComponent: forgo.ForgoComponentCtor<
  forgo.ForgoComponentProps & { firstName: string, lastName: string }
> = () => {
  const component = new forgo.Component({
    render({ firstName, lastName }) {
      return (

          Hello, {firstName} {lastName} !

      );
    },
  });
  return component;
};

The line with const StatefulComponent produces this error:
Type 'ForgoElementProps' is not assignable to type 'ForgoElementProps & { firstName: string; lastName: string; }'.ts(2322)

Because the new forgo.Component() construct is inferred to be a Component<forgo.ForgoElementProps>, while TypeScript expects the ctor to return a Component<ForgoElementProps & { firstName: string; lastName: string;}>.
If the code is modified from const component = new Component(...) ; return component; to instead read return new Component(...), TypeScript can correctly deduce that the component is a Component<ForgoElementProps & { firstName: string; lastName: string;}> because that's what the ctor's type signature says it should return.
Full version that typechecks correctly:
const StatefulComponent2: forgo.ForgoComponentCtor<
  forgo.ForgoComponentProps & { firstName: string, lastName: string }
> = () => {
  return new forgo.Component({
    render({ firstName, lastName }) {
      return (

          Hello, {firstName} {lastName} !

      );
    },
  });
};

The problem with this version ^^ is that now we don't have access to a component variable to add event listeners to, pass to libraries, etc.
We can solve the issue by supplying a type annotation to both the ctor and to the Component constructor:
interface StatefulComponentProps extends forgo.ForgoComponentProps {
  firstName: string;
  lastName: string
}

const StatefulComponent: forgo.ForgoComponentCtor<StatefulComponentProps> = () => {
  const component = new forgo.Component<StatefulComponentProps>({
    render({ firstName, lastName }) {
      return (

          Hello, {firstName} {lastName} !

      );
    },
  });
  return component;
};

It's effective, but verbose and clunky. Declaring the named interface doesn't feel right if it's not going to be used anywhere else in the codebase but right here.

Looks like we get the same behavior with the existing API if we assign the component to a variable instead of returning it immediately:
const App: ForgoComponentCtor<
  ForgoComponentProps & { firstName: string }
> = () => {
  // TS complains that `ForgoComponent` needs a type parameter
  const component: ForgoComponent = {
    // TS complains that firstName is implicitly `any`.
    render({ firstName }) {
      return
Hello, {firstName}!
;
    }
  };
  return component;
};

And we're hitting this because we've never had a reason to assign the component to a variable before.

I think having to repeat the type argument is fine. It's slightly more verbose, but it's logical and hopefully not too bad.
Sorry haven't spent enough time on this yet - but will do over the weekend.

Okay, I'll proceed with doing the unit test conversions that way.

I find the following example of yours quite reasonable - I like it. (I tried a few other approaches, but this is still the most elegant.)
const StatefulComponent: forgo.ForgoComponentCtor<StatefulComponentProps> = () => {
  const component = new forgo.Component<StatefulComponentProps>({
    render({ firstName, lastName }) {
      return (

          Hello, {firstName} {lastName} !

      );
    },
  });
  return component;
};

Adding key to ForgoElementProps comes down to whether reading the parent context key is something we want to support + encourage. To date I've leaned in the direction of not making that an official part of the API until we have a compelling reason to, but I'll follow your lead on it.

Alright, let's not do anything on this for now. Hard to walk back once we publish.

I've got all the existing unit tests passing against the new API.
Still too:

Write tests for the new behavior
Remove some old types like ForgoRenderArgs that we shouldn't be using anymore
Update documentation
Make forgo-state etc. compatible with the new API.

At some point I'll publish an alpha release of all the packages so I can start porting my app over and test this stuff in a real project.

Amazing stuff! Thanks for all your hard work on this - and sorry I wasn't of much help. I'll try it out today.
I think we should make some noise about this release - it's the biggest change since V1. :)
In addition to the things you mentioned, We should:

improve the performance (I'll look at it this week)
write a blog about v3, how it's different etc.
Maybe do a "Show HN" or something.

Also, I can fix up forgo-state this week.

I agree, between this and all the other work over the last year, Forgo is stronger now and we should highlight that.
Doing perf work before making the big announcement makes sense. In that case, let's make sure the JS Benchmarks page reflects the new performance before the announcement goes out.

I cleaned up old types and the TODOs I had. I also adjusted the component API so that specifying the component props type can be done as new Component<MyProps>() instead of new Component<ForgoComponentProps & MyProps>(), because that's been bugging me forever.
And I added unit tests asserting the shape of the new API - that event listeners get called, in order, that shouldUpdate kicks in if any of the listeners returns true.
I still haven't done a manual test in a sandbox. Besides that, I need to do docs updates. Then it's just updating the extra forgo packages to use the new API and I think this will be ready for review.

That's phenomenal!
I'll look at it tomorrow or the day after, just recovering from a mild covid infection.

Oh no! Sorry to hear that. I've had several people get it in the last couple weeks.
<EMAIL_ADDRESS>(tag prerelease) is now published, and the "hello world" works in a sandbox! I'm going to look at the forgo-state conversion now; I want to get this ready to convert my app over since that'll test it better than any sandbox I think up.

Well... that was easy.
I've update forgo-state and forgo-router and cut alphas for them, and ported my app to the new component API, and all of my e2e tests pass. Since the minimum upgrade path is syntax with little semantic difference it was basically all just going as fast as I could type (though I'm not taking advantage of the new structural opportunities the new API enables yet).
For forgo-state I changed it to not return a component, since now it doesn't need to create a wrapper - it can just use the event listeners. The new API doesn't let forgo-state control whether its listeners come before any listeners registered in userland, but I'm not sure that's a problem.

Thoughts after converting forgo, forgo-state, forgo-router, my own app:

For the most part the API feels good. Sometimes doing return new Component and sometimes const component = ...; component.addEventListener(...); return component is a little bit of friction, but I think it's definitely worth it for what it gets us in extensibility.
The more I sit with it, the more it feels incorrect & unintuitive to call shouldUpdate an event listener when it has a return value and Array.some(...) semantics. But I haven't figured out what it should be changed to.
Components have a .__internal property that forgo-state and forgo-router need to reach into. Ideally we'd hide that from userland with TypeScript's stripInternal flag, but then our own extension packages couldn't see it. We should figure out what in .__internal makes sense to expose on a public API and hide the rest. I think it's usually the node, but exposing that feels weird since it's an implementation detail.

Addendum: transformAttrs would probably also need to be multicast (e.g., wrap click handler in both auto-refresh and error capture), and wouldn't be served by event listener semantics - it'd probably be more like a reducer. Maybe using component.on() instead of component.addEventListener() would minimize confusion? Not sure about that.

I keep looking for ways to improve this proposal, but nothing feels great, just okay. Here's what I'm thinking right now:
const MyComponent: ForgoComponentCtor<MyProps> = (_props, {component}) => {
  component.mount.push(() => {
    ...
    component.unmount.push(() => ...);
  });
  component.transformAttrs = () => ...
  component.shouldUpdate.push(() => ...);
  component.render = () => ...
};

Pros:

The user doesn't need a named interface for props, since they'll be passed component that matches the generic parameter passed to ForgoComponentCtor
It's very clear whether a method is single-cast or multicast
Multicast methods don't carry semantic baggage (like being shaped like an event listener). If we need to give any of them special behavior (e.g., shouldUpdate) we can just do that.
This saves a modest amount of boilerplate: the user doesn't have to instantiate the component, return it, or amend their forgo import to explicitly import Component (if using they're named imports)
The user can define the component's methods in a logical order. One downside of the existing proposal is that it feels weird to define render before you define the methods that affect what happens in render (mount setting variables, shouldUpdate deciding whether to render at all).
Minor Forgo code simplification vs the current proposal.

Cons:

We'll have to add a runtime check to ensure render is defined when the constructor returns. The type system can't guarantee that under this proposal. Probably not a big deal since it's our only mandatory method, and it's hard to imagine a user accidentally forgetting to render.
We'll have to add runtime checks to ensure the array-typed properties don't get assigned to something different. We can keep that code to a minimum by making component a Proxy and denying any set on the relevant properties.
Exposing the underlying arrays for multicast properties directly to the user feels inelegant, and means we don't control whether the user pushes to the front or back of the array

Though letting them make that choice might possibly be useful? Maybe?
Exposing the arrays implies a level of trust inside the codebase. There's no good reason some library should empty out the array or overwrite an index, but we're making it possible to do so. We could use even more Proxys to prevent that if we felt strongly about it.

I'd like to add a compatibility layer bridging the old component syntax. This would give users an upgrade path, and let us release this as a non-breaking 3.x, with a deprecation notice that the old syntax will stop working in 4.0. We can let the user set a flag on window that makes Forgo print a warning to the console if the old syntax is used, helping users catch any place they haven't migrated (the flag is to keep the console from being spammed).

Hmmm, continuing to define the component as whatever the user returns could hamper making the error boundary logic general-purpose. If we supply the component object (or the user instantiates a class), then providing component.withErrorBoundary(() => ...) is pretty simple. But if the user hands us a POJO, where do they get an error boundary function that knows what component it goes with? We could pass one into args, but then it's clumsy to define click handlers in the component closure scope because args isn't available there.

Excellent writeup. I agree with the Pros and Cons [mentioned above] (https://github.com/forgojs/forgo/issues/59#issuecomment-1180615004). I don't think the Cons are a big deal. So we should definitely consider this proposal.

Or maybe we revisit keeping the existing syntax but making multicast properties use arrays. Looking back at that discussion, my objections can be solved by just deciding that mount and friends are always arrays. We can allow both methods and arrays of methods temporarily as a compatibility layer, then in 4.x support only arrays of methods.

We can consider this too.

I'd like to preserve the current proposal's trait of exposing all that stuff in the ctor scope, but that means we can't let the user hand us a POJO to represent the component.

We could get around this by passing these functions in ForgoCtorArgs, then binding them to the component after the ctor returns.

I think I largely understand what you're trying to say. But can you give a short example please?

We have a set of proposals here. Maybe we should name/number them?
I'll have a go at it:

Original (ORIG): https://github.com/forgojs/forgo/issues/59#issuecomment-1107347533
Component Returned by User (CRU): https://github.com/forgojs/forgo/issues/59#issuecomment-1107295201
Component as Ctor Param (COCP): https://github.com/forgojs/forgo/issues/59#issuecomment-1180615004

CRU is the currently very nearly complete. Please add others are you see fit.

What I don't like about COCP is that the coding style looks very mutable/imperative. We're changing fields.
component.render = () => {}

If we adopt this, I'd like to continue replacing the args parameter with an instance of the component (which Forgo would add an update method to after the ctor returns).

I like the ORIG proposal too, with the above edit you mentioned.
The only upside with having args I can see is that it allows us to add stuff into the args object in future, which we haven't thought about yet - but I'm not really sure if that's a good thing. If we're using the ORIG proposal, my vote would be to make the edit you mentioned above.

I also don't like how imperative nature of COCP is, especially for the mandatory render() method. Since render() is the only mandatory method, we could modify COCP to make that part less error-prone by having the ctor return the render method instead of assigning to a property on the component:
function MyCtor(_props, component) {
  component.mount.push(() => ...);
  return (_props, _component) => {

Hello, world!

  }
}

That type-checks well, and preserves the advantage over CRU of not needing the explicit named interface for props, because it can be inferred from the ctor generic just like the existing syntax's types are.
This approach also makes the minimal component super minimal:
function MyCtor() {
  return () =>
Hello, world!

}

Re: assigning properties vs calling methods: I like that component.mount(() => ...) feels more "normal" than component.mount.push(() => ...). Looking at a lifecycle method and guessing from the API whether it's single-cast or multicast still seems ambiguous, but I'm not sure we're going to find a great answer to that. Maybe the answer is to just expect people to know how to use the tool, and to throw an exception if the user overwrites a single-cast method.

Thinking about ORIG some more, I think saying "arrays only" fixes some error patterns but leaves others in. Whenever a library receives a component, it doesn't know if it already has the arrays in place, so every call site turns into
(component) => component.mount = component.mount ? [...component.mount, foo] : [foo]

That's pretty gnarly to have everywhere, and you just know people are going to have subtle bugs because they took a shortcut.
Between that and introducing two ways to call withErrorBoundary() and friends, I think I'm back to ORIG not being the right choice.

CRU as currently implemented is slightly different from what you linked, basically just that it does component.addEventListener('mount', () => ...) instead of component.mount(() => ...). But yeah, it's basically done. I just need to update the docs and see if packages besides forgo-state and forgo-router need porting.
I'm fine with implementing something else if CRU isn't the right choice.

Modified COCP, and CRU without addEventListener, seem pretty similar. The tradeoff seems to be:
COCP: reduced boilerplate (no component import or instantiation, no double type declaration). Minimal example compares well against React. User could get confused by component being a function parameter ("Wait, I have the ctor, the render method, and the component? How are these different? Which one is really the component?"). Maybe if we don't call the second ctor argument component, but instead call it lifecycle or hooks or something, that'd be less confusing. And I may be overestimating how confusing this is - Solid is componentless and people seem fine with that.
CRU: Very explicit, it's clear what you're doing. More boilerplate. Lifecycle methods must be declared after render (in my experience, for long render methods that means lifecycle methods get pushed to the bottom of the file when I sometimes forget I even have them).
So basically COCP sounds nicer to use, while CRU might be less confusing to newbies.
Right now I favor COCP, modified to use component.mount(() => ...) syntax, with render as the ctor return value..

I think a bit of elegance is lost somewhere. In the following example, we attach functions to a pre-existing components (as in mount), as well as return a function back (the render func) to be attached by the caller.
function MyCtor(_props, component) {
  component.mount.push(() => ...);
  return (_props, _component) => {

Hello, world!

  }
}

When I read it (as someone who's not familiar with this discussion), I'm not sure if it makes entirely makes sense.

Fair enough.
I can proceed with the CRU syntax, swapping out component.addEventListener for component.mount and get that ready for a PR. Sound good?

Are you fully in agreement, though? You mentioned downsides with CRU as well, so I'm not entirely sure if they've been addressed.
I suppose we could support the current syntax entirely on CRU by writing a wrapper func. Even COCP can perhaps be written on top of CRU - since component creation is in "userland" and a factory method could handle that.

I think CRU has compromises, but it's probably the best option we're going to get.
I checked if we could borrow ideas from other frameworks, but they either do what Forgo does now (with the accompanying limitations), or act like React hooks, with magic under-the-hood behavior to tell what component a hook goes with. Neither of those feel appropriate here.

I suppose we could support the legacy syntax entirely on CRU by writing a wrapper func.

I can include that in the PR, then we can do a non-breaking 3.x release, with a deprecation notice that only the new syntax will be in 4.0. It can definitely work at the JS level. I'll have to experiment to see about not introducing breaking change on types.

I've submitted PRs for all the Forgo repos. I only verified forgo-state (the only repo with tests) and forgo-router (my app uses it). The rest looked simple enough to just rely on types.
I released betas for forgo-state and forgo-router so I could put them to the test in my app. I didn't version bump anything else - I figure that should happen after the PR gets merged.
I'm not sure how to update the template for the code sandbox. It doesn't look like the code for that is stored in any of our git repos. Do you have to share ownership of the resource on codesandbox.io?

Once these get merged, I think that means we can go ahead and release 3.2.0 and all the ancillary packages, and update the website.

Do you have to share ownership of the resource on codesandbox.io?

I just did that.

Fantastic. I've merged all of them.

The rest looked simple enough to just rely on types.

Yes that's true.

I updated the sandboxes, bumped all the versions, and cut releases! Forgo 3.2.0 is out! 🎉
There's a PR for the website just to make sure I handle that right, and a PR for the npm version minor I ran to bump forgo out of beta.

Everything is out!


How exactly does it work?

Can someone point me to an article that explains how the library works? How exactly does the JavaScript load just the requested icons?  Is the browser able to cache used icons? And how much overhead is involved in this process? Thanks.

Data is loaded from API. Documentation for API: https://docs.iconify.design/api/
Yes, there is cache.

API responses are cached in localStorage or sessionStorage, depending on configuration. By default its localStorage. See https://docs.iconify.design/iconify-icon/enable-cache.html
If that fails, there is always browser cache. Displaying same page means loading same icons, so API queries are the same and are usually cached in browser.


Notification on Boosts hitting a certain point

It would be nice to allow an "idle" notification when your potion/any boost get to a certain threshold. For example, in NMZ when boosted by a super combat potion, get a notification when your boosts drop to "+x" with x being set by the user.

Already implemented I believe


Prefect recipes and tests are not functional due to Pydantic conflict

Environment
N/A
What is the issue?
Prefect currently relies on Pydantic 1, but Quacc and its dependencies rely on Pydantic 2. As such, all the Prefect tests are now being skipped and the Prefect recipes are not functional without a little bit of hacking around.
This can be resolved by setting the minimum version of Prefect once the following is merged:

https://github.com/PrefectHQ/prefect/issues/10145

How can we reproduce the issue?
N/A

Honestly, it's probably worth removing Prefect support altogether unless the following is merged:

https://github.com/PrefectHQ/prefect/issues/10928


run KRM Config functions from kustomize

We have a design doc and POC (add links)
This will trigger 3.7 or 3.8

this includes writing documentation and examples (or file new issues for that)
do container-based in distinct issue

Feel free to build off the contrubuted POC PR.  it might be best (most welcoming) to merge that and build off it. let me know what you think.

I am OK to work on top that. But that PR adds some flags to build command. Is that OK?

Created issues for doc.
Containerized function is also implemented.


Fix transportation constraints

https://github.com/leonlan/fjsp/blob/28dafbce8791386c7b7e47db72ec1622731c40bc/fjsp/CpModel.py#L137-L157
This constraint is not correct yet.
To recap:

If there are two operations $i$ and $j$, let $M_i$ denote the eligible machine set for $i$ and define $M_j$ similarly.
Assume that there is an edge $i \rightarrow j$, implying that $i$ must come before $j$. (This is not always true!)
Let $m_i \in M_i$ and $m_j \in M_j$ denote some machine pair.

Nowe we distinguish two cases:

There is a machine edge between $m_i$ and $m_j$. Then there are no restrictions: we can schedule $i$ on $m_i$ or not, and we can schedule $j$ on $m_j$ or not, independent of the other choice.
There is no machine edge between $m_i$ and $m_j$. Then that means that if I schedule on $i$ on $m_i$, then we cannot schedule the operations on $m_j$, because there is an accessibility restriction. Therefore, the presence of $i$ on $m_i$ forces the non-presence of $j$ on $m_j$.

The correct constraint is therefore:
$$\text{PresenceOf}(A) + \text{PresenceOf}(B) \leq 1.$$

Fixed in by 214852e.


add uptime monitor project with golang.

Description
add cool project to this repo with golang...
Please include a summary of the program i.e what problem it solves.
Checklist:

[ ] My code follows the style guidelines of this project
[ ] I have added my code in its respective language folder.
[ ] I have mentioned a short description about the code at the beginning of the program.
[ ] I have performed a self-review of my own code
[ ] I have commented my code, particularly in hard-to-understand areas.
[ ] My changes generate no new warnings
[ ] I have not delete any files that already exists in the repository.

please check it, tnx


Substreams: Introducing Substreams Video

Perhaps include the "Introducing Substreams" video as an embed to the front page: https://substreams.streamingfast.io/

Video added to main doc page for Substreams.


Add version to uv python module

Just discovered this code fails
import uv
uv.__version__

With error
AttributeError: module 'uv' has no attribute '__version__'
I know it's rare for users to import uv as a module, but it was the "obvious" way to check the version when a jupyter notebook is open.
Note that running uv --version on the terminal works fine, so does running !uv --version on a notebook

IMHO (and this is just comment from a side - I've learned about it when I proposed to use _version_ in another module), we should not continue this practice and where popular packages do not have them already, we should not add them - because that only increases the confusion about status of __version__ attribute. It's not only used inconsistently, but also while it's popular in some packages it's status as "standard" is clearly "NO".
It's been proposed in https://peps.python.org/pep-0396/ and rejected.
Instead the standard (and simple and fast) way of retrieving version of the installed package is via importlib-metadata (https://docs.python.org/3/library/importlib.metadata.html#distribution-versions)  and this is the one I think we - as community should promote.
It's a bit hot topic - see<EMAIL_ADDRESS>where the PEP-396 has been rejected - and of course it's up to maintainers to decide, but my personal opinion is - let's stop using it (or at least let's not add it to packages that don't use it already).

Ok, I thought it was standard but your argument is very clear.
I don't fully follow the rationale in the rejections of the PEPs, but so be it.

Yes, the way to do this, instead of:
import uv
uv.__version__

Do this instead:
>>> from importlib.metadata import version
>>> version("uv")
... 0.1.20


Bubble Sort

Description 📜
I made a documentation for Bubble sorting in c++. I also added documentation for dynamic memory allocation.
Fixes #878
Fixes #885

Type of change 📝

[x] Doc#umentation (Content Creation in the form of codes or tutorials)

Domain of Contribution 📊

[x] C/#CPP

Checklist ✅

[x] I follow Contributing Guidelines & Code of conduct of this project.
[x] I have performed a self-review of my own code or work.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] My changes generates no new warnings.
[x] I'm GWOC'21 contributor

Screenshots / Gif (Optional) 📸

@vasu-1  There is already 1 directory
Data Structures > Sorting

@vasu-1 There is already 1 directory
Data Structures > Sorting
Usi mein daal raha hun

Cool ! :100:

@vasu-1 @Xyandraa9  Wait a minute,  why's there Dynamic Alloc files on this?

I apologise for the error, it's actually my first time contributing so I thought when i commit the changes to the Dynamic Memory Allocation issue, I will be able to create another PR, but I got confused. What should I do to rectify this?

@Xyandraa9 please delete this pr ..
And make two new saperate PRs for both the issues 👍

@vasu-1 okay


Long recordings cannot be recorded

Hello,
we have a bbb recording with 7239 secounds.
We are always running into the same issue:
Error: Could not stop Xvfb.     at Xvfb.stopSync (/root/bbb-recorder/node_modules/xvfb/index.js:129:17)     at main (/root/bbb-recorder/export.js:95:18)     at <anonymous>
Maybe someone has an idea how to fix the problem?
We are running bbb-recorder on an Ubuntu 18.04 VM with no bbb installed.
All best

Hi,
Try to remove this line:
https://github.com/jibon57/bbb-recorder/blob/bf6eeb2996aa0ad7d1d6a922fe2bb082cd265848/export.js#L95
Not sure why in your server can't close Xvfb process but that will be work around.

Or I think setTimout can help here. Can you try like this:
setTimeout(function(){
	xvfb.stopSync();
}, 3000);

It's better to give it 3 seconds to clean up.

Next test with 3 seconds timeout is running.
I will give you feedback as soon as possible.
Thank you!

A other error:
`/root/bbb-recorder/meeting.mp4
/root/Downloads/meeting.webm
/root/bbb-recorder/node_modules/xvfb/index.js:129
throw new Error('Could not stop Xvfb.');
^
Error: Could not stop Xvfb.
at Xvfb.stopSync (/root/bbb-recorder/node_modules/xvfb/index.js:129:17)
at Timeout._onTimeout (/root/bbb-recorder/export.js:97:9)
at ontimeout (timers.js:482:11)
at tryOnTimeout (timers.js:317:5)
at Timer.listOnTimeout (timers.js:277:5)
`
Should i try it without  xvfb.stopSync()  ?

Are you running multiple process at a same time? Did the process was complete? I mean, did you get MP4 file output? Yes, you can try  xvfb.stopSync()

No i am running only one process at the same time.
The process didn't complete, there was no MP4 file as output.
I will try without xvfb.stopSync().

That worked!
Thank you!!


docs: add banner for fee token switching

adds banner indicating fee token support will be through AA

Do you think it makes sense to add this banner into the legacy repo? The fact that it's in the legacy would seem to imply that already.  For the HC, I added an intermediary 'placeholder' page where I stuck the banner, and then a link back to the old doc. https://github.com/bobanetwork/boba/pull/161 What do you think?

makes sense, will open one on the main repo!


3850 Improve speed

I have found out that when doing http transfer on 3850s (probably 3650s), it takes forever (denali and up) - mine takes almost 6hours.
Increasing tcp windows size, helps tremendously:
ip tcp window-size<PHONE_NUMBER>
ip tcp path-mtu-discovery

I would try a few window sizes, this is the maximum window size allowed (maybe try/expect and decrease it if there's an IO error - I tried it on a 2960X and it failed a few times, I'll need to do further testing)
Below is an example of the file transfer across the atlantic, only 291.601 seconds, before this it was 5+ hours.
-CSWT02#copy http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>a.SPA.bin flash: Destination filename [cat3k_caa-universalk<IP_ADDRESS>a.SPA.bin]? Accessing http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>a.SPA.bin... Loading http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>a.SPA.bin !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 425928073 bytes copied in 291.601 secs (1460654 bytes/sec)

Thanks for the feedback.
Does ip tcp window-size apply to management traffic, or all traffic?

As far as I know it's only affecting traffic destined to the switch itself.

TCP window size is ideally set to (link bitrate x link latency). Setting a window size too high can cause memory issues, and packet loss will cause more delays.
I can programmatically determine latency with a ping test, but link bandwidth is tricky. I can't infer line rate of attached interface.
Will you run some tests and see what works well for your bandwidth and latency?

In the past, adjusting TCP windows size hasn't consistently worked. This is in the context of SCP transfers using Netmiko.
Some related discussion here:
https://github.com/ktbyers/netmiko/issues/491
I also recently did an upgrade of a couple of IOS-XE devices from 16.08.01 to 16.12.03 using Ansible's net_put and the TCP window size did not make a performance difference (IIRC). It was taking over 3 hours to transfer a 542MB file to the device.
ip ssh bulk-mode in IOS-XE 17 looks interesting (this is from @edurguti )

It would be interesting to get more data on some of these performance problems and workarounds as the default transfer speeds are crazy slow...

@ktbyers My testing on the cat3k series suggests the limit is the control plane CPU. Even plain FTP pegs the CPU at <500Kbps, only a marginal improvement over TFTP.
I looked for a way to force a weaker (and therefore less CPU-intensive) cipher suite for SCP, but didn't turn up anything.

Hi, I just tested again with http:
ip tcp window-size<PHONE_NUMBER> ip tcp path-mtu-discovery
NASGH3850-10-121-CSWT02#copy http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>.SPA.bin flash: Destination filename [cat3k_caa-universalk<IP_ADDRESS>.SPA.bin]?  Accessing http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>.SPA.bin... Loading http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>.SPA.bin !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 450283034 bytes copied in 1268.110 secs (355082 bytes/sec)
NASGH3850-10-121-CSWT02#dir flash: | i 16.09 64643  -rw-   450283034  Jun 16 2020 07:30:46 -05:00  cat3k_caa-universalk<IP_ADDRESS>.SPA.bin
I have another one running without adjusting the tcp window size and it's still going
Below is the latency:
NASGH3850-10-121-CSWT02#ping <IP_ADDRESS> source  vlan  101 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to <IP_ADDRESS>, timeout is 2 seconds: Packet sent with a source address of <IP_ADDRESS>  !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 70/72/80 ms

@edurguti I guess the broader question is--is there any pattern when we can expect changing the TCP window size will work versus when it won't (as it seems to work in some cases, but not in others)?
And I don't really have a good explanation as to why except for some vague "maybe something platform or OS-version specific".
Let me see if I can test on my ISR2 router(s) and see whether your exact change works there or not.

I never had it fail on 3850/3650, but on 2960x it does fail.
Here's how long it took on the one where I didn't change the windows size
NASGH3850-10-120-CSW(config)#end NASGH3850-10-120-CSWT01#copy http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>.SPA.bin flash: Destination filename [cat3k_caa-universalk<IP_ADDRESS>.SPA.bin]?  Accessing http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>.SPA.bin... Loading http://<IP_ADDRESS>/cat3k_caa-universalk<IP_ADDRESS>.SPA.bin !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 450283034 bytes copied in **10066.090** secs (44733 bytes/sec)

@ktbyers @edurguti can either of you post the output of sh proc cpu sort during the transfer?

I took a few while transferring:
NASGH3850-10-121-CSWT02#show processes cpu
Core 0: CPU utilization for five seconds: 6%; one minute: 16%; five
minutes: 10%
Core 1: CPU utilization for five seconds: 0%; one minute: 7%; five minutes:
3%
Core 2: CPU utilization for five seconds: 1%; one minute: 4%; five minutes:
2%
Core 3: CPU utilization for five seconds: 1%; one minute: 2%; five minutes:
2%
Core 4: CPU utilization for five seconds: 0%; one minute: 3%; five minutes:
2%
Core 5: CPU utilization for five seconds: 0%; one minute: 1%; five minutes:
1%
On Tue, Jun 16, 2020 at 5:56 PM Austin de Coup-Crank <
<EMAIL_ADDRESS>wrote:

@ktbyers https://github.com/ktbyers @edurguti
https://github.com/edurguti can either of you post the output of sh
proc cpu sort during the transfer?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/austind/iosfw/issues/2#issuecomment-644853576, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AETQIF2KQXVZW4NIFTILMIDRW6IZDANCNFSM4H4IOZRA
.


Code for mup guide blog

 Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.Nolan Dey seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.You have signed the CLA already but the status is still pending? Let us recheck it.

@Quentin-Anthony resolved your comment and also updated the README

If things look good to you can you disable the CLA protections and merge?

Merged! Woohoo!


Update CI/CD

:tada: This PR is included in version 0.18.0-development.7 :tada:
The release is available on:

npm package (@development dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

:tada: This PR is included in version 0.18.0-rc.1 :tada:
The release is available on:

npm package (@testnet dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


[string-view-lite] Update to 1.7.0

Describe the pull request

What does your PR fix?
Updates string-view-lite to 1.7.0

Which triplets are supported/not supported? Have you updated the CI baseline?
As before, Yes

Does your PR follow the maintainer guide?

Yes

Thanks for the update!


Update UrlAutoConverterTwigExtension.php

Added an exception for the img tag.

thx .. merged this .. but actually I would much rather see this PR finally done https://github.com/liip/LiipUrlAutoConverterBundle/pull/14


responsive-dropdown menu：dropdown menu not showing with relative div under

https://daisyui.com/components/navbar/#responsive-dropdown-menu-on-small-screen-center-menu-on-large-screen
Here is the scene where the problem occurs：https://play.tailwindcss.com/FvLyT7MX8s?layout=horizontal
When I write pc pages, I often use relative positioning on the outer layer, because the background image uses img , and only on the mobile side will the background image be opened with content. Now I don't know how to solve the problem that the drop-down does not display.

https://daisyui.com/components/navbar/#responsive-dropdown-menu-on-small-screen-center-menu-on-large-screen Here is the scene where the problem occurs：https://play.tailwindcss.com/FvLyT7MX8s?layout=horizontal When I write pc pages, I often use relative positioning on the outer layer, because the background image uses img , and only on the mobile side will the background image be opened with content. Now I don't know how to solve the problem that the drop-down does not display.

Beijing time on October 23rd at 13:28 pm：
I have solved this problem，It seems that the relative z-index below is higher than navbar ,so i add z-50 relative in the navbar outside
like this:https://play.tailwindcss.com/BSkvvh2NK4?layout=preview，then it can works


Add parameters to your includes

I started using simple-html-template recently, it's great.
However, it would be even greater if you could pass some parameters to your includes.
Example
index.html
...
<include src="partial/breadcrumb.html" title="Home" />
...

partial/breadcrumb.html
...
<variable name="title" />
...

This would result to Home being displayed inside the breadcrumb partial template.

Interesting. Since I'm beginner in node.js , could you add in proper way the fixes I mentioned in my published issues?  I know they are very simple for advanced users.  Please take a look what I published long time ago in the Issues section

@xdon82 I see no real need to add support for PHP files, since you can already use include in PHP natively. I also can't reproduce your other issue about the Windows platform.

I mix php with html in some files. So If php code is included in html where the header (including menu) is repetive, then it will be changed automatically when I change that included part - body-header.html for instance.
If you have better idea how to do it, please show me an example

or rather i was supposed to say when html is included in php , but the idea is the same...

Use <?php include ('body-header.html'); ?> instead of <include src="body-header.html"/> in your PHP files.
See the official PHP documentation

hmm tbh you are right, I don't know why I made it much more complicated :P
I think i wanted to keep it in one way (the template system) but as you noticed it doesn;t make sense
thx

Thank you guys for the suggestion. Please feel free to create PRs, I am quite busy at work right now, I will take a look when I have the capacity. Thanks!


Update SPL token init to use initialize_account3

There is now a function to init SPL token accounts without requiring the rent account. Would be good to upgrade to use this when possible.
https://github.com/solana-labs/solana-program-library/blob/287c3bedaf5ee5b49983495fd2826e84d35bc561/token/program/src/instruction.rs#L806

Labeling this as blocked since the new version of the spl-token crate has not yet been published on crates.io.

can update init mint as well with initialize_mint2

Since rent is now accessible via Rent::get() (https://github.com/solana-labs/solana/pull/16422), we could do a similar optimization on contexts that use init/init_if_needed with currently require a rent account. That would make it a bit nicer to use too, since adding init without a rent account will result in a compilation error right now.

Can i try to do it ? Pretty new to rust but if its changing methods i might handle that :D

Can i try to do it ? Pretty new to rust but if its changing methods i might handle that :D

Go for it!

Methods don't exist in the latest version on crates.io (3.2.0) as of 11/26

spl-token 3.3.0 is live on mainnet. This is no longer blocked!

spl-token:3.3.0 which introduced initialize_account3 requires solana-program:^1.9.2 so we sill blocked :)
https://crates.io/crates/spl-token/3.3.0/dependencies

Blocked by https://github.com/project-serum/anchor/issues/1669


Device Capability Model exported from IoT Central fails validation in PnPCodeGen

Not sure if it's an issue with IoT Central or an issue with the json schema document, but there seems to be a mismatch.
To reproduce this, we can create a new device template in IoT Central by importing the capability model for the MXChip IoT DevKit. I then exported the capability model and tried to run the "IoT Plug and Play: Generate Device Code Stub" within VS Code.
The error returned is
[ERROR][PnPCodeGen] Invalid content of the capabilityModel, error: Microsoft.Azure.IoT.DigitalTwin.Parser.ModelParserException: Content is not valid

Name=urn:szasDemo:szas_alert_device_v4:1, Id=http://azureiot.com/v1/classes/Interface/contents, Description=Extra Node found.http://azureiot.com/v1/classes/Interface/contents

I managed to fix it by deleting "contents": [], near the bottom of the json document.

Thanks @johnhaire89,
I followed your repro steps but the exported JSON does not include the offending "contents": [].
There was another issue related to support @context with an Array.
Both issues should be fixed now, let me know if you can still repro.

@johnhaire89 have you been able to repro it with the latest version?

closing due to the lack of response. @johnhaire89 if you still reproes this issue, please reactivate.


grammar correction

Description
Made grammatical corrections to the Testimonials page
What
General grammar corrections
Why
Because bad grammar is not cool
Verification Steps
go to about/testimonials and the testimonials are (hopefully) properly edited
Checklist:

[x] This pr is linked to the related trello card
[x] My code follows the style guidelines of this project
[ ] I have requested a code review from (at least) two team members
[ ] I have commented my code, particularly in hard-to-understand areas
[x] I have made corresponding changes to the documentation
[x] This change has been verified by another team member

@evanhearne B R U H

@SinenWew reviewing now, but in future, please use an appropriate message. :)

@SinenWew changes look fine, I will merge this for you now. :)


Issues - xlose connection

When running i get the close connection right after accessing the url. Tried to access different devices
`2017/01/26 00:10:54 <IP_ADDRESS>:62858 200 GET /auth_token.js
2017/01/26 00:10:54 <IP_ADDRESS>:62857 200 GET /js/hterm.js
2017/01/26 00:10:54 <IP_ADDRESS>:62858 200 GET /favicon.png
2017/01/26 00:10:54 <IP_ADDRESS>:62860 200 GET /js/gotty.js
2017/01/26 00:10:54 New client connected: <IP_ADDRESS>:62861
2017/01/26 00:10:54 Command is running for client <IP_ADDRESS>:62861 with PID 5625 (args=""), connections: 1
2017/01/26 00:10:54 <IP_ADDRESS>:62861 101 GET /ws
2017/01/26 00:10:54 Command exited for: <IP_ADDRESS>:62861
2017/01/26 00:10:54 Connection closed: <IP_ADDRESS>:62861, connections: 0
2017/01/26 00:10:54 read tcp <IP_ADDRESS>:3333-><IP_ADDRESS>:62861: use of closed network connection
`

I think connection related issues like this should be fixed in the master branch. Let me know when it still exists.


Video recording is not working

Hello,
I tried your code and photo capturing is working perfectly. But when I tried capture video then first time it capture perfect but when I tried to capture it second time then It is not capturing video.
Then I run your code without changing single line, I got same scenario. First time video capture works, but when I stop debugging and again start then video capturing is not working.
what I found was,When I click button for recording video it goes to "if(!self.camera.isRecording) " condition and when I press same button for stoping video it goes to "else condition" and that is fine.
But when I run app second time then It always go to "if(!self.camera.isRecording) "  condition. It is not going in "else" condition.
if(!self.camera.isRecording) {
//always come here after I run the app for first time. every time it goes to this condition
[self.camera startRecordingWithOutputUrl:outputURL];
}
else {
[self.camera stopRecording:^(LLSimpleCamera *camera, NSURL *outputFileUrl, NSError *error) {
}];
}
I found this error : Error Domain=AVFoundationErrorDomain Code=-11823 "Cannot Save" UserInfo=0x165c36b0 {NSLocalizedRecoverySuggestion=Try saving again., AVErrorRecordingSuccessfullyFinishedKey=false, NSLocalizedDescription=Cannot Save, NSUnderlyingError=0x16514ca0 "The operation couldn’t be completed. (OSStatus error -12672.)"}
I am running your code in iOS 7.1.2 with iPhone4
So How to solve this ?

I found the solution.
Solution is you must remove the path(at which you are recording video) before recording again at same path. That is why It was working fine for first time but from second time It is not. So what I did is
if(!self.camera.isRecording) {
NSString *recordingPath = [ NSTemporaryDirectory<EMAIL_ADDRESS>NSURL *recordingURL = [[NSURL alloc] initFileURLWithPath:recordingPath];
[[NSFileManager defaultManager] removeItemAtURL:recordingURL error:NULL];
[self.camera startRecordingWithOutputUrl:recordingURL];
}
else {
[self.camera stopRecording:^(LLSimpleCamera *camera, NSURL *outputFileUrl, NSError *error) {
}];
}
"[[NSFileManager defaultManager] removeItemAtURL:recordingURL error:NULL];" works for me.''


KMS Auditor Fails on Principal-Service statements

Bad code:
                    if isinstance(statement.get("Principal"), basestring):
                        # Handles the case where the prnciple is *
                        aws_principal = [statement.get("Principal")]
                    else:
                        aws_principal = statement.get("Principal").get("AWS")

Policy that breaks it:
"Principal": {
    "Service": "lightsail.amazonaws.com"
}

Solution should look like this, but prettier:
                    if isinstance(statement.get("Principal"), basestring):
                        # Handles the case where the prnciple is *
                        aws_principal = [statement.get("Principal")]
                    elif 'AWS' in statement['Principal']:
                        aws_principal = statement.get("Principal").get("AWS")
                        # A principal can either be a single ARN in a string, or an array of ARNs
                        if isinstance(aws_principal, basestring):
                            aws_principal = [aws_principal]
                    elif 'Service' in statement['Principal']:
                        aws_principal = statement.get("Principal").get("Service")
                        # A principal can either be a single ARN in a string, or an array of ARNs
                        if isinstance(aws_principal, basestring):
                            aws_principal = [aws_principal]

fixed and merged


Ambrosium torch ITEM should have the name "ambrosium_torch" not "ambrosium_wall_torch"

When this is fixed, recipes and loot tables need to be updated

Can be closed


Update README

Modify to align with testing via metal3-dev-env/BMO

/hold - still WIP pending e2e testing and resolution of the FIXME re rootfs


Support MODULE.bazel

Noticed when working on https//github.com/bazelbuild/rules_python, that the CI was failing because MODULE.bazel is not autoformatted by buildifier when using these hooks.

Hey @keith, is this something you could take a look at?


bpf: check for cilium-map-migrate instead of cilium CLI client in ini…

The cilium CLI is no longer used by init.sh since commit 1c18d1da0526
("cache: Support looking up reserved identities"). Instead check for
cilium-map-migrate which is used in several places.

test-me-please

Coverage decreased (-0.01%) to 45.589% when pulling 3fb22e0ef2ee6655de359621855fdfddae908968 on pr/tklauser/bpf-init-remove-cilium-cli-check into cf0f9de5b2575d4b6e4fd6e49b68961c032e6a29 on master.


Fixed Link

Fixed a beta.docs.qmk.fm link since those are not working anymore.
Replaced:
https://beta.docs.qmk.fm/using-qmk/guides/flashing/flashing
with
https://docs.qmk.fm/#/flashing

Thanks for adjusting this.
There are also QMK documentation links in guide.md, it would be awesome if you could also fix those?

Done, I think at least.
I thought this would be a quick edit and tried to edit everthing via Github Web GUI.


actively monitor the power status of each host

The baremetal operator should actively monitor the power on each host to ensure it matches the desired state.
We should show the power status of each host as one of:

powering on
powered on
powering off
powered off

And we should adjust the power state when it does not match what the CRD shows the user wanted.

Basic power management was done in #93, without the change to 4 power state values.


Add Token Counter Displayer in Repl

Add Token Counter Displayer

[x] Create new Repl output type called notification output.
[x] Add new hasTokenCounter and customNotification properties to workspace.
[x] Import Acorn dependency to count tokens in user's program.
[x] Display token counter in Repl conditionally depending on assessment configurations.
[x] Add new BooleanCell in admin panel to toggle token counter feature.
[ ] Fix testcases.

Note that modifying custom notifications hasn't been implemented yet (possible future updates).

Co-authored-by: Lau Xiang Yu

Pull Request Test Coverage Report for Build<PHONE_NUMBER>
Details

-14 of 39 (64.1%)  changed or added relevant lines in 7 files are covered.
No unchanged relevant lines lost coverage.
Overall coverage increased (+0.05%) to 37.248%

Changes Missing Coverage
Covered Lines
Changed/Added Lines
%

src/commons/repl/Repl.tsx
0
1
0.0%

src/commons/workspace/WorkspaceActions.ts
5
6
83.33%

src/commons/assessmentWorkspace/AssessmentWorkspace.tsx
5
7
71.43%

src/commons/workspace/WorkspaceReducer.ts
7
12
58.33%

src/pages/academy/adminPanel/subcomponents/assessmentConfigPanel/AssessmentConfigPanel.tsx
0
5
0.0%

Totals

Change from base Build<PHONE_NUMBER>:
0.05%

Covered Lines:
5746

Relevant Lines:
14499

💛  - Coveralls

Corresponding backend PR: https://github.com/source-academy/backend/pull/1062


[Bug] 2-setup-azure-environment.yml Error

Summary
The environment should use 'with' not 'env' from line 84 to line 100. I kept facing this issue wondering why environment variables weren't being set
How to reproduce
Prereq: On Mac

Following all Instructions beginning this Lab
Upon Editing the deployment file with your username Github Actions will run and give you this Error

Screenshots

SOLUTION
I changed the lines 84 - 100 for 'env' -> 'with' in 2-setup-azure-environment.yml and it resolved the issue.

This was also resolved with #38 by changing the path in pull-main.sh to initialize-repository.sh

This was also resolved with #38 by changing the path in pull-main.sh to initialize-repository.sh

I had a permission denied error after changing the name to initialize-repository.sh.
I resolved it by adding an extra command
      - name: Pull main
        run: |
          chmod +x ./.github/script/initialize-repository.sh
          ./.github/script/initialize-repository.sh
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

This was also resolved with #38 by changing the path in pull-main.sh to initialize-repository.sh

Sounds like this solved it so I'll close it out but please reopen if I misunderstood.


chore(actions): enforce new changelog format and convention

This ticket make sure new changelog entries submitted adheres to the changelog standard to avoid conflicts like CHANGELOG from slipping in.

I checked the results with some fake commits (https://github.com/Kong/kong/pull/11757/commits), these checks seems to work.


Allow icon on top when content is placed inside an anchor

Allows the "icon-on-top" theme to work when surrounding the content with an anchor, like this
          <vaadin-tab theme="icon-on-top">

              <iron-icon icon="lumo:user"></iron-icon>
              Tab one

          </vaadin-tab>

Related to vaadin/vaadin-app-layout#48

This change is

Thanks for looking into this @web-padawan. Yes, that PR does fix the issue. Can you reopen and consider merging it then?

I have submitted #121 and we will discuss it.
The only problem for now is that slotted <iron-icon> cannot be styled when wrapped in  tag at all, due to the ::slotted selector limitations. It should be ok for icon-on-top but will affect normal tabs, so there margin will not apply to the icon.
@jouni what would you prefer? Should we support ::slotted(a) for icon-on-top theme only?

Closing in favor of #121, let's continue the discussion there.


drop PRM api calls

https://github.com/edenlabllc/ehealth.api/issues/735
https://github.com/edenlabllc/ehealth.api/issues/856

Changes Unknown when pulling b0ddb3753110a865362fa1babb370e813955b0ab on merge_prm into ** on master**.

Changes Unknown when pulling abe0b65ad48d5131424d0387ca1a59dc89a07874 on merge_prm into ** on master**.

Changes Unknown when pulling e1e365872d4aba9fd2ea7bfcc11c72fbcad33273 on merge_prm into ** on master**.

Changes Unknown when pulling 9f66f042a7342f35ac272f91334ef03621b6bec6 on merge_prm into ** on master**.

Changes Unknown when pulling<PHONE_NUMBER>80afe3e0b4aae884a41e38690bd706 on merge_prm into ** on master**.

Changes Unknown when pulling ecc7fcf2563f3e9db89bc54fa99a32fd48f734d4 on merge_prm into ** on master**.

Changes Unknown when pulling a82dfac884c6295989f4b5677771127a98a9f72d on merge_prm into ** on master**.

Changes Unknown when pulling 60488dc1617b4b5863d533fce759f8d6c1756094 on merge_prm into ** on master**.

Changes Unknown when pulling 90982469fa8d51574918531127f2e1ff69cb820a on merge_prm into ** on master**.

Changes Unknown when pulling 148aa58e5212ef32668e86cc61fd60510b1119f7 on merge_prm into ** on master**.

Changes Unknown when pulling 17fd25d53d5c3a7e0efafa014975ed2c3bd2ebb9 on merge_prm into ** on master**.

Changes Unknown when pulling 310e0ffacbbfbab192b09e426cf5a1418726d222 on merge_prm into ** on master**.

Changes Unknown when pulling 8caeaf9db0c56f26a35f88cc9596e24fb1c6aa6a on merge_prm into ** on master**.

Changes Unknown when pulling 735b19ce4c4a7fb84c217a3507a76b0eada2c6a0 on merge_prm into ** on master**.

Coverage increased (+3.04%) to 83.818% when pulling 5419eab6060d8f377e7da1a6d46c00838e22d275 on merge_prm into 322e2ef9dc5e8dd42fc12c3c8db8105882772f50 on master.

Changes Unknown when pulling 9ae2c46890c012db9a36d23d96c1254daedef0ed on merge_prm into ** on master**.

Changes Unknown when pulling 7a568e84c9d0e7f37f66dd7042fed43fe7c13142 on merge_prm into ** on master**.

Changes Unknown when pulling 528d43d65752996e60916fe40fdbe06f92a149ba on merge_prm into ** on master**.

Changes Unknown when pulling fc0c8e34425921e97c2c62096af4b11a78a301f7 on merge_prm into ** on master**.

Changes Unknown when pulling 61c63cf348c62d278736b202989d8330d5f2f622 on merge_prm into ** on master**.

Changes Unknown when pulling 6efc277c44571d75bcf6e0ee4e48555d1be62fff on merge_prm into ** on master**.

Changes Unknown when pulling 8a540e00cff34a1a6a196f411348b7ce16ff946d on merge_prm into ** on master**.

Changes Unknown when pulling b76b1732f037ecda415f03e600bf900b51f58b96 on merge_prm into ** on master**.

Changes Unknown when pulling a201e61f48aff169d40c1277abf1d18feb317a3e on merge_prm into ** on master**.

Changes Unknown when pulling 45725a093f87373d4570f05b64d2b25786dbc8d0 on merge_prm into ** on master**.

Changes Unknown when pulling 1889ae96a6bb7e407d7a7911c6f9d07ff5a9e132 on merge_prm into ** on master**.

Changes Unknown when pulling 1ad122e300378680d6e9277a978d024f2d5a647e on merge_prm into ** on master**.

Changes Unknown when pulling 0a091b1f8058c9330b761f9bdb0f390c26b471f9 on merge_prm into ** on master**.

Changes Unknown when pulling a4950ce980c63a23cf576a8fe73845a26c4167ce on merge_prm into ** on master**.

Changes Unknown when pulling 2a55145f7cd916fdc50d65bc6cac63aad8a5c05a on merge_prm into ** on master**.

Changes Unknown when pulling 2a5468b5aa36b51891fd02a3ca0e273a20f6943a on merge_prm into ** on master**.

🎉