@evolu/common 6.0.1-preview.19 → 6.0.1-preview.20
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.map +1 -1
- package/dist/src/Assert.js +1 -1
- package/dist/src/Buffer.d.ts +1 -1
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Buffer.js +1 -1
- package/dist/src/CallbackRegistry.d.ts +53 -0
- package/dist/src/CallbackRegistry.d.ts.map +1 -0
- package/dist/src/CallbackRegistry.js +25 -0
- package/dist/src/Console.d.ts +31 -6
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +72 -9
- package/dist/src/Crypto.d.ts +48 -37
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +27 -50
- package/dist/src/Evolu/Db.d.ts +138 -66
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +248 -645
- package/dist/src/Evolu/Diff.d.ts +3 -3
- package/dist/src/Evolu/Diff.d.ts.map +1 -1
- package/dist/src/Evolu/Diff.js +7 -5
- package/dist/src/Evolu/Evolu.d.ts +79 -116
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +275 -132
- package/dist/src/Evolu/Internal.d.ts +0 -2
- package/dist/src/Evolu/Internal.d.ts.map +1 -1
- package/dist/src/Evolu/Internal.js +0 -2
- package/dist/src/Evolu/LocalAuth.d.ts +144 -0
- package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
- package/dist/src/Evolu/LocalAuth.js +171 -0
- package/dist/src/Evolu/Owner.d.ts +129 -83
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Owner.js +80 -89
- package/dist/src/Evolu/Platform.d.ts +9 -7
- package/dist/src/Evolu/Platform.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.d.ts +114 -191
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +409 -416
- package/dist/src/Evolu/Public.d.ts +6 -8
- package/dist/src/Evolu/Public.d.ts.map +1 -1
- package/dist/src/Evolu/Public.js +2 -3
- package/dist/src/Evolu/PublicKysely.js +3 -3
- package/dist/src/Evolu/Relay.d.ts +1 -2
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +11 -9
- package/dist/src/Evolu/Schema.d.ts +88 -27
- package/dist/src/Evolu/Schema.d.ts.map +1 -1
- package/dist/src/Evolu/Schema.js +141 -24
- package/dist/src/Evolu/Storage.d.ts +158 -14
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +32 -32
- package/dist/src/Evolu/Sync.d.ts +77 -13
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +453 -20
- package/dist/src/Evolu/Timestamp.d.ts +29 -27
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +20 -18
- package/dist/src/ManyToManyMap.d.ts +74 -10
- package/dist/src/ManyToManyMap.d.ts.map +1 -1
- package/dist/src/ManyToManyMap.js +41 -6
- package/dist/src/Random.d.ts +3 -2
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/RefCountedResourceManager.d.ts +119 -0
- package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
- package/dist/src/RefCountedResourceManager.js +197 -0
- package/dist/src/Result.d.ts +144 -22
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +5 -2
- package/dist/src/Sqlite.d.ts +20 -4
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +50 -8
- package/dist/src/Task.d.ts +511 -0
- package/dist/src/Task.d.ts.map +1 -0
- package/dist/src/Task.js +410 -0
- package/dist/src/Time.d.ts +59 -0
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +87 -4
- package/dist/src/Type.d.ts +431 -341
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +458 -466
- package/dist/src/WebSocket.d.ts +5 -2
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +12 -13
- package/dist/src/Worker.d.ts +39 -11
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +22 -4
- package/dist/src/index.d.ts +2 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -3
- package/package.json +7 -7
- package/src/Assert.ts +2 -4
- package/src/Buffer.ts +1 -1
- package/src/CallbackRegistry.ts +84 -0
- package/src/Console.ts +91 -11
- package/src/Crypto.ts +78 -91
- package/src/Evolu/Db.ts +455 -947
- package/src/Evolu/Diff.ts +7 -5
- package/src/Evolu/Evolu.ts +545 -307
- package/src/Evolu/Internal.ts +0 -2
- package/src/Evolu/LocalAuth.ts +422 -0
- package/src/Evolu/Owner.ts +191 -131
- package/src/Evolu/Platform.ts +9 -9
- package/src/Evolu/Protocol.ts +536 -653
- package/src/Evolu/Public.ts +7 -9
- package/src/Evolu/PublicKysely.ts +3 -3
- package/src/Evolu/Relay.ts +17 -12
- package/src/Evolu/Schema.ts +271 -66
- package/src/Evolu/Storage.ts +263 -55
- package/src/Evolu/Sync.ts +758 -37
- package/src/Evolu/Timestamp.ts +30 -35
- package/src/ManyToManyMap.ts +127 -24
- package/src/Random.ts +3 -2
- package/src/RefCountedResourceManager.ts +368 -0
- package/src/Result.ts +149 -23
- package/src/Sqlite.ts +59 -24
- package/src/Task.ts +779 -0
- package/src/Time.ts +168 -4
- package/src/Type.ts +657 -695
- package/src/WebSocket.ts +23 -17
- package/src/Worker.ts +72 -23
- package/src/index.ts +2 -3
- package/dist/src/Callbacks.d.ts +0 -20
- package/dist/src/Callbacks.d.ts.map +0 -1
- package/dist/src/Callbacks.js +0 -18
- package/dist/src/Evolu/Config.d.ts +0 -82
- package/dist/src/Evolu/Config.d.ts.map +0 -1
- package/dist/src/Evolu/Config.js +0 -9
- package/dist/src/Evolu/Kysely.d.ts +0 -6
- package/dist/src/Evolu/Kysely.d.ts.map +0 -1
- package/dist/src/Evolu/Kysely.js +0 -21
- package/dist/src/NanoId.d.ts +0 -27
- package/dist/src/NanoId.d.ts.map +0 -1
- package/dist/src/NanoId.js +0 -6
- package/dist/src/Promise.d.ts +0 -180
- package/dist/src/Promise.d.ts.map +0 -1
- package/dist/src/Promise.js +0 -176
- package/src/Callbacks.ts +0 -43
- package/src/Evolu/Config.ts +0 -97
- package/src/Evolu/Kysely.ts +0 -38
- package/src/NanoId.ts +0 -39
- package/src/Promise.ts +0 -295
package/dist/src/WebSocket.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { RetryError, RetryOptions } from "./Promise.js";
|
|
7
6
|
import { Result } from "./Result.js";
|
|
7
|
+
import { RetryError, RetryOptions } from "./Task.js";
|
|
8
8
|
/** WebSocket with auto-reconnect and offline support. */
|
|
9
9
|
export interface WebSocket extends Disposable {
|
|
10
10
|
/**
|
|
@@ -13,9 +13,12 @@ export interface WebSocket extends Disposable {
|
|
|
13
13
|
*/
|
|
14
14
|
send: (data: string | ArrayBufferLike | Blob | ArrayBufferView) => Result<void, WebSocketSendError>;
|
|
15
15
|
readonly getReadyState: () => WebSocketReadyState;
|
|
16
|
+
/** Returns true if the WebSocket is open and ready to send data. */
|
|
17
|
+
readonly isOpen: () => boolean;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
|
-
* An error that occurs when trying to send data but WebSocket is
|
|
20
|
+
* An error that occurs when trying to send data but WebSocket is not available
|
|
21
|
+
* or is in the CONNECTING state.
|
|
19
22
|
*
|
|
20
23
|
* https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
|
21
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebSocket.d.ts","sourceRoot":"","sources":["../../src/WebSocket.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,
|
|
1
|
+
{"version":3,"file":"WebSocket.d.ts","sourceRoot":"","sources":["../../src/WebSocket.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAW,MAAM,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAS,UAAU,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAG5D,yDAAyD;AACzD,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C;;;OAGG;IACH,IAAI,EAAE,CACJ,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,GAAG,eAAe,KACpD,MAAM,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;IAEtC,QAAQ,CAAC,aAAa,EAAE,MAAM,mBAAmB,CAAC;IAElD,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;CACrC;AAED,mCAAmC;AACnC,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/E,MAAM,MAAM,eAAe,GAAG,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,KACvB,SAAS,CAAC;AAEf,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAEnC,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC;IAEpC,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAEpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAE1C,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAEtC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAExD,kCAAkC;IAClC,YAAY,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEjE;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,UAAU,CAAC,SAAS,CAAC;CACpD;AAED,MAAM,MAAM,cAAc,GACtB,qBAAqB,GACrB,wBAAwB,GACxB,UAAU,CAAC,mBAAmB,CAAC,CAAC;AAEpC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED,MAAM,MAAM,mBAAmB,GAC3B,qBAAqB,GACrB,6BAA6B,CAAC;AAElC,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,IAAI,EAAE,+BAA+B,CAAC;IAC/C,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,eAAe,EAAE,eA2H7B,CAAC"}
|
package/dist/src/WebSocket.js
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
import { assertNoErrorInCatch } from "./Assert.js";
|
|
7
|
-
import { retry } from "./Promise.js";
|
|
8
7
|
import { err, ok } from "./Result.js";
|
|
8
|
+
import { retry } from "./Task.js";
|
|
9
|
+
import { maxPositiveInt } from "./Type.js";
|
|
9
10
|
/**
|
|
10
11
|
* Create a new {@link WebSocket}.
|
|
11
12
|
*
|
|
@@ -37,13 +38,11 @@ import { err, ok } from "./Result.js";
|
|
|
37
38
|
*
|
|
38
39
|
* TODO:
|
|
39
40
|
*/
|
|
40
|
-
export const createWebSocket = (url,
|
|
41
|
-
const { protocols, binaryType, onOpen, onClose, onMessage, onError, retryOptions, WebSocketConstructor = globalThis.WebSocket, } = options;
|
|
41
|
+
export const createWebSocket = (url, { protocols, binaryType, onOpen, onClose, onMessage, onError, retryOptions, WebSocketConstructor = globalThis.WebSocket, } = {}) => {
|
|
42
42
|
let isDisposed = false;
|
|
43
43
|
const reconnectController = new AbortController();
|
|
44
44
|
const defaultRetryOptions = {
|
|
45
|
-
|
|
46
|
-
maxRetries: Infinity,
|
|
45
|
+
retries: maxPositiveInt, // Practically infinite retries
|
|
47
46
|
};
|
|
48
47
|
let socket = null;
|
|
49
48
|
const disposeSocket = () => {
|
|
@@ -66,7 +65,10 @@ export const createWebSocket = (url, options = {}) => {
|
|
|
66
65
|
* - Is rejected when a connection is closed.
|
|
67
66
|
* - Is resolved when WebSocket is disposed().
|
|
68
67
|
*/
|
|
69
|
-
retry(
|
|
68
|
+
retry({
|
|
69
|
+
...defaultRetryOptions,
|
|
70
|
+
...retryOptions,
|
|
71
|
+
}, () => new Promise((resolve) => {
|
|
70
72
|
disposePromise = () => {
|
|
71
73
|
resolve(ok());
|
|
72
74
|
};
|
|
@@ -98,19 +100,16 @@ export const createWebSocket = (url, options = {}) => {
|
|
|
98
100
|
socket.onmessage = (event) => {
|
|
99
101
|
onMessage?.(event.data);
|
|
100
102
|
};
|
|
101
|
-
})
|
|
102
|
-
...defaultRetryOptions,
|
|
103
|
-
...retryOptions,
|
|
104
|
-
})
|
|
103
|
+
}))(reconnectController)
|
|
105
104
|
.then((result) => {
|
|
106
|
-
if (result.ok || result.error.type === "
|
|
105
|
+
if (result.ok || result.error.type === "AbortError")
|
|
107
106
|
return;
|
|
108
107
|
onError?.(result.error);
|
|
109
108
|
})
|
|
110
109
|
.catch((error) => {
|
|
111
110
|
assertNoErrorInCatch("WebSocket retry", error);
|
|
112
111
|
});
|
|
113
|
-
|
|
112
|
+
return {
|
|
114
113
|
send: (data) => {
|
|
115
114
|
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send
|
|
116
115
|
if (!socket || socket.readyState === socket.CONNECTING) {
|
|
@@ -120,6 +119,7 @@ export const createWebSocket = (url, options = {}) => {
|
|
|
120
119
|
return ok();
|
|
121
120
|
},
|
|
122
121
|
getReadyState: () => socket ? nativeToStringState[socket.readyState] : "connecting",
|
|
122
|
+
isOpen: () => (socket ? socket.readyState === socket.OPEN : false),
|
|
123
123
|
[Symbol.dispose]() {
|
|
124
124
|
if (isDisposed)
|
|
125
125
|
return;
|
|
@@ -129,7 +129,6 @@ export const createWebSocket = (url, options = {}) => {
|
|
|
129
129
|
disposePromise?.();
|
|
130
130
|
},
|
|
131
131
|
};
|
|
132
|
-
return webSocket;
|
|
133
132
|
};
|
|
134
133
|
const nativeToStringState = {
|
|
135
134
|
[WebSocket.CONNECTING]: "connecting",
|
package/dist/src/Worker.d.ts
CHANGED
|
@@ -14,6 +14,21 @@ export interface Worker<Input, Output> {
|
|
|
14
14
|
export interface WorkerPostMessageDep<Output> {
|
|
15
15
|
readonly postMessage: (message: Output) => void;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Error reporting wrapper that catches synchronous errors in handlers and
|
|
19
|
+
* converts them to transferable error messages sent to the main thread.
|
|
20
|
+
*/
|
|
21
|
+
export type WithErrorReporting = <A extends Array<any>>(handler: (...args: A) => void) => (...args: A) => void;
|
|
22
|
+
type HasInit<Input> = Extract<Input, {
|
|
23
|
+
type: "init";
|
|
24
|
+
}> extends never ? ["Input must contain a variant with { type: 'init' }"] : unknown;
|
|
25
|
+
type HasWorkerErrorOutput<T> = Extract<T, {
|
|
26
|
+
type: "onError";
|
|
27
|
+
}> extends infer E ? [E] extends [never] ? [
|
|
28
|
+
"Output must contain { type: 'onError'; error: TransferableError | ... }"
|
|
29
|
+
] : E extends {
|
|
30
|
+
error: infer Err;
|
|
31
|
+
} ? TransferableError extends Err ? unknown : ["Output.onError.error must include TransferableError"] : ["Output.onError must have an error property"] : never;
|
|
17
32
|
/**
|
|
18
33
|
* Creates a {@link Worker} that supports initialization with dependencies and
|
|
19
34
|
* safe error handling.
|
|
@@ -25,20 +40,33 @@ export declare const createInitializedWorker: <Input extends {
|
|
|
25
40
|
} & HasWorkerErrorOutput<Output>, Deps>({ init, onMessage, }: {
|
|
26
41
|
readonly init: (initMessage: Extract<Input, {
|
|
27
42
|
type: "init";
|
|
28
|
-
}>, postMessage: (msg: Output) => void,
|
|
43
|
+
}>, postMessage: (msg: Output) => void, withErrorReporting: WithErrorReporting) => Promise<Deps | null>;
|
|
29
44
|
readonly onMessage: (deps: Deps) => (message: Exclude<Input, {
|
|
30
45
|
type: "init";
|
|
31
46
|
}>) => void;
|
|
32
47
|
}) => Worker<Input, Output>;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
type:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
48
|
+
/** Type helper to extract message types from a union type */
|
|
49
|
+
export type MessageHandlers<Input extends {
|
|
50
|
+
readonly type: string;
|
|
51
|
+
}, Deps> = {
|
|
52
|
+
readonly [K in Input["type"]]: (deps: Deps) => (message: Extract<Input, {
|
|
53
|
+
type: K;
|
|
54
|
+
}>) => void;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Creates a {@link Worker} with type-safe message handlers for each message
|
|
58
|
+
* type. This provides better type safety and organization compared to a single
|
|
59
|
+
* onMessage handler.
|
|
60
|
+
*/
|
|
61
|
+
export declare const createInitializedWorkerWithHandlers: <Input extends {
|
|
62
|
+
readonly type: string;
|
|
63
|
+
} & HasInit<Input>, Output extends {
|
|
64
|
+
readonly type: string;
|
|
65
|
+
} & HasWorkerErrorOutput<Output>, Deps>({ init, handlers, }: {
|
|
66
|
+
readonly init: (initMessage: Extract<Input, {
|
|
67
|
+
type: "init";
|
|
68
|
+
}>, postMessage: (msg: Output) => void, withErrorReporting: WithErrorReporting) => Promise<Deps | null>;
|
|
69
|
+
readonly handlers: Omit<MessageHandlers<Input, Deps>, "init">;
|
|
70
|
+
}) => Worker<Input, Output>;
|
|
43
71
|
export {};
|
|
44
72
|
//# sourceMappingURL=Worker.d.ts.map
|
package/dist/src/Worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAA2B,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAExE,yCAAyC;AACzC,MAAM,WAAW,MAAM,CAAC,KAAK,EAAE,MAAM;IACnC,qCAAqC;IACrC,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,KAAK,IAAI,CAAC;IAE/C,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC;CACnE;AAED,MAAM,WAAW,oBAAoB,CAAC,MAAM;IAC1C,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,KAAK,CAAC,EACxD,MAAM,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,oBAAoB,CAAC,MAAM,CAAC,EACvE,IAAI,EACJ,sBAGC;IACD,QAAQ,CAAC,IAAI,EAAE,CACb,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7C,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,EAClC,
|
|
1
|
+
{"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../src/Worker.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Worker.js
CHANGED
|
@@ -24,7 +24,11 @@ export const createInitializedWorker = ({ init, onMessage, }) => {
|
|
|
24
24
|
error: createTransferableError(error),
|
|
25
25
|
});
|
|
26
26
|
};
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Wraps function to catch errors and send them to the main thread instead of
|
|
29
|
+
* crashing the worker.
|
|
30
|
+
*/
|
|
31
|
+
const withErrorReporting = (handler) => (...args) => {
|
|
28
32
|
try {
|
|
29
33
|
handler(...args);
|
|
30
34
|
}
|
|
@@ -39,20 +43,20 @@ export const createInitializedWorker = ({ init, onMessage, }) => {
|
|
|
39
43
|
pendingMessages.push(message);
|
|
40
44
|
}
|
|
41
45
|
else {
|
|
42
|
-
|
|
46
|
+
withErrorReporting(onMessage(deps))(message);
|
|
43
47
|
}
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
46
50
|
if (initializing)
|
|
47
51
|
return;
|
|
48
52
|
initializing = true;
|
|
49
|
-
init(message, postMessage,
|
|
53
|
+
init(message, postMessage, withErrorReporting)
|
|
50
54
|
.then((_deps) => {
|
|
51
55
|
if (_deps == null)
|
|
52
56
|
return;
|
|
53
57
|
deps = _deps;
|
|
54
58
|
for (const message of pendingMessages) {
|
|
55
|
-
|
|
59
|
+
withErrorReporting(onMessage(deps))(message);
|
|
56
60
|
}
|
|
57
61
|
pendingMessages.length = 0;
|
|
58
62
|
})
|
|
@@ -64,3 +68,17 @@ export const createInitializedWorker = ({ init, onMessage, }) => {
|
|
|
64
68
|
};
|
|
65
69
|
return worker;
|
|
66
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* Creates a {@link Worker} with type-safe message handlers for each message
|
|
73
|
+
* type. This provides better type safety and organization compared to a single
|
|
74
|
+
* onMessage handler.
|
|
75
|
+
*/
|
|
76
|
+
export const createInitializedWorkerWithHandlers = ({ init, handlers, }) => createInitializedWorker({
|
|
77
|
+
init,
|
|
78
|
+
onMessage: (deps) => (message) => {
|
|
79
|
+
const messageType = message.type;
|
|
80
|
+
const handler = handlers[messageType];
|
|
81
|
+
// TypeScript knows handler exists because handlers covers all non-init message types
|
|
82
|
+
handler(deps)(message);
|
|
83
|
+
},
|
|
84
|
+
});
|
package/dist/src/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./Assert.js";
|
|
|
3
3
|
export * from "./BigInt.js";
|
|
4
4
|
export * from "./Brand.js";
|
|
5
5
|
export * from "./Buffer.js";
|
|
6
|
-
export * from "./
|
|
6
|
+
export * from "./CallbackRegistry.js";
|
|
7
7
|
export * from "./Console.js";
|
|
8
8
|
export * from "./Crypto.js";
|
|
9
9
|
export * from "./Eq.js";
|
|
@@ -11,17 +11,16 @@ export * from "./Error.js";
|
|
|
11
11
|
export * from "./Evolu/Public.js";
|
|
12
12
|
export * from "./Function.js";
|
|
13
13
|
export * from "./ManyToManyMap.js";
|
|
14
|
-
export * from "./NanoId.js";
|
|
15
14
|
export * from "./Number.js";
|
|
16
15
|
export * from "./Object.js";
|
|
17
16
|
export * from "./Order.js";
|
|
18
|
-
export * from "./Promise.js";
|
|
19
17
|
export * from "./Random.js";
|
|
20
18
|
export * from "./Ref.js";
|
|
21
19
|
export * from "./Result.js";
|
|
22
20
|
export * from "./Sqlite.js";
|
|
23
21
|
export * from "./Store.js";
|
|
24
22
|
export * from "./String.js";
|
|
23
|
+
export * from "./Task.js";
|
|
25
24
|
export * from "./Time.js";
|
|
26
25
|
export * from "./Type.js";
|
|
27
26
|
export * from "./Types.js";
|
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,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export * from "./Assert.js";
|
|
|
3
3
|
export * from "./BigInt.js";
|
|
4
4
|
export * from "./Brand.js";
|
|
5
5
|
export * from "./Buffer.js";
|
|
6
|
-
export * from "./
|
|
6
|
+
export * from "./CallbackRegistry.js";
|
|
7
7
|
export * from "./Console.js";
|
|
8
8
|
export * from "./Crypto.js";
|
|
9
9
|
export * from "./Eq.js";
|
|
@@ -11,17 +11,16 @@ export * from "./Error.js";
|
|
|
11
11
|
export * from "./Evolu/Public.js";
|
|
12
12
|
export * from "./Function.js";
|
|
13
13
|
export * from "./ManyToManyMap.js";
|
|
14
|
-
export * from "./NanoId.js";
|
|
15
14
|
export * from "./Number.js";
|
|
16
15
|
export * from "./Object.js";
|
|
17
16
|
export * from "./Order.js";
|
|
18
|
-
export * from "./Promise.js";
|
|
19
17
|
export * from "./Random.js";
|
|
20
18
|
export * from "./Ref.js";
|
|
21
19
|
export * from "./Result.js";
|
|
22
20
|
export * from "./Sqlite.js";
|
|
23
21
|
export * from "./Store.js";
|
|
24
22
|
export * from "./String.js";
|
|
23
|
+
export * from "./Task.js";
|
|
25
24
|
export * from "./Time.js";
|
|
26
25
|
export * from "./Type.js";
|
|
27
26
|
export * from "./Types.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evolu/common",
|
|
3
|
-
"version": "6.0.1-preview.
|
|
3
|
+
"version": "6.0.1-preview.20",
|
|
4
4
|
"description": "TypeScript library and local-first framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"evolu",
|
|
@@ -42,12 +42,11 @@
|
|
|
42
42
|
"README.md"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@noble/ciphers": "^
|
|
46
|
-
"@noble/hashes": "^
|
|
47
|
-
"@scure/bip39": "^
|
|
45
|
+
"@noble/ciphers": "^2.0.0",
|
|
46
|
+
"@noble/hashes": "^2.0.0",
|
|
47
|
+
"@scure/bip39": "^2.0.0",
|
|
48
48
|
"kysely": "^0.28.4",
|
|
49
49
|
"msgpackr": "^1.11.5",
|
|
50
|
-
"nanoid": "^3.3.11",
|
|
51
50
|
"random": "^5.4.1"
|
|
52
51
|
},
|
|
53
52
|
"devDependencies": {
|
|
@@ -55,9 +54,10 @@
|
|
|
55
54
|
"@types/better-sqlite3": "^7.6.13",
|
|
56
55
|
"@types/ws": "^8.18.1",
|
|
57
56
|
"better-sqlite3": "^12.1.1",
|
|
58
|
-
"
|
|
57
|
+
"fast-check": "^4.2.0",
|
|
58
|
+
"shx": "^0.4.0",
|
|
59
59
|
"typescript": "^5.9.2",
|
|
60
|
-
"vitest": "^
|
|
60
|
+
"vitest": "^4.0.4",
|
|
61
61
|
"ws": "^8.18.2",
|
|
62
62
|
"@evolu/tsconfig": "0.0.2"
|
|
63
63
|
},
|
package/src/Assert.ts
CHANGED
|
@@ -110,10 +110,8 @@ export const assertNonEmptyReadonlyArray: <T>(
|
|
|
110
110
|
* ```
|
|
111
111
|
*/
|
|
112
112
|
export function assertNoErrorInCatch(context: string, error: unknown): never {
|
|
113
|
-
throw
|
|
114
|
-
|
|
115
|
-
`Error in ${context}: an unexpected error reached a catch block and requires a fix`,
|
|
116
|
-
),
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Error in ${context}: an unexpected error reached a catch block and requires a fix`,
|
|
117
115
|
{ cause: error },
|
|
118
116
|
);
|
|
119
117
|
}
|
package/src/Buffer.ts
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Brand } from "./Brand.js";
|
|
2
|
+
import { RandomBytesDep } from "./Crypto.js";
|
|
3
|
+
import { Result } from "./Result.js";
|
|
4
|
+
import { createId, Id } from "./Type.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A registry for one-time callback functions.
|
|
8
|
+
*
|
|
9
|
+
* Stores callbacks with unique IDs and executes them once with an optional
|
|
10
|
+
* argument. Executed callbacks are automatically removed from the registry.
|
|
11
|
+
*
|
|
12
|
+
* This is useful for correlating asynchronous operations across boundaries
|
|
13
|
+
* where callback functions cannot be passed directly (e.g., web workers).
|
|
14
|
+
*
|
|
15
|
+
* The `execute` method intentionally does not use try-catch or {@link Result}
|
|
16
|
+
* because it's the callback's responsibility to handle its own errors. The
|
|
17
|
+
* registry is just a correlation mechanism and should not interfere with error
|
|
18
|
+
* handling or debugging by masking the original error location.
|
|
19
|
+
*
|
|
20
|
+
* ### Example
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* // No-argument callbacks
|
|
24
|
+
* const registry = createCallbackRegistry(deps);
|
|
25
|
+
* const id = registry.register(() => console.log("called"));
|
|
26
|
+
* registry.execute(id);
|
|
27
|
+
*
|
|
28
|
+
* // With argument callbacks
|
|
29
|
+
* const stringRegistry = createCallbackRegistry<string>(deps);
|
|
30
|
+
* const id = stringRegistry.register((value) => {
|
|
31
|
+
* console.log(value);
|
|
32
|
+
* });
|
|
33
|
+
* stringRegistry.execute(id, "hello");
|
|
34
|
+
*
|
|
35
|
+
* // Promise.withResolvers pattern
|
|
36
|
+
* const promiseRegistry = createCallbackRegistry<string>(deps);
|
|
37
|
+
* const { promise, resolve } = Promise.withResolvers<string>();
|
|
38
|
+
* const id = promiseRegistry.register(resolve);
|
|
39
|
+
* promiseRegistry.execute(id, "resolved value");
|
|
40
|
+
* await promise; // "resolved value"
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @template T - The type of argument passed to callbacks (defaults to undefined
|
|
44
|
+
* for no-argument callbacks)
|
|
45
|
+
*/
|
|
46
|
+
export interface CallbackRegistry<T = undefined> {
|
|
47
|
+
/** Registers a callback function and returns a unique ID. */
|
|
48
|
+
readonly register: (callback: (arg: T) => void) => CallbackId;
|
|
49
|
+
|
|
50
|
+
/** Executes and removes a callback associated with the given ID. */
|
|
51
|
+
readonly execute: T extends undefined
|
|
52
|
+
? (id: CallbackId) => undefined
|
|
53
|
+
: (id: CallbackId, arg: T) => undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type CallbackId = Id & Brand<"Callback">;
|
|
57
|
+
|
|
58
|
+
/** Creates a new {@link CallbackRegistry} for one-time callback functions. */
|
|
59
|
+
export const createCallbackRegistry = <T = undefined>(
|
|
60
|
+
deps: RandomBytesDep,
|
|
61
|
+
): CallbackRegistry<T> => {
|
|
62
|
+
const callbackMap = new Map<CallbackId, (arg: T) => void>();
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
register: (callback) => {
|
|
66
|
+
const id = createId<"Callback">(deps);
|
|
67
|
+
callbackMap.set(id, callback);
|
|
68
|
+
return id;
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
execute: (id: CallbackId, ...args: T extends undefined ? [] : [T]) => {
|
|
72
|
+
const callback = callbackMap.get(id);
|
|
73
|
+
if (callback) {
|
|
74
|
+
callbackMap.delete(id);
|
|
75
|
+
if (args.length === 0) {
|
|
76
|
+
// Called without argument (undefined case)
|
|
77
|
+
(callback as () => void)();
|
|
78
|
+
} else {
|
|
79
|
+
callback(args[0]);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
} as CallbackRegistry<T>;
|
|
84
|
+
};
|
package/src/Console.ts
CHANGED
|
@@ -13,14 +13,28 @@
|
|
|
13
13
|
* ### Example
|
|
14
14
|
*
|
|
15
15
|
* ```ts
|
|
16
|
-
* deps.console.log("[
|
|
16
|
+
* deps.console.log("[evolu]", "createEvoluInstance", { name });
|
|
17
17
|
* ```
|
|
18
18
|
*
|
|
19
19
|
* **Tip**: In browser dev tools, you can filter logs by tag (e.g., `[db]`) to
|
|
20
|
-
* quickly find relevant messages.
|
|
20
|
+
* quickly find relevant messages. In Node.js, use `grep` to filter output:
|
|
21
21
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* ```bash
|
|
23
|
+
* node app.js | grep "\[relay\]" # Show only relay logs
|
|
24
|
+
* node app.js | grep -E "\[db\]|\[sql\]" # Show db and sql logs
|
|
25
|
+
* node app.js | grep -v "\[debug\]" # Hide debug logs
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* Or add to package.json scripts:
|
|
29
|
+
*
|
|
30
|
+
* ```json
|
|
31
|
+
* {
|
|
32
|
+
* "scripts": {
|
|
33
|
+
* "dev:relay": "node app.js | grep \"\\[relay\\]\"",
|
|
34
|
+
* "dev:db": "node app.js | grep -E \"\\[db\\]|\\[sql\\]\""
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
24
38
|
*
|
|
25
39
|
* @module
|
|
26
40
|
*/
|
|
@@ -51,6 +65,9 @@ export interface Console {
|
|
|
51
65
|
/** Starts a timer with an optional label */
|
|
52
66
|
time: (label?: string) => void;
|
|
53
67
|
|
|
68
|
+
/** Logs the elapsed time for a timer without ending it */
|
|
69
|
+
timeLog: (label?: string, ...data: Array<any>) => void;
|
|
70
|
+
|
|
54
71
|
/** Ends a timer and logs the elapsed time */
|
|
55
72
|
timeEnd: (label?: string) => void;
|
|
56
73
|
|
|
@@ -69,9 +86,6 @@ export interface Console {
|
|
|
69
86
|
/** Writes a message if the value is falsy, otherwise does nothing */
|
|
70
87
|
assert: (value: any, message?: string, ...optionalParams: Array<any>) => void;
|
|
71
88
|
|
|
72
|
-
/** Logs the elapsed time for a timer without ending it */
|
|
73
|
-
timeLog: (label?: string, ...data: Array<any>) => void;
|
|
74
|
-
|
|
75
89
|
/** Prints a stack trace with an optional message */
|
|
76
90
|
trace: (message?: any, ...optionalParams: Array<any>) => void;
|
|
77
91
|
}
|
|
@@ -121,6 +135,10 @@ export const createConsole = (config: ConsoleConfig = {}): Console => {
|
|
|
121
135
|
// eslint-disable-next-line no-console
|
|
122
136
|
if (instance.enabled) console.time(label);
|
|
123
137
|
},
|
|
138
|
+
timeLog: (label, ...data) => {
|
|
139
|
+
// eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
|
|
140
|
+
if (instance.enabled) console.timeLog(label, ...data);
|
|
141
|
+
},
|
|
124
142
|
timeEnd: (label) => {
|
|
125
143
|
// eslint-disable-next-line no-console
|
|
126
144
|
if (instance.enabled) console.timeEnd(label);
|
|
@@ -145,10 +163,6 @@ export const createConsole = (config: ConsoleConfig = {}): Console => {
|
|
|
145
163
|
// eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
|
|
146
164
|
if (instance.enabled) console.assert(value, message, ...optionalParams);
|
|
147
165
|
},
|
|
148
|
-
timeLog: (label, ...data) => {
|
|
149
|
-
// eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
|
|
150
|
-
if (instance.enabled) console.timeLog(label, ...data);
|
|
151
|
-
},
|
|
152
166
|
trace: (message, ...optionalParams) => {
|
|
153
167
|
// eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
|
|
154
168
|
if (instance.enabled) console.trace(message, ...optionalParams);
|
|
@@ -157,3 +171,69 @@ export const createConsole = (config: ConsoleConfig = {}): Console => {
|
|
|
157
171
|
|
|
158
172
|
return instance;
|
|
159
173
|
};
|
|
174
|
+
|
|
175
|
+
export interface ConsoleWithTimeConfig extends ConsoleConfig {
|
|
176
|
+
/**
|
|
177
|
+
* Type of timestamp to prepend to log messages.
|
|
178
|
+
*
|
|
179
|
+
* - 'absolute': Shows actual time (e.g., "14:32:15.234")
|
|
180
|
+
* - 'relative': Shows time since console creation (e.g., "+1.234s")
|
|
181
|
+
*/
|
|
182
|
+
readonly timestampType: "absolute" | "relative";
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Creates a console instance with timestamp prefixes. */
|
|
186
|
+
export const createConsoleWithTime = (
|
|
187
|
+
config: ConsoleWithTimeConfig = { timestampType: "relative" },
|
|
188
|
+
): Console => {
|
|
189
|
+
const console = createConsole(config);
|
|
190
|
+
const startTime = performance.now();
|
|
191
|
+
|
|
192
|
+
const getTimestamp = (): string => {
|
|
193
|
+
if (config.timestampType === "relative") {
|
|
194
|
+
const elapsed = (performance.now() - startTime) / 1000;
|
|
195
|
+
|
|
196
|
+
// Format for better readability at different time scales
|
|
197
|
+
if (elapsed < 60) {
|
|
198
|
+
// Under 1 minute: show seconds with millisecond precision
|
|
199
|
+
return `+${elapsed.toFixed(3)}s`;
|
|
200
|
+
} else if (elapsed < 3600) {
|
|
201
|
+
// 1 minute to 1 hour: show minutes and seconds with millisecond precision
|
|
202
|
+
const minutes = Math.floor(elapsed / 60);
|
|
203
|
+
const seconds = (elapsed % 60).toFixed(3);
|
|
204
|
+
return `+${minutes}m${seconds}s`;
|
|
205
|
+
} else {
|
|
206
|
+
// Over 1 hour: show hours, minutes, and seconds with millisecond precision
|
|
207
|
+
const hours = Math.floor(elapsed / 3600);
|
|
208
|
+
const minutes = Math.floor((elapsed % 3600) / 60);
|
|
209
|
+
const seconds = ((elapsed % 3600) % 60).toFixed(3);
|
|
210
|
+
return `+${hours}h${minutes}m${seconds}s`;
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
// Absolute time - format as HH:MM:SS.mmm
|
|
214
|
+
const now = new Date();
|
|
215
|
+
const hours = now.getHours().toString().padStart(2, "0");
|
|
216
|
+
const minutes = now.getMinutes().toString().padStart(2, "0");
|
|
217
|
+
const seconds = now.getSeconds().toString().padStart(2, "0");
|
|
218
|
+
const milliseconds = now.getMilliseconds().toString().padStart(3, "0");
|
|
219
|
+
return `${hours}:${minutes}:${seconds}.${milliseconds}`;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const withTimestamp =
|
|
224
|
+
(fn: (...args: Array<any>) => void) =>
|
|
225
|
+
(...args: Array<any>) => {
|
|
226
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
227
|
+
fn(`[${getTimestamp()}]`, ...args);
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// Override methods that should have timestamps
|
|
231
|
+
console.log = withTimestamp(console.log);
|
|
232
|
+
console.info = withTimestamp(console.info);
|
|
233
|
+
console.warn = withTimestamp(console.warn);
|
|
234
|
+
console.error = withTimestamp(console.error);
|
|
235
|
+
console.debug = withTimestamp(console.debug);
|
|
236
|
+
console.trace = withTimestamp(console.trace);
|
|
237
|
+
|
|
238
|
+
return console;
|
|
239
|
+
};
|