@audiotool/nexus 0.0.8 → 0.0.10

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.
Files changed (36) hide show
  1. package/dist/api.js +2 -2
  2. package/dist/{audiotool-api-BeiEe46q.js → audiotool-api-D9u-oGp3.js} +191 -184
  3. package/dist/document/backend/create-wasm-document-state.d.ts +11 -0
  4. package/dist/document/backend/document-service/connection/index.d.ts +37 -0
  5. package/dist/document/backend/document-service/connection/ping-notifier.d.ts +20 -0
  6. package/dist/document/backend/document-service/connection/transaction-receiver.d.ts +26 -0
  7. package/dist/document/backend/document-service/connection/transaction-receiver.test.d.ts +1 -0
  8. package/dist/document/backend/document-service/connection/transaction-sender.d.ts +17 -0
  9. package/dist/document/backend/document-service/connection/transaction-sender.test.d.ts +1 -0
  10. package/dist/document/backend/document-service/consolidator.d.ts +2 -1
  11. package/dist/document/backend/document-service/gateway.d.ts +18 -32
  12. package/dist/document/backend/gateway.d.ts +22 -2
  13. package/dist/document/backend/validator.d.ts +2 -0
  14. package/dist/document/document.d.ts +24 -15
  15. package/dist/document/event-manager.d.ts +5 -0
  16. package/dist/document/mock/mock-document-state.d.ts +1 -0
  17. package/dist/document.js +1 -1
  18. package/dist/{get-schema-location-details-BSMUliFD.js → get-schema-location-details-CI3Fi5PK.js} +1 -1
  19. package/dist/{observable-notifier-value-pw47I_2-.js → hash-map-CMrPM1s6.js} +87 -88
  20. package/dist/index.js +1117 -1045
  21. package/dist/lang-K-8hAzE4.js +40 -0
  22. package/dist/login-status.d.ts +1 -2
  23. package/dist/synced-document.d.ts +19 -1
  24. package/dist/utils/combine-notifiers.d.ts +1 -1
  25. package/dist/utils/grpc/retrying-client.d.ts +2 -0
  26. package/dist/utils/lang.d.ts +17 -8
  27. package/dist/utils.js +3 -3
  28. package/package.json +2 -1
  29. package/dist/document/backend/document-service/wrapper/buffered-sender.d.ts +0 -29
  30. package/dist/document/backend/document-service/wrapper/create-ping-loop.d.ts +0 -8
  31. package/dist/document/backend/document-service/wrapper/create-receive-next-transaction-fn.d.ts +0 -15
  32. package/dist/document/backend/document-service/wrapper/wrapper.d.ts +0 -41
  33. package/dist/document/init-collab-gateway.d.ts +0 -6
  34. package/dist/lang-KJQpoj7q.js +0 -13
  35. /package/dist/{document/backend/document-service/wrapper/buffered-sender.test.d.ts → audiotool-client.test.d.ts} +0 -0
  36. /package/dist/document/backend/document-service/{wrapper/wrapper.test.d.ts → connection/ping-notifier.test.d.ts} +0 -0
@@ -12,6 +12,8 @@ export type WasmDocumentState = {
12
12
  * * an error string if the transaction is invalid
13
13
  */
14
14
  applyTransaction: (transaction: Transaction) => Transaction | string;
15
+ /** Causes {@link applyTransaction} to throw. Used to clean up memory in the wasm. */
16
+ terminate(): void;
15
17
  };
16
18
  /** Type of object returned by the wasm module if an error happens. */
17
19
  type WasmError = {
@@ -42,4 +44,13 @@ declare global {
42
44
  } | undefined;
43
45
  var createDocumentState: (() => WasmState) | undefined;
44
46
  }
47
+ /**
48
+ * @internal
49
+ *
50
+ * For debugging - tracks how many documents are currently open in wasm but not yet closed.
51
+ *
52
+ * This can be used to assert that all documents have been terminated when a nexus document is terminated.
53
+ * This is important because the wasm memory won't be freed on its own if it's not referenced.
54
+ */
55
+ export declare let DEBUG_totalOpenWasmDocuments: number;
45
56
  export {};
