@xylabs/forget 6.0.2 → 6.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ForgetPromise.d.ts","sourceRoot":"","sources":["../../src/ForgetPromise.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE1E,kDAAkD;AAClD,KAAK,kBAAkB,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,CAAA;AAEhD;;GAEG;AAEH,qBAAa,aAAa;IACxB,kEAAkE;IAClE,MAAM,CAAC,aAAa,SAAI;IACxB,0DAA0D;IAC1D,MAAM,CAAC,eAAe,SAAI;IAC1B,yDAAyD;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAU;IAE/B,uDAAuD;IACvD,MAAM,KAAK,MAAM,YAEhB;IAED;;;;;OAKG;WACU,aAAa,CAAC,QAAQ,SAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAc3D,2EAA2E;IAC3E,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;IAOzF;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IA+DzG,gFAAgF;IAChF,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAgB,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;CAMpG"}
1
+ {"version":3,"file":"ForgetPromise.d.ts","sourceRoot":"","sources":["../../src/ForgetPromise.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE1E,kDAAkD;AAClD,KAAK,kBAAkB,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,CAAA;AAEhD;;GAEG;AAEH,qBAAa,aAAa;IACxB,kEAAkE;IAClE,MAAM,CAAC,aAAa,SAAI;IACxB,0DAA0D;IAC1D,MAAM,CAAC,eAAe,SAAI;IAC1B,yDAAyD;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAU;IAE/B,uDAAuD;IACvD,MAAM,KAAK,MAAM,YAEhB;IAED;;;;;OAKG;WACU,aAAa,CAAC,QAAQ,SAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAc3D,2EAA2E;IAC3E,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;IAOzF;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAgEzG,gFAAgF;IAChF,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAgB,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;CAMpG"}
@@ -71,10 +71,11 @@ var ForgetPromise = class {
71
71
  completed = true;
72
72
  resolvedConfig?.onComplete?.([result, void 0]);
73
73
  }).catch((error) => {
74
+ const caughtError = error instanceof Error ? error : new Error(String(error));
74
75
  this.activeForgets--;
75
76
  completed = true;
76
- this.logger.error(`forgotten promise excepted [${config?.name ?? "unknown"}]: ${error.message}`, error);
77
- resolvedConfig?.onComplete?.([void 0, error]);
77
+ this.logger.error(`forgotten promise excepted [${config?.name ?? "unknown"}]: ${caughtError.message}`, caughtError);
78
+ resolvedConfig?.onComplete?.([void 0, caughtError]);
78
79
  });
79
80
  };
80
81
  const promises = [promiseWrapper()];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/ForgetConfig.ts", "../../src/ForgetNodeConfig.ts", "../../src/ForgetPromise.ts", "../../src/ForgetPromiseNode.ts", "../../src/forgetNode.ts"],
