@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.
Files changed (140) hide show
  1. package/dist/src/Assert.d.ts.map +1 -1
  2. package/dist/src/Assert.js +1 -1
  3. package/dist/src/Buffer.d.ts +1 -1
  4. package/dist/src/Buffer.d.ts.map +1 -1
  5. package/dist/src/Buffer.js +1 -1
  6. package/dist/src/CallbackRegistry.d.ts +53 -0
  7. package/dist/src/CallbackRegistry.d.ts.map +1 -0
  8. package/dist/src/CallbackRegistry.js +25 -0
  9. package/dist/src/Console.d.ts +31 -6
  10. package/dist/src/Console.d.ts.map +1 -1
  11. package/dist/src/Console.js +72 -9
  12. package/dist/src/Crypto.d.ts +48 -37
  13. package/dist/src/Crypto.d.ts.map +1 -1
  14. package/dist/src/Crypto.js +27 -50
  15. package/dist/src/Evolu/Db.d.ts +138 -66
  16. package/dist/src/Evolu/Db.d.ts.map +1 -1
  17. package/dist/src/Evolu/Db.js +248 -645
  18. package/dist/src/Evolu/Diff.d.ts +3 -3
  19. package/dist/src/Evolu/Diff.d.ts.map +1 -1
  20. package/dist/src/Evolu/Diff.js +7 -5
  21. package/dist/src/Evolu/Evolu.d.ts +79 -116
  22. package/dist/src/Evolu/Evolu.d.ts.map +1 -1
  23. package/dist/src/Evolu/Evolu.js +275 -132
  24. package/dist/src/Evolu/Internal.d.ts +0 -2
  25. package/dist/src/Evolu/Internal.d.ts.map +1 -1
  26. package/dist/src/Evolu/Internal.js +0 -2
  27. package/dist/src/Evolu/LocalAuth.d.ts +144 -0
  28. package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
  29. package/dist/src/Evolu/LocalAuth.js +171 -0
  30. package/dist/src/Evolu/Owner.d.ts +129 -83
  31. package/dist/src/Evolu/Owner.d.ts.map +1 -1
  32. package/dist/src/Evolu/Owner.js +80 -89
  33. package/dist/src/Evolu/Platform.d.ts +9 -7
  34. package/dist/src/Evolu/Platform.d.ts.map +1 -1
  35. package/dist/src/Evolu/Protocol.d.ts +114 -191
  36. package/dist/src/Evolu/Protocol.d.ts.map +1 -1
  37. package/dist/src/Evolu/Protocol.js +409 -416
  38. package/dist/src/Evolu/Public.d.ts +6 -8
  39. package/dist/src/Evolu/Public.d.ts.map +1 -1
  40. package/dist/src/Evolu/Public.js +2 -3
  41. package/dist/src/Evolu/PublicKysely.js +3 -3
  42. package/dist/src/Evolu/Relay.d.ts +1 -2
  43. package/dist/src/Evolu/Relay.d.ts.map +1 -1
  44. package/dist/src/Evolu/Relay.js +11 -9
  45. package/dist/src/Evolu/Schema.d.ts +88 -27
  46. package/dist/src/Evolu/Schema.d.ts.map +1 -1
  47. package/dist/src/Evolu/Schema.js +141 -24
  48. package/dist/src/Evolu/Storage.d.ts +158 -14
  49. package/dist/src/Evolu/Storage.d.ts.map +1 -1
  50. package/dist/src/Evolu/Storage.js +32 -32
  51. package/dist/src/Evolu/Sync.d.ts +77 -13
  52. package/dist/src/Evolu/Sync.d.ts.map +1 -1
  53. package/dist/src/Evolu/Sync.js +453 -20
  54. package/dist/src/Evolu/Timestamp.d.ts +29 -27
  55. package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
  56. package/dist/src/Evolu/Timestamp.js +20 -18
  57. package/dist/src/ManyToManyMap.d.ts +74 -10
  58. package/dist/src/ManyToManyMap.d.ts.map +1 -1
  59. package/dist/src/ManyToManyMap.js +41 -6
  60. package/dist/src/Random.d.ts +3 -2
  61. package/dist/src/Random.d.ts.map +1 -1
  62. package/dist/src/RefCountedResourceManager.d.ts +119 -0
  63. package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
  64. package/dist/src/RefCountedResourceManager.js +197 -0
  65. package/dist/src/Result.d.ts +144 -22
  66. package/dist/src/Result.d.ts.map +1 -1
  67. package/dist/src/Result.js +5 -2
  68. package/dist/src/Sqlite.d.ts +20 -4
  69. package/dist/src/Sqlite.d.ts.map +1 -1
  70. package/dist/src/Sqlite.js +50 -8
  71. package/dist/src/Task.d.ts +511 -0
  72. package/dist/src/Task.d.ts.map +1 -0
  73. package/dist/src/Task.js +410 -0
  74. package/dist/src/Time.d.ts +59 -0
  75. package/dist/src/Time.d.ts.map +1 -1
  76. package/dist/src/Time.js +87 -4
  77. package/dist/src/Type.d.ts +431 -341
  78. package/dist/src/Type.d.ts.map +1 -1
  79. package/dist/src/Type.js +458 -466
  80. package/dist/src/WebSocket.d.ts +5 -2
  81. package/dist/src/WebSocket.d.ts.map +1 -1
  82. package/dist/src/WebSocket.js +12 -13
  83. package/dist/src/Worker.d.ts +39 -11
  84. package/dist/src/Worker.d.ts.map +1 -1
  85. package/dist/src/Worker.js +22 -4
  86. package/dist/src/index.d.ts +2 -3
  87. package/dist/src/index.d.ts.map +1 -1
  88. package/dist/src/index.js +2 -3
  89. package/package.json +7 -7
  90. package/src/Assert.ts +2 -4
  91. package/src/Buffer.ts +1 -1
  92. package/src/CallbackRegistry.ts +84 -0
  93. package/src/Console.ts +91 -11
  94. package/src/Crypto.ts +78 -91
  95. package/src/Evolu/Db.ts +455 -947
  96. package/src/Evolu/Diff.ts +7 -5
  97. package/src/Evolu/Evolu.ts +545 -307
  98. package/src/Evolu/Internal.ts +0 -2
  99. package/src/Evolu/LocalAuth.ts +422 -0
  100. package/src/Evolu/Owner.ts +191 -131
  101. package/src/Evolu/Platform.ts +9 -9
  102. package/src/Evolu/Protocol.ts +536 -653
  103. package/src/Evolu/Public.ts +7 -9
  104. package/src/Evolu/PublicKysely.ts +3 -3
  105. package/src/Evolu/Relay.ts +17 -12
  106. package/src/Evolu/Schema.ts +271 -66
  107. package/src/Evolu/Storage.ts +263 -55
  108. package/src/Evolu/Sync.ts +758 -37
  109. package/src/Evolu/Timestamp.ts +30 -35
  110. package/src/ManyToManyMap.ts +127 -24
  111. package/src/Random.ts +3 -2
  112. package/src/RefCountedResourceManager.ts +368 -0
  113. package/src/Result.ts +149 -23
  114. package/src/Sqlite.ts +59 -24
  115. package/src/Task.ts +779 -0
  116. package/src/Time.ts +168 -4
  117. package/src/Type.ts +657 -695
  118. package/src/WebSocket.ts +23 -17
  119. package/src/Worker.ts +72 -23
  120. package/src/index.ts +2 -3
  121. package/dist/src/Callbacks.d.ts +0 -20
  122. package/dist/src/Callbacks.d.ts.map +0 -1
  123. package/dist/src/Callbacks.js +0 -18
  124. package/dist/src/Evolu/Config.d.ts +0 -82
  125. package/dist/src/Evolu/Config.d.ts.map +0 -1
  126. package/dist/src/Evolu/Config.js +0 -9
  127. package/dist/src/Evolu/Kysely.d.ts +0 -6
  128. package/dist/src/Evolu/Kysely.d.ts.map +0 -1
  129. package/dist/src/Evolu/Kysely.js +0 -21
  130. package/dist/src/NanoId.d.ts +0 -27
  131. package/dist/src/NanoId.d.ts.map +0 -1
  132. package/dist/src/NanoId.js +0 -6
  133. package/dist/src/Promise.d.ts +0 -180
  134. package/dist/src/Promise.d.ts.map +0 -1
  135. package/dist/src/Promise.js +0 -176
  136. package/src/Callbacks.ts +0 -43
  137. package/src/Evolu/Config.ts +0 -97
  138. package/src/Evolu/Kysely.ts +0 -38
  139. package/src/NanoId.ts +0 -39
  140. package/src/Promise.ts +0 -295