@@ -0,0 +1,37 @@
1
+ import { DocumentService } from '../../../../gen/audiotool/document/v1/document_service_connect';
2
+ import { Transaction } from '../../../../gen/audiotool/document/v1/document_service_pb';
3
+ import { RetryingClient } from '../../../../utils/grpc/retrying-client';
4
+ import { ObservableValue } from '../../../../utils/observable-notifier-value';
5
+
6
+ /** This object represents a connection to the document service. It's built from a document service client.
7
+ *
8
+ * While it isn't terminated, it will continuously ping the backend to check if the connection is still alive,
9
+ * and update the ping value.
10
+ *
11
+ * The parameter {@link connectionOk} turns to false if something goes wrong in a recoverable way.
12
+ * If something goes wrong in an unrecoverable way, the service connection will throw an error in a detached promise.
13
+ *
14
+ */
15
+ export type DocumentServiceConnection = {
16
+ /** The stream of incoming transactions. The document is "loaded" when the first transaction is received.*/
17
+ receiveNextTransaction: AsyncIterable<Transaction, void, void>;
18
+ /** Send the next transaction to the backend, returns a string if the backend rejects it. */
19
+ sendNextTransaction: (t: Transaction) => Promise<string | undefined>;
20
+ /** The current ping to the backend. */
21
+ pingMs: ObservableValue<number>;
22
+ /**
23
+ * Turns to false if any of the three calls (send, receive, ping) fail in a recoverable way.
24
+ */
25
+ connectionOk: ObservableValue<boolean>;
26
+ /** Terminate the connection. Has the following effect:
27
+ * * `receiveNextTransaction` is terminated
28
+ * * `sendNextTransaction` will throw an error
29
+ *
30
+ * Resolves once the last transaction has been sent.
31
+ */
32
+ terminate: () => Promise<void>;
33
+ };
34
+ export declare const createDocumentServiceConnection: (documentService: RetryingClient<typeof DocumentService>, projectName: string, opts?: {
35
+ backoffMs?: number;
36
+ pingIntervalMs?: number;
37
+ }) => DocumentServiceConnection;
@@ -0,0 +1,20 @@
1
+ import { DocumentService } from '../../../../gen/audiotool/document/v1/document_service_connect';
2
+ import { RetryingClient } from '../../../../utils/grpc/retrying-client';
3
+ import { Observable } from '../../../../utils/observable-notifier';
4
+ import { ObservableValue } from '../../../../utils/observable-notifier-value';
5
+
6
+ /** A ping notifier continuously pings the backend to check if the connection is still alive. */
7
+ export type PingNotifier = {
8
+ /** emits a true/false value every time a successful/failed ping is received. */
9
+ pingCallResults: Observable<boolean>;
10
+ /** true while ping call is not retrying */
11
+ connectionOk: ObservableValue<boolean>;
12
+ /** current ping to server, in milliseconds. Currently doesn't update if no ping response is received */
13
+ pingMs: ObservableValue<number>;
14
+ /** Immediately terminates the ping loop. */
15
+ terminate: () => void;
16
+ };
17
+ export declare const createPingNotifier: (documentService: Pick<RetryingClient<typeof DocumentService>, "ping">, projectName: string, opts?: {
18
+ pingIntervalMs?: number;
19
+ clientId?: string;
20
+ }) => PingNotifier;
@@ -0,0 +1,26 @@
1
+ import { DocumentService } from '../../../../gen/audiotool/document/v1/document_service_connect';
2
+ import { Transaction } from '../../../../gen/audiotool/document/v1/document_service_pb';
3
+ import { RetryingClient } from '../../../../utils/grpc/retrying-client';
4
+ import { ObservableValue } from '../../../../utils/observable-notifier-value';
5
+
6
+ export type TransactionReceiver = {
7
+ /** Get the next transaction sent from the backend. On disconnect, just blocks until
8
+ * reconnection. Throws only if unrecoverable. The very first transaction will "load" the current document
9
+ * state, which might be empty if the document is new.
10
+ */
11
+ nextTransactionIterator: AsyncIterable<Transaction, void, void>;
12
+ /**
13
+ * Stops internal logic, terminates the iterator. No effect on connectionOk.
14
+ */
15
+ terminate(): void;
16
+ /** Trigger a recovery of the connection. This should be called if an issue is detected in the logic
17
+ * outside of the iterator (e.g. if the ping call fails), because the connection used internally
18
+ * in this object cannot reliably detect disconnects.
19
+ */
20
+ reconnect(): void;
21
+ /** Turns to false while we're trying to reconnect. */
22
+ connectionOk: ObservableValue<boolean>;
23
+ };
24
+ export declare const createTransactionReceiver: (documentService: Pick<RetryingClient<typeof DocumentService>, "attach">, projectName: string, opts?: {
25
+ backoffMs?: number;
26
+ }) => TransactionReceiver;
@@ -0,0 +1,17 @@
1
+ import { DocumentService } from '../../../../gen/audiotool/document/v1/document_service_connect';
2
+ import { Transaction } from '../../../../gen/audiotool/document/v1/document_service_pb';
3
+ import { RetryingClient } from '../../../../utils/grpc/retrying-client';
4
+ import { ObservableValue } from '../../../../utils/observable-notifier-value';
5
+
6
+ export type TransactionSender = {
7
+ sendNextTransaction: (t: Transaction) => Promise<string | undefined>;
8
+ /** Turns to false if sending is temporarily interrupted. */
9
+ connectionOk: ObservableValue<boolean>;
10
+ /** Terminate this sender. This will cause all sendNextTransaction calls
11
+ * to throw. The promise will resolve once the last transaction has been
12
+ * confirmed as received by the backend, and the sendNextTransaction
13
+ * methods of all pending transactions have been resolved.
14
+ */
15
+ terminate: () => Promise<void>;
16
+ };
17
+ export declare const createTransactionSender: (documentService: Pick<RetryingClient<typeof DocumentService>, "applyTransactions">, projectName: string) => TransactionSender;
@@ -1,5 +1,6 @@
1
1
  import { Transaction } from '../../../gen/audiotool/document/v1/document_service_pb';
