newRegistry

The newRegistry method provides a utility to manage and clean up resources or subscriptions, ensuring all registered tasks are executed and handling any errors during the cleanup process.

Implementation
function newRegistry<E = unknown>(
  onError: (error: E) => void = console.error,
): [
  register: (callback?: () => void | Promise<void>) => () => Promise<void>,
  cleanup: () => Promise<void>,
] {
  const registrationsIndex: {
    [registrationId: number]: () => Promise<void>;
  } = {};
  let registrationId = 0;
  return [
    function register(
      listener?: () => void | Promise<void>,
    ): () => Promise<void> {
      const id = registrationId++;
      return (registrationsIndex[id] = async () => {
        delete registrationsIndex[id];
        try {
          await listener?.();
        } catch (e) {
          onError(e as E);
        }
      });
    },
    async function cleanup(): Promise<void> {
      await Promise.all(
        Object.values(registrationsIndex).map((registration) => registration()),
      );
    },
  ];
}

Examples

// Create a registry
const [register, cleanup] = newRegistry<string>((error) =>
  console.error("Cleanup error:", error)
);

// Register a cleanup task
const unregister = register(async () => {
  console.log("Cleaning up task 1...");
  // Simulate an asynchronous cleanup task
  await new Promise((resolve) => setTimeout(resolve, 1000));
  console.log("Task 1 cleaned up!");
});

// Register another cleanup task
register(() => {
  console.log("Cleaning up task 2...");
});

// Execute a single cleanup task and unregister it
unregister().then(() => {
  console.log("Task 1 manually cleaned up!");
});

// Execute all remaining cleanup tasks
cleanup().then(() => {
  console.log("All tasks cleaned up!");
});

Signature

function newRegistry<E = unknown>(
  onError: (error: E) => void = console.error
): [
  register: (callback?: () => void | Promise<void>) => () => Promise<void>,
  cleanup: () => Promise<void>
]

Parameters

Returns

A tuple containing two functions:

  1. register: Registers a cleanup callback function.
    Type: (callback?: () => void | Promise<void>) => () => Promise<void>
    • Input: A callback function to be invoked during cleanup. It can be synchronous or asynchronous.
    • Output: A function that, when called, will execute the registered callback and remove it from the registry.
  2. cleanup: Executes and clears all registered cleanup functions in the order they were registered.
    Type: () => Promise<void>

Behavior Details