@dxos/context 0.8.4-main.e098934 → 0.8.4-main.e8ec1fe
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 +144 -292
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +144 -292
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/resource.d.ts +16 -3
- package/dist/types/src/resource.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/resource.ts +27 -8
|
@@ -14,59 +14,6 @@ var ContextDisposedError = class extends Error {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
// src/context.ts
|
|
17
|
-
function _check_private_redeclaration(obj, privateCollection) {
|
|
18
|
-
if (privateCollection.has(obj)) {
|
|
19
|
-
throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function _class_apply_descriptor_get(receiver, descriptor) {
|
|
23
|
-
if (descriptor.get) {
|
|
24
|
-
return descriptor.get.call(receiver);
|
|
25
|
-
}
|
|
26
|
-
return descriptor.value;
|
|
27
|
-
}
|
|
28
|
-
function _class_apply_descriptor_set(receiver, descriptor, value) {
|
|
29
|
-
if (descriptor.set) {
|
|
30
|
-
descriptor.set.call(receiver, value);
|
|
31
|
-
} else {
|
|
32
|
-
if (!descriptor.writable) {
|
|
33
|
-
throw new TypeError("attempted to set read only private field");
|
|
34
|
-
}
|
|
35
|
-
descriptor.value = value;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function _class_extract_field_descriptor(receiver, privateMap, action) {
|
|
39
|
-
if (!privateMap.has(receiver)) {
|
|
40
|
-
throw new TypeError("attempted to " + action + " private field on non-instance");
|
|
41
|
-
}
|
|
42
|
-
return privateMap.get(receiver);
|
|
43
|
-
}
|
|
44
|
-
function _class_private_field_get(receiver, privateMap) {
|
|
45
|
-
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "get");
|
|
46
|
-
return _class_apply_descriptor_get(receiver, descriptor);
|
|
47
|
-
}
|
|
48
|
-
function _class_private_field_init(obj, privateMap, value) {
|
|
49
|
-
_check_private_redeclaration(obj, privateMap);
|
|
50
|
-
privateMap.set(obj, value);
|
|
51
|
-
}
|
|
52
|
-
function _class_private_field_set(receiver, privateMap, value) {
|
|
53
|
-
var descriptor = _class_extract_field_descriptor(receiver, privateMap, "set");
|
|
54
|
-
_class_apply_descriptor_set(receiver, descriptor, value);
|
|
55
|
-
return value;
|
|
56
|
-
}
|
|
57
|
-
function _define_property(obj, key, value) {
|
|
58
|
-
if (key in obj) {
|
|
59
|
-
Object.defineProperty(obj, key, {
|
|
60
|
-
value,
|
|
61
|
-
enumerable: true,
|
|
62
|
-
configurable: true,
|
|
63
|
-
writable: true
|
|
64
|
-
});
|
|
65
|
-
} else {
|
|
66
|
-
obj[key] = value;
|
|
67
|
-
}
|
|
68
|
-
return obj;
|
|
69
|
-
}
|
|
70
17
|
function _ts_decorate(decorators, target, key, desc) {
|
|
71
18
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
72
19
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -85,25 +32,41 @@ var DEFAULT_ERROR_HANDLER = (error, ctx) => {
|
|
|
85
32
|
};
|
|
86
33
|
var CONTEXT_FLAG_IS_DISPOSED = 1 << 0;
|
|
87
34
|
var CONTEXT_FLAG_LEAK_DETECTED = 1 << 1;
|
|
88
|
-
var _disposeCallbacks = /* @__PURE__ */ new WeakMap();
|
|
89
|
-
var _name = /* @__PURE__ */ new WeakMap();
|
|
90
|
-
var _parent = /* @__PURE__ */ new WeakMap();
|
|
91
|
-
var _attributes = /* @__PURE__ */ new WeakMap();
|
|
92
|
-
var _onError = /* @__PURE__ */ new WeakMap();
|
|
93
|
-
var _flags = /* @__PURE__ */ new WeakMap();
|
|
94
|
-
var _disposePromise = /* @__PURE__ */ new WeakMap();
|
|
95
|
-
var _isDisposed = /* @__PURE__ */ new WeakMap();
|
|
96
|
-
var _leakDetected = /* @__PURE__ */ new WeakMap();
|
|
97
|
-
var _inspect_custom = inspect.custom;
|
|
98
35
|
var Context = class _Context {
|
|
99
36
|
static default() {
|
|
100
37
|
return new _Context();
|
|
101
38
|
}
|
|
39
|
+
#disposeCallbacks = [];
|
|
40
|
+
#name = void 0;
|
|
41
|
+
#parent = void 0;
|
|
42
|
+
#attributes;
|
|
43
|
+
#onError;
|
|
44
|
+
#flags = 0;
|
|
45
|
+
#disposePromise = void 0;
|
|
46
|
+
maxSafeDisposeCallbacks = MAX_SAFE_DISPOSE_CALLBACKS;
|
|
47
|
+
constructor(params = {}, callMeta) {
|
|
48
|
+
this.#name = getContextName(params, callMeta);
|
|
49
|
+
this.#parent = params.parent;
|
|
50
|
+
this.#attributes = params.attributes ?? {};
|
|
51
|
+
this.#onError = params.onError ?? DEFAULT_ERROR_HANDLER;
|
|
52
|
+
}
|
|
53
|
+
get #isDisposed() {
|
|
54
|
+
return !!(this.#flags & CONTEXT_FLAG_IS_DISPOSED);
|
|
55
|
+
}
|
|
56
|
+
set #isDisposed(value) {
|
|
57
|
+
this.#flags = value ? this.#flags | CONTEXT_FLAG_IS_DISPOSED : this.#flags & ~CONTEXT_FLAG_IS_DISPOSED;
|
|
58
|
+
}
|
|
59
|
+
get #leakDetected() {
|
|
60
|
+
return !!(this.#flags & CONTEXT_FLAG_LEAK_DETECTED);
|
|
61
|
+
}
|
|
62
|
+
set #leakDetected(value) {
|
|
63
|
+
this.#flags = value ? this.#flags | CONTEXT_FLAG_LEAK_DETECTED : this.#flags & ~CONTEXT_FLAG_LEAK_DETECTED;
|
|
64
|
+
}
|
|
102
65
|
get disposed() {
|
|
103
|
-
return
|
|
66
|
+
return this.#isDisposed;
|
|
104
67
|
}
|
|
105
68
|
get disposeCallbacksLength() {
|
|
106
|
-
return
|
|
69
|
+
return this.#disposeCallbacks.length;
|
|
107
70
|
}
|
|
108
71
|
/**
|
|
109
72
|
* Schedules a callback to run when the context is disposed.
|
|
@@ -115,13 +78,13 @@ var Context = class _Context {
|
|
|
115
78
|
* @returns A function that can be used to remove the callback from the dispose list.
|
|
116
79
|
*/
|
|
117
80
|
onDispose(callback) {
|
|
118
|
-
if (
|
|
81
|
+
if (this.#isDisposed) {
|
|
119
82
|
void (async () => {
|
|
120
83
|
try {
|
|
121
84
|
await callback();
|
|
122
85
|
} catch (error) {
|
|
123
86
|
log.catch(error, {
|
|
124
|
-
context:
|
|
87
|
+
context: this.#name
|
|
125
88
|
}, {
|
|
126
89
|
F: __dxlog_file,
|
|
127
90
|
L: 119,
|
|
@@ -131,14 +94,14 @@ var Context = class _Context {
|
|
|
131
94
|
}
|
|
132
95
|
})();
|
|
133
96
|
}
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
97
|
+
this.#disposeCallbacks.push(callback);
|
|
98
|
+
if (this.#disposeCallbacks.length > this.maxSafeDisposeCallbacks && !this.#leakDetected) {
|
|
99
|
+
this.#leakDetected = true;
|
|
137
100
|
const callSite = new StackTrace().getStackArray(1)[0].trim();
|
|
138
101
|
log.warn("Context has a large number of dispose callbacks (this might be a memory leak).", {
|
|
139
|
-
context:
|
|
102
|
+
context: this.#name,
|
|
140
103
|
callSite,
|
|
141
|
-
count:
|
|
104
|
+
count: this.#disposeCallbacks.length
|
|
142
105
|
}, {
|
|
143
106
|
F: __dxlog_file,
|
|
144
107
|
L: 128,
|
|
@@ -147,9 +110,9 @@ var Context = class _Context {
|
|
|
147
110
|
});
|
|
148
111
|
}
|
|
149
112
|
return () => {
|
|
150
|
-
const index =
|
|
113
|
+
const index = this.#disposeCallbacks.indexOf(callback);
|
|
151
114
|
if (index !== -1) {
|
|
152
|
-
|
|
115
|
+
this.#disposeCallbacks.splice(index, 1);
|
|
153
116
|
}
|
|
154
117
|
};
|
|
155
118
|
}
|
|
@@ -162,20 +125,20 @@ var Context = class _Context {
|
|
|
162
125
|
* @returns true if there were no errors during the dispose process.
|
|
163
126
|
*/
|
|
164
127
|
async dispose(throwOnError = false) {
|
|
165
|
-
if (
|
|
166
|
-
return
|
|
128
|
+
if (this.#disposePromise) {
|
|
129
|
+
return this.#disposePromise;
|
|
167
130
|
}
|
|
168
|
-
|
|
131
|
+
this.#isDisposed = true;
|
|
169
132
|
let resolveDispose;
|
|
170
133
|
const promise = new Promise((resolve) => {
|
|
171
134
|
resolveDispose = resolve;
|
|
172
135
|
});
|
|
173
|
-
|
|
174
|
-
const callbacks = Array.from(
|
|
175
|
-
|
|
136
|
+
this.#disposePromise = promise;
|
|
137
|
+
const callbacks = Array.from(this.#disposeCallbacks).reverse();
|
|
138
|
+
this.#disposeCallbacks.length = 0;
|
|
176
139
|
if (DEBUG_LOG_DISPOSE) {
|
|
177
140
|
log("disposing", {
|
|
178
|
-
context:
|
|
141
|
+
context: this.#name,
|
|
179
142
|
count: callbacks.length
|
|
180
143
|
}, {
|
|
181
144
|
F: __dxlog_file,
|
|
@@ -197,7 +160,7 @@ var Context = class _Context {
|
|
|
197
160
|
errors.push(err);
|
|
198
161
|
} else {
|
|
199
162
|
log.catch(err, {
|
|
200
|
-
context:
|
|
163
|
+
context: this.#name,
|
|
201
164
|
callback: i,
|
|
202
165
|
count: callbacks.length
|
|
203
166
|
}, {
|
|
@@ -215,7 +178,7 @@ var Context = class _Context {
|
|
|
215
178
|
resolveDispose(clean);
|
|
216
179
|
if (DEBUG_LOG_DISPOSE) {
|
|
217
180
|
log("disposed", {
|
|
218
|
-
context:
|
|
181
|
+
context: this.#name
|
|
219
182
|
}, {
|
|
220
183
|
F: __dxlog_file,
|
|
221
184
|
L: 199,
|
|
@@ -231,11 +194,11 @@ var Context = class _Context {
|
|
|
231
194
|
* IF the error handler is not set, the error will dispose the context and cause an unhandled rejection.
|
|
232
195
|
*/
|
|
233
196
|
raise(error) {
|
|
234
|
-
if (
|
|
197
|
+
if (this.#isDisposed) {
|
|
235
198
|
return;
|
|
236
199
|
}
|
|
237
200
|
try {
|
|
238
|
-
|
|
201
|
+
this.#onError(error, this);
|
|
239
202
|
} catch (err) {
|
|
240
203
|
void Promise.reject(err);
|
|
241
204
|
}
|
|
@@ -261,78 +224,23 @@ var Context = class _Context {
|
|
|
261
224
|
return newCtx;
|
|
262
225
|
}
|
|
263
226
|
getAttribute(key) {
|
|
264
|
-
if (key in
|
|
265
|
-
return
|
|
227
|
+
if (key in this.#attributes) {
|
|
228
|
+
return this.#attributes[key];
|
|
266
229
|
}
|
|
267
|
-
if (
|
|
268
|
-
return
|
|
230
|
+
if (this.#parent) {
|
|
231
|
+
return this.#parent.getAttribute(key);
|
|
269
232
|
}
|
|
270
233
|
return void 0;
|
|
271
234
|
}
|
|
235
|
+
[Symbol.toStringTag] = "Context";
|
|
236
|
+
[inspect.custom] = () => this.toString();
|
|
272
237
|
toString() {
|
|
273
|
-
return `Context(${
|
|
238
|
+
return `Context(${this.#isDisposed ? "disposed" : "active"})`;
|
|
274
239
|
}
|
|
275
240
|
async [Symbol.asyncDispose]() {
|
|
276
241
|
await this.dispose();
|
|
277
242
|
}
|
|
278
|
-
constructor(params = {}, callMeta) {
|
|
279
|
-
_class_private_field_init(this, _isDisposed, {
|
|
280
|
-
get: get_isDisposed,
|
|
281
|
-
set: set_isDisposed
|
|
282
|
-
});
|
|
283
|
-
_class_private_field_init(this, _leakDetected, {
|
|
284
|
-
get: get_leakDetected,
|
|
285
|
-
set: set_leakDetected
|
|
286
|
-
});
|
|
287
|
-
_class_private_field_init(this, _disposeCallbacks, {
|
|
288
|
-
writable: true,
|
|
289
|
-
value: []
|
|
290
|
-
});
|
|
291
|
-
_class_private_field_init(this, _name, {
|
|
292
|
-
writable: true,
|
|
293
|
-
value: void 0
|
|
294
|
-
});
|
|
295
|
-
_class_private_field_init(this, _parent, {
|
|
296
|
-
writable: true,
|
|
297
|
-
value: void 0
|
|
298
|
-
});
|
|
299
|
-
_class_private_field_init(this, _attributes, {
|
|
300
|
-
writable: true,
|
|
301
|
-
value: void 0
|
|
302
|
-
});
|
|
303
|
-
_class_private_field_init(this, _onError, {
|
|
304
|
-
writable: true,
|
|
305
|
-
value: void 0
|
|
306
|
-
});
|
|
307
|
-
_class_private_field_init(this, _flags, {
|
|
308
|
-
writable: true,
|
|
309
|
-
value: 0
|
|
310
|
-
});
|
|
311
|
-
_class_private_field_init(this, _disposePromise, {
|
|
312
|
-
writable: true,
|
|
313
|
-
value: void 0
|
|
314
|
-
});
|
|
315
|
-
_define_property(this, "maxSafeDisposeCallbacks", MAX_SAFE_DISPOSE_CALLBACKS);
|
|
316
|
-
_define_property(this, Symbol.toStringTag, "Context");
|
|
317
|
-
_define_property(this, _inspect_custom, () => this.toString());
|
|
318
|
-
_class_private_field_set(this, _name, getContextName(params, callMeta));
|
|
319
|
-
_class_private_field_set(this, _parent, params.parent);
|
|
320
|
-
_class_private_field_set(this, _attributes, params.attributes ?? {});
|
|
321
|
-
_class_private_field_set(this, _onError, params.onError ?? DEFAULT_ERROR_HANDLER);
|
|
322
|
-
}
|
|
323
243
|
};
|
|
324
|
-
function get_isDisposed() {
|
|
325
|
-
return !!(_class_private_field_get(this, _flags) & CONTEXT_FLAG_IS_DISPOSED);
|
|
326
|
-
}
|
|
327
|
-
function set_isDisposed(value) {
|
|
328
|
-
_class_private_field_set(this, _flags, value ? _class_private_field_get(this, _flags) | CONTEXT_FLAG_IS_DISPOSED : _class_private_field_get(this, _flags) & ~CONTEXT_FLAG_IS_DISPOSED);
|
|
329
|
-
}
|
|
330
|
-
function get_leakDetected() {
|
|
331
|
-
return !!(_class_private_field_get(this, _flags) & CONTEXT_FLAG_LEAK_DETECTED);
|
|
332
|
-
}
|
|
333
|
-
function set_leakDetected(value) {
|
|
334
|
-
_class_private_field_set(this, _flags, value ? _class_private_field_get(this, _flags) | CONTEXT_FLAG_LEAK_DETECTED : _class_private_field_get(this, _flags) & ~CONTEXT_FLAG_LEAK_DETECTED);
|
|
335
|
-
}
|
|
336
244
|
Context = _ts_decorate([
|
|
337
245
|
safeInstanceof("Context")
|
|
338
246
|
], Context);
|
|
@@ -363,92 +271,59 @@ var cancelWithContext = (ctx, promise) => {
|
|
|
363
271
|
|
|
364
272
|
// src/resource.ts
|
|
365
273
|
import { throwUnhandledError } from "@dxos/util";
|
|
366
|
-
|
|
367
|
-
if (privateCollection.has(obj)) {
|
|
368
|
-
throw new TypeError("Cannot initialize the same private elements twice on an object");
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
function _class_apply_descriptor_get2(receiver, descriptor) {
|
|
372
|
-
if (descriptor.get) {
|
|
373
|
-
return descriptor.get.call(receiver);
|
|
374
|
-
}
|
|
375
|
-
return descriptor.value;
|
|
376
|
-
}
|
|
377
|
-
function _class_apply_descriptor_set2(receiver, descriptor, value) {
|
|
378
|
-
if (descriptor.set) {
|
|
379
|
-
descriptor.set.call(receiver, value);
|
|
380
|
-
} else {
|
|
381
|
-
if (!descriptor.writable) {
|
|
382
|
-
throw new TypeError("attempted to set read only private field");
|
|
383
|
-
}
|
|
384
|
-
descriptor.value = value;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
function _class_extract_field_descriptor2(receiver, privateMap, action) {
|
|
388
|
-
if (!privateMap.has(receiver)) {
|
|
389
|
-
throw new TypeError("attempted to " + action + " private field on non-instance");
|
|
390
|
-
}
|
|
391
|
-
return privateMap.get(receiver);
|
|
392
|
-
}
|
|
393
|
-
function _class_private_field_get2(receiver, privateMap) {
|
|
394
|
-
var descriptor = _class_extract_field_descriptor2(receiver, privateMap, "get");
|
|
395
|
-
return _class_apply_descriptor_get2(receiver, descriptor);
|
|
396
|
-
}
|
|
397
|
-
function _class_private_field_init2(obj, privateMap, value) {
|
|
398
|
-
_check_private_redeclaration2(obj, privateMap);
|
|
399
|
-
privateMap.set(obj, value);
|
|
400
|
-
}
|
|
401
|
-
function _class_private_field_set2(receiver, privateMap, value) {
|
|
402
|
-
var descriptor = _class_extract_field_descriptor2(receiver, privateMap, "set");
|
|
403
|
-
_class_apply_descriptor_set2(receiver, descriptor, value);
|
|
404
|
-
return value;
|
|
405
|
-
}
|
|
406
|
-
function _class_private_method_get(receiver, privateSet, fn) {
|
|
407
|
-
if (!privateSet.has(receiver)) {
|
|
408
|
-
throw new TypeError("attempted to get private field on non-instance");
|
|
409
|
-
}
|
|
410
|
-
return fn;
|
|
411
|
-
}
|
|
412
|
-
function _class_private_method_init(obj, privateSet) {
|
|
413
|
-
_check_private_redeclaration2(obj, privateSet);
|
|
414
|
-
privateSet.add(obj);
|
|
415
|
-
}
|
|
416
|
-
var LifecycleState = /* @__PURE__ */ function(LifecycleState2) {
|
|
274
|
+
var LifecycleState = /* @__PURE__ */ (function(LifecycleState2) {
|
|
417
275
|
LifecycleState2["CLOSED"] = "CLOSED";
|
|
418
276
|
LifecycleState2["OPEN"] = "OPEN";
|
|
419
277
|
LifecycleState2["ERROR"] = "ERROR";
|
|
420
278
|
return LifecycleState2;
|
|
421
|
-
}({});
|
|
279
|
+
})({});
|
|
422
280
|
var CLOSE_RESOURCE_ON_UNHANDLED_ERROR = false;
|
|
423
|
-
var _lifecycleState = /* @__PURE__ */ new WeakMap();
|
|
424
|
-
var _openPromise = /* @__PURE__ */ new WeakMap();
|
|
425
|
-
var _closePromise = /* @__PURE__ */ new WeakMap();
|
|
426
|
-
var _internalCtx = /* @__PURE__ */ new WeakMap();
|
|
427
|
-
var _parentCtx = /* @__PURE__ */ new WeakMap();
|
|
428
|
-
var _name2 = /* @__PURE__ */ new WeakMap();
|
|
429
|
-
var _open = /* @__PURE__ */ new WeakSet();
|
|
430
|
-
var _close = /* @__PURE__ */ new WeakSet();
|
|
431
|
-
var _createContext = /* @__PURE__ */ new WeakSet();
|
|
432
|
-
var _createParentContext = /* @__PURE__ */ new WeakSet();
|
|
433
281
|
var Resource = class {
|
|
282
|
+
#lifecycleState = "CLOSED";
|
|
283
|
+
#openPromise = null;
|
|
284
|
+
#closePromise = null;
|
|
285
|
+
/**
|
|
286
|
+
* Managed internally by the resource.
|
|
287
|
+
* Recreated on close.
|
|
288
|
+
* Errors are propagated to the `_catch` method and the parent context.
|
|
289
|
+
*/
|
|
290
|
+
#internalCtx = this.#createContext();
|
|
291
|
+
/**
|
|
292
|
+
* Context that is used to bubble up errors that are not handled by the resource.
|
|
293
|
+
* Provided in the open method.
|
|
294
|
+
*/
|
|
295
|
+
#parentCtx = this.#createParentContext();
|
|
296
|
+
/**
|
|
297
|
+
* ```ts
|
|
298
|
+
* await using resource = new Resource();
|
|
299
|
+
* await resource.open();
|
|
300
|
+
* ```
|
|
301
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using
|
|
302
|
+
*/
|
|
303
|
+
async [Symbol.asyncDispose]() {
|
|
304
|
+
await this.close();
|
|
305
|
+
}
|
|
306
|
+
get #name() {
|
|
307
|
+
return Object.getPrototypeOf(this).constructor.name;
|
|
308
|
+
}
|
|
434
309
|
get isOpen() {
|
|
435
|
-
return
|
|
310
|
+
return this.#lifecycleState === "OPEN" && this.#closePromise == null;
|
|
436
311
|
}
|
|
437
312
|
get _lifecycleState() {
|
|
438
|
-
return
|
|
313
|
+
return this.#lifecycleState;
|
|
439
314
|
}
|
|
440
315
|
get _ctx() {
|
|
441
|
-
return
|
|
316
|
+
return this.#internalCtx;
|
|
442
317
|
}
|
|
443
318
|
/**
|
|
444
319
|
* To be overridden by subclasses.
|
|
445
320
|
*/
|
|
446
|
-
async _open(
|
|
321
|
+
async _open(_ctx) {
|
|
447
322
|
}
|
|
448
323
|
/**
|
|
449
324
|
* To be overridden by subclasses.
|
|
450
325
|
*/
|
|
451
|
-
async _close(
|
|
326
|
+
async _close(_ctx) {
|
|
452
327
|
}
|
|
453
328
|
/**
|
|
454
329
|
* Error handler for errors that are caught by the context.
|
|
@@ -465,6 +340,19 @@ var Resource = class {
|
|
|
465
340
|
throw err;
|
|
466
341
|
}
|
|
467
342
|
/**
|
|
343
|
+
* Calls the provided function, opening and closing the resource.
|
|
344
|
+
* NOTE: Consider using `using` instead.
|
|
345
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using
|
|
346
|
+
*/
|
|
347
|
+
async use(fn) {
|
|
348
|
+
try {
|
|
349
|
+
await this.open();
|
|
350
|
+
return await fn(this);
|
|
351
|
+
} finally {
|
|
352
|
+
await this.close();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
468
356
|
* Opens the resource.
|
|
469
357
|
* If the resource is already open, it does nothing.
|
|
470
358
|
* If the resource is in an error state, it throws an error.
|
|
@@ -472,15 +360,15 @@ var Resource = class {
|
|
|
472
360
|
* @param ctx - Context to use for opening the resource. This context will receive errors that are not handled in `_catch`.
|
|
473
361
|
*/
|
|
474
362
|
async open(ctx) {
|
|
475
|
-
switch (
|
|
363
|
+
switch (this.#lifecycleState) {
|
|
476
364
|
case "OPEN":
|
|
477
365
|
return this;
|
|
478
366
|
case "ERROR":
|
|
479
|
-
throw new Error(`Invalid state: ${
|
|
367
|
+
throw new Error(`Invalid state: ${this.#lifecycleState}`);
|
|
480
368
|
default:
|
|
481
369
|
}
|
|
482
|
-
await
|
|
483
|
-
await
|
|
370
|
+
await this.#closePromise;
|
|
371
|
+
await (this.#openPromise ??= this.#open(ctx));
|
|
484
372
|
return this;
|
|
485
373
|
}
|
|
486
374
|
/**
|
|
@@ -488,98 +376,62 @@ var Resource = class {
|
|
|
488
376
|
* If the resource is already closed, it does nothing.
|
|
489
377
|
*/
|
|
490
378
|
async close(ctx) {
|
|
491
|
-
if (
|
|
379
|
+
if (this.#lifecycleState === "CLOSED") {
|
|
492
380
|
return this;
|
|
493
381
|
}
|
|
494
|
-
await
|
|
495
|
-
await
|
|
382
|
+
await this.#openPromise;
|
|
383
|
+
await (this.#closePromise ??= this.#close(ctx));
|
|
496
384
|
return this;
|
|
497
385
|
}
|
|
498
386
|
/**
|
|
499
387
|
* Waits until the resource is open.
|
|
500
388
|
*/
|
|
501
389
|
async waitUntilOpen() {
|
|
502
|
-
switch (
|
|
390
|
+
switch (this.#lifecycleState) {
|
|
503
391
|
case "OPEN":
|
|
504
392
|
return;
|
|
505
393
|
case "ERROR":
|
|
506
|
-
throw new Error(`Invalid state: ${
|
|
394
|
+
throw new Error(`Invalid state: ${this.#lifecycleState}`);
|
|
507
395
|
}
|
|
508
|
-
if (!
|
|
396
|
+
if (!this.#openPromise) {
|
|
509
397
|
throw new Error("Resource is not being opened");
|
|
510
398
|
}
|
|
511
|
-
await
|
|
512
|
-
}
|
|
513
|
-
async
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
value: _class_private_method_get(this, _createContext, createContext).call(this)
|
|
399
|
+
await this.#openPromise;
|
|
400
|
+
}
|
|
401
|
+
async #open(ctx) {
|
|
402
|
+
this.#closePromise = null;
|
|
403
|
+
this.#parentCtx = ctx?.derive({
|
|
404
|
+
name: this.#name
|
|
405
|
+
}) ?? this.#createParentContext();
|
|
406
|
+
await this._open(this.#parentCtx);
|
|
407
|
+
this.#lifecycleState = "OPEN";
|
|
408
|
+
}
|
|
409
|
+
async #close(ctx = Context.default()) {
|
|
410
|
+
this.#openPromise = null;
|
|
411
|
+
await this.#internalCtx.dispose();
|
|
412
|
+
await this._close(ctx);
|
|
413
|
+
this.#internalCtx = this.#createContext();
|
|
414
|
+
this.#lifecycleState = "CLOSED";
|
|
415
|
+
}
|
|
416
|
+
#createContext() {
|
|
417
|
+
return new Context({
|
|
418
|
+
name: this.#name,
|
|
419
|
+
onError: (error) => queueMicrotask(async () => {
|
|
420
|
+
try {
|
|
421
|
+
await this._catch(error);
|
|
422
|
+
} catch (err) {
|
|
423
|
+
this.#lifecycleState = "ERROR";
|
|
424
|
+
this.#parentCtx.raise(err);
|
|
425
|
+
}
|
|
426
|
+
})
|
|
540
427
|
});
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
428
|
+
}
|
|
429
|
+
#createParentContext() {
|
|
430
|
+
return new Context({
|
|
431
|
+
name: this.#name
|
|
544
432
|
});
|
|
545
433
|
}
|
|
546
434
|
};
|
|
547
|
-
function get_name() {
|
|
548
|
-
return Object.getPrototypeOf(this).constructor.name;
|
|
549
|
-
}
|
|
550
|
-
async function open(ctx) {
|
|
551
|
-
_class_private_field_set2(this, _closePromise, null);
|
|
552
|
-
_class_private_field_set2(this, _parentCtx, ctx?.derive({
|
|
553
|
-
name: _class_private_field_get2(this, _name2)
|
|
554
|
-
}) ?? _class_private_method_get(this, _createParentContext, createParentContext).call(this));
|
|
555
|
-
await this._open(_class_private_field_get2(this, _parentCtx));
|
|
556
|
-
_class_private_field_set2(this, _lifecycleState, "OPEN");
|
|
557
|
-
}
|
|
558
|
-
async function close(ctx = Context.default()) {
|
|
559
|
-
_class_private_field_set2(this, _openPromise, null);
|
|
560
|
-
await _class_private_field_get2(this, _internalCtx).dispose();
|
|
561
|
-
await this._close(ctx);
|
|
562
|
-
_class_private_field_set2(this, _internalCtx, _class_private_method_get(this, _createContext, createContext).call(this));
|
|
563
|
-
_class_private_field_set2(this, _lifecycleState, "CLOSED");
|
|
564
|
-
}
|
|
565
|
-
function createContext() {
|
|
566
|
-
return new Context({
|
|
567
|
-
name: _class_private_field_get2(this, _name2),
|
|
568
|
-
onError: (error) => queueMicrotask(async () => {
|
|
569
|
-
try {
|
|
570
|
-
await this._catch(error);
|
|
571
|
-
} catch (err) {
|
|
572
|
-
_class_private_field_set2(this, _lifecycleState, "ERROR");
|
|
573
|
-
_class_private_field_get2(this, _parentCtx).raise(err);
|
|
574
|
-
}
|
|
575
|
-
})
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
function createParentContext() {
|
|
579
|
-
return new Context({
|
|
580
|
-
name: _class_private_field_get2(this, _name2)
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
435
|
var openInContext = async (ctx, resource) => {
|
|
584
436
|
await resource.open?.(ctx);
|
|
585
437
|
ctx.onDispose(() => resource.close?.());
|