@evolu/common 6.0.1-preview.2 → 6.0.1-preview.21

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 (154) hide show
  1. package/dist/src/Assert.d.ts +6 -3
  2. package/dist/src/Assert.d.ts.map +1 -1
  3. package/dist/src/Assert.js +7 -4
  4. package/dist/src/Brand.d.ts +75 -0
  5. package/dist/src/Brand.d.ts.map +1 -0
  6. package/dist/src/Brand.js +1 -0
  7. package/dist/src/Buffer.d.ts +1 -1
  8. package/dist/src/Buffer.d.ts.map +1 -1
  9. package/dist/src/Buffer.js +1 -1
  10. package/dist/src/CallbackRegistry.d.ts +53 -0
  11. package/dist/src/CallbackRegistry.d.ts.map +1 -0
  12. package/dist/src/CallbackRegistry.js +25 -0
  13. package/dist/src/Console.d.ts +31 -6
  14. package/dist/src/Console.d.ts.map +1 -1
  15. package/dist/src/Console.js +72 -9
  16. package/dist/src/Crypto.d.ts +61 -34
  17. package/dist/src/Crypto.d.ts.map +1 -1
  18. package/dist/src/Crypto.js +29 -42
  19. package/dist/src/Evolu/Db.d.ts +159 -66
  20. package/dist/src/Evolu/Db.d.ts.map +1 -1
  21. package/dist/src/Evolu/Db.js +300 -705
  22. package/dist/src/Evolu/Diff.d.ts +3 -3
  23. package/dist/src/Evolu/Diff.d.ts.map +1 -1
  24. package/dist/src/Evolu/Diff.js +7 -5
  25. package/dist/src/Evolu/Evolu.d.ts +200 -115
  26. package/dist/src/Evolu/Evolu.d.ts.map +1 -1
  27. package/dist/src/Evolu/Evolu.js +287 -157
  28. package/dist/src/Evolu/Internal.d.ts +0 -2
  29. package/dist/src/Evolu/Internal.d.ts.map +1 -1
  30. package/dist/src/Evolu/Internal.js +0 -2
  31. package/dist/src/Evolu/LocalAuth.d.ts +144 -0
  32. package/dist/src/Evolu/LocalAuth.d.ts.map +1 -0
  33. package/dist/src/Evolu/LocalAuth.js +171 -0
  34. package/dist/src/Evolu/Owner.d.ts +209 -124
  35. package/dist/src/Evolu/Owner.d.ts.map +1 -1
  36. package/dist/src/Evolu/Owner.js +118 -104
  37. package/dist/src/Evolu/Platform.d.ts +9 -7
  38. package/dist/src/Evolu/Platform.d.ts.map +1 -1
  39. package/dist/src/Evolu/Protocol.d.ts +256 -211
  40. package/dist/src/Evolu/Protocol.d.ts.map +1 -1
  41. package/dist/src/Evolu/Protocol.js +558 -359
  42. package/dist/src/Evolu/Public.d.ts +6 -8
  43. package/dist/src/Evolu/Public.d.ts.map +1 -1
  44. package/dist/src/Evolu/Public.js +2 -3
  45. package/dist/src/Evolu/PublicKysely.js +3 -3
  46. package/dist/src/Evolu/Query.d.ts +2 -1
  47. package/dist/src/Evolu/Query.d.ts.map +1 -1
  48. package/dist/src/Evolu/Relay.d.ts +72 -4
  49. package/dist/src/Evolu/Relay.d.ts.map +1 -1
  50. package/dist/src/Evolu/Relay.js +124 -13
  51. package/dist/src/Evolu/Schema.d.ts +129 -73
  52. package/dist/src/Evolu/Schema.d.ts.map +1 -1
  53. package/dist/src/Evolu/Schema.js +169 -89
  54. package/dist/src/Evolu/Storage.d.ts +159 -14
  55. package/dist/src/Evolu/Storage.d.ts.map +1 -1
  56. package/dist/src/Evolu/Storage.js +42 -32
  57. package/dist/src/Evolu/Sync.d.ts +68 -13
  58. package/dist/src/Evolu/Sync.d.ts.map +1 -1
  59. package/dist/src/Evolu/Sync.js +414 -20
  60. package/dist/src/Evolu/Timestamp.d.ts +35 -27
  61. package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
  62. package/dist/src/Evolu/Timestamp.js +27 -18
  63. package/dist/src/ManyToManyMap.d.ts +74 -10
  64. package/dist/src/ManyToManyMap.d.ts.map +1 -1
  65. package/dist/src/ManyToManyMap.js +41 -6
  66. package/dist/src/Number.d.ts +2 -1
  67. package/dist/src/Number.d.ts.map +1 -1
  68. package/dist/src/Random.d.ts +3 -2
  69. package/dist/src/Random.d.ts.map +1 -1
  70. package/dist/src/RefCountedResourceManager.d.ts +119 -0
  71. package/dist/src/RefCountedResourceManager.d.ts.map +1 -0
  72. package/dist/src/RefCountedResourceManager.js +197 -0
  73. package/dist/src/Result.d.ts +176 -51
  74. package/dist/src/Result.d.ts.map +1 -1
  75. package/dist/src/Result.js +30 -241
  76. package/dist/src/Sqlite.d.ts +21 -4
  77. package/dist/src/Sqlite.d.ts.map +1 -1
  78. package/dist/src/Sqlite.js +50 -8
  79. package/dist/src/Task.d.ts +511 -0
  80. package/dist/src/Task.d.ts.map +1 -0
  81. package/dist/src/Task.js +410 -0
  82. package/dist/src/Time.d.ts +59 -0
  83. package/dist/src/Time.d.ts.map +1 -1
  84. package/dist/src/Time.js +87 -4
  85. package/dist/src/Type.d.ts +474 -327
  86. package/dist/src/Type.d.ts.map +1 -1
  87. package/dist/src/Type.js +502 -436
  88. package/dist/src/Types.d.ts +0 -74
  89. package/dist/src/Types.d.ts.map +1 -1
  90. package/dist/src/WebSocket.d.ts +5 -2
  91. package/dist/src/WebSocket.d.ts.map +1 -1
  92. package/dist/src/WebSocket.js +12 -13
  93. package/dist/src/Worker.d.ts +39 -11
  94. package/dist/src/Worker.d.ts.map +1 -1
  95. package/dist/src/Worker.js +22 -4
  96. package/dist/src/index.d.ts +3 -3
  97. package/dist/src/index.d.ts.map +1 -1
  98. package/dist/src/index.js +3 -3
  99. package/package.json +14 -13
  100. package/src/Assert.ts +8 -7
  101. package/src/Brand.ts +75 -0
  102. package/src/Buffer.ts +1 -1
  103. package/src/CallbackRegistry.ts +84 -0
  104. package/src/Console.ts +91 -11
  105. package/src/Crypto.ts +94 -79
  106. package/src/Evolu/Db.ts +528 -1027
  107. package/src/Evolu/Diff.ts +7 -5
  108. package/src/Evolu/Evolu.ts +682 -329
  109. package/src/Evolu/Internal.ts +0 -2
  110. package/src/Evolu/LocalAuth.ts +422 -0
  111. package/src/Evolu/Owner.ts +282 -227
  112. package/src/Evolu/Platform.ts +9 -9
  113. package/src/Evolu/Protocol.ts +788 -640
  114. package/src/Evolu/Public.ts +7 -14
  115. package/src/Evolu/PublicKysely.ts +3 -3
  116. package/src/Evolu/Query.ts +2 -1
  117. package/src/Evolu/Relay.ts +238 -18
  118. package/src/Evolu/Schema.ts +391 -191
  119. package/src/Evolu/Storage.ts +275 -55
  120. package/src/Evolu/Sync.ts +708 -37
  121. package/src/Evolu/Timestamp.ts +38 -35
  122. package/src/ManyToManyMap.ts +127 -24
  123. package/src/Number.ts +2 -6
  124. package/src/Random.ts +3 -2
  125. package/src/RefCountedResourceManager.ts +368 -0
  126. package/src/Result.ts +183 -53
  127. package/src/Sqlite.ts +59 -23
  128. package/src/Task.ts +779 -0
  129. package/src/Time.ts +168 -4
  130. package/src/Type.ts +708 -660
  131. package/src/Types.ts +0 -76
  132. package/src/WebSocket.ts +23 -17
  133. package/src/Worker.ts +72 -23
  134. package/src/index.ts +3 -3
  135. package/dist/src/Callbacks.d.ts +0 -20
  136. package/dist/src/Callbacks.d.ts.map +0 -1
  137. package/dist/src/Callbacks.js +0 -18
  138. package/dist/src/Evolu/Config.d.ts +0 -69
  139. package/dist/src/Evolu/Config.d.ts.map +0 -1
  140. package/dist/src/Evolu/Config.js +0 -9
  141. package/dist/src/Evolu/Kysely.d.ts +0 -6
  142. package/dist/src/Evolu/Kysely.d.ts.map +0 -1
  143. package/dist/src/Evolu/Kysely.js +0 -21
  144. package/dist/src/NanoId.d.ts +0 -27
  145. package/dist/src/NanoId.d.ts.map +0 -1
  146. package/dist/src/NanoId.js +0 -6
  147. package/dist/src/Promise.d.ts +0 -180
  148. package/dist/src/Promise.d.ts.map +0 -1
  149. package/dist/src/Promise.js +0 -176
  150. package/src/Callbacks.ts +0 -43
  151. package/src/Evolu/Config.ts +0 -83
  152. package/src/Evolu/Kysely.ts +0 -38
  153. package/src/NanoId.ts +0 -39
  154. package/src/Promise.ts +0 -295
