@evolu/web 3.0.0-next.0 → 3.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/LICENSE +21 -0
- package/dist/src/Platform.d.ts +3 -1
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +3 -0
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +138 -57
- package/dist/src/Task.d.ts +9 -19
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +10 -59
- package/dist/src/Worker.d.ts +25 -3
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +231 -12
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/local-first/Db.worker.js +3 -4
- package/dist/src/local-first/Evolu.d.ts +8 -2
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +40 -8
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Shared.worker.js +108 -4
- package/dist/src/local-first/index.d.ts +1 -1
- package/package.json +17 -14
- package/src/Platform.ts +5 -1
- package/src/Sqlite.ts +47 -18
- package/src/Task.ts +23 -70
- package/src/Worker.ts +181 -13
- package/src/index.ts +5 -4
- package/src/local-first/Db.worker.ts +5 -6
- package/src/local-first/Evolu.ts +64 -5
- package/src/local-first/Shared.worker.ts +46 -6
- package/src/local-first/index.ts +1 -1
package/dist/src/Worker.js
CHANGED
|
@@ -1,7 +1,84 @@
|
|
|
1
|
-
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
53
|
+
import { assert, createConsole, createConsoleStoreOutput, disposable, } from "@evolu/common";
|
|
2
54
|
/** Creates a {@link Worker} from a Web Worker. */
|
|
3
55
|
export const createWorker = (nativeWorker) => wrap(nativeWorker);
|
|
4
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Installs a one-tab SharedWorker polyfill backed by a Web Worker.
|
|
58
|
+
*
|
|
59
|
+
* Use it before constructing a SharedWorker in browsers without native
|
|
60
|
+
* SharedWorker support.
|
|
61
|
+
*/
|
|
62
|
+
export const installOneTabSharedWorkerPolyfill = () => {
|
|
63
|
+
if (typeof globalThis.SharedWorker === "function")
|
|
64
|
+
return;
|
|
65
|
+
Object.defineProperty(globalThis, "SharedWorker", {
|
|
66
|
+
configurable: true,
|
|
67
|
+
writable: true,
|
|
68
|
+
value: class {
|
|
69
|
+
port;
|
|
70
|
+
constructor(scriptURL, options) {
|
|
71
|
+
this.port = new globalThis.Worker(scriptURL, options);
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Creates a {@link SharedWorker} from a Web SharedWorker.
|
|
78
|
+
*
|
|
79
|
+
* Call {@link installOneTabSharedWorkerPolyfill} first to support browsers
|
|
80
|
+
* without native SharedWorker support.
|
|
81
|
+
*/
|
|
5
82
|
export const createSharedWorker = (nativeSharedWorker) => {
|
|
6
83
|
const port = wrap(nativeSharedWorker.port);
|
|
7
84
|
return {
|
|
@@ -21,15 +98,26 @@ export const createSharedWorker = (nativeSharedWorker) => {
|
|
|
21
98
|
* ```
|
|
22
99
|
*/
|
|
23
100
|
export const createMessageChannel = () => {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
101
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
102
|
+
try {
|
|
103
|
+
const channel = new globalThis.MessageChannel();
|
|
104
|
+
const disposer = __addDisposableResource(env_1, new DisposableStack(), false);
|
|
105
|
+
const port1 = disposer.use(wrap(channel.port1));
|
|
106
|
+
const port2 = disposer.use(wrap(channel.port2));
|
|
107
|
+
const disposables = disposer.move();
|
|
108
|
+
return {
|
|
109
|
+
port1,
|
|
110
|
+
port2,
|
|
111
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (e_1) {
|
|
115
|
+
env_1.error = e_1;
|
|
116
|
+
env_1.hasError = true;
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
__disposeResources(env_1);
|
|
120
|
+
}
|
|
33
121
|
};
|
|
34
122
|
/**
|
|
35
123
|
* Creates an Evolu {@link MessagePort} from a Web MessagePort.
|
|
@@ -37,6 +125,46 @@ export const createMessageChannel = () => {
|
|
|
37
125
|
* Use this for ports received via postMessage transfer.
|
|
38
126
|
*/
|
|
39
127
|
export const createMessagePort = (nativePort) => wrap(nativePort);
|
|
128
|
+
/** Creates an Evolu {@link BroadcastChannel} from a Web BroadcastChannel. */
|
|
129
|
+
export const createBroadcastChannel = (name) => {
|
|
130
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
131
|
+
try {
|
|
132
|
+
const nativeBroadcastChannel = new globalThis.BroadcastChannel(name);
|
|
133
|
+
const disposer = __addDisposableResource(env_2, new DisposableStack(), false);
|
|
134
|
+
let disposed = false;
|
|
135
|
+
disposer.defer(() => {
|
|
136
|
+
disposed = true;
|
|
137
|
+
nativeBroadcastChannel.onmessage = null;
|
|
138
|
+
nativeBroadcastChannel.close();
|
|
139
|
+
});
|
|
140
|
+
let onMessageHandler = null;
|
|
141
|
+
return disposable({
|
|
142
|
+
postMessage: (message) => {
|
|
143
|
+
nativeBroadcastChannel.postMessage(message);
|
|
144
|
+
},
|
|
145
|
+
get onMessage() {
|
|
146
|
+
return disposed ? null : onMessageHandler;
|
|
147
|
+
},
|
|
148
|
+
set onMessage(fn) {
|
|
149
|
+
if (disposed)
|
|
150
|
+
return;
|
|
151
|
+
onMessageHandler = fn;
|
|
152
|
+
nativeBroadcastChannel.onmessage = fn
|
|
153
|
+
? (event) => {
|
|
154
|
+
fn(event.data);
|
|
155
|
+
}
|
|
156
|
+
: null;
|
|
157
|
+
},
|
|
158
|
+
}, disposer);
|
|
159
|
+
}
|
|
160
|
+
catch (e_2) {
|
|
161
|
+
env_2.error = e_2;
|
|
162
|
+
env_2.hasError = true;
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
__disposeResources(env_2);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
40
168
|
/**
|
|
41
169
|
* Creates an Evolu {@link WorkerSelf} from a Web `DedicatedWorkerGlobalScope`
|
|
42
170
|
* (`self` inside a dedicated worker).
|
|
@@ -62,6 +190,95 @@ export const createSharedWorkerSelf = (nativeSelf) => {
|
|
|
62
190
|
};
|
|
63
191
|
return self;
|
|
64
192
|
};
|
|
193
|
+
/**
|
|
194
|
+
* Creates a one-tab {@link SharedWorkerSelf} polyfill for browsers without
|
|
195
|
+
* native SharedWorker support.
|
|
196
|
+
*
|
|
197
|
+
* Delivers one synthetic `onConnect` port, queues startup messages until
|
|
198
|
+
* `onMessage` is set, and does not share state across tabs.
|
|
199
|
+
*/
|
|
200
|
+
export const createOneTabSharedWorkerSelfPolyfill = (nativeSelf) => {
|
|
201
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
202
|
+
try {
|
|
203
|
+
const disposer = __addDisposableResource(env_3, new DisposableStack(), false);
|
|
204
|
+
let onConnectHandler = null;
|
|
205
|
+
let onMessageHandler = null;
|
|
206
|
+
const messages = [];
|
|
207
|
+
let connected = false;
|
|
208
|
+
disposer.defer(() => {
|
|
209
|
+
messages.length = 0;
|
|
210
|
+
onConnectHandler = null;
|
|
211
|
+
onMessageHandler = null;
|
|
212
|
+
nativeSelf.onmessage = null;
|
|
213
|
+
nativeSelf.close();
|
|
214
|
+
});
|
|
215
|
+
const disposables = disposer.move();
|
|
216
|
+
nativeSelf.onmessage = (event) => {
|
|
217
|
+
if (disposables.disposed)
|
|
218
|
+
return;
|
|
219
|
+
const handler = onMessageHandler;
|
|
220
|
+
if (handler)
|
|
221
|
+
handler(event.data);
|
|
222
|
+
else
|
|
223
|
+
messages.push(event.data);
|
|
224
|
+
};
|
|
225
|
+
const flushMessages = () => {
|
|
226
|
+
for (const message of messages.splice(0)) {
|
|
227
|
+
const handler = onMessageHandler;
|
|
228
|
+
if (!handler)
|
|
229
|
+
return;
|
|
230
|
+
handler(message);
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
const port = {
|
|
234
|
+
postMessage: (message, transfer) => {
|
|
235
|
+
if (disposables.disposed)
|
|
236
|
+
return;
|
|
237
|
+
if (transfer == null)
|
|
238
|
+
nativeSelf.postMessage(message);
|
|
239
|
+
else
|
|
240
|
+
nativeSelf.postMessage(message, [...transfer]);
|
|
241
|
+
},
|
|
242
|
+
get onMessage() {
|
|
243
|
+
return disposables.disposed ? null : onMessageHandler;
|
|
244
|
+
},
|
|
245
|
+
set onMessage(fn) {
|
|
246
|
+
if (disposables.disposed)
|
|
247
|
+
return;
|
|
248
|
+
onMessageHandler = fn;
|
|
249
|
+
if (fn)
|
|
250
|
+
flushMessages();
|
|
251
|
+
},
|
|
252
|
+
native: nativeSelf,
|
|
253
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
254
|
+
};
|
|
255
|
+
const connect = () => {
|
|
256
|
+
if (connected || !onConnectHandler)
|
|
257
|
+
return;
|
|
258
|
+
connected = true;
|
|
259
|
+
onConnectHandler(port);
|
|
260
|
+
};
|
|
261
|
+
return {
|
|
262
|
+
get onConnect() {
|
|
263
|
+
return onConnectHandler;
|
|
264
|
+
},
|
|
265
|
+
set onConnect(fn) {
|
|
266
|
+
if (disposables.disposed)
|
|
267
|
+
return;
|
|
268
|
+
onConnectHandler = fn;
|
|
269
|
+
connect();
|
|
270
|
+
},
|
|
271
|
+
[Symbol.dispose]: () => disposables.dispose(),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
catch (e_3) {
|
|
275
|
+
env_3.error = e_3;
|
|
276
|
+
env_3.hasError = true;
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
__disposeResources(env_3);
|
|
280
|
+
}
|
|
281
|
+
};
|
|
65
282
|
/** Creates deps shared by web worker entry points. */
|
|
66
283
|
export const createWorkerDeps = () => {
|
|
67
284
|
const consoleStoreOutput = createConsoleStoreOutput();
|
|
@@ -69,6 +286,8 @@ export const createWorkerDeps = () => {
|
|
|
69
286
|
return {
|
|
70
287
|
console,
|
|
71
288
|
consoleStoreOutputEntry: consoleStoreOutput.entry,
|
|
289
|
+
createBroadcastChannel,
|
|
290
|
+
createMessageChannel,
|
|
72
291
|
createMessagePort,
|
|
73
292
|
};
|
|
74
293
|
};
|
|
@@ -99,7 +318,7 @@ const wrap = (native) => {
|
|
|
99
318
|
native: native,
|
|
100
319
|
[Symbol.dispose]: () => {
|
|
101
320
|
native.onmessage = null;
|
|
102
|
-
if (
|
|
321
|
+
if ("terminate" in native)
|
|
103
322
|
native.terminate();
|
|
104
323
|
else
|
|
105
324
|
native.close();
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export * from "./local-first/index.
|
|
2
|
-
export
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
1
|
+
export * from "./local-first/index.ts";
|
|
2
|
+
export { availableParallelism } from "./Platform.ts";
|
|
3
|
+
export * from "./Sqlite.ts";
|
|
4
|
+
export * from "./Task.ts";
|
|
5
|
+
export * from "./Worker.ts";
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -4,13 +4,12 @@ installPolyfills();
|
|
|
4
4
|
import { createRandomBytes } from "@evolu/common";
|
|
5
5
|
import { startDbWorker } from "@evolu/common/local-first";
|
|
6
6
|
import { createWasmSqliteDriver } from "../Sqlite.js";
|
|
7
|
-
import {
|
|
7
|
+
import { createRun } from "../Task.js";
|
|
8
8
|
import { createWorkerDeps, createWorkerSelf } from "../Worker.js";
|
|
9
|
-
// TODO: Disposal.
|
|
10
9
|
const run = createRun({
|
|
11
10
|
...createWorkerDeps(),
|
|
12
11
|
createSqliteDriver: createWasmSqliteDriver,
|
|
13
|
-
|
|
12
|
+
lockManager: globalThis.navigator.locks,
|
|
14
13
|
randomBytes: createRandomBytes(),
|
|
15
14
|
});
|
|
16
|
-
run(startDbWorker(createWorkerSelf(self)));
|
|
15
|
+
void run(startDbWorker(createWorkerSelf(self)));
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ConsoleDep } from "@evolu/common";
|
|
2
2
|
import type { EvoluDeps } from "@evolu/common/local-first";
|
|
3
|
+
export interface SharedWorkerUnsupported {
|
|
4
|
+
readonly type: "SharedWorkerUnsupported";
|
|
5
|
+
}
|
|
6
|
+
export interface SharedWorkerUnsupportedDep {
|
|
7
|
+
readonly onSharedWorkerUnsupported: () => void;
|
|
8
|
+
}
|
|
3
9
|
/** Creates Evolu dependencies for the web platform. */
|
|
4
|
-
export declare const createEvoluDeps: (deps?: Partial<ConsoleDep>) => EvoluDeps;
|
|
10
|
+
export declare const createEvoluDeps: (deps?: Partial<ConsoleDep> & Partial<SharedWorkerUnsupportedDep>) => EvoluDeps;
|
|
5
11
|
//# sourceMappingURL=Evolu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,KAAK,EAIV,SAAS,EAGV,MAAM,2BAA2B,CAAC;AAkBnC,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;CAC1C;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,yBAAyB,EAAE,MAAM,IAAI,CAAC;CAChD;AAED,uDAAuD;AACvD,eAAO,MAAM,eAAe,UACpB,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,0BAA0B,CAAC,KAC9D,SAkEF,CAAC"}
|
|
@@ -1,24 +1,56 @@
|
|
|
1
|
+
import { exhaustiveCheck } from "@evolu/common";
|
|
1
2
|
import { createEvoluDeps as createCommonEvoluDeps } from "@evolu/common/local-first";
|
|
2
3
|
import { reloadApp } from "../Platform.js";
|
|
3
|
-
import { createMessageChannel, createSharedWorker, createWorker, } from "../Worker.js";
|
|
4
|
-
// // TODO: Redesign.
|
|
5
|
-
// // eslint-disable-next-line evolu/require-pure-annotation
|
|
6
|
-
// export const localAuth = createLocalAuth({
|
|
7
|
-
// randomBytes: createRandomBytes(),
|
|
8
|
-
// secureStorage: createWebAuthnStore({ randomBytes: createRandomBytes() }),
|
|
9
|
-
// });
|
|
4
|
+
import { createBroadcastChannel, createMessageChannel, createSharedWorker, createWorker, installOneTabSharedWorkerPolyfill, } from "../Worker.js";
|
|
10
5
|
/** Creates Evolu dependencies for the web platform. */
|
|
11
6
|
export const createEvoluDeps = (deps = {}) => {
|
|
7
|
+
installOneTabSharedWorkerPolyfill();
|
|
12
8
|
const createDbWorker = () => createWorker(new Worker(new URL("Db.worker.js", import.meta.url), {
|
|
13
9
|
type: "module",
|
|
14
10
|
}));
|
|
15
|
-
const
|
|
11
|
+
const webSharedWorker = createSharedWorker(new SharedWorker(new URL("Shared.worker.js", import.meta.url), {
|
|
16
12
|
type: "module",
|
|
17
13
|
}));
|
|
14
|
+
let onSharedWorkerMessage = null;
|
|
15
|
+
const sharedWorker = {
|
|
16
|
+
...webSharedWorker,
|
|
17
|
+
port: {
|
|
18
|
+
...webSharedWorker.port,
|
|
19
|
+
get onMessage() {
|
|
20
|
+
return onSharedWorkerMessage;
|
|
21
|
+
},
|
|
22
|
+
set onMessage(fn) {
|
|
23
|
+
onSharedWorkerMessage = fn;
|
|
24
|
+
webSharedWorker.port.onMessage = fn
|
|
25
|
+
? (message) => {
|
|
26
|
+
switch (message.type) {
|
|
27
|
+
case "DbWorkerInit": {
|
|
28
|
+
fn(message);
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case "SharedWorkerUnsupported": {
|
|
32
|
+
if (deps.onSharedWorkerUnsupported) {
|
|
33
|
+
deps.onSharedWorkerUnsupported();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
globalThis.alert("This browser supports Evolu in one tab only. Close this tab and use the already open tab.");
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
default:
|
|
41
|
+
exhaustiveCheck(message);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
: null;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
18
48
|
return createCommonEvoluDeps({
|
|
19
49
|
...deps,
|
|
20
50
|
createDbWorker,
|
|
51
|
+
createBroadcastChannel,
|
|
21
52
|
createMessageChannel,
|
|
53
|
+
lockManager: globalThis.navigator.locks,
|
|
22
54
|
reloadApp,
|
|
23
55
|
sharedWorker,
|
|
24
56
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalAuth.d.ts","sourceRoot":"","sources":["../../../src/local-first/LocalAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,cAAc,EACd,aAAa,EAEd,MAAM,eAAe,CAAC;AAiBvB,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"LocalAuth.d.ts","sourceRoot":"","sources":["../../../src/local-first/LocalAuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,cAAc,EACd,aAAa,EAEd,MAAM,eAAe,CAAC;AAiBvB,eAAO,MAAM,mBAAmB,SAAU,cAAc,KAAG,aA4GzD,CAAC"}
|
|
@@ -1,13 +1,117 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
1
53
|
/// <reference lib="webworker" />
|
|
2
54
|
import { installPolyfills } from "@evolu/common/polyfills";
|
|
3
55
|
installPolyfills();
|
|
4
|
-
import { createWebSocket } from "@evolu/common";
|
|
56
|
+
import { createWebSocket, ok, waitForAbort } from "@evolu/common";
|
|
5
57
|
import { initSharedWorker } from "@evolu/common/local-first";
|
|
6
58
|
import { createRun } from "../Task.js";
|
|
7
|
-
import { createSharedWorkerSelf, createWorkerDeps } from "../Worker.js";
|
|
8
|
-
// No disposal (`await using`) is needed — a SharedWorker lives forever.
|
|
59
|
+
import { createOneTabSharedWorkerSelfPolyfill, createSharedWorkerSelf, createWorkerDeps, } from "../Worker.js";
|
|
9
60
|
const run = createRun({
|
|
10
61
|
...createWorkerDeps(),
|
|
11
62
|
createWebSocket,
|
|
63
|
+
lockManager: globalThis.navigator.locks,
|
|
64
|
+
});
|
|
65
|
+
void run(async (run) => {
|
|
66
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
67
|
+
try {
|
|
68
|
+
if ("onconnect" in self) {
|
|
69
|
+
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
70
|
+
try {
|
|
71
|
+
const _ = __addDisposableResource(env_2, await run.ok(initSharedWorker(createSharedWorkerSelf(self))), true);
|
|
72
|
+
return await run(waitForAbort);
|
|
73
|
+
}
|
|
74
|
+
catch (e_1) {
|
|
75
|
+
env_2.error = e_1;
|
|
76
|
+
env_2.hasError = true;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
const result_1 = __disposeResources(env_2);
|
|
80
|
+
if (result_1)
|
|
81
|
+
await result_1;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const workerSelf = __addDisposableResource(env_1, createOneTabSharedWorkerSelfPolyfill(self), false);
|
|
85
|
+
await globalThis.navigator.locks.request("evolu-one-tab-sharedworker-polyfill", { ifAvailable: true, mode: "exclusive" }, async (lock) => {
|
|
86
|
+
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
87
|
+
try {
|
|
88
|
+
if (!lock) {
|
|
89
|
+
const message = {
|
|
90
|
+
type: "SharedWorkerUnsupported",
|
|
91
|
+
};
|
|
92
|
+
self.postMessage(message);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const _ = __addDisposableResource(env_3, await run.ok(initSharedWorker(workerSelf)), true);
|
|
96
|
+
await run(waitForAbort);
|
|
97
|
+
}
|
|
98
|
+
catch (e_3) {
|
|
99
|
+
env_3.error = e_3;
|
|
100
|
+
env_3.hasError = true;
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
const result_2 = __disposeResources(env_3);
|
|
104
|
+
if (result_2)
|
|
105
|
+
await result_2;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return ok();
|
|
109
|
+
}
|
|
110
|
+
catch (e_2) {
|
|
111
|
+
env_1.error = e_2;
|
|
112
|
+
env_1.hasError = true;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
__disposeResources(env_1);
|
|
116
|
+
}
|
|
12
117
|
});
|
|
13
|
-
run(initSharedWorker(createSharedWorkerSelf(self)));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./Evolu.
|
|
1
|
+
export * from "./Evolu.ts";
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evolu/web",
|
|
3
|
-
"version": "3.0.0
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Evolu for web",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"evolu",
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
],
|
|
9
9
|
"author": "Daniel Steigerwald <daniel@steigerwald.cz>",
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"repository":
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/evoluhq/evolu.git"
|
|
14
|
+
},
|
|
12
15
|
"bugs": {
|
|
13
16
|
"url": "https://github.com/evoluhq/evolu/issues"
|
|
14
17
|
},
|
|
@@ -27,22 +30,18 @@
|
|
|
27
30
|
"src/**",
|
|
28
31
|
"README.md"
|
|
29
32
|
],
|
|
30
|
-
"scripts": {
|
|
31
|
-
"build": "tsc --build tsconfig.build.json",
|
|
32
|
-
"prepack": "npm run build",
|
|
33
|
-
"format": "prettier --write \"src/*.{ts,tsx,md}\""
|
|
34
|
-
},
|
|
35
33
|
"dependencies": {
|
|
36
34
|
"@evolu/sqlite-wasm": "2.2.4",
|
|
37
35
|
"idb-keyval": "^6.2.2"
|
|
38
36
|
},
|
|
39
37
|
"devDependencies": {
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@types/sharedworker": "^0.0.221",
|
|
38
|
+
"@types/node": "^24.10.9",
|
|
39
|
+
"@types/sharedworker": "^0.0.229",
|
|
43
40
|
"@types/web-locks-api": "^0.0.5",
|
|
44
|
-
"typescript": "
|
|
45
|
-
"user-agent-data-types": "^0.4.2"
|
|
41
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
42
|
+
"user-agent-data-types": "^0.4.2",
|
|
43
|
+
"@evolu/common": "8.0.0",
|
|
44
|
+
"@evolu/typescript-config": "0.0.2"
|
|
46
45
|
},
|
|
47
46
|
"peerDependencies": {
|
|
48
47
|
"@evolu/common": "^8.0.0-next.0"
|
|
@@ -53,5 +52,9 @@
|
|
|
53
52
|
"engines": {
|
|
54
53
|
"node": ">=24.0.0"
|
|
55
54
|
},
|
|
56
|
-
"sideEffects": false
|
|
57
|
-
|
|
55
|
+
"sideEffects": false,
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsc --build tsconfig.build.json",
|
|
58
|
+
"format": "prettier --write \"src/*.{ts,tsx,md}\""
|
|
59
|
+
}
|
|
60
|
+
}
|
package/src/Platform.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { PositiveInt, type ReloadApp } from "@evolu/common";
|
|
2
|
+
|
|
3
|
+
/** Returns the amount of logical processors available to the browser. */
|
|
4
|
+
export const availableParallelism = (): PositiveInt =>
|
|
5
|
+
PositiveInt.orThrow(globalThis.navigator.hardwareConcurrency);
|
|
2
6
|
|
|
3
7
|
export const reloadApp: ReloadApp = (url) => {
|
|
4
8
|
if (typeof document === "undefined") {
|