4
- "sourcesContent": ["/**\n * Configuration options for fire-and-forget promises.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetConfig<T = any> {\n /** Optional name for identifying the forgotten promise in logs. */\n name?: string\n /** Called when the promise is cancelled due to timeout. */\n onCancel?: () => void\n /** Called when the promise completes, with a tuple of [result, error]. */\n onComplete?: (result: [T | undefined, Error | undefined]) => void\n /** Called when an exception occurs outside the promise itself. */\n onException?: (error: Error) => void\n /** Timeout in milliseconds after which the promise is considered timed out. */\n timeout?: number\n}\n\n/** Default forget configuration with a 30-second timeout. */\nexport const defaultForgetConfig: ForgetConfig<unknown> = { timeout: 30_000 }\n", "import { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/**\n * Node.js-specific forget configuration that extends ForgetConfig with process termination options.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetNodeConfig<T = any> extends ForgetConfig<T> {\n /** Terminate the process on an exception that happens outside of the promise being forgotten. */\n terminateOnException?: boolean\n /** Terminate the process if the promise times out. */\n terminateOnTimeout?: boolean\n}\n\n/** Default Node.js forget configuration with termination disabled. */\nexport const defaultForgetNodeConfig: ForgetNodeConfig<unknown> = {\n ...defaultForgetConfig,\n terminateOnTimeout: false,\n terminateOnException: false,\n}\n", "import { delay } from '@xylabs/delay'\nimport type { Logger } from '@xylabs/logger'\nimport type { Promisable, PromiseEx } from '@xylabs/promise'\nimport { isNumber, isPromise } from '@xylabs/typeof'\n\nimport { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/** A function that returns a promisable value. */\ntype PromisableFunction<T> = () => Promisable<T>\n\n/**\n * Manages fire-and-forget promises with tracking, timeouts, and error handling.\n */\n// eslint-disable-next-line unicorn/no-static-only-class\nexport class ForgetPromise {\n /** Number of currently active (unresolved) forgotten promises. */\n static activeForgets = 0\n /** Number of forgotten promises that threw exceptions. */\n static exceptedForgets = 0\n /** Logger instance used for error and warning output. */\n static logger: Logger = console\n\n /** Whether any forgotten promises are still active. */\n static get active() {\n return this.activeForgets > 0\n }\n\n /**\n * Waits until all forgotten promises have completed.\n * @param interval - Polling interval in milliseconds.\n * @param timeout - Optional maximum wait time in milliseconds.\n * @returns The number of remaining active forgets (0 if all completed).\n */\n static async awaitInactive(interval = 100, timeout?: number) {\n let timeoutRemaining = timeout\n while (this.active) {\n await delay(interval)\n if (timeoutRemaining !== undefined) {\n timeoutRemaining -= interval\n if (timeoutRemaining <= 0) {\n return this.activeForgets\n }\n }\n }\n return 0\n }\n\n /** Handles exceptions from forgotten promises by logging error details. */\n static exceptionHandler(error: Error, { name }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise handler excepted [${name}]: ${error.message}`, error)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n\n /**\n * Used to explicitly launch an async function (or Promise) with awaiting it\n * @param promise The promise to forget\n * @param config Configuration of forget settings\n */\n static forget<T>(promise: Promise<T> | PromiseEx<T> | PromisableFunction<T> | T, config?: ForgetConfig<T>) {\n const externalStackTrace = (new Error('Stack')).stack\n\n // default | global | provided priorities for config (not deep merge)\n const resolvedConfig = {\n ...defaultForgetConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n const resolvedPromise = typeof promise === 'function' ? (promise as PromisableFunction<T>)() : promise\n if (isPromise(resolvedPromise)) {\n try {\n let completed = false\n this.activeForgets++\n\n const promiseWrapper = async () => {\n await resolvedPromise\n .then((result: T) => {\n this.activeForgets--\n completed = true\n resolvedConfig?.onComplete?.([result, undefined])\n })\n .catch((error) => {\n this.activeForgets--\n completed = true\n this.logger.error(`forgotten promise excepted [${config?.name ?? 'unknown'}]: ${error.message}`, error)\n resolvedConfig?.onComplete?.([undefined, error])\n })\n }\n\n const promises = [promiseWrapper()]\n\n // if there is a timeout, add it to the race\n const timeout = resolvedConfig.timeout ?? defaultForgetConfig.timeout\n if (isNumber(timeout)) {\n const timeoutFunc = async () => {\n await delay(timeout)\n if (!completed) {\n resolvedConfig.onCancel?.()\n this.timeoutHandler(timeout, resolvedConfig, externalStackTrace)\n }\n }\n promises.push(timeoutFunc())\n }\n\n const all = Promise.race(promises)\n\n all\n .then(() => {\n return\n })\n .catch(() => {\n return\n })\n } catch (ex) {\n this.exceptedForgets += 1\n resolvedConfig?.onException?.(ex as Error)\n this.exceptionHandler(ex as Error, resolvedConfig, externalStackTrace)\n }\n } else {\n // we do nothing here since if it was a non-promise, it already got invoked.\n return\n }\n }\n\n /** Handles timeout events for forgotten promises by logging timeout details. */\n static timeoutHandler(time: number, { name = 'unknown' }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise timeout out after ${time}ms [Cancelling] [${name}]`)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n}\n", "/// <reference types=\"node\" />\n\nimport type { Promisable } from '@xylabs/promise'\n\nimport { defaultForgetNodeConfig, type ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromise } from './ForgetPromise.ts'\n\n/**\n * Node.js extension of ForgetPromise that can terminate the process on exceptions or timeouts.\n */\nexport class ForgetPromiseNode extends ForgetPromise {\n /** Handles exceptions, optionally terminating the process based on config. */\n static override exceptionHandler(error: Error, config: ForgetNodeConfig, externalStackTrace?: string) {\n // default | global | provided priorities for config (not deep merge)\n super.exceptionHandler(error, config, externalStackTrace)\n if (config?.terminateOnException === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1)\n }\n }\n\n /** Forgets a promise using Node.js-specific configuration with process termination support. */\n static override forget<T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) {\n const resolvedConfig = {\n ...defaultForgetNodeConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n super.forget(promise, resolvedConfig)\n }\n\n /** Handles timeouts, optionally terminating the process based on config. */\n static override timeoutHandler(time: number, config: ForgetNodeConfig, externalStackTrace?: string) {\n super.timeoutHandler(time, config, externalStackTrace)\n if (config?.terminateOnTimeout === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(2)\n }\n }\n}\n", "import { type Promisable } from '@xylabs/promise'\n\nimport type { ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromiseNode } from './ForgetPromiseNode.ts'\n\n/**\n * Node.js variant of forget that can optionally terminate the process on exceptions or timeouts.\n * @param promise - The promise or promisable value to forget.\n * @param config - Optional Node.js-specific configuration including process termination options.\n */\nexport const forgetNode = <T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) => {\n ForgetPromiseNode.forget<T>(promise, config)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Configuration options for fire-and-forget promises.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetConfig<T = any> {\n /** Optional name for identifying the forgotten promise in logs. */\n name?: string\n /** Called when the promise is cancelled due to timeout. */\n onCancel?: () => void\n /** Called when the promise completes, with a tuple of [result, error]. */\n onComplete?: (result: [T | undefined, Error | undefined]) => void\n /** Called when an exception occurs outside the promise itself. */\n onException?: (error: Error) => void\n /** Timeout in milliseconds after which the promise is considered timed out. */\n timeout?: number\n}\n\n/** Default forget configuration with a 30-second timeout. */\nexport const defaultForgetConfig: ForgetConfig<unknown> = { timeout: 30_000 }\n", "import { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/**\n * Node.js-specific forget configuration that extends ForgetConfig with process termination options.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetNodeConfig<T = any> extends ForgetConfig<T> {\n /** Terminate the process on an exception that happens outside of the promise being forgotten. */\n terminateOnException?: boolean\n /** Terminate the process if the promise times out. */\n terminateOnTimeout?: boolean\n}\n\n/** Default Node.js forget configuration with termination disabled. */\nexport const defaultForgetNodeConfig: ForgetNodeConfig<unknown> = {\n ...defaultForgetConfig,\n terminateOnTimeout: false,\n terminateOnException: false,\n}\n", "import { delay } from '@xylabs/delay'\nimport type { Logger } from '@xylabs/logger'\nimport type { Promisable, PromiseEx } from '@xylabs/promise'\nimport { isNumber, isPromise } from '@xylabs/typeof'\n\nimport { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/** A function that returns a promisable value. */\ntype PromisableFunction<T> = () => Promisable<T>\n\n/**\n * Manages fire-and-forget promises with tracking, timeouts, and error handling.\n */\n// eslint-disable-next-line unicorn/no-static-only-class\nexport class ForgetPromise {\n /** Number of currently active (unresolved) forgotten promises. */\n static activeForgets = 0\n /** Number of forgotten promises that threw exceptions. */\n static exceptedForgets = 0\n /** Logger instance used for error and warning output. */\n static logger: Logger = console\n\n /** Whether any forgotten promises are still active. */\n static get active() {\n return this.activeForgets > 0\n }\n\n /**\n * Waits until all forgotten promises have completed.\n * @param interval - Polling interval in milliseconds.\n * @param timeout - Optional maximum wait time in milliseconds.\n * @returns The number of remaining active forgets (0 if all completed).\n */\n static async awaitInactive(interval = 100, timeout?: number) {\n let timeoutRemaining = timeout\n while (this.active) {\n await delay(interval)\n if (timeoutRemaining !== undefined) {\n timeoutRemaining -= interval\n if (timeoutRemaining <= 0) {\n return this.activeForgets\n }\n }\n }\n return 0\n }\n\n /** Handles exceptions from forgotten promises by logging error details. */\n static exceptionHandler(error: Error, { name }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise handler excepted [${name}]: ${error.message}`, error)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n\n /**\n * Used to explicitly launch an async function (or Promise) with awaiting it\n * @param promise The promise to forget\n * @param config Configuration of forget settings\n */\n static forget<T>(promise: Promise<T> | PromiseEx<T> | PromisableFunction<T> | T, config?: ForgetConfig<T>) {\n const externalStackTrace = (new Error('Stack')).stack\n\n // default | global | provided priorities for config (not deep merge)\n const resolvedConfig = {\n ...defaultForgetConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n const resolvedPromise = typeof promise === 'function' ? (promise as PromisableFunction<T>)() : promise\n if (isPromise(resolvedPromise)) {\n try {\n let completed = false\n this.activeForgets++\n\n const promiseWrapper = async () => {\n await resolvedPromise\n .then((result: T) => {\n this.activeForgets--\n completed = true\n resolvedConfig?.onComplete?.([result, undefined])\n })\n .catch((error: unknown) => {\n const caughtError = error instanceof Error ? error : new Error(String(error))\n this.activeForgets--\n completed = true\n this.logger.error(`forgotten promise excepted [${config?.name ?? 'unknown'}]: ${caughtError.message}`, caughtError)\n resolvedConfig?.onComplete?.([undefined, caughtError])\n })\n }\n\n const promises = [promiseWrapper()]\n\n // if there is a timeout, add it to the race\n const timeout = resolvedConfig.timeout ?? defaultForgetConfig.timeout\n if (isNumber(timeout)) {\n const timeoutFunc = async () => {\n await delay(timeout)\n if (!completed) {\n resolvedConfig.onCancel?.()\n this.timeoutHandler(timeout, resolvedConfig, externalStackTrace)\n }\n }\n promises.push(timeoutFunc())\n }\n\n const all = Promise.race(promises)\n\n all\n .then(() => {\n return\n })\n .catch(() => {\n return\n })\n } catch (ex) {\n this.exceptedForgets += 1\n resolvedConfig?.onException?.(ex as Error)\n this.exceptionHandler(ex as Error, resolvedConfig, externalStackTrace)\n }\n } else {\n // we do nothing here since if it was a non-promise, it already got invoked.\n return\n }\n }\n\n /** Handles timeout events for forgotten promises by logging timeout details. */\n static timeoutHandler(time: number, { name = 'unknown' }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise timeout out after ${time}ms [Cancelling] [${name}]`)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n}\n", "/// <reference types=\"node\" />\n\nimport type { Promisable } from '@xylabs/promise'\n\nimport { defaultForgetNodeConfig, type ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromise } from './ForgetPromise.ts'\n\n/**\n * Node.js extension of ForgetPromise that can terminate the process on exceptions or timeouts.\n */\nexport class ForgetPromiseNode extends ForgetPromise {\n /** Handles exceptions, optionally terminating the process based on config. */\n static override exceptionHandler(error: Error, config: ForgetNodeConfig, externalStackTrace?: string) {\n // default | global | provided priorities for config (not deep merge)\n super.exceptionHandler(error, config, externalStackTrace)\n if (config?.terminateOnException === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1)\n }\n }\n\n /** Forgets a promise using Node.js-specific configuration with process termination support. */\n static override forget<T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) {\n const resolvedConfig = {\n ...defaultForgetNodeConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n super.forget(promise, resolvedConfig)\n }\n\n /** Handles timeouts, optionally terminating the process based on config. */\n static override timeoutHandler(time: number, config: ForgetNodeConfig, externalStackTrace?: string) {\n super.timeoutHandler(time, config, externalStackTrace)\n if (config?.terminateOnTimeout === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(2)\n }\n }\n}\n", "import { type Promisable } from '@xylabs/promise'\n\nimport type { ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromiseNode } from './ForgetPromiseNode.ts'\n\n/**\n * Node.js variant of forget that can optionally terminate the process on exceptions or timeouts.\n * @param promise - The promise or promisable value to forget.\n * @param config - Optional Node.js-specific configuration including process termination options.\n */\nexport const forgetNode = <T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) => {\n ForgetPromiseNode.forget<T>(promise, config)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ForgetPromise.d.ts","sourceRoot":"","sources":["../../src/ForgetPromise.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE1E,kDAAkD;AAClD,KAAK,kBAAkB,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,CAAA;AAEhD;;GAEG;AAEH,qBAAa,aAAa;IACxB,kEAAkE;IAClE,MAAM,CAAC,aAAa,SAAI;IACxB,0DAA0D;IAC1D,MAAM,CAAC,eAAe,SAAI;IAC1B,yDAAyD;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAU;IAE/B,uDAAuD;IACvD,MAAM,KAAK,MAAM,YAEhB;IAED;;;;;OAKG;WACU,aAAa,CAAC,QAAQ,SAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAc3D,2EAA2E;IAC3E,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;IAOzF;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IA+DzG,gFAAgF;IAChF,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAgB,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;CAMpG"}
1
+ {"version":3,"file":"ForgetPromise.d.ts","sourceRoot":"","sources":["../../src/ForgetPromise.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAG5D,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE1E,kDAAkD;AAClD,KAAK,kBAAkB,CAAC,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,CAAA;AAEhD;;GAEG;AAEH,qBAAa,aAAa;IACxB,kEAAkE;IAClE,MAAM,CAAC,aAAa,SAAI;IACxB,0DAA0D;IAC1D,MAAM,CAAC,eAAe,SAAI;IAC1B,yDAAyD;IACzD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAU;IAE/B,uDAAuD;IACvD,MAAM,KAAK,MAAM,YAEhB;IAED;;;;;OAKG;WACU,aAAa,CAAC,QAAQ,SAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAc3D,2EAA2E;IAC3E,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;IAOzF;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAgEzG,gFAAgF;IAChF,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAgB,EAAE,EAAE,YAAY,EAAE,kBAAkB,CAAC,EAAE,MAAM;CAMpG"}
@@ -71,10 +71,11 @@ var ForgetPromise = class {
71
71
  completed = true;
72
72
  resolvedConfig?.onComplete?.([result, void 0]);
73
73
  }).catch((error) => {
74
+ const caughtError = error instanceof Error ? error : new Error(String(error));
74
75
  this.activeForgets--;
75
76
  completed = true;
76
- this.logger.error(`forgotten promise excepted [${config?.name ?? "unknown"}]: ${error.message}`, error);
77
- resolvedConfig?.onComplete?.([void 0, error]);
77
+ this.logger.error(`forgotten promise excepted [${config?.name ?? "unknown"}]: ${caughtError.message}`, caughtError);
78
+ resolvedConfig?.onComplete?.([void 0, caughtError]);
78
79
  });
79
80
  };
