@dxos/context 0.1.56-main.e47dfd1 → 0.1.56-main.e79d64a
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.
- package/dist/lib/browser/index.mjs +25 -8
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +25 -8
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/types/src/context.d.ts +7 -2
- package/dist/types/src/context.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/context.ts +25 -2
|
@@ -17,10 +17,16 @@ var Context = class Context1 {
|
|
|
17
17
|
constructor({ onError = (error) => {
|
|
18
18
|
void this.dispose();
|
|
19
19
|
throw error;
|
|
20
|
-
} } = {}) {
|
|
20
|
+
}, attributes = {}, parent } = {}) {
|
|
21
21
|
this._disposeCallbacks = [];
|
|
22
22
|
this._isDisposed = false;
|
|
23
|
+
this._disposePromise = void 0;
|
|
24
|
+
this._parent = null;
|
|
23
25
|
this._onError = onError;
|
|
26
|
+
this._attributes = attributes;
|
|
27
|
+
if (parent !== void 0) {
|
|
28
|
+
this._parent = parent;
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
get disposed() {
|
|
26
32
|
return this._isDisposed;
|
|
@@ -42,7 +48,7 @@ var Context = class Context1 {
|
|
|
42
48
|
} catch (error) {
|
|
43
49
|
log.catch(error, void 0, {
|
|
44
50
|
F: __dxlog_file,
|
|
45
|
-
L:
|
|
51
|
+
L: 70,
|
|
46
52
|
S: this,
|
|
47
53
|
C: (f, a) => f(...a)
|
|
48
54
|
});
|
|
@@ -56,7 +62,7 @@ var Context = class Context1 {
|
|
|
56
62
|
safeThreshold: MAX_SAFE_DISPOSE_CALLBACKS
|
|
57
63
|
}, {
|
|
58
64
|
F: __dxlog_file,
|
|
59
|
-
L:
|
|
65
|
+
L: 77,
|
|
60
66
|
S: this,
|
|
61
67
|
C: (f, a) => f(...a)
|
|
62
68
|
});
|
|
@@ -89,7 +95,7 @@ var Context = class Context1 {
|
|
|
89
95
|
} catch (error) {
|
|
90
96
|
log.catch(error, void 0, {
|
|
91
97
|
F: __dxlog_file,
|
|
92
|
-
L:
|
|
98
|
+
L: 112,
|
|
93
99
|
S: this,
|
|
94
100
|
C: (f, a) => f(...a)
|
|
95
101
|
});
|
|
@@ -115,24 +121,35 @@ var Context = class Context1 {
|
|
|
115
121
|
void Promise.reject(err);
|
|
116
122
|
}
|
|
117
123
|
}
|
|
118
|
-
derive({ onError } = {}) {
|
|
124
|
+
derive({ onError, attributes } = {}) {
|
|
119
125
|
const newCtx = new Context({
|
|
126
|
+
// TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.
|
|
120
127
|
onError: async (error) => {
|
|
121
128
|
if (!onError) {
|
|
122
129
|
this.raise(error);
|
|
123
130
|
} else {
|
|
124
131
|
try {
|
|
125
132
|
await onError(error);
|
|
126
|
-
} catch
|
|
133
|
+
} catch {
|
|
127
134
|
this.raise(error);
|
|
128
135
|
}
|
|
129
136
|
}
|
|
130
|
-
}
|
|
137
|
+
},
|
|
138
|
+
attributes
|
|
131
139
|
});
|
|
132
140
|
const clearDispose = this.onDispose(() => newCtx.dispose());
|
|
133
141
|
newCtx.onDispose(clearDispose);
|
|
134
142
|
return newCtx;
|
|
135
143
|
}
|
|
144
|
+
getAttribute(key) {
|
|
145
|
+
if (key in this._attributes) {
|
|
146
|
+
return this._attributes[key];
|
|
147
|
+
}
|
|
148
|
+
if (this._parent !== null) {
|
|
149
|
+
return this._parent.getAttribute(key);
|
|
150
|
+
}
|
|
151
|
+
return void 0;
|
|
152
|
+
}
|
|
136
153
|
};
|
|
137
154
|
Context = _ts_decorate([
|
|
138
155
|
safeInstanceof("Context")
|
|
@@ -150,7 +167,7 @@ var cancelWithContext = (ctx, promise) => {
|
|
|
150
167
|
new Promise((resolve, reject) => {
|
|
151
168
|
clearDispose = ctx.onDispose(() => reject(new CancelledError()));
|
|
152
169
|
})
|
|
153
|
-
]).finally(() => clearDispose
|
|
170
|
+
]).finally(() => clearDispose?.());
|
|
154
171
|
};
|
|
155
172
|
export {
|
|
156
173
|
Context,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/context.ts", "../../../src/promise-utils.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => void | Promise<void>;\n\nexport type CreateContextParams = {\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 private readonly _onError: ContextErrorHandler;\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n private _isDisposed = false;\n private _disposePromise?: Promise<void>;\n\n constructor({\n onError = (error) => {\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n }: CreateContextParams = {}) {\n this._onError = onError;\n }\n\n get disposed() {\n return this._isDisposed;\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) {\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 > MAX_SAFE_DISPOSE_CALLBACKS) {\n log.warn('Context has a large number of dispose callbacks. This might be a memory leak.', {\n count: this._disposeCallbacks.length,\n safeThreshold: MAX_SAFE_DISPOSE_CALLBACKS,\n });\n }\n\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 * Sync callbacks are run in the reverse order they were added.\n * Async callbacks are run in parallel.\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 dispose(): Promise<void> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n this._isDisposed = true;\n\n const promises = [];\n for (const callback of this._disposeCallbacks.reverse()) {\n promises.push(\n (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })(),\n );\n }\n this._disposeCallbacks.length = 0;\n\n return (this._disposePromise = Promise.all(promises).then(() => {}));\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 }: CreateContextParams = {}): Context {\n const newCtx = new 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 });\n const clearDispose = this.onDispose(() => newCtx.dispose());\n newCtx.onDispose(clearDispose);\n return newCtx;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CancelledError } from '@dxos/errors';\n\nimport { Context } from './context';\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 CancelledError()): 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 CancelledError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n"],
|
|
5
|
-
"mappings": ";AAIA,SAASA,WAAW;AACpB,SAASC,sBAAsB;;;;;;;;;;;;
|
|
6
|
-
"names": ["log", "safeInstanceof", "MAX_SAFE_DISPOSE_CALLBACKS", "Context", "constructor", "onError", "error", "dispose", "_disposeCallbacks", "_isDisposed", "_onError", "disposed", "onDispose", "callback", "catch", "push", "length", "warn", "count", "safeThreshold", "index", "indexOf", "splice", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => void | Promise<void>;\n\nexport type CreateContextParams = {\n onError?: ContextErrorHandler;\n attributes?: Record<string, any>;\n parent?: Context;\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 private readonly _onError: ContextErrorHandler;\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n private _isDisposed = false;\n private _disposePromise?: Promise<void> = undefined;\n private _parent: Context | null = null;\n\n private _attributes: Record<string, any>;\n\n constructor({\n onError = (error) => {\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n attributes = {},\n parent,\n }: CreateContextParams = {}) {\n this._onError = onError;\n this._attributes = attributes;\n if (parent !== undefined) {\n this._parent = parent;\n }\n }\n\n get disposed() {\n return this._isDisposed;\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) {\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 > MAX_SAFE_DISPOSE_CALLBACKS) {\n log.warn('Context has a large number of dispose callbacks. This might be a memory leak.', {\n count: this._disposeCallbacks.length,\n safeThreshold: MAX_SAFE_DISPOSE_CALLBACKS,\n });\n }\n\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 * Sync callbacks are run in the reverse order they were added.\n * Async callbacks are run in parallel.\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 dispose(): Promise<void> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n this._isDisposed = true;\n\n const promises = [];\n for (const callback of this._disposeCallbacks.reverse()) {\n promises.push(\n (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })(),\n );\n }\n this._disposeCallbacks.length = 0;\n\n return (this._disposePromise = Promise.all(promises).then(() => {}));\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 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 !== null) {\n return this._parent.getAttribute(key);\n }\n return undefined;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CancelledError } from '@dxos/errors';\n\nimport { Context } from './context';\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 CancelledError()): 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 CancelledError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["log", "safeInstanceof", "MAX_SAFE_DISPOSE_CALLBACKS", "Context", "constructor", "onError", "error", "dispose", "attributes", "parent", "_disposeCallbacks", "_isDisposed", "_disposePromise", "undefined", "_parent", "_onError", "_attributes", "disposed", "onDispose", "callback", "catch", "push", "length", "warn", "count", "safeThreshold", "index", "indexOf", "splice", "promises", "reverse", "Promise", "all", "then", "raise", "err", "reject", "derive", "newCtx", "clearDispose", "getAttribute", "key", "CancelledError", "rejectOnDispose", "ctx", "error", "CancelledError", "Promise", "resolve", "reject", "onDispose", "cancelWithContext", "promise", "clearDispose", "race", "finally"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/common/context/src/context.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/common/context/src/context.ts":{"bytes":16517,"imports":[{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/common/context/src/promise-utils.ts":{"bytes":2954,"imports":[{"path":"@dxos/errors","kind":"import-statement","external":true}],"format":"esm"},"packages/common/context/src/index.ts":{"bytes":563,"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"}],"format":"esm"}},"outputs":{"packages/common/context/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9018},"packages/common/context/dist/lib/browser/index.mjs":{"imports":[{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@dxos/errors","kind":"import-statement","external":true}],"exports":["Context","cancelWithContext","rejectOnDispose"],"entryPoint":"packages/common/context/src/index.ts","inputs":{"packages/common/context/src/context.ts":{"bytesInOutput":4806},"packages/common/context/src/index.ts":{"bytesInOutput":0},"packages/common/context/src/promise-utils.ts":{"bytesInOutput":445}},"bytes":5439}}}
|
package/dist/lib/node/index.cjs
CHANGED
|
@@ -45,10 +45,16 @@ var Context = class Context1 {
|
|
|
45
45
|
constructor({ onError = (error) => {
|
|
46
46
|
void this.dispose();
|
|
47
47
|
throw error;
|
|
48
|
-
} } = {}) {
|
|
48
|
+
}, attributes = {}, parent } = {}) {
|
|
49
49
|
this._disposeCallbacks = [];
|
|
50
50
|
this._isDisposed = false;
|
|
51
|
+
this._disposePromise = void 0;
|
|
52
|
+
this._parent = null;
|
|
51
53
|
this._onError = onError;
|
|
54
|
+
this._attributes = attributes;
|
|
55
|
+
if (parent !== void 0) {
|
|
56
|
+
this._parent = parent;
|
|
57
|
+
}
|
|
52
58
|
}
|
|
53
59
|
get disposed() {
|
|
54
60
|
return this._isDisposed;
|
|
@@ -70,7 +76,7 @@ var Context = class Context1 {
|
|
|
70
76
|
} catch (error) {
|
|
71
77
|
import_log.log.catch(error, void 0, {
|
|
72
78
|
F: __dxlog_file,
|
|
73
|
-
L:
|
|
79
|
+
L: 70,
|
|
74
80
|
S: this,
|
|
75
81
|
C: (f, a) => f(...a)
|
|
76
82
|
});
|
|
@@ -84,7 +90,7 @@ var Context = class Context1 {
|
|
|
84
90
|
safeThreshold: MAX_SAFE_DISPOSE_CALLBACKS
|
|
85
91
|
}, {
|
|
86
92
|
F: __dxlog_file,
|
|
87
|
-
L:
|
|
93
|
+
L: 77,
|
|
88
94
|
S: this,
|
|
89
95
|
C: (f, a) => f(...a)
|
|
90
96
|
});
|
|
@@ -117,7 +123,7 @@ var Context = class Context1 {
|
|
|
117
123
|
} catch (error) {
|
|
118
124
|
import_log.log.catch(error, void 0, {
|
|
119
125
|
F: __dxlog_file,
|
|
120
|
-
L:
|
|
126
|
+
L: 112,
|
|
121
127
|
S: this,
|
|
122
128
|
C: (f, a) => f(...a)
|
|
123
129
|
});
|
|
@@ -143,24 +149,35 @@ var Context = class Context1 {
|
|
|
143
149
|
void Promise.reject(err);
|
|
144
150
|
}
|
|
145
151
|
}
|
|
146
|
-
derive({ onError } = {}) {
|
|
152
|
+
derive({ onError, attributes } = {}) {
|
|
147
153
|
const newCtx = new Context({
|
|
154
|
+
// TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.
|
|
148
155
|
onError: async (error) => {
|
|
149
156
|
if (!onError) {
|
|
150
157
|
this.raise(error);
|
|
151
158
|
} else {
|
|
152
159
|
try {
|
|
153
160
|
await onError(error);
|
|
154
|
-
} catch
|
|
161
|
+
} catch {
|
|
155
162
|
this.raise(error);
|
|
156
163
|
}
|
|
157
164
|
}
|
|
158
|
-
}
|
|
165
|
+
},
|
|
166
|
+
attributes
|
|
159
167
|
});
|
|
160
168
|
const clearDispose = this.onDispose(() => newCtx.dispose());
|
|
161
169
|
newCtx.onDispose(clearDispose);
|
|
162
170
|
return newCtx;
|
|
163
171
|
}
|
|
172
|
+
getAttribute(key) {
|
|
173
|
+
if (key in this._attributes) {
|
|
174
|
+
return this._attributes[key];
|
|
175
|
+
}
|
|
176
|
+
if (this._parent !== null) {
|
|
177
|
+
return this._parent.getAttribute(key);
|
|
178
|
+
}
|
|
179
|
+
return void 0;
|
|
180
|
+
}
|
|
164
181
|
};
|
|
165
182
|
Context = _ts_decorate([
|
|
166
183
|
(0, import_util.safeInstanceof)("Context")
|
|
@@ -178,7 +195,7 @@ var cancelWithContext = (ctx, promise) => {
|
|
|
178
195
|
new Promise((resolve, reject) => {
|
|
179
196
|
clearDispose = ctx.onDispose(() => reject(new import_errors.CancelledError()));
|
|
180
197
|
})
|
|
181
|
-
]).finally(() => clearDispose
|
|
198
|
+
]).finally(() => clearDispose?.());
|
|
182
199
|
};
|
|
183
200
|
// Annotate the CommonJS export names for ESM import in node:
|
|
184
201
|
0 && (module.exports = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/index.ts", "../../../src/context.ts", "../../../src/promise-utils.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './context';\nexport * from './promise-utils';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => void | Promise<void>;\n\nexport type CreateContextParams = {\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 private readonly _onError: ContextErrorHandler;\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n private _isDisposed = false;\n private _disposePromise?: Promise<void>;\n\n constructor({\n onError = (error) => {\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n }: CreateContextParams = {}) {\n this._onError = onError;\n }\n\n get disposed() {\n return this._isDisposed;\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) {\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 > MAX_SAFE_DISPOSE_CALLBACKS) {\n log.warn('Context has a large number of dispose callbacks. This might be a memory leak.', {\n count: this._disposeCallbacks.length,\n safeThreshold: MAX_SAFE_DISPOSE_CALLBACKS,\n });\n }\n\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 * Sync callbacks are run in the reverse order they were added.\n * Async callbacks are run in parallel.\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 dispose(): Promise<void> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n this._isDisposed = true;\n\n const promises = [];\n for (const callback of this._disposeCallbacks.reverse()) {\n promises.push(\n (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })(),\n );\n }\n this._disposeCallbacks.length = 0;\n\n return (this._disposePromise = Promise.all(promises).then(() => {}));\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 }: CreateContextParams = {}): Context {\n const newCtx = new 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 });\n const clearDispose = this.onDispose(() => newCtx.dispose());\n newCtx.onDispose(clearDispose);\n return newCtx;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CancelledError } from '@dxos/errors';\n\nimport { Context } from './context';\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 CancelledError()): 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 CancelledError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;ACIA,iBAAoB;AACpB,kBAA+B;;;;;;;;;;;;
|
|
6
|
-
"names": ["MAX_SAFE_DISPOSE_CALLBACKS", "Context", "constructor", "onError", "error", "dispose", "_disposeCallbacks", "_isDisposed", "_onError", "disposed", "onDispose", "callback", "log", "catch", "push", "length", "warn", "count", "safeThreshold", "index", "indexOf", "splice", "
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2022 DXOS.org\n//\n\nexport * from './context';\nexport * from './promise-utils';\n", "//\n// Copyright 2022 DXOS.org\n//\n\nimport { log } from '@dxos/log';\nimport { safeInstanceof } from '@dxos/util';\n\nexport type ContextErrorHandler = (error: Error) => void;\n\nexport type DisposeCallback = () => void | Promise<void>;\n\nexport type CreateContextParams = {\n onError?: ContextErrorHandler;\n attributes?: Record<string, any>;\n parent?: Context;\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 private readonly _onError: ContextErrorHandler;\n private readonly _disposeCallbacks: DisposeCallback[] = [];\n private _isDisposed = false;\n private _disposePromise?: Promise<void> = undefined;\n private _parent: Context | null = null;\n\n private _attributes: Record<string, any>;\n\n constructor({\n onError = (error) => {\n void this.dispose();\n\n // Will generate an unhandled rejection.\n throw error;\n },\n attributes = {},\n parent,\n }: CreateContextParams = {}) {\n this._onError = onError;\n this._attributes = attributes;\n if (parent !== undefined) {\n this._parent = parent;\n }\n }\n\n get disposed() {\n return this._isDisposed;\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) {\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 > MAX_SAFE_DISPOSE_CALLBACKS) {\n log.warn('Context has a large number of dispose callbacks. This might be a memory leak.', {\n count: this._disposeCallbacks.length,\n safeThreshold: MAX_SAFE_DISPOSE_CALLBACKS,\n });\n }\n\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 * Sync callbacks are run in the reverse order they were added.\n * Async callbacks are run in parallel.\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 dispose(): Promise<void> {\n if (this._disposePromise) {\n return this._disposePromise;\n }\n this._isDisposed = true;\n\n const promises = [];\n for (const callback of this._disposeCallbacks.reverse()) {\n promises.push(\n (async () => {\n try {\n await callback();\n } catch (error: any) {\n log.catch(error);\n }\n })(),\n );\n }\n this._disposeCallbacks.length = 0;\n\n return (this._disposePromise = Promise.all(promises).then(() => {}));\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 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 !== null) {\n return this._parent.getAttribute(key);\n }\n return undefined;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CancelledError } from '@dxos/errors';\n\nimport { Context } from './context';\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 CancelledError()): 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 CancelledError()));\n }),\n ]).finally(() => clearDispose?.());\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["MAX_SAFE_DISPOSE_CALLBACKS", "Context", "constructor", "onError", "error", "dispose", "attributes", "parent", "_disposeCallbacks", "_isDisposed", "_disposePromise", "undefined", "_parent", "_onError", "_attributes", "disposed", "onDispose", "callback", "log", "catch", "push", "length", "warn", "count", "safeThreshold", "index", "indexOf", "splice", "promises", "reverse", "Promise", "all", "then", "raise", "err", "reject", "derive", "newCtx", "clearDispose", "getAttribute", "key", "safeInstanceof", "rejectOnDispose", "ctx", "error", "CancelledError", "Promise", "resolve", "reject", "onDispose", "cancelWithContext", "promise", "clearDispose", "race", "finally"]
|
|
7
7
|
}
|
package/dist/lib/node/meta.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/common/context/src/context.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/common/context/src/context.ts":{"bytes":16517,"imports":[{"path":"@dxos/log","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"format":"esm"},"packages/common/context/src/promise-utils.ts":{"bytes":2954,"imports":[{"path":"@dxos/errors","kind":"import-statement","external":true}],"format":"esm"},"packages/common/context/src/index.ts":{"bytes":563,"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"}],"format":"esm"}},"outputs":{"packages/common/context/dist/lib/node/index.cjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":9151},"packages/common/context/dist/lib/node/index.cjs":{"imports":[{"path":"@dxos/log","kind":"require-call","external":true},{"path":"@dxos/util","kind":"require-call","external":true},{"path":"@dxos/errors","kind":"require-call","external":true}],"exports":[],"entryPoint":"packages/common/context/src/index.ts","inputs":{"packages/common/context/src/index.ts":{"bytesInOutput":207},"packages/common/context/src/context.ts":{"bytesInOutput":4858},"packages/common/context/src/promise-utils.ts":{"bytesInOutput":471}},"bytes":6644}}}
|
|
@@ -2,13 +2,17 @@ export type ContextErrorHandler = (error: Error) => void;
|
|
|
2
2
|
export type DisposeCallback = () => void | Promise<void>;
|
|
3
3
|
export type CreateContextParams = {
|
|
4
4
|
onError?: ContextErrorHandler;
|
|
5
|
+
attributes?: Record<string, any>;
|
|
6
|
+
parent?: Context;
|
|
5
7
|
};
|
|
6
8
|
export declare class Context {
|
|
7
9
|
private readonly _onError;
|
|
8
10
|
private readonly _disposeCallbacks;
|
|
9
11
|
private _isDisposed;
|
|
10
12
|
private _disposePromise?;
|
|
11
|
-
|
|
13
|
+
private _parent;
|
|
14
|
+
private _attributes;
|
|
15
|
+
constructor({ onError, attributes, parent, }?: CreateContextParams);
|
|
12
16
|
get disposed(): boolean;
|
|
13
17
|
/**
|
|
14
18
|
* Schedules a callback to run when the context is disposed.
|
|
@@ -35,6 +39,7 @@ export declare class Context {
|
|
|
35
39
|
* IF the error handler is not set, the error will dispose the context and cause an unhandled rejection.
|
|
36
40
|
*/
|
|
37
41
|
raise(error: Error): void;
|
|
38
|
-
derive({ onError }?: CreateContextParams): Context;
|
|
42
|
+
derive({ onError, attributes }?: CreateContextParams): Context;
|
|
43
|
+
getAttribute(key: string): any;
|
|
39
44
|
}
|
|
40
45
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/context.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../src/context.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;AAEzD,MAAM,MAAM,eAAe,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAOF,qBACa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAyB;IAC3D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAC,CAA4B;IACpD,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,WAAW,CAAsB;gBAE7B,EACV,OAKC,EACD,UAAe,EACf,MAAM,GACP,GAAE,mBAAwB;IAQ3B,IAAI,QAAQ,YAEX;IAED;;;;;;;;OAQG;IACH,SAAS,CAAC,QAAQ,EAAE,eAAe;IA4BnC;;;;;;;OAOG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBxB;;;;OAIG;IACH,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAezB,MAAM,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,GAAE,mBAAwB,GAAG,OAAO;IAqBlE,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG;CAS/B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/context",
|
|
3
|
-
"version": "0.1.56-main.
|
|
3
|
+
"version": "0.1.56-main.e79d64a",
|
|
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/errors": "0.1.56-main.
|
|
20
|
-
"@dxos/log": "0.1.56-main.
|
|
21
|
-
"@dxos/util": "0.1.56-main.
|
|
19
|
+
"@dxos/errors": "0.1.56-main.e79d64a",
|
|
20
|
+
"@dxos/log": "0.1.56-main.e79d64a",
|
|
21
|
+
"@dxos/util": "0.1.56-main.e79d64a"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
package/src/context.ts
CHANGED
|
@@ -11,6 +11,8 @@ export type DisposeCallback = () => void | Promise<void>;
|
|
|
11
11
|
|
|
12
12
|
export type CreateContextParams = {
|
|
13
13
|
onError?: ContextErrorHandler;
|
|
14
|
+
attributes?: Record<string, any>;
|
|
15
|
+
parent?: Context;
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -23,7 +25,10 @@ export class Context {
|
|
|
23
25
|
private readonly _onError: ContextErrorHandler;
|
|
24
26
|
private readonly _disposeCallbacks: DisposeCallback[] = [];
|
|
25
27
|
private _isDisposed = false;
|
|
26
|
-
private _disposePromise?: Promise<void
|
|
28
|
+
private _disposePromise?: Promise<void> = undefined;
|
|
29
|
+
private _parent: Context | null = null;
|
|
30
|
+
|
|
31
|
+
private _attributes: Record<string, any>;
|
|
27
32
|
|
|
28
33
|
constructor({
|
|
29
34
|
onError = (error) => {
|
|
@@ -32,8 +37,14 @@ export class Context {
|
|
|
32
37
|
// Will generate an unhandled rejection.
|
|
33
38
|
throw error;
|
|
34
39
|
},
|
|
40
|
+
attributes = {},
|
|
41
|
+
parent,
|
|
35
42
|
}: CreateContextParams = {}) {
|
|
36
43
|
this._onError = onError;
|
|
44
|
+
this._attributes = attributes;
|
|
45
|
+
if (parent !== undefined) {
|
|
46
|
+
this._parent = parent;
|
|
47
|
+
}
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
get disposed() {
|
|
@@ -128,8 +139,9 @@ export class Context {
|
|
|
128
139
|
}
|
|
129
140
|
}
|
|
130
141
|
|
|
131
|
-
derive({ onError }: CreateContextParams = {}): Context {
|
|
142
|
+
derive({ onError, attributes }: CreateContextParams = {}): Context {
|
|
132
143
|
const newCtx = new Context({
|
|
144
|
+
// TODO(dmaretskyi): Optimize to not require allocating a new closure for every context.
|
|
133
145
|
onError: async (error) => {
|
|
134
146
|
if (!onError) {
|
|
135
147
|
this.raise(error);
|
|
@@ -141,9 +153,20 @@ export class Context {
|
|
|
141
153
|
}
|
|
142
154
|
}
|
|
143
155
|
},
|
|
156
|
+
attributes,
|
|
144
157
|
});
|
|
145
158
|
const clearDispose = this.onDispose(() => newCtx.dispose());
|
|
146
159
|
newCtx.onDispose(clearDispose);
|
|
147
160
|
return newCtx;
|
|
148
161
|
}
|
|
162
|
+
|
|
163
|
+
getAttribute(key: string): any {
|
|
164
|
+
if (key in this._attributes) {
|
|
165
|
+
return this._attributes[key];
|
|
166
|
+
}
|
|
167
|
+
if (this._parent !== null) {
|
|
168
|
+
return this._parent.getAttribute(key);
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
149
172
|
}
|