2
2
  import { WasmDocumentState } from '../create-wasm-document-state';
3
+ import { ReadonlyTransaction } from '../gateway';
3
4
 
4
5
  /**
5
6
  * This class can be used to "consolidate" two transaction histories in such a way that
@@ -28,5 +29,5 @@ export declare class NexusStateConsolidator {
28
29
  /** new rejected transactions received from the document service. Must be a subset of `newOutgoing`. */
29
30
  newReceivedRejected: Set<string>,
30
31
  /** new locally created transactions */
31
- newCreated: Transaction[]): Transaction[];
32
+ newCreated: Transaction[]): ReadonlyTransaction[];
32
33
  }
@@ -1,36 +1,22 @@
1
- import { Transaction } from '../../../gen/audiotool/document/v1/document_service_pb';
2
- import { ObservableValue } from '../../../utils/observable-notifier-value';
3
1
  import { NexusGateway } from '../gateway';
2
+ import { DocumentService } from '../../../gen/audiotool/document/v1/document_service_connect';
3
+ import { RetryingClient } from '../../../utils/grpc/retrying-client';
4
4
  import { WasmDocumentState } from '../create-wasm-document-state';
5
- import { DocumentServiceWrapper } from './wrapper/wrapper';
6
5
 
7
- /** A gateway that is connected to some collab backend that might:
8
- * * reject transaction
9
- * * reorder transactions
10
- * * interleave transactions with transactions of other clients
6
+ /** Collab gateway returns a gateway that syncs with a document service.
11
7
  */
12
- export declare class CollabGateway implements NexusGateway {
13
- #private;
14
- /**
15
- * Some stats, useful for debugging.
16
- */
17
- static readonly stats: {
18
- numReceivedCtr: number;
19
- numConfirmedCtr: number;
20
- numQueuedCtr: number;
21
- numRejectedCtr: number;
22
- };
23
- readonly blocked: ObservableValue<boolean>;
24
- constructor({ documentService, state, logOutgoingTransactions, logIncomingTransactions, logConsolidatedTransactions, logRejectedTransactions, }: {
25
- documentService: DocumentServiceWrapper;
26
- state: WasmDocumentState;
27
- logOutgoingTransactions?: boolean;
28
- logIncomingTransactions?: boolean;
29
- logConsolidatedTransactions?: boolean;
30
- logRejectedTransactions?: boolean;
31
- });
32
- /** Send a transaction to the document service. */
33
- send(t: Transaction): void;
34
- /** Receive new transactions from the backend, already consolidated with the local change history.*/
35
- synchronize(): Transaction[];
36
- }
8
+ export declare const createCollabGateway: (documentService: RetryingClient<typeof DocumentService>, state: WasmDocumentState, projectName: string, opts?: {
9
+ logOutgoingTransactions?: boolean;
10
+ logIncomingTransactions?: boolean;
11
+ logConsolidatedTransactions?: boolean;
12
+ logRejectedTransactions?: boolean;
13
+ }) => NexusGateway;
14
+ /** Statistics for debugging - global singleton for easy of access.
15
+ * Won't be correct if multiple gateways are created.
16
+ */
17
+ export declare const debugStatistics: {
18
+ numReceivedCtr: number;
19
+ numConfirmedCtr: number;
20
+ numQueuedCtr: number;
21
+ numRejectedCtr: number;
22
+ };
@@ -1,6 +1,17 @@
1
- import { Transaction } from '../../gen/audiotool/document/v1/document_service_pb';
1
+ import { Modification, Transaction } from '../../gen/audiotool/document/v1/document_service_pb';
2
2
  import { ObservableValue } from '../../utils/observable-notifier-value';
