@evolu/common 6.0.1-preview.3 → 6.0.1-preview.30

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 (173) hide show
  1. package/dist/src/Array.d.ts +58 -5
  2. package/dist/src/Array.d.ts.map +1 -1
  3. package/dist/src/Array.js +53 -5
  4. package/dist/src/Assert.d.ts +6 -16
  5. package/dist/src/Assert.d.ts.map +1 -1
  6. package/dist/src/Assert.js +6 -18
  7. package/dist/src/Brand.d.ts +75 -0
  8. package/dist/src/Brand.d.ts.map +1 -0
  9. package/dist/src/Brand.js +1 -0
  10. package/dist/src/Buffer.d.ts +1 -1
  11. package/dist/src/Buffer.d.ts.map +1 -1
  12. package/dist/src/Buffer.js +8 -7
  13. package/dist/src/Cache.d.ts +44 -0
  14. package/dist/src/Cache.d.ts.map +1 -0
  15. package/dist/src/Cache.js +52 -0
  16. package/dist/src/Callbacks.d.ts +45 -12
  17. package/dist/src/Callbacks.d.ts.map +1 -1
  18. package/dist/src/Callbacks.js +14 -7
  19. package/dist/src/Console.d.ts +31 -6
  20. package/dist/src/Console.d.ts.map +1 -1
  21. package/dist/src/Console.js +72 -9
  22. package/dist/src/Crypto.d.ts +61 -34
  23. package/dist/src/Crypto.d.ts.map +1 -1
  24. package/dist/src/Crypto.js +32 -45
  25. package/dist/src/Evolu/Db.d.ts +158 -65
  26. package/dist/src/Evolu/Db.d.ts.map +1 -1
  27. package/dist/src/Evolu/Db.js +286 -694
  28. package/dist/src/Evolu/Diff.d.ts +3 -3
  29. package/dist/src/Evolu/Diff.d.ts.map +1 -1
  30. package/dist/src/Evolu/Diff.js +7 -5
  31. package/dist/src/Evolu/Evolu.d.ts +208 -133
  32. package/dist/src/Evolu/Evolu.d.ts.map +1 -1
  33. package/dist/src/Evolu/Evolu.js +188 -183
  34. package/dist/src/Evolu/Internal.d.ts +0 -2
  35. package/dist/src/Evolu/Internal.d.ts.map +1 -1
  36. package/dist/src/Evolu/Internal.js +0 -2
  37. package/dist/src/Evolu/LocalAuth.d.ts +150 -0
  38. package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
  39. package/dist/src/Evolu/LocalAuth.js +174 -0
  40. package/dist/src/Evolu/Owner.d.ts +264 -120
  41. package/dist/src/Evolu/Owner.d.ts.map +1 -1
  42. package/dist/src/Evolu/Owner.js +130 -104
  43. package/dist/src/Evolu/Platform.d.ts +9 -7
  44. package/dist/src/Evolu/Platform.d.ts.map +1 -1
  45. package/dist/src/Evolu/Protocol.d.ts +277 -232
  46. package/dist/src/Evolu/Protocol.d.ts.map +1 -1
  47. package/dist/src/Evolu/Protocol.js +603 -378
  48. package/dist/src/Evolu/Public.d.ts +6 -8
  49. package/dist/src/Evolu/Public.d.ts.map +1 -1
  50. package/dist/src/Evolu/Public.js +2 -3
  51. package/dist/src/Evolu/PublicKysely.js +3 -3
  52. package/dist/src/Evolu/Query.d.ts +2 -1
  53. package/dist/src/Evolu/Query.d.ts.map +1 -1
  54. package/dist/src/Evolu/Relay.d.ts +92 -7
  55. package/dist/src/Evolu/Relay.d.ts.map +1 -1
  56. package/dist/src/Evolu/Relay.js +243 -76
  57. package/dist/src/Evolu/Schema.d.ts +129 -73
  58. package/dist/src/Evolu/Schema.d.ts.map +1 -1
  59. package/dist/src/Evolu/Schema.js +169 -89
  60. package/dist/src/Evolu/Storage.d.ts +212 -26
  61. package/dist/src/Evolu/Storage.d.ts.map +1 -1
  62. package/dist/src/Evolu/Storage.js +137 -79
  63. package/dist/src/Evolu/Sync.d.ts +68 -13
  64. package/dist/src/Evolu/Sync.d.ts.map +1 -1
  65. package/dist/src/Evolu/Sync.js +422 -20
  66. package/dist/src/Evolu/Timestamp.d.ts +85 -27
  67. package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
  68. package/dist/src/Evolu/Timestamp.js +77 -18
  69. package/dist/src/Identicon.d.ts +35 -0
  70. package/dist/src/Identicon.d.ts.map +1 -0
  71. package/dist/src/Identicon.js +143 -0
  72. package/dist/src/Instances.d.ts +34 -0
  73. package/dist/src/Instances.d.ts.map +1 -0
  74. package/dist/src/Instances.js +44 -0
  75. package/dist/src/ManyToManyMap.d.ts +71 -10
  76. package/dist/src/ManyToManyMap.d.ts.map +1 -1
  77. package/dist/src/ManyToManyMap.js +41 -6
  78. package/dist/src/Number.d.ts +4 -3
  79. package/dist/src/Number.d.ts.map +1 -1
  80. package/dist/src/Number.js +5 -4
  81. package/dist/src/Platform.d.ts +20 -0
  82. package/dist/src/Platform.d.ts.map +1 -0
  83. package/dist/src/Platform.js +22 -0
  84. package/dist/src/Random.d.ts +3 -2
  85. package/dist/src/Random.d.ts.map +1 -1
  86. package/dist/src/Resources.d.ts +118 -0
  87. package/dist/src/Resources.d.ts.map +1 -0
  88. package/dist/src/Resources.js +197 -0
  89. package/dist/src/Result.d.ts +184 -52
  90. package/dist/src/Result.d.ts.map +1 -1
  91. package/dist/src/Result.js +30 -241
  92. package/dist/src/Skiplist.js +2 -1
  93. package/dist/src/Sqlite.d.ts +63 -5
  94. package/dist/src/Sqlite.d.ts.map +1 -1
  95. package/dist/src/Sqlite.js +110 -9
  96. package/dist/src/Task.d.ts +586 -0
  97. package/dist/src/Task.d.ts.map +1 -0
  98. package/dist/src/Task.js +469 -0
  99. package/dist/src/Time.d.ts +66 -1
  100. package/dist/src/Time.d.ts.map +1 -1
  101. package/dist/src/Time.js +99 -5
  102. package/dist/src/Type.d.ts +621 -340
  103. package/dist/src/Type.d.ts.map +1 -1
  104. package/dist/src/Type.js +665 -464
  105. package/dist/src/Types.d.ts +1 -75
  106. package/dist/src/Types.d.ts.map +1 -1
  107. package/dist/src/WebSocket.d.ts +5 -2
  108. package/dist/src/WebSocket.d.ts.map +1 -1
  109. package/dist/src/WebSocket.js +12 -18
  110. package/dist/src/Worker.d.ts +39 -11
  111. package/dist/src/Worker.d.ts.map +1 -1
  112. package/dist/src/Worker.js +22 -4
  113. package/dist/src/index.d.ts +7 -2
  114. package/dist/src/index.d.ts.map +1 -1
  115. package/dist/src/index.js +7 -2
  116. package/package.json +14 -13
  117. package/src/Array.ts +76 -11
  118. package/src/Assert.ts +6 -24
  119. package/src/Brand.ts +75 -0
  120. package/src/Buffer.ts +7 -7
  121. package/src/Cache.ts +85 -0
  122. package/src/Callbacks.ts +62 -22
  123. package/src/Console.ts +91 -11
  124. package/src/Crypto.ts +97 -82
  125. package/src/Evolu/Db.ts +514 -1020
  126. package/src/Evolu/Diff.ts +7 -5
  127. package/src/Evolu/Evolu.ts +464 -355
  128. package/src/Evolu/Internal.ts +0 -2
  129. package/src/Evolu/LocalAuth.ts +463 -0
  130. package/src/Evolu/Owner.ts +369 -228
  131. package/src/Evolu/Platform.ts +9 -9
  132. package/src/Evolu/Protocol.ts +859 -676
  133. package/src/Evolu/Public.ts +7 -14
  134. package/src/Evolu/PublicKysely.ts +3 -3
  135. package/src/Evolu/Query.ts +2 -1
  136. package/src/Evolu/Relay.ts +420 -92
  137. package/src/Evolu/Schema.ts +391 -191
  138. package/src/Evolu/Storage.ts +451 -118
  139. package/src/Evolu/Sync.ts +720 -37
  140. package/src/Evolu/Timestamp.ts +88 -35
  141. package/src/Identicon.ts +197 -0
  142. package/src/Instances.ts +90 -0
  143. package/src/ManyToManyMap.ts +124 -24
  144. package/src/Number.ts +6 -10
  145. package/src/Platform.ts +26 -0
  146. package/src/Random.ts +3 -2
  147. package/src/Resources.ts +367 -0
  148. package/src/Result.ts +191 -54
  149. package/src/Skiplist.ts +1 -1
  150. package/src/Sqlite.ts +122 -17
  151. package/src/Task.ts +901 -0
  152. package/src/Time.ts +180 -5
  153. package/src/Type.ts +1083 -727
  154. package/src/Types.ts +1 -77
  155. package/src/WebSocket.ts +27 -25
  156. package/src/Worker.ts +72 -23
  157. package/src/index.ts +7 -2
  158. package/dist/src/Evolu/Config.d.ts +0 -69
  159. package/dist/src/Evolu/Config.d.ts.map +0 -1
  160. package/dist/src/Evolu/Config.js +0 -9
  161. package/dist/src/Evolu/Kysely.d.ts +0 -6
  162. package/dist/src/Evolu/Kysely.d.ts.map +0 -1
  163. package/dist/src/Evolu/Kysely.js +0 -21
  164. package/dist/src/NanoId.d.ts +0 -27
  165. package/dist/src/NanoId.d.ts.map +0 -1
  166. package/dist/src/NanoId.js +0 -6
  167. package/dist/src/Promise.d.ts +0 -180
  168. package/dist/src/Promise.d.ts.map +0 -1
  169. package/dist/src/Promise.js +0 -176
  170. package/src/Evolu/Config.ts +0 -83
  171. package/src/Evolu/Kysely.ts +0 -38
  172. package/src/NanoId.ts +0 -39
  173. package/src/Promise.ts +0 -295
