@evolu/common 8.0.0-next.2 → 8.0.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/Assert.d.ts +5 -5
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +4 -4
- package/dist/src/Identicon.js +4 -4
- package/dist/src/LockManager.d.ts +74 -0
- package/dist/src/LockManager.d.ts.map +1 -0
- package/dist/src/LockManager.js +103 -0
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +90 -26
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +153 -68
- package/dist/src/Resource.d.ts +6 -6
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +211 -162
- package/dist/src/Schedule.d.ts +5 -5
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +53 -44
- package/dist/src/Sqlite.d.ts +2 -0
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +64 -40
- package/dist/src/Task.d.ts +6 -33
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +213 -204
- package/dist/src/Test.d.ts +4 -4
- package/dist/src/Time.d.ts +5 -0
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +5 -0
- package/dist/src/Type.d.ts +7 -0
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +7 -0
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +7 -6
- package/dist/src/Worker.d.ts +42 -8
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +298 -75
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/local-first/Db.d.ts +5 -4
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +44 -38
- package/dist/src/local-first/Evolu.d.ts +3 -2
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +90 -80
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Shared.d.ts +65 -54
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +387 -373
- package/package.json +1 -1
- package/src/Array.ts +8 -8
- package/src/Assert.ts +5 -5
- package/src/Identicon.ts +4 -4
- package/src/LockManager.ts +181 -0
- package/src/Microtask.ts +17 -11
- package/src/Object.ts +3 -3
- package/src/RefCount.ts +25 -21
- package/src/Resource.ts +63 -56
- package/src/Schedule.ts +70 -48
- package/src/Set.ts +4 -4
- package/src/Sqlite.ts +41 -30
- package/src/Task.ts +77 -120
- package/src/Test.ts +4 -4
- package/src/Time.ts +7 -0
- package/src/Type.ts +9 -0
- package/src/WebSocket.ts +7 -6
- package/src/Worker.ts +240 -49
- package/src/index.ts +1 -0
- package/src/local-first/Db.ts +69 -46
- package/src/local-first/Evolu.ts +74 -68
- package/src/local-first/Owner.ts +1 -1
- package/src/local-first/Query.ts +1 -1
- package/src/local-first/Shared.ts +472 -464
package/dist/src/Assert.d.ts
CHANGED
|
@@ -94,11 +94,11 @@ export declare function assertNotAborted<T, E>(result: Result<T, E | AbortError>
|
|
|
94
94
|
* ### Example
|
|
95
95
|
*
|
|
96
96
|
* ```ts
|
|
97
|
-
*
|
|
98
|
-
* assertNotDisposed(
|
|
99
|
-
* await
|
|
100
|
-
* assertNotDisposed(
|
|
97
|
+
* using disposer = new globalThis.AsyncDisposableStack();
|
|
98
|
+
* assertNotDisposed(disposer); // no-op
|
|
99
|
+
* await disposer.disposeAsync();
|
|
100
|
+
* assertNotDisposed(disposer); // throws Error
|
|
101
101
|
* ```
|
|
102
102
|
*/
|
|
103
|
-
export declare const assertNotDisposed: (value:
|
|
103
|
+
export declare const assertNotDisposed: (value: DisposableStack | AsyncDisposableStack) => void;
|
|
104
104
|
//# sourceMappingURL=Assert.d.ts.map
|
package/dist/src/Assert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Assert.d.ts","sourceRoot":"","sources":["../../src/Assert.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAQ,MAAM,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,MAAM,EAAE,CACnB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,SAIZ,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAClC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAKlC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,EAAE,CAAC,CAAC,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAK3C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,EACzC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAEhC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3B,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EACnC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAYlC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"Assert.d.ts","sourceRoot":"","sources":["../../src/Assert.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAQ,MAAM,WAAW,CAAC;AAE1D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,MAAM,EAAE,CACnB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,SAIZ,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAClC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAKlC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,EAAE,CAAC,CAAC,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAK3C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,UAAU,EAAE,CAAC,CAAC,SAAS,OAAO,EACzC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC,CAEhC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,UAAU,CAAC,EAC7B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3B,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EACnC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,EACjC,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAYlC;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,eAAe,GAAG,oBAAoB,KAC5C,IAEF,CAAC"}
|
package/dist/src/Assert.js
CHANGED
|
@@ -90,10 +90,10 @@ export function assertNotAborted(result, message = "Expected result to not be ab
|
|
|
90
90
|
* ### Example
|
|
91
91
|
*
|
|
92
92
|
* ```ts
|
|
93
|
-
*
|
|
94
|
-
* assertNotDisposed(
|
|
95
|
-
* await
|
|
96
|
-
* assertNotDisposed(
|
|
93
|
+
* using disposer = new globalThis.AsyncDisposableStack();
|
|
94
|
+
* assertNotDisposed(disposer); // no-op
|
|
95
|
+
* await disposer.disposeAsync();
|
|
96
|
+
* assertNotDisposed(disposer); // throws Error
|
|
97
97
|
* ```
|
|
98
98
|
*/
|
|
99
99
|
export const assertNotDisposed = (value) => {
|
package/dist/src/Identicon.js
CHANGED
|
@@ -106,15 +106,15 @@ export const createIdenticon = (id, style = "github") => {
|
|
|
106
106
|
case "sutnar": {
|
|
107
107
|
// Three compositional variants with adaptive colors.
|
|
108
108
|
const hue = (bytes[0] / 255) * 360;
|
|
109
|
-
const saturation =
|
|
110
|
-
const lightness =
|
|
109
|
+
const saturation = 60 + (bytes[1] / 255) * 30;
|
|
110
|
+
const lightness = 35 + (bytes[2] / 255) * 20;
|
|
111
111
|
// Generate palette from base hue with variations
|
|
112
112
|
const toHsl = (h, s, l) => `hsl(${h},${s}%,${l}%)`;
|
|
113
113
|
const color1 = toHsl(hue, saturation, lightness);
|
|
114
114
|
const color2 = toHsl((hue + 120) % 360, saturation, lightness);
|
|
115
115
|
const color3 = toHsl((hue + 240) % 360, saturation, lightness);
|
|
116
|
-
const color4 = toHsl(hue, saturation * 0.
|
|
117
|
-
const color5 = toHsl(hue, saturation * 0.5, Math.min(lightness * 1.3,
|
|
116
|
+
const color4 = toHsl(hue, saturation * 0.5, lightness * 0.6);
|
|
117
|
+
const color5 = toHsl(hue, saturation * 0.5, Math.min(lightness * 1.3, 60));
|
|
118
118
|
const palette = [color1, color2, color3, color4, color5];
|
|
119
119
|
// Layout variant based on first byte.
|
|
120
120
|
const variant = bytes[3] % 3;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {@link LockManager} helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { AbortError, type Task } from "./Task.js";
|
|
7
|
+
import type { Callback } from "./Types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Dependency wrapper for {@link LockManager}.
|
|
10
|
+
*
|
|
11
|
+
* For React Native, use the `lockManager` ponyfill from `@evolu/react-native`.
|
|
12
|
+
* For tests, use {@link testCreateLockManager}.
|
|
13
|
+
*
|
|
14
|
+
* ### Example
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* // Web or Node.js 24+
|
|
18
|
+
* import { testCreateLockManager } from "@evolu/common";
|
|
19
|
+
*
|
|
20
|
+
* const deps: LockManagerDep = {
|
|
21
|
+
* lockManager: testCreateLockManager(),
|
|
22
|
+
* };
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* ### Example
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* // React Native
|
|
29
|
+
* import { lockManager } from "@evolu/react-native";
|
|
30
|
+
*
|
|
31
|
+
* const deps: LockManagerDep = { lockManager };
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export interface LockManagerDep {
|
|
35
|
+
readonly lockManager: LockManager;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Creates a test {@link LockManager} backed by the native platform
|
|
39
|
+
* {@link LockManager}.
|
|
40
|
+
*
|
|
41
|
+
* Native backing is intentional: tests must observe the same locking behavior
|
|
42
|
+
* as the platform runtime, and a userland implementation cannot reproduce it.
|
|
43
|
+
*
|
|
44
|
+
* The platform `LockManager` cannot be instantiated, so tests cannot create an
|
|
45
|
+
* isolated native lock per case. This helper isolates lock usage per instance
|
|
46
|
+
* via internal namespacing, so tests can reuse the same lock names without
|
|
47
|
+
* contending through the global Web Locks. Query results are filtered to that
|
|
48
|
+
* private namespace and returned with the original visible names.
|
|
49
|
+
*/
|
|
50
|
+
export declare const testCreateLockManager: (nativeLockManager?: LockManager) => LockManager;
|
|
51
|
+
/**
|
|
52
|
+
* Competes to become the current leader for `name` using {@link LockManager}.
|
|
53
|
+
*
|
|
54
|
+
* Only one caller can lead for a given name at a time, and the returned
|
|
55
|
+
* {@link AsyncDisposable} represents that leadership.
|
|
56
|
+
*
|
|
57
|
+
* Leadership is held until the returned handle is disposed. Once released,
|
|
58
|
+
* another waiting caller may become the next leader. Waiting for leadership is
|
|
59
|
+
* abortable via the calling {@link Task}'s signal.
|
|
60
|
+
*/
|
|
61
|
+
export declare const acquireLeaderLock: (name: string) => Task<AsyncDisposable, AbortError, LockManagerDep>;
|
|
62
|
+
/**
|
|
63
|
+
* Competes to become the current leader for `name` using {@link LockManager}.
|
|
64
|
+
*
|
|
65
|
+
* Only one caller can lead for a given name at a time. The callback runs when
|
|
66
|
+
* leadership is acquired, and the returned {@link Disposable} represents that
|
|
67
|
+
* leadership request.
|
|
68
|
+
*
|
|
69
|
+
* Leadership is held until the returned handle is disposed. Once released,
|
|
70
|
+
* another waiting caller may become the next leader. Waiting for leadership is
|
|
71
|
+
* abortable by disposing the returned handle.
|
|
72
|
+
*/
|
|
73
|
+
export declare const acquireLeaderLockCallback: (deps: LockManagerDep) => (name: string, callback: Callback<void>) => Disposable;
|
|
74
|
+
//# sourceMappingURL=LockManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LockManager.d.ts","sourceRoot":"","sources":["../../src/LockManager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;CACnC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GAChC,oBAAmB,WAAwC,KAC1D,WAwCF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAC3B,MAAM,MAAM,KAAG,IAAI,CAAC,eAAe,EAAE,UAAU,EAAE,cAAc,CA4B7D,CAAC;AAEN;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,GACnC,MAAM,cAAc,MACpB,MAAM,MAAM,EAAE,UAAU,QAAQ,CAAC,IAAI,CAAC,KAAG,UAsBzC,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {@link LockManager} helpers.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { createRandomBytes } from "./Crypto.js";
|
|
7
|
+
import { lazyVoid } from "./Function.js";
|
|
8
|
+
import { tryAsync } from "./Result.js";
|
|
9
|
+
import { AbortError } from "./Task.js";
|
|
10
|
+
import { createId } from "./Type.js";
|
|
11
|
+
/**
|
|
12
|
+
* Creates a test {@link LockManager} backed by the native platform
|
|
13
|
+
* {@link LockManager}.
|
|
14
|
+
*
|
|
15
|
+
* Native backing is intentional: tests must observe the same locking behavior
|
|
16
|
+
* as the platform runtime, and a userland implementation cannot reproduce it.
|
|
17
|
+
*
|
|
18
|
+
* The platform `LockManager` cannot be instantiated, so tests cannot create an
|
|
19
|
+
* isolated native lock per case. This helper isolates lock usage per instance
|
|
20
|
+
* via internal namespacing, so tests can reuse the same lock names without
|
|
21
|
+
* contending through the global Web Locks. Query results are filtered to that
|
|
22
|
+
* private namespace and returned with the original visible names.
|
|
23
|
+
*/
|
|
24
|
+
export const testCreateLockManager = (nativeLockManager = globalThis.navigator.locks) => {
|
|
25
|
+
const namespace = createId({ randomBytes: createRandomBytes() });
|
|
26
|
+
const filterLockInfosByNamespace = (locks) => locks.flatMap((lock) => lock.name?.endsWith(namespace) === true
|
|
27
|
+
? [{ ...lock, name: lock.name.slice(0, -namespace.length) }]
|
|
28
|
+
: []);
|
|
29
|
+
return {
|
|
30
|
+
request: (name, optionsOrCallback, maybeCallback) => {
|
|
31
|
+
const [options, callback] = typeof optionsOrCallback === "function"
|
|
32
|
+
? [{}, optionsOrCallback]
|
|
33
|
+
: [optionsOrCallback, maybeCallback];
|
|
34
|
+
return nativeLockManager.request(`${name}${namespace}`, options, (lock) => callback(lock && { mode: lock.mode, name }));
|
|
35
|
+
},
|
|
36
|
+
query: async () => {
|
|
37
|
+
const locks = await nativeLockManager.query();
|
|
38
|
+
return {
|
|
39
|
+
...(locks.held && {
|
|
40
|
+
held: filterLockInfosByNamespace(locks.held),
|
|
41
|
+
}),
|
|
42
|
+
...(locks.pending && {
|
|
43
|
+
pending: filterLockInfosByNamespace(locks.pending),
|
|
44
|
+
}),
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Competes to become the current leader for `name` using {@link LockManager}.
|
|
51
|
+
*
|
|
52
|
+
* Only one caller can lead for a given name at a time, and the returned
|
|
53
|
+
* {@link AsyncDisposable} represents that leadership.
|
|
54
|
+
*
|
|
55
|
+
* Leadership is held until the returned handle is disposed. Once released,
|
|
56
|
+
* another waiting caller may become the next leader. Waiting for leadership is
|
|
57
|
+
* abortable via the calling {@link Task}'s signal.
|
|
58
|
+
*/
|
|
59
|
+
export const acquireLeaderLock = (name) => (run) => tryAsync(async () => {
|
|
60
|
+
const acquisition = Promise.withResolvers();
|
|
61
|
+
const released = Promise.withResolvers();
|
|
62
|
+
const request = run.deps.lockManager.request(createLeaderLockName(name), { mode: "exclusive", signal: run.signal }, async () => {
|
|
63
|
+
acquisition.resolve();
|
|
64
|
+
await released.promise;
|
|
65
|
+
});
|
|
66
|
+
void request.catch(acquisition.reject);
|
|
67
|
+
await acquisition.promise;
|
|
68
|
+
return {
|
|
69
|
+
[Symbol.asyncDispose]: async () => {
|
|
70
|
+
released.resolve();
|
|
71
|
+
await request;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}, (error) => AbortError.is(error) ? error : { type: "AbortError", reason: error });
|
|
75
|
+
/**
|
|
76
|
+
* Competes to become the current leader for `name` using {@link LockManager}.
|
|
77
|
+
*
|
|
78
|
+
* Only one caller can lead for a given name at a time. The callback runs when
|
|
79
|
+
* leadership is acquired, and the returned {@link Disposable} represents that
|
|
80
|
+
* leadership request.
|
|
81
|
+
*
|
|
82
|
+
* Leadership is held until the returned handle is disposed. Once released,
|
|
83
|
+
* another waiting caller may become the next leader. Waiting for leadership is
|
|
84
|
+
* abortable by disposing the returned handle.
|
|
85
|
+
*/
|
|
86
|
+
export const acquireLeaderLockCallback = (deps) => (name, callback) => {
|
|
87
|
+
const abortController = new AbortController();
|
|
88
|
+
let release = null;
|
|
89
|
+
const request = deps.lockManager.request(createLeaderLockName(name), { mode: "exclusive", signal: abortController.signal }, async () => {
|
|
90
|
+
const released = Promise.withResolvers();
|
|
91
|
+
release = released.resolve;
|
|
92
|
+
callback();
|
|
93
|
+
await released.promise;
|
|
94
|
+
});
|
|
95
|
+
void request.catch(lazyVoid);
|
|
96
|
+
return {
|
|
97
|
+
[Symbol.dispose]: () => {
|
|
98
|
+
abortController.abort();
|
|
99
|
+
release?.();
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
const createLeaderLockName = (name) => `evolu-leaderlock-${name}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Microtask.d.ts","sourceRoot":"","sources":["../../src/Microtask.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"Microtask.d.ts","sourceRoot":"","sources":["../../src/Microtask.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiB,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGvE;;;;;GAKG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,CAAE,SAAQ,UAAU;IACnD,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAEjC,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,sCAAsC;AACtC,eAAO,MAAM,oBAAoB,GAAI,CAAC,EACpC,SAAS,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAAI,KACjD,cAAc,CAAC,CAAC,CAqClB,CAAC"}
|
package/dist/src/Microtask.js
CHANGED
|
@@ -3,35 +3,99 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
7
|
+
if (value !== null && value !== void 0) {
|
|
8
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
9
|
+
var dispose, inner;
|
|
10
|
+
if (async) {
|
|
11
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
12
|
+
dispose = value[Symbol.asyncDispose];
|
|
13
|
+
}
|
|
14
|
+
if (dispose === void 0) {
|
|
15
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.dispose];
|
|
17
|
+
if (async) inner = dispose;
|
|
18
|
+
}
|
|
19
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
20
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
21
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
22
|
+
}
|
|
23
|
+
else if (async) {
|
|
24
|
+
env.stack.push({ async: true });
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
29
|
+
return function (env) {
|
|
30
|
+
function fail(e) {
|
|
31
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
32
|
+
env.hasError = true;
|
|
33
|
+
}
|
|
34
|
+
var r, s = 0;
|
|
35
|
+
function next() {
|
|
36
|
+
while (r = env.stack.pop()) {
|
|
37
|
+
try {
|
|
38
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
39
|
+
if (r.dispose) {
|
|
40
|
+
var result = r.dispose.call(r.value);
|
|
41
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
42
|
+
}
|
|
43
|
+
else s |= 1;
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
fail(e);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
50
|
+
if (env.hasError) throw env.error;
|
|
51
|
+
}
|
|
52
|
+
return next();
|
|
53
|
+
};
|
|
54
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
55
|
+
var e = new Error(message);
|
|
56
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
|
+
});
|
|
6
58
|
import { appendToArray } from "./Array.js";
|
|
59
|
+
import { assertNotDisposed } from "./Assert.js";
|
|
7
60
|
/** Creates {@link MicrotaskBatch}. */
|
|
8
61
|
export const createMicrotaskBatch = (onFlush) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
push: (item) => {
|
|
20
|
-
if (disposed)
|
|
21
|
-
return;
|
|
22
|
-
if (queue == null) {
|
|
23
|
-
queue = [item];
|
|
24
|
-
queueMicrotask(flushNow);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
queue = appendToArray(queue, item);
|
|
28
|
-
},
|
|
29
|
-
flushNow,
|
|
30
|
-
[Symbol.dispose]: () => {
|
|
31
|
-
if (disposed)
|
|
62
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
63
|
+
try {
|
|
64
|
+
const disposer = __addDisposableResource(env_1, new DisposableStack(), false);
|
|
65
|
+
let queue = null;
|
|
66
|
+
disposer.defer(() => {
|
|
67
|
+
queue = null;
|
|
68
|
+
});
|
|
69
|
+
const disposables = disposer.move();
|
|
70
|
+
const flushQueuedItems = () => {
|
|
71
|
+
if (queue == null)
|
|
32
72
|
return;
|
|
33
|
-
|
|
73
|
+
const queuedItems = queue;
|
|
34
74
|
queue = null;
|
|
35
|
-
|
|
36
|
-
|
|
75
|
+
onFlush(queuedItems);
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
push: (item) => {
|
|
79
|
+
assertNotDisposed(disposables);
|
|
80
|
+
if (queue == null) {
|
|
81
|
+
queue = [item];
|
|
82
|
+
queueMicrotask(flushQueuedItems);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
queue = appendToArray(queue, item);
|
|
86
|
+
},
|
|
87
|
+
flushNow: () => {
|
|
88
|
+
assertNotDisposed(disposables);
|
|
89
|
+
flushQueuedItems();
|
|
90
|
+
},
|
|
91
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (e_1) {
|
|
95
|
+
env_1.error = e_1;
|
|
96
|
+
env_1.hasError = true;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
__disposeResources(env_1);
|
|
100
|
+
}
|
|
37
101
|
};
|
package/dist/src/Object.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Object.d.ts","sourceRoot":"","sources":["../../src/Object.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,GAAG,EAAE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,OAAO,KACb,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAOjC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,UAAU,CAAC,QACnC,CAAC;AAE9B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,QAAQ,CAAC,OAAO,CAEA,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3D,QAAQ,CAAC,KACR,aAAa,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"Object.d.ts","sourceRoot":"","sources":["../../src/Object.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RefCount.d.ts","sourceRoot":"","sources":["../../src/RefCount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAsB,MAAM,WAAW,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,WAAW,CAAC;IAEtC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,cAAc,CAAC;IAEzC,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,cAAc,CAAC;IAExC,uEAAuE;IACvE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,gCAAgC;AAChC,eAAO,MAAM,cAAc,QAAO,
|
|
1
|
+
{"version":3,"file":"RefCount.d.ts","sourceRoot":"","sources":["../../src/RefCount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAgC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,WAAW,EAAsB,MAAM,WAAW,CAAC;AAE5E;;;;GAIG;AACH,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,MAAM,WAAW,CAAC;IAEtC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,cAAc,CAAC;IAEzC,iCAAiC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,cAAc,CAAC;IAExC,uEAAuE;IACvE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,gCAAgC;AAChC,eAAO,MAAM,cAAc,QAAO,QA4BjC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa,CAAC,IAAI,CAAE,SAAQ,UAAU;IACrD,sDAAsD;IACtD,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,WAAW,CAAC;IAE/C;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,cAAc,CAAC;IAElD,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,cAAc,CAAC;IAEjD,2EAA2E;IAC3E,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC;IAErC,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;IAEvC,uEAAuE;IACvE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,+CAA+C;AAC/C,MAAM,WAAW,0BAA0B,CACzC,IAAI,EACJ,CAAC,GAAG,IAAI,CACR,SAAQ,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;CAAG;AAElC,qCAAqC;AACrC,wBAAgB,mBAAmB,CAAC,IAAI,GAAG,OAAO,KAAK,aAAa,CAAC,IAAI,CAAC,CAAC;AAC3E,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,EACzC,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,CAAC,CAAC,GAC3C,aAAa,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/src/RefCount.js
CHANGED
|
@@ -3,81 +3,166 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
7
|
+
if (value !== null && value !== void 0) {
|
|
8
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
9
|
+
var dispose, inner;
|
|
10
|
+
if (async) {
|
|
11
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
12
|
+
dispose = value[Symbol.asyncDispose];
|
|
13
|
+
}
|
|
14
|
+
if (dispose === void 0) {
|
|
15
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.dispose];
|
|
17
|
+
if (async) inner = dispose;
|
|
18
|
+
}
|
|
19
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
20
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
21
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
22
|
+
}
|
|
23
|
+
else if (async) {
|
|
24
|
+
env.stack.push({ async: true });
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
29
|
+
return function (env) {
|
|
30
|
+
function fail(e) {
|
|
31
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
32
|
+
env.hasError = true;
|
|
33
|
+
}
|
|
34
|
+
var r, s = 0;
|
|
35
|
+
function next() {
|
|
36
|
+
while (r = env.stack.pop()) {
|
|
37
|
+
try {
|
|
38
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
39
|
+
if (r.dispose) {
|
|
40
|
+
var result = r.dispose.call(r.value);
|
|
41
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
42
|
+
}
|
|
43
|
+
else s |= 1;
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
fail(e);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
50
|
+
if (env.hasError) throw env.error;
|
|
51
|
+
}
|
|
52
|
+
return next();
|
|
53
|
+
};
|
|
54
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
55
|
+
var e = new Error(message);
|
|
56
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
|
+
});
|
|
6
58
|
import { assert, assertNotDisposed } from "./Assert.js";
|
|
7
59
|
import { identity } from "./Function.js";
|
|
8
60
|
import { createLookupMap } from "./Lookup.js";
|
|
9
61
|
import { NonNegativeInt, PositiveInt, zeroNonNegativeInt } from "./Type.js";
|
|
10
62
|
/** Creates {@link RefCount}. */
|
|
11
63
|
export const createRefCount = () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
64
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
65
|
+
try {
|
|
66
|
+
// We use DisposableStack only because of assertNotDisposed.
|
|
67
|
+
const disposer = __addDisposableResource(env_1, new DisposableStack(), false);
|
|
68
|
+
let count = zeroNonNegativeInt;
|
|
69
|
+
const disposables = disposer.move();
|
|
70
|
+
return {
|
|
71
|
+
increment: () => {
|
|
72
|
+
assertNotDisposed(disposables);
|
|
73
|
+
const nextCount = PositiveInt.orThrow(count + 1);
|
|
74
|
+
count = nextCount;
|
|
75
|
+
return nextCount;
|
|
76
|
+
},
|
|
77
|
+
decrement: () => {
|
|
78
|
+
assertNotDisposed(disposables);
|
|
79
|
+
assert(count > 0, "RefCount must not be decremented below zero.");
|
|
80
|
+
count = NonNegativeInt.orThrow(count - 1);
|
|
81
|
+
return count;
|
|
82
|
+
},
|
|
83
|
+
getCount: () => {
|
|
84
|
+
assertNotDisposed(disposables);
|
|
85
|
+
return count;
|
|
86
|
+
},
|
|
87
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (e_1) {
|
|
91
|
+
env_1.error = e_1;
|
|
92
|
+
env_1.hasError = true;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
__disposeResources(env_1);
|
|
96
|
+
}
|
|
37
97
|
};
|
|
38
98
|
export function createRefCountByKey({ lookup = identity, } = {}) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
refCountByKey.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
return {
|
|
55
|
-
increment: (key) => {
|
|
56
|
-
assertNotDisposed(moved);
|
|
57
|
-
return getRefCount(key).increment();
|
|
58
|
-
},
|
|
59
|
-
decrement: (key) => {
|
|
60
|
-
assertNotDisposed(moved);
|
|
61
|
-
const refCount = getRefCount(key);
|
|
62
|
-
const nextCount = refCount.decrement();
|
|
63
|
-
if (nextCount === 0) {
|
|
64
|
-
refCount[Symbol.dispose]();
|
|
65
|
-
refCountByKey.delete(key);
|
|
99
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
100
|
+
try {
|
|
101
|
+
// We use DisposableStack only because of assertNotDisposed.
|
|
102
|
+
const disposer = __addDisposableResource(env_2, new DisposableStack(), false);
|
|
103
|
+
const refCountByKey = disposer.adopt(createLookupMap({ lookup }), (refCountByKey) => {
|
|
104
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
105
|
+
try {
|
|
106
|
+
const disposer = __addDisposableResource(env_3, new DisposableStack(), false);
|
|
107
|
+
disposer.defer(() => {
|
|
108
|
+
refCountByKey.clear();
|
|
109
|
+
});
|
|
110
|
+
for (const refCount of refCountByKey.values()) {
|
|
111
|
+
disposer.use(refCount);
|
|
112
|
+
}
|
|
66
113
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
114
|
+
catch (e_3) {
|
|
115
|
+
env_3.error = e_3;
|
|
116
|
+
env_3.hasError = true;
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
__disposeResources(env_3);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
const disposables = disposer.move();
|
|
123
|
+
const getRefCount = (key) => {
|
|
124
|
+
let refCount = refCountByKey.get(key);
|
|
125
|
+
if (!refCount) {
|
|
126
|
+
refCount = createRefCount();
|
|
127
|
+
refCountByKey.set(key, refCount);
|
|
128
|
+
}
|
|
129
|
+
return refCount;
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
increment: (key) => {
|
|
133
|
+
assertNotDisposed(disposables);
|
|
134
|
+
return getRefCount(key).increment();
|
|
135
|
+
},
|
|
136
|
+
decrement: (key) => {
|
|
137
|
+
assertNotDisposed(disposables);
|
|
138
|
+
const refCount = getRefCount(key);
|
|
139
|
+
const nextCount = refCount.decrement();
|
|
140
|
+
if (nextCount === 0) {
|
|
141
|
+
refCountByKey.delete(key);
|
|
142
|
+
refCount[Symbol.dispose]();
|
|
143
|
+
}
|
|
144
|
+
return nextCount;
|
|
145
|
+
},
|
|
146
|
+
getCount: (key) => {
|
|
147
|
+
assertNotDisposed(disposables);
|
|
148
|
+
return refCountByKey.get(key)?.getCount() ?? zeroNonNegativeInt;
|
|
149
|
+
},
|
|
150
|
+
has: (key) => {
|
|
151
|
+
assertNotDisposed(disposables);
|
|
152
|
+
return refCountByKey.has(key);
|
|
153
|
+
},
|
|
154
|
+
keys: () => {
|
|
155
|
+
assertNotDisposed(disposables);
|
|
156
|
+
return new Set(refCountByKey.keys());
|
|
157
|
+
},
|
|
158
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch (e_2) {
|
|
162
|
+
env_2.error = e_2;
|
|
163
|
+
env_2.hasError = true;
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
__disposeResources(env_2);
|
|
167
|
+
}
|
|
83
168
|
}
|