@evolu/web 3.0.0-next.0 → 3.0.0-next.1
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/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +138 -57
- package/dist/src/Task.d.ts +4 -13
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +3 -28
- package/dist/src/Worker.d.ts +25 -3
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +232 -12
- package/dist/src/local-first/Db.worker.js +2 -2
- 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/Shared.worker.js +84 -3
- package/package.json +16 -13
- package/src/Sqlite.ts +47 -18
- package/src/Task.ts +5 -40
- package/src/Worker.ts +178 -10
- package/src/local-first/Db.worker.ts +2 -2
- package/src/local-first/Evolu.ts +62 -3
- package/src/local-first/Shared.worker.ts +44 -4
|
@@ -7,14 +7,14 @@ installPolyfills();
|
|
|
7
7
|
import { createRandomBytes } from "@evolu/common";
|
|
8
8
|
import { startDbWorker } from "@evolu/common/local-first";
|
|
9
9
|
import { createWasmSqliteDriver } from "../Sqlite.js";
|
|
10
|
-
import {
|
|
10
|
+
import { createRun } from "../Task.js";
|
|
11
11
|
import { createWorkerDeps, createWorkerSelf } from "../Worker.js";
|
|
12
12
|
|
|
13
13
|
// TODO: Disposal.
|
|
14
14
|
const run = createRun({
|
|
15
15
|
...createWorkerDeps(),
|
|
16
16
|
createSqliteDriver: createWasmSqliteDriver,
|
|
17
|
-
|
|
17
|
+
lockManager: globalThis.navigator.locks,
|
|
18
18
|
randomBytes: createRandomBytes(),
|
|
19
19
|
});
|
|
20
20
|
|
package/src/local-first/Evolu.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { exhaustiveCheck, type ConsoleDep } from "@evolu/common";
|
|
2
2
|
import type {
|
|
3
|
+
SharedWorker as CommonSharedWorker,
|
|
3
4
|
CreateDbWorker,
|
|
4
5
|
DbWorkerInit,
|
|
5
6
|
EvoluDeps,
|
|
6
7
|
SharedWorkerInput,
|
|
8
|
+
SharedWorkerOutput,
|
|
7
9
|
} from "@evolu/common/local-first";
|
|
8
10
|
import { createEvoluDeps as createCommonEvoluDeps } from "@evolu/common/local-first";
|
|
9
11
|
import { reloadApp } from "../Platform.js";
|
|
10
12
|
import {
|
|
13
|
+
createBroadcastChannel,
|
|
11
14
|
createMessageChannel,
|
|
12
15
|
createSharedWorker,
|
|
13
16
|
createWorker,
|
|
17
|
+
installOneTabSharedWorkerPolyfill,
|
|
14
18
|
} from "../Worker.js";
|
|
15
19
|
|
|
16
20
|
// // TODO: Redesign.
|
|
@@ -20,8 +24,20 @@ import {
|
|
|
20
24
|
// secureStorage: createWebAuthnStore({ randomBytes: createRandomBytes() }),
|
|
21
25
|
// });
|
|
22
26
|
|
|
27
|
+
export interface SharedWorkerUnsupported {
|
|
28
|
+
readonly type: "SharedWorkerUnsupported";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface SharedWorkerUnsupportedDep {
|
|
32
|
+
readonly onSharedWorkerUnsupported: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
/** Creates Evolu dependencies for the web platform. */
|
|
24
|
-
export const createEvoluDeps = (
|
|
36
|
+
export const createEvoluDeps = (
|
|
37
|
+
deps: Partial<ConsoleDep> & Partial<SharedWorkerUnsupportedDep> = {},
|
|
38
|
+
): EvoluDeps => {
|
|
39
|
+
installOneTabSharedWorkerPolyfill();
|
|
40
|
+
|
|
25
41
|
const createDbWorker: CreateDbWorker = () =>
|
|
26
42
|
createWorker<DbWorkerInit, never>(
|
|
27
43
|
new Worker(new URL("Db.worker.js", import.meta.url), {
|
|
@@ -29,16 +45,59 @@ export const createEvoluDeps = (deps: Partial<ConsoleDep> = {}): EvoluDeps => {
|
|
|
29
45
|
}),
|
|
30
46
|
);
|
|
31
47
|
|
|
32
|
-
const
|
|
48
|
+
const webSharedWorker = createSharedWorker<
|
|
49
|
+
SharedWorkerInput,
|
|
50
|
+
SharedWorkerOutput
|
|
51
|
+
>(
|
|
33
52
|
new SharedWorker(new URL("Shared.worker.js", import.meta.url), {
|
|
34
53
|
type: "module",
|
|
35
54
|
}),
|
|
36
55
|
);
|
|
56
|
+
let onSharedWorkerMessage: ((message: SharedWorkerOutput) => void) | null =
|
|
57
|
+
null;
|
|
58
|
+
const sharedWorker: CommonSharedWorker = {
|
|
59
|
+
...webSharedWorker,
|
|
60
|
+
port: {
|
|
61
|
+
...webSharedWorker.port,
|
|
62
|
+
get onMessage() {
|
|
63
|
+
return onSharedWorkerMessage;
|
|
64
|
+
},
|
|
65
|
+
set onMessage(fn) {
|
|
66
|
+
onSharedWorkerMessage = fn;
|
|
67
|
+
webSharedWorker.port.onMessage = fn
|
|
68
|
+
? (message: SharedWorkerOutput | SharedWorkerUnsupported) => {
|
|
69
|
+
switch (message.type) {
|
|
70
|
+
case "DbWorkerInit": {
|
|
71
|
+
fn(message);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
case "SharedWorkerUnsupported": {
|
|
76
|
+
if (deps.onSharedWorkerUnsupported) {
|
|
77
|
+
deps.onSharedWorkerUnsupported();
|
|
78
|
+
} else {
|
|
79
|
+
globalThis.alert(
|
|
80
|
+
"This browser supports Evolu in one tab only. Close this tab and use the already open tab.",
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
default:
|
|
87
|
+
exhaustiveCheck(message);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
: null;
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
37
94
|
|
|
38
95
|
return createCommonEvoluDeps({
|
|
39
96
|
...deps,
|
|
40
97
|
createDbWorker,
|
|
98
|
+
createBroadcastChannel,
|
|
41
99
|
createMessageChannel,
|
|
100
|
+
lockManager: globalThis.navigator.locks,
|
|
42
101
|
reloadApp,
|
|
43
102
|
sharedWorker,
|
|
44
103
|
});
|
|
@@ -1,18 +1,58 @@
|
|
|
1
1
|
/// <reference lib="webworker" />
|
|
2
|
-
declare const self: SharedWorkerGlobalScope;
|
|
2
|
+
declare const self: DedicatedWorkerGlobalScope | SharedWorkerGlobalScope;
|
|
3
3
|
|
|
4
4
|
import { installPolyfills } from "@evolu/common/polyfills";
|
|
5
5
|
installPolyfills();
|
|
6
6
|
|
|
7
|
-
import { createWebSocket } from "@evolu/common";
|
|
7
|
+
import { createWebSocket, ok } from "@evolu/common";
|
|
8
|
+
import type {
|
|
9
|
+
SharedWorkerInput,
|
|
10
|
+
SharedWorkerOutput,
|
|
11
|
+
} from "@evolu/common/local-first";
|
|
8
12
|
import { initSharedWorker } from "@evolu/common/local-first";
|
|
13
|
+
import type { SharedWorkerUnsupported } from "./Evolu.js";
|
|
9
14
|
import { createRun } from "../Task.js";
|
|
10
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
createOneTabSharedWorkerSelfPolyfill,
|
|
17
|
+
createSharedWorkerSelf,
|
|
18
|
+
createWorkerDeps,
|
|
19
|
+
} from "../Worker.js";
|
|
11
20
|
|
|
12
21
|
// No disposal (`await using`) is needed — a SharedWorker lives forever.
|
|
13
22
|
const run = createRun({
|
|
14
23
|
...createWorkerDeps(),
|
|
15
24
|
createWebSocket,
|
|
25
|
+
lockManager: globalThis.navigator.locks,
|
|
16
26
|
});
|
|
17
27
|
|
|
18
|
-
run(
|
|
28
|
+
void run(async (run) => {
|
|
29
|
+
if ("onconnect" in self) {
|
|
30
|
+
void run(initSharedWorker(createSharedWorkerSelf(self)));
|
|
31
|
+
return ok();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
using workerSelf = createOneTabSharedWorkerSelfPolyfill<
|
|
35
|
+
SharedWorkerInput,
|
|
36
|
+
SharedWorkerOutput
|
|
37
|
+
>(self);
|
|
38
|
+
|
|
39
|
+
await globalThis.navigator.locks.request(
|
|
40
|
+
"evolu-one-tab-sharedworker-polyfill",
|
|
41
|
+
{ ifAvailable: true, mode: "exclusive" },
|
|
42
|
+
async (lock) => {
|
|
43
|
+
if (!lock) {
|
|
44
|
+
const message: SharedWorkerUnsupported = {
|
|
45
|
+
type: "SharedWorkerUnsupported",
|
|
46
|
+
};
|
|
47
|
+
self.postMessage(message);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
void run(initSharedWorker(workerSelf));
|
|
52
|
+
|
|
53
|
+
await Promise.withResolvers<never>().promise;
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
return ok();
|
|
58
|
+
});
|