@@ -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,49 +1,64 @@
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 "./Types.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: MnemonicSeed, path: ReadonlyArray<string>) => Uint8Array;
52
+ export declare const createSlip21: (seed: Entropy16 | Entropy32 | Entropy64, path: ReadonlyArray<string | number>) => Entropy32;
30
53
  /**
31
- * Creates a 21-character Base64URL ID (also known as nanoid) from a SLIP-21
32
- * derived key.
33
- *
34
- * Reduces the 256-bit SLIP-21 output to 126 bits (21 chars × 6 bits) for a
35
- * compact, human-readable, and shareable identifier suitable for UI display or
36
- * URL use. While this lowers entropy, 126 bits remains cryptographically secure
37
- * for uniqueness and unpredictability in most applications (comparable to
38
- * UUIDv4's 122 bits).
54
+ * Derives a single node in the SLIP-21 hierarchical key derivation.
39
55
  *
40
- * See https://github.com/satoshilabs/slips/blob/master/slip-0021.md
56
+ * @see {@link createSlip21}
41
57
  */
42
- export declare const createSlip21Id: (seed: MnemonicSeed, path: ReadonlyArray<string>) => Id;
58
+ export declare const deriveSlip21Node: (label: string, parentNode: Entropy64) => Entropy64;
43
59
  /** The encryption key for {@link SymmetricCrypto}. */
