@evolu/common 6.0.1-preview.30 → 6.0.1-preview.32
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/Array.d.ts +27 -3
- package/dist/src/Array.d.ts.map +1 -1
- package/dist/src/Array.js +39 -3
- package/dist/src/Evolu/Db.d.ts +3 -0
- package/dist/src/Evolu/Db.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.d.ts.map +1 -1
- package/dist/src/Evolu/Evolu.js +8 -9
- package/dist/src/Evolu/Owner.d.ts +13 -4
- package/dist/src/Evolu/Owner.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.d.ts.map +1 -1
- package/dist/src/Evolu/Relay.js +13 -18
- package/dist/src/Evolu/Storage.d.ts +42 -14
- package/dist/src/Evolu/Storage.d.ts.map +1 -1
- package/dist/src/Evolu/Storage.js +125 -85
- package/dist/src/Evolu/Sync.d.ts +2 -3
- package/dist/src/Evolu/Sync.d.ts.map +1 -1
- package/dist/src/Evolu/Sync.js +27 -8
- package/dist/src/Type.d.ts +3 -2
- package/dist/src/Type.d.ts.map +1 -1
- package/dist/src/Type.js +3 -2
- package/package.json +1 -1
- package/src/Array.ts +47 -3
- package/src/Evolu/Db.ts +3 -0
- package/src/Evolu/Evolu.ts +12 -9
- package/src/Evolu/Owner.ts +15 -29
- package/src/Evolu/Relay.ts +36 -20
- package/src/Evolu/Storage.ts +184 -120
- package/src/Evolu/Sync.ts +57 -11
- package/src/Type.ts +3 -2
package/src/Evolu/Sync.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
firstInArray,
|
|
3
|
+
isNonEmptyReadonlyArray,
|
|
4
|
+
NonEmptyArray,
|
|
5
|
+
NonEmptyReadonlyArray,
|
|
6
|
+
} from "../Array.js";
|
|
2
7
|
import { assert } from "../Assert.js";
|
|
3
8
|
import { Brand } from "../Brand.js";
|
|
4
9
|
import { ConsoleDep } from "../Console.js";
|
|
@@ -17,7 +22,7 @@ import { err, ok, Result } from "../Result.js";
|
|
|
17
22
|
import { sql, SqliteDep, SqliteError, SqliteValue } from "../Sqlite.js";
|
|
18
23
|
import { AbortError, createMutex } from "../Task.js";
|
|
19
24
|
import { TimeDep } from "../Time.js";
|
|
20
|
-
import { IdBytes, idBytesToId, idToIdBytes } from "../Type.js";
|
|
25
|
+
import { IdBytes, idBytesToId, idToIdBytes, PositiveInt } from "../Type.js";
|
|
21
26
|
import { CreateWebSocketDep, WebSocket } from "../WebSocket.js";
|
|
22
27
|
import type { PostMessageDep } from "./Db.js";
|
|
23
28
|
import {
|
|
@@ -51,8 +56,12 @@ import {
|
|
|
51
56
|
CrdtMessage,
|
|
52
57
|
createBaseSqliteStorage,
|
|
53
58
|
DbChange,
|
|
59
|
+
getOwnerUsage,
|
|
60
|
+
getTimestampInsertStrategy,
|
|
54
61
|
Storage,
|
|
62
|
+
StorageInsertTimestampStrategy,
|
|
55
63
|
StorageWriteError,
|
|
64
|
+
updateOwnerUsage,
|
|
56
65
|
} from "./Storage.js";
|
|
57
66
|
import {
|
|
58
67
|
createInitialTimestamp,
|
|
@@ -519,11 +528,13 @@ const createClientStorage =
|
|
|
519
528
|
clockTimestamp = nextTimestamp.value;
|
|
520
529
|
}
|
|
521
530
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
531
|
+
if (isNonEmptyReadonlyArray(messages)) {
|
|
532
|
+
const applyMessagesResult = applyMessages({ ...deps, storage })(
|
|
533
|
+
owner.id,
|
|
534
|
+
messages,
|
|
535
|
+
);
|
|
536
|
+
if (!applyMessagesResult.ok) return applyMessagesResult;
|
|
537
|
+
}
|
|
527
538
|
|
|
528
539
|
// // Apply local mutations atomically with approved messages
|
|
529
540
|
// for (const change of localMutations) {
|
|
@@ -644,25 +655,56 @@ export const applyLocalOnlyChange =
|
|
|
644
655
|
return ok();
|
|
645
656
|
};
|
|
646
657
|
|
|
647
|
-
|
|
658
|
+
const applyMessages =
|
|
648
659
|
(deps: ClientStorageDep & ClockDep & RandomDep & SqliteDep) =>
|
|
649
660
|
(
|
|
650
661
|
ownerId: OwnerId,
|
|
651
|
-
messages:
|
|
662
|
+
messages: NonEmptyReadonlyArray<CrdtMessage>,
|
|
652
663
|
): Result<void, SqliteError> => {
|
|
653
664
|
const ownerIdBytes = ownerIdToOwnerIdBytes(ownerId);
|
|
654
665
|
|
|
666
|
+
const usageResult = getOwnerUsage(deps)(
|
|
667
|
+
ownerIdBytes,
|
|
668
|
+
timestampToTimestampBytes(firstInArray(messages).timestamp),
|
|
669
|
+
);
|
|
670
|
+
if (!usageResult.ok) return usageResult;
|
|
671
|
+
|
|
672
|
+
let { firstTimestamp, lastTimestamp } = usageResult.value;
|
|
673
|
+
|
|
655
674
|
for (const message of messages) {
|
|
656
675
|
const result1 = applyMessageToAppTable(deps)(ownerIdBytes, message);
|
|
657
676
|
if (!result1.ok) return result1;
|
|
658
677
|
|
|
678
|
+
const timestamp = timestampToTimestampBytes(message.timestamp);
|
|
679
|
+
|
|
680
|
+
let strategy;
|
|
681
|
+
[strategy, firstTimestamp, lastTimestamp] = getTimestampInsertStrategy(
|
|
682
|
+
timestamp,
|
|
683
|
+
firstTimestamp,
|
|
684
|
+
lastTimestamp,
|
|
685
|
+
);
|
|
686
|
+
|
|
659
687
|
const result2 = applyMessageToTimestampAndHistoryTables(deps)(
|
|
660
688
|
ownerIdBytes,
|
|
661
689
|
message,
|
|
690
|
+
strategy,
|
|
662
691
|
);
|
|
663
692
|
if (!result2.ok) return result2;
|
|
664
693
|
}
|
|
665
694
|
|
|
695
|
+
/**
|
|
696
|
+
* TODO: Implement proper storedBytes tracking for client using encrypted
|
|
697
|
+
* message sizes (need to figure out how to reuse received or postpone
|
|
698
|
+
* client...).
|
|
699
|
+
*/
|
|
700
|
+
const updateUsage = updateOwnerUsage(deps)(
|
|
701
|
+
ownerIdBytes,
|
|
702
|
+
1 as PositiveInt, // Placeholder until proper tracking implemented
|
|
703
|
+
firstTimestamp,
|
|
704
|
+
lastTimestamp,
|
|
705
|
+
);
|
|
706
|
+
if (!updateUsage.ok) return updateUsage;
|
|
707
|
+
|
|
666
708
|
return ok();
|
|
667
709
|
};
|
|
668
710
|
|
|
@@ -705,11 +747,15 @@ const applyMessageToAppTable =
|
|
|
705
747
|
|
|
706
748
|
export const applyMessageToTimestampAndHistoryTables =
|
|
707
749
|
(deps: ClientStorageDep & SqliteDep) =>
|
|
708
|
-
(
|
|
750
|
+
(
|
|
751
|
+
ownerId: OwnerIdBytes,
|
|
752
|
+
message: CrdtMessage,
|
|
753
|
+
strategy: StorageInsertTimestampStrategy,
|
|
754
|
+
): Result<void, SqliteError> => {
|
|
709
755
|
const timestamp = timestampToTimestampBytes(message.timestamp);
|
|
710
756
|
const id = idToIdBytes(message.change.id);
|
|
711
757
|
|
|
712
|
-
const result = deps.storage.insertTimestamp(ownerId, timestamp);
|
|
758
|
+
const result = deps.storage.insertTimestamp(ownerId, timestamp, strategy);
|
|
713
759
|
if (!result.ok) return result;
|
|
714
760
|
|
|
715
761
|
for (const [column, value] of Object.entries(message.change.values)) {
|
package/src/Type.ts
CHANGED
|
@@ -1641,8 +1641,9 @@ export const createId = <B extends string = never>(
|
|
|
1641
1641
|
* });
|
|
1642
1642
|
* ```
|
|
1643
1643
|
*
|
|
1644
|
-
* **Important**: This transformation
|
|
1645
|
-
*
|
|
1644
|
+
* **Important**: This transformation uses the first 16 bytes of SHA-256 hash of
|
|
1645
|
+
* the string bytes, therefore it's not possible to recover the original
|
|
1646
|
+
* external string from the generated {@link Id}. If you need to preserve the
|
|
1646
1647
|
* original external ID, store it in a separate column.
|
|
1647
1648
|
*
|
|
1648
1649
|
* @category String
|