@@ -1,242 +1,3 @@
1
- /**
2
- * 🛡️ Type-safe errors
3
- *
4
- * ## Intro
5
- *
6
- * The problem with throwing an exception in JavaScript is that the caught error
7
- * is always of an unknown type. The unknown type is a problem because we can't
8
- * be sure all errors have been handled because the TypeScript compiler can't
9
- * help us.
10
- *
11
- * Some other languages like Rust 🦀 or Haskell 📚 use a type-safe approach to
12
- * error handling, where errors are explicitly represented as part of the return
13
- * type, such as Result or Either, allowing the developer to handle all errors
14
- * safely. ✅
15
- *
16
- * ✨ Evolu uses {@link Result}, and it looks like this:
17
- *
18
- * ```ts
19
- * type Result<T, E> = Ok<T> | Err<E>;
20
- *
21
- * interface Ok<T> {
22
- * readonly ok: true;
23
- * readonly value: T;
24
- * }
25
- *
26
- * interface Err<E> {
27
- * readonly ok: false;
28
- * readonly error: E;
29
- * }
30
- *
31
- * const ok = <T>(value: T): Ok<T> => ({ ok: true, value });
32
- * const err = <E>(error: E): Err<E> => ({ ok: false, error });
33
- * ```
34
- *
35
- * Now let's look at how `Result` can be used for safe JSON parsing:
36
- *
37
- * ```ts
38
- * interface ParseJsonError {
39
- * readonly type: "ParseJsonError";
40
- * readonly message: string;
41
- * }
42
- *
43
- * const parseJson = (value: string): Result<unknown, ParseJsonError> => {
44
- * try {
45
- * return ok(JSON.parse(value));
46
- * } catch (error) {
47
- * return err({ type: "ParseJsonError", message: String(error) });
48
- * }
49
- * };
50
- *
51
- * // Result<unknown, ParseJsonError>
52
- * const json = parseJson('{"key": "value"}');
53
- *
54
- * // Fail fast to handle errors early.
55
- * if (!json.ok) return json; // Err<ParseJsonError>
56
- *
57
- * // Now, we have access to the json.value.
58
- * expectTypeOf(json.value).toBeUnknown();
59
- * ```
60
- *
61
- * Note how we didn't have to use the try/catch, just `if (!json.ok)`, and how
62
- * the error isn't unknown but has a type.
63
- *
64
- * But we had to use `try/catch` in the `parseJson` function. For such a case,
65
- * wrapping unsafe code, Evolu provides the {@link trySync} helper:
66
- *
67
- * ```ts
68
- * const parseJson = (value: string): Result<unknown, ParseJsonError> =>
69
- * trySync(
70
- * () => JSON.parse(value) as unknown,
71
- * (error) => ({ type: "ParseJsonError", message: String(error) }),
72
- * );
73
- * ```
74
- *
75
- * ✨ {@link trySync} helper makes unsafe (can throw) synchronous code safe; for
76
- * unsafe asynchronous code, use {@link tryAsync}.
77
- *
78
- * Let's summarize it:
79
- *
80
- * - For synchronous safe code, use `ok` and `err`.
81
- * - For unsafe code, use `trySync` or `tryAsync`.
82
- * - For asynchronous safe code, use `Promise` with {@link Result}.
83
- *
84
- * Asynchronous safe (because of a Promise using Result) code is
85
- * straightforward:
86
- *
87
- * ```ts
88
- * const fetchUser = async (
89
- * userId: string,
90
- * ): Promise<Result<User, FetchUserError>> => {
91
- * // Simulate an API call
92
- * return new Promise((resolve) => {
93
- * setTimeout(() => {
94
- * if (userId === "1") {
95
- * resolve(ok({ id: "1", name: "Alice" }));
96
- * } else {
97
- * resolve(
98
- * err({ type: "FetchUserError", reason: "user not found" }),
99
- * );
100
- * }
101
- * }, 1000);
102
- * });
103
- * };
104
- * ```
105
- *
106
- * ## Examples
107
- *
108
- * ### Sequential Operations with Short-Circuiting
109
- *
110
- * When performing a sequence of operations where any failure should stop
111
- * further processing, use the `Result` type with early returns.
112
- *
113
- * Here's an example of a database reset operation that drops tables, restores a
114
- * schema, and initializes the database, stopping on the first error:
115
- *
116
- * ```ts
117
- * const resetResult = deps.sqlite.transaction(() => {
118
- * const dropAllTablesResult = dropAllTables(deps);
119
- * if (!dropAllTablesResult.ok) return dropAllTablesResult;
120
- *
121
- * if (message.restore) {
122
- * const dbSchema = getDbSchema(deps)();
123
- * if (!dbSchema.ok) return dbSchema;
124
- *
125
- * const ensureDbSchemaResult = ensureDbSchema(deps)(
126
- * message.restore.dbSchema,
127
- * dbSchema.value,
128
- * );
129
- * if (!ensureDbSchemaResult.ok) return ensureDbSchemaResult;
130
- *
131
- * const initializeDbResult = initializeDb(deps)(
132
- * message.restore.mnemonic,
133
- * );
134
- * if (!initializeDbResult.ok) return initializeDbResult;
135
- * }
136
- * return ok();
137
- * });
138
- *
139
- * if (!resetResult.ok) {
140
- * deps.postMessage({ type: "onError", error: resetResult.error });
141
- * return;
142
- * }
143
- * ```
144
- *
145
- * In this pattern:
146
- *
147
- * - Each operation returns a `Result` (e.g., `Result<void, E>` or `Result<T,
148
- * E>`).
149
- * - After each operation, check `if (!result.ok)` and return the `Err` to
150
- * short-circuit.
151
- * - If all operations succeed, return `ok()` (or another value if needed).
152
- * - Outside the transaction, handle the final `Result` to report success or
153
- * failure.
154
- *
155
- * This approach ensures type-safe error handling, avoids nested try/catch
156
- * blocks, and clearly communicates the control flow.
157
- *
158
- * ### A function with two different errors:
159
- *
160
- * ```ts
161
- * const example = (value: string): Result<number, FooError | BarError> => {
162
- * const foo = getFoo(value);
163
- * if (!foo.ok) return foo;
164
- *
165
- * const bar = barize(foo.value);
166
- * if (!bar.ok) return bar;
167
- *
168
- * return ok(barToNumber(bar.value));
169
- * };
170
- * ```
171
- *
172
- * ## FAQ
173
- *
174
- * ### What if my function doesn't return a value on success?
175
- *
176
- * If your function performs an operation but doesn't need to return a value on
177
- * success, you can use `Result<void, E>`. Using `Result<void, E>` is clearer
178
- * than using `Result<true, E>` or `Result<null, E>` because it communicates
179
- * that the function doesn't produce a value but can produce errors.
180
- *
181
- * ### How do I short-circuit processing of an array on the first error?
182
- *
183
- * If you want to stop processing as soon as an error occurs (short-circuit),
184
- * you should produce and check each `Result` inside a loop:
185
- *
186
- * ```ts
187
- * for (const query of [
188
- * sql`drop table evolu_owner;`,
189
- * sql`drop table evolu_message;`,
190
- * ]) {
191
- * const result = deps.sqlite.exec(query);
192
- * if (!result.ok) return result;
193
- * }
194
- * // All queries succeeded
195
- * ```
196
- *
197
- * ### How do I handle an array of operations and short-circuit on the first error?
198
- *
199
- * If you have an array of operations (not results), you should make them
200
- * _lazy_—that is, represent each operation as a function (see `LazyValue` in
201
- * `Function.ts`). This way, you only execute each operation as needed, and can
202
- * stop on the first error:
203
- *
204
- * ```ts
205
- * import type { LazyValue } from "./Function";
206
- *
207
- * const operations: LazyValue<Result<void, MyError>>[] = [
208
- * () => doSomething(),
209
- * () => doSomethingElse(),
210
- * ];
211
- *
212
- * for (const op of operations) {
213
- * const result = op();
214
- * if (!result.ok) return result;
215
- * }
216
- * // All operations succeeded
217
- * ```
218
- *
219
- * If you already have an array of `Result`s, the processing has already
220
- * happened, so you can't short-circuit. In that case, you can check for the
221
- * first error:
222
- *
223
- * ```ts
224
- * const firstError = results.find((r) => !r.ok);
225
- * if (firstError) return firstError;
226
- * // All results are Ok
227
- * ```
228
- *
229
- * ### Why doesn't Evolu provide "handy helpers"?
230
- *
231
- * Evolu intentionally favors imperative patterns (like the `for...of` loop
232
- * above) over monadic helpers. Imperative code is generally more readable,
233
- * easier to debug, and more familiar to most JavaScript and TypeScript
234
- * developers. While monads and functional helpers can be powerful, they often
235
- * obscure control flow and make debugging harder. Evolu's approach keeps error
236
- * handling explicit and straightforward.
237
- *
238
- * @module
239
- */
240
1
  export function ok(value = undefined) {
241
2
  return { ok: true, value: value };
242
3
  }