@@ -1 +1 @@
1
- {"version":3,"file":"Assert.d.ts","sourceRoot":"","sources":["../../src/Assert.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,MAAM,EAAE,CACnB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,SAIZ,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAClC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAKlC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,EAAE,CAAC,CAAC,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAK3C,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,CAO3E"}
1
+ {"version":3,"file":"Assert.d.ts","sourceRoot":"","sources":["../../src/Assert.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,MAAM,EAAE,CACnB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,KACZ,OAAO,CAAC,SAIZ,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,EAAE,CAAC,CAAC,EAClC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,EACb,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAKlC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,EAAE,CAAC,CAAC,EAC1C,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACrB,OAAO,CAAC,EAAE,MAAM,KACb,OAAO,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAK3C,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,CAK3E"}
@@ -76,5 +76,5 @@ export const assertNonEmptyReadonlyArray = (arr, message = "Expected a non-empty
76
76
  * ```
77
77
  */
78
78
  export function assertNoErrorInCatch(context, error) {
79
- throw Object.assign(new Error(`Error in ${context}: an unexpected error reached a catch block and requires a fix`), { cause: error });
79
+ throw new Error(`Error in ${context}: an unexpected error reached a catch block and requires a fix`, { cause: error });
80
80
  }
@@ -1,5 +1,5 @@
1
1
  import { NonNegativeInt } from "./Type.js";
2
- export { bytesToHex, bytesToUtf8, concatBytes, hexToBytes, utf8ToBytes, } from "@noble/ciphers/utils";
2
+ export { bytesToHex, bytesToUtf8, concatBytes, hexToBytes, utf8ToBytes, } from "@noble/ciphers/utils.js";
3
3
  /**
4
4
  * Custom error for {@link Buffer}-related failures like premature end of data.
5
5
  * Provides better stack traces for debugging binary protocol issues.
@@ -1 +1 @@
1
- {"version":3,"file":"Buffer.d.ts","sourceRoot":"","sources":["../../src/Buffer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAE9B;;;GAGG;AACH,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAM5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,MAAM;IACrB,sDAAsD;IACtD,WAAW,EAAE,MAAM,cAAc,CAAC;IAElC,gEAAgE;IAChE,SAAS,EAAE,MAAM,cAAc,CAAC;IAEhC;;;OAGG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAEtD;;;OAGG;IACH,KAAK,EAAE,MAAM,cAAc,CAAC;IAE5B;;;OAGG;IACH,MAAM,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,UAAU,CAAC;IAE1C;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAE3C;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB;;;;OAIG;IACH,MAAM,EAAE,MAAM,UAAU,CAAC;CAC1B;AAED,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,KACzC,MA4DF,CAAC"}
1
+ {"version":3,"file":"Buffer.d.ts","sourceRoot":"","sources":["../../src/Buffer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,UAAU,EACV,WAAW,EACX,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAM5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,WAAW,MAAM;IACrB,sDAAsD;IACtD,WAAW,EAAE,MAAM,cAAc,CAAC;IAElC,gEAAgE;IAChE,SAAS,EAAE,MAAM,cAAc,CAAC;IAEhC;;;OAGG;IACH,MAAM,EAAE,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAEtD;;;OAGG;IACH,KAAK,EAAE,MAAM,cAAc,CAAC;IAE5B;;;OAGG;IACH,MAAM,EAAE,CAAC,CAAC,EAAE,cAAc,KAAK,UAAU,CAAC;IAE1C;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAE3C;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB;;;;OAIG;IACH,MAAM,EAAE,MAAM,UAAU,CAAC;CAC1B;AAED,eAAO,MAAM,YAAY,GACvB,YAAY,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,KACzC,MA4DF,CAAC"}
@@ -1,4 +1,4 @@
1
- export { bytesToHex, bytesToUtf8, concatBytes, hexToBytes, utf8ToBytes, } from "@noble/ciphers/utils";
1
+ export { bytesToHex, bytesToUtf8, concatBytes, hexToBytes, utf8ToBytes, } from "@noble/ciphers/utils.js";
2
2
  /**
3
3
  * Custom error for {@link Buffer}-related failures like premature end of data.
4
4
  * Provides better stack traces for debugging binary protocol issues.
@@ -0,0 +1,53 @@
1
+ import { Brand } from "./Brand.js";
2
+ import { RandomBytesDep } from "./Crypto.js";
3
+ import { Id } from "./Type.js";
4
+ /**
5
+ * A registry for one-time callback functions.
6
+ *
7
+ * Stores callbacks with unique IDs and executes them once with an optional
8
+ * argument. Executed callbacks are automatically removed from the registry.
9
+ *
10
+ * This is useful for correlating asynchronous operations across boundaries
11
+ * where callback functions cannot be passed directly (e.g., web workers).
12
+ *
13
+ * The `execute` method intentionally does not use try-catch or {@link Result}
14
+ * because it's the callback's responsibility to handle its own errors. The
15
+ * registry is just a correlation mechanism and should not interfere with error
16
+ * handling or debugging by masking the original error location.
17
+ *
18
+ * ### Example
19
+ *
20
+ * ```ts
21
+ * // No-argument callbacks
22
+ * const registry = createCallbackRegistry(deps);
23
+ * const id = registry.register(() => console.log("called"));
24
+ * registry.execute(id);
25
+ *
26
+ * // With argument callbacks
27
+ * const stringRegistry = createCallbackRegistry<string>(deps);
28
+ * const id = stringRegistry.register((value) => {
29
+ * console.log(value);
30
+ * });
31
+ * stringRegistry.execute(id, "hello");
32
+ *
33
+ * // Promise.withResolvers pattern
34
+ * const promiseRegistry = createCallbackRegistry<string>(deps);
35
+ * const { promise, resolve } = Promise.withResolvers<string>();
36
+ * const id = promiseRegistry.register(resolve);
37
+ * promiseRegistry.execute(id, "resolved value");
38
+ * await promise; // "resolved value"
39
+ * ```
40
+ *
41
+ * @template T - The type of argument passed to callbacks (defaults to undefined
42
+ * for no-argument callbacks)
43
+ */
44
+ export interface CallbackRegistry<T = undefined> {
45
+ /** Registers a callback function and returns a unique ID. */
46
+ readonly register: (callback: (arg: T) => void) => CallbackId;
47
+ /** Executes and removes a callback associated with the given ID. */
48
+ readonly execute: T extends undefined ? (id: CallbackId) => undefined : (id: CallbackId, arg: T) => undefined;
49
+ }
50
+ export type CallbackId = Id & Brand<"Callback">;
51
+ /** Creates a new {@link CallbackRegistry} for one-time callback functions. */
52
+ export declare const createCallbackRegistry: <T = undefined>(deps: RandomBytesDep) => CallbackRegistry<T>;
53
+ //# sourceMappingURL=CallbackRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallbackRegistry.d.ts","sourceRoot":"","sources":["../../src/CallbackRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAY,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,SAAS;IAC7C,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,KAAK,UAAU,CAAC;IAE9D,oEAAoE;IACpE,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,SAAS,GACjC,CAAC,EAAE,EAAE,UAAU,KAAK,SAAS,GAC7B,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,KAAK,SAAS,CAAC;CAC3C;AAED,MAAM,MAAM,UAAU,GAAG,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC;AAEhD,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,GAAI,CAAC,GAAG,SAAS,EAClD,MAAM,cAAc,KACnB,gBAAgB,CAAC,CAAC,CAuBpB,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { createId } from "./Type.js";
2
+ /** Creates a new {@link CallbackRegistry} for one-time callback functions. */
3
+ export const createCallbackRegistry = (deps) => {
4
+ const callbackMap = new Map();
5
+ return {
6
+ register: (callback) => {
7
+ const id = createId(deps);
8
+ callbackMap.set(id, callback);
9
+ return id;
10
+ },
11
+ execute: (id, ...args) => {
12
+ const callback = callbackMap.get(id);
13
+ if (callback) {
14
+ callbackMap.delete(id);
15
+ if (args.length === 0) {
16
+ // Called without argument (undefined case)
17
+ callback();
18
+ }
19
+ else {
20
+ callback(args[0]);
21
+ }
22
+ }
23
+ },
24
+ };
25
+ };
@@ -13,14 +13,28 @@
13
13
  * ### Example
14
14
  *
15
15
  * ```ts
16
- * deps.console.log("[db]", "send data message", protocolMessage);
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
- * **Warning**: If you encounter platform-specific issues or missing methods,
23
- * please contribute a PR with details about the environment and behavior.
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
  */
@@ -43,6 +57,8 @@ export interface Console {
43
57
  debug: (...args: Array<any>) => void;
44
58
  /** Starts a timer with an optional label */
45
59
  time: (label?: string) => void;
60
+ /** Logs the elapsed time for a timer without ending it */
61
+ timeLog: (label?: string, ...data: Array<any>) => void;
46
62
  /** Ends a timer and logs the elapsed time */
47
63
  timeEnd: (label?: string) => void;
48
64
  /** Displays an object's properties in a detailed format */
@@ -55,8 +71,6 @@ export interface Console {
55
71
  countReset: (label?: string) => void;
56
72
  /** Writes a message if the value is falsy, otherwise does nothing */
57
73
  assert: (value: any, message?: string, ...optionalParams: Array<any>) => void;
58
- /** Logs the elapsed time for a timer without ending it */
59
- timeLog: (label?: string, ...data: Array<any>) => void;
60
74
  /** Prints a stack trace with an optional message */
61
75
  trace: (message?: any, ...optionalParams: Array<any>) => void;
62
76
  }
@@ -75,4 +89,15 @@ export interface ConsoleConfig {
75
89
  }
76
90
  /** Creates a console instance using the global console. */
77
91
  export declare const createConsole: (config?: ConsoleConfig) => Console;
92
+ export interface ConsoleWithTimeConfig extends ConsoleConfig {
93
+ /**
94
+ * Type of timestamp to prepend to log messages.
95
+ *
96
+ * - 'absolute': Shows actual time (e.g., "14:32:15.234")
97
+ * - 'relative': Shows time since console creation (e.g., "+1.234s")
98
+ */
99
+ readonly timestampType: "absolute" | "relative";
100
+ }
101
+ /** Creates a console instance with timestamp prefixes. */
102
+ export declare const createConsoleWithTime: (config?: ConsoleWithTimeConfig) => Console;
78
103
  //# sourceMappingURL=Console.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Console.d.ts","sourceRoot":"","sources":["../../src/Console.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,uCAAuC;IACvC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEnC,2DAA2D;IAC3D,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpC,gCAAgC;IAChC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpC,+BAA+B;IAC/B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAErC,8BAA8B;IAC9B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAErC,4CAA4C;IAC5C,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAE/B,6CAA6C;IAC7C,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,2DAA2D;IAC3D,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAE1C,uCAAuC;IACvC,KAAK,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAE9D,yEAAyE;IACzE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhC,6CAA6C;IAC7C,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAErC,qEAAqE;IACrE,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAE9E,0DAA0D;IAC1D,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEvD,oDAAoD;IACpD,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;CAC/D;AAED,6DAA6D;AAC7D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,2DAA2D;AAC3D,eAAO,MAAM,aAAa,GAAI,SAAQ,aAAkB,KAAG,OAgE1D,CAAC"}
1
+ {"version":3,"file":"Console.d.ts","sourceRoot":"","sources":["../../src/Console.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,uCAAuC;IACvC,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEnC,2DAA2D;IAC3D,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpC,gCAAgC;IAChC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEpC,+BAA+B;IAC/B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAErC,8BAA8B;IAC9B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAErC,4CAA4C;IAC5C,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAE/B,0DAA0D;IAC1D,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAEvD,6CAA6C;IAC7C,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAElC,2DAA2D;IAC3D,GAAG,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAE1C,uCAAuC;IACvC,KAAK,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAE9D,yEAAyE;IACzE,KAAK,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhC,6CAA6C;IAC7C,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAErC,qEAAqE;IACrE,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAE9E,oDAAoD;IACpD,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;CAC/D;AAED,6DAA6D;AAC7D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,2DAA2D;AAC3D,eAAO,MAAM,aAAa,GAAI,SAAQ,aAAkB,KAAG,OAgE1D,CAAC;AAEF,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU,CAAC;CACjD;AAED,0DAA0D;AAC1D,eAAO,MAAM,qBAAqB,GAChC,SAAQ,qBAAqD,KAC5D,OAmDF,CAAC"}
@@ -13,14 +13,28 @@
13
13
  * ### Example
14
14
  *
15
15
  * ```ts
16
- * deps.console.log("[db]", "send data message", protocolMessage);
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
- * **Warning**: If you encounter platform-specific issues or missing methods,
23
- * please contribute a PR with details about the environment and behavior.
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
  */
@@ -58,6 +72,11 @@ export const createConsole = (config = {}) => {
58
72
  if (instance.enabled)
59
73
  console.time(label);
60
74
  },
75
+ timeLog: (label, ...data) => {
76
+ // eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
77
+ if (instance.enabled)
78
+ console.timeLog(label, ...data);
79
+ },
61
80
  timeEnd: (label) => {
62
81
  // eslint-disable-next-line no-console
63
82
  if (instance.enabled)
@@ -88,11 +107,6 @@ export const createConsole = (config = {}) => {
88
107
  if (instance.enabled)
89
108
  console.assert(value, message, ...optionalParams);
90
109
  },
91
- timeLog: (label, ...data) => {
92
- // eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
93
- if (instance.enabled)
94
- console.timeLog(label, ...data);
95
- },
96
110
  trace: (message, ...optionalParams) => {
97
111
  // eslint-disable-next-line no-console, @typescript-eslint/no-unsafe-argument
98
112
  if (instance.enabled)
@@ -101,3 +115,52 @@ export const createConsole = (config = {}) => {
101
115
  };
102
116
  return instance;
103
117
  };
118
+ /** Creates a console instance with timestamp prefixes. */
119
+ export const createConsoleWithTime = (config = { timestampType: "relative" }) => {
120
+ const console = createConsole(config);
121
+ const startTime = performance.now();
122
+ const getTimestamp = () => {
123
+ if (config.timestampType === "relative") {
124
+ const elapsed = (performance.now() - startTime) / 1000;
125
+ // Format for better readability at different time scales
126
+ if (elapsed < 60) {
127
+ // Under 1 minute: show seconds with millisecond precision
128
+ return `+${elapsed.toFixed(3)}s`;
129
+ }
130
+ else if (elapsed < 3600) {
131
+ // 1 minute to 1 hour: show minutes and seconds with millisecond precision
132
+ const minutes = Math.floor(elapsed / 60);
133
+ const seconds = (elapsed % 60).toFixed(3);
134
+ return `+${minutes}m${seconds}s`;
135
+ }
136
+ else {
137
+ // Over 1 hour: show hours, minutes, and seconds with millisecond precision
138
+ const hours = Math.floor(elapsed / 3600);
139
+ const minutes = Math.floor((elapsed % 3600) / 60);
140
+ const seconds = ((elapsed % 3600) % 60).toFixed(3);
141
+ return `+${hours}h${minutes}m${seconds}s`;
142
+ }
143
+ }
144
+ else {
145
+ // Absolute time - format as HH:MM:SS.mmm
146
+ const now = new Date();
147
+ const hours = now.getHours().toString().padStart(2, "0");
148
+ const minutes = now.getMinutes().toString().padStart(2, "0");
149
+ const seconds = now.getSeconds().toString().padStart(2, "0");
150
+ const milliseconds = now.getMilliseconds().toString().padStart(3, "0");
151
+ return `${hours}:${minutes}:${seconds}.${milliseconds}`;
152
+ }
153
+ };
154
+ const withTimestamp = (fn) => (...args) => {
155
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
156
+ fn(`[${getTimestamp()}]`, ...args);
157
+ };
158
+ // Override methods that should have timestamps
159
+ console.log = withTimestamp(console.log);
160
+ console.info = withTimestamp(console.info);
161
+ console.warn = withTimestamp(console.warn);
162
+ console.error = withTimestamp(console.error);
163
+ console.debug = withTimestamp(console.debug);
164
+ console.trace = withTimestamp(console.trace);
165
+ return console;
166
+ };
@@ -1,53 +1,63 @@
1
- /**
2
- * 🔒
3
- *
4
- * @module
5
- */
6
1
  import { Result } from "./Result.js";
7
- import { Id, Mnemonic, NonNegativeInt } from "./Type.js";
8
- import { Brand } from "./Brand.js";
9
- /** `Uint8Array` created by {@link createRandomBytes}. */
10
- export type RandomBytes = Uint8Array & Brand<"RandomBytes">;
11
- export type CreateRandomBytes = (bytesLength?: number) => RandomBytes;
12
- export interface CreateRandomBytesDep {
13
- readonly createRandomBytes: CreateRandomBytes;
2
+ import { NonNegativeInt } from "./Type.js";
3
+ export interface RandomBytes {
4
+ /**
5
+ * Creates cryptographically secure random bytes with type-safe length
6
+ * branding.
7
+ *
8
+ * Uses the operating system's cryptographically secure random number
9
+ * generator (crypto.getRandomValues) to generate high-quality entropy
10
+ * suitable for cryptographic operations.
11
+ *
12
+ * ### Type Safety
13
+ *
14
+ * Returns specific branded types for common sizes:
15
+ *
16
+ * - `Random16` for 16-byte values (128 bits)
17
+ * - `Random32` for 32-byte values (256 bits)
18
+ * - `Random64` for 64-byte values (512 bits)
19
+ * - `Random` for any other size
20
+ *
21
+ * ### Example
22
+ *
23
+ * ```ts
24
+ * const nonce = randomBytes.create(16); // Type: Random16
25
+ * const key = randomBytes.create(32); // Type: Random32
26
+ * const seed = randomBytes.create(64); // Type: Random64
27
+ * const custom = randomBytes.create(48); // Type: Random
28
+ * ```
29
+ */
30
+ create(bytesLength: 16): Entropy16;
31
+ create(bytesLength: 32): Entropy32;
32
+ create(bytesLength: 64): Entropy64;
33
+ create(bytesLength: number): Entropy;
14
34
  }
15
- /** Cryptographically secure PRNG. Uses internal OS-level crypto.getRandomValues. */
16
- export declare const createRandomBytes: CreateRandomBytes;
17
- export type CreateMnemonic = () => Mnemonic;
18
- export interface CreateMnemonicDep {
19
- readonly createMnemonic: CreateMnemonic;
35
+ export interface RandomBytesDep {
36
+ readonly randomBytes: RandomBytes;
20
37
  }
21
- export declare const createEnglishMnemonic: CreateMnemonic;
22
- export type MnemonicSeed = Uint8Array & Brand<"MnemonicSeed">;
23
- export declare const mnemonicToMnemonicSeed: (mnemonic: Mnemonic) => MnemonicSeed;
38
+ declare const Entropy: import("./Type.js").BrandType<import("./Type.js").Type<"Uint8Array", Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>, import("./Type.js").Uint8ArrayError, Uint8Array<ArrayBufferLike>, import("./Type.js").Uint8ArrayError>, "Entropy", import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>, never>;
39
+ type Entropy = typeof Entropy.Type;
40
+ export declare const Entropy16: import("./Type.js").BrandType<import("./Type.js").Type<"Brand", Uint8Array<ArrayBufferLike> & import("./Brand.js").Brand<"Entropy">, Uint8Array<ArrayBufferLike>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>, Uint8Array<ArrayBufferLike>, never>, "Length16", import("./Type.js").LengthError<16>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>>;
41
+ export type Entropy16 = typeof Entropy16.Type;
42
+ export declare const Entropy32: import("./Type.js").BrandType<import("./Type.js").Type<"Brand", Uint8Array<ArrayBufferLike> & import("./Brand.js").Brand<"Entropy">, Uint8Array<ArrayBufferLike>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>, Uint8Array<ArrayBufferLike>, never>, "Length32", import("./Type.js").LengthError<32>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>>;
43
+ export type Entropy32 = typeof Entropy32.Type;
44
+ export declare const Entropy64: import("./Type.js").BrandType<import("./Type.js").Type<"Brand", Uint8Array<ArrayBufferLike> & import("./Brand.js").Brand<"Entropy">, Uint8Array<ArrayBufferLike>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>, Uint8Array<ArrayBufferLike>, never>, "Length64", import("./Type.js").LengthError<64>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>>;
45
+ export type Entropy64 = typeof Entropy64.Type;
46
+ export declare const createRandomBytes: () => RandomBytes;
24
47
  /**
25
48
  * SLIP21.
26
49
  *
27
50
  * https://github.com/satoshilabs/slips/blob/master/slip-0021.md
28
51
  */
29
- export declare const createSlip21: (seed: Uint8Array, path: ReadonlyArray<string>) => Uint8Array;
52
+ export declare const createSlip21: (seed: Entropy16 | Entropy32 | Entropy64, path: ReadonlyArray<string | number>) => Entropy32;
30
53
  /**
31
54
  * Derives a single node in the SLIP-21 hierarchical key derivation.
32
55
  *
33
56
  * @see {@link createSlip21}
34
57
  */
35
- export declare const deriveSlip21Node: (component: string, m: Uint8Array) => Uint8Array;
36
- /**
37
- * Creates a 21-character Base64URL ID (also known as nanoid) from a SLIP-21
38
- * derived key.
39
- *
40
- * Reduces the 256-bit SLIP-21 output to 126 bits (21 chars × 6 bits) for a
41
- * compact, human-readable, and shareable identifier suitable for UI display or
42
- * URL use. While this lowers entropy, 126 bits remains cryptographically secure
43
- * for uniqueness and unpredictability in most applications (comparable to
44
- * UUIDv4's 122 bits).
45
- *
46
- * See https://github.com/satoshilabs/slips/blob/master/slip-0021.md
47
- */
48
- export declare const createSlip21Id: (seed: MnemonicSeed, path: ReadonlyArray<string>) => Id;
58
+ export declare const deriveSlip21Node: (label: string, parentNode: Entropy64) => Entropy64;
49
59
  /** The encryption key for {@link SymmetricCrypto}. */
50
- export declare const EncryptionKey: import("./Type.js").BrandType<import("./Type.js").BrandType<import("./Type.js").Type<"Uint8Array", Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>, import("./Type.js").Uint8ArrayError, Uint8Array<ArrayBufferLike>, import("./Type.js").Uint8ArrayError>, "Length32", import("./Type.js").LengthError<32>, import("./Type.js").Uint8ArrayError>, "EncryptionKey", import("./Type.js").BrandWithoutRefineError<"EncryptionKey", import("./Type.js").Uint8ArrayError | import("./Type.js").LengthError<32>>, never>;
60
+ export declare const EncryptionKey: import("./Type.js").BrandType<import("./Type.js").BrandType<import("./Type.js").Type<"Brand", Uint8Array<ArrayBufferLike> & import("./Brand.js").Brand<"Entropy">, Uint8Array<ArrayBufferLike>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>, Uint8Array<ArrayBufferLike>, never>, "Length32", import("./Type.js").LengthError<32>, import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError>>, "EncryptionKey", import("./Type.js").BrandWithoutRefineError<"EncryptionKey", import("./Type.js").BrandWithoutRefineError<"Entropy", import("./Type.js").Uint8ArrayError> | import("./Type.js").LengthError<32>>, never>;
51
61
  export type EncryptionKey = typeof EncryptionKey.Type;
52
62
  /** Symmetric cryptography. */
53
63
  export interface SymmetricCrypto {
@@ -70,7 +80,7 @@ export interface SymmetricCryptoDecryptError {
70
80
  *
71
81
  * https://github.com/paulmillr/noble-ciphers?tab=readme-ov-file#which-cipher-should-i-pick
72
82
  */
73
- export declare const createSymmetricCrypto: (deps: CreateRandomBytesDep) => SymmetricCrypto;
83
+ export declare const createSymmetricCrypto: (deps: RandomBytesDep) => SymmetricCrypto;
74
84
  /**
75
85
  * Returns the PADMÉ padded length for a given input length.
76
86
  *
@@ -95,4 +105,5 @@ export type TimingSafeEqual = (a: Uint8Array, b: Uint8Array) => boolean;
95
105
  export interface TimingSafeEqualDep {
96
106
  readonly timingSafeEqual: TimingSafeEqual;
97
107
  }
108
+ export {};
98
109
  //# sourceMappingURL=Crypto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAc,MAAM,EAAW,MAAM,aAAa,CAAC;AAC1D,OAAO,EAEL,EAAE,EAEF,QAAQ,EACR,cAAc,EAEf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,yDAAyD;AACzD,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,KAAK,WAAW,CAAC;AAEtE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;CAC/C;AAED,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,EAAE,iBACS,CAAC;AAE1C,MAAM,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC;AAE5C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;CACzC;AAED,eAAO,MAAM,qBAAqB,EAAE,cACe,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC;AAE9D,eAAO,MAAM,sBAAsB,GAAI,UAAU,QAAQ,KAAG,YACR,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,UAAU,EAChB,MAAM,aAAa,CAAC,MAAM,CAAC,KAC1B,UAWF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,WAAW,MAAM,EACjB,GAAG,UAAU,KACZ,UAMF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,YAAY,EAClB,MAAM,aAAa,CAAC,MAAM,CAAC,KAC1B,EAUF,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,aAAa,8fAAiD,CAAC;AAC5E,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAEtD,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IAErC,QAAQ,CAAC,OAAO,EAAE,CAChB,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,aAAa,KACzB;QACH,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;QAC3B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;KACjC,CAAC;IAEF,QAAQ,CAAC,OAAO,EAAE,CAChB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,UAAU,KACd,MAAM,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,6BAA6B,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,oBAAoB,KACzB,eAyBF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,cAAc,KAAG,cAO1D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,cAAc,KAAG,cAE3D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C"}
1
+ {"version":3,"file":"Crypto.d.ts","sourceRoot":"","sources":["../../src/Crypto.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAW,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAiB,cAAc,EAAc,MAAM,WAAW,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,MAAM,CAAC,WAAW,EAAE,EAAE,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,WAAW,EAAE,EAAE,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,WAAW,EAAE,EAAE,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;CACnC;AAED,QAAA,MAAM,OAAO,uVAA+B,CAAC;AAC7C,KAAK,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAC;AAEnC,eAAO,MAAM,SAAS,mbAAsB,CAAC;AAC7C,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;AAE9C,eAAO,MAAM,SAAS,mbAAsB,CAAC;AAC7C,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;AAE9C,eAAO,MAAM,SAAS,mbAAsB,CAAC;AAC7C,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;AAE9C,eAAO,MAAM,iBAAiB,QAAO,WAEnC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,EACvC,MAAM,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,KACnC,SAaF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAC3B,OAAO,MAAM,EACb,YAAY,SAAS,KACpB,SAMF,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,aAAa,2qBAAoC,CAAC;AAC/D,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAEtD,8BAA8B;AAC9B,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IAErC,QAAQ,CAAC,OAAO,EAAE,CAChB,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,aAAa,KACzB;QACH,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;QAC3B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;KACjC,CAAC;IAEF,QAAQ,CAAC,OAAO,EAAE,CAChB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,aAAa,EAC5B,KAAK,EAAE,UAAU,KACd,MAAM,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,6BAA6B,CAAC;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,cAAc,KACnB,eAyBF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,cAAc,KAAG,cAO1D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,cAAc,KAAG,cAE3D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;CAC3C"}
@@ -3,80 +3,57 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { xchacha20poly1305 } from "@noble/ciphers/chacha";
7
- import { hmac } from "@noble/hashes/hmac";
8
- import { sha512 } from "@noble/hashes/sha2";
9
- import { randomBytes } from "@noble/hashes/utils";
10
- import * as bip39 from "@scure/bip39";
11
- import { wordlist } from "@scure/bip39/wordlists/english";
12
- import { urlAlphabet } from "nanoid";
13
- import { getOrThrow, trySync } from "./Result.js";
14
- import { brand, length, NonNegativeInt, Uint8Array, } from "./Type.js";
15
- import { assert } from "./Assert.js";
16
- import { utf8ToBytes } from "./Buffer.js";
17
- /** Cryptographically secure PRNG. Uses internal OS-level crypto.getRandomValues. */
18
- export const createRandomBytes = (bytesLength = 32) => randomBytes(bytesLength);
19
- export const createEnglishMnemonic = () => bip39.generateMnemonic(wordlist, 128);
20
- export const mnemonicToMnemonicSeed = (mnemonic) => bip39.mnemonicToSeedSync(mnemonic);
6
+ import { xchacha20poly1305 } from "@noble/ciphers/chacha.js";
7
+ import { hmac } from "@noble/hashes/hmac.js";
8
+ import { sha512 } from "@noble/hashes/sha2.js";
9
+ import { randomBytes, utf8ToBytes } from "@noble/hashes/utils.js";
10
+ import { trySync } from "./Result.js";
11
+ import { brand, length, NonNegativeInt, Uint8Array } from "./Type.js";
12
+ const Entropy = brand("Entropy", Uint8Array);
13
+ export const Entropy16 = length(16)(Entropy);
14
+ export const Entropy32 = length(32)(Entropy);
15
+ export const Entropy64 = length(64)(Entropy);
16
+ export const createRandomBytes = () => ({
17
+ create: randomBytes,
18
+ });
21
19
  /**
22
20
  * SLIP21.
23
21
  *
24
22
  * https://github.com/satoshilabs/slips/blob/master/slip-0021.md
25
23
  */
26
24
  export const createSlip21 = (seed, path) => {
27
- assert(seed.length >= 16 && seed.length <= 64, `Unusual SLIP-0021 seed length: ${seed.length} bytes`);
28
- let m = hmac(sha512, utf8ToBytes("Symmetric key seed"), seed);
29
- for (const component of path) {
30
- m = deriveSlip21Node(component, m);
25
+ let currentNode = hmac(sha512, utf8ToBytes("Symmetric key seed"), seed);
26
+ for (const element of path) {
27
+ const label = typeof element === "number" ? element.toString() : element;
28
+ currentNode = deriveSlip21Node(label, currentNode);
31
29
  }
32
- return m.slice(32, 64);
30
+ return currentNode.slice(32, 64);
33
31
  };
34
32
  /**
35
33
  * Derives a single node in the SLIP-21 hierarchical key derivation.
36
34
  *
37
35
  * @see {@link createSlip21}
38
36
  */
39
- export const deriveSlip21Node = (component, m) => {
40
- const p = utf8ToBytes(component);
41
- const e = new globalThis.Uint8Array(p.byteLength + 1);
42
- e[0] = 0;
43
- e.set(p, 1);
44
- return hmac(sha512, m.slice(0, 32), e);
45
- };
46
- /**
47
- * Creates a 21-character Base64URL ID (also known as nanoid) from a SLIP-21
48
- * derived key.
49
- *
50
- * Reduces the 256-bit SLIP-21 output to 126 bits (21 chars × 6 bits) for a
51
- * compact, human-readable, and shareable identifier suitable for UI display or
52
- * URL use. While this lowers entropy, 126 bits remains cryptographically secure
53
- * for uniqueness and unpredictability in most applications (comparable to
54
- * UUIDv4's 122 bits).
55
- *
56
- * See https://github.com/satoshilabs/slips/blob/master/slip-0021.md
57
- */
58
- export const createSlip21Id = (seed, path) => {
59
- const slip21 = createSlip21(seed, path);
60
- let id = "";
61
- // Convert the key to the Id/NanoId/Base64Url format.
62
- for (let i = 0; i < 21; i++) {
63
- id = (id + urlAlphabet[slip21[i] & 63]);
64
- }
65
- return id;
37
+ export const deriveSlip21Node = (label, parentNode) => {
38
+ const labelBytes = utf8ToBytes(label);
39
+ const message = new globalThis.Uint8Array(labelBytes.byteLength + 1);
40
+ message[0] = 0;
41
+ message.set(labelBytes, 1);
42
+ return hmac(sha512, parentNode.slice(0, 32), message);
66
43
  };
67
44
  /** The encryption key for {@link SymmetricCrypto}. */
68
- export const EncryptionKey = brand("EncryptionKey", length(32)(Uint8Array));
45
+ export const EncryptionKey = brand("EncryptionKey", Entropy32);
69
46
  /**
70
47
  * XChaCha20-Poly1305 encryption
71
48
  *
72
49
  * https://github.com/paulmillr/noble-ciphers?tab=readme-ov-file#which-cipher-should-i-pick
73
50
  */
74
51
  export const createSymmetricCrypto = (deps) => {
75
- const nonceLength = getOrThrow(NonNegativeInt.from(24));
52
+ const nonceLength = NonNegativeInt.orThrow(24);
76
53
  const symmetricCrypto = {
77
54
  nonceLength,
78
55
  encrypt: (plaintext, encryptionKey) => {
79
- const nonce = deps.createRandomBytes(nonceLength);
56
+ const nonce = deps.randomBytes.create(nonceLength);
80
57
  const ciphertext = xchacha20poly1305(encryptionKey, nonce).encrypt(plaintext);
81
58
  return { nonce, ciphertext };
82
59
  },