@evolu/common 8.0.0-next.5 → 8.0.0
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/Array.d.ts +279 -173
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +105 -101
- package/dist/src/Assert.d.ts +39 -44
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +38 -31
- package/dist/src/BigInt.d.ts +6 -3
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -2
- package/dist/src/Brand.d.ts +27 -40
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Buffer.d.ts +27 -11
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +9 -4
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +30 -19
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +145 -66
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +91 -43
- package/dist/src/Crypto.d.ts +85 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +44 -20
- package/dist/src/Eq.d.ts +87 -21
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +67 -19
- package/dist/src/Error.d.ts +3 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Function.d.ts +119 -58
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +86 -43
- package/dist/src/Http.d.ts +394 -0
- package/dist/src/Http.d.ts.map +1 -0
- package/dist/src/Http.js +102 -0
- package/dist/src/Identicon.d.ts +16 -7
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +14 -5
- package/dist/src/LeakDetector.d.ts +88 -0
- package/dist/src/LeakDetector.d.ts.map +1 -0
- package/dist/src/LeakDetector.js +86 -0
- package/dist/src/LockManager.d.ts +18 -9
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/LockManager.js +7 -8
- package/dist/src/Lookup.d.ts +43 -13
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +28 -8
- package/dist/src/Microtask.d.ts +1 -1
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +3 -7
- package/dist/src/Number.d.ts +49 -13
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +34 -5
- package/dist/src/Object.d.ts +160 -40
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +92 -46
- package/dist/src/Option.d.ts +10 -7
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +9 -6
- package/dist/src/Order.d.ts +21 -21
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +18 -21
- package/dist/src/Platform.d.ts +31 -0
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +98 -0
- package/dist/src/Random.d.ts +32 -17
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +12 -8
- package/dist/src/Redacted.d.ts +43 -29
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +14 -3
- package/dist/src/Ref.d.ts +11 -3
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +2 -2
- package/dist/src/RefCount.d.ts +2 -6
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +33 -90
- package/dist/src/Relation.d.ts +70 -5
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +77 -2
- package/dist/src/Resource.d.ts +590 -155
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +592 -343
- package/dist/src/Result.d.ts +838 -191
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +163 -102
- package/dist/src/Schedule.d.ts +684 -231
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +766 -295
- package/dist/src/Set.d.ts +89 -40
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +50 -29
- package/dist/src/Sqlite.d.ts +29 -72
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +39 -45
- package/dist/src/StackTrace.d.ts +40 -0
- package/dist/src/StackTrace.d.ts.map +1 -0
- package/dist/src/StackTrace.js +140 -0
- package/dist/src/Store.d.ts +5 -4
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +5 -4
- package/dist/src/String.d.ts +7 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +20 -7
- package/dist/src/Task.d.ts +3428 -1629
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1876 -1279
- package/dist/src/Test.d.ts +17 -124
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +17 -68
- package/dist/src/Time.d.ts +108 -49
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +172 -73
- package/dist/src/Type.d.ts +3542 -1926
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3070 -1784
- package/dist/src/Types.d.ts +200 -100
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +39 -8
- package/dist/src/WebSocket.d.ts +48 -23
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +15 -6
- package/dist/src/Worker.d.ts +94 -36
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +58 -24
- package/dist/src/index.d.ts +55 -52
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/cs.d.ts +94 -0
- package/dist/src/intl/cs.d.ts.map +1 -0
- package/dist/src/intl/cs.js +220 -0
- package/dist/src/intl/index.d.ts +7 -0
- package/dist/src/intl/index.d.ts.map +1 -0
- package/dist/src/intl/index.js +6 -0
- package/dist/src/local-first/Db.d.ts +12 -8
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +107 -130
- package/dist/src/local-first/Error.d.ts +4 -4
- package/dist/src/local-first/Evolu.d.ts +338 -92
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +47 -55
- package/dist/src/local-first/LocalAuth.d.ts +4 -4
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +61 -24
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +45 -8
- package/dist/src/local-first/Protocol.d.ts +44 -31
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +36 -13
- package/dist/src/local-first/Query.d.ts +147 -62
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +112 -58
- package/dist/src/local-first/Relay.d.ts +44 -14
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +92 -41
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +25 -8
- package/dist/src/local-first/Shared.d.ts +23 -21
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +85 -42
- package/dist/src/local-first/Storage.d.ts +53 -32
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +194 -234
- package/dist/src/local-first/Timestamp.d.ts +21 -21
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +2 -2
- package/dist/src/local-first/index.d.ts +11 -11
- package/package.json +14 -13
- package/src/Array.ts +306 -205
- package/src/Assert.ts +48 -68
- package/src/BigInt.ts +6 -3
- package/src/Brand.ts +27 -40
- package/src/Buffer.ts +28 -12
- package/src/Cache.ts +9 -4
- package/src/Callbacks.ts +30 -19
- package/src/Console.ts +156 -84
- package/src/Crypto.ts +83 -41
- package/src/Eq.ts +95 -22
- package/src/Error.ts +5 -2
- package/src/Function.ts +167 -59
- package/src/Http.ts +549 -0
- package/src/Identicon.ts +16 -7
- package/src/LeakDetector.ts +182 -0
- package/src/LockManager.ts +43 -39
- package/src/Lookup.ts +62 -28
- package/src/Microtask.ts +19 -23
- package/src/Number.ts +64 -12
- package/src/Object.ts +173 -49
- package/src/Option.ts +10 -7
- package/src/Order.ts +23 -21
- package/src/Platform.ts +136 -0
- package/src/Polyfills.ts +6 -12
- package/src/Random.ts +32 -19
- package/src/Redacted.ts +44 -30
- package/src/Ref.ts +14 -6
- package/src/RefCount.ts +38 -80
- package/src/Relation.ts +202 -10
- package/src/Resource.ts +1199 -591
- package/src/Result.ts +930 -271
- package/src/Schedule.ts +859 -343
- package/src/Set.ts +89 -40
- package/src/Sqlite.ts +142 -137
- package/src/StackTrace.ts +230 -0
- package/src/Store.ts +8 -7
- package/src/String.ts +22 -5
- package/src/Task.ts +5109 -2845
- package/src/Test.ts +20 -167
- package/src/Time.ts +293 -90
- package/src/Type.ts +10034 -4117
- package/src/Types.ts +227 -101
- package/src/WebSocket.ts +64 -36
- package/src/Worker.ts +180 -72
- package/src/index.ts +55 -52
- package/src/intl/cs.ts +388 -0
- package/src/intl/index.ts +7 -0
- package/src/local-first/Db.ts +161 -190
- package/src/local-first/Error.ts +4 -4
- package/src/local-first/Evolu.ts +495 -250
- package/src/local-first/LocalAuth.ts +6 -12
- package/src/local-first/Owner.ts +58 -21
- package/src/local-first/Protocol.ts +49 -31
- package/src/local-first/Query.ts +146 -61
- package/src/local-first/Relay.ts +51 -21
- package/src/local-first/Schema.ts +109 -51
- package/src/local-first/Shared.ts +253 -214
- package/src/local-first/Storage.ts +266 -264
- package/src/local-first/Timestamp.ts +25 -18
- package/src/local-first/index.ts +11 -11
- package/dist/src/Skiplist.d.ts +0 -28
- package/dist/src/Skiplist.d.ts.map +0 -1
- package/dist/src/Skiplist.js +0 -64
- package/dist/src/Tracer.d.ts +0 -48
- package/dist/src/Tracer.d.ts.map +0 -1
- package/dist/src/Tracer.js +0 -6
- package/src/Skiplist.ts +0 -108
- package/src/Tracer.ts +0 -54
|
@@ -8,37 +8,43 @@ import {
|
|
|
8
8
|
emptyArray,
|
|
9
9
|
firstInArray,
|
|
10
10
|
isNonEmptyArray,
|
|
11
|
-
shiftFromArray,
|
|
12
11
|
type NonEmptyReadonlyArray,
|
|
13
|
-
} from "../Array.
|
|
14
|
-
import { assert
|
|
15
|
-
import type { Brand } from "../Brand.
|
|
16
|
-
import { createCallbacks } from "../Callbacks.
|
|
17
|
-
import type { ConsoleEntry, ConsoleLevel } from "../Console.
|
|
18
|
-
import type { EncryptionKey } from "../Crypto.
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
12
|
+
} from "../Array.ts";
|
|
13
|
+
import { assert } from "../Assert.ts";
|
|
14
|
+
import type { Brand } from "../Brand.ts";
|
|
15
|
+
import { createCallbacks } from "../Callbacks.ts";
|
|
16
|
+
import type { ConsoleEntry, ConsoleLevel } from "../Console.ts";
|
|
17
|
+
import type { EncryptionKey } from "../Crypto.ts";
|
|
18
|
+
import { disposable } from "../Function.ts";
|
|
19
|
+
import { acquireLeaderLock, type LockManagerDep } from "../LockManager.ts";
|
|
20
|
+
import {
|
|
21
|
+
createLookupMap,
|
|
22
|
+
structuralLookup,
|
|
23
|
+
type LookupMap,
|
|
24
|
+
type StructuralLookupKey,
|
|
25
|
+
} from "../Lookup.ts";
|
|
26
|
+
import { createRefCountByKey, type RefCountByKey } from "../RefCount.ts";
|
|
22
27
|
import {
|
|
23
28
|
createSharedResourceByKey,
|
|
24
29
|
createSharedResourceByKeyWithClaims,
|
|
25
30
|
type BorrowedResource,
|
|
31
|
+
type ClaimLease,
|
|
26
32
|
type SharedResourceByKeyWithClaims,
|
|
27
|
-
} from "../Resource.
|
|
28
|
-
import { ok, type Result } from "../Result.
|
|
29
|
-
import type { NonEmptyReadonlySet } from "../Set.
|
|
30
|
-
import type { SqliteSchema } from "../Sqlite.
|
|
31
|
-
import { createStore, type Store } from "../Store.
|
|
33
|
+
} from "../Resource.ts";
|
|
34
|
+
import { ok, type Result } from "../Result.ts";
|
|
35
|
+
import type { NonEmptyReadonlySet } from "../Set.ts";
|
|
36
|
+
import type { SqliteSchema } from "../Sqlite.ts";
|
|
37
|
+
import { createStore, type Store } from "../Store.ts";
|
|
32
38
|
import {
|
|
33
39
|
AbortError,
|
|
34
40
|
createMutex,
|
|
35
41
|
unabortable,
|
|
36
42
|
type Mutex,
|
|
37
43
|
type Task,
|
|
38
|
-
} from "../Task.
|
|
39
|
-
import {
|
|
40
|
-
import type { Callback
|
|
41
|
-
import type { CreateWebSocketDep, WebSocket } from "../WebSocket.
|
|
44
|
+
} from "../Task.ts";
|
|
45
|
+
import type { ExtractTyped, Id, Name, Typed } from "../Type.ts";
|
|
46
|
+
import type { Callback } from "../Types.ts";
|
|
47
|
+
import type { CreateWebSocketDep, WebSocket } from "../WebSocket.ts";
|
|
42
48
|
import type {
|
|
43
49
|
SharedWorker as CommonSharedWorker,
|
|
44
50
|
CreateBroadcastChannelDep,
|
|
@@ -47,10 +53,10 @@ import type {
|
|
|
47
53
|
NativeMessagePort,
|
|
48
54
|
SharedWorkerSelf,
|
|
49
55
|
WorkerDeps,
|
|
50
|
-
} from "../Worker.
|
|
51
|
-
import type { DbWorkerInit } from "./Db.
|
|
52
|
-
import type { EvoluError } from "./Error.
|
|
53
|
-
import type { Owner, OwnerId, OwnerTransport, SyncOwner } from "./Owner.
|
|
56
|
+
} from "../Worker.ts";
|
|
57
|
+
import type { DbWorkerInit } from "./Db.ts";
|
|
58
|
+
import type { EvoluError } from "./Error.ts";
|
|
59
|
+
import type { Owner, OwnerId, OwnerTransport, SyncOwner } from "./Owner.ts";
|
|
54
60
|
import {
|
|
55
61
|
createProtocolMessageForUnsubscribe,
|
|
56
62
|
createProtocolMessageFromCrdtMessages,
|
|
@@ -58,16 +64,16 @@ import {
|
|
|
58
64
|
type ApplyProtocolMessageAsClientResult,
|
|
59
65
|
type ProtocolError,
|
|
60
66
|
type ProtocolMessage,
|
|
61
|
-
} from "./Protocol.
|
|
67
|
+
} from "./Protocol.ts";
|
|
62
68
|
import {
|
|
63
69
|
makePatches,
|
|
64
70
|
type Patch,
|
|
65
71
|
type Query,
|
|
66
72
|
type Row,
|
|
67
73
|
type RowsByQueryMap,
|
|
68
|
-
} from "./Query.
|
|
69
|
-
import type { MutationChange } from "./Schema.
|
|
70
|
-
import type { CrdtMessage } from "./Storage.
|
|
74
|
+
} from "./Query.ts";
|
|
75
|
+
import type { MutationChange } from "./Schema.ts";
|
|
76
|
+
import type { CrdtMessage } from "./Storage.ts";
|
|
71
77
|
|
|
72
78
|
export type SharedWorker = CommonSharedWorker<
|
|
73
79
|
SharedWorkerInput,
|
|
@@ -156,7 +162,9 @@ export type DbWorkerRequest =
|
|
|
156
162
|
| {
|
|
157
163
|
readonly type: "ForEvolu";
|
|
158
164
|
readonly id: EvoluInstanceId;
|
|
159
|
-
readonly message:
|
|
165
|
+
readonly message: {
|
|
166
|
+
readonly [Message in EvoluInput as Message["type"]]: Message;
|
|
167
|
+
}["Mutate" | "Query" | "Export"];
|
|
160
168
|
}
|
|
161
169
|
| {
|
|
162
170
|
readonly type: "ForSharedWorker";
|
|
@@ -234,7 +242,7 @@ export type SharedWorkerDeps = WorkerDeps &
|
|
|
234
242
|
|
|
235
243
|
interface EvoluTenant extends AsyncDisposable {
|
|
236
244
|
readonly addInstance: (
|
|
237
|
-
message:
|
|
245
|
+
message: ExtractTyped<SharedWorkerInput, "CreateEvolu">,
|
|
238
246
|
onDisposed: () => void,
|
|
239
247
|
) => void;
|
|
240
248
|
|
|
@@ -265,8 +273,7 @@ interface TransportsDep {
|
|
|
265
273
|
readonly transports: SharedResourceByKeyWithClaims<
|
|
266
274
|
OwnerTransport,
|
|
267
275
|
OwnerId,
|
|
268
|
-
WebSocket
|
|
269
|
-
SharedWorkerDeps
|
|
276
|
+
WebSocket
|
|
270
277
|
>;
|
|
271
278
|
}
|
|
272
279
|
|
|
@@ -274,6 +281,7 @@ export type EvoluInstanceId = Id & Brand<"EvoluInstance">;
|
|
|
274
281
|
|
|
275
282
|
export type SyncState = 123;
|
|
276
283
|
|
|
284
|
+
/** Initializes the platform-agnostic Evolu SharedWorker. */
|
|
277
285
|
export const initSharedWorker =
|
|
278
286
|
(
|
|
279
287
|
self: SharedWorkerSelf<SharedWorkerInput, SharedWorkerOutput>,
|
|
@@ -313,15 +321,10 @@ export const initSharedWorker =
|
|
|
313
321
|
|
|
314
322
|
case "CreateEvolu": {
|
|
315
323
|
void sharedWorkerRun(async (run) => {
|
|
316
|
-
const
|
|
324
|
+
const tenantLease = await run.ok(
|
|
317
325
|
unabortable(tenantsByName.acquire(message)),
|
|
318
326
|
);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
tenant.value.addInstance(
|
|
322
|
-
message,
|
|
323
|
-
() => void sharedWorkerRun(tenantsByName.release(message)),
|
|
324
|
-
);
|
|
327
|
+
tenantLease.resource.addInstance(message, tenantLease.release);
|
|
325
328
|
return ok();
|
|
326
329
|
});
|
|
327
330
|
break;
|
|
@@ -340,12 +343,13 @@ export const initSharedWorker =
|
|
|
340
343
|
}),
|
|
341
344
|
);
|
|
342
345
|
|
|
346
|
+
const currentTenantsByName = new Map<Name, BorrowedResource<EvoluTenant>>();
|
|
343
347
|
const transports = disposer.use(
|
|
344
|
-
await run.
|
|
348
|
+
await run.ok(
|
|
345
349
|
createSharedResourceByKeyWithClaims<
|
|
346
|
-
WebSocket,
|
|
347
350
|
OwnerTransport,
|
|
348
351
|
OwnerId,
|
|
352
|
+
WebSocket,
|
|
349
353
|
SharedWorkerDeps,
|
|
350
354
|
StructuralLookupKey
|
|
351
355
|
>(
|
|
@@ -420,11 +424,15 @@ export const initSharedWorker =
|
|
|
420
424
|
});
|
|
421
425
|
|
|
422
426
|
const tenantsByName = disposer.use(
|
|
423
|
-
await sharedWorkerRun.
|
|
424
|
-
createSharedResourceByKey(
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
427
|
+
await sharedWorkerRun.ok(
|
|
428
|
+
createSharedResourceByKey(
|
|
429
|
+
(message: ExtractTyped<SharedWorkerInput, "CreateEvolu">) =>
|
|
430
|
+
createEvoluTenant(message, currentTenantsByName),
|
|
431
|
+
{
|
|
432
|
+
idleDisposeAfter: "3s",
|
|
433
|
+
lookup: (message) => message.name,
|
|
434
|
+
},
|
|
435
|
+
),
|
|
428
436
|
),
|
|
429
437
|
);
|
|
430
438
|
|
|
@@ -433,26 +441,23 @@ export const initSharedWorker =
|
|
|
433
441
|
const forEachTenant = (
|
|
434
442
|
callback: Callback<BorrowedResource<EvoluTenant>>,
|
|
435
443
|
): void => {
|
|
436
|
-
for (const tenant of
|
|
437
|
-
callback(tenant);
|
|
438
|
-
}
|
|
444
|
+
for (const tenant of currentTenantsByName.values()) callback(tenant);
|
|
439
445
|
};
|
|
440
446
|
|
|
441
447
|
return ok(disposer.move());
|
|
442
448
|
};
|
|
443
449
|
|
|
444
450
|
const createEvoluTenant =
|
|
445
|
-
(
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
> =>
|
|
451
|
+
(
|
|
452
|
+
{
|
|
453
|
+
name,
|
|
454
|
+
consoleLevel,
|
|
455
|
+
sqliteSchema,
|
|
456
|
+
encryptionKey,
|
|
457
|
+
memoryOnly,
|
|
458
|
+
}: ExtractTyped<SharedWorkerInput, "CreateEvolu">,
|
|
459
|
+
currentTenantsByName: Map<Name, BorrowedResource<EvoluTenant>>,
|
|
460
|
+
): Task<EvoluTenant, never, EvoluTenantDeps> =>
|
|
456
461
|
async (run) => {
|
|
457
462
|
await using disposer = new AsyncDisposableStack();
|
|
458
463
|
const tenantRun = disposer.use(run.create());
|
|
@@ -462,6 +467,7 @@ const createEvoluTenant =
|
|
|
462
467
|
|
|
463
468
|
interface EvoluInstance extends AsyncDisposable {
|
|
464
469
|
readonly id: EvoluInstanceId;
|
|
470
|
+
readonly claimLeasesBySyncOwner: LookupMap<SyncOwner, Array<ClaimLease>>;
|
|
465
471
|
readonly onDisposed: () => void;
|
|
466
472
|
readonly port: MessagePort<EvoluOutput, EvoluInput>;
|
|
467
473
|
readonly useOwnerMutex: Mutex;
|
|
@@ -533,7 +539,7 @@ const createEvoluTenant =
|
|
|
533
539
|
|
|
534
540
|
const queue: Array<DbWorkerRequest> = [];
|
|
535
541
|
const callbacks = disposer.use(
|
|
536
|
-
createCallbacks<
|
|
542
|
+
createCallbacks<ExtractTyped<DbWorkerOutput, "OnQueuedResponse">>(
|
|
537
543
|
run.deps,
|
|
538
544
|
),
|
|
539
545
|
);
|
|
@@ -559,7 +565,7 @@ const createEvoluTenant =
|
|
|
559
565
|
}
|
|
560
566
|
|
|
561
567
|
// Complete the current queue item and continue with the next one.
|
|
562
|
-
|
|
568
|
+
queue.shift();
|
|
563
569
|
queueRequestInFlight = false;
|
|
564
570
|
runQueue();
|
|
565
571
|
});
|
|
@@ -578,21 +584,16 @@ const createEvoluTenant =
|
|
|
578
584
|
// DbWorker releases it: either because Dispose was delivered or because
|
|
579
585
|
// the hosting tab closed. The wait is unabortable because tenant disposal
|
|
580
586
|
// must finish even after tenantRun receives an abort request.
|
|
581
|
-
|
|
582
|
-
// AbortError here means tenantRun was already disposed before this
|
|
583
|
-
// cleanup could start, violating the disposal ordering above.
|
|
584
|
-
assertNotAborted(lock);
|
|
585
|
-
await using _ = lock.value;
|
|
587
|
+
await using _ = await tenantRun.ok(acquireLeaderLock(name));
|
|
586
588
|
});
|
|
587
589
|
|
|
588
590
|
disposer.defer(deps.tabLeaderPortStore.subscribe(initDbWorker));
|
|
589
591
|
|
|
590
592
|
initDbWorker();
|
|
591
593
|
await dbWorkerInited.promise;
|
|
592
|
-
const disposables = disposer.move();
|
|
593
594
|
|
|
594
595
|
const handleResponseForEvolu = (
|
|
595
|
-
response:
|
|
596
|
+
response: ExtractTyped<DbWorkerQueuedResponse, "ForEvolu">,
|
|
596
597
|
first: DbWorkerRequest,
|
|
597
598
|
): void => {
|
|
598
599
|
const instance = instancesById.get(response.id);
|
|
@@ -669,7 +670,7 @@ const createEvoluTenant =
|
|
|
669
670
|
};
|
|
670
671
|
|
|
671
672
|
const handleResponseForSharedWorker = (
|
|
672
|
-
response:
|
|
673
|
+
response: ExtractTyped<DbWorkerQueuedResponse, "ForSharedWorker">,
|
|
673
674
|
): void => {
|
|
674
675
|
switch (response.message.type) {
|
|
675
676
|
case "CreateSyncMessages":
|
|
@@ -718,20 +719,20 @@ const createEvoluTenant =
|
|
|
718
719
|
protocolMessagesByOwnerId: ReadonlyMap<OwnerId, ProtocolMessage>,
|
|
719
720
|
): void => {
|
|
720
721
|
for (const [ownerId, protocolMessage] of protocolMessagesByOwnerId) {
|
|
721
|
-
|
|
722
|
+
deps.transports.forEachResourceForClaim(
|
|
722
723
|
ownerId,
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
if (!webSocket?.isOpen()) continue;
|
|
724
|
+
(webSocket, transport) => {
|
|
725
|
+
if (!webSocket.isOpen()) return;
|
|
726
726
|
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
727
|
+
console.debug("sendProtocolMessage", {
|
|
728
|
+
ownerId,
|
|
729
|
+
url: transport.url,
|
|
730
|
+
byteLength: protocolMessage.byteLength,
|
|
731
|
+
});
|
|
732
732
|
|
|
733
|
-
|
|
734
|
-
|
|
733
|
+
webSocket.send(protocolMessage);
|
|
734
|
+
},
|
|
735
|
+
);
|
|
735
736
|
}
|
|
736
737
|
};
|
|
737
738
|
|
|
@@ -757,156 +758,187 @@ const createEvoluTenant =
|
|
|
757
758
|
async (run) => {
|
|
758
759
|
if (action === "add") {
|
|
759
760
|
instance.usedSyncOwners.increment(syncOwner);
|
|
760
|
-
|
|
761
|
-
|
|
761
|
+
let succeeded = false;
|
|
762
|
+
using compensation = new DisposableStack();
|
|
763
|
+
compensation.defer(() => {
|
|
764
|
+
if (!succeeded) instance.usedSyncOwners.decrement(syncOwner);
|
|
765
|
+
});
|
|
766
|
+
const claimLease = await run.ok(
|
|
767
|
+
deps.transports.claim(syncOwner.owner.id, syncOwner.transports),
|
|
762
768
|
);
|
|
769
|
+
instance.claimLeasesBySyncOwner
|
|
770
|
+
.getOrInsertComputed(syncOwner, () => [])
|
|
771
|
+
.push(claimLease);
|
|
772
|
+
succeeded = true;
|
|
763
773
|
} else {
|
|
764
774
|
instance.usedSyncOwners.decrement(syncOwner);
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
)
|
|
775
|
+
const claimLeases = instance.claimLeasesBySyncOwner.get(syncOwner);
|
|
776
|
+
assert(claimLeases, "Expected a ClaimLease for the used owner.");
|
|
777
|
+
const claimLease = claimLeases.pop();
|
|
778
|
+
assert(claimLease, "Expected a ClaimLease for the used owner.");
|
|
779
|
+
claimLease.release();
|
|
780
|
+
if (claimLeases.length === 0) {
|
|
781
|
+
instance.claimLeasesBySyncOwner.delete(syncOwner);
|
|
782
|
+
}
|
|
771
783
|
}
|
|
784
|
+
return ok();
|
|
772
785
|
};
|
|
773
786
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
787
|
+
disposer.defer(() => {
|
|
788
|
+
currentTenantsByName.delete(name);
|
|
789
|
+
});
|
|
790
|
+
const tenant = disposable<EvoluTenant>(
|
|
791
|
+
{
|
|
792
|
+
addInstance: (message, onDisposed) => {
|
|
793
|
+
const disposer = new AsyncDisposableStack();
|
|
794
|
+
const instance: EvoluInstance = {
|
|
795
|
+
id: message.id,
|
|
796
|
+
claimLeasesBySyncOwner: createLookupMap({
|
|
797
|
+
lookup: (syncOwner: SyncOwner) =>
|
|
798
|
+
structuralLookup<{
|
|
799
|
+
readonly ownerId: OwnerId;
|
|
800
|
+
readonly transports: ReadonlyArray<StructuralLookupKey>;
|
|
801
|
+
}>({
|
|
802
|
+
ownerId: syncOwner.owner.id,
|
|
803
|
+
transports: syncOwner.transports
|
|
804
|
+
.map(structuralLookup)
|
|
805
|
+
.toSorted(),
|
|
806
|
+
}),
|
|
807
|
+
}),
|
|
808
|
+
port: deps.createMessagePort<EvoluOutput, EvoluInput>(
|
|
809
|
+
message.evoluPort,
|
|
810
|
+
),
|
|
811
|
+
onDisposed,
|
|
812
|
+
rowsByQuery: new Map<Query, ReadonlyArray<Row>>(),
|
|
813
|
+
useOwnerMutex: createMutex(),
|
|
814
|
+
usedSyncOwners: createRefCountByKey<SyncOwner, OwnerId>({
|
|
815
|
+
lookup: (syncOwner) => syncOwner.owner.id,
|
|
816
|
+
}),
|
|
817
|
+
[Symbol.asyncDispose]: () => disposer.disposeAsync(),
|
|
818
|
+
};
|
|
793
819
|
|
|
794
|
-
|
|
820
|
+
instancesById.set(instance.id, instance);
|
|
795
821
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
disposer.use(instance.useOwnerMutex);
|
|
822
|
+
disposer.defer(instance.onDisposed);
|
|
823
|
+
disposer.use(instance.usedSyncOwners);
|
|
799
824
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
825
|
+
disposer.defer(async () => {
|
|
826
|
+
await tenantRun(
|
|
827
|
+
instance.useOwnerMutex.withLock(async (run) => {
|
|
828
|
+
for (const syncOwner of instance.usedSyncOwners.keys()) {
|
|
829
|
+
while (instance.usedSyncOwners.has(syncOwner)) {
|
|
830
|
+
await run(toggleSyncOwner(instance, syncOwner, "remove"));
|
|
831
|
+
}
|
|
806
832
|
}
|
|
833
|
+
return ok();
|
|
834
|
+
}),
|
|
835
|
+
);
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
disposer.defer(() => {
|
|
839
|
+
instancesById.delete(instance.id);
|
|
840
|
+
console.info("evoluDispose", { name, id: instance.id });
|
|
841
|
+
});
|
|
842
|
+
disposer.use(instance.port);
|
|
843
|
+
disposer.defer(() => {
|
|
844
|
+
instance.port.onMessage = null;
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
// The main-thread Evolu instance holds this per-instance leader lock
|
|
848
|
+
// while it is alive. Acquiring the same lock here means the main
|
|
849
|
+
// thread instance was disposed or its tab closed, so the tenant-side
|
|
850
|
+
// instance must dispose itself.
|
|
851
|
+
void tenantRun
|
|
852
|
+
.abortable(acquireLeaderLock(message.id))
|
|
853
|
+
.then((lock) => {
|
|
854
|
+
if (!lock.ok) return;
|
|
855
|
+
|
|
856
|
+
disposer.use(lock.value);
|
|
857
|
+
return instance[Symbol.asyncDispose]();
|
|
858
|
+
});
|
|
859
|
+
|
|
860
|
+
instance.port.onMessage = (message) => {
|
|
861
|
+
switch (message.type) {
|
|
862
|
+
case "Query":
|
|
863
|
+
case "Export": {
|
|
864
|
+
queue.push({ type: "ForEvolu", id: instance.id, message });
|
|
865
|
+
runQueue();
|
|
866
|
+
break;
|
|
867
|
+
}
|
|
868
|
+
case "Mutate": {
|
|
869
|
+
// TODO: Delegate do vsech evolu instances, co to pouzivaji
|
|
870
|
+
queue.push({ type: "ForEvolu", id: instance.id, message });
|
|
871
|
+
runQueue();
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
case "UseOwner": {
|
|
875
|
+
void tenantRun(
|
|
876
|
+
instance.useOwnerMutex.withLock(async (run) => {
|
|
877
|
+
for (const { owner, action } of message.actions) {
|
|
878
|
+
console.debug("useOwner", {
|
|
879
|
+
id: instance.id,
|
|
880
|
+
action,
|
|
881
|
+
ownerId: owner.owner.id,
|
|
882
|
+
transportUrls: owner.transports.map(({ url }) => url),
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
await run(toggleSyncOwner(instance, owner, action));
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
return ok();
|
|
889
|
+
}),
|
|
890
|
+
);
|
|
891
|
+
break;
|
|
807
892
|
}
|
|
808
|
-
return ok();
|
|
809
|
-
}),
|
|
810
|
-
);
|
|
811
|
-
});
|
|
812
|
-
|
|
813
|
-
disposer.defer(() => {
|
|
814
|
-
instancesById.delete(instance.id);
|
|
815
|
-
console.info("evoluDispose", { name, id: instance.id });
|
|
816
|
-
});
|
|
817
|
-
disposer.use(instance.port);
|
|
818
|
-
|
|
819
|
-
// The main-thread Evolu instance holds this per-instance leader lock
|
|
820
|
-
// while it is alive. Acquiring the same lock here means the main
|
|
821
|
-
// thread instance was disposed or its tab closed, so the tenant-side
|
|
822
|
-
// instance must dispose itself.
|
|
823
|
-
void tenantRun(acquireLeaderLock(message.id)).then((lock) => {
|
|
824
|
-
if (!lock.ok) return;
|
|
825
|
-
|
|
826
|
-
disposer.use(lock.value);
|
|
827
|
-
return disposer.disposeAsync();
|
|
828
|
-
});
|
|
829
|
-
|
|
830
|
-
instance.port.onMessage = (message) => {
|
|
831
|
-
switch (message.type) {
|
|
832
|
-
case "Query":
|
|
833
|
-
case "Export": {
|
|
834
|
-
queue.push({ type: "ForEvolu", id: instance.id, message });
|
|
835
|
-
runQueue();
|
|
836
|
-
break;
|
|
837
|
-
}
|
|
838
|
-
case "Mutate": {
|
|
839
|
-
// TODO: Delegate do vsech evolu instances, co to pouzivaji
|
|
840
|
-
queue.push({ type: "ForEvolu", id: instance.id, message });
|
|
841
|
-
runQueue();
|
|
842
|
-
break;
|
|
843
893
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
instance.useOwnerMutex.withLock(async (run) => {
|
|
847
|
-
for (const { owner, action } of message.actions) {
|
|
848
|
-
console.debug("useOwner", {
|
|
849
|
-
id: instance.id,
|
|
850
|
-
action,
|
|
851
|
-
ownerId: owner.owner.id,
|
|
852
|
-
transportUrls: owner.transports.map(({ url }) => url),
|
|
853
|
-
});
|
|
854
|
-
|
|
855
|
-
await run(toggleSyncOwner(instance, owner, action));
|
|
856
|
-
}
|
|
894
|
+
};
|
|
895
|
+
},
|
|
857
896
|
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
);
|
|
861
|
-
break;
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
};
|
|
865
|
-
},
|
|
897
|
+
requestCreateSyncMessages: (ownerIds): void => {
|
|
898
|
+
const ownersToSync = [...getUsedOwnersById(ownerIds).values()];
|
|
866
899
|
|
|
867
|
-
|
|
868
|
-
const ownersToSync = [...getUsedOwnersById(ownerIds).values()];
|
|
900
|
+
if (!isNonEmptyArray(ownersToSync)) return;
|
|
869
901
|
|
|
870
|
-
|
|
902
|
+
console.debug("requestCreateSyncMessages", {
|
|
903
|
+
ownerIds: ownersToSync.map(({ id }) => id),
|
|
904
|
+
});
|
|
871
905
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
906
|
+
queue.push({
|
|
907
|
+
type: "ForSharedWorker",
|
|
908
|
+
message: {
|
|
909
|
+
type: "CreateSyncMessages",
|
|
910
|
+
owners: ownersToSync,
|
|
911
|
+
},
|
|
912
|
+
});
|
|
875
913
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
message: {
|
|
879
|
-
type: "CreateSyncMessages",
|
|
880
|
-
owners: ownersToSync,
|
|
881
|
-
},
|
|
882
|
-
});
|
|
914
|
+
runQueue();
|
|
915
|
+
},
|
|
883
916
|
|
|
884
|
-
|
|
885
|
-
|
|
917
|
+
requestApplySyncMessage: (ownerId, inputMessage): void => {
|
|
918
|
+
const owner = getUsedOwnersById(new Set([ownerId])).get(ownerId);
|
|
919
|
+
if (!owner) return;
|
|
886
920
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
921
|
+
console.debug("requestApplySyncMessage", {
|
|
922
|
+
ownerId,
|
|
923
|
+
byteLength: inputMessage.byteLength,
|
|
924
|
+
});
|
|
890
925
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
type: "ApplySyncMessage",
|
|
900
|
-
owner,
|
|
901
|
-
inputMessage,
|
|
902
|
-
},
|
|
903
|
-
});
|
|
926
|
+
queue.push({
|
|
927
|
+
type: "ForSharedWorker",
|
|
928
|
+
message: {
|
|
929
|
+
type: "ApplySyncMessage",
|
|
930
|
+
owner,
|
|
931
|
+
inputMessage,
|
|
932
|
+
},
|
|
933
|
+
});
|
|
904
934
|
|
|
905
|
-
|
|
935
|
+
runQueue();
|
|
936
|
+
},
|
|
906
937
|
},
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
938
|
+
disposer,
|
|
939
|
+
);
|
|
940
|
+
currentTenantsByName.set(name, tenant);
|
|
941
|
+
return ok(tenant);
|
|
910
942
|
};
|
|
911
943
|
|
|
912
944
|
// | (Typed<"reset"> & {
|
|
@@ -932,10 +964,17 @@ const createEvoluTenant =
|
|
|
932
964
|
// readonly reload: boolean;
|
|
933
965
|
// })
|
|
934
966
|
|
|
935
|
-
// TODO:
|
|
936
|
-
// -
|
|
937
|
-
// -
|
|
967
|
+
// TODO: SharedWorker follow-ups.
|
|
968
|
+
// - Complete the queue head when a DbWorker mutation returns an error.
|
|
969
|
+
// - Make retried DbWorker requests deterministic by materializing clocks and
|
|
970
|
+
// timestamps in the SharedWorker before enqueueing them.
|
|
971
|
+
// - Replace the callback registry and queueRequestInFlight flag with one
|
|
972
|
+
// explicit in-flight request state.
|
|
973
|
+
// - Detect DbWorker and port liveness so a worker-only crash resumes the queue.
|
|
974
|
+
// - Consolidate usedSyncOwners and claimLeasesBySyncOwner into one owner-use
|
|
975
|
+
// state abstraction without changing repeated-use semantics.
|
|
976
|
+
// - Split worker protocol types and the EvoluTenant implementation into focused
|
|
977
|
+
// modules.
|
|
978
|
+
// - Remove the obsolete commented protocol block above.
|
|
979
|
+
// - Replace the SyncState placeholder with actual sync monitoring state.
|
|
938
980
|
// - Propagate invalid protocol messages to sync state.
|
|
939
|
-
// - Make DbWorker logically stateless by making all requests idempotent.
|
|
940
|
-
// - Investigate WebKit bug 301520 relevance to DbWorker disposal. (again)
|
|
941
|
-
// https://bugs.webkit.org/show_bug.cgi?id=301520
|