pure
    Preparing search index...
    • An async event wrapper that ensures an async initialization is only ran once. Any subsequent calls after the first call will return a promise that resolves/rejects with the result of the first call.

      import { once } from "@pistonite/pure/sync";

      const getLuckyNumber = once({
      fn: async () => {
      console.log("running expensive initialization...")
      await new Promise((resolve) => setTimeout(resolve, 100));
      console.log("done")
      return 42;
      }
      });

      const result1 = getLuckyNumber();
      const result2 = getLuckyNumber();
      console.log(await result1);
      console.log(await result2);
      // logs:
      // running expensive initialization...
      // done
      // 42
      // 42

      Some initialization might require clean up, such as unregister event handlers and/or timers. In this case, a production build might work fine but a HMR (Hot Module Reload) development server might not do this for you automatically.

      One way to work around this during development is to store the cleanup as a global object

      const getResourceThatNeedsCleanup = once({
      fn: async () => {
      if (__DEV__) { // Configure your bundler to inject this
      // await if you need async clean up
      await (window as any).cleanupMyResource?.();
      }

      let resource: MyResource;
      if (__DEV__) {
      (window as any).cleanupMyResource = async () => {
      await resource?.cleanup();
      };
      }

      resource = await initResource();
      return resource;
      }
      });

      An alternative solution is to not use once but instead tie the initialization of the resource to some other lifecycle event that gets cleaned up during HMR. For example, A framework that supports HMR for React components might unmount the component before reloading, which gives you a chance to clean up the resource.

      This is not an issue if the resource doesn't leak other resources, since it will eventually be GC'd.

      Type Parameters

      Parameters

      Returns (...args: Parameters<TFn>) => Promise<AwaitRet<TFn>>