@evolu/web 2.4.0 → 3.0.0-next.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/README.md +3 -1
- package/dist/src/Platform.d.ts +3 -0
- package/dist/src/Platform.d.ts.map +1 -0
- package/dist/src/{local-first/Platform.js → Platform.js} +1 -1
- package/dist/src/Sqlite.d.ts +3 -0
- package/dist/src/Sqlite.d.ts.map +1 -0
- package/dist/src/{WasmSqliteDriver.js → Sqlite.js} +35 -39
- package/dist/src/Task.d.ts +38 -0
- package/dist/src/Task.d.ts.map +1 -0
- package/dist/src/Task.js +63 -0
- package/dist/src/Worker.d.ts +38 -0
- package/dist/src/Worker.d.ts.map +1 -0
- package/dist/src/Worker.js +108 -0
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/local-first/Db.worker.js +13 -10
- package/dist/src/local-first/Evolu.d.ts +5 -0
- package/dist/src/local-first/Evolu.d.ts.map +1 -0
- package/dist/src/local-first/Evolu.js +25 -0
- package/dist/src/local-first/LocalAuth.d.ts +2 -3
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/LocalAuth.js +60 -71
- package/dist/src/local-first/Shared.worker.d.ts +2 -0
- package/dist/src/local-first/Shared.worker.d.ts.map +1 -0
- package/dist/src/local-first/Shared.worker.js +13 -0
- package/dist/src/local-first/index.d.ts +1 -3
- package/dist/src/local-first/index.d.ts.map +1 -1
- package/dist/src/local-first/index.js +1 -20
- package/package.json +17 -20
- package/src/Platform.ts +9 -0
- package/src/Sqlite.ts +109 -0
- package/src/Task.ts +94 -0
- package/src/Worker.ts +151 -0
- package/src/index.ts +3 -3
- package/src/local-first/Db.worker.ts +16 -16
- package/src/local-first/Evolu.ts +45 -0
- package/src/local-first/LocalAuth.ts +93 -105
- package/src/local-first/Shared.worker.ts +18 -0
- package/src/local-first/index.ts +1 -41
- package/LICENSE +0 -21
- package/dist/src/SharedWebWorker.d.ts +0 -30
- package/dist/src/SharedWebWorker.d.ts.map +0 -1
- package/dist/src/SharedWebWorker.js +0 -104
- package/dist/src/WasmSqliteDriver.d.ts +0 -3
- package/dist/src/WasmSqliteDriver.d.ts.map +0 -1
- package/dist/src/WebWorker.d.ts +0 -17
- package/dist/src/WebWorker.d.ts.map +0 -1
- package/dist/src/WebWorker.js +0 -42
- package/dist/src/local-first/Platform.d.ts +0 -3
- package/dist/src/local-first/Platform.d.ts.map +0 -1
- package/dist/test/SharedWebWorker.test.d.ts +0 -2
- package/dist/test/SharedWebWorker.test.d.ts.map +0 -1
- package/dist/test/SharedWebWorker.test.js +0 -248
- package/src/SharedWebWorker.ts +0 -149
- package/src/WasmSqliteDriver.ts +0 -118
- package/src/WebWorker.ts +0 -54
- package/src/local-first/Platform.ts +0 -9
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Evolu for Web
|
|
2
2
|
|
|
3
|
+
This package provides Evolu for the web platform (browsers). We use "web" rather than "browser" because "web platform" is the standard W3C terminology for browser APIs and aligns with ecosystem conventions.
|
|
4
|
+
|
|
3
5
|
## Documentation
|
|
4
6
|
|
|
5
7
|
For detailed information and usage examples, please visit [evolu.dev](https://www.evolu.dev).
|
|
@@ -10,4 +12,4 @@ The Evolu community is on [GitHub Discussions](https://github.com/evoluhq/evolu/
|
|
|
10
12
|
|
|
11
13
|
To chat with other community members, you can join the [Evolu Discord](https://discord.gg/2J8yyyyxtZ).
|
|
12
14
|
|
|
13
|
-
[](https://x.com/evoluhq)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Platform.d.ts","sourceRoot":"","sources":["../../src/Platform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,eAAO,MAAM,SAAS,EAAE,SAMvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAa,MAAM,eAAe,CAAC;AAyBnE,eAAO,MAAM,sBAAsB,EAAE,kBAmFlC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { bytesToHex, createPreparedStatementsCache, } from "@evolu/common";
|
|
2
|
-
import sqlite3InitModule from "@evolu/sqlite-wasm";
|
|
1
|
+
import { bytesToHex, createPreparedStatementsCache, ok } from "@evolu/common";
|
|
2
|
+
import sqlite3InitModule, {} from "@evolu/sqlite-wasm";
|
|
3
3
|
// @ts-expect-error Missing types.
|
|
4
4
|
globalThis.sqlite3ApiConfig = {
|
|
5
5
|
warn: (arg) => {
|
|
@@ -14,45 +14,46 @@ globalThis.sqlite3ApiConfig = {
|
|
|
14
14
|
};
|
|
15
15
|
// Init ASAP.
|
|
16
16
|
const sqlite3Promise = sqlite3InitModule();
|
|
17
|
-
export const createWasmSqliteDriver =
|
|
17
|
+
export const createWasmSqliteDriver = (name, options) => async () => {
|
|
18
18
|
const sqlite3 = await sqlite3Promise;
|
|
19
19
|
// This is used to make OPFS default vfs for multipleciphers
|
|
20
20
|
// @ts-expect-error Missing types (update @evolu/sqlite-wasm types)
|
|
21
21
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
22
22
|
sqlite3.capi.sqlite3mc_vfs_create("opfs", 1);
|
|
23
|
+
const stack = new globalThis.DisposableStack();
|
|
23
24
|
let db;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
25
|
+
switch (options?.mode) {
|
|
26
|
+
case "memory":
|
|
27
|
+
db = new sqlite3.oo1.DB(":memory:");
|
|
28
|
+
break;
|
|
29
|
+
case "encrypted": {
|
|
30
|
+
const pool = await sqlite3.installOpfsSAHPoolVfs({
|
|
31
|
+
directory: `.${name}`,
|
|
32
|
+
});
|
|
33
|
+
db = new pool.OpfsSAHPoolDb("file:evolu1.db?vfs=multipleciphers-opfs-sahpool");
|
|
34
|
+
db.exec(`
|
|
35
|
+
PRAGMA cipher = 'sqlcipher';
|
|
36
|
+
PRAGMA key = "x'${bytesToHex(options.encryptionKey)}'";
|
|
37
|
+
`);
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
default: {
|
|
41
|
+
const pool = await sqlite3.installOpfsSAHPoolVfs({ name });
|
|
42
|
+
db = new pool.OpfsSAHPoolDb("file:evolu1.db");
|
|
43
|
+
}
|
|
39
44
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
statement.finalize();
|
|
45
|
+
db = stack.adopt(db, (db) => {
|
|
46
|
+
db.close();
|
|
43
47
|
});
|
|
44
|
-
const
|
|
45
|
-
|
|
48
|
+
const cache = stack.use(createPreparedStatementsCache((sql) => db.prepare(sql), (statement) => {
|
|
49
|
+
statement.finalize();
|
|
50
|
+
}));
|
|
51
|
+
return ok({
|
|
52
|
+
exec: (query) => {
|
|
46
53
|
const prepared = cache.get(query);
|
|
47
54
|
if (prepared) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
prepared.stepReset();
|
|
51
|
-
return {
|
|
52
|
-
rows: [],
|
|
53
|
-
changes: db.changes(),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
55
|
+
if (query.parameters.length > 0)
|
|
56
|
+
prepared.bind(query.parameters);
|
|
56
57
|
const rows = [];
|
|
57
58
|
while (prepared.step()) {
|
|
58
59
|
rows.push(prepared.get({}));
|
|
@@ -60,7 +61,7 @@ export const createWasmSqliteDriver = async (name, options) => {
|
|
|
60
61
|
prepared.reset();
|
|
61
62
|
return {
|
|
62
63
|
rows: rows,
|
|
63
|
-
changes:
|
|
64
|
+
changes: db.changes(),
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
67
|
const rows = db.exec(query.sql, {
|
|
@@ -73,13 +74,8 @@ export const createWasmSqliteDriver = async (name, options) => {
|
|
|
73
74
|
},
|
|
74
75
|
export: () => sqlite3.capi.sqlite3_js_db_export(db),
|
|
75
76
|
[Symbol.dispose]: () => {
|
|
76
|
-
if (isDisposed)
|
|
77
|
-
return;
|
|
78
|
-
isDisposed = true;
|
|
79
77
|
// poolUtil.unlink?
|
|
80
|
-
|
|
81
|
-
db.close();
|
|
78
|
+
stack.dispose();
|
|
82
79
|
},
|
|
83
|
-
};
|
|
84
|
-
return driver;
|
|
80
|
+
});
|
|
85
81
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web platform-specific Task utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { type CreateRun, type LeaderLock, type RunDeps } from "@evolu/common";
|
|
7
|
+
/**
|
|
8
|
+
* Creates a {@link LeaderLock} backed by the Web Locks API.
|
|
9
|
+
*
|
|
10
|
+
* Waiting for the browser lock is intentionally unabortable. If a caller starts
|
|
11
|
+
* waiting and its {@link Run} or fiber is later aborted, the underlying Web
|
|
12
|
+
* Locks request keeps waiting until the browser grants the lock. Only the
|
|
13
|
+
* returned lease releases it.
|
|
14
|
+
*/
|
|
15
|
+
export declare const createLeaderLock: () => LeaderLock;
|
|
16
|
+
/**
|
|
17
|
+
* Creates {@link Run} for the browser with global error handling.
|
|
18
|
+
*
|
|
19
|
+
* Registers `error` and `unhandledrejection` handlers that log errors to the
|
|
20
|
+
* console. Handlers are removed when the Run is disposed.
|
|
21
|
+
*
|
|
22
|
+
* ### Example
|
|
23
|
+
*
|
|
24
|
+
* ```ts
|
|
25
|
+
* const console = createConsole({
|
|
26
|
+
* formatter: createConsoleFormatter()({
|
|
27
|
+
* timestampFormat: "relative",
|
|
28
|
+
* }),
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* await using run = createRun({ console });
|
|
32
|
+
* await using stack = new AsyncDisposableStack();
|
|
33
|
+
*
|
|
34
|
+
* stack.use(await run.orThrow(startApp()));
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const createRun: CreateRun<RunDeps>;
|
|
38
|
+
//# sourceMappingURL=Task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Task.d.ts","sourceRoot":"","sources":["../../src/Task.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,UAAU,EAEf,KAAK,OAAO,EACb,MAAM,eAAe,CAAC;AAEvB;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,QAAO,UAuBlC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS,EAAE,SAAS,CAAC,OAAO,CAuBxC,CAAC"}
|
package/dist/src/Task.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web platform-specific Task utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { createRun as createCommonRun, createUnknownError, ok, } from "@evolu/common";
|
|
7
|
+
/**
|
|
8
|
+
* Creates a {@link LeaderLock} backed by the Web Locks API.
|
|
9
|
+
*
|
|
10
|
+
* Waiting for the browser lock is intentionally unabortable. If a caller starts
|
|
11
|
+
* waiting and its {@link Run} or fiber is later aborted, the underlying Web
|
|
12
|
+
* Locks request keeps waiting until the browser grants the lock. Only the
|
|
13
|
+
* returned lease releases it.
|
|
14
|
+
*/
|
|
15
|
+
export const createLeaderLock = () => ({
|
|
16
|
+
lock: (name) => async () => {
|
|
17
|
+
const acquired = Promise.withResolvers();
|
|
18
|
+
const release = Promise.withResolvers();
|
|
19
|
+
void globalThis.navigator.locks.request(`evolu-leaderlock-${name}`, { mode: "exclusive" }, async () => {
|
|
20
|
+
acquired.resolve();
|
|
21
|
+
await release.promise;
|
|
22
|
+
});
|
|
23
|
+
await acquired.promise;
|
|
24
|
+
return ok({
|
|
25
|
+
[Symbol.asyncDispose]: async () => {
|
|
26
|
+
release.resolve();
|
|
27
|
+
return Promise.resolve();
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Creates {@link Run} for the browser with global error handling.
|
|
34
|
+
*
|
|
35
|
+
* Registers `error` and `unhandledrejection` handlers that log errors to the
|
|
36
|
+
* console. Handlers are removed when the Run is disposed.
|
|
37
|
+
*
|
|
38
|
+
* ### Example
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* const console = createConsole({
|
|
42
|
+
* formatter: createConsoleFormatter()({
|
|
43
|
+
* timestampFormat: "relative",
|
|
44
|
+
* }),
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* await using run = createRun({ console });
|
|
48
|
+
* await using stack = new AsyncDisposableStack();
|
|
49
|
+
*
|
|
50
|
+
* stack.use(await run.orThrow(startApp()));
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const createRun = (deps) => {
|
|
54
|
+
const run = createCommonRun(deps);
|
|
55
|
+
const console = run.deps.console.child("global");
|
|
56
|
+
globalThis.addEventListener("error", (event) => {
|
|
57
|
+
console.error("error", createUnknownError(event.error));
|
|
58
|
+
}, { signal: run.signal });
|
|
59
|
+
globalThis.addEventListener("unhandledrejection", (event) => {
|
|
60
|
+
console.error("unhandledrejection", createUnknownError(event.reason));
|
|
61
|
+
}, { signal: run.signal });
|
|
62
|
+
return run;
|
|
63
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { CreateMessagePort, MessageChannel, SharedWorker, SharedWorkerSelf, Worker, WorkerDeps, WorkerSelf } from "@evolu/common";
|
|
2
|
+
/** Creates a {@link Worker} from a Web Worker. */
|
|
3
|
+
export declare const createWorker: <Input, Output>(nativeWorker: globalThis.Worker) => Worker<Input, Output>;
|
|
4
|
+
/** Creates an Evolu {@link SharedWorker} from a Web SharedWorker. */
|
|
5
|
+
export declare const createSharedWorker: <Input, Output = never>(nativeSharedWorker: globalThis.SharedWorker) => SharedWorker<Input, Output>;
|
|
6
|
+
/**
|
|
7
|
+
* Creates a {@link MessageChannel} from a Web MessageChannel.
|
|
8
|
+
*
|
|
9
|
+
* ### Example
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* const channel = createMessageChannel<Request, Response>();
|
|
13
|
+
* channel.port1.onMessage = (response) => console.log(response);
|
|
14
|
+
* channel.port1.postMessage({ type: "ping" });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare const createMessageChannel: <Input, Output = never>() => MessageChannel<Input, Output>;
|
|
18
|
+
/**
|
|
19
|
+
* Creates an Evolu {@link MessagePort} from a Web MessagePort.
|
|
20
|
+
*
|
|
21
|
+
* Use this for ports received via postMessage transfer.
|
|
22
|
+
*/
|
|
23
|
+
export declare const createMessagePort: CreateMessagePort;
|
|
24
|
+
/**
|
|
25
|
+
* Creates an Evolu {@link WorkerSelf} from a Web `DedicatedWorkerGlobalScope`
|
|
26
|
+
* (`self` inside a dedicated worker).
|
|
27
|
+
*/
|
|
28
|
+
export declare const createWorkerSelf: <Input, Output = never>(nativeSelf: globalThis.DedicatedWorkerGlobalScope) => WorkerSelf<Input, Output>;
|
|
29
|
+
/**
|
|
30
|
+
* Creates an Evolu {@link SharedWorkerSelf} from a Web `SharedWorkerGlobalScope`
|
|
31
|
+
* (`self` inside a shared worker).
|
|
32
|
+
*
|
|
33
|
+
* Disposing closes the shared worker scope for all connected clients.
|
|
34
|
+
*/
|
|
35
|
+
export declare const createSharedWorkerSelf: <Input, Output = never>(nativeSelf: globalThis.SharedWorkerGlobalScope) => SharedWorkerSelf<Input, Output>;
|
|
36
|
+
/** Creates deps shared by web worker entry points. */
|
|
37
|
+
export declare const createWorkerDeps: () => WorkerDeps;
|
|
38
|
+
//# sourceMappingURL=Worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EAGd,YAAY,EACZ,gBAAgB,EAEhB,MAAM,EACN,UAAU,EACV,UAAU,EACX,MAAM,eAAe,CAAC;AAGvB,kDAAkD;AAClD,eAAO,MAAM,YAAY,GAAI,KAAK,EAAE,MAAM,EACxC,cAAc,UAAU,CAAC,MAAM,KAC9B,MAAM,CAAC,KAAK,EAAE,MAAM,CAAuB,CAAC;AAE/C,qEAAqE;AACrE,eAAO,MAAM,kBAAkB,GAAI,KAAK,EAAE,MAAM,GAAG,KAAK,EACtD,oBAAoB,UAAU,CAAC,YAAY,KAC1C,YAAY,CAAC,KAAK,EAAE,MAAM,CAM5B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAAI,KAAK,EAAE,MAAM,GAAG,KAAK,OAAK,cAAc,CAC3E,KAAK,EACL,MAAM,CAYP,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBACuB,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,EAAE,MAAM,GAAG,KAAK,EACpD,YAAY,UAAU,CAAC,0BAA0B,KAChD,UAAU,CAAC,KAAK,EAAE,MAAM,CAAoC,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,KAAK,EAAE,MAAM,GAAG,KAAK,EAC1D,YAAY,UAAU,CAAC,uBAAuB,KAC7C,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAkBhC,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,QAAO,UASnC,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { assert, createConsole, createConsoleStoreOutput } from "@evolu/common";
|
|
2
|
+
/** Creates a {@link Worker} from a Web Worker. */
|
|
3
|
+
export const createWorker = (nativeWorker) => wrap(nativeWorker);
|
|
4
|
+
/** Creates an Evolu {@link SharedWorker} from a Web SharedWorker. */
|
|
5
|
+
export const createSharedWorker = (nativeSharedWorker) => {
|
|
6
|
+
const port = wrap(nativeSharedWorker.port);
|
|
7
|
+
return {
|
|
8
|
+
port,
|
|
9
|
+
[Symbol.dispose]: port[Symbol.dispose],
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Creates a {@link MessageChannel} from a Web MessageChannel.
|
|
14
|
+
*
|
|
15
|
+
* ### Example
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* const channel = createMessageChannel<Request, Response>();
|
|
19
|
+
* channel.port1.onMessage = (response) => console.log(response);
|
|
20
|
+
* channel.port1.postMessage({ type: "ping" });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export const createMessageChannel = () => {
|
|
24
|
+
const channel = new globalThis.MessageChannel();
|
|
25
|
+
const stack = new DisposableStack();
|
|
26
|
+
return {
|
|
27
|
+
port1: stack.use(wrap(channel.port1)),
|
|
28
|
+
port2: stack.use(wrap(channel.port2)),
|
|
29
|
+
[Symbol.dispose]: () => {
|
|
30
|
+
stack.dispose();
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Creates an Evolu {@link MessagePort} from a Web MessagePort.
|
|
36
|
+
*
|
|
37
|
+
* Use this for ports received via postMessage transfer.
|
|
38
|
+
*/
|
|
39
|
+
export const createMessagePort = (nativePort) => wrap(nativePort);
|
|
40
|
+
/**
|
|
41
|
+
* Creates an Evolu {@link WorkerSelf} from a Web `DedicatedWorkerGlobalScope`
|
|
42
|
+
* (`self` inside a dedicated worker).
|
|
43
|
+
*/
|
|
44
|
+
export const createWorkerSelf = (nativeSelf) => wrap(nativeSelf);
|
|
45
|
+
/**
|
|
46
|
+
* Creates an Evolu {@link SharedWorkerSelf} from a Web `SharedWorkerGlobalScope`
|
|
47
|
+
* (`self` inside a shared worker).
|
|
48
|
+
*
|
|
49
|
+
* Disposing closes the shared worker scope for all connected clients.
|
|
50
|
+
*/
|
|
51
|
+
export const createSharedWorkerSelf = (nativeSelf) => {
|
|
52
|
+
const self = {
|
|
53
|
+
onConnect: null,
|
|
54
|
+
[Symbol.dispose]: () => {
|
|
55
|
+
nativeSelf.onconnect = null;
|
|
56
|
+
nativeSelf.close();
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
nativeSelf.onconnect = (e) => {
|
|
60
|
+
assert(self.onConnect != null, "onConnect must be set before receiving connections");
|
|
61
|
+
self.onConnect(wrap(e.ports[0]));
|
|
62
|
+
};
|
|
63
|
+
return self;
|
|
64
|
+
};
|
|
65
|
+
/** Creates deps shared by web worker entry points. */
|
|
66
|
+
export const createWorkerDeps = () => {
|
|
67
|
+
const consoleStoreOutput = createConsoleStoreOutput();
|
|
68
|
+
const console = createConsole({ output: consoleStoreOutput });
|
|
69
|
+
return {
|
|
70
|
+
console,
|
|
71
|
+
consoleStoreOutputEntry: consoleStoreOutput.entry,
|
|
72
|
+
createMessagePort,
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
const wrap = (native) => {
|
|
76
|
+
let onMessageHandler = null;
|
|
77
|
+
return {
|
|
78
|
+
postMessage: (message, transfer) => {
|
|
79
|
+
if (transfer == null)
|
|
80
|
+
native.postMessage(message);
|
|
81
|
+
else
|
|
82
|
+
native.postMessage(message, [...transfer]);
|
|
83
|
+
},
|
|
84
|
+
get onMessage() {
|
|
85
|
+
return onMessageHandler;
|
|
86
|
+
},
|
|
87
|
+
set onMessage(fn) {
|
|
88
|
+
onMessageHandler = fn;
|
|
89
|
+
if (fn) {
|
|
90
|
+
// Messages are queued until onMessage is assigned.
|
|
91
|
+
native.onmessage = (event) => {
|
|
92
|
+
fn(event.data);
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
native.onmessage = null;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
native: native,
|
|
100
|
+
[Symbol.dispose]: () => {
|
|
101
|
+
native.onmessage = null;
|
|
102
|
+
if (native instanceof globalThis.Worker)
|
|
103
|
+
native.terminate();
|
|
104
|
+
else
|
|
105
|
+
native.close();
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./local-first/index.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
2
|
+
export * from "./Sqlite.js";
|
|
3
|
+
export * from "./Task.js";
|
|
4
|
+
export * from "./Worker.js";
|
|
5
5
|
//# 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,
|
|
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"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from "./local-first/index.js";
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./
|
|
2
|
+
export * from "./Sqlite.js";
|
|
3
|
+
export * from "./Task.js";
|
|
4
|
+
export * from "./Worker.js";
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
/// <reference lib="webworker" />
|
|
2
|
+
import { installPolyfills } from "@evolu/common/polyfills";
|
|
3
|
+
installPolyfills();
|
|
4
|
+
import { createRandomBytes } from "@evolu/common";
|
|
5
|
+
import { startDbWorker } from "@evolu/common/local-first";
|
|
6
|
+
import { createWasmSqliteDriver } from "../Sqlite.js";
|
|
7
|
+
import { createLeaderLock, createRun } from "../Task.js";
|
|
8
|
+
import { createWorkerDeps, createWorkerSelf } from "../Worker.js";
|
|
9
|
+
// TODO: Disposal.
|
|
10
|
+
const run = createRun({
|
|
11
|
+
...createWorkerDeps(),
|
|
7
12
|
createSqliteDriver: createWasmSqliteDriver,
|
|
8
|
-
|
|
9
|
-
random: createRandom(),
|
|
13
|
+
leaderLock: createLeaderLock(),
|
|
10
14
|
randomBytes: createRandomBytes(),
|
|
11
|
-
time: createTime(),
|
|
12
15
|
});
|
|
13
|
-
|
|
16
|
+
run(startDbWorker(createWorkerSelf(self)));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ConsoleDep } from "@evolu/common";
|
|
2
|
+
import type { EvoluDeps } from "@evolu/common/local-first";
|
|
3
|
+
/** Creates Evolu dependencies for the web platform. */
|
|
4
|
+
export declare const createEvoluDeps: (deps?: Partial<ConsoleDep>) => EvoluDeps;
|
|
5
|
+
//# sourceMappingURL=Evolu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/local-first/Evolu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAGV,SAAS,EAEV,MAAM,2BAA2B,CAAC;AAgBnC,uDAAuD;AACvD,eAAO,MAAM,eAAe,GAAI,OAAM,OAAO,CAAC,UAAU,CAAM,KAAG,SAqBhE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createEvoluDeps as createCommonEvoluDeps } from "@evolu/common/local-first";
|
|
2
|
+
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
|
+
// });
|
|
10
|
+
/** Creates Evolu dependencies for the web platform. */
|
|
11
|
+
export const createEvoluDeps = (deps = {}) => {
|
|
12
|
+
const createDbWorker = () => createWorker(new Worker(new URL("Db.worker.js", import.meta.url), {
|
|
13
|
+
type: "module",
|
|
14
|
+
}));
|
|
15
|
+
const sharedWorker = createSharedWorker(new SharedWorker(new URL("Shared.worker.js", import.meta.url), {
|
|
16
|
+
type: "module",
|
|
17
|
+
}));
|
|
18
|
+
return createCommonEvoluDeps({
|
|
19
|
+
...deps,
|
|
20
|
+
createDbWorker,
|
|
21
|
+
createMessageChannel,
|
|
22
|
+
reloadApp,
|
|
23
|
+
sharedWorker,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export declare const createWebAuthnStore: (deps: RandomBytesDep & SymmetricCryptoDep) => SecureStorage;
|
|
1
|
+
import type { RandomBytesDep, SecureStorage } from "@evolu/common";
|
|
2
|
+
export declare const createWebAuthnStore: (deps: RandomBytesDep) => SecureStorage;
|
|
4
3
|
//# sourceMappingURL=LocalAuth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalAuth.d.ts","sourceRoot":"","sources":["../../../src/local-first/LocalAuth.ts"],"names":[],"mappings":"
|
|
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,GAAI,MAAM,cAAc,KAAG,aA4GzD,CAAC"}
|