80
81
  const promises = [promiseWrapper()];
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/ForgetConfig.ts", "../../src/ForgetNodeConfig.ts", "../../src/ForgetPromise.ts", "../../src/ForgetPromiseNode.ts", "../../src/forgetNode.ts"],
4
- "sourcesContent": ["/**\n * Configuration options for fire-and-forget promises.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetConfig<T = any> {\n /** Optional name for identifying the forgotten promise in logs. */\n name?: string\n /** Called when the promise is cancelled due to timeout. */\n onCancel?: () => void\n /** Called when the promise completes, with a tuple of [result, error]. */\n onComplete?: (result: [T | undefined, Error | undefined]) => void\n /** Called when an exception occurs outside the promise itself. */\n onException?: (error: Error) => void\n /** Timeout in milliseconds after which the promise is considered timed out. */\n timeout?: number\n}\n\n/** Default forget configuration with a 30-second timeout. */\nexport const defaultForgetConfig: ForgetConfig<unknown> = { timeout: 30_000 }\n", "import { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/**\n * Node.js-specific forget configuration that extends ForgetConfig with process termination options.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetNodeConfig<T = any> extends ForgetConfig<T> {\n /** Terminate the process on an exception that happens outside of the promise being forgotten. */\n terminateOnException?: boolean\n /** Terminate the process if the promise times out. */\n terminateOnTimeout?: boolean\n}\n\n/** Default Node.js forget configuration with termination disabled. */\nexport const defaultForgetNodeConfig: ForgetNodeConfig<unknown> = {\n ...defaultForgetConfig,\n terminateOnTimeout: false,\n terminateOnException: false,\n}\n", "import { delay } from '@xylabs/delay'\nimport type { Logger } from '@xylabs/logger'\nimport type { Promisable, PromiseEx } from '@xylabs/promise'\nimport { isNumber, isPromise } from '@xylabs/typeof'\n\nimport { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/** A function that returns a promisable value. */\ntype PromisableFunction<T> = () => Promisable<T>\n\n/**\n * Manages fire-and-forget promises with tracking, timeouts, and error handling.\n */\n// eslint-disable-next-line unicorn/no-static-only-class\nexport class ForgetPromise {\n /** Number of currently active (unresolved) forgotten promises. */\n static activeForgets = 0\n /** Number of forgotten promises that threw exceptions. */\n static exceptedForgets = 0\n /** Logger instance used for error and warning output. */\n static logger: Logger = console\n\n /** Whether any forgotten promises are still active. */\n static get active() {\n return this.activeForgets > 0\n }\n\n /**\n * Waits until all forgotten promises have completed.\n * @param interval - Polling interval in milliseconds.\n * @param timeout - Optional maximum wait time in milliseconds.\n * @returns The number of remaining active forgets (0 if all completed).\n */\n static async awaitInactive(interval = 100, timeout?: number) {\n let timeoutRemaining = timeout\n while (this.active) {\n await delay(interval)\n if (timeoutRemaining !== undefined) {\n timeoutRemaining -= interval\n if (timeoutRemaining <= 0) {\n return this.activeForgets\n }\n }\n }\n return 0\n }\n\n /** Handles exceptions from forgotten promises by logging error details. */\n static exceptionHandler(error: Error, { name }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise handler excepted [${name}]: ${error.message}`, error)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n\n /**\n * Used to explicitly launch an async function (or Promise) with awaiting it\n * @param promise The promise to forget\n * @param config Configuration of forget settings\n */\n static forget<T>(promise: Promise<T> | PromiseEx<T> | PromisableFunction<T> | T, config?: ForgetConfig<T>) {\n const externalStackTrace = (new Error('Stack')).stack\n\n // default | global | provided priorities for config (not deep merge)\n const resolvedConfig = {\n ...defaultForgetConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n const resolvedPromise = typeof promise === 'function' ? (promise as PromisableFunction<T>)() : promise\n if (isPromise(resolvedPromise)) {\n try {\n let completed = false\n this.activeForgets++\n\n const promiseWrapper = async () => {\n await resolvedPromise\n .then((result: T) => {\n this.activeForgets--\n completed = true\n resolvedConfig?.onComplete?.([result, undefined])\n })\n .catch((error) => {\n this.activeForgets--\n completed = true\n this.logger.error(`forgotten promise excepted [${config?.name ?? 'unknown'}]: ${error.message}`, error)\n resolvedConfig?.onComplete?.([undefined, error])\n })\n }\n\n const promises = [promiseWrapper()]\n\n // if there is a timeout, add it to the race\n const timeout = resolvedConfig.timeout ?? defaultForgetConfig.timeout\n if (isNumber(timeout)) {\n const timeoutFunc = async () => {\n await delay(timeout)\n if (!completed) {\n resolvedConfig.onCancel?.()\n this.timeoutHandler(timeout, resolvedConfig, externalStackTrace)\n }\n }\n promises.push(timeoutFunc())\n }\n\n const all = Promise.race(promises)\n\n all\n .then(() => {\n return\n })\n .catch(() => {\n return\n })\n } catch (ex) {\n this.exceptedForgets += 1\n resolvedConfig?.onException?.(ex as Error)\n this.exceptionHandler(ex as Error, resolvedConfig, externalStackTrace)\n }\n } else {\n // we do nothing here since if it was a non-promise, it already got invoked.\n return\n }\n }\n\n /** Handles timeout events for forgotten promises by logging timeout details. */\n static timeoutHandler(time: number, { name = 'unknown' }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise timeout out after ${time}ms [Cancelling] [${name}]`)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n}\n", "/// <reference types=\"node\" />\n\nimport type { Promisable } from '@xylabs/promise'\n\nimport { defaultForgetNodeConfig, type ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromise } from './ForgetPromise.ts'\n\n/**\n * Node.js extension of ForgetPromise that can terminate the process on exceptions or timeouts.\n */\nexport class ForgetPromiseNode extends ForgetPromise {\n /** Handles exceptions, optionally terminating the process based on config. */\n static override exceptionHandler(error: Error, config: ForgetNodeConfig, externalStackTrace?: string) {\n // default | global | provided priorities for config (not deep merge)\n super.exceptionHandler(error, config, externalStackTrace)\n if (config?.terminateOnException === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1)\n }\n }\n\n /** Forgets a promise using Node.js-specific configuration with process termination support. */\n static override forget<T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) {\n const resolvedConfig = {\n ...defaultForgetNodeConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n super.forget(promise, resolvedConfig)\n }\n\n /** Handles timeouts, optionally terminating the process based on config. */\n static override timeoutHandler(time: number, config: ForgetNodeConfig, externalStackTrace?: string) {\n super.timeoutHandler(time, config, externalStackTrace)\n if (config?.terminateOnTimeout === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(2)\n }\n }\n}\n", "import { type Promisable } from '@xylabs/promise'\n\nimport type { ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromiseNode } from './ForgetPromiseNode.ts'\n\n/**\n * Node.js variant of forget that can optionally terminate the process on exceptions or timeouts.\n * @param promise - The promise or promisable value to forget.\n * @param config - Optional Node.js-specific configuration including process termination options.\n */\nexport const forgetNode = <T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) => {\n ForgetPromiseNode.forget<T>(promise, config)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Configuration options for fire-and-forget promises.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetConfig<T = any> {\n /** Optional name for identifying the forgotten promise in logs. */\n name?: string\n /** Called when the promise is cancelled due to timeout. */\n onCancel?: () => void\n /** Called when the promise completes, with a tuple of [result, error]. */\n onComplete?: (result: [T | undefined, Error | undefined]) => void\n /** Called when an exception occurs outside the promise itself. */\n onException?: (error: Error) => void\n /** Timeout in milliseconds after which the promise is considered timed out. */\n timeout?: number\n}\n\n/** Default forget configuration with a 30-second timeout. */\nexport const defaultForgetConfig: ForgetConfig<unknown> = { timeout: 30_000 }\n", "import { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/**\n * Node.js-specific forget configuration that extends ForgetConfig with process termination options.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport interface ForgetNodeConfig<T = any> extends ForgetConfig<T> {\n /** Terminate the process on an exception that happens outside of the promise being forgotten. */\n terminateOnException?: boolean\n /** Terminate the process if the promise times out. */\n terminateOnTimeout?: boolean\n}\n\n/** Default Node.js forget configuration with termination disabled. */\nexport const defaultForgetNodeConfig: ForgetNodeConfig<unknown> = {\n ...defaultForgetConfig,\n terminateOnTimeout: false,\n terminateOnException: false,\n}\n", "import { delay } from '@xylabs/delay'\nimport type { Logger } from '@xylabs/logger'\nimport type { Promisable, PromiseEx } from '@xylabs/promise'\nimport { isNumber, isPromise } from '@xylabs/typeof'\n\nimport { defaultForgetConfig, type ForgetConfig } from './ForgetConfig.ts'\n\n/** A function that returns a promisable value. */\ntype PromisableFunction<T> = () => Promisable<T>\n\n/**\n * Manages fire-and-forget promises with tracking, timeouts, and error handling.\n */\n// eslint-disable-next-line unicorn/no-static-only-class\nexport class ForgetPromise {\n /** Number of currently active (unresolved) forgotten promises. */\n static activeForgets = 0\n /** Number of forgotten promises that threw exceptions. */\n static exceptedForgets = 0\n /** Logger instance used for error and warning output. */\n static logger: Logger = console\n\n /** Whether any forgotten promises are still active. */\n static get active() {\n return this.activeForgets > 0\n }\n\n /**\n * Waits until all forgotten promises have completed.\n * @param interval - Polling interval in milliseconds.\n * @param timeout - Optional maximum wait time in milliseconds.\n * @returns The number of remaining active forgets (0 if all completed).\n */\n static async awaitInactive(interval = 100, timeout?: number) {\n let timeoutRemaining = timeout\n while (this.active) {\n await delay(interval)\n if (timeoutRemaining !== undefined) {\n timeoutRemaining -= interval\n if (timeoutRemaining <= 0) {\n return this.activeForgets\n }\n }\n }\n return 0\n }\n\n /** Handles exceptions from forgotten promises by logging error details. */\n static exceptionHandler(error: Error, { name }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise handler excepted [${name}]: ${error.message}`, error)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n\n /**\n * Used to explicitly launch an async function (or Promise) with awaiting it\n * @param promise The promise to forget\n * @param config Configuration of forget settings\n */\n static forget<T>(promise: Promise<T> | PromiseEx<T> | PromisableFunction<T> | T, config?: ForgetConfig<T>) {\n const externalStackTrace = (new Error('Stack')).stack\n\n // default | global | provided priorities for config (not deep merge)\n const resolvedConfig = {\n ...defaultForgetConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n const resolvedPromise = typeof promise === 'function' ? (promise as PromisableFunction<T>)() : promise\n if (isPromise(resolvedPromise)) {\n try {\n let completed = false\n this.activeForgets++\n\n const promiseWrapper = async () => {\n await resolvedPromise\n .then((result: T) => {\n this.activeForgets--\n completed = true\n resolvedConfig?.onComplete?.([result, undefined])\n })\n .catch((error: unknown) => {\n const caughtError = error instanceof Error ? error : new Error(String(error))\n this.activeForgets--\n completed = true\n this.logger.error(`forgotten promise excepted [${config?.name ?? 'unknown'}]: ${caughtError.message}`, caughtError)\n resolvedConfig?.onComplete?.([undefined, caughtError])\n })\n }\n\n const promises = [promiseWrapper()]\n\n // if there is a timeout, add it to the race\n const timeout = resolvedConfig.timeout ?? defaultForgetConfig.timeout\n if (isNumber(timeout)) {\n const timeoutFunc = async () => {\n await delay(timeout)\n if (!completed) {\n resolvedConfig.onCancel?.()\n this.timeoutHandler(timeout, resolvedConfig, externalStackTrace)\n }\n }\n promises.push(timeoutFunc())\n }\n\n const all = Promise.race(promises)\n\n all\n .then(() => {\n return\n })\n .catch(() => {\n return\n })\n } catch (ex) {\n this.exceptedForgets += 1\n resolvedConfig?.onException?.(ex as Error)\n this.exceptionHandler(ex as Error, resolvedConfig, externalStackTrace)\n }\n } else {\n // we do nothing here since if it was a non-promise, it already got invoked.\n return\n }\n }\n\n /** Handles timeout events for forgotten promises by logging timeout details. */\n static timeoutHandler(time: number, { name = 'unknown' }: ForgetConfig, externalStackTrace?: string) {\n this.logger.error(`forget promise timeout out after ${time}ms [Cancelling] [${name}]`)\n if (externalStackTrace !== undefined) {\n this.logger.warn(`External Stack trace [${name}]:`, externalStackTrace)\n }\n }\n}\n", "/// <reference types=\"node\" />\n\nimport type { Promisable } from '@xylabs/promise'\n\nimport { defaultForgetNodeConfig, type ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromise } from './ForgetPromise.ts'\n\n/**\n * Node.js extension of ForgetPromise that can terminate the process on exceptions or timeouts.\n */\nexport class ForgetPromiseNode extends ForgetPromise {\n /** Handles exceptions, optionally terminating the process based on config. */\n static override exceptionHandler(error: Error, config: ForgetNodeConfig, externalStackTrace?: string) {\n // default | global | provided priorities for config (not deep merge)\n super.exceptionHandler(error, config, externalStackTrace)\n if (config?.terminateOnException === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(1)\n }\n }\n\n /** Forgets a promise using Node.js-specific configuration with process termination support. */\n static override forget<T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) {\n const resolvedConfig = {\n ...defaultForgetNodeConfig, ...globalThis.xy?.forget?.config, ...config,\n }\n super.forget(promise, resolvedConfig)\n }\n\n /** Handles timeouts, optionally terminating the process based on config. */\n static override timeoutHandler(time: number, config: ForgetNodeConfig, externalStackTrace?: string) {\n super.timeoutHandler(time, config, externalStackTrace)\n if (config?.terminateOnTimeout === true) {\n this.logger.error(`Attempting to terminate process [${config?.name ?? 'unknown'}]...`)\n // eslint-disable-next-line unicorn/no-process-exit\n process.exit(2)\n }\n }\n}\n", "import { type Promisable } from '@xylabs/promise'\n\nimport type { ForgetNodeConfig } from './ForgetNodeConfig.ts'\nimport { ForgetPromiseNode } from './ForgetPromiseNode.ts'\n\n/**\n * Node.js variant of forget that can optionally terminate the process on exceptions or timeouts.\n * @param promise - The promise or promisable value to forget.\n * @param config - Optional Node.js-specific configuration including process termination options.\n */\nexport const forgetNode = <T>(promise: Promisable<T>, config?: ForgetNodeConfig<T>) => {\n ForgetPromiseNode.forget<T>(promise, config)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xylabs/forget",
3
- "version": "6.0.2",
3
+ "version": "6.0.4",
4
4
  "description": "Base functionality used throughout XY Labs TypeScript/JavaScript libraries",
5
5
  "keywords": [
6
6
  "forget",
@@ -53,19 +53,19 @@
53
53
  "README.md"
54
54
  ],
55
55
  "dependencies": {
56
- "@xylabs/delay": "~6.0.2",
57
- "@xylabs/logger": "~6.0.2",
58
- "@xylabs/promise": "~6.0.2",
59
- "@xylabs/typeof": "~6.0.2"
56
+ "@xylabs/delay": "~6.0.4",
57
+ "@xylabs/logger": "~6.0.4",
58
+ "@xylabs/typeof": "~6.0.4",
59
+ "@xylabs/promise": "~6.0.4"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@types/node": "^25.9.1",
63
- "@xylabs/toolchain": "^8.1.1",
64
- "@xylabs/tsconfig": "^8.1.1",
65
- "@xylabs/tsconfig-dom": "^8.1.1",
63
+ "@xylabs/toolchain": "^8.1.5",
64
+ "@xylabs/tsconfig": "^8.1.5",
65
+ "@xylabs/tsconfig-dom": "^8.1.5",
66
66
  "eslint": "^10.4.0",
67
67
  "typescript": "^6.0.3",
68
- "vite": "^8.0.13",
68
+ "vite": "^8.0.14",
69
69
  "vitest": "^4.1.7"
70
70
  },
71
71
  "engines": {