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