44
- 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>;
45
61
  export type EncryptionKey = typeof EncryptionKey.Type;
46
- export declare const createEncryptionKey: (seed: MnemonicSeed) => EncryptionKey;
47
62
  /** Symmetric cryptography. */
48
63
  export interface SymmetricCrypto {
49
64
  readonly nonceLength: NonNegativeInt;
@@ -65,7 +80,7 @@ export interface SymmetricCryptoDecryptError {
65
80
  *
66
81
  * https://github.com/paulmillr/noble-ciphers?tab=readme-ov-file#which-cipher-should-i-pick
67
82
  */
68
- export declare const createSymmetricCrypto: (deps: CreateRandomBytesDep) => SymmetricCrypto;
83
+ export declare const createSymmetricCrypto: (deps: RandomBytesDep) => SymmetricCrypto;
69
84
  /**
70
85
  * Returns the PADMÉ padded length for a given input length.
71
86
  *
@@ -79,4 +94,16 @@ export declare const padmePaddedLength: (length: NonNegativeInt) => NonNegativeI
79
94
  * {@link padmePaddedLength}.
80
95
  */
81
96
  export declare const padmePaddingLength: (length: NonNegativeInt) => NonNegativeInt;
97
+ /**
98
+ * Performs a timing-safe comparison of two Uint8Arrays. Returns true if they
99
+ * are equal, false otherwise. Takes constant time regardless of where the
100
+ * arrays differ.
101
+ *
102
+ * @see https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b
103
+ */
104
+ export type TimingSafeEqual = (a: Uint8Array, b: Uint8Array) => boolean;
105
+ export interface TimingSafeEqualDep {
106
+ readonly timingSafeEqual: TimingSafeEqual;
107
+ }
108
+ export {};
82
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;AAEnC,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,YAAY,EAClB,MAAM,aAAa,CAAC,MAAM,CAAC,KAC1B,UAUF,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,eAAO,MAAM,mBAAmB,GAAI,MAAM,YAAY,KAAG,aACS,CAAC;AAEnE,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;AAEH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,cAAc,KAAG,cAE3D,CAAC"}
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,70 +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
- /** Cryptographically secure PRNG. Uses internal OS-level crypto.getRandomValues. */
16
- export const createRandomBytes = (bytesLength = 32) => randomBytes(bytesLength);
17
- export const createEnglishMnemonic = () => bip39.generateMnemonic(wordlist, 128);
18
- 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
+ });
19
19
  /**
20
20
  * SLIP21.
21
21
  *
22
22
  * https://github.com/satoshilabs/slips/blob/master/slip-0021.md
23
23
  */