3
3
 
4
+ /** A read only variant of a transaction that is returned by {@link NexusGateway.synchronize}.
5
+ *
6
+ * It's important that the gateway doesn't have to clone every transaction for performance reasons,
7
+ * but the returned transactions must also never be modified by the caller. This type
8
+ * allows us to enforce this.
9
+ */
10
+ export type ReadonlyTransaction = {
11
+ readonly id: string;
12
+ readonly commitIndex: number;
13
+ readonly modifications: readonly Modification[];
14
+ };
4
15
  /**
5
16
  * This is the interface the {@link NexusDocument} uses to sync itself with
6
17
  * a state from some "backend". This could be a server, local storage,
@@ -15,6 +26,8 @@ export interface NexusGateway {
15
26
  */
16
27
  send(t: Transaction): void;
17
28
  /** Fetch new transactions that should be immediately applied to the document to sync with upstream.
29
+ *
30
+ * The returned transactions MUST NOT be modified by the caller.
18
31
  *
19
32
  * This function must only be called after all local transactions created since the last call
20
33
  * to {@link synchronize} have been sent with {@link send}.
@@ -29,9 +42,16 @@ export interface NexusGateway {
29
42
  * one transaction. If the document state is empty, that transaction can be empty. The studio
30
43
  * will show the loading spinner until the first transaction is received.
31
44
  */
32
- synchronize(): Transaction[];
45
+ synchronize(): ReadonlyTransaction[];
33
46
  /** This becomes true when the gateway is blocked in some way from syncing with upstream state.
34
47
  * The document should be locked in this case to prevent data loss.
35
48
  */
36
49
  blocked: ObservableValue<boolean>;
50
+ /** Terminate the gateway. This will have the following effect:
51
+ * * `send` will throw
52
+ * * `synchronize` will return an empty array
53
+ *
54
+ * The promise will resolve once the last sent transaction has been confirmed as received by the backend.
55
+ */
56
+ terminate(): Promise<void>;
37
57
  }
@@ -7,4 +7,6 @@ import { Modification } from '../../gen/audiotool/document/v1/document_service_p
7
7
  */
8
8
  export interface NexusValidator {
9
9
  validate(mod: Modification): string | undefined;
10
+ /** terminate causes {@link validate} to throw. */
11
+ terminate(): void;
10
12
  }
@@ -1,8 +1,7 @@
1
- import { Modification, Transaction } from '../gen/audiotool/document/v1/document_service_pb';
2
- import { EntityTypes } from '../gen/audiotool/document/v1/utils/types';
3
1
  import { Notifier } from '../utils/observable-notifier';
4
- import { NexusGateway } from './backend/gateway';
2
+ import { NexusGateway, ReadonlyTransaction } from './backend/gateway';
5
3
  import { NexusValidator } from './backend/validator';
4
+ import { Modification, Transaction } from '../gen/audiotool/document/v1/document_service_pb';
6
5
  import { EntityTypeKey } from './entity-utils';
7
6
  import { NexusEventManager } from './event-manager';
8
7
  import { EntityQuery } from './query/entity';
@@ -100,16 +99,6 @@ export declare class NexusDocument {
100
99
  */
101
100
  actionId?: symbol;
102
101
  }>;
