@dxos/context 0.5.3-main.bc67fdb → 0.5.3-main.c8ad1bb

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.
@@ -116,7 +116,7 @@ var Context = class _Context {
116
116
  const callbacks = Array.from(this._disposeCallbacks).reverse();
117
117
  this._disposeCallbacks.length = 0;
118
118
  if (this._name) {
119
- log.info("disposing", {
119
+ log("disposing", {
120
120
  context: this._name,
121
121
  count: callbacks.length
122
122
  }, {
@@ -151,7 +151,7 @@ var Context = class _Context {
151
151
  }
152
152
  resolveDispose(clean);
153
153
  if (this._name) {
154
- log.info("disposed", {
154
+ log("disposed", {
155
155
  context: this._name
156
156
  }, {
157
157
  F: __dxlog_file,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/context.ts", "../../../src/context-disposed-error.ts", "../../../src/promise-utils.ts", "../../../src/resource.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { inspect } from 'node:util';\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nimport { ContextDisposedError } from './context-disposed-error';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => any | Promise<any>;\n\nexport type CreateContextParams = {\n name?: string;\n parent?: Context;\n attributes?: Record<string, any>;\n onError?: ContextErrorHandler;\n};\n\n/**\n * Maximum number of dispose callbacks before we start logging warnings.\n */\nconst MAX_SAFE_DISPOSE_CALLBACKS = 300;\n\n@safeInstanceof('Context')\nexport class Context {\n static default() {\n return new Context();\n }\n\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n\n private readonly _name?: string;\n private readonly _parent?: Context;\n private readonly _attributes: Record<string, any>;\n private readonly _onError: ContextErrorHandler;\n\n private _isDisposed = false;\n private _disposePromise?: Promise<boolean> = undefined;\n\n public maxSafeDisposeCallbacks = MAX_SAFE_DISPOSE_CALLBACKS;\n\n constructor({\n name, // TODO(burdon): Automate?\n parent,\n attributes = {},\n onError = (error) => {\n if (error instanceof ContextDisposedError) {\n return;\n }\n\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n }: CreateContextParams = {}) {\n this._name = name;\n this._parent = parent;\n this._attributes = attributes;\n this._onError = onError;\n }\n\n get disposed() {\n return this._isDisposed;\n }\n\n get disposeCallbacksLength() {\n return this._disposeCallbacks.length;\n }\n\n /**\n * Schedules a callback to run when the context is disposed.\n * May be async, in this case the disposer might choose to wait for all resource to released.\n * Throwing an error inside the callback will result in the error being logged, but not re-thrown.\n *\n * NOTE: Will call the callback immediately if the context is already disposed.\n *\n * @returns A function that can be used to remove the callback from the dispose list.\n */\n onDispose(callback: DisposeCallback): () => void {\n if (this._isDisposed) {\n // Call the callback immediately if the context is already disposed.\n void (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })();\n }\n\n this._disposeCallbacks.push(callback);\n if (this._disposeCallbacks.length > this.maxSafeDisposeCallbacks) {\n log.warn('Context has a large number of dispose callbacks (this might be a memory leak).', {\n count: this._disposeCallbacks.length,\n });\n }\n\n // Remove handler.\n return () => {\n const index = this._disposeCallbacks.indexOf(callback);\n if (index !== -1) {\n this._disposeCallbacks.splice(index, 1);\n }\n };\n }\n\n /**\n * Runs all dispose callbacks.\n * Callbacks are run in the reverse order they were added.\n * This function never throws.\n * It is safe to ignore the returned promise if the caller does not wish to wait for callbacks to complete.\n * Disposing context means that onDispose will throw an error and any errors raised will be logged and not propagated.\n */\n async dispose(throwOnError = false): Promise<boolean> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n\n // TODO(burdon): Probably should not be set until the dispose is complete, but causes tests to fail if moved.\n this._isDisposed = true;\n\n // Set the promise before running the callbacks.\n let resolveDispose!: (value: boolean) => void;\n this._disposePromise = new Promise<boolean>((resolve) => {\n resolveDispose = resolve;\n });\n\n // Process last first.\n // Clone the array so that any mutations to the original array don't affect the dispose process.\n const callbacks = Array.from(this._disposeCallbacks).reverse();\n this._disposeCallbacks.length = 0;\n\n if (this._name) {\n log.info('disposing', { context: this._name, count: callbacks.length });\n }\n\n let i = 0;\n let clean = true;\n for (const callback of callbacks) {\n try {\n await callback();\n i++;\n } catch (err: any) {\n log.catch(err, { context: this._name, callback: i, count: callbacks.length });\n clean = false;\n if (throwOnError) {\n throw err;\n }\n }\n }\n\n resolveDispose(clean);\n if (this._name) {\n log.info('disposed', { context: this._name });\n }\n\n return clean;\n }\n\n /**\n * Raise the error inside the context.\n * The error will be propagated to the error handler.\n * IF the error handler is not set, the error will dispose the context and cause an unhandled rejection.\n */\n raise(error: Error): void {\n if (this._isDisposed) {\n // TODO(dmaretskyi): Don't log those.\n // log.warn('Error in disposed context', error);\n return;\n }\n\n try {\n this._onError(error);\n } catch (err) {\n // Generate an unhandled rejection and stop the error propagation.\n void Promise.reject(err);\n }\n }\n\n derive({ onError, attributes }: CreateContextParams = {}): Context {\n const newCtx = new Context({\n // TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.\n onError: async (error) => {\n if (!onError) {\n this.raise(error);\n } else {\n try {\n await onError(error);\n } catch {\n this.raise(error);\n }\n }\n },\n attributes,\n });\n\n const clearDispose = this.onDispose(() => newCtx.dispose());\n newCtx.onDispose(clearDispose);\n return newCtx;\n }\n\n getAttribute(key: string): any {\n if (key in this._attributes) {\n return this._attributes[key];\n }\n if (this._parent) {\n return this._parent.getAttribute(key);\n }\n\n return undefined;\n }\n\n [Symbol.toStringTag] = 'Context';\n [inspect.custom] = () => this.toString();\n\n toString() {\n return `Context(${this._isDisposed ? 'disposed' : 'active'})`;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport class ContextDisposedError extends Error {\n constructor() {\n super('Context disposed.');\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Context } from './context';\nimport { ContextDisposedError } from './context-disposed-error';\n\n/**\n * @returns A promise that rejects when the context is disposed.\n */\n// TODO(dmaretskyi): Memory leak.\nexport const rejectOnDispose = (ctx: Context, error = new ContextDisposedError()): Promise<never> =>\n new Promise((resolve, reject) => {\n ctx.onDispose(() => reject(error));\n });\n\n/**\n * Rejects the promise if the context is disposed.\n */\nexport const cancelWithContext = <T>(ctx: Context, promise: Promise<T>): Promise<T> => {\n let clearDispose: () => void;\n return Promise.race([\n promise,\n new Promise<never>((resolve, reject) => {\n // Will be called before .finally() handlers.\n clearDispose = ctx.onDispose(() => reject(new ContextDisposedError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport '@dxos/util';\n\nimport { Context } from './context';\n\nexport enum LifecycleState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n ERROR = 'ERROR',\n}\n\nexport interface Lifecycle {\n open?(ctx?: Context): Promise<any> | any;\n close?(): Promise<any> | any;\n}\n\n/**\n * Base class for resources that need to be opened and closed.\n */\nexport abstract class Resource implements Lifecycle {\n #lifecycleState = LifecycleState.CLOSED;\n #openPromise: Promise<void> | null = null;\n #closePromise: Promise<void> | null = null;\n\n /**\n * Managed internally by the resource.\n * Recreated on close.\n * Errors are propagated to the `_catch` method and the parent context.\n */\n #internalCtx: Context = this.#createContext();\n\n /**\n * Context that is used to bubble up errors that are not handled by the resource.\n * Provided in the open method.\n */\n #parentCtx: Context = new Context();\n\n protected get _lifecycleState() {\n return this.#lifecycleState;\n }\n\n protected get _ctx() {\n return this.#internalCtx;\n }\n\n /**\n * To be overridden by subclasses.\n */\n protected async _open(ctx: Context): Promise<void> {}\n\n /**\n * To be overridden by subclasses.\n */\n protected async _close(ctx: Context): Promise<void> {}\n\n /**\n * Error handler for errors that are caught by the context.\n * By default, errors are bubbled up to the parent context which is passed to the open method.\n */\n protected async _catch(err: Error): Promise<void> {\n throw err;\n }\n\n /**\n * Opens the resource.\n * If the resource is already open, it does nothing.\n * If the resource is in an error state, it throws an error.\n * If the resource is closed, it waits for it to close and then opens it.\n * @param ctx - Context to use for opening the resource. This context will receive errors that are not handled in `_catch`.\n */\n async open(ctx?: Context): Promise<this> {\n switch (this.#lifecycleState) {\n case LifecycleState.OPEN:\n return this;\n case LifecycleState.ERROR:\n throw new Error(`Invalid state: ${this.#lifecycleState}`);\n default:\n }\n\n await this.#closePromise;\n await (this.#openPromise ??= this.#open(ctx));\n\n return this;\n }\n\n /**\n * Closes the resource.\n * If the resource is already closed, it does nothing.\n */\n async close(ctx?: Context): Promise<this> {\n if (this.#lifecycleState === LifecycleState.CLOSED) {\n return this;\n }\n await this.#openPromise;\n await (this.#closePromise ??= this.#close(ctx));\n\n return this;\n }\n\n async [Symbol.asyncDispose]() {\n await this.close();\n }\n\n async #open(ctx?: Context) {\n this.#closePromise = null;\n if (ctx) {\n this.#parentCtx = ctx;\n }\n await this._open(this.#parentCtx);\n this.#lifecycleState = LifecycleState.OPEN;\n }\n\n async #close(ctx = new Context()) {\n this.#openPromise = null;\n await this.#internalCtx.dispose();\n await this._close(ctx);\n this.#internalCtx = this.#createContext();\n this.#lifecycleState = LifecycleState.CLOSED;\n }\n\n #createContext() {\n return new Context({\n onError: (error) =>\n queueMicrotask(async () => {\n try {\n await this._catch(error);\n } catch (err: any) {\n this.#lifecycleState = LifecycleState.ERROR;\n this.#parentCtx.raise(err);\n }\n }),\n });\n }\n}\n\nexport const openInContext = async <T extends Lifecycle>(ctx: Context, resource: T): Promise<T> => {\n await resource.open?.(ctx);\n ctx.onDispose(() => resource.close?.());\n\n return resource;\n};\n"],
5
- "mappings": "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",
6
- "names": ["inspect", "log", "safeInstanceof", "ContextDisposedError", "Error", "constructor", "MAX_SAFE_DISPOSE_CALLBACKS", "Context", "constructor", "name", "parent", "attributes", "onError", "error", "ContextDisposedError", "dispose", "_disposeCallbacks", "_isDisposed", "_disposePromise", "undefined", "maxSafeDisposeCallbacks", "Symbol", "inspect", "toString", "_name", "_parent", "_attributes", "_onError", "toStringTag", "custom", "default", "disposed", "disposeCallbacksLength", "length", "onDispose", "callback", "log", "catch", "push", "warn", "count", "index", "indexOf", "splice", "throwOnError", "resolveDispose", "Promise", "resolve", "callbacks", "Array", "from", "reverse", "info", "context", "i", "clean", "err", "raise", "reject", "derive", "newCtx", "clearDispose", "getAttribute", "key", "safeInstanceof", "rejectOnDispose", "ctx", "error", "ContextDisposedError", "Promise", "resolve", "reject", "onDispose", "cancelWithContext", "promise", "clearDispose", "race", "finally", "LifecycleState", "Resource", "Context", "_lifecycleState", "_ctx", "_open", "ctx", "_close", "_catch", "err", "open", "Error", "close", "Symbol", "asyncDispose", "dispose", "onError", "error", "queueMicrotask", "raise", "openInContext", "resource", "onDispose"]
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { inspect } from 'node:util';\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nimport { ContextDisposedError } from './context-disposed-error';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => any | Promise<any>;\n\nexport type CreateContextParams = {\n name?: string;\n parent?: Context;\n attributes?: Record<string, any>;\n onError?: ContextErrorHandler;\n};\n\n/**\n * Maximum number of dispose callbacks before we start logging warnings.\n */\nconst MAX_SAFE_DISPOSE_CALLBACKS = 300;\n\n@safeInstanceof('Context')\nexport class Context {\n static default() {\n return new Context();\n }\n\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n\n private readonly _name?: string;\n private readonly _parent?: Context;\n private readonly _attributes: Record<string, any>;\n private readonly _onError: ContextErrorHandler;\n\n private _isDisposed = false;\n private _disposePromise?: Promise<boolean> = undefined;\n\n public maxSafeDisposeCallbacks = MAX_SAFE_DISPOSE_CALLBACKS;\n\n constructor({\n name, // TODO(burdon): Automate?\n parent,\n attributes = {},\n onError = (error) => {\n if (error instanceof ContextDisposedError) {\n return;\n }\n\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n }: CreateContextParams = {}) {\n this._name = name;\n this._parent = parent;\n this._attributes = attributes;\n this._onError = onError;\n }\n\n get disposed() {\n return this._isDisposed;\n }\n\n get disposeCallbacksLength() {\n return this._disposeCallbacks.length;\n }\n\n /**\n * Schedules a callback to run when the context is disposed.\n * May be async, in this case the disposer might choose to wait for all resource to released.\n * Throwing an error inside the callback will result in the error being logged, but not re-thrown.\n *\n * NOTE: Will call the callback immediately if the context is already disposed.\n *\n * @returns A function that can be used to remove the callback from the dispose list.\n */\n onDispose(callback: DisposeCallback): () => void {\n if (this._isDisposed) {\n // Call the callback immediately if the context is already disposed.\n void (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })();\n }\n\n this._disposeCallbacks.push(callback);\n if (this._disposeCallbacks.length > this.maxSafeDisposeCallbacks) {\n log.warn('Context has a large number of dispose callbacks (this might be a memory leak).', {\n count: this._disposeCallbacks.length,\n });\n }\n\n // Remove handler.\n return () => {\n const index = this._disposeCallbacks.indexOf(callback);\n if (index !== -1) {\n this._disposeCallbacks.splice(index, 1);\n }\n };\n }\n\n /**\n * Runs all dispose callbacks.\n * Callbacks are run in the reverse order they were added.\n * This function never throws.\n * It is safe to ignore the returned promise if the caller does not wish to wait for callbacks to complete.\n * Disposing context means that onDispose will throw an error and any errors raised will be logged and not propagated.\n */\n async dispose(throwOnError = false): Promise<boolean> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n\n // TODO(burdon): Probably should not be set until the dispose is complete, but causes tests to fail if moved.\n this._isDisposed = true;\n\n // Set the promise before running the callbacks.\n let resolveDispose!: (value: boolean) => void;\n this._disposePromise = new Promise<boolean>((resolve) => {\n resolveDispose = resolve;\n });\n\n // Process last first.\n // Clone the array so that any mutations to the original array don't affect the dispose process.\n const callbacks = Array.from(this._disposeCallbacks).reverse();\n this._disposeCallbacks.length = 0;\n\n if (this._name) {\n log('disposing', { context: this._name, count: callbacks.length });\n }\n\n let i = 0;\n let clean = true;\n for (const callback of callbacks) {\n try {\n await callback();\n i++;\n } catch (err: any) {\n log.catch(err, { context: this._name, callback: i, count: callbacks.length });\n clean = false;\n if (throwOnError) {\n throw err;\n }\n }\n }\n\n resolveDispose(clean);\n if (this._name) {\n log('disposed', { context: this._name });\n }\n\n return clean;\n }\n\n /**\n * Raise the error inside the context.\n * The error will be propagated to the error handler.\n * IF the error handler is not set, the error will dispose the context and cause an unhandled rejection.\n */\n raise(error: Error): void {\n if (this._isDisposed) {\n // TODO(dmaretskyi): Don't log those.\n // log.warn('Error in disposed context', error);\n return;\n }\n\n try {\n this._onError(error);\n } catch (err) {\n // Generate an unhandled rejection and stop the error propagation.\n void Promise.reject(err);\n }\n }\n\n derive({ onError, attributes }: CreateContextParams = {}): Context {\n const newCtx = new Context({\n // TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.\n onError: async (error) => {\n if (!onError) {\n this.raise(error);\n } else {\n try {\n await onError(error);\n } catch {\n this.raise(error);\n }\n }\n },\n attributes,\n });\n\n const clearDispose = this.onDispose(() => newCtx.dispose());\n newCtx.onDispose(clearDispose);\n return newCtx;\n }\n\n getAttribute(key: string): any {\n if (key in this._attributes) {\n return this._attributes[key];\n }\n if (this._parent) {\n return this._parent.getAttribute(key);\n }\n\n return undefined;\n }\n\n [Symbol.toStringTag] = 'Context';\n [inspect.custom] = () => this.toString();\n\n toString() {\n return `Context(${this._isDisposed ? 'disposed' : 'active'})`;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport class ContextDisposedError extends Error {\n constructor() {\n super('Context disposed.');\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Context } from './context';\nimport { ContextDisposedError } from './context-disposed-error';\n\n/**\n * @returns A promise that rejects when the context is disposed.\n */\n// TODO(dmaretskyi): Memory leak.\nexport const rejectOnDispose = (ctx: Context, error = new ContextDisposedError()): Promise<never> =>\n new Promise((resolve, reject) => {\n ctx.onDispose(() => reject(error));\n });\n\n/**\n * Rejects the promise if the context is disposed.\n */\nexport const cancelWithContext = <T>(ctx: Context, promise: Promise<T>): Promise<T> => {\n let clearDispose: () => void;\n return Promise.race([\n promise,\n new Promise<never>((resolve, reject) => {\n // Will be called before .finally() handlers.\n clearDispose = ctx.onDispose(() => reject(new ContextDisposedError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport '@dxos/util';\n\nimport { Context } from './context';\n\nexport enum LifecycleState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n ERROR = 'ERROR',\n}\n\nexport interface Lifecycle {\n open?(ctx?: Context): Promise<any> | any;\n close?(): Promise<any> | any;\n}\n\n/**\n * Base class for resources that need to be opened and closed.\n */\nexport abstract class Resource implements Lifecycle {\n #lifecycleState = LifecycleState.CLOSED;\n #openPromise: Promise<void> | null = null;\n #closePromise: Promise<void> | null = null;\n\n /**\n * Managed internally by the resource.\n * Recreated on close.\n * Errors are propagated to the `_catch` method and the parent context.\n */\n #internalCtx: Context = this.#createContext();\n\n /**\n * Context that is used to bubble up errors that are not handled by the resource.\n * Provided in the open method.\n */\n #parentCtx: Context = new Context();\n\n protected get _lifecycleState() {\n return this.#lifecycleState;\n }\n\n protected get _ctx() {\n return this.#internalCtx;\n }\n\n /**\n * To be overridden by subclasses.\n */\n protected async _open(ctx: Context): Promise<void> {}\n\n /**\n * To be overridden by subclasses.\n */\n protected async _close(ctx: Context): Promise<void> {}\n\n /**\n * Error handler for errors that are caught by the context.\n * By default, errors are bubbled up to the parent context which is passed to the open method.\n */\n protected async _catch(err: Error): Promise<void> {\n throw err;\n }\n\n /**\n * Opens the resource.\n * If the resource is already open, it does nothing.\n * If the resource is in an error state, it throws an error.\n * If the resource is closed, it waits for it to close and then opens it.\n * @param ctx - Context to use for opening the resource. This context will receive errors that are not handled in `_catch`.\n */\n async open(ctx?: Context): Promise<this> {\n switch (this.#lifecycleState) {\n case LifecycleState.OPEN:\n return this;\n case LifecycleState.ERROR:\n throw new Error(`Invalid state: ${this.#lifecycleState}`);\n default:\n }\n\n await this.#closePromise;\n await (this.#openPromise ??= this.#open(ctx));\n\n return this;\n }\n\n /**\n * Closes the resource.\n * If the resource is already closed, it does nothing.\n */\n async close(ctx?: Context): Promise<this> {\n if (this.#lifecycleState === LifecycleState.CLOSED) {\n return this;\n }\n await this.#openPromise;\n await (this.#closePromise ??= this.#close(ctx));\n\n return this;\n }\n\n async [Symbol.asyncDispose]() {\n await this.close();\n }\n\n async #open(ctx?: Context) {\n this.#closePromise = null;\n if (ctx) {\n this.#parentCtx = ctx;\n }\n await this._open(this.#parentCtx);\n this.#lifecycleState = LifecycleState.OPEN;\n }\n\n async #close(ctx = new Context()) {\n this.#openPromise = null;\n await this.#internalCtx.dispose();\n await this._close(ctx);\n this.#internalCtx = this.#createContext();\n this.#lifecycleState = LifecycleState.CLOSED;\n }\n\n #createContext() {\n return new Context({\n onError: (error) =>\n queueMicrotask(async () => {\n try {\n await this._catch(error);\n } catch (err: any) {\n this.#lifecycleState = LifecycleState.ERROR;\n this.#parentCtx.raise(err);\n }\n }),\n });\n }\n}\n\nexport const openInContext = async <T extends Lifecycle>(ctx: Context, resource: T): Promise<T> => {\n await resource.open?.(ctx);\n ctx.onDispose(() => resource.close?.());\n\n return resource;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["inspect", "log", "safeInstanceof", "ContextDisposedError", "Error", "constructor", "MAX_SAFE_DISPOSE_CALLBACKS", "Context", "constructor", "name", "parent", "attributes", "onError", "error", "ContextDisposedError", "dispose", "_disposeCallbacks", "_isDisposed", "_disposePromise", "undefined", "maxSafeDisposeCallbacks", "Symbol", "inspect", "toString", "_name", "_parent", "_attributes", "_onError", "toStringTag", "custom", "default", "disposed", "disposeCallbacksLength", "length", "onDispose", "callback", "log", "catch", "push", "warn", "count", "index", "indexOf", "splice", "throwOnError", "resolveDispose", "Promise", "resolve", "callbacks", "Array", "from", "reverse", "context", "i", "clean", "err", "raise", "reject", "derive", "newCtx", "clearDispose", "getAttribute", "key", "safeInstanceof", "rejectOnDispose", "ctx", "error", "ContextDisposedError", "Promise", "resolve", "reject", "onDispose", "cancelWithContext", "promise", "clearDispose", "race", "finally", "LifecycleState", "Resource", "Context", "_lifecycleState", "_ctx", "_open", "ctx", "_close", "_catch", "err", "open", "Error", "close", "Symbol", "asyncDispose", "dispose", "onError", "error", "queueMicrotask", "raise", "openInContext", "resource", "onDispose"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/common/context/src/context-disposed-error.ts":{"bytes":817,"imports":[],"format":"esm"},"packages/common/context/src/context.ts":{"bytes":21533,"imports":[{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/promise-utils.ts":{"bytes":3040,"imports":[{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/resource.ts":{"bytes":11744,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"}],"format":"esm"},"packages/common/context/src/index.ts":{"bytes":777,"imports":[{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"},{"path":"packages/common/context/src/promise-utils.ts","kind":"import-statement","original":"./promise-utils"},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"},{"path":"packages/common/context/src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"}},"outputs":{"packages/common/context/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17046},"packages/common/context/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Context","ContextDisposedError","LifecycleState","Resource","cancelWithContext","openInContext","rejectOnDispose"],"entryPoint":"packages/common/context/src/index.ts","inputs":{"packages/common/context/src/context.ts":{"bytesInOutput":5913},"packages/common/context/src/context-disposed-error.ts":{"bytesInOutput":106},"packages/common/context/src/index.ts":{"bytesInOutput":0},"packages/common/context/src/promise-utils.ts":{"bytesInOutput":410},"packages/common/context/src/resource.ts":{"bytesInOutput":2979}},"bytes":9812}}}
1
+ {"inputs":{"packages/common/context/src/context-disposed-error.ts":{"bytes":817,"imports":[],"format":"esm"},"packages/common/context/src/context.ts":{"bytes":21471,"imports":[{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/promise-utils.ts":{"bytes":3040,"imports":[{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/resource.ts":{"bytes":11744,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"}],"format":"esm"},"packages/common/context/src/index.ts":{"bytes":777,"imports":[{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"},{"path":"packages/common/context/src/promise-utils.ts","kind":"import-statement","original":"./promise-utils"},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"},{"path":"packages/common/context/src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"}},"outputs":{"packages/common/context/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17016},"packages/common/context/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/node-std/util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Context","ContextDisposedError","LifecycleState","Resource","cancelWithContext","openInContext","rejectOnDispose"],"entryPoint":"packages/common/context/src/index.ts","inputs":{"packages/common/context/src/context.ts":{"bytesInOutput":5903},"packages/common/context/src/context-disposed-error.ts":{"bytesInOutput":106},"packages/common/context/src/index.ts":{"bytesInOutput":0},"packages/common/context/src/promise-utils.ts":{"bytesInOutput":410},"packages/common/context/src/resource.ts":{"bytesInOutput":2979}},"bytes":9802}}}
@@ -141,7 +141,7 @@ var Context = class _Context {
141
141
  const callbacks = Array.from(this._disposeCallbacks).reverse();
142
142
  this._disposeCallbacks.length = 0;
143
143
  if (this._name) {
144
- import_log.log.info("disposing", {
144
+ (0, import_log.log)("disposing", {
145
145
  context: this._name,
146
146
  count: callbacks.length
147
147
  }, {
@@ -176,7 +176,7 @@ var Context = class _Context {
176
176
  }
177
177
  resolveDispose(clean);
178
178
  if (this._name) {
179
- import_log.log.info("disposed", {
179
+ (0, import_log.log)("disposed", {
180
180
  context: this._name
181
181
  }, {
182
182
  F: __dxlog_file,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/context.ts", "../../../src/context-disposed-error.ts", "../../../src/promise-utils.ts", "../../../src/resource.ts"],
4
- "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { inspect } from 'node:util';\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nimport { ContextDisposedError } from './context-disposed-error';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => any | Promise<any>;\n\nexport type CreateContextParams = {\n name?: string;\n parent?: Context;\n attributes?: Record<string, any>;\n onError?: ContextErrorHandler;\n};\n\n/**\n * Maximum number of dispose callbacks before we start logging warnings.\n */\nconst MAX_SAFE_DISPOSE_CALLBACKS = 300;\n\n@safeInstanceof('Context')\nexport class Context {\n static default() {\n return new Context();\n }\n\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n\n private readonly _name?: string;\n private readonly _parent?: Context;\n private readonly _attributes: Record<string, any>;\n private readonly _onError: ContextErrorHandler;\n\n private _isDisposed = false;\n private _disposePromise?: Promise<boolean> = undefined;\n\n public maxSafeDisposeCallbacks = MAX_SAFE_DISPOSE_CALLBACKS;\n\n constructor({\n name, // TODO(burdon): Automate?\n parent,\n attributes = {},\n onError = (error) => {\n if (error instanceof ContextDisposedError) {\n return;\n }\n\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n }: CreateContextParams = {}) {\n this._name = name;\n this._parent = parent;\n this._attributes = attributes;\n this._onError = onError;\n }\n\n get disposed() {\n return this._isDisposed;\n }\n\n get disposeCallbacksLength() {\n return this._disposeCallbacks.length;\n }\n\n /**\n * Schedules a callback to run when the context is disposed.\n * May be async, in this case the disposer might choose to wait for all resource to released.\n * Throwing an error inside the callback will result in the error being logged, but not re-thrown.\n *\n * NOTE: Will call the callback immediately if the context is already disposed.\n *\n * @returns A function that can be used to remove the callback from the dispose list.\n */\n onDispose(callback: DisposeCallback): () => void {\n if (this._isDisposed) {\n // Call the callback immediately if the context is already disposed.\n void (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })();\n }\n\n this._disposeCallbacks.push(callback);\n if (this._disposeCallbacks.length > this.maxSafeDisposeCallbacks) {\n log.warn('Context has a large number of dispose callbacks (this might be a memory leak).', {\n count: this._disposeCallbacks.length,\n });\n }\n\n // Remove handler.\n return () => {\n const index = this._disposeCallbacks.indexOf(callback);\n if (index !== -1) {\n this._disposeCallbacks.splice(index, 1);\n }\n };\n }\n\n /**\n * Runs all dispose callbacks.\n * Callbacks are run in the reverse order they were added.\n * This function never throws.\n * It is safe to ignore the returned promise if the caller does not wish to wait for callbacks to complete.\n * Disposing context means that onDispose will throw an error and any errors raised will be logged and not propagated.\n */\n async dispose(throwOnError = false): Promise<boolean> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n\n // TODO(burdon): Probably should not be set until the dispose is complete, but causes tests to fail if moved.\n this._isDisposed = true;\n\n // Set the promise before running the callbacks.\n let resolveDispose!: (value: boolean) => void;\n this._disposePromise = new Promise<boolean>((resolve) => {\n resolveDispose = resolve;\n });\n\n // Process last first.\n // Clone the array so that any mutations to the original array don't affect the dispose process.\n const callbacks = Array.from(this._disposeCallbacks).reverse();\n this._disposeCallbacks.length = 0;\n\n if (this._name) {\n log.info('disposing', { context: this._name, count: callbacks.length });\n }\n\n let i = 0;\n let clean = true;\n for (const callback of callbacks) {\n try {\n await callback();\n i++;\n } catch (err: any) {\n log.catch(err, { context: this._name, callback: i, count: callbacks.length });\n clean = false;\n if (throwOnError) {\n throw err;\n }\n }\n }\n\n resolveDispose(clean);\n if (this._name) {\n log.info('disposed', { context: this._name });\n }\n\n return clean;\n }\n\n /**\n * Raise the error inside the context.\n * The error will be propagated to the error handler.\n * IF the error handler is not set, the error will dispose the context and cause an unhandled rejection.\n */\n raise(error: Error): void {\n if (this._isDisposed) {\n // TODO(dmaretskyi): Don't log those.\n // log.warn('Error in disposed context', error);\n return;\n }\n\n try {\n this._onError(error);\n } catch (err) {\n // Generate an unhandled rejection and stop the error propagation.\n void Promise.reject(err);\n }\n }\n\n derive({ onError, attributes }: CreateContextParams = {}): Context {\n const newCtx = new Context({\n // TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.\n onError: async (error) => {\n if (!onError) {\n this.raise(error);\n } else {\n try {\n await onError(error);\n } catch {\n this.raise(error);\n }\n }\n },\n attributes,\n });\n\n const clearDispose = this.onDispose(() => newCtx.dispose());\n newCtx.onDispose(clearDispose);\n return newCtx;\n }\n\n getAttribute(key: string): any {\n if (key in this._attributes) {\n return this._attributes[key];\n }\n if (this._parent) {\n return this._parent.getAttribute(key);\n }\n\n return undefined;\n }\n\n [Symbol.toStringTag] = 'Context';\n [inspect.custom] = () => this.toString();\n\n toString() {\n return `Context(${this._isDisposed ? 'disposed' : 'active'})`;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport class ContextDisposedError extends Error {\n constructor() {\n super('Context disposed.');\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Context } from './context';\nimport { ContextDisposedError } from './context-disposed-error';\n\n/**\n * @returns A promise that rejects when the context is disposed.\n */\n// TODO(dmaretskyi): Memory leak.\nexport const rejectOnDispose = (ctx: Context, error = new ContextDisposedError()): Promise<never> =>\n new Promise((resolve, reject) => {\n ctx.onDispose(() => reject(error));\n });\n\n/**\n * Rejects the promise if the context is disposed.\n */\nexport const cancelWithContext = <T>(ctx: Context, promise: Promise<T>): Promise<T> => {\n let clearDispose: () => void;\n return Promise.race([\n promise,\n new Promise<never>((resolve, reject) => {\n // Will be called before .finally() handlers.\n clearDispose = ctx.onDispose(() => reject(new ContextDisposedError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport '@dxos/util';\n\nimport { Context } from './context';\n\nexport enum LifecycleState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n ERROR = 'ERROR',\n}\n\nexport interface Lifecycle {\n open?(ctx?: Context): Promise<any> | any;\n close?(): Promise<any> | any;\n}\n\n/**\n * Base class for resources that need to be opened and closed.\n */\nexport abstract class Resource implements Lifecycle {\n #lifecycleState = LifecycleState.CLOSED;\n #openPromise: Promise<void> | null = null;\n #closePromise: Promise<void> | null = null;\n\n /**\n * Managed internally by the resource.\n * Recreated on close.\n * Errors are propagated to the `_catch` method and the parent context.\n */\n #internalCtx: Context = this.#createContext();\n\n /**\n * Context that is used to bubble up errors that are not handled by the resource.\n * Provided in the open method.\n */\n #parentCtx: Context = new Context();\n\n protected get _lifecycleState() {\n return this.#lifecycleState;\n }\n\n protected get _ctx() {\n return this.#internalCtx;\n }\n\n /**\n * To be overridden by subclasses.\n */\n protected async _open(ctx: Context): Promise<void> {}\n\n /**\n * To be overridden by subclasses.\n */\n protected async _close(ctx: Context): Promise<void> {}\n\n /**\n * Error handler for errors that are caught by the context.\n * By default, errors are bubbled up to the parent context which is passed to the open method.\n */\n protected async _catch(err: Error): Promise<void> {\n throw err;\n }\n\n /**\n * Opens the resource.\n * If the resource is already open, it does nothing.\n * If the resource is in an error state, it throws an error.\n * If the resource is closed, it waits for it to close and then opens it.\n * @param ctx - Context to use for opening the resource. This context will receive errors that are not handled in `_catch`.\n */\n async open(ctx?: Context): Promise<this> {\n switch (this.#lifecycleState) {\n case LifecycleState.OPEN:\n return this;\n case LifecycleState.ERROR:\n throw new Error(`Invalid state: ${this.#lifecycleState}`);\n default:\n }\n\n await this.#closePromise;\n await (this.#openPromise ??= this.#open(ctx));\n\n return this;\n }\n\n /**\n * Closes the resource.\n * If the resource is already closed, it does nothing.\n */\n async close(ctx?: Context): Promise<this> {\n if (this.#lifecycleState === LifecycleState.CLOSED) {\n return this;\n }\n await this.#openPromise;\n await (this.#closePromise ??= this.#close(ctx));\n\n return this;\n }\n\n async [Symbol.asyncDispose]() {\n await this.close();\n }\n\n async #open(ctx?: Context) {\n this.#closePromise = null;\n if (ctx) {\n this.#parentCtx = ctx;\n }\n await this._open(this.#parentCtx);\n this.#lifecycleState = LifecycleState.OPEN;\n }\n\n async #close(ctx = new Context()) {\n this.#openPromise = null;\n await this.#internalCtx.dispose();\n await this._close(ctx);\n this.#internalCtx = this.#createContext();\n this.#lifecycleState = LifecycleState.CLOSED;\n }\n\n #createContext() {\n return new Context({\n onError: (error) =>\n queueMicrotask(async () => {\n try {\n await this._catch(error);\n } catch (err: any) {\n this.#lifecycleState = LifecycleState.ERROR;\n this.#parentCtx.raise(err);\n }\n }),\n });\n }\n}\n\nexport const openInContext = async <T extends Lifecycle>(ctx: Context, resource: T): Promise<T> => {\n await resource.open?.(ctx);\n ctx.onDispose(() => resource.close?.());\n\n return resource;\n};\n"],
5
- "mappings": "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",
6
- "names": ["import_util", "ContextDisposedError", "Error", "constructor", "MAX_SAFE_DISPOSE_CALLBACKS", "Context", "name", "parent", "attributes", "onError", "error", "dispose", "_disposeCallbacks", "_isDisposed", "_disposePromise", "undefined", "maxSafeDisposeCallbacks", "Symbol", "inspect", "toString", "_name", "_parent", "_attributes", "_onError", "toStringTag", "custom", "default", "disposed", "disposeCallbacksLength", "length", "onDispose", "callback", "log", "catch", "push", "warn", "count", "index", "indexOf", "splice", "throwOnError", "resolveDispose", "Promise", "resolve", "callbacks", "Array", "from", "reverse", "info", "context", "i", "clean", "err", "raise", "reject", "derive", "newCtx", "clearDispose", "getAttribute", "key", "safeInstanceof", "rejectOnDispose", "ctx", "cancelWithContext", "promise", "race", "finally", "LifecycleState", "Resource", "_lifecycleState", "_ctx", "_open", "_close", "_catch", "open", "close", "asyncDispose", "queueMicrotask", "openInContext", "resource"]
4
+ "sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { inspect } from 'node:util';\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nimport { ContextDisposedError } from './context-disposed-error';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => any | Promise<any>;\n\nexport type CreateContextParams = {\n name?: string;\n parent?: Context;\n attributes?: Record<string, any>;\n onError?: ContextErrorHandler;\n};\n\n/**\n * Maximum number of dispose callbacks before we start logging warnings.\n */\nconst MAX_SAFE_DISPOSE_CALLBACKS = 300;\n\n@safeInstanceof('Context')\nexport class Context {\n static default() {\n return new Context();\n }\n\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n\n private readonly _name?: string;\n private readonly _parent?: Context;\n private readonly _attributes: Record<string, any>;\n private readonly _onError: ContextErrorHandler;\n\n private _isDisposed = false;\n private _disposePromise?: Promise<boolean> = undefined;\n\n public maxSafeDisposeCallbacks = MAX_SAFE_DISPOSE_CALLBACKS;\n\n constructor({\n name, // TODO(burdon): Automate?\n parent,\n attributes = {},\n onError = (error) => {\n if (error instanceof ContextDisposedError) {\n return;\n }\n\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n }: CreateContextParams = {}) {\n this._name = name;\n this._parent = parent;\n this._attributes = attributes;\n this._onError = onError;\n }\n\n get disposed() {\n return this._isDisposed;\n }\n\n get disposeCallbacksLength() {\n return this._disposeCallbacks.length;\n }\n\n /**\n * Schedules a callback to run when the context is disposed.\n * May be async, in this case the disposer might choose to wait for all resource to released.\n * Throwing an error inside the callback will result in the error being logged, but not re-thrown.\n *\n * NOTE: Will call the callback immediately if the context is already disposed.\n *\n * @returns A function that can be used to remove the callback from the dispose list.\n */\n onDispose(callback: DisposeCallback): () => void {\n if (this._isDisposed) {\n // Call the callback immediately if the context is already disposed.\n void (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })();\n }\n\n this._disposeCallbacks.push(callback);\n if (this._disposeCallbacks.length > this.maxSafeDisposeCallbacks) {\n log.warn('Context has a large number of dispose callbacks (this might be a memory leak).', {\n count: this._disposeCallbacks.length,\n });\n }\n\n // Remove handler.\n return () => {\n const index = this._disposeCallbacks.indexOf(callback);\n if (index !== -1) {\n this._disposeCallbacks.splice(index, 1);\n }\n };\n }\n\n /**\n * Runs all dispose callbacks.\n * Callbacks are run in the reverse order they were added.\n * This function never throws.\n * It is safe to ignore the returned promise if the caller does not wish to wait for callbacks to complete.\n * Disposing context means that onDispose will throw an error and any errors raised will be logged and not propagated.\n */\n async dispose(throwOnError = false): Promise<boolean> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n\n // TODO(burdon): Probably should not be set until the dispose is complete, but causes tests to fail if moved.\n this._isDisposed = true;\n\n // Set the promise before running the callbacks.\n let resolveDispose!: (value: boolean) => void;\n this._disposePromise = new Promise<boolean>((resolve) => {\n resolveDispose = resolve;\n });\n\n // Process last first.\n // Clone the array so that any mutations to the original array don't affect the dispose process.\n const callbacks = Array.from(this._disposeCallbacks).reverse();\n this._disposeCallbacks.length = 0;\n\n if (this._name) {\n log('disposing', { context: this._name, count: callbacks.length });\n }\n\n let i = 0;\n let clean = true;\n for (const callback of callbacks) {\n try {\n await callback();\n i++;\n } catch (err: any) {\n log.catch(err, { context: this._name, callback: i, count: callbacks.length });\n clean = false;\n if (throwOnError) {\n throw err;\n }\n }\n }\n\n resolveDispose(clean);\n if (this._name) {\n log('disposed', { context: this._name });\n }\n\n return clean;\n }\n\n /**\n * Raise the error inside the context.\n * The error will be propagated to the error handler.\n * IF the error handler is not set, the error will dispose the context and cause an unhandled rejection.\n */\n raise(error: Error): void {\n if (this._isDisposed) {\n // TODO(dmaretskyi): Don't log those.\n // log.warn('Error in disposed context', error);\n return;\n }\n\n try {\n this._onError(error);\n } catch (err) {\n // Generate an unhandled rejection and stop the error propagation.\n void Promise.reject(err);\n }\n }\n\n derive({ onError, attributes }: CreateContextParams = {}): Context {\n const newCtx = new Context({\n // TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.\n onError: async (error) => {\n if (!onError) {\n this.raise(error);\n } else {\n try {\n await onError(error);\n } catch {\n this.raise(error);\n }\n }\n },\n attributes,\n });\n\n const clearDispose = this.onDispose(() => newCtx.dispose());\n newCtx.onDispose(clearDispose);\n return newCtx;\n }\n\n getAttribute(key: string): any {\n if (key in this._attributes) {\n return this._attributes[key];\n }\n if (this._parent) {\n return this._parent.getAttribute(key);\n }\n\n return undefined;\n }\n\n [Symbol.toStringTag] = 'Context';\n [inspect.custom] = () => this.toString();\n\n toString() {\n return `Context(${this._isDisposed ? 'disposed' : 'active'})`;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport class ContextDisposedError extends Error {\n constructor() {\n super('Context disposed.');\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { type Context } from './context';\nimport { ContextDisposedError } from './context-disposed-error';\n\n/**\n * @returns A promise that rejects when the context is disposed.\n */\n// TODO(dmaretskyi): Memory leak.\nexport const rejectOnDispose = (ctx: Context, error = new ContextDisposedError()): Promise<never> =>\n new Promise((resolve, reject) => {\n ctx.onDispose(() => reject(error));\n });\n\n/**\n * Rejects the promise if the context is disposed.\n */\nexport const cancelWithContext = <T>(ctx: Context, promise: Promise<T>): Promise<T> => {\n let clearDispose: () => void;\n return Promise.race([\n promise,\n new Promise<never>((resolve, reject) => {\n // Will be called before .finally() handlers.\n clearDispose = ctx.onDispose(() => reject(new ContextDisposedError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport '@dxos/util';\n\nimport { Context } from './context';\n\nexport enum LifecycleState {\n CLOSED = 'CLOSED',\n OPEN = 'OPEN',\n ERROR = 'ERROR',\n}\n\nexport interface Lifecycle {\n open?(ctx?: Context): Promise<any> | any;\n close?(): Promise<any> | any;\n}\n\n/**\n * Base class for resources that need to be opened and closed.\n */\nexport abstract class Resource implements Lifecycle {\n #lifecycleState = LifecycleState.CLOSED;\n #openPromise: Promise<void> | null = null;\n #closePromise: Promise<void> | null = null;\n\n /**\n * Managed internally by the resource.\n * Recreated on close.\n * Errors are propagated to the `_catch` method and the parent context.\n */\n #internalCtx: Context = this.#createContext();\n\n /**\n * Context that is used to bubble up errors that are not handled by the resource.\n * Provided in the open method.\n */\n #parentCtx: Context = new Context();\n\n protected get _lifecycleState() {\n return this.#lifecycleState;\n }\n\n protected get _ctx() {\n return this.#internalCtx;\n }\n\n /**\n * To be overridden by subclasses.\n */\n protected async _open(ctx: Context): Promise<void> {}\n\n /**\n * To be overridden by subclasses.\n */\n protected async _close(ctx: Context): Promise<void> {}\n\n /**\n * Error handler for errors that are caught by the context.\n * By default, errors are bubbled up to the parent context which is passed to the open method.\n */\n protected async _catch(err: Error): Promise<void> {\n throw err;\n }\n\n /**\n * Opens the resource.\n * If the resource is already open, it does nothing.\n * If the resource is in an error state, it throws an error.\n * If the resource is closed, it waits for it to close and then opens it.\n * @param ctx - Context to use for opening the resource. This context will receive errors that are not handled in `_catch`.\n */\n async open(ctx?: Context): Promise<this> {\n switch (this.#lifecycleState) {\n case LifecycleState.OPEN:\n return this;\n case LifecycleState.ERROR:\n throw new Error(`Invalid state: ${this.#lifecycleState}`);\n default:\n }\n\n await this.#closePromise;\n await (this.#openPromise ??= this.#open(ctx));\n\n return this;\n }\n\n /**\n * Closes the resource.\n * If the resource is already closed, it does nothing.\n */\n async close(ctx?: Context): Promise<this> {\n if (this.#lifecycleState === LifecycleState.CLOSED) {\n return this;\n }\n await this.#openPromise;\n await (this.#closePromise ??= this.#close(ctx));\n\n return this;\n }\n\n async [Symbol.asyncDispose]() {\n await this.close();\n }\n\n async #open(ctx?: Context) {\n this.#closePromise = null;\n if (ctx) {\n this.#parentCtx = ctx;\n }\n await this._open(this.#parentCtx);\n this.#lifecycleState = LifecycleState.OPEN;\n }\n\n async #close(ctx = new Context()) {\n this.#openPromise = null;\n await this.#internalCtx.dispose();\n await this._close(ctx);\n this.#internalCtx = this.#createContext();\n this.#lifecycleState = LifecycleState.CLOSED;\n }\n\n #createContext() {\n return new Context({\n onError: (error) =>\n queueMicrotask(async () => {\n try {\n await this._catch(error);\n } catch (err: any) {\n this.#lifecycleState = LifecycleState.ERROR;\n this.#parentCtx.raise(err);\n }\n }),\n });\n }\n}\n\nexport const openInContext = async <T extends Lifecycle>(ctx: Context, resource: T): Promise<T> => {\n await resource.open?.(ctx);\n ctx.onDispose(() => resource.close?.());\n\n return resource;\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_util", "ContextDisposedError", "Error", "constructor", "MAX_SAFE_DISPOSE_CALLBACKS", "Context", "name", "parent", "attributes", "onError", "error", "dispose", "_disposeCallbacks", "_isDisposed", "_disposePromise", "undefined", "maxSafeDisposeCallbacks", "Symbol", "inspect", "toString", "_name", "_parent", "_attributes", "_onError", "toStringTag", "custom", "default", "disposed", "disposeCallbacksLength", "length", "onDispose", "callback", "log", "catch", "push", "warn", "count", "index", "indexOf", "splice", "throwOnError", "resolveDispose", "Promise", "resolve", "callbacks", "Array", "from", "reverse", "context", "i", "clean", "err", "raise", "reject", "derive", "newCtx", "clearDispose", "getAttribute", "key", "safeInstanceof", "rejectOnDispose", "ctx", "cancelWithContext", "promise", "race", "finally", "LifecycleState", "Resource", "_lifecycleState", "_ctx", "_open", "_close", "_catch", "open", "close", "asyncDispose", "queueMicrotask", "openInContext", "resource"]
7
7
  }
@@ -1 +1 @@
1
- {"inputs":{"packages/common/context/src/context-disposed-error.ts":{"bytes":817,"imports":[],"format":"esm"},"packages/common/context/src/context.ts":{"bytes":21533,"imports":[{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/promise-utils.ts":{"bytes":3040,"imports":[{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/resource.ts":{"bytes":11744,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"}],"format":"esm"},"packages/common/context/src/index.ts":{"bytes":777,"imports":[{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"},{"path":"packages/common/context/src/promise-utils.ts","kind":"import-statement","original":"./promise-utils"},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"},{"path":"packages/common/context/src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"}},"outputs":{"packages/common/context/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17046},"packages/common/context/dist/lib/node/index.cjs":{"imports":[{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Context","ContextDisposedError","LifecycleState","Resource","cancelWithContext","openInContext","rejectOnDispose"],"entryPoint":"packages/common/context/src/index.ts","inputs":{"packages/common/context/src/context.ts":{"bytesInOutput":5903},"packages/common/context/src/context-disposed-error.ts":{"bytesInOutput":106},"packages/common/context/src/index.ts":{"bytesInOutput":0},"packages/common/context/src/promise-utils.ts":{"bytesInOutput":410},"packages/common/context/src/resource.ts":{"bytesInOutput":2979}},"bytes":9802}}}
1
+ {"inputs":{"packages/common/context/src/context-disposed-error.ts":{"bytes":817,"imports":[],"format":"esm"},"packages/common/context/src/context.ts":{"bytes":21471,"imports":[{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/promise-utils.ts":{"bytes":3040,"imports":[{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"}],"format":"esm"},"packages/common/context/src/resource.ts":{"bytes":11744,"imports":[{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"}],"format":"esm"},"packages/common/context/src/index.ts":{"bytes":777,"imports":[{"path":"packages/common/context/src/context.ts","kind":"import-statement","original":"./context"},{"path":"packages/common/context/src/promise-utils.ts","kind":"import-statement","original":"./promise-utils"},{"path":"packages/common/context/src/context-disposed-error.ts","kind":"import-statement","original":"./context-disposed-error"},{"path":"packages/common/context/src/resource.ts","kind":"import-statement","original":"./resource"}],"format":"esm"}},"outputs":{"packages/common/context/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":17016},"packages/common/context/dist/lib/node/index.cjs":{"imports":[{"path":"node:util","kind":"import-statement","external":true},{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["Context","ContextDisposedError","LifecycleState","Resource","cancelWithContext","openInContext","rejectOnDispose"],"entryPoint":"packages/common/context/src/index.ts","inputs":{"packages/common/context/src/context.ts":{"bytesInOutput":5893},"packages/common/context/src/context-disposed-error.ts":{"bytesInOutput":106},"packages/common/context/src/index.ts":{"bytesInOutput":0},"packages/common/context/src/promise-utils.ts":{"bytesInOutput":410},"packages/common/context/src/resource.ts":{"bytesInOutput":2979}},"bytes":9792}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/context",
3
- "version": "0.5.3-main.bc67fdb",
3
+ "version": "0.5.3-main.c8ad1bb",
4
4
  "description": "Async utils.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -16,9 +16,9 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@dxos/log": "0.5.3-main.bc67fdb",
20
- "@dxos/node-std": "0.5.3-main.bc67fdb",
21
- "@dxos/util": "0.5.3-main.bc67fdb"
19
+ "@dxos/node-std": "0.5.3-main.c8ad1bb",
20
+ "@dxos/util": "0.5.3-main.c8ad1bb",
21
+ "@dxos/log": "0.5.3-main.c8ad1bb"
22
22
  },
23
23
  "publishConfig": {
24
24
  "access": "public"
package/src/context.ts CHANGED
@@ -136,7 +136,7 @@ export class Context {
136
136
  this._disposeCallbacks.length = 0;
137
137
 
138
138
  if (this._name) {
139
- log.info('disposing', { context: this._name, count: callbacks.length });
139
+ log('disposing', { context: this._name, count: callbacks.length });
140
140
  }
141
141
 
142
142
  let i = 0;
@@ -156,7 +156,7 @@ export class Context {
156
156
 
157
157
  resolveDispose(clean);
158
158
  if (this._name) {
159
- log.info('disposed', { context: this._name });
159
+ log('disposed', { context: this._name });
160
160
  }
161
161
 
162
162
  return clean;