24
24
  export const createSlip21 = (seed, path) => {
25
- let m = hmac(sha512, "Symmetric key seed", seed);
26
- for (const component of path) {
27
- const p = new TextEncoder().encode(component);
28
- const e = new globalThis.Uint8Array(p.byteLength + 1);
29
- e[0] = 0;
30
- e.set(p, 1);
31
- m = hmac(sha512, m.slice(0, 32), e);
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);
32
29
  }
33
- return m.slice(32, 64);
30
+ return currentNode.slice(32, 64);
34
31
  };
35
32
  /**
36
- * Creates a 21-character Base64URL ID (also known as nanoid) from a SLIP-21
37
- * derived key.
33
+ * Derives a single node in the SLIP-21 hierarchical key derivation.
38
34
  *
39
- * Reduces the 256-bit SLIP-21 output to 126 bits (21 chars × 6 bits) for a
40
- * compact, human-readable, and shareable identifier suitable for UI display or
41
- * URL use. While this lowers entropy, 126 bits remains cryptographically secure
42
- * for uniqueness and unpredictability in most applications (comparable to
43
- * UUIDv4's 122 bits).
44
- *
45
- * See https://github.com/satoshilabs/slips/blob/master/slip-0021.md
35
+ * @see {@link createSlip21}
46
36
  */
47
- export const createSlip21Id = (seed, path) => {
48
- const slip21 = createSlip21(seed, path);
49
- let id = "";
50
- // Convert the key to the Id/NanoId/Base64Url format.
51
- for (let i = 0; i < 21; i++) {
52
- id = (id + urlAlphabet[slip21[i] & 63]);
53
- }
54
- 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);
55
43
  };