103
- /** Public field to query the entities in the document.
104
- *
105
- * @deprecated Don't use this field, as it can cause race conditions on the nexus document.
106
- *
107
- * Instead, use
108
- * * for building a transaction: {@link TransactionBuilder.entities}
109
- * * for other purposes, being aware of caveats: {@link NexusDocument.queryEntitiesWithoutLock}
110
- *
111
- */
112
- readonly entities: EntityQuery<keyof EntityTypes>;
113
102
  /**
114
103
  * This flag is set to true if {@link takeTransactions} is called. Before that, no transactions
115
104
  * from the backend are processed, and no transactions are allowed to be created from the frontend.
@@ -139,7 +128,9 @@ export declare class NexusDocument {
139
128
  * Note that every transaction by default is undoable, unless the flag in {@link TransactionOptions} is set to false.
140
129
  * @returns: {@link TransactionBuilder}
141
130
  */
142
- createTransaction(opts?: TransactionOptions): Promise<TransactionBuilder>;
131
+ createTransaction(opts?: TransactionOptions,
132
+ /** @internal allows skipping of taking the transaction lock */
133
+ _takeTransactionLock?: boolean): Promise<TransactionBuilder>;
143
134
  /**
144
135
  * A helper method for small transactions.
145
136
  *
@@ -169,15 +160,33 @@ export declare class NexusDocument {
169
160
  takeTransactions(props?: {
170
161
  validator?: NexusValidator;
171
162
  gateway?: NexusGateway;
163
+ /** if a project template should be loaded on startup, pass a promise that resolves to the transaction */
164
+ templateTransaction?: Promise<Transaction>;
172
165
  }): Promise<void>;
173
166
  /** Apply a transaction that doesn't originate from this document. Yields to the browser
174
167
  * scheduler every few modifications applied to make sure we don't block the main thread
175
168
  * for too long for big transactions. Throws if the transaction lock isn't taken.
169
+ *
176
170
  */
177
- applyIncomingTransactions(ts: Transaction[]): Promise<void>;
171
+ _applyIncomingTransactions(ts: ReadonlyTransaction[],
172
+ /** @internal */
173
+ opts?: {
174
+ /** This can be false if the transaction lock is already held already when calling from the outside.
175
+ * The method will throw if takeTransactionLock is false and the lock is not held.
176
+ */
177
+ _takeTransactionLock?: boolean;
178
+ }): Promise<void>;
178
179
  /** For debugging purposes */
179
180
  getStats(): {
180
181
  entities: number;
181
182
  references: number;
182
183
  };
184
+ /** Stop the document from syncing. This will have the following effect:
185
+ * First, all pending `modify` and `createTransaction` calls will finish.
186
+ * The modifications they create will be synced with the backend, and the document is locked down.
187
+ *
188
+ * After this, calling `modify` or `createTransaction` will throw an error. The only property that
189
+ * can still be accessed is `queryEntities`. The document can be thrown away safely after this.
190
+ */
191
+ terminate(): Promise<void>;
183
192
  }
@@ -175,6 +175,11 @@ export declare class NexusEventManager {
175
175
  from: NexusLocation) => void): Terminable;
176
176
  /** @internal */
177
177
  _dispatchStopPointingTo(to: NexusLocation, from: NexusLocation): void;
