@evolu/common 8.0.0-next.3 → 8.0.0-next.5
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 +10 -5
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +10 -5
- package/dist/src/Error.d.ts +5 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +16 -0
- 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 +66 -41
- package/dist/src/Task.d.ts +99 -123
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +273 -256
- package/dist/src/Test.d.ts +14 -15
- package/dist/src/Test.d.ts.map +1 -1
- 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/Types.d.ts +0 -8
- package/dist/src/Types.d.ts.map +1 -1
- 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 +292 -112
- 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 +43 -37
- 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 +390 -376
- package/package.json +1 -1
- package/src/Array.ts +8 -8
- package/src/Assert.ts +11 -6
- package/src/Error.ts +5 -4
- 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 +43 -31
- package/src/Task.ts +392 -430
- package/src/Test.ts +14 -15
- package/src/Time.ts +7 -0
- package/src/Type.ts +9 -0
- package/src/Types.ts +0 -9
- package/src/WebSocket.ts +7 -6
- package/src/Worker.ts +195 -53
- package/src/index.ts +1 -0
- package/src/local-first/Db.ts +86 -61
- 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 +485 -476
|
@@ -59,6 +59,7 @@ import { appendToArray, firstInArray, } from "../Array.js";
|
|
|
59
59
|
import { assert, assertNonEmptyReadonlyArray, assertType } from "../Assert.js";
|
|
60
60
|
import { EncryptionKey, } from "../Crypto.js";
|
|
61
61
|
import { exhaustiveCheck, lazyFalse, lazyVoid } from "../Function.js";
|
|
62
|
+
import { acquireLeaderLock } from "../LockManager.js";
|
|
62
63
|
import { createRecord, getProperty, objectToEntries } from "../Object.js";
|
|
63
64
|
import { ok } from "../Result.js";
|
|
64
65
|
import { booleanToSqliteBoolean, createSqlite, sql, SqliteBoolean, sqliteBooleanToBoolean, sqliteQueryStringToSqliteQuery, SqliteValue, } from "../Sqlite.js";
|
|
@@ -68,13 +69,14 @@ import { Id, IdBytes, idBytesToId, idToIdBytes, onePositiveInt, } from "../Type.
|
|
|
68
69
|
import { ownerIdBytesToOwnerId, ownerIdToOwnerIdBytes } from "./Owner.js";
|
|
69
70
|
import { applyProtocolMessageAsClient, createProtocolMessageForSync, decryptAndDecodeDbChange, encodeAndEncryptDbChange, protocolVersion, SubscriptionFlags, } from "./Protocol.js";
|
|
70
71
|
import { ensureSqliteSchema, getEvoluSqliteSchema, systemColumns, } from "./Schema.js";
|
|
72
|
+
import { consoleEntryOrErrorBroadcastChannelName } from "./Shared.js";
|
|
71
73
|
import { createBaseSqliteStorage, createBaseSqliteStorageTables, DbChange, getTimestampInsertStrategy, readOwnerUsageOrDefault, updateOwnerUsage, } from "./Storage.js";
|
|
72
74
|
import { createInitialTimestamp, defaultTimestampMaxDrift, receiveTimestamp, sendTimestamp, TimestampBytes, timestampBytesToTimestamp, timestampToTimestampBytes, } from "./Timestamp.js";
|
|
73
|
-
export const startDbWorker = (self) => async (
|
|
75
|
+
export const startDbWorker = (self) => async (run) => {
|
|
74
76
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
75
77
|
try {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
+
const disposer = __addDisposableResource(env_1, new AsyncDisposableStack(), true);
|
|
79
|
+
disposer.use(self);
|
|
78
80
|
const { deps } = run;
|
|
79
81
|
let initialized = false;
|
|
80
82
|
const initMessage = await run.orThrow(callback(({ ok }) => {
|
|
@@ -86,29 +88,35 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
86
88
|
}));
|
|
87
89
|
const console = deps.console.child(initMessage.name).child("DbWorker");
|
|
88
90
|
console.setLevel(initMessage.consoleLevel);
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
91
|
+
const port = disposer.use(deps.createMessagePort(initMessage.port));
|
|
92
|
+
const consoleEntryOrErrorBroadcastChannel = disposer.use(deps.createBroadcastChannel(consoleEntryOrErrorBroadcastChannelName));
|
|
93
|
+
disposer.defer(deps.consoleStoreOutputEntry.subscribe(() => {
|
|
92
94
|
const entry = deps.consoleStoreOutputEntry.get();
|
|
93
95
|
if (entry)
|
|
94
|
-
|
|
96
|
+
consoleEntryOrErrorBroadcastChannel.postMessage({
|
|
97
|
+
type: "ConsoleEntry",
|
|
98
|
+
entry,
|
|
99
|
+
});
|
|
95
100
|
}));
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return ok();
|
|
101
|
+
console.debug("createDbWorker");
|
|
102
|
+
disposer.use(await run.orThrow(acquireLeaderLock(initMessage.name)));
|
|
99
103
|
port.postMessage({ type: "LeaderAcquired", name: initMessage.name });
|
|
100
|
-
const sqlite =
|
|
104
|
+
const sqlite = disposer.use(await run.orThrow(createSqlite(initMessage.name, initMessage.memoryOnly
|
|
101
105
|
? { mode: "memory" }
|
|
102
106
|
: { mode: "encrypted", encryptionKey: initMessage.encryptionKey })));
|
|
103
107
|
console.debug("SQLite created");
|
|
104
|
-
const baseSqliteStorage = createBaseSqliteStorage({
|
|
108
|
+
const baseSqliteStorage = createBaseSqliteStorage({
|
|
109
|
+
sqlite,
|
|
110
|
+
...deps,
|
|
111
|
+
});
|
|
105
112
|
const dbDeps = {
|
|
106
|
-
...
|
|
113
|
+
...deps,
|
|
107
114
|
sqlite,
|
|
108
115
|
sqliteSchema: initMessage.sqliteSchema,
|
|
109
116
|
baseSqliteStorage,
|
|
110
117
|
timestampConfig: { maxDrift: defaultTimestampMaxDrift },
|
|
111
118
|
};
|
|
119
|
+
const dbWorkerRun = disposer.use(run.create());
|
|
112
120
|
const currentSchema = getEvoluSqliteSchema(dbDeps)();
|
|
113
121
|
const dbIsInitialized = "evolu_version" in currentSchema.tables;
|
|
114
122
|
const clock = createClock(dbDeps)(dbIsInitialized);
|
|
@@ -120,27 +128,21 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
120
128
|
});
|
|
121
129
|
const storage = createClientStorage({ ...dbDeps, clock })({
|
|
122
130
|
onError: (error) => {
|
|
123
|
-
|
|
131
|
+
consoleEntryOrErrorBroadcastChannel.postMessage({
|
|
132
|
+
type: "Error",
|
|
133
|
+
error,
|
|
134
|
+
});
|
|
124
135
|
},
|
|
125
136
|
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
*
|
|
133
|
-
* The Set intentionally lives for one leader's lifetime. If that leader tab
|
|
134
|
-
* closes, retries go to a new leader with a fresh Set. Revisit this only if
|
|
135
|
-
* memory pressure shows up; even millions of short callback IDs are
|
|
136
|
-
* acceptable here, and naive eviction could let a still-retried request run
|
|
137
|
-
* again.
|
|
138
|
-
*/
|
|
139
|
-
const processedRequestIds = new Set();
|
|
140
|
-
port.onMessage = ({ callbackId, request }) => {
|
|
141
|
-
if (processedRequestIds.has(callbackId))
|
|
137
|
+
const disposables = disposer.move();
|
|
138
|
+
port.onMessage = (input) => {
|
|
139
|
+
if (input.type === "Dispose") {
|
|
140
|
+
if (!disposables.disposed)
|
|
141
|
+
console.debug("disposeDbWorker");
|
|
142
|
+
void disposables.disposeAsync();
|
|
142
143
|
return;
|
|
143
|
-
|
|
144
|
+
}
|
|
145
|
+
const { callbackId, request } = input;
|
|
144
146
|
const postQueuedResponse = (response) => {
|
|
145
147
|
port.postMessage({ type: "OnQueuedResponse", callbackId, response }, response.type === "ForEvolu" && response.message.type === "Export"
|
|
146
148
|
? [response.message.file.buffer]
|
|
@@ -152,12 +154,15 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
152
154
|
case "Mutate": {
|
|
153
155
|
const result = handleMutation({ ...dbDeps, clock })(request.message);
|
|
154
156
|
if (!result.ok) {
|
|
155
|
-
|
|
157
|
+
consoleEntryOrErrorBroadcastChannel.postMessage({
|
|
158
|
+
type: "Error",
|
|
159
|
+
error: result.error,
|
|
160
|
+
});
|
|
156
161
|
}
|
|
157
162
|
else {
|
|
158
163
|
postQueuedResponse({
|
|
159
164
|
type: "ForEvolu",
|
|
160
|
-
|
|
165
|
+
id: request.id,
|
|
161
166
|
message: result.value,
|
|
162
167
|
});
|
|
163
168
|
}
|
|
@@ -166,7 +171,7 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
166
171
|
case "Query":
|
|
167
172
|
postQueuedResponse({
|
|
168
173
|
type: "ForEvolu",
|
|
169
|
-
|
|
174
|
+
id: request.id,
|
|
170
175
|
message: {
|
|
171
176
|
type: "Query",
|
|
172
177
|
rowsByQuery: loadQueries(dbDeps)(request.message.queries),
|
|
@@ -176,7 +181,7 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
176
181
|
case "Export":
|
|
177
182
|
postQueuedResponse({
|
|
178
183
|
type: "ForEvolu",
|
|
179
|
-
|
|
184
|
+
id: request.id,
|
|
180
185
|
message: {
|
|
181
186
|
type: "Export",
|
|
182
187
|
file: dbDeps.sqlite.export(),
|
|
@@ -211,7 +216,8 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
211
216
|
}
|
|
212
217
|
case "ApplySyncMessage": {
|
|
213
218
|
const { owner, inputMessage } = request.message;
|
|
214
|
-
|
|
219
|
+
dbWorkerRun(async (run) => {
|
|
220
|
+
const { storage } = run.deps;
|
|
215
221
|
storage.setRequestContext(owner.encryptionKey);
|
|
216
222
|
const result = await run(applyProtocolMessageAsClient(inputMessage, {
|
|
217
223
|
writeKey: owner.writeKey,
|
|
@@ -227,7 +233,7 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
227
233
|
},
|
|
228
234
|
});
|
|
229
235
|
return ok();
|
|
230
|
-
});
|
|
236
|
+
}, { storage });
|
|
231
237
|
break;
|
|
232
238
|
}
|
|
233
239
|
default:
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { type NonEmptyReadonlyArray } from "../Array.js";
|
|
7
7
|
import type { ConsoleDep } from "../Console.js";
|
|
8
|
+
import { type LockManagerDep } from "../LockManager.js";
|
|
8
9
|
import type { FlushSyncDep, ReloadAppDep } from "../Platform.js";
|
|
9
10
|
import type { Listener, ReadonlyStore, Unsubscribe } from "../Store.js";
|
|
10
11
|
import { type Task } from "../Task.js";
|
|
11
12
|
import type { TypeError } from "../Type.js";
|
|
12
13
|
import { Name } from "../Type.js";
|
|
13
|
-
import type { CreateMessageChannelDep } from "../Worker.js";
|
|
14
|
+
import type { CreateBroadcastChannelDep, CreateMessageChannelDep } from "../Worker.js";
|
|
14
15
|
import type { CreateDbWorkerDep } from "./Db.js";
|
|
15
16
|
import type { EvoluError } from "./Error.js";
|
|
16
17
|
import type { AppOwner, Owner, OwnerTransport, ReadonlyOwner } from "./Owner.js";
|
|
@@ -444,7 +445,7 @@ export type EvoluDeps = EvoluPlatformDeps & EvoluErrorDep & Disposable;
|
|
|
444
445
|
* Provides worker and channel adapters plus optional platform integrations for
|
|
445
446
|
* logging and synchronous UI flush.
|
|
446
447
|
*/
|
|
447
|
-
export type EvoluPlatformDeps = CreateDbWorkerDep & CreateMessageChannelDep & ReloadAppDep & SharedWorkerDep & Partial<ConsoleDep> & Partial<FlushSyncDep>;
|
|
448
|
+
export type EvoluPlatformDeps = CreateDbWorkerDep & CreateBroadcastChannelDep & CreateMessageChannelDep & LockManagerDep & ReloadAppDep & SharedWorkerDep & Partial<ConsoleDep> & Partial<FlushSyncDep>;
|
|
448
449
|
/**
|
|
449
450
|
* Creates shared dependencies used by all {@link createEvolu} instances on a
|
|
450
451
|
* platform.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,aAAa,CAAC;AAOrB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"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"}
|
|
@@ -61,6 +61,7 @@ import { createCallbacks } from "../Callbacks.js";
|
|
|
61
61
|
import { createConsole } from "../Console.js";
|
|
62
62
|
import { createUnknownError } from "../Error.js";
|
|
63
63
|
import { exhaustiveCheck, todo } from "../Function.js";
|
|
64
|
+
import { acquireLeaderLock, acquireLeaderLockCallback, } from "../LockManager.js";
|
|
64
65
|
import { createMicrotaskBatch } from "../Microtask.js";
|
|
65
66
|
import { createRefCountByKey } from "../RefCount.js";
|
|
66
67
|
import { err, ok } from "../Result.js";
|
|
@@ -72,6 +73,7 @@ import { brand, createId, createIdFromString, Name, UrlSafeString, } from "../Ty
|
|
|
72
73
|
import { createOwnerWebSocketTransport } from "./Owner.js";
|
|
73
74
|
import { applyPatches } from "./Query.js";
|
|
74
75
|
import { evoluSchemaToSqliteSchema } from "./Schema.js";
|
|
76
|
+
import { consoleEntryOrErrorBroadcastChannelName } from "./Shared.js";
|
|
75
77
|
import { DbChange } from "./Storage.js";
|
|
76
78
|
/**
|
|
77
79
|
* Application name.
|
|
@@ -99,61 +101,75 @@ export const testAppName = /*#__PURE__*/ AppName.orThrow("AppName");
|
|
|
99
101
|
* Dispose it only during app shutdown.
|
|
100
102
|
*/
|
|
101
103
|
export const createEvoluDeps = (deps) => {
|
|
102
|
-
const {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
104
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
105
|
+
try {
|
|
106
|
+
const { createBroadcastChannel, sharedWorker } = deps;
|
|
107
|
+
const console = deps.console ?? createConsole();
|
|
108
|
+
const disposer = __addDisposableResource(env_1, new DisposableStack(), false);
|
|
109
|
+
disposer.use(sharedWorker);
|
|
110
|
+
const evoluError = disposer.use(createStore(null));
|
|
111
|
+
const consoleEntryOrErrorBroadcastChannel = disposer.use(createBroadcastChannel(consoleEntryOrErrorBroadcastChannelName));
|
|
112
|
+
consoleEntryOrErrorBroadcastChannel.onMessage = (message) => {
|
|
113
|
+
switch (message.type) {
|
|
114
|
+
case "ConsoleEntry":
|
|
115
|
+
console.write(message.entry);
|
|
116
|
+
// Fallback channel for unexpected errors without EvoluError typing.
|
|
117
|
+
if (message.entry.method === "error") {
|
|
118
|
+
evoluError.set(createUnknownError(message.entry.args));
|
|
119
|
+
}
|
|
120
|
+
break;
|
|
121
|
+
case "Error":
|
|
122
|
+
evoluError.set(message.error);
|
|
123
|
+
// Keep typed errors visible in logs as operational failures.
|
|
124
|
+
console.error(message.error);
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
exhaustiveCheck(message);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
sharedWorker.port.onMessage = (message) => {
|
|
131
|
+
deps.createDbWorker().postMessage(message, [message.port]);
|
|
132
|
+
};
|
|
133
|
+
disposer.use(acquireLeaderLockCallback(deps)("tab", () => {
|
|
134
|
+
sharedWorker.port.postMessage({
|
|
135
|
+
type: "AnnounceTabLeader",
|
|
136
|
+
consoleLevel: console.getLevel(),
|
|
137
|
+
});
|
|
138
|
+
}));
|
|
139
|
+
const disposables = disposer.move();
|
|
140
|
+
return {
|
|
141
|
+
...deps,
|
|
142
|
+
evoluError,
|
|
143
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
catch (e_1) {
|
|
147
|
+
env_1.error = e_1;
|
|
148
|
+
env_1.hasError = true;
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
__disposeResources(env_1);
|
|
152
|
+
}
|
|
137
153
|
};
|
|
138
154
|
/**
|
|
139
155
|
* Creates an {@link Evolu} instance from {@link EvoluSchema} and
|
|
140
156
|
* {@link EvoluConfig}.
|
|
141
157
|
*/
|
|
142
158
|
export const createEvolu = (schema, config) => async (run) => {
|
|
143
|
-
const
|
|
159
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
144
160
|
try {
|
|
145
161
|
const { appName, appOwner, memoryOnly = false, transports = [{ type: "WebSocket", url: "wss://free.evoluhq.com" }], } = config;
|
|
146
162
|
const name = Name.orThrow(`${appName}-${createIdFromString(appOwner.id)}`);
|
|
147
163
|
const console = run.deps.console.child(name).child("Evolu");
|
|
148
164
|
console.info("createEvolu");
|
|
149
|
-
const
|
|
150
|
-
const rowsByQueryMapStore =
|
|
151
|
-
const subscribedQueriesRefCount =
|
|
165
|
+
const disposer = __addDisposableResource(env_2, new AsyncDisposableStack(), true);
|
|
166
|
+
const rowsByQueryMapStore = disposer.use(createStore(new Map()));
|
|
167
|
+
const subscribedQueriesRefCount = disposer.use(createRefCountByKey());
|
|
152
168
|
/**
|
|
153
169
|
* Settle pending query loads during disposal so awaiting callers and React
|
|
154
170
|
* `use` thenables do not hang forever during teardown.
|
|
155
171
|
*/
|
|
156
|
-
const loadingPromisesByQuery =
|
|
172
|
+
const loadingPromisesByQuery = disposer.adopt(new Map(), (loadingPromisesByQuery) => {
|
|
157
173
|
for (const loadingPromise of loadingPromisesByQuery.values()) {
|
|
158
174
|
if (loadingPromise.promise.status === "fulfilled")
|
|
159
175
|
continue;
|
|
@@ -199,13 +215,13 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
199
215
|
}
|
|
200
216
|
}
|
|
201
217
|
};
|
|
202
|
-
const onMutateCompleteCallbacks =
|
|
218
|
+
const onMutateCompleteCallbacks = disposer.use(createCallbacks(run.deps));
|
|
203
219
|
let exportDatabasePending = null;
|
|
204
|
-
|
|
220
|
+
disposer.defer(() => {
|
|
205
221
|
exportDatabasePending?.reject({ type: "EvoluDisposedError" });
|
|
206
222
|
exportDatabasePending = null;
|
|
207
223
|
});
|
|
208
|
-
const mutateBatch =
|
|
224
|
+
const mutateBatch = disposer.use(createMicrotaskBatch((items) => {
|
|
209
225
|
console.debug("mutateBatch", { changeCount: items.length });
|
|
210
226
|
releaseUnsubscribedLoadingPromises();
|
|
211
227
|
postMessage({
|
|
@@ -217,19 +233,20 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
217
233
|
subscribedQueries: subscribedQueriesRefCount.keys(),
|
|
218
234
|
});
|
|
219
235
|
}));
|
|
220
|
-
const queryBatch =
|
|
236
|
+
const queryBatch = disposer.use(createMicrotaskBatch((queries) => {
|
|
221
237
|
const dedupedQueries = new Set(queries);
|
|
222
238
|
assert(isNonEmptySet(dedupedQueries), "Expected non-empty query batch.");
|
|
223
239
|
console.debug("queryBatch", { queryCount: dedupedQueries.size });
|
|
224
240
|
postMessage({ type: "Query", queries: dedupedQueries });
|
|
225
241
|
}));
|
|
226
|
-
const useOwnerBatch =
|
|
242
|
+
const useOwnerBatch = disposer.use(createMicrotaskBatch((actions) => postMessage({ type: "UseOwner", actions })));
|
|
227
243
|
let postMessage;
|
|
228
244
|
// Scope worker/channel wiring and keep only postMessage outside.
|
|
229
245
|
{
|
|
230
|
-
const
|
|
231
|
-
const
|
|
232
|
-
|
|
246
|
+
const id = createId(run.deps);
|
|
247
|
+
const { createMessageChannel, sharedWorker } = run.deps;
|
|
248
|
+
disposer.use(await run.orThrow(acquireLeaderLock(id)));
|
|
249
|
+
const evoluChannel = disposer.use(createMessageChannel());
|
|
233
250
|
evoluChannel.port1.onMessage = (message) => {
|
|
234
251
|
switch (message.type) {
|
|
235
252
|
case "OnPatchesByQuery": {
|
|
@@ -294,30 +311,17 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
294
311
|
sharedWorker.port.postMessage({
|
|
295
312
|
type: "CreateEvolu",
|
|
296
313
|
name,
|
|
297
|
-
|
|
298
|
-
dbWorkerPort: dbWorkerChannel.port2.native,
|
|
299
|
-
}, [evoluChannel.port2.native, dbWorkerChannel.port2.native]);
|
|
300
|
-
/**
|
|
301
|
-
* No stack.use because Evolu instances don't dispose DbWorker because
|
|
302
|
-
* it's SharedWorder responsibility. DbWorker can be used by another tab.
|
|
303
|
-
* That's required because SQLite WASM needs a single web worker.
|
|
304
|
-
*/
|
|
305
|
-
createDbWorker().postMessage({
|
|
306
|
-
type: "Init",
|
|
307
|
-
name,
|
|
314
|
+
id,
|
|
308
315
|
consoleLevel: console.getLevel(),
|
|
309
316
|
sqliteSchema: evoluSchemaToSqliteSchema(schema, config.indexes),
|
|
310
317
|
encryptionKey: appOwner.encryptionKey,
|
|
311
318
|
memoryOnly,
|
|
312
|
-
|
|
313
|
-
}, [
|
|
319
|
+
evoluPort: evoluChannel.port2.native,
|
|
320
|
+
}, [evoluChannel.port2.native]);
|
|
314
321
|
postMessage = evoluChannel.port1.postMessage;
|
|
315
|
-
stack.defer(() => {
|
|
316
|
-
postMessage({ type: "Dispose" });
|
|
317
|
-
});
|
|
318
322
|
}
|
|
319
323
|
const createMutation = (kind) => (table, values, options) => {
|
|
320
|
-
assertNotDisposed(
|
|
324
|
+
assertNotDisposed(disposables);
|
|
321
325
|
const { id = createId(run.deps), isDeleted, ...changeValues } = values;
|
|
322
326
|
const dbChange = {
|
|
323
327
|
table,
|
|
@@ -336,7 +340,7 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
336
340
|
return { id };
|
|
337
341
|
};
|
|
338
342
|
const loadQuery = (query) => {
|
|
339
|
-
assertNotDisposed(
|
|
343
|
+
assertNotDisposed(disposables);
|
|
340
344
|
const loadingPromise = loadingPromisesByQuery.get(query);
|
|
341
345
|
if (loadingPromise) {
|
|
342
346
|
return loadingPromise.promise;
|
|
@@ -353,12 +357,12 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
353
357
|
return typedPromise;
|
|
354
358
|
};
|
|
355
359
|
const getQueryRows = (query) => {
|
|
356
|
-
assertNotDisposed(
|
|
360
|
+
assertNotDisposed(disposables);
|
|
357
361
|
return (rowsByQueryMapStore.get().get(query) ??
|
|
358
362
|
emptyArray);
|
|
359
363
|
};
|
|
360
364
|
const useOwner = (owner, ownerTransports) => {
|
|
361
|
-
assertNotDisposed(
|
|
365
|
+
assertNotDisposed(disposables);
|
|
362
366
|
const effectiveTransports = ownerTransports ?? transports;
|
|
363
367
|
assertNonEmptyReadonlyArray(effectiveTransports, "useOwner requires explicit non-empty transports when config.transports is empty.");
|
|
364
368
|
const syncOwner = {
|
|
@@ -371,6 +375,8 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
371
375
|
});
|
|
372
376
|
let isUsed = true;
|
|
373
377
|
return () => {
|
|
378
|
+
if (disposables.disposed)
|
|
379
|
+
return;
|
|
374
380
|
assert(isUsed, "UnuseOwner can be called only once.");
|
|
375
381
|
isUsed = false;
|
|
376
382
|
useOwnerBatch.push({
|
|
@@ -379,9 +385,12 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
379
385
|
});
|
|
380
386
|
};
|
|
381
387
|
};
|
|
382
|
-
const
|
|
388
|
+
const disposables = disposer.move();
|
|
383
389
|
if (isNonEmptyArray(transports))
|
|
384
390
|
useOwner(appOwner);
|
|
391
|
+
if (run.signal.aborted) {
|
|
392
|
+
await disposables.disposeAsync();
|
|
393
|
+
}
|
|
385
394
|
return ok({
|
|
386
395
|
name,
|
|
387
396
|
appOwner,
|
|
@@ -391,7 +400,7 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
391
400
|
loadQuery,
|
|
392
401
|
loadQueries: (queries) => queries.map((query) => loadQuery(query)),
|
|
393
402
|
subscribeQuery: (query) => (listener) => {
|
|
394
|
-
assertNotDisposed(
|
|
403
|
+
assertNotDisposed(disposables);
|
|
395
404
|
subscribedQueriesRefCount.increment(query);
|
|
396
405
|
let isSubscribed = true;
|
|
397
406
|
let previousRows = null;
|
|
@@ -407,14 +416,14 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
407
416
|
isSubscribed = false;
|
|
408
417
|
previousRows = null;
|
|
409
418
|
unsubscribe();
|
|
410
|
-
if (
|
|
419
|
+
if (disposables.disposed)
|
|
411
420
|
return;
|
|
412
421
|
subscribedQueriesRefCount.decrement(query);
|
|
413
422
|
};
|
|
414
423
|
},
|
|
415
424
|
getQueryRows,
|
|
416
425
|
exportDatabase: () => {
|
|
417
|
-
assertNotDisposed(
|
|
426
|
+
assertNotDisposed(disposables);
|
|
418
427
|
if (!exportDatabasePending) {
|
|
419
428
|
exportDatabasePending =
|
|
420
429
|
Promise.withResolvers();
|
|
@@ -423,27 +432,28 @@ export const createEvolu = (schema, config) => async (run) => {
|
|
|
423
432
|
return exportDatabasePending.promise;
|
|
424
433
|
},
|
|
425
434
|
deleteDatabase: () => {
|
|
426
|
-
assertNotDisposed(
|
|
435
|
+
assertNotDisposed(disposables);
|
|
427
436
|
todo();
|
|
428
437
|
},
|
|
429
438
|
deleteOwner: (owner) => {
|
|
430
|
-
assertNotDisposed(
|
|
439
|
+
assertNotDisposed(disposables);
|
|
431
440
|
void owner;
|
|
432
441
|
todo();
|
|
433
442
|
},
|
|
434
443
|
useOwner,
|
|
435
444
|
[Symbol.asyncDispose]: () => {
|
|
436
|
-
|
|
437
|
-
|
|
445
|
+
if (!disposables.disposed)
|
|
446
|
+
console.info("disposeEvolu");
|
|
447
|
+
return disposables.disposeAsync();
|
|
438
448
|
},
|
|
439
449
|
});
|
|
440
450
|
}
|
|
441
|
-
catch (
|
|
442
|
-
|
|
443
|
-
|
|
451
|
+
catch (e_2) {
|
|
452
|
+
env_2.error = e_2;
|
|
453
|
+
env_2.hasError = true;
|
|
444
454
|
}
|
|
445
455
|
finally {
|
|
446
|
-
const result_1 = __disposeResources(
|
|
456
|
+
const result_1 = __disposeResources(env_2);
|
|
447
457
|
if (result_1)
|
|
448
458
|
await result_1;
|
|
449
459
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Owner.d.ts","sourceRoot":"","sources":["../../../src/local-first/Owner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAUnD,OAAO,EAML,QAAQ,EACR,cAAc,EACd,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAC;CAC5C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,WAAW,KAAM,SAAQ,aAAa;IAC1C,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,KAAK,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC,cAAc,CAAC,CAAC;CAC5D;AAED,iFAAiF;AACjF,eAAO,MAAM,OAAO,mZAAqC,CAAC;AAC1D,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAE1C,+CAA+C;AAC/C,eAAO,MAAM,YAAY,uvBAA+C,CAAC;AACzE,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAC;AAEpD,wDAAwD;AACxD,eAAO,MAAM,qBAAqB,GAAI,SAAS,OAAO,KAAG,YACnB,CAAC;AAEvC,wDAAwD;AACxD,eAAO,MAAM,qBAAqB,GAAI,cAAc,YAAY,KAAG,
|
|
1
|
+
{"version":3,"file":"Owner.d.ts","sourceRoot":"","sources":["../../../src/local-first/Owner.ts"],"names":[],"mappings":"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"}
|