56
44
  /** The encryption key for {@link SymmetricCrypto}. */
57
- export const EncryptionKey = brand("EncryptionKey", length(32)(Uint8Array));
58
- export const createEncryptionKey = (seed) => createSlip21(seed, ["Evolu", "Encryption Key"]);
45
+ export const EncryptionKey = brand("EncryptionKey", Entropy32);
59
46
  /**
60
47
  * XChaCha20-Poly1305 encryption
61
48
  *
62
49
  * https://github.com/paulmillr/noble-ciphers?tab=readme-ov-file#which-cipher-should-i-pick
63
50
  */
64
51
  export const createSymmetricCrypto = (deps) => {
65
- const nonceLength = getOrThrow(NonNegativeInt.from(24));
52
+ const nonceLength = NonNegativeInt.orThrow(24);
66
53
  const symmetricCrypto = {
67
54
  nonceLength,
68
55
  encrypt: (plaintext, encryptionKey) => {
69
- const nonce = deps.createRandomBytes(nonceLength);
56
+ const nonce = deps.randomBytes.create(nonceLength);
70
57
  const ciphertext = xchacha20poly1305(encryptionKey, nonce).encrypt(plaintext);
71
58
  return { nonce, ciphertext };
72
59
  },
@@ -86,17 +73,17 @@ export const createSymmetricCrypto = (deps) => {
86
73
  */
87
74
  export const padmePaddedLength = (length) => {
88
75
  if (length <= 0)
89
- return 0;
76
+ return NonNegativeInt.orThrow(0);
90
77
  const e = 31 - Math.clz32(length >>> 0);
91
78
  const s = 32 - Math.clz32(e >>> 0);
92
79
  const z = Math.max(0, e - s);
93
80
  const mask = (1 << z) - 1;
94
- return ((length + mask) & ~mask);
81
+ return NonNegativeInt.orThrow((length + mask) & ~mask);
95
82
  };
96
83
  /**
97
84
  * Returns the PADMÉ padding length for a given input length. Uses
98
85
  * {@link padmePaddedLength}.
99
86
  */
100
87
  export const padmePaddingLength = (length) => {
101
- return (padmePaddedLength(length) - length);
88
+ return NonNegativeInt.orThrow(padmePaddedLength(length) - length);
102
89
  };
@@ -1,37 +1,150 @@
1
1
  import { NonEmptyReadonlyArray } from "../Array.js";
2
2
  import { CallbackId } from "../Callbacks.js";
3
- import { ConsoleDep } from "../Console.js";
4
- import { CreateMnemonicDep, CreateRandomBytesDep, SymmetricCryptoDecryptError } from "../Crypto.js";
3
+ import { ConsoleConfig, ConsoleDep } from "../Console.js";
4
+ import { EncryptionKey, RandomBytesDep, SymmetricCryptoDecryptError } from "../Crypto.js";
5
5
  import { TransferableError } from "../Error.js";
6
- import { NanoIdLibDep } from "../NanoId.js";
7
6
  import { RandomDep } from "../Random.js";
8
- import { Ref } from "../Ref.js";
9
- import { Result } from "../Result.js";
10
- import { CreateSqliteDriverDep, SafeSql, SqliteDep, SqliteError, SqliteRow } from "../Sqlite.js";
7
+ import { CreateSqliteDriverDep, SqliteError } from "../Sqlite.js";
11
8
  import { TimeDep } from "../Time.js";
12
9
  import { Id, Mnemonic, SimpleName } from "../Type.js";
10
+ import { CreateWebSocketDep } from "../WebSocket.js";
13
11
  import { Worker } from "../Worker.js";
14
- import { Config } from "./Config.js";
15
12
  import { QueryPatches } from "./Diff.js";
16
- import { AppOwner, OwnerRow } from "./Owner.js";
17
- import { Base64Url256, BinaryOwnerId, CrdtMessage, DbChange, ProtocolError, Storage } from "./Protocol.js";
13
+ import { AppOwner, OwnerTransport } from "./Owner.js";
14
+ import { ProtocolError } from "./Protocol.js";
18
15
  import { Query } from "./Query.js";
19
- import { SqliteStorageBase } from "./Storage.js";
20
- import { CreateSyncDep } from "./Sync.js";
21
- import { Timestamp, TimestampError } from "./Timestamp.js";
22
- export interface DbSchema {
23
- readonly tables: ReadonlyArray<DbTable>;
24
- readonly indexes: ReadonlyArray<DbIndex>;
16
+ import { DbSchema, MutationChange } from "./Schema.js";
17
+ import { SyncOwner } from "./Sync.js";
18
+ import { TimestampConfig, TimestampError } from "./Timestamp.js";
19
+ export interface DbConfig extends ConsoleConfig, TimestampConfig {
20
+ /**
21
+ * The name of the Evolu instance. Evolu is multitenant - it can run multiple
22
+ * instances concurrently. Each instance must have a unique name.
23
+ *
24
+ * The instance name is used as the SQLite database filename for persistent
25
+ * storage, ensuring that database files are separated and invisible to each
26
+ * other.
27
+ *
28
+ * The default value is: `Evolu`.
29
+ *
30
+ * ### Example
31
+ *
32
+ * ```ts
33
+ * // name: SimpleName.orThrow("MyApp")
34
+ * ```
35
+ */
36
+ readonly name: SimpleName;
37
+ /**
38
+ * Transport configuration for data sync and backup. Supports single transport
39
+ * or multiple transports simultaneously for redundancy.
40
+ *
41
+ * **Redundancy:** The ideal setup uses at least two completely independent
42
+ * relays - for example, a home relay and a geographically separate relay.
43
+ * Data is sent to both relays simultaneously, providing true redundancy
44
+ * similar to using two independent clouds. This eliminates vendor lock-in and
45
+ * ensures your app continues working regardless of circumstances - whether
46
+ * home relay hardware is stolen or a remote relay provider shuts down.
47
+ *
48
+ * Currently supports:
49
+ *
50
+ * - WebSocket: Real-time bidirectional communication with relay servers
51
+ *
52
+ * Empty transports create local-only instances. Transports can be dynamically
53
+ * added and removed for any owner (including {@link AppOwner}) via
54
+ * {@link Evolu#useOwner}.
55
+ *
56
+ * Use {@link createOwnerWebSocketTransport} to create WebSocket transport
57
+ * configurations with proper URL formatting and {@link OwnerId} inclusion. The
58
+ * {@link OwnerId} in the URL enables relay authentication, allowing relay
59
+ * servers to control access (e.g., for paid tiers or private instances).
60
+ *
61
+ * The default value is:
62
+ *
63
+ * `{ type: "WebSocket", url: "wss://free.evoluhq.com" }`.
64
+ *
65
+ * ### Example
66
+ *
67
+ * ```ts
68
+ * // Single WebSocket relay
69
+ * transports: [{ type: "WebSocket", url: "wss://relay1.example.com" }];
70
+ *
71
+ * // Multiple WebSocket relays for redundancy
72
+ * transports: [
73
+ * { type: "WebSocket", url: "wss://relay1.example.com" },
74
+ * { type: "WebSocket", url: "wss://relay2.example.com" },
75
+ * { type: "WebSocket", url: "wss://relay3.example.com" },
76
+ * ];
77
+ *
78
+ * // Local-only instance (no sync) - useful for device settings or when relay
79
+ * // URL will be provided later (e.g., after authentication), allowing users
80
+ * // to work offline before the app connects
81
+ * transports: [];
82
+ *
83
+ * // Using createOwnerWebSocketTransport helper for relay authentication
84
+ * transports: [
85
+ * createOwnerWebSocketTransport({
86
+ * url: "ws://localhost:4000",
87
+ * ownerId,
88
+ * }),
89
+ * ];
90
+ * ```
91
+ */
92
+ readonly transports: ReadonlyArray<OwnerTransport>;
93
+ /**
94
+ * External AppOwner to use when creating Evolu instance. Use this when you
95
+ * want to manage AppOwner creation and persistence externally (e.g., with
96
+ * your own authentication system). If omitted, Evolu will automatically
97
+ * create and persist an AppOwner locally.
98
+ *
99
+ * For device-specific settings and account management state, we can use a
100
+ * separate local-only Evolu instance via `transports: []`.
101
+ *
102
+ * ### Example
103
+ *
104
+ * ```ts
105
+ * const ConfigId = id("Config");
106
+ * type ConfigId = typeof ConfigId.Type;
107
+ *
108
+ * const DeviceSchema = {
109
+ * config: {
110
+ * id: ConfigId,
111
+ * key: NonEmptyString50,
112
+ * value: NonEmptyString50,
113
+ * },
114
+ * };
115
+ *
116
+ * // Local-only instance for device settings (no sync)
117
+ * const deviceEvolu = createEvolu(evoluReactWebDeps)(DeviceSchema, {
118
+ * name: SimpleName.orThrow("MyApp-Device"),
119
+ * transports: [], // No sync - stays local to device
120
+ * });
121
+ *
122
+ * // Main synced instance for user data
123
+ * const evolu = createEvolu(evoluReactWebDeps)(MainSchema, {
124
+ * name: SimpleName.orThrow("MyApp"),
125
+ * // Default transports for sync
126
+ * });
127
+ * ```
128
+ */
129
+ readonly externalAppOwner?: AppOwner;
130
+ /**
131
+ * Use in-memory SQLite database instead of persistent storage. Useful for
132
+ * testing or temporary data that doesn't need persistence.
133
+ *
134
+ * In-memory databases exist only in RAM and are completely destroyed when the
135
+ * process ends, making them forensically safe for sensitive data.
136
+ *
137
+ * The default value is: `false`.
138
+ */
139
+ readonly inMemory?: boolean;
140
+ /**
141
+ * Encryption key for the SQLite database.
142
+ *
143
+ * @experimental
144
+ */
145
+ readonly encryptionKey?: EncryptionKey;
25
146
  }
26
- export interface DbTable {
27
- readonly name: Base64Url256;
28
- readonly columns: ReadonlyArray<Base64Url256>;
29
- }
30
- export declare const DbIndex: import("../Type.js").ObjectType<{
31
- name: import("../Type.js").Type<"String", string, string, import("../Type.js").StringError, string, import("../Type.js").StringError>;
32
- sql: import("../Type.js").Type<"String", string, string, import("../Type.js").StringError, string, import("../Type.js").StringError>;
33
- }>;
34
- export type DbIndex = typeof DbIndex.Type;
147
+ export declare const defaultDbConfig: DbConfig;
35
148
  export type DbWorker = Worker<DbWorkerInput, DbWorkerOutput>;
36
149
  export type CreateDbWorker = (name: SimpleName) => DbWorker;
37
150
  export interface CreateDbWorkerDep {
@@ -39,13 +152,14 @@ export interface CreateDbWorkerDep {
39
152
  }
40
153
  export type DbWorkerInput = {
41
154
  readonly type: "init";
42
- readonly config: Config;
155
+ readonly config: DbConfig;
43
156
  readonly dbSchema: DbSchema;
44
- readonly initialData: ReadonlyArray<DbChange>;
157
+ } | {
158
+ readonly type: "getAppOwner";
45
159
  } | {
46
160
  readonly type: "mutate";
47
161
  readonly tabId: Id;
48
- readonly changes: NonEmptyReadonlyArray<DbChange>;
162
+ readonly changes: NonEmptyReadonlyArray<MutationChange>;
49
163
  readonly onCompleteIds: ReadonlyArray<CallbackId>;
50
164
  readonly subscribedQueries: ReadonlyArray<Query>;
51
165
  } | {
@@ -66,20 +180,24 @@ export type DbWorkerInput = {
66
180
  } | {
67
181
  readonly type: "export";
68
182
  readonly onCompleteId: CallbackId;
183
+ } | {
184
+ readonly type: "useOwner";
185
+ readonly use: boolean;
186
+ readonly owner: SyncOwner;
69
187
  };
70
188
  export type DbWorkerOutput = {
71
- readonly type: "onInit";
72
- readonly owner: AppOwner;
73
- } | {
74
189
  readonly type: "onError";
75
- readonly error: SqliteError | TransferableError | TimestampError | ProtocolError | SymmetricCryptoDecryptError;
190
+ readonly error: ProtocolError | SqliteError | SymmetricCryptoDecryptError | TimestampError | TransferableError;
191
+ } | {
192
+ readonly type: "onGetAppOwner";
193
+ readonly appOwner: AppOwner;
76
194
  } | {
77
- readonly type: "onChange";
195
+ readonly type: "onQueryPatches";
78
196
  readonly tabId: Id;
79
- readonly patches: ReadonlyArray<QueryPatches>;
197
+ readonly queryPatches: ReadonlyArray<QueryPatches>;
80
198
  readonly onCompleteIds: ReadonlyArray<CallbackId>;
81
199
  } | {
82
- readonly type: "onReceive";
200
+ readonly type: "refreshQueries";
83
201
  readonly tabId?: Id;
84
202
  } | {
85
203
  readonly type: "onReset";
@@ -90,37 +208,12 @@ export type DbWorkerOutput = {
90
208
  readonly onCompleteId: CallbackId;
91
209
  readonly file: Uint8Array;
92
210
  };
93
- export type DbWorkerPlatformDeps = CreateSqliteDriverDep & CreateSyncDep & ConsoleDep & TimeDep & RandomDep & NanoIdLibDep & CreateMnemonicDep & CreateRandomBytesDep;
94
- export interface OwnerRowRefDep {
95
- readonly ownerRowRef: Ref<OwnerRow>;
211
+ export type DbWorkerPlatformDeps = ConsoleDep & CreateSqliteDriverDep & CreateWebSocketDep & RandomBytesDep & RandomDep & TimeDep;
212
+ export interface PostMessageDep {
213
+ readonly postMessage: (message: DbWorkerOutput) => void;
96
214
  }
97
- export declare const createDbWorkerForPlatform: (platformDeps: DbWorkerPlatformDeps) => DbWorker;
98
- /**
99
- * Get the current database schema by reading SQLite metadata.
100
- *
101
- * TODO: Refactor out Evolu stuff and move it to Sqlite.
102
- */
103
- export declare const getDbSchema: (deps: SqliteDep) => ({ allIndexes }?: {
104
- allIndexes?: boolean;
105
- }) => Result<DbSchema, SqliteError>;
106
- export interface DbSnapshot {
107
- readonly schema: DbSchema;
108
- readonly tables: Array<{
109
- name: string;
110
- rows: ReadonlyArray<SqliteRow>;
111
- }>;
112
- }
113
- export declare const getDbSnapshot: (deps: SqliteDep) => DbSnapshot;
114
- export declare const createAppTable: (tableName: string, columns: ReadonlyArray<string>) => SafeSql;
115
- export declare const applyMessageToTimestampAndHistoryTables: (deps: SqliteDep & ClientStorageDep) => (ownerId: BinaryOwnerId, message: CrdtMessage) => Result<void, SqliteError>;
116
- export declare const maybeMigrateToVersion0: (deps: SqliteDep) => (schema: DbSchema) => Result<{
117
- readonly messages: ReadonlyArray<CrdtMessage>;
118
- readonly mnemonic: Mnemonic;
119
- readonly lastTimestamp: Timestamp;
120
- } | null, SqliteError>;
121
- export interface ClientStorage extends SqliteStorageBase, Storage {
122
- }
123
- export interface ClientStorageDep {
124
- readonly storage: ClientStorage;
215
+ export interface AppOwnerDep {
216
+ readonly appOwner: AppOwner;
125
217
  }
218
+ export declare const createDbWorkerForPlatform: (platformDeps: DbWorkerPlatformDeps) => DbWorker;
126
219
  //# sourceMappingURL=Db.d.ts.map