@@ -269,15 +30,40 @@ export const err = (error) => ({ ok: false, error });
269
30
  * const config = getOrThrow(loadConfig());
270
31
  * // Safe to use config here
271
32
  * ```
33
+ *
34
+ * Throws: `Error` with the original error attached as `cause`.
272
35
  */
273
36
  export const getOrThrow = (result) => {
274
37
  if (result.ok) {
275
38
  return result.value;
276
39
  }
277
40
  else {
278
- throw new Error(`Result error: ${JSON.stringify(result.error)}`);
41
+ throw new Error("getOrThrow", { cause: result.error });
279
42
  }
280
43
  };
44
+ /**
45
+ * Extracts the value from a {@link Result} if it is an `Ok`, or returns `null`
46
+ * if it is an `Err`.
47
+ *
48
+ * **Intended usage:**
49
+ *
50
+ * - When you need to convert a `Result` to a nullable value for APIs that expect
51
+ * `T | null`.
52
+ * - When the error is not important and you just want the value or nothing.
53
+ *
54
+ * ### Example
55
+ *
56
+ * ```ts
57
+ * const parseResult = parseJson('{"key": "value"}');
58
+ * const value = getOrNull(parseResult);
59
+ * // value is unknown | null
60
+ *
61
+ * if (value != null) {
62
+ * console.log("Parsed value:", value);
63
+ * }
64
+ * ```
65
+ */
66
+ export const getOrNull = (result) => result.ok ? result.value : null;
281
67
  /**
282
68
  * Wraps synchronous functions that may throw exceptions, returning a
283
69
  * {@link Result}.
@@ -298,7 +84,10 @@ export const getOrThrow = (result) => {
298
84
  * const parseJson = (value: string): Result<unknown, ParseJsonError> =>
299
85
  * trySync(
300
86
  * () => JSON.parse(value) as unknown,
301
- * (error) => ({ type: "ParseJsonError", message: String(error) }),
87
+ * (error): ParseJsonError => ({
88
+ * type: "ParseJsonError",
89
+ * message: String(error),
90
+ * }),
302
91
  * );
303
92
  * ```