178
+ /**
179
+ * @internal
180
+ *
181
+ * Removes all event listeners.*/
182
+ _clear(): void;
178
183
  /**
179
184
  * @internal
180
185
  * Some stats for debugging. Static for easy access. This method can get quite slow, 6.5ms measured
@@ -3,4 +3,5 @@ import { Transaction } from '../../gen/audiotool/document/v1/document_service_pb
3
3
 
4
4
  export declare class MockNexusDocumentState implements WasmDocumentState {
5
5
  applyTransaction(t: Transaction): string | Transaction;
6
+ terminate(): void;
6
7
  }
package/dist/document.js CHANGED
@@ -1,4 +1,4 @@
1
- import { g as e, s as t, a as c } from "./get-schema-location-details-BSMUliFD.js";
1
+ import { g as e, s as t, a as c } from "./get-schema-location-details-CI3Fi5PK.js";
2
2
  import { T as h } from "./opt_pb-Dp9pF04Q.js";
3
3
  export {
4
4
  h as TargetType,
@@ -1,4 +1,4 @@
1
- import { t as o, a as d } from "./lang-KJQpoj7q.js";
1
+ import { t as o, a as d } from "./lang-K-8hAzE4.js";
2
2
  import { e as f } from "./types-Cztu157p.js";
3
3
  import { ScalarType as e } from "@bufbuild/protobuf";
4
4
  const g = {
@@ -3,16 +3,86 @@ var v = (i) => {
3
3
  };
4
4
  var M = (i, e, s) => e.has(i) || v("Cannot " + s);
5
5
  var t = (i, e, s) => (M(i, e, "read from private field"), s ? s.call(i) : e.get(i)), h = (i, e, s) => e.has(i) ? v("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(i) : e.set(i, s), o = (i, e, s, r) => (M(i, e, "write to private field"), r ? r.call(i, s) : e.set(i, s), s);
6
- var l, m, f;
6
+ var l;
7
+ class A {
8
+ constructor() {
9
+ h(this, l, /* @__PURE__ */ new Set());
10
+ }
11
+ // A set allows us to remove while iterating
12
+ subscribe(e) {
13
+ return t(this, l).add(e), { terminate: () => t(this, l).delete(e) };
14
+ }
15
+ notify(e) {
16
+ t(this, l).forEach((s) => s(e));
17
+ }
18
+ terminate() {
19
+ t(this, l).clear();
20
+ }
21
+ }
22
+ l = new WeakMap();
23
+ var f, c, g;
7
24
  class E {
25
+ constructor(e) {
26
+ h(this, f, new A());
27
+ h(this, c);
28
+ h(this, g, V(t(this, f)));
29
+ o(this, c, e);
30
+ }
31
+ getValue() {
32
+ return t(this, g).call(this), t(this, c);
33
+ }
34
+ setValue(e) {
35
+ t(this, c) !== e && (o(this, c, e), t(this, f).notify(e));
36
+ }
37
+ subscribe(e, s = !1) {
38
+ return s && e(t(this, c)), t(this, f).subscribe(e);
39
+ }
40
+ terminate() {
41
+ t(this, f).terminate();
42
+ }
43
+ }
44
+ f = new WeakMap(), c = new WeakMap(), g = new WeakMap();
45
+ var u, y, n;
46
+ class N {
47
+ constructor(e) {
48
+ h(this, u, new A());
49
+ h(this, y, V(t(this, u)));
50
+ h(this, n);
51
+ o(this, n, e ?? /* @__PURE__ */ new Map());
52
+ }
53
+ /** Subscribe to updates of the set */
54
+ subscribe(e, s = !1) {
55
+ return s && e(t(this, n)), t(this, u).subscribe(() => e(t(this, n)));
56
+ }
57
+ /** Get the underlying map. Readonly because changing it won't trigger updates. */
58
+ getValue() {
59
+ return t(this, y).call(this), t(this, n);
60
+ }
61
+ set(e, s) {
62
+ return t(this, n).set(e, s), t(this, u).notify(), this;
63
+ }
64
+ delete(e) {
65
+ const s = t(this, n).delete(e);
66
+ return s && t(this, u).notify(), s;
67
+ }
68
+ clear() {
69
+ const e = t(this, n).size > 0;
70
+ t(this, n).clear(), e && t(this, u).notify();
71
+ }
72
+ }
73
+ u = new WeakMap(), y = new WeakMap(), n = new WeakMap();
74
+ const V = (i) => () => {
75
+ };
76
+ var d, m, b;
77
+ class T {
8
78
  /** if `warnAfterMs` is set, the lock will emit a warning if a call to `lock.acquire()
9
79
  * tok more than `warnAfterMs` milliseconds.
10
80
  */
11
81
  constructor(e) {
12
- h(this, l, !1);
82
+ h(this, d, !1);
13
83
  h(this, m, []);
14
- h(this, f);
15
- o(this, f, (e == null ? void 0 : e.warnAfterMs) ?? void 0);
84
+ h(this, b);
85
+ o(this, b, (e == null ? void 0 : e.warnAfterMs) ?? void 0);
16
86
  }
17
87
  /**
18
88
  * Wait until no other async thread holds a lock, then returns a lock.
@@ -36,17 +106,17 @@ class E {
36
106
  async acquire() {
37
107
  let e = () => {
38
108
  };
39
- t(this, f) !== void 0 && (e = k(
40
- t(this, f),
41
- `Waited for lock.acquire() for more than ${t(this, f)} ms, deadlock?`
42
- )), t(this, l) && await new Promise((r) => t(this, m).push(r)), e(), o(this, l, !0);
109
+ t(this, b) !== void 0 && (e = k(
110
+ t(this, b),
111
+ `Waited for lock.acquire() for more than ${t(this, b)} ms, deadlock?`
112
+ )), t(this, d) && await new Promise((r) => t(this, m).push(r)), e(), o(this, d, !0);
43
113
  let s = !1;
44
114
  return {
45
115
  release: () => {
46
116
  var r;
47
117
  if (s)
48
118
  throw new Error("Lock already released");
49
- s = !0, t(this, m).length > 0 ? (r = t(this, m).shift()) == null || r() : o(this, l, !1);
119
+ s = !0, t(this, m).length > 0 ? (r = t(this, m).shift()) == null || r() : o(this, d, !1);
50
120
  }
51
121
  };
52
122
  }
@@ -88,36 +158,18 @@ class E {
88
158
  * without `await`ing the `lock.acquire()`.
89
159
  */
90
160
  get locked() {
91
- return t(this, l);
161
+ return t(this, d);
92
162
  }
93
163
  }
