@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,8 +1,10 @@
1
+ import { Brand } from "./Brand.js";
1
2
  import { ConsoleDep } from "./Console.js";
3
+ import { EncryptionKey } from "./Crypto.js";
2
4
  import { TransferableError } from "./Error.js";
3
5
  import { Result } from "./Result.js";
4
6
  import { SimpleName } from "./Type.js";
5
- import { Brand, Predicate } from "./Types.js";
7
+ import { Predicate } from "./Types.js";
6
8
  /**
7
9
  * SQLite driver interface. This is the minimal interface that platform-specific
8
10
  * drivers must implement.
@@ -17,6 +19,7 @@ export interface CreateSqliteDriverDep {
17
19
  }
18
20
  export interface SqliteDriverOptions {
19
21
  memory?: boolean;
22
+ encryptionKey?: EncryptionKey | undefined;
20
23
  }
21
24
  /**
22
25
  * Cross-platform SQLite abstraction.
@@ -108,13 +111,54 @@ export interface RawSql {
108
111
  sql: string;
109
112
  }
110
113
  export type SqlTemplateParam = SqliteValue | SqlIdentifier | RawSql;
111
- /** TODO: Docs. */
114
+ /**
115
+ * Creates a safe SQL query using a tagged template literal.
116
+ *
117
+ * Parameters are automatically escaped and bound as SQLite values. Use
118
+ * `sql.identifier` for column/table names and `sql.raw` for unescaped SQL.
119
+ *
120
+ * ### Example
121
+ *
122
+ * ```ts
123
+ * const id = 42;
124
+ * const name = "Alice";
125
+ *
126
+ * const result = sqlite.exec(sql`
127
+ * select *
128
+ * from users
129
+ * where id = ${id} and name = ${name};
130
+ * `);
131
+ *
132
+ * // For identifiers
133
+ * const tableName = "users";
134
+ * sqlite.exec(sql`
135
+ * create table ${sql.identifier(tableName)} (
136
+ * "id" text primary key,
137
+ * "name" text not null
138
+ * );
139
+ * `);
140
+ *
141
+ * // For raw SQL (use with caution)
142
+ * const orderBy = "created_at desc";
143
+ * sqlite.exec(sql`select * from users order by ${sql.raw(orderBy)};`);
144
+ * ```
145
+ *
146
+ * ### TIP
147
+ *
148
+ * Use `prettier-plugin-sql-cst` for SQL formatting. Like Prettier for
149
+ * JavaScript, this plugin formats SQL expressions differently depending on
150
+ * their length.
151
+ */
112
152
  export declare const sql: {
113
153
  (strings: TemplateStringsArray, ...parameters: Array<SqlTemplateParam>): SqliteQuery;
114
154
  identifier(identifier: string): SqlIdentifier;
115
155
  raw(raw: string): RawSql;
116
156
  prepared(strings: TemplateStringsArray, ...parameters: Array<SqlTemplateParam>): SqliteQuery;
117
157
  };
158
+ /**
159
+ * Checks if a SQL string contains mutation keywords (insert, update, delete,
160
+ * etc.). Results are cached for performance.
161
+ */
118
162
  export declare const isSqlMutation: Predicate<string>;
