@evolu/common 8.0.0-next.4 → 8.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/dist/src/Array.d.ts +279 -173
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +105 -101
- package/dist/src/Assert.d.ts +44 -44
- package/dist/src/Assert.d.ts.map +1 -1
- package/dist/src/Assert.js +44 -32
- package/dist/src/BigInt.d.ts +6 -3
- package/dist/src/BigInt.d.ts.map +1 -1
- package/dist/src/BigInt.js +5 -2
- package/dist/src/Brand.d.ts +27 -40
- package/dist/src/Brand.d.ts.map +1 -1
- package/dist/src/Buffer.d.ts +27 -11
- package/dist/src/Buffer.d.ts.map +1 -1
- package/dist/src/Cache.d.ts +9 -4
- package/dist/src/Cache.d.ts.map +1 -1
- package/dist/src/Cache.js +8 -3
- package/dist/src/Callbacks.d.ts +30 -19
- package/dist/src/Callbacks.d.ts.map +1 -1
- package/dist/src/Console.d.ts +145 -66
- package/dist/src/Console.d.ts.map +1 -1
- package/dist/src/Console.js +91 -43
- package/dist/src/Crypto.d.ts +85 -42
- package/dist/src/Crypto.d.ts.map +1 -1
- package/dist/src/Crypto.js +44 -20
- package/dist/src/Eq.d.ts +87 -21
- package/dist/src/Eq.d.ts.map +1 -1
- package/dist/src/Eq.js +67 -19
- package/dist/src/Error.d.ts +5 -3
- package/dist/src/Error.d.ts.map +1 -1
- package/dist/src/Error.js +16 -0
- package/dist/src/Function.d.ts +119 -58
- package/dist/src/Function.d.ts.map +1 -1
- package/dist/src/Function.js +86 -43
- package/dist/src/Http.d.ts +394 -0
- package/dist/src/Http.d.ts.map +1 -0
- package/dist/src/Http.js +102 -0
- package/dist/src/Identicon.d.ts +16 -7
- package/dist/src/Identicon.d.ts.map +1 -1
- package/dist/src/Identicon.js +14 -5
- package/dist/src/LeakDetector.d.ts +88 -0
- package/dist/src/LeakDetector.d.ts.map +1 -0
- package/dist/src/LeakDetector.js +86 -0
- package/dist/src/LockManager.d.ts +18 -9
- package/dist/src/LockManager.d.ts.map +1 -1
- package/dist/src/LockManager.js +7 -8
- package/dist/src/Lookup.d.ts +43 -13
- package/dist/src/Lookup.d.ts.map +1 -1
- package/dist/src/Lookup.js +28 -8
- package/dist/src/Microtask.d.ts +1 -1
- package/dist/src/Microtask.d.ts.map +1 -1
- package/dist/src/Microtask.js +3 -7
- package/dist/src/Number.d.ts +49 -13
- package/dist/src/Number.d.ts.map +1 -1
- package/dist/src/Number.js +34 -5
- package/dist/src/Object.d.ts +160 -40
- package/dist/src/Object.d.ts.map +1 -1
- package/dist/src/Object.js +92 -46
- package/dist/src/Option.d.ts +10 -7
- package/dist/src/Option.d.ts.map +1 -1
- package/dist/src/Option.js +9 -6
- package/dist/src/Order.d.ts +21 -21
- package/dist/src/Order.d.ts.map +1 -1
- package/dist/src/Order.js +18 -21
- package/dist/src/Platform.d.ts +31 -0
- package/dist/src/Platform.d.ts.map +1 -1
- package/dist/src/Platform.js +98 -0
- package/dist/src/Random.d.ts +32 -17
- package/dist/src/Random.d.ts.map +1 -1
- package/dist/src/Random.js +12 -8
- package/dist/src/Redacted.d.ts +43 -29
- package/dist/src/Redacted.d.ts.map +1 -1
- package/dist/src/Redacted.js +14 -3
- package/dist/src/Ref.d.ts +11 -3
- package/dist/src/Ref.d.ts.map +1 -1
- package/dist/src/Ref.js +2 -2
- package/dist/src/RefCount.d.ts +2 -6
- package/dist/src/RefCount.d.ts.map +1 -1
- package/dist/src/RefCount.js +33 -90
- package/dist/src/Relation.d.ts +70 -5
- package/dist/src/Relation.d.ts.map +1 -1
- package/dist/src/Relation.js +77 -2
- package/dist/src/Resource.d.ts +590 -155
- package/dist/src/Resource.d.ts.map +1 -1
- package/dist/src/Resource.js +592 -343
- package/dist/src/Result.d.ts +838 -191
- package/dist/src/Result.d.ts.map +1 -1
- package/dist/src/Result.js +163 -102
- package/dist/src/Schedule.d.ts +684 -231
- package/dist/src/Schedule.d.ts.map +1 -1
- package/dist/src/Schedule.js +766 -295
- package/dist/src/Set.d.ts +89 -40
- package/dist/src/Set.d.ts.map +1 -1
- package/dist/src/Set.js +50 -29
- package/dist/src/Sqlite.d.ts +29 -72
- package/dist/src/Sqlite.d.ts.map +1 -1
- package/dist/src/Sqlite.js +41 -46
- package/dist/src/StackTrace.d.ts +40 -0
- package/dist/src/StackTrace.d.ts.map +1 -0
- package/dist/src/StackTrace.js +140 -0
- package/dist/src/Store.d.ts +5 -4
- package/dist/src/Store.d.ts.map +1 -1
- package/dist/src/Store.js +5 -4
- package/dist/src/String.d.ts +7 -1
- package/dist/src/String.d.ts.map +1 -1
- package/dist/src/String.js +20 -7
- package/dist/src/Task.d.ts +3572 -1770
- package/dist/src/Task.d.ts.map +1 -1
- package/dist/src/Task.js +1879 -1274
- package/dist/src/Test.d.ts +17 -125
- package/dist/src/Test.d.ts.map +1 -1
- package/dist/src/Test.js +17 -68
- package/dist/src/Time.d.ts +108 -49
- package/dist/src/Time.d.ts.map +1 -1
- package/dist/src/Time.js +172 -73
- package/dist/src/Type.d.ts +3542 -1926
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3070 -1784
- package/dist/src/Types.d.ts +200 -108
- package/dist/src/Types.d.ts.map +1 -1
- package/dist/src/Types.js +39 -8
- package/dist/src/WebSocket.d.ts +48 -23
- package/dist/src/WebSocket.d.ts.map +1 -1
- package/dist/src/WebSocket.js +15 -6
- package/dist/src/Worker.d.ts +94 -36
- package/dist/src/Worker.d.ts.map +1 -1
- package/dist/src/Worker.js +58 -24
- package/dist/src/index.d.ts +55 -52
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/src/intl/cs.d.ts +94 -0
- package/dist/src/intl/cs.d.ts.map +1 -0
- package/dist/src/intl/cs.js +220 -0
- package/dist/src/intl/index.d.ts +7 -0
- package/dist/src/intl/index.d.ts.map +1 -0
- package/dist/src/intl/index.js +6 -0
- package/dist/src/local-first/Db.d.ts +12 -8
- package/dist/src/local-first/Db.d.ts.map +1 -1
- package/dist/src/local-first/Db.js +109 -132
- package/dist/src/local-first/Error.d.ts +4 -4
- package/dist/src/local-first/Evolu.d.ts +338 -92
- package/dist/src/local-first/Evolu.d.ts.map +1 -1
- package/dist/src/local-first/Evolu.js +47 -55
- package/dist/src/local-first/LocalAuth.d.ts +4 -4
- package/dist/src/local-first/LocalAuth.d.ts.map +1 -1
- package/dist/src/local-first/Owner.d.ts +61 -24
- package/dist/src/local-first/Owner.d.ts.map +1 -1
- package/dist/src/local-first/Owner.js +45 -8
- package/dist/src/local-first/Protocol.d.ts +44 -31
- package/dist/src/local-first/Protocol.d.ts.map +1 -1
- package/dist/src/local-first/Protocol.js +36 -13
- package/dist/src/local-first/Query.d.ts +147 -62
- package/dist/src/local-first/Query.d.ts.map +1 -1
- package/dist/src/local-first/Query.js +112 -58
- package/dist/src/local-first/Relay.d.ts +44 -14
- package/dist/src/local-first/Relay.d.ts.map +1 -1
- package/dist/src/local-first/Schema.d.ts +92 -41
- package/dist/src/local-first/Schema.d.ts.map +1 -1
- package/dist/src/local-first/Schema.js +25 -8
- package/dist/src/local-first/Shared.d.ts +23 -21
- package/dist/src/local-first/Shared.d.ts.map +1 -1
- package/dist/src/local-first/Shared.js +100 -57
- package/dist/src/local-first/Storage.d.ts +53 -32
- package/dist/src/local-first/Storage.d.ts.map +1 -1
- package/dist/src/local-first/Storage.js +194 -234
- package/dist/src/local-first/Timestamp.d.ts +21 -21
- package/dist/src/local-first/Timestamp.d.ts.map +1 -1
- package/dist/src/local-first/Timestamp.js +2 -2
- package/dist/src/local-first/index.d.ts +11 -11
- package/package.json +14 -13
- package/src/Array.ts +306 -205
- package/src/Assert.ts +54 -69
- package/src/BigInt.ts +6 -3
- package/src/Brand.ts +27 -40
- package/src/Buffer.ts +28 -12
- package/src/Cache.ts +9 -4
- package/src/Callbacks.ts +30 -19
- package/src/Console.ts +156 -84
- package/src/Crypto.ts +83 -41
- package/src/Eq.ts +95 -22
- package/src/Error.ts +8 -4
- package/src/Function.ts +167 -59
- package/src/Http.ts +549 -0
- package/src/Identicon.ts +16 -7
- package/src/LeakDetector.ts +182 -0
- package/src/LockManager.ts +43 -39
- package/src/Lookup.ts +62 -28
- package/src/Microtask.ts +19 -23
- package/src/Number.ts +64 -12
- package/src/Object.ts +173 -49
- package/src/Option.ts +10 -7
- package/src/Order.ts +23 -21
- package/src/Platform.ts +136 -0
- package/src/Polyfills.ts +6 -12
- package/src/Random.ts +32 -19
- package/src/Redacted.ts +44 -30
- package/src/Ref.ts +14 -6
- package/src/RefCount.ts +38 -80
- package/src/Relation.ts +202 -10
- package/src/Resource.ts +1199 -591
- package/src/Result.ts +930 -271
- package/src/Schedule.ts +859 -343
- package/src/Set.ts +89 -40
- package/src/Sqlite.ts +144 -138
- package/src/StackTrace.ts +230 -0
- package/src/Store.ts +8 -7
- package/src/String.ts +22 -5
- package/src/Task.ts +5101 -2832
- package/src/Test.ts +20 -168
- package/src/Time.ts +293 -90
- package/src/Type.ts +10034 -4117
- package/src/Types.ts +227 -110
- package/src/WebSocket.ts +64 -36
- package/src/Worker.ts +180 -72
- package/src/index.ts +55 -52
- package/src/intl/cs.ts +388 -0
- package/src/intl/index.ts +7 -0
- package/src/local-first/Db.ts +152 -179
- package/src/local-first/Error.ts +4 -4
- package/src/local-first/Evolu.ts +495 -250
- package/src/local-first/LocalAuth.ts +6 -12
- package/src/local-first/Owner.ts +58 -21
- package/src/local-first/Protocol.ts +49 -31
- package/src/local-first/Query.ts +146 -61
- package/src/local-first/Relay.ts +51 -21
- package/src/local-first/Schema.ts +109 -51
- package/src/local-first/Shared.ts +266 -226
- package/src/local-first/Storage.ts +266 -264
- package/src/local-first/Timestamp.ts +25 -18
- package/src/local-first/index.ts +11 -11
- package/dist/src/Skiplist.d.ts +0 -28
- package/dist/src/Skiplist.d.ts.map +0 -1
- package/dist/src/Skiplist.js +0 -64
- package/dist/src/Tracer.d.ts +0 -48
- package/dist/src/Tracer.d.ts.map +0 -1
- package/dist/src/Tracer.js +0 -6
- package/src/Skiplist.ts +0 -108
- package/src/Tracer.ts +0 -54
package/src/Console.ts
CHANGED
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { objectFrom } from "./Object.
|
|
8
|
-
import type { ReadonlyStore } from "./Store.
|
|
9
|
-
import { createStore } from "./Store.
|
|
10
|
-
import type { Task } from "./Task.
|
|
7
|
+
import { objectFrom } from "./Object.ts";
|
|
8
|
+
import type { ReadonlyStore } from "./Store.ts";
|
|
9
|
+
import { createStore } from "./Store.ts";
|
|
10
|
+
import type { Task } from "./Task.ts";
|
|
11
11
|
import {
|
|
12
12
|
createTime,
|
|
13
13
|
formatMillisAsClockTime,
|
|
14
14
|
formatMillisAsDuration,
|
|
15
15
|
type Millis,
|
|
16
16
|
type TimeDep,
|
|
17
|
-
} from "./Time.
|
|
17
|
+
} from "./Time.ts";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Platform-agnostic console with structured logging.
|
|
@@ -42,31 +42,47 @@ import {
|
|
|
42
42
|
* {@link ReadonlyStore} for subscribing
|
|
43
43
|
* - {@link createMultiOutput} — fans out to multiple outputs
|
|
44
44
|
*
|
|
45
|
+
* Wrap logged values in named objects such as `{ config }` so developer tools
|
|
46
|
+
* display useful, expandable labels.
|
|
47
|
+
*
|
|
45
48
|
* ### Example
|
|
46
49
|
*
|
|
47
50
|
* ```ts
|
|
48
|
-
*
|
|
49
|
-
*
|
|
51
|
+
* import {
|
|
52
|
+
* createConsole,
|
|
53
|
+
* createConsoleArrayOutput,
|
|
54
|
+
* type Console,
|
|
55
|
+
* type ConsoleEntry,
|
|
56
|
+
* type ConsoleLevel,
|
|
57
|
+
* } from "@evolu/common";
|
|
50
58
|
*
|
|
51
|
-
*
|
|
52
|
-
* const
|
|
53
|
-
*
|
|
54
|
-
* formatter: createConsoleFormatter()({ timestampFormat: "relative" }),
|
|
59
|
+
* const entries: Array<ConsoleEntry> = [];
|
|
60
|
+
* const root = createConsole({
|
|
61
|
+
* output: createConsoleArrayOutput(entries),
|
|
55
62
|
* });
|
|
56
|
-
*
|
|
57
|
-
* //
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
63
|
+
* const relay = root.child("relay");
|
|
64
|
+
* // Silence a noisy subsystem without affecting root logs.
|
|
65
|
+
* relay.setLevel("silent");
|
|
66
|
+
* relay.info("polling");
|
|
67
|
+
* root.info("Creating instance", { config: { port: 4000 } });
|
|
68
|
+
*
|
|
69
|
+
* expect(root.getLevel()).toBe("log");
|
|
70
|
+
* expect(relay.getLevel()).toBe("silent");
|
|
71
|
+
* expect(entries[0]?.args).toEqual([
|
|
72
|
+
* "Creating instance",
|
|
73
|
+
* { config: { port: 4000 } },
|
|
74
|
+
* ]);
|
|
75
|
+
*
|
|
76
|
+
* const setLevelRecursive = (
|
|
77
|
+
* console: Console,
|
|
78
|
+
* level: ConsoleLevel,
|
|
79
|
+
* ): void => {
|
|
80
|
+
* console.setLevel(level);
|
|
81
|
+
* for (const child of console.children) setLevelRecursive(child, level);
|
|
69
82
|
* };
|
|
83
|
+
* setLevelRecursive(root, "warn");
|
|
84
|
+
* expect(root.getLevel()).toBe("warn");
|
|
85
|
+
* expect(relay.getLevel()).toBe("warn");
|
|
70
86
|
* ```
|
|
71
87
|
*
|
|
72
88
|
* Console intentionally does not use {@link Task}. Logging must be as fast as
|
|
@@ -177,13 +193,7 @@ export interface ConsoleDep {
|
|
|
177
193
|
* - `"silent"` — Disables all logging
|
|
178
194
|
*/
|
|
179
195
|
export type ConsoleLevel =
|
|
180
|
-
| "
|
|
181
|
-
| "debug"
|
|
182
|
-
| "log"
|
|
183
|
-
| "info"
|
|
184
|
-
| "warn"
|
|
185
|
-
| "error"
|
|
186
|
-
| "silent";
|
|
196
|
+
"trace" | "debug" | "log" | "info" | "warn" | "error" | "silent";
|
|
187
197
|
|
|
188
198
|
/**
|
|
189
199
|
* Structured log entry captured by {@link Console}.
|
|
@@ -294,10 +304,7 @@ export interface ConsoleFormatterConfig {
|
|
|
294
304
|
|
|
295
305
|
/** Timestamp format for {@link ConsoleFormatterConfig}. */
|
|
296
306
|
export type ConsoleEntryTimestampFormat =
|
|
297
|
-
| "
|
|
298
|
-
| "absolute"
|
|
299
|
-
| "iso"
|
|
300
|
-
| "none";
|
|
307
|
+
"relative" | "absolute" | "iso" | "none";
|
|
301
308
|
|
|
302
309
|
/**
|
|
303
310
|
* A {@link ConsoleOutput} that stores the latest entry in a
|
|
@@ -308,12 +315,26 @@ export type ConsoleEntryTimestampFormat =
|
|
|
308
315
|
* ### Example
|
|
309
316
|
*
|
|
310
317
|
* ```ts
|
|
318
|
+
* import {
|
|
319
|
+
* createConsole,
|
|
320
|
+
* createConsoleStoreOutput,
|
|
321
|
+
* type ConsoleEntry,
|
|
322
|
+
* } from "@evolu/common";
|
|
323
|
+
*
|
|
311
324
|
* const storeOutput = createConsoleStoreOutput();
|
|
312
325
|
* const console = createConsole({ output: storeOutput });
|
|
326
|
+
* let forwardedEntry: ConsoleEntry | null = null;
|
|
327
|
+
* const unsubscribe = storeOutput.entry.subscribe(() => {
|
|
328
|
+
* forwardedEntry = storeOutput.entry.get();
|
|
329
|
+
* });
|
|
330
|
+
*
|
|
331
|
+
* console.child("relay").info("connected");
|
|
332
|
+
* unsubscribe();
|
|
313
333
|
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
334
|
+
* expect(forwardedEntry).toEqual({
|
|
335
|
+
* method: "info",
|
|
336
|
+
* path: ["relay"],
|
|
337
|
+
* args: ["connected"],
|
|
317
338
|
* });
|
|
318
339
|
* ```
|
|
319
340
|
*/
|
|
@@ -432,16 +453,26 @@ export const createConsole = ({
|
|
|
432
453
|
* ### Example
|
|
433
454
|
*
|
|
434
455
|
* ```ts
|
|
456
|
+
* import {
|
|
457
|
+
* createNativeConsoleOutput,
|
|
458
|
+
* type ConsoleOutput,
|
|
459
|
+
* } from "@evolu/common";
|
|
460
|
+
*
|
|
435
461
|
* const output = createNativeConsoleOutput();
|
|
462
|
+
*
|
|
463
|
+
* expectTypeOf(output).toEqualTypeOf<ConsoleOutput>();
|
|
464
|
+
* expect(output.write).toBeTypeOf("function");
|
|
436
465
|
* ```
|
|
437
466
|
*/
|
|
438
467
|
export const createNativeConsoleOutput = (): ConsoleOutput => ({
|
|
439
468
|
write: (entry, formatter) => {
|
|
440
469
|
const args = formatter ? formatter(entry) : entry.args;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
470
|
+
(
|
|
471
|
+
globalThis.console as unknown as Record<
|
|
472
|
+
ConsoleMethod,
|
|
473
|
+
(...args: Array<unknown>) => void
|
|
474
|
+
>
|
|
475
|
+
)[entry.method](...args);
|
|
445
476
|
},
|
|
446
477
|
});
|
|
447
478
|
|
|
@@ -453,23 +484,52 @@ export const createNativeConsoleOutput = (): ConsoleOutput => ({
|
|
|
453
484
|
* ### Example
|
|
454
485
|
*
|
|
455
486
|
* ```ts
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
*
|
|
487
|
+
* import {
|
|
488
|
+
* createConsoleFormatter,
|
|
489
|
+
* Millis,
|
|
490
|
+
* testCreateTime,
|
|
491
|
+
* type ConsoleEntry,
|
|
492
|
+
* } from "@evolu/common";
|
|
493
|
+
*
|
|
494
|
+
* const time = testCreateTime({ startAt: Millis.orThrow(0) });
|
|
495
|
+
* const formatRelative = createConsoleFormatter({ time })({
|
|
496
|
+
* timestampFormat: "relative",
|
|
460
497
|
* });
|
|
498
|
+
* const connected: ConsoleEntry = {
|
|
499
|
+
* method: "log",
|
|
500
|
+
* path: ["relay"],
|
|
501
|
+
* args: ["connected"],
|
|
502
|
+
* };
|
|
461
503
|
*
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
504
|
+
* expect(formatRelative(connected)).toEqual([
|
|
505
|
+
* "+0.000s [relay]",
|
|
506
|
+
* "connected",
|
|
507
|
+
* ]);
|
|
508
|
+
* time.advance("1.5s");
|
|
509
|
+
* expect(
|
|
510
|
+
* formatRelative({
|
|
511
|
+
* ...connected,
|
|
512
|
+
* path: ["relay", "db"],
|
|
513
|
+
* args: ["opened"],
|
|
514
|
+
* }),
|
|
515
|
+
* ).toEqual(["+1.500s [relay] [db]", "opened"]);
|
|
516
|
+
*
|
|
517
|
+
* const localTimestamp = new globalThis.Date(
|
|
518
|
+
* 2026,
|
|
519
|
+
* 0,
|
|
520
|
+
* 28,
|
|
521
|
+
* 14,
|
|
522
|
+
* 30,
|
|
523
|
+
* 15,
|
|
524
|
+
* 123,
|
|
525
|
+
* ).getTime();
|
|
526
|
+
* const formatAbsolute = createConsoleFormatter({
|
|
527
|
+
* time: testCreateTime({ startAt: Millis.orThrow(localTimestamp) }),
|
|
528
|
+
* })({ timestampFormat: "absolute" });
|
|
529
|
+
* expect(formatAbsolute(connected)).toEqual([
|
|
530
|
+
* "14:30:15.123 [relay]",
|
|
531
|
+
* "connected",
|
|
532
|
+
* ]);
|
|
473
533
|
* ```
|
|
474
534
|
*/
|
|
475
535
|
export const createConsoleFormatter =
|
|
@@ -524,11 +584,20 @@ export const createConsoleStoreOutput = (): ConsoleStoreOutput => {
|
|
|
524
584
|
* ### Example
|
|
525
585
|
*
|
|
526
586
|
* ```ts
|
|
527
|
-
*
|
|
528
|
-
*
|
|
587
|
+
* import {
|
|
588
|
+
* createConsole,
|
|
589
|
+
* createConsoleArrayOutput,
|
|
590
|
+
* type ConsoleEntry,
|
|
591
|
+
* } from "@evolu/common";
|
|
529
592
|
*
|
|
530
|
-
*
|
|
531
|
-
*
|
|
593
|
+
* const entries: Array<ConsoleEntry> = [];
|
|
594
|
+
* const console = createConsole({
|
|
595
|
+
* output: createConsoleArrayOutput(entries),
|
|
596
|
+
* });
|
|
597
|
+
* console.info("connected");
|
|
598
|
+
* expect(entries).toEqual([
|
|
599
|
+
* { method: "info", path: [], args: ["connected"] },
|
|
600
|
+
* ]);
|
|
532
601
|
* ```
|
|
533
602
|
*/
|
|
534
603
|
export const createConsoleArrayOutput = (
|
|
@@ -548,10 +617,25 @@ export const createConsoleArrayOutput = (
|
|
|
548
617
|
* ### Example
|
|
549
618
|
*
|
|
550
619
|
* ```ts
|
|
620
|
+
* import {
|
|
621
|
+
* createConsole,
|
|
622
|
+
* createConsoleArrayOutput,
|
|
623
|
+
* createConsoleStoreOutput,
|
|
624
|
+
* createMultiOutput,
|
|
625
|
+
* type ConsoleEntry,
|
|
626
|
+
* } from "@evolu/common";
|
|
627
|
+
*
|
|
628
|
+
* const entries: Array<ConsoleEntry> = [];
|
|
551
629
|
* const storeOutput = createConsoleStoreOutput();
|
|
552
630
|
* const console = createConsole({
|
|
553
|
-
* output: createMultiOutput([
|
|
631
|
+
* output: createMultiOutput([
|
|
632
|
+
* createConsoleArrayOutput(entries),
|
|
633
|
+
* storeOutput,
|
|
634
|
+
* ]),
|
|
554
635
|
* });
|
|
636
|
+
* console.error("disconnected");
|
|
637
|
+
*
|
|
638
|
+
* expect(storeOutput.entry.get()).toEqual(entries[0]);
|
|
555
639
|
* ```
|
|
556
640
|
*/
|
|
557
641
|
export const createMultiOutput = (
|
|
@@ -565,33 +649,21 @@ export const createMultiOutput = (
|
|
|
565
649
|
/**
|
|
566
650
|
* Creates a {@link TestConsole} that captures all output for testing.
|
|
567
651
|
*
|
|
568
|
-
* Unlike {@link createConsole}, this doesn't require dependencies and
|
|
569
|
-
*
|
|
652
|
+
* Unlike {@link createConsole}, this doesn't require dependencies and captures
|
|
653
|
+
* entries in memory.
|
|
570
654
|
*
|
|
571
655
|
* ### Example
|
|
572
656
|
*
|
|
573
657
|
* ```ts
|
|
574
|
-
*
|
|
575
|
-
* const console = testCreateConsole();
|
|
576
|
-
* console.info("Hello");
|
|
577
|
-
*
|
|
578
|
-
* expect(console.getEntriesSnapshot()).toMatchInlineSnapshot(`
|
|
579
|
-
* [
|
|
580
|
-
* {
|
|
581
|
-
* "method": "info",
|
|
582
|
-
* "path": [],
|
|
583
|
-
* "args": ["Hello"]
|
|
584
|
-
* }
|
|
585
|
-
* ]
|
|
586
|
-
* `);
|
|
587
|
-
* });
|
|
658
|
+
* import { testCreateConsole } from "@evolu/common";
|
|
588
659
|
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
* }
|
|
660
|
+
* const console = testCreateConsole({ level: "info" });
|
|
661
|
+
* console.debug("ignored");
|
|
662
|
+
* console.child("relay").info("connected");
|
|
663
|
+
*
|
|
664
|
+
* expect(console.getEntriesSnapshot()).toEqual([
|
|
665
|
+
* { method: "info", path: ["relay"], args: ["connected"] },
|
|
666
|
+
* ]);
|
|
595
667
|
* ```
|
|
596
668
|
*/
|
|
597
669
|
export const testCreateConsole = ({
|
package/src/Crypto.ts
CHANGED
|
@@ -12,10 +12,9 @@ import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
|
|
|
12
12
|
import { hmac } from "@noble/hashes/hmac.js";
|
|
13
13
|
import { sha512 } from "@noble/hashes/sha2.js";
|
|
14
14
|
import { randomBytes, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
15
|
-
import {
|
|
16
|
-
import type {
|
|
17
|
-
import
|
|
18
|
-
import { trySync } from "./Result.js";
|
|
15
|
+
import type { RandomLibDep } from "./Random.ts";
|
|
16
|
+
import type { Result } from "./Result.ts";
|
|
17
|
+
import { trySync } from "./Result.ts";
|
|
19
18
|
import {
|
|
20
19
|
brand,
|
|
21
20
|
length,
|
|
@@ -23,7 +22,7 @@ import {
|
|
|
23
22
|
Uint8Array,
|
|
24
23
|
type Typed,
|
|
25
24
|
zeroNonNegativeInt,
|
|
26
|
-
} from "./Type.
|
|
25
|
+
} from "./Type.ts";
|
|
27
26
|
|
|
28
27
|
export interface RandomBytes {
|
|
29
28
|
/**
|
|
@@ -38,20 +37,35 @@ export interface RandomBytes {
|
|
|
38
37
|
*
|
|
39
38
|
* Returns specific branded types for common sizes:
|
|
40
39
|
*
|
|
41
|
-
* - `
|
|
42
|
-
* - `
|
|
43
|
-
* - `
|
|
44
|
-
* - `
|
|
45
|
-
* - `
|
|
40
|
+
* - `Entropy16` for 16-byte values (128 bits)
|
|
41
|
+
* - `Entropy24` for 24-byte values (192 bits)
|
|
42
|
+
* - `Entropy32` for 32-byte values (256 bits)
|
|
43
|
+
* - `Entropy64` for 64-byte values (512 bits)
|
|
44
|
+
* - `Entropy` for any other size
|
|
46
45
|
*
|
|
47
46
|
* ### Example
|
|
48
47
|
*
|
|
49
48
|
* ```ts
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
49
|
+
* import {
|
|
50
|
+
* createRandomBytes,
|
|
51
|
+
* type Entropy16,
|
|
52
|
+
* type Entropy24,
|
|
53
|
+
* type Entropy32,
|
|
54
|
+
* type Entropy64,
|
|
55
|
+
* } from "@evolu/common";
|
|
56
|
+
*
|
|
57
|
+
* const randomBytes = createRandomBytes();
|
|
58
|
+
* const nonce16 = randomBytes.create(16);
|
|
59
|
+
* const nonce24 = randomBytes.create(24);
|
|
60
|
+
* const key = randomBytes.create(32);
|
|
61
|
+
* const seed = randomBytes.create(64);
|
|
62
|
+
* const custom = randomBytes.create(48);
|
|
63
|
+
*
|
|
64
|
+
* expectTypeOf(nonce16).toEqualTypeOf<Entropy16>();
|
|
65
|
+
* expectTypeOf(nonce24).toEqualTypeOf<Entropy24>();
|
|
66
|
+
* expectTypeOf(key).toEqualTypeOf<Entropy32>();
|
|
67
|
+
* expectTypeOf(seed).toEqualTypeOf<Entropy64>();
|
|
68
|
+
* expect(custom).toHaveLength(48);
|
|
55
69
|
* ```
|
|
56
70
|
*/
|
|
57
71
|
create(bytesLength: 16): Entropy16;
|
|
@@ -66,19 +80,19 @@ export interface RandomBytesDep {
|
|
|
66
80
|
}
|
|
67
81
|
|
|
68
82
|
const Entropy = /*#__PURE__*/ brand("Entropy", Uint8Array);
|
|
69
|
-
type Entropy = typeof Entropy.
|
|
83
|
+
type Entropy = typeof Entropy.Output;
|
|
70
84
|
|
|
71
85
|
export const Entropy16 = /*#__PURE__*/ length(16)(Entropy);
|
|
72
|
-
export type Entropy16 = typeof Entropy16.
|
|
86
|
+
export type Entropy16 = typeof Entropy16.Output;
|
|
73
87
|
|
|
74
88
|
export const Entropy24 = /*#__PURE__*/ length(24)(Entropy);
|
|
75
|
-
export type Entropy24 = typeof Entropy24.
|
|
89
|
+
export type Entropy24 = typeof Entropy24.Output;
|
|
76
90
|
|
|
77
91
|
export const Entropy32 = /*#__PURE__*/ length(32)(Entropy);
|
|
78
|
-
export type Entropy32 = typeof Entropy32.
|
|
92
|
+
export type Entropy32 = typeof Entropy32.Output;
|
|
79
93
|
|
|
80
94
|
export const Entropy64 = /*#__PURE__*/ length(64)(Entropy);
|
|
81
|
-
export type Entropy64 = typeof Entropy64.
|
|
95
|
+
export type Entropy64 = typeof Entropy64.Output;
|
|
82
96
|
|
|
83
97
|
export const createRandomBytes = (): RandomBytes => ({
|
|
84
98
|
create: randomBytes as RandomBytes["create"],
|
|
@@ -87,10 +101,10 @@ export const createRandomBytes = (): RandomBytes => ({
|
|
|
87
101
|
/** Creates seeded random bytes for deterministic tests. */
|
|
88
102
|
export const testCreateRandomBytes = (deps: RandomLibDep): RandomBytes =>
|
|
89
103
|
({
|
|
90
|
-
create: (bytesLength: number) =>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
104
|
+
create: (bytesLength: number) =>
|
|
105
|
+
globalThis.Uint8Array.from({ length: bytesLength }, () =>
|
|
106
|
+
deps.randomLib.int(0, 255),
|
|
107
|
+
),
|
|
94
108
|
}) as RandomBytes;
|
|
95
109
|
|
|
96
110
|
/**
|
|
@@ -134,7 +148,7 @@ export const deriveSlip21Node = (
|
|
|
134
148
|
|
|
135
149
|
/** The encryption key for symmetric encryption. */
|
|
136
150
|
export const EncryptionKey = /*#__PURE__*/ brand("EncryptionKey", Entropy32);
|
|
137
|
-
export type EncryptionKey = typeof EncryptionKey.
|
|
151
|
+
export type EncryptionKey = typeof EncryptionKey.Output;
|
|
138
152
|
|
|
139
153
|
/** The nonce length for XChaCha20-Poly1305 encryption. */
|
|
140
154
|
export const xChaCha20Poly1305NonceLength = 24;
|
|
@@ -149,7 +163,7 @@ export const XChaCha20Poly1305Ciphertext = /*#__PURE__*/ brand(
|
|
|
149
163
|
Uint8Array,
|
|
150
164
|
);
|
|
151
165
|
export type XChaCha20Poly1305Ciphertext =
|
|
152
|
-
typeof XChaCha20Poly1305Ciphertext.
|
|
166
|
+
typeof XChaCha20Poly1305Ciphertext.Output;
|
|
153
167
|
|
|
154
168
|
/**
|
|
155
169
|
* Encrypts plaintext with XChaCha20-Poly1305.
|
|
@@ -160,11 +174,22 @@ export type XChaCha20Poly1305Ciphertext =
|
|
|
160
174
|
* ### Example
|
|
161
175
|
*
|
|
162
176
|
* ```ts
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
177
|
+
* import {
|
|
178
|
+
* createRandomBytes,
|
|
179
|
+
* EncryptionKey,
|
|
180
|
+
* encryptWithXChaCha20Poly1305,
|
|
181
|
+
* type XChaCha20Poly1305Ciphertext,
|
|
182
|
+
* utf8ToBytes,
|
|
183
|
+
* } from "@evolu/common";
|
|
184
|
+
*
|
|
185
|
+
* const plaintext = utf8ToBytes("secret message");
|
|
186
|
+
* const encryptionKey = EncryptionKey.orThrow(new Uint8Array(32).fill(7));
|
|
187
|
+
* const [ciphertext, nonce] = encryptWithXChaCha20Poly1305({
|
|
188
|
+
* randomBytes: createRandomBytes(),
|
|
189
|
+
* })(plaintext, encryptionKey);
|
|
190
|
+
*
|
|
191
|
+
* expectTypeOf(ciphertext).toEqualTypeOf<XChaCha20Poly1305Ciphertext>();
|
|
192
|
+
* expect(nonce).toHaveLength(24);
|
|
168
193
|
* ```
|
|
169
194
|
*
|
|
170
195
|
* @see https://github.com/paulmillr/noble-ciphers
|
|
@@ -196,16 +221,33 @@ export interface DecryptWithXChaCha20Poly1305Error extends Typed<"DecryptWithXCh
|
|
|
196
221
|
* ### Example
|
|
197
222
|
*
|
|
198
223
|
* ```ts
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* }
|
|
208
|
-
*
|
|
224
|
+
* import {
|
|
225
|
+
* bytesToUtf8,
|
|
226
|
+
* createRandomBytes,
|
|
227
|
+
* decryptWithXChaCha20Poly1305,
|
|
228
|
+
* EncryptionKey,
|
|
229
|
+
* encryptWithXChaCha20Poly1305,
|
|
230
|
+
* ok,
|
|
231
|
+
* utf8ToBytes,
|
|
232
|
+
* } from "@evolu/common";
|
|
233
|
+
*
|
|
234
|
+
* const plaintext = utf8ToBytes("secret message");
|
|
235
|
+
* const encryptionKey = EncryptionKey.orThrow(new Uint8Array(32).fill(7));
|
|
236
|
+
* const [ciphertext, nonce] = encryptWithXChaCha20Poly1305({
|
|
237
|
+
* randomBytes: createRandomBytes(),
|
|
238
|
+
* })(plaintext, encryptionKey);
|
|
239
|
+
*
|
|
240
|
+
* const decryptMessage = () => {
|
|
241
|
+
* const result = decryptWithXChaCha20Poly1305(
|
|
242
|
+
* ciphertext,
|
|
243
|
+
* nonce,
|
|
244
|
+
* encryptionKey,
|
|
245
|
+
* );
|
|
246
|
+
* if (!result.ok) return result;
|
|
247
|
+
* return ok(bytesToUtf8(result.value));
|
|
248
|
+
* };
|
|
249
|
+
*
|
|
250
|
+
* expectOk(decryptMessage(), "secret message");
|
|
209
251
|
* ```
|
|
210
252
|
*/
|
|
211
253
|
export const decryptWithXChaCha20Poly1305 = (
|