94
- l = new WeakMap(), m = new WeakMap(), f = new WeakMap();
164
+ d = new WeakMap(), m = new WeakMap(), b = new WeakMap();
95
165
  const k = (i, e) => {
96
166
  const s = setTimeout(() => {
97
167
  console.warn(e), console.trace("Waited here:");
98
168
  }, i);
99
169
  return () => clearTimeout(s);
100
- };
101
- var d;
102
- class A {
103
- constructor() {
104
- h(this, d, /* @__PURE__ */ new Set());
105
- }
106
- // A set allows us to remove while iterating
107
- subscribe(e) {
108
- return t(this, d).add(e), { terminate: () => t(this, d).delete(e) };
109
- }
110
- notify(e) {
111
- t(this, d).forEach((s) => s(e));
112
- }
113
- terminate() {
114
- t(this, d).clear();
115
- }
116
- }
117
- d = new WeakMap();
118
- const w = Symbol();
170
+ }, w = Symbol();
119
171
  var a;
120
- class N {
172
+ class _ {
121
173
  constructor() {
122
174
  /** Maps the hash of a key to both key and value */
123
175
  h(this, a, /* @__PURE__ */ new Map());
@@ -165,64 +217,11 @@ class N {
165
217
  }
166
218
  }
167
219
  a = new WeakMap();
168
- var b, c, g;
169
- class T {
170
- constructor(e) {
171
- h(this, b, new A());
172
- h(this, c);
173
- h(this, g, V(t(this, b)));
174
- o(this, c, e);
175
- }
176
- getValue() {
177
- return t(this, g).call(this), t(this, c);
178
- }
179
- setValue(e) {
180
- t(this, c) !== e && (o(this, c, e), t(this, b).notify(e));
181
- }
182
- subscribe(e, s = !1) {
183
- return s && e(t(this, c)), t(this, b).subscribe(e);
184
- }
185
- terminate() {
186
- t(this, b).terminate();
187
- }
188
- }
189
- b = new WeakMap(), c = new WeakMap(), g = new WeakMap();
190
- var u, y, n;
191
- class _ {
192
- constructor(e) {
193
- h(this, u, new A());
194
- h(this, y, V(t(this, u)));
195
- h(this, n);
196
- o(this, n, e ?? /* @__PURE__ */ new Map());
197
- }
198
- /** Subscribe to updates of the set */
199
- subscribe(e, s = !1) {
200
- return s && e(t(this, n)), t(this, u).subscribe(() => e(t(this, n)));
201
- }
202
- /** Get the underlying map. Readonly because changing it won't trigger updates. */
203
- getValue() {
204
- return t(this, y).call(this), t(this, n);
205
- }
206
- set(e, s) {
207
- return t(this, n).set(e, s), t(this, u).notify(), this;
208
- }
209
- delete(e) {
210
- const s = t(this, n).delete(e);
211
- return s && t(this, u).notify(), s;
212
- }
213
- clear() {
214
- const e = t(this, n).size > 0;
215
- t(this, n).clear(), e && t(this, u).notify();
216
- }
217
- }
218
- u = new WeakMap(), y = new WeakMap(), n = new WeakMap();
219
- const V = (i) => () => {
220
- };
221
220
  export {
222
- E as A,
223
- N as H,
224
- _ as M,
221
+ T as A,
222
+ _ as H,
223
+ N as M,
225
224
  A as N,
226
- T as V,
225
+ E as V,
227
226
  w as h
228
227
  };