@evolu/common 8.0.0-next.3 → 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 +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 +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 +195 -53
- 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
|
@@ -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,16 +69,18 @@ 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
|
|
78
|
+
const disposer = __addDisposableResource(env_1, new AsyncDisposableStack(), true);
|
|
79
|
+
disposer.use(self);
|
|
80
|
+
const dbWorkerRun = disposer.use(run.create());
|
|
81
|
+
const { deps } = dbWorkerRun;
|
|
79
82
|
let initialized = false;
|
|
80
|
-
const initMessage = await
|
|
83
|
+
const initMessage = await dbWorkerRun.orThrow(callback(({ ok }) => {
|
|
81
84
|
self.onMessage = (message) => {
|
|
82
85
|
assert(!initialized, "DbWorker must be initialized only once");
|
|
83
86
|
initialized = true;
|
|
@@ -86,24 +89,29 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
86
89
|
}));
|
|
87
90
|
const console = deps.console.child(initMessage.name).child("DbWorker");
|
|
88
91
|
console.setLevel(initMessage.consoleLevel);
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
+
const port = disposer.use(deps.createMessagePort(initMessage.port));
|
|
93
|
+
const consoleEntryOrErrorBroadcastChannel = disposer.use(deps.createBroadcastChannel(consoleEntryOrErrorBroadcastChannelName));
|
|
94
|
+
disposer.defer(deps.consoleStoreOutputEntry.subscribe(() => {
|
|
92
95
|
const entry = deps.consoleStoreOutputEntry.get();
|
|
93
96
|
if (entry)
|
|
94
|
-
|
|
97
|
+
consoleEntryOrErrorBroadcastChannel.postMessage({
|
|
98
|
+
type: "ConsoleEntry",
|
|
99
|
+
entry,
|
|
100
|
+
});
|
|
95
101
|
}));
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return ok();
|
|
102
|
+
console.debug("createDbWorker");
|
|
103
|
+
disposer.use(await dbWorkerRun.orThrow(acquireLeaderLock(initMessage.name)));
|
|
99
104
|
port.postMessage({ type: "LeaderAcquired", name: initMessage.name });
|
|
100
|
-
const sqlite =
|
|
105
|
+
const sqlite = disposer.use(await dbWorkerRun.orThrow(createSqlite(initMessage.name, initMessage.memoryOnly
|
|
101
106
|
? { mode: "memory" }
|
|
102
107
|
: { mode: "encrypted", encryptionKey: initMessage.encryptionKey })));
|
|
103
108
|
console.debug("SQLite created");
|
|
104
|
-
const baseSqliteStorage = createBaseSqliteStorage({
|
|
109
|
+
const baseSqliteStorage = createBaseSqliteStorage({
|
|
110
|
+
sqlite,
|
|
111
|
+
...dbWorkerRun.deps,
|
|
112
|
+
});
|
|
105
113
|
const dbDeps = {
|
|
106
|
-
...
|
|
114
|
+
...dbWorkerRun.deps,
|
|
107
115
|
sqlite,
|
|
108
116
|
sqliteSchema: initMessage.sqliteSchema,
|
|
109
117
|
baseSqliteStorage,
|
|
@@ -120,27 +128,22 @@ 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
|
-
const
|
|
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
|
+
const dbWorkerRunWithStorage = dbWorkerRun.addDeps({ storage });
|
|
139
|
+
port.onMessage = (input) => {
|
|
140
|
+
if (input.type === "Dispose") {
|
|
141
|
+
if (!disposables.disposed)
|
|
142
|
+
console.debug("disposeDbWorker");
|
|
143
|
+
void disposables.disposeAsync();
|
|
142
144
|
return;
|
|
143
|
-
|
|
145
|
+
}
|
|
146
|
+
const { callbackId, request } = input;
|
|
144
147
|
const postQueuedResponse = (response) => {
|
|
145
148
|
port.postMessage({ type: "OnQueuedResponse", callbackId, response }, response.type === "ForEvolu" && response.message.type === "Export"
|
|
146
149
|
? [response.message.file.buffer]
|
|
@@ -152,12 +155,15 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
152
155
|
case "Mutate": {
|
|
153
156
|
const result = handleMutation({ ...dbDeps, clock })(request.message);
|
|
154
157
|
if (!result.ok) {
|
|
155
|
-
|
|
158
|
+
consoleEntryOrErrorBroadcastChannel.postMessage({
|
|
159
|
+
type: "Error",
|
|
160
|
+
error: result.error,
|
|
161
|
+
});
|
|
156
162
|
}
|
|
157
163
|
else {
|
|
158
164
|
postQueuedResponse({
|
|
159
165
|
type: "ForEvolu",
|
|
160
|
-
|
|
166
|
+
id: request.id,
|
|
161
167
|
message: result.value,
|
|
162
168
|
});
|
|
163
169
|
}
|
|
@@ -166,7 +172,7 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
166
172
|
case "Query":
|
|
167
173
|
postQueuedResponse({
|
|
168
174
|
type: "ForEvolu",
|
|
169
|
-
|
|
175
|
+
id: request.id,
|
|
170
176
|
message: {
|
|
171
177
|
type: "Query",
|
|
172
178
|
rowsByQuery: loadQueries(dbDeps)(request.message.queries),
|
|
@@ -176,7 +182,7 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
176
182
|
case "Export":
|
|
177
183
|
postQueuedResponse({
|
|
178
184
|
type: "ForEvolu",
|
|
179
|
-
|
|
185
|
+
id: request.id,
|
|
180
186
|
message: {
|
|
181
187
|
type: "Export",
|
|
182
188
|
file: dbDeps.sqlite.export(),
|
|
@@ -211,7 +217,7 @@ export const startDbWorker = (self) => async (_run) => {
|
|
|
211
217
|
}
|
|
212
218
|
case "ApplySyncMessage": {
|
|
213
219
|
const { owner, inputMessage } = request.message;
|
|
214
|
-
|
|
220
|
+
dbWorkerRunWithStorage(async (run) => {
|
|
215
221
|
storage.setRequestContext(owner.encryptionKey);
|
|
216
222
|
const result = await run(applyProtocolMessageAsClient(inputMessage, {
|
|
217
223
|
writeKey: owner.writeKey,
|
|
@@ -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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"}
|