304
93
  */
@@ -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.
@@ -124,11 +127,25 @@ export interface SqliteQueryPlanRow {
124
127
  export declare const explainSqliteQueryPlan: (deps: SqliteDep) => (query: SqliteQuery) => Result<void, SqliteError>;
125
128
  /**
126
129
  * 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.
130
+ * a dedicated boolean type.
131
+ *
132
+ * Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
133
+ * readability.
129
134
  *
130
135
  * See: https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
131
136
  */
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>;
137
+ export declare const SqliteBoolean: import("./Type.js").UnionType<[import("./Type.js").LiteralType<0>, import("./Type.js").LiteralType<1>]>;
133
138
  export type SqliteBoolean = typeof SqliteBoolean.Type;
139
+ /**
140
+ * Represents the {@link SqliteBoolean} value for `true`.
141
+ *
142
+ * See {@link SqliteBoolean}.
143
+ */
144
+ export declare const sqliteTrue = 1;
145
+ /**
146
+ * Represents the {@link SqliteBoolean} value for `false`.
147
+ *
148
+ * See {@link SqliteBoolean}.
149
+ */
150
+ export declare const sqliteFalse = 0;
134
151
  //# sourceMappingURL=Sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAA2B,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAW,MAAM,EAAqB,MAAM,aAAa,CAAC;AACjE,OAAO,EAIL,UAAU,EAKX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAoB,MAAM,YAAY,CAAC;AAEhE;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,KAAK,gBAAgB,CAAC;IAC7E,QAAQ,CAAC,MAAM,EAAE,MAAM,UAAU,CAAC;CACnC;AAED,MAAM,MAAM,kBAAkB,GAAG,CAC/B,IAAI,EAAE,UAAU,EAChB,OAAO,CAAC,EAAE,mBAAmB,KAC1B,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CACjD;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,MAAO,SAAQ,UAAU;IACxC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC7C,KAAK,EAAE,WAAW,KACf,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,EACzB,QAAQ,EAAE,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,KACvC,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC;IAEhC,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CACvC;AAED,kDAAkD;AAClD,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAExD;;;;;GAKG;AACH,eAAO,MAAM,WAAW,wlBAA0C,CAAC;AACnE,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAElD,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEzC;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAEvC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IAC/D,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,YAAY,GACtB,MAAM,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,MAEhD,MAAM,UAAU,EAChB,UAAU,mBAAmB,KAC5B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CA+Ff,CAAC;AAyB1B,MAAM,WAAW,kBAAkB,CAAC,CAAC,CAAE,SAAQ,UAAU;IACvD,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,SAAS,OAAO,EAC9B,KAAK,EAAE,WAAW,EAClB,aAAa,CAAC,EAAE,CAAC,KACd,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;CACpC;AAED,eAAO,MAAM,6BAA6B,GAAI,CAAC,EAC7C,SAAS,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,EAC5B,WAAW,CAAC,SAAS,EAAE,CAAC,KAAK,IAAI,KAChC,kBAAkB,CAAC,CAAC,CAuBtB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,eAAe,CAAC;IACtB,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,CAAC;AAEpE,kBAAkB;AAClB,eAAO,MAAM,GAAG;cACL,oBAAoB,iBACd,KAAK,CAAC,gBAAgB,CAAC,GACrC,WAAW;2BAoBgB,MAAM,GAAG,aAAa;aAcpC,MAAM,GAAG,MAAM;sBAGpB,oBAAoB,iBACd,KAAK,CAAC,gBAAgB,CAAC,GACrC,WAAW;CArBb,CAAC;AA4CF,eAAO,MAAM,aAAa,EAAE,SAAS,CAAC,MAAM,CACS,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,sBAAsB,GAChC,MAAM,SAAS,MACf,OAAO,WAAW,KAAG,MAAM,CAAC,IAAI,EAAE,WAAW,CAgB7C,CAAC;AAoBJ;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,uRAKzB,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC"}
1
+ {"version":3,"file":"Sqlite.d.ts","sourceRoot":"","sources":["../../src/Sqlite.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createTransferableError } from "./Error.js";
2
2
  import { err, ok, tryAsync, trySync } from "./Result.js";
3
- import { Boolean, Null, Number, String, transform, Uint8Array, union, } from "./Type.js";
3
+ import { Null, Number, String, Uint8Array, union } from "./Type.js";
4
4
  /**
5
5
  * A value that can be stored in Sqlite.
6
6
  *
@@ -21,9 +21,9 @@ export const createSqlite = (deps) => async (name, options) => tryAsync(async ()
21
21
  }, createSqliteError);
22
22
  const sqlite = {
23
23
  exec: (query) => trySync(() => {
24
- deps.console?.log("[sql]", query);
24
+ deps.console?.log("[sql]", { query });
25
25
  const result = maybeLogSqliteQueryExecutionTime(query, () => driver.exec(query, isSqlMutation(query.sql)));
26
- deps.console?.log("[sql]", result);
26
+ deps.console?.log("[sql]", { result });
27
27
  return result;
28
28
  }, (error) => ({
29
29
  type: "SqliteError",
@@ -172,7 +172,35 @@ const isSqlMutationRegEx = new RegExp(`\\b(${[
172
172
  "pragma",
173
173
  "vacuum",
174
174
  ].join("|")})\\b`, "i");
175
- export const isSqlMutation = (sql) => isSqlMutationRegEx.test(sql.replace(/--.*$/gm, ""));
175
+ /**
176
+ * Removes SQL line comments (--) from a SQL string without using regex to avoid
177
+ * ReDoS vulnerabilities.
178
+ */
179
+ const removeSqlComments = (sql) => {
180
+ let result = "";
181
+ let i = 0;
182
+ while (i < sql.length) {
183
+ // Check for comment start
184
+ if (i < sql.length - 1 && sql[i] === "-" && sql[i + 1] === "-") {
185
+ // Skip until end of line or end of string
186
+ i += 2;
187
+ while (i < sql.length && sql[i] !== "\n") {
188
+ i++;
189
+ }
190
+ // Keep the newline if present
191
+ if (i < sql.length && sql[i] === "\n") {
192
+ result += "\n";
193
+ i++;
194
+ }
195
+ }
196
+ else {
197
+ result += sql[i];
198
+ i++;
199
+ }
200
+ }
201
+ return result;
202
+ };
203
+ export const isSqlMutation = (sql) => isSqlMutationRegEx.test(removeSqlComments(sql));
176
204
  export const explainSqliteQueryPlan = (deps) => (query) => {
177
205
  const result = deps.sqlite.exec({
178
206
  ...query,
@@ -181,7 +209,7 @@ export const explainSqliteQueryPlan = (deps) => (query) => {
181
209
  if (!result.ok)
182
210
  return result;
183
211
  // eslint-disable-next-line no-console
184
- console.log("ExplainQueryPlan", query);
212
+ console.log("[explainSqliteQueryPlan]", query);
185
213
  // eslint-disable-next-line no-console
186
214
  console.log(drawSqliteQueryPlan(result.value.rows));
187
215
  return ok();
@@ -203,9 +231,23 @@ const drawSqliteQueryPlan = (rows) => rows
203
231
  .join("\n");
204
232
  /**
205
233
  * 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.
234
+ * a dedicated boolean type.
235
+ *
236
+ * Use {@link sqliteTrue} and {@link sqliteFalse} constants for better
237
+ * readability.
208
238
  *
209
239
  * See: https://www.sqlite.org/quirks.html#no_separate_boolean_datatype
210
240
  */
211
- export const SqliteBoolean = transform(Boolean, union(0, 1), (value) => ok(value ? 1 : 0), (value) => value === 1);
241
+ export const SqliteBoolean = union(0, 1);
242
+ /**
243
+ * Represents the {@link SqliteBoolean} value for `true`.
244
+ *
245
+ * See {@link SqliteBoolean}.
246
+ */
247
+ export const sqliteTrue = 1;
248
+ /**
249
+ * Represents the {@link SqliteBoolean} value for `false`.
250
+ *
251
+ * See {@link SqliteBoolean}.
252
+ */
253
+ export const sqliteFalse = 0;