@evolu/common 6.0.1-preview.12 → 6.0.1-preview.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/Evolu/Db.d.ts +1 -6
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Db.js +17 -64
- package/dist/src/Evolu/Evolu.d.ts +126 -6
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +18 -4
- package/dist/src/Evolu/Protocol.d.ts +20 -5
- package/dist/src/Evolu/Protocol.d.ts.map +1 -1
- package/dist/src/Evolu/Protocol.js +32 -8
- package/dist/src/Evolu/Schema.d.ts +23 -5
- package/dist/src/Evolu/Schema.d.ts.map +1 -1
- package/dist/src/Evolu/Schema.js +27 -5
- package/dist/src/Evolu/Timestamp.d.ts +6 -0
- package/dist/src/Evolu/Timestamp.d.ts.map +1 -1
- package/dist/src/Evolu/Timestamp.js +7 -0
- package/dist/src/Type.d.ts +5 -1
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +5 -1
- package/package.json +3 -2
- package/src/Evolu/Db.ts +17 -100
- package/src/Evolu/Evolu.ts +148 -10
- package/src/Evolu/Protocol.ts +90 -38
- package/src/Evolu/Schema.ts +38 -7
- package/src/Evolu/Timestamp.ts +8 -0
- package/src/Type.ts +5 -1
package/dist/src/Evolu/Db.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { BinaryOwnerId, CrdtMessage, DbChange, ProtocolError, Storage } from "./
|
|
|
18
18
|
import { Query } from "./Query.js";
|
|
19
19
|
import { SqliteStorageBase } from "./Storage.js";
|
|
20
20
|
import { CreateSyncDep } from "./Sync.js";
|
|
21
|
-
import {
|
|
21
|
+
import { TimestampError } from "./Timestamp.js";
|
|
22
22
|
export declare const DbTable: import("../Type.js").ObjectType<{
|
|
23
23
|
name: import("../Type.js").BrandType<import("../Type.js").Type<"Brand", string & import("../Types.js").Brand<"Base64Url">, string, import("../Type.js").RegexError<"Base64Url">, string, import("../Type.js").StringError>, "MaxLength256", import("../Type.js").MaxLengthError<256>, import("../Type.js").StringError | import("../Type.js").RegexError<"Base64Url">>;
|
|
24
24
|
columns: import("../Type.js").ArrayType<import("../Type.js").BrandType<import("../Type.js").Type<"Brand", string & import("../Types.js").Brand<"Base64Url">, string, import("../Type.js").RegexError<"Base64Url">, string, import("../Type.js").StringError>, "MaxLength256", import("../Type.js").MaxLengthError<256>, import("../Type.js").StringError | import("../Type.js").RegexError<"Base64Url">>>;
|
|
@@ -121,11 +121,6 @@ export interface DbSnapshot {
|
|
|
121
121
|
export declare const getDbSnapshot: (deps: SqliteDep) => DbSnapshot;
|
|
122
122
|
export declare const createAppTable: (tableName: string, columns: ReadonlyArray<string>) => SafeSql;
|
|
123
123
|
export declare const applyMessageToTimestampAndHistoryTables: (deps: SqliteDep & ClientStorageDep) => (ownerId: BinaryOwnerId, message: CrdtMessage) => Result<void, SqliteError>;
|
|
124
|
-
export declare const maybeMigrateToVersion0: (deps: SqliteDep) => (schema: DbSchema) => Result<{
|
|
125
|
-
readonly messages: ReadonlyArray<CrdtMessage>;
|
|
126
|
-
readonly mnemonic: Mnemonic;
|
|
127
|
-
readonly lastTimestamp: Timestamp;
|
|
128
|
-
} | null, SqliteError>;
|
|
129
124
|
export interface ClientStorage extends SqliteStorageBase, Storage {
|
|
130
125
|
}
|
|
131
126
|
export interface ClientStorageDep {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Db.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,qBAAqB,EACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EAEpB,2BAA2B,EAE5B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAa,GAAG,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,
|
|
1
|
+
{"version":3,"file":"Db.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Db.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Evolu/Db.js
CHANGED
|
@@ -5,7 +5,7 @@ import { eqArrayNumber } from "../Eq.js";
|
|
|
5
5
|
import { constFalse, exhaustiveCheck } from "../Function.js";
|
|
6
6
|
import { objectToEntries } from "../Object.js";
|
|
7
7
|
import { createRef } from "../Ref.js";
|
|
8
|
-
import {
|
|
8
|
+
import { ok } from "../Result.js";
|
|
9
9
|
import { createSqlite, explainSqliteQueryPlan, sql, } from "../Sqlite.js";
|
|
10
10
|
import { array, object, String } from "../Type.js";
|
|
11
11
|
import { createInitializedWorker, } from "../Worker.js";
|
|
@@ -14,7 +14,7 @@ import { createAppOwner, createOwnerRow, } from "./Owner.js";
|
|
|
14
14
|
import { applyProtocolMessageAsClient, Base64Url256, binaryIdToId, createProtocolMessageForSync, createProtocolMessageFromCrdtMessages, decryptAndDecodeDbChange, encodeAndEncryptDbChange, idToBinaryId, ownerIdToBinaryOwnerId, protocolVersion, } from "./Protocol.js";
|
|
15
15
|
import { createQueryRowsCache, deserializeQuery, emptyRows, } from "./Query.js";
|
|
16
16
|
import { createSqliteStorageBase, } from "./Storage.js";
|
|
17
|
-
import {
|
|
17
|
+
import { binaryTimestampToTimestamp, receiveTimestamp, sendTimestamp, timestampStringToTimestamp, timestampToBinaryTimestamp, timestampToTimestampString, } from "./Timestamp.js";
|
|
18
18
|
export const DbTable = object({
|
|
19
19
|
name: Base64Url256,
|
|
20
20
|
columns: array(Base64Url256),
|
|
@@ -50,14 +50,10 @@ export const createDbWorkerForPlatform = (platformDeps) => {
|
|
|
50
50
|
const ensureDbSchemaResult = ensureDbSchema({ sqlite })(initMessage.dbSchema, currentDbSchema.value);
|
|
51
51
|
if (!ensureDbSchemaResult.ok)
|
|
52
52
|
return ensureDbSchemaResult;
|
|
53
|
-
const maybeMigrateToVersion0Result = maybeMigrateToVersion0({ sqlite })(currentDbSchema.value);
|
|
54
|
-
if (!maybeMigrateToVersion0Result.ok)
|
|
55
|
-
return maybeMigrateToVersion0Result;
|
|
56
53
|
const ownerExists = currentDbSchema.value.tables.some((table) => table.name === "evolu_owner");
|
|
57
54
|
const appOwnerAndOwnerRow = ownerExists
|
|
58
55
|
? selectAppOwner({ sqlite })
|
|
59
|
-
: initializeDb({ ...platformDeps, sqlite })(
|
|
60
|
-
initMessage.config.mnemonic);
|
|
56
|
+
: initializeDb({ ...platformDeps, sqlite })(initMessage.config.mnemonic);
|
|
61
57
|
if (!appOwnerAndOwnerRow.ok)
|
|
62
58
|
return appOwnerAndOwnerRow;
|
|
63
59
|
const [appOwner, ownerRow] = appOwnerAndOwnerRow.value;
|
|
@@ -81,11 +77,6 @@ export const createDbWorkerForPlatform = (platformDeps) => {
|
|
|
81
77
|
...depsWithoutSyncAndStorage,
|
|
82
78
|
storage: storage.value,
|
|
83
79
|
};
|
|
84
|
-
if (maybeMigrateToVersion0Result.value) {
|
|
85
|
-
const result = applyMessages(depsWithoutSync)(maybeMigrateToVersion0Result.value.messages, maybeMigrateToVersion0Result.value.lastTimestamp);
|
|
86
|
-
if (!result.ok)
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
89
80
|
if (!ownerExists && isNonEmptyReadonlyArray(initMessage.initialData)) {
|
|
90
81
|
const result = applyChanges(depsWithoutSync)(initMessage.initialData);
|
|
91
82
|
if (!result.ok)
|
|
@@ -129,13 +120,7 @@ export const createDbWorkerForPlatform = (platformDeps) => {
|
|
|
129
120
|
return result;
|
|
130
121
|
}
|
|
131
122
|
else {
|
|
132
|
-
const
|
|
133
|
-
if (!millis.ok) {
|
|
134
|
-
return err({
|
|
135
|
-
type: "TimestampTimeOutOfRangeError",
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
const date = new Date(millis.value).toISOString();
|
|
123
|
+
const date = new Date(deps.time.now()).toISOString();
|
|
139
124
|
for (const [column, value] of objectToEntries(change.values)) {
|
|
140
125
|
const result = deps.sqlite.exec(sql.prepared `
|
|
141
126
|
insert into ${sql.identifier(change.table)}
|
|
@@ -553,8 +538,8 @@ const applyMessages = (deps) => (messages, lastTimestamp) => {
|
|
|
553
538
|
return ok();
|
|
554
539
|
};
|
|
555
540
|
const applyMessageToAppTable = (deps) => (ownerId, message) => {
|
|
556
|
-
const date = new Date(message.timestamp.millis).toISOString();
|
|
557
541
|
const timestamp = timestampToBinaryTimestamp(message.timestamp);
|
|
542
|
+
const updatedAt = new Date(message.timestamp.millis).toISOString();
|
|
558
543
|
for (const [column, value] of objectToEntries(message.change.values)) {
|
|
559
544
|
const result = deps.sqlite.exec(sql.prepared `
|
|
560
545
|
with
|
|
@@ -570,15 +555,15 @@ const applyMessageToAppTable = (deps) => (ownerId, message) => {
|
|
|
570
555
|
limit 1
|
|
571
556
|
)
|
|
572
557
|
insert into ${sql.identifier(message.change.table)}
|
|
573
|
-
("id", ${sql.identifier(column)},
|
|
574
|
-
select ${message.change.id}, ${value}, ${
|
|
558
|
+
("id", ${sql.identifier(column)}, updatedAt)
|
|
559
|
+
select ${message.change.id}, ${value}, ${updatedAt}
|
|
575
560
|
where
|
|
576
561
|
(select "timestamp" from lastTimestamp) is null
|
|
577
562
|
or (select "timestamp" from lastTimestamp) < ${timestamp}
|
|
578
563
|
on conflict ("id") do update
|
|
579
564
|
set
|
|
580
565
|
${sql.identifier(column)} = ${value},
|
|
581
|
-
updatedAt = ${
|
|
566
|
+
updatedAt = ${updatedAt}
|
|
582
567
|
where
|
|
583
568
|
(select "timestamp" from lastTimestamp) is null
|
|
584
569
|
or (select "timestamp" from lastTimestamp) < ${timestamp};
|
|
@@ -636,41 +621,6 @@ const loadQueries = (deps) => (tabId, queries) => {
|
|
|
636
621
|
}));
|
|
637
622
|
return ok(queryPatchesArray);
|
|
638
623
|
};
|
|
639
|
-
export const maybeMigrateToVersion0 = (deps) => (schema) => {
|
|
640
|
-
// evolu_history is a new table
|
|
641
|
-
const hasOwnerButNoHistory = schema.tables.some((t) => t.name === "evolu_owner") &&
|
|
642
|
-
!schema.tables.some((t) => t.name === "evolu_history");
|
|
643
|
-
if (!hasOwnerButNoHistory) {
|
|
644
|
-
return ok(null);
|
|
645
|
-
}
|
|
646
|
-
const mnemonicAndLastTimestamp = deps.sqlite.exec(sql ` select mnemonic, timestamp from evolu_owner limit 1; `);
|
|
647
|
-
if (!mnemonicAndLastTimestamp.ok)
|
|
648
|
-
return mnemonicAndLastTimestamp;
|
|
649
|
-
const messagesRows = deps.sqlite.exec(sql `
|
|
650
|
-
select "timestamp", "table", "id", "column", "value" from evolu_message;
|
|
651
|
-
`);
|
|
652
|
-
if (!messagesRows.ok)
|
|
653
|
-
return messagesRows;
|
|
654
|
-
for (const query of [
|
|
655
|
-
sql `drop table evolu_owner;`,
|
|
656
|
-
sql `drop table evolu_message;`,
|
|
657
|
-
]) {
|
|
658
|
-
const result = deps.sqlite.exec(query);
|
|
659
|
-
if (!result.ok)
|
|
660
|
-
return result;
|
|
661
|
-
}
|
|
662
|
-
const messages = messagesRows.value.rows.map((message) => ({
|
|
663
|
-
timestamp: timestampStringToTimestamp(message.timestamp),
|
|
664
|
-
change: {
|
|
665
|
-
id: message.id,
|
|
666
|
-
table: message.table,
|
|
667
|
-
values: { [message.column]: message.value },
|
|
668
|
-
},
|
|
669
|
-
}));
|
|
670
|
-
const { rows: [{ mnemonic, timestamp }], } = mnemonicAndLastTimestamp.value;
|
|
671
|
-
const lastTimestamp = timestampStringToTimestamp(timestamp);
|
|
672
|
-
return ok({ messages, mnemonic, lastTimestamp });
|
|
673
|
-
};
|
|
674
624
|
const dropAllTables = (deps) => {
|
|
675
625
|
const schema = getDbSchema(deps)();
|
|
676
626
|
if (!schema.ok)
|
|
@@ -726,7 +676,7 @@ const createClientStorage = (deps) => (options) => {
|
|
|
726
676
|
const owner = deps.ownerRowRef.get();
|
|
727
677
|
const decodedAndDecryptedMessages = [];
|
|
728
678
|
for (const message of messages) {
|
|
729
|
-
const dbChange = decryptAndDecodeDbChange(deps)(message
|
|
679
|
+
const dbChange = decryptAndDecodeDbChange(deps)(message, owner.encryptionKey);
|
|
730
680
|
if (!dbChange.ok) {
|
|
731
681
|
deps.postMessage({
|
|
732
682
|
type: "onError",
|
|
@@ -778,13 +728,16 @@ const createClientStorage = (deps) => (options) => {
|
|
|
778
728
|
assert(eqArrayNumber(r.id, id), "All rows must have the same Id");
|
|
779
729
|
values[r.column] = r.value;
|
|
780
730
|
}
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
731
|
+
const message = {
|
|
732
|
+
timestamp: binaryTimestampToTimestamp(timestamp),
|
|
733
|
+
change: {
|
|
734
|
+
table: rows[0].table,
|
|
735
|
+
id: binaryIdToId(rows[0].id),
|
|
736
|
+
values,
|
|
737
|
+
},
|
|
785
738
|
};
|
|
786
739
|
const { encryptionKey } = deps.ownerRowRef.get();
|
|
787
|
-
return encodeAndEncryptDbChange(deps)(
|
|
740
|
+
return encodeAndEncryptDbChange(deps)(message, encryptionKey);
|
|
788
741
|
},
|
|
789
742
|
};
|
|
790
743
|
return ok(storage);
|
|
@@ -194,32 +194,152 @@ export interface Evolu<S extends EvoluSchema = EvoluSchema> {
|
|
|
194
194
|
*/
|
|
195
195
|
readonly getSyncState: () => SyncState;
|
|
196
196
|
/**
|
|
197
|
-
* Inserts a row
|
|
197
|
+
* Inserts a row into the database and returns a {@link Result} with the new
|
|
198
|
+
* {@link Id}.
|
|
199
|
+
*
|
|
200
|
+
* The first argument is the table name, and the second is an object
|
|
201
|
+
* containing the row data. An optional third argument provides mutation
|
|
202
|
+
* options including an `onComplete` callback and `onlyValidate` flag.
|
|
203
|
+
*
|
|
204
|
+
* Returns a Result type - use `.ok` to check if the insertion succeeded, and
|
|
205
|
+
* `.value.id` to access the generated ID on success, or `.error` to handle
|
|
206
|
+
* validation errors.
|
|
207
|
+
*
|
|
208
|
+
* Evolu does not use SQL for mutations to ensure data can be safely and
|
|
209
|
+
* predictably merged without conflicts. Explicit mutations also allow Evolu
|
|
210
|
+
* to automatically add and update {@link DefaultColumns}.
|
|
198
211
|
*
|
|
199
212
|
* ### Example
|
|
200
213
|
*
|
|
201
214
|
* ```ts
|
|
202
|
-
*
|
|
215
|
+
* const result = evolu.insert("todo", {
|
|
216
|
+
* title: "Learn Evolu",
|
|
217
|
+
* isCompleted: false,
|
|
218
|
+
* });
|
|
219
|
+
*
|
|
220
|
+
* if (result.ok) {
|
|
221
|
+
* console.log("Todo created with ID:", result.value.id);
|
|
222
|
+
* } else {
|
|
223
|
+
* console.error("Validation error:", result.error);
|
|
224
|
+
* }
|
|
225
|
+
*
|
|
226
|
+
* // With onComplete callback
|
|
227
|
+
* evolu.insert(
|
|
228
|
+
* "todo",
|
|
229
|
+
* { title: "Another todo" },
|
|
230
|
+
* {
|
|
231
|
+
* onComplete: () => {
|
|
232
|
+
* console.log("Insert completed");
|
|
233
|
+
* },
|
|
234
|
+
* },
|
|
235
|
+
* );
|
|
203
236
|
* ```
|
|
204
237
|
*/
|
|
205
238
|
insert: Mutation<S, "insert">;
|
|
206
239
|
/**
|
|
207
|
-
* Updates a row
|
|
240
|
+
* Updates a row in the database and returns a {@link Result} with the existing
|
|
241
|
+
* {@link Id}.
|
|
242
|
+
*
|
|
243
|
+
* The first argument is the table name, and the second is an object
|
|
244
|
+
* containing the row data including the required `id` field. An optional
|
|
245
|
+
* third argument provides mutation options including an `onComplete` callback
|
|
246
|
+
* and `onlyValidate` flag.
|
|
247
|
+
*
|
|
248
|
+
* Returns a Result type - use `.ok` to check if the update succeeded, and
|
|
249
|
+
* `.value.id` to access the ID on success, or `.error` to handle validation
|
|
250
|
+
* errors.
|
|
251
|
+
*
|
|
252
|
+
* Evolu does not use SQL for mutations to ensure data can be safely and
|
|
253
|
+
* predictably merged without conflicts. Explicit mutations also allow Evolu
|
|
254
|
+
* to automatically add and update {@link DefaultColumns}.
|
|
208
255
|
*
|
|
209
256
|
* ### Example
|
|
210
257
|
*
|
|
211
258
|
* ```ts
|
|
212
|
-
*
|
|
259
|
+
* const result = evolu.update("todo", {
|
|
260
|
+
* id: todoId,
|
|
261
|
+
* title: "Updated title",
|
|
262
|
+
* isCompleted: true,
|
|
263
|
+
* });
|
|
264
|
+
*
|
|
265
|
+
* if (result.ok) {
|
|
266
|
+
* console.log("Todo updated with ID:", result.value.id);
|
|
267
|
+
* } else {
|
|
268
|
+
* console.error("Validation error:", result.error);
|
|
269
|
+
* }
|
|
270
|
+
*
|
|
271
|
+
* // To delete a row, set isDeleted to true
|
|
272
|
+
* evolu.update("todo", { id: todoId, isDeleted: true });
|
|
273
|
+
*
|
|
274
|
+
* // With onComplete callback
|
|
275
|
+
* evolu.update(
|
|
276
|
+
* "todo",
|
|
277
|
+
* { id: todoId, title: "New title" },
|
|
278
|
+
* {
|
|
279
|
+
* onComplete: () => {
|
|
280
|
+
* console.log("Update completed");
|
|
281
|
+
* },
|
|
282
|
+
* },
|
|
283
|
+
* );
|
|
213
284
|
* ```
|
|
214
285
|
*/
|
|
215
286
|
update: Mutation<S, "update">;
|
|
216
287
|
/**
|
|
217
|
-
* Upserts a row
|
|
288
|
+
* Upserts a row in the database and returns a {@link Result} with the existing
|
|
289
|
+
* {@link Id}.
|
|
290
|
+
*
|
|
291
|
+
* The first argument is the table name, and the second is an object
|
|
292
|
+
* containing the row data including the required `id` field. An optional
|
|
293
|
+
* third argument provides mutation options including an `onComplete` callback
|
|
294
|
+
* and `onlyValidate` flag.
|
|
295
|
+
*
|
|
296
|
+
* This function allows you to use custom IDs and optionally set `createdAt`,
|
|
297
|
+
* which is useful for external systems, data migrations, or when the same row
|
|
298
|
+
* may already be created on a different device.
|
|
299
|
+
*
|
|
300
|
+
* Returns a Result type - use `.ok` to check if the upsert succeeded, and
|
|
301
|
+
* `.value.id` to access the ID on success, or `.error` to handle validation
|
|
302
|
+
* errors.
|
|
303
|
+
*
|
|
304
|
+
* Evolu does not use SQL for mutations to ensure data can be safely and
|
|
305
|
+
* predictably merged without conflicts. Explicit mutations also allow Evolu
|
|
306
|
+
* to automatically add and update {@link DefaultColumns}.
|
|
218
307
|
*
|
|
219
308
|
* ### Example
|
|
220
309
|
*
|
|
221
310
|
* ```ts
|
|
222
|
-
* //
|
|
311
|
+
* // Use deterministic ID for stable upserts across devices
|
|
312
|
+
* const stableId = createIdFromString("my-todo-1");
|
|
313
|
+
*
|
|
314
|
+
* const result = evolu.upsert("todo", {
|
|
315
|
+
* id: stableId,
|
|
316
|
+
* title: "Learn Evolu",
|
|
317
|
+
* isCompleted: false,
|
|
318
|
+
* });
|
|
319
|
+
*
|
|
320
|
+
* if (result.ok) {
|
|
321
|
+
* console.log("Todo upserted with ID:", result.value.id);
|
|
322
|
+
* } else {
|
|
323
|
+
* console.error("Validation error:", result.error);
|
|
324
|
+
* }
|
|
325
|
+
*
|
|
326
|
+
* // Data migration with custom createdAt
|
|
327
|
+
* evolu.upsert("todo", {
|
|
328
|
+
* id: externalId,
|
|
329
|
+
* title: "Migrated todo",
|
|
330
|
+
* createdAt: new Date("2023-01-01"), // Preserve original timestamp
|
|
331
|
+
* });
|
|
332
|
+
*
|
|
333
|
+
* // With onComplete callback
|
|
334
|
+
* evolu.upsert(
|
|
335
|
+
* "todo",
|
|
336
|
+
* { id: stableId, title: "Updated title" },
|
|
337
|
+
* {
|
|
338
|
+
* onComplete: () => {
|
|
339
|
+
* console.log("Upsert completed");
|
|
340
|
+
* },
|
|
341
|
+
* },
|
|
342
|
+
* );
|
|
223
343
|
* ```
|
|
224
344
|
*/
|
|
225
345
|
upsert: Mutation<S, "upsert">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Evolu.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAA0B,WAAW,EAAe,MAAM,cAAc,CAAC;AAChF,OAAO,EAAe,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAML,QAAQ,EAET,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,MAAM,EAAiB,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAEL,aAAa,EACb,+BAA+B,EAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EAGL,OAAO,EACP,0BAA0B,EAC1B,KAAK,EACL,SAAS,EAET,GAAG,EAGJ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,
|
|
1
|
+
{"version":3,"file":"Evolu.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Evolu.ts"],"names":[],"mappings":"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"}
|
package/dist/src/Evolu/Evolu.js
CHANGED
|
@@ -186,7 +186,11 @@ const createEvoluInstance = (deps) => (schema, evoluConfig) => {
|
|
|
186
186
|
const id = createId(deps);
|
|
187
187
|
const values = getMutationType(table, "insert").fromUnknown(props);
|
|
188
188
|
if (values.ok) {
|
|
189
|
-
const
|
|
189
|
+
const valuesWithCreatedAt = {
|
|
190
|
+
...values.value,
|
|
191
|
+
createdAt: new Date(deps.time.now()).toISOString(),
|
|
192
|
+
};
|
|
193
|
+
const dbChange = { table, id, values: valuesWithCreatedAt };
|
|
190
194
|
assertValidDbChange(dbChange);
|
|
191
195
|
initialDataDbChanges.push(dbChange);
|
|
192
196
|
return ok({ id });
|
|
@@ -215,9 +219,19 @@ const createEvoluInstance = (deps) => (schema, evoluConfig) => {
|
|
|
215
219
|
mutateMicrotaskQueue.push([undefined, undefined]);
|
|
216
220
|
}
|
|
217
221
|
else {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
222
|
+
const values = { ...result.value };
|
|
223
|
+
delete values.id;
|
|
224
|
+
if (kind === "insert" || kind === "upsert") {
|
|
225
|
+
// Only set createdAt if not provided by user
|
|
226
|
+
if (!("createdAt" in values)) {
|
|
227
|
+
values.createdAt = new Date(deps.time.now()).toISOString();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const dbChange = {
|
|
231
|
+
table,
|
|
232
|
+
id,
|
|
233
|
+
values,
|
|
234
|
+
};
|
|
221
235
|
assertValidDbChange(dbChange);
|
|
222
236
|
mutateMicrotaskQueue.push([dbChange, options?.onComplete]);
|
|
223
237
|
}
|
|
@@ -279,7 +279,7 @@ export interface TimestampsRangeWithTimestampsBuffer extends BaseRange {
|
|
|
279
279
|
readonly timestamps: TimestampsBuffer;
|
|
280
280
|
}
|
|
281
281
|
export type Range = SkipRange | FingerprintRange | TimestampsRange;
|
|
282
|
-
export type ProtocolError = ProtocolUnsupportedVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError;
|
|
282
|
+
export type ProtocolError = ProtocolUnsupportedVersionError | ProtocolInvalidDataError | ProtocolWriteKeyError | ProtocolWriteError | ProtocolSyncError | ProtocolTimestampMismatchError;
|
|
283
283
|
/** Base interface for all protocol errors. */
|
|
284
284
|
export interface ProtocolErrorBase {
|
|
285
285
|
readonly ownerId: OwnerId;
|
|
@@ -318,6 +318,16 @@ export interface ProtocolWriteError extends ProtocolErrorBase {
|
|
|
318
318
|
export interface ProtocolSyncError extends ProtocolErrorBase {
|
|
319
319
|
readonly type: "ProtocolSyncError";
|
|
320
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* Error when embedded timestamp doesn't match expected timestamp in
|
|
323
|
+
* EncryptedDbChange. Indicates potential tampering or corruption of CRDT
|
|
324
|
+
* messages.
|
|
325
|
+
*/
|
|
326
|
+
export interface ProtocolTimestampMismatchError {
|
|
327
|
+
readonly type: "ProtocolTimestampMismatchError";
|
|
328
|
+
readonly expected: Timestamp;
|
|
329
|
+
readonly embedded: Timestamp;
|
|
330
|
+
}
|
|
321
331
|
/**
|
|
322
332
|
* Creates a {@link ProtocolMessage} from CRDT messages.
|
|
323
333
|
*
|
|
@@ -412,13 +422,18 @@ export declare const binaryTimestampToFingerprint: (timestamp: BinaryTimestamp)
|
|
|
412
422
|
/**
|
|
413
423
|
* Encodes and encrypts a {@link DbChange} using the provided owner's encryption
|
|
414
424
|
* key. Returns an encrypted binary representation as {@link EncryptedDbChange}.
|
|
425
|
+
*
|
|
426
|
+
* The format includes the protocol version for backward compatibility and the
|
|
427
|
+
* timestamp for tamper-proof verification that the timestamp matches the change
|
|
428
|
+
* data.
|
|
415
429
|
*/
|
|
416
|
-
export declare const encodeAndEncryptDbChange: (deps: SymmetricCryptoDep) => (
|
|
430
|
+
export declare const encodeAndEncryptDbChange: (deps: SymmetricCryptoDep) => (message: CrdtMessage, key: EncryptionKey) => EncryptedDbChange;
|
|
417
431
|
/**
|
|
418
|
-
* Decrypts and decodes an {@link
|
|
419
|
-
* encryption key.
|
|
432
|
+
* Decrypts and decodes an {@link EncryptedCrdtMessage} using the provided
|
|
433
|
+
* owner's encryption key. Verifies that the embedded timestamp matches the
|
|
434
|
+
* expected timestamp to ensure message integrity.
|
|
420
435
|
*/
|
|
421
|
-
export declare const decryptAndDecodeDbChange: (deps: SymmetricCryptoDep) => (
|
|
436
|
+
export declare const decryptAndDecodeDbChange: (deps: SymmetricCryptoDep) => (message: EncryptedCrdtMessage, key: EncryptionKey) => Result<DbChange, SymmetricCryptoDecryptError | ProtocolInvalidDataError | ProtocolTimestampMismatchError>;
|
|
422
437
|
/**
|
|
423
438
|
* Encodes a non-negative integer into a variable-length integer format. It's
|
|
424
439
|
* more efficient than encoding via {@link encodeNumber}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2IG;AAIH,OAAO,EAA2B,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAE7E,OAAO,EACL,MAAM,EAMP,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,oBAAoB,EACpB,aAAa,EAEb,2BAA2B,EAC3B,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAW,MAAM,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAIL,EAAE,EAIF,MAAM,EACN,cAAc,EAGd,WAAW,EAEZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAa,MAAM,aAAa,CAAC;AAC/C,OAAO,EAEL,OAAO,EACP,oBAAoB,EACpB,QAAQ,EAET,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,
|
|
1
|
+
{"version":3,"file":"Protocol.d.ts","sourceRoot":"","sources":["../../../src/Evolu/Protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -151,7 +151,7 @@ import { err, ok } from "../Result.js";
|
|
|
151
151
|
import { SqliteValue } from "../Sqlite.js";
|
|
152
152
|
import { Base64Url, base64UrlAlphabet, DateIsoString, Id, idTypeValueLength, JsonValueFromString, maxLength, NonNegativeInt, Number, object, record, } from "../Type.js";
|
|
153
153
|
import { writeKeyLength, } from "./Owner.js";
|
|
154
|
-
import { binaryTimestampToTimestamp, Counter, Millis, timestampToBinaryTimestamp, } from "./Timestamp.js";
|
|
154
|
+
import { binaryTimestampLength, binaryTimestampToTimestamp, Counter, eqTimestamp, Millis, timestampToBinaryTimestamp, } from "./Timestamp.js";
|
|
155
155
|
/** Maximum size of the entire protocol message in bytes. */
|
|
156
156
|
export const maxProtocolMessageSize = 1_000_000;
|
|
157
157
|
/** Maximum size of the ranges in bytes. */
|
|
@@ -210,7 +210,7 @@ export const createProtocolMessageFromCrdtMessages = (deps) => (owner, messages,
|
|
|
210
210
|
});
|
|
211
211
|
let notAllMessagesSent = false;
|
|
212
212
|
for (const message of messages) {
|
|
213
|
-
const change = encodeAndEncryptDbChange(deps)(message
|
|
213
|
+
const change = encodeAndEncryptDbChange(deps)(message, owner.encryptionKey);
|
|
214
214
|
const encryptedCrdtMessage = { timestamp: message.timestamp, change };
|
|
215
215
|
if (buffer.canAddMessage(encryptedCrdtMessage)) {
|
|
216
216
|
buffer.addMessage(encryptedCrdtMessage);
|
|
@@ -901,7 +901,7 @@ const decodeTimestamps = (buffer, length) => {
|
|
|
901
901
|
const deltaMillis = decodeNonNegativeInt(buffer);
|
|
902
902
|
const millis = Millis.from(previousMillis + deltaMillis);
|
|
903
903
|
if (!millis.ok)
|
|
904
|
-
throw new
|
|
904
|
+
throw new ProtocolDecodeError(millis.error.type);
|
|
905
905
|
millises.push(millis.value);
|
|
906
906
|
previousMillis = millis.value;
|
|
907
907
|
}
|
|
@@ -910,7 +910,7 @@ const decodeTimestamps = (buffer, length) => {
|
|
|
910
910
|
while (counterIndex < length) {
|
|
911
911
|
const counter = Counter.from(decodeNonNegativeInt(buffer));
|
|
912
912
|
if (!counter.ok)
|
|
913
|
-
throw new
|
|
913
|
+
throw new ProtocolDecodeError(counter.error.type);
|
|
914
914
|
const runLength = decodeNonNegativeInt(buffer);
|
|
915
915
|
for (let i = 0; i < runLength; i++) {
|
|
916
916
|
counters.push(counter.value);
|
|
@@ -1025,9 +1025,19 @@ export const binaryTimestampToFingerprint = (timestamp) => {
|
|
|
1025
1025
|
/**
|
|
1026
1026
|
* Encodes and encrypts a {@link DbChange} using the provided owner's encryption
|
|
1027
1027
|
* key. Returns an encrypted binary representation as {@link EncryptedDbChange}.
|
|
1028
|
+
*
|
|
1029
|
+
* The format includes the protocol version for backward compatibility and the
|
|
1030
|
+
* timestamp for tamper-proof verification that the timestamp matches the change
|
|
1031
|
+
* data.
|
|
1028
1032
|
*/
|
|
1029
|
-
export const encodeAndEncryptDbChange = (deps) => (
|
|
1033
|
+
export const encodeAndEncryptDbChange = (deps) => (message, key) => {
|
|
1034
|
+
const change = message.change;
|
|
1030
1035
|
const buffer = createBuffer();
|
|
1036
|
+
// Encode protocol version first for backward compatibility
|
|
1037
|
+
encodeNonNegativeInt(buffer, protocolVersion);
|
|
1038
|
+
// Encode the timestamp (after version) for tamper verification
|
|
1039
|
+
const binaryTimestamp = timestampToBinaryTimestamp(message.timestamp);
|
|
1040
|
+
buffer.extend(binaryTimestamp);
|
|
1031
1041
|
encodeBase64Url256(buffer, change.table);
|
|
1032
1042
|
buffer.extend(idToBinaryId(change.id));
|
|
1033
1043
|
const entries = objectToEntries(change.values).map(([column, value]) => {
|
|
@@ -1049,10 +1059,11 @@ export const encodeAndEncryptDbChange = (deps) => (change, key) => {
|
|
|
1049
1059
|
return buffer.unwrap();
|
|
1050
1060
|
};
|
|
1051
1061
|
/**
|
|
1052
|
-
* Decrypts and decodes an {@link
|
|
1053
|
-
* encryption key.
|
|
1062
|
+
* Decrypts and decodes an {@link EncryptedCrdtMessage} using the provided
|
|
1063
|
+
* owner's encryption key. Verifies that the embedded timestamp matches the
|
|
1064
|
+
* expected timestamp to ensure message integrity.
|
|
1054
1065
|
*/
|
|
1055
|
-
export const decryptAndDecodeDbChange = (deps) => (
|
|
1066
|
+
export const decryptAndDecodeDbChange = (deps) => (message, key) => tryDecodeProtocolData(message.change, (buffer) => {
|
|
1056
1067
|
const nonce = buffer.shiftN(deps.symmetricCrypto.nonceLength);
|
|
1057
1068
|
const ciphertextLength = decodeLength(buffer);
|
|
1058
1069
|
const ciphertext = buffer.shiftN(ciphertextLength);
|
|
@@ -1061,6 +1072,19 @@ export const decryptAndDecodeDbChange = (deps) => (change, key) => tryDecodeProt
|
|
|
1061
1072
|
return plaintextBytes;
|
|
1062
1073
|
buffer.reset();
|
|
1063
1074
|
buffer.extend(plaintextBytes.value);
|
|
1075
|
+
// Decode version (for future compatibility, no validation needed for now)
|
|
1076
|
+
decodeNonNegativeInt(buffer);
|
|
1077
|
+
// Decode and verify the embedded timestamp
|
|
1078
|
+
const embeddedBinaryTimestamp = buffer.shiftN(binaryTimestampLength);
|
|
1079
|
+
const embeddedTimestamp = binaryTimestampToTimestamp(embeddedBinaryTimestamp);
|
|
1080
|
+
// Verify timestamp integrity
|
|
1081
|
+
if (!eqTimestamp(embeddedTimestamp, message.timestamp)) {
|
|
1082
|
+
return err({
|
|
1083
|
+
type: "ProtocolTimestampMismatchError",
|
|
1084
|
+
expected: message.timestamp,
|
|
1085
|
+
embedded: embeddedTimestamp,
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1064
1088
|
const table = decodeBase64Url256WithLength(buffer);
|
|
1065
1089
|
const id = decodeId(buffer);
|
|
1066
1090
|
const length = decodeLength(buffer);
|