119
163
  export interface SqliteQueryPlanRow {
120
164
  id: number;
@@ -124,11 +168,25 @@ export interface SqliteQueryPlanRow {
124
168
  export declare const explainSqliteQueryPlan: (deps: SqliteDep) => (query: SqliteQuery) => Result<void, SqliteError>;
125
169
  /**
126
170
  * SQLite represents boolean values using `0` (false) and `1` (true) instead of
127
- * a dedicated boolean type. This transform Type ensures that values conform to
128
- * SQLite's boolean representation.
171
+ * a dedicated boolean type.
172
+ *
173
+ * Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
174
+ * readability.
129
175
  *
130
176
  * See: https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
131
177
  */
132
- export declare const SqliteBoolean: import("./Type.js").TransformType<import("./Type.js").Type<"Boolean", boolean, boolean, import("./Type.js").BooleanError, boolean, import("./Type.js").BooleanError>, import("./Type.js").UnionType<[import("./Type.js").LiteralType<0>, import("./Type.js").LiteralType<1>]>, never>;
178
+ export declare const SqliteBoolean: import("./Type.js").UnionType<[import("./Type.js").LiteralType<0>, import("./Type.js").LiteralType<1>]>;
133
179
  export type SqliteBoolean = typeof SqliteBoolean.Type;
180
+ /**
181
+ * Represents the {@link SqliteBoolean} value for `true`.
182
+ *
183
+ * See {@link SqliteBoolean}.
184
+ */
185
+ export declare const sqliteTrue = 1;
186
+ /**
187
+ * Represents the {@link SqliteBoolean} value for `false`.
188
+ *
189
+ * See {@link SqliteBoolean}.
190
+ */
191
+ export declare const sqliteFalse = 0;
134
192
  //# sourceMappingURL=Sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
+ import { createLruCache } from "./Cache.js";
1
2
  import { createTransferableError } from "./Error.js";
2
3
  import { err, ok, tryAsync, trySync } from "./Result.js";
3
- import { Boolean, Null, Number, String, transform, Uint8Array, union, } from "./Type.js";
4
+ import { Null, Number, PositiveInt, String, Uint8Array, union, } from "./Type.js";
4
5
  /**
5
6
  * A value that can be stored in Sqlite.
6
7
  *
@@ -21,9 +22,9 @@ export const createSqlite = (deps) => async (name, options) => tryAsync(async ()
21
22
  }, createSqliteError);
22
23
  const sqlite = {
23
24
  exec: (query) => trySync(() => {
24
- deps.console?.log("[sql]", query);
25
+ deps.console?.log("[sql]", { query });
25
26
  const result = maybeLogSqliteQueryExecutionTime(query, () => driver.exec(query, isSqlMutation(query.sql)));
26
- deps.console?.log("[sql]", result);
27
+ deps.console?.log("[sql]", { result });
27
28
  return result;
28
29
  }, (error) => ({
29
30
  type: "SqliteError",
@@ -121,7 +122,44 @@ export const createPreparedStatementsCache = (factory, disposeFn) => {
121
122
  },
122
123
  };
123
124
  };
124
- /** TODO: Docs. */
125
+ /**
126
+ * Creates a safe SQL query using a tagged template literal.
127
+ *
128
+ * Parameters are automatically escaped and bound as SQLite values. Use
129
+ * `sql.identifier` for column/table names and `sql.raw` for unescaped SQL.
130
+ *
131
+ * ### Example
132
+ *
133
+ * ```ts
134
+ * const id = 42;
135
+ * const name = "Alice";
136
+ *
137
+ * const result = sqlite.exec(sql`
138
+ * select *
139
+ * from users
140
+ * where id = ${id} and name = ${name};
141
+ * `);
142
+ *
143
+ * // For identifiers
144
+ * const tableName = "users";
145
+ * sqlite.exec(sql`
146
+ * create table ${sql.identifier(tableName)} (
147
+ * "id" text primary key,
148
+ * "name" text not null
149
+ * );
150
+ * `);
151
+ *
152
+ * // For raw SQL (use with caution)
153
+ * const orderBy = "created_at desc";
154
+ * sqlite.exec(sql`select * from users order by ${sql.raw(orderBy)};`);
155
+ * ```
156
+ *
157
+ * ### TIP
158
+ *
159
+ * Use `prettier-plugin-sql-cst` for SQL formatting. Like Prettier for
160
+ * JavaScript, this plugin formats SQL expressions differently depending on
161
+ * their length.
162
+ */
125
163
  export const sql = (strings, ...parameters) => {
126
164
  let sql = "";
127
165
  const values = [];
@@ -158,6 +196,25 @@ sql.prepared = (strings, ...parameters) => {
158
196
  const query = sql(strings, ...parameters);
159
197
  return { ...query, options: { prepare: true } };
160
198
  };
199
+ /**
200
+ * Checks if a SQL string contains mutation keywords (insert, update, delete,
201
+ * etc.). Results are cached for performance.
202
+ */
203
+ export const isSqlMutation = (sql) => {
204
+ /**
205
+ * Without cache, "insert 1_000_000" Storage test dropped from 57742
206
+ * inserts/sec to 34k. Regex we used was fast, but CodeQL flagged it as a
207
+ * potential ReDoS vulnerability, so manual comment removal was the only
208
+ * option. LRU cache restores performance.
209
+ */
210
+ const cached = isSqlMutationCache.get(sql);
211
+ if (cached !== undefined)
212
+ return cached;
213
+ const result = isSqlMutationRegEx.test(removeSqlComments(sql));
214
+ isSqlMutationCache.set(sql, result);
215
+ return result;
216
+ };
217
+ const isSqlMutationCache = createLruCache(PositiveInt.orThrow(10_000));
161
218
  const isSqlMutationRegEx = new RegExp(`\\b(${[
162
219
  "alter",
163
220
  "create",
@@ -172,7 +229,37 @@ const isSqlMutationRegEx = new RegExp(`\\b(${[
172
229
  "pragma",
173
230
  "vacuum",
174
231
  ].join("|")})\\b`, "i");
175
- export const isSqlMutation = (sql) => isSqlMutationRegEx.test(sql.replace(/--.*$/gm, ""));
232
+ /**
233
+ * Removes SQL line comments (--) from a SQL string without using regex to avoid
234
+ * ReDoS vulnerabilities.
235
+ */
236
+ const removeSqlComments = (sql) => {
237
+ // Fast path: if there are no comments, return the original string
238
+ if (!sql.includes("--"))
239
+ return sql;
240
+ let result = "";
241
+ let i = 0;
242
+ while (i < sql.length) {
243
+ // Check for comment start
244
+ if (i < sql.length - 1 && sql[i] === "-" && sql[i + 1] === "-") {
245
+ // Skip until end of line or end of string
246
+ i += 2;
247
+ while (i < sql.length && sql[i] !== "\n") {
248
+ i++;
249
+ }
250
+ // Keep the newline if present
251
+ if (i < sql.length && sql[i] === "\n") {
252
+ result += "\n";
253
+ i++;
254
+ }
255
+ }
256
+ else {
257
+ result += sql[i];
258
+ i++;
259
+ }
260
+ }
261
+ return result;
262
+ };
176
263
  export const explainSqliteQueryPlan = (deps) => (query) => {
177
264
  const result = deps.sqlite.exec({
178
265
  ...query,
@@ -181,7 +268,7 @@ export const explainSqliteQueryPlan = (deps) => (query) => {
181
268
  if (!result.ok)
182
269
  return result;
183
270
  // eslint-disable-next-line no-console
184
- console.log("ExplainQueryPlan", query);
271
+ console.log("[explainSqliteQueryPlan]", query);
185
272
  // eslint-disable-next-line no-console
186
273
  console.log(drawSqliteQueryPlan(result.value.rows));
187
274
  return ok();
@@ -203,9 +290,23 @@ const drawSqliteQueryPlan = (rows) => rows
203
290
  .join("\n");
204
291
  /**
205
292
  * SQLite represents boolean values using `0` (false) and `1` (true) instead of
206
- * a dedicated boolean type. This transform Type ensures that values conform to
207
- * SQLite's boolean representation.
293
+ * a dedicated boolean type.
294
+ *
295
+ * Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
296
+ * readability.
208
297
  *
209
298
  * See: https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
210
299
  */
211
- export const SqliteBoolean = transform(Boolean, union(0, 1), (value) => ok(value ? 1 : 0), (value) => value === 1);
300
+ export const SqliteBoolean = union(0, 1);
301
+ /**
302
+ * Represents the {@link SqliteBoolean} value for `true`.
303
+ *
304
+ * See {@link SqliteBoolean}.
305
+ */
306
+ export const sqliteTrue = 1;
307
+ /**
308
+ * Represents the {@link SqliteBoolean} value for `false`.
309
+ *
310
+ * See {@link SqliteBoolean}.
311
+ */
312
+ export const sqliteFalse = 0;