cojson 0.13.11 → 0.13.13

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 (72) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +12 -0
  3. package/dist/CoValuesStore.d.ts +3 -1
  4. package/dist/CoValuesStore.d.ts.map +1 -1
  5. package/dist/CoValuesStore.js +7 -6
  6. package/dist/CoValuesStore.js.map +1 -1
  7. package/dist/PeerState.d.ts +0 -2
  8. package/dist/PeerState.d.ts.map +1 -1
  9. package/dist/PeerState.js +0 -1
  10. package/dist/PeerState.js.map +1 -1
  11. package/dist/SyncStateManager.js +2 -2
  12. package/dist/SyncStateManager.js.map +1 -1
  13. package/dist/coValueCore.js +2 -2
  14. package/dist/coValueCore.js.map +1 -1
  15. package/dist/coValueState.d.ts +21 -46
  16. package/dist/coValueState.d.ts.map +1 -1
  17. package/dist/coValueState.js +170 -246
  18. package/dist/coValueState.js.map +1 -1
  19. package/dist/coValues/group.js +2 -2
  20. package/dist/coValues/group.js.map +1 -1
  21. package/dist/exports.d.ts +2 -4
  22. package/dist/exports.d.ts.map +1 -1
  23. package/dist/exports.js +1 -2
  24. package/dist/exports.js.map +1 -1
  25. package/dist/localNode.d.ts.map +1 -1
  26. package/dist/localNode.js +20 -16
  27. package/dist/localNode.js.map +1 -1
  28. package/dist/sync.d.ts.map +1 -1
  29. package/dist/sync.js +32 -41
  30. package/dist/sync.js.map +1 -1
  31. package/dist/tests/coValueState.test.js +57 -104
  32. package/dist/tests/coValueState.test.js.map +1 -1
  33. package/dist/tests/group.test.js +1 -2
  34. package/dist/tests/group.test.js.map +1 -1
  35. package/dist/tests/messagesTestUtils.d.ts +4 -1
  36. package/dist/tests/messagesTestUtils.d.ts.map +1 -1
  37. package/dist/tests/messagesTestUtils.js +10 -0
  38. package/dist/tests/messagesTestUtils.js.map +1 -1
  39. package/dist/tests/sync.peerReconciliation.test.js +8 -8
  40. package/dist/tests/sync.peerReconciliation.test.js.map +1 -1
  41. package/dist/tests/sync.test.js +6 -4
  42. package/dist/tests/sync.test.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/CoValuesStore.ts +9 -6
  45. package/src/PeerState.ts +0 -2
  46. package/src/SyncStateManager.ts +2 -2
  47. package/src/coValueCore.ts +2 -2
  48. package/src/coValueState.ts +194 -316
  49. package/src/coValues/group.ts +2 -2
  50. package/src/exports.ts +0 -6
  51. package/src/localNode.ts +30 -21
  52. package/src/sync.ts +35 -43
  53. package/src/tests/coValueState.test.ts +55 -106
  54. package/src/tests/group.test.ts +2 -2
  55. package/src/tests/messagesTestUtils.ts +12 -1
  56. package/src/tests/sync.peerReconciliation.test.ts +8 -8
  57. package/src/tests/sync.test.ts +8 -23
  58. package/dist/storage/FileSystem.d.ts +0 -37
  59. package/dist/storage/FileSystem.d.ts.map +0 -1
  60. package/dist/storage/FileSystem.js +0 -48
  61. package/dist/storage/FileSystem.js.map +0 -1
  62. package/dist/storage/chunksAndKnownStates.d.ts +0 -7
  63. package/dist/storage/chunksAndKnownStates.d.ts.map +0 -1
  64. package/dist/storage/chunksAndKnownStates.js +0 -98
  65. package/dist/storage/chunksAndKnownStates.js.map +0 -1
  66. package/dist/storage/index.d.ts +0 -52
  67. package/dist/storage/index.d.ts.map +0 -1
  68. package/dist/storage/index.js +0 -335
  69. package/dist/storage/index.js.map +0 -1
  70. package/src/storage/FileSystem.ts +0 -113
  71. package/src/storage/chunksAndKnownStates.ts +0 -137
  72. package/src/storage/index.ts +0 -531
@@ -1,98 +0,0 @@
1
- import { MAX_RECOMMENDED_TX_SIZE } from "../coValueCore.js";
2
- import { getPriorityFromHeader } from "../priority.js";
3
- export function contentSinceChunk(id, chunk, known) {
4
- const newContentPieces = [];
5
- newContentPieces.push({
6
- id: id,
7
- action: "content",
8
- header: known?.header ? undefined : chunk.header,
9
- new: {},
10
- priority: getPriorityFromHeader(chunk.header),
11
- });
12
- for (const [sessionID, sessionsEntry] of Object.entries(chunk.sessionEntries)) {
13
- for (const entry of sessionsEntry) {
14
- const knownStart = known?.sessions[sessionID] || 0;
15
- if (entry.after + entry.transactions.length <= knownStart) {
16
- continue;
17
- }
18
- const actuallyNewTransactions = entry.transactions.slice(Math.max(0, knownStart - entry.after));
19
- const newAfter = entry.after +
20
- (actuallyNewTransactions.length - entry.transactions.length);
21
- let newContentEntry = newContentPieces[0]?.new[sessionID];
22
- if (!newContentEntry) {
23
- newContentEntry = {
24
- after: newAfter,
25
- lastSignature: entry.lastSignature,
26
- newTransactions: actuallyNewTransactions,
27
- };
28
- newContentPieces[0].new[sessionID] = newContentEntry;
29
- }
30
- else {
31
- newContentEntry.newTransactions.push(...actuallyNewTransactions);
32
- newContentEntry.lastSignature = entry.lastSignature;
33
- }
34
- }
35
- }
36
- return newContentPieces;
37
- }
38
- export function chunkToKnownState(id, chunk) {
39
- const ourKnown = {
40
- id,
41
- header: !!chunk.header,
42
- sessions: {},
43
- };
44
- for (const [sessionID, sessionEntries] of Object.entries(chunk.sessionEntries)) {
45
- for (const entry of sessionEntries) {
46
- ourKnown.sessions[sessionID] =
47
- entry.after + entry.transactions.length;
48
- }
49
- }
50
- return ourKnown;
51
- }
52
- export function mergeChunks(chunkA, chunkB) {
53
- const header = chunkA.header || chunkB.header;
54
- const newSessions = { ...chunkA.sessionEntries };
55
- for (const sessionID in chunkB.sessionEntries) {
56
- // figure out if we can merge the chunks
57
- const sessionEntriesA = chunkA.sessionEntries[sessionID];
58
- const sessionEntriesB = chunkB.sessionEntries[sessionID];
59
- if (!sessionEntriesA) {
60
- newSessions[sessionID] = sessionEntriesB;
61
- continue;
62
- }
63
- const lastEntryOfA = sessionEntriesA[sessionEntriesA.length - 1];
64
- const firstEntryOfB = sessionEntriesB[0];
65
- if (lastEntryOfA.after + lastEntryOfA.transactions.length ===
66
- firstEntryOfB.after) {
67
- const newEntries = [];
68
- let bytesSinceLastSignature = 0;
69
- for (const entry of sessionEntriesA.concat(sessionEntriesB)) {
70
- const entryByteLength = entry.transactions.reduce((sum, tx) => sum +
71
- (tx.privacy === "private"
72
- ? tx.encryptedChanges.length
73
- : tx.changes.length), 0);
74
- if (newEntries.length === 0 ||
75
- bytesSinceLastSignature + entryByteLength > MAX_RECOMMENDED_TX_SIZE) {
76
- newEntries.push({
77
- after: entry.after,
78
- lastSignature: entry.lastSignature,
79
- transactions: entry.transactions,
80
- });
81
- bytesSinceLastSignature = 0;
82
- }
83
- else {
84
- const lastNewEntry = newEntries[newEntries.length - 1];
85
- lastNewEntry.transactions.push(...entry.transactions);
86
- lastNewEntry.lastSignature = entry.lastSignature;
87
- bytesSinceLastSignature += entry.transactions.length;
88
- }
89
- }
90
- newSessions[sessionID] = newEntries;
91
- }
92
- else {
93
- return "nonContigous";
94
- }
95
- }
96
- return { header, sessionEntries: newSessions };
97
- }
98
- //# sourceMappingURL=chunksAndKnownStates.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunksAndKnownStates.js","sourceRoot":"","sources":["../../src/storage/chunksAndKnownStates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,MAAM,UAAU,iBAAiB,CAC/B,EAAW,EACX,KAAmB,EACnB,KAAyB;IAEzB,MAAM,gBAAgB,GAAwB,EAAE,CAAC;IAEjD,gBAAgB,CAAC,IAAI,CAAC;QACpB,EAAE,EAAE,EAAE;QACN,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;QAChD,GAAG,EAAE,EAAE;QACP,QAAQ,EAAE,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC;KAC9C,CAAC,CAAC;IAEH,KAAK,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CACrD,KAAK,CAAC,cAAc,CACrB,EAAE,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,KAAK,EAAE,QAAQ,CAAC,SAAsB,CAAC,IAAI,CAAC,CAAC;YAEhE,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;gBAC1D,SAAS;YACX,CAAC;YAED,MAAM,uBAAuB,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CACtD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CACtC,CAAC;YAEF,MAAM,QAAQ,GACZ,KAAK,CAAC,KAAK;gBACX,CAAC,uBAAuB,CAAC,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YAE/D,IAAI,eAAe,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAsB,CAAC,CAAC;YAEvE,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,eAAe,GAAG;oBAChB,KAAK,EAAE,QAAQ;oBACf,aAAa,EAAE,KAAK,CAAC,aAAa;oBAClC,eAAe,EAAE,uBAAuB;iBACzC,CAAC;gBACF,gBAAgB,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,SAAsB,CAAC,GAAG,eAAe,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,eAAe,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,CAAC;gBACjE,eAAe,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAW,EAAE,KAAmB;IAChE,MAAM,QAAQ,GAAsB;QAClC,EAAE;QACF,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM;QACtB,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF,KAAK,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CACtD,KAAK,CAAC,cAAc,CACrB,EAAE,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,QAAQ,CAAC,QAAQ,CAAC,SAAsB,CAAC;gBACvC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,MAAoB,EACpB,MAAoB;IAEpB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;IAE9C,MAAM,WAAW,GAAG,EAAE,GAAG,MAAM,CAAC,cAAc,EAAE,CAAC;IACjD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QAC9C,wCAAwC;QACxC,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QACzD,MAAM,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC,SAAS,CAAE,CAAC;QAE1D,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,WAAW,CAAC,SAAS,CAAC,GAAG,eAAe,CAAC;YACzC,SAAS;QACX,CAAC;QAED,MAAM,YAAY,GAAG,eAAe,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;QAClE,MAAM,aAAa,GAAG,eAAe,CAAC,CAAC,CAAE,CAAC;QAE1C,IACE,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM;YACrD,aAAa,CAAC,KAAK,EACnB,CAAC;YACD,MAAM,UAAU,GAAG,EAAE,CAAC;YACtB,IAAI,uBAAuB,GAAG,CAAC,CAAC;YAChC,KAAK,MAAM,KAAK,IAAI,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC5D,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAC/C,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CACV,GAAG;oBACH,CAAC,EAAE,CAAC,OAAO,KAAK,SAAS;wBACvB,CAAC,CAAC,EAAE,CAAC,gBAAgB,CAAC,MAAM;wBAC5B,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EACxB,CAAC,CACF,CAAC;gBACF,IACE,UAAU,CAAC,MAAM,KAAK,CAAC;oBACvB,uBAAuB,GAAG,eAAe,GAAG,uBAAuB,EACnE,CAAC;oBACD,UAAU,CAAC,IAAI,CAAC;wBACd,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,aAAa,EAAE,KAAK,CAAC,aAAa;wBAClC,YAAY,EAAE,KAAK,CAAC,YAAY;qBACjC,CAAC,CAAC;oBACH,uBAAuB,GAAG,CAAC,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACN,MAAM,YAAY,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;oBACxD,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;oBACtD,YAAY,CAAC,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC;oBAEjD,uBAAuB,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC;gBACvD,CAAC;YACH,CAAC;YACD,WAAW,CAAC,SAAS,CAAC,GAAG,UAAU,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,OAAO,cAAuB,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AACjD,CAAC"}
@@ -1,52 +0,0 @@
1
- import { CoValueHeader, Transaction } from "../coValueCore.js";
2
- import { Signature } from "../crypto/crypto.js";
3
- import { RawCoID } from "../ids.js";
4
- import { CoValueKnownState, IncomingSyncStream, NewContentMessage, OutgoingSyncQueue, Peer } from "../sync.js";
5
- import { BlockFilename, FileSystem } from "./FileSystem.js";
6
- export type { BlockFilename, WalFilename } from "./FileSystem.js";
7
- export type CoValueChunk = {
8
- header?: CoValueHeader;
9
- sessionEntries: {
10
- [sessionID: string]: {
11
- after: number;
12
- lastSignature: Signature;
13
- transactions: Transaction[];
14
- }[];
15
- };
16
- };
17
- export declare class LSMStorage<WH, RH, FS extends FileSystem<WH, RH>> {
18
- fs: FS;
19
- fromLocalNode: IncomingSyncStream;
20
- toLocalNode: OutgoingSyncQueue;
21
- currentWal: WH | undefined;
22
- coValues: {
23
- [id: RawCoID]: CoValueChunk | undefined;
24
- };
25
- fileCache: string[] | undefined;
26
- headerCache: Map<`L${number}-${string}-${string}-H${number}.jsonl`, {
27
- [id: `co_z${string}`]: {
28
- start: number;
29
- length: number;
30
- };
31
- }>;
32
- blockFileHandles: Map<`L${number}-${string}-${string}-H${number}.jsonl`, Promise<{
33
- handle: RH;
34
- size: number;
35
- }>>;
36
- constructor(fs: FS, fromLocalNode: IncomingSyncStream, toLocalNode: OutgoingSyncQueue);
37
- sendNewContent(id: RawCoID, known: CoValueKnownState | undefined, asDependencyOf: RawCoID | undefined): Promise<void>;
38
- withWAL(handler: (wal: WH) => Promise<void>): Promise<void>;
39
- handleNewContent(newContent: NewContentMessage): Promise<void>;
40
- getBlockHandle(blockFile: BlockFilename, fs: FS): Promise<{
41
- handle: RH;
42
- size: number;
43
- }>;
44
- loadCoValue(id: RawCoID, fs: FS): Promise<CoValueChunk | undefined>;
45
- compact(): Promise<void>;
46
- static asPeer<WH, RH, FS extends FileSystem<WH, RH>>({ fs, trace, localNodeName, }: {
47
- fs: FS;
48
- trace?: boolean;
49
- localNodeName?: string;
50
- }): Peer;
51
- }
52
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,IAAI,EACL,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,aAAa,EACb,UAAU,EAQX,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAIlE,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,cAAc,EAAE;QACd,CAAC,SAAS,EAAE,MAAM,GAAG;YACnB,KAAK,EAAE,MAAM,CAAC;YACd,aAAa,EAAE,SAAS,CAAC;YACzB,YAAY,EAAE,WAAW,EAAE,CAAC;SAC7B,EAAE,CAAC;KACL,CAAC;CACH,CAAC;AAEF,qBAAa,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC;IAgBlD,EAAE,EAAE,EAAE;IACN,aAAa,EAAE,kBAAkB;IACjC,WAAW,EAAE,iBAAiB;IAjBvC,UAAU,EAAE,EAAE,GAAG,SAAS,CAAC;IAC3B,QAAQ,EAAE;QACR,CAAC,EAAE,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAAC;KACzC,CAAC;IACF,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAChC,WAAW;;mBAEiB,MAAM;oBAAU,MAAM;;OAC9C;IACJ,gBAAgB;gBAEI,EAAE;cAAQ,MAAM;QAChC;gBAGK,EAAE,EAAE,EAAE,EACN,aAAa,EAAE,kBAAkB,EACjC,WAAW,EAAE,iBAAiB;IA6CjC,cAAc,CAClB,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,iBAAiB,GAAG,SAAS,EACpC,cAAc,EAAE,OAAO,GAAG,SAAS;IAuF/B,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC;IAS3C,gBAAgB,CAAC,UAAU,EAAE,iBAAiB;IA6D9C,cAAc,CAClB,SAAS,EAAE,aAAa,EACxB,EAAE,EAAE,EAAE,GACL,OAAO,CAAC;QAAE,MAAM,EAAE,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAQlC,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAuDnE,OAAO;IA4Kb,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EACnD,EAAE,EACF,KAAK,EACL,aAAuB,GACxB,EAAE;QACD,EAAE,EAAE,EAAE,CAAC;QACP,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI;CAiBT"}
@@ -1,335 +0,0 @@
1
- import { logger } from "../logger.js";
2
- import { connectedPeers } from "../streamUtils.js";
3
- import { readChunk, readHeader, textDecoder, writeBlock, writeToWal, } from "./FileSystem.js";
4
- import { chunkToKnownState, contentSinceChunk, mergeChunks, } from "./chunksAndKnownStates.js";
5
- const MAX_N_LEVELS = 3;
6
- export class LSMStorage {
7
- constructor(fs, fromLocalNode, toLocalNode) {
8
- this.fs = fs;
9
- this.fromLocalNode = fromLocalNode;
10
- this.toLocalNode = toLocalNode;
11
- this.headerCache = new Map();
12
- this.blockFileHandles = new Map();
13
- this.coValues = {};
14
- this.currentWal = undefined;
15
- let nMsg = 0;
16
- const processMessages = async () => {
17
- for await (const msg of fromLocalNode) {
18
- try {
19
- if (msg === "Disconnected" || msg === "PingTimeout") {
20
- throw new Error("Unexpected Disconnected message");
21
- }
22
- if (msg.action === "done") {
23
- return;
24
- }
25
- if (msg.action === "content") {
26
- await this.handleNewContent(msg);
27
- }
28
- else if (msg.action === "load" || msg.action === "known") {
29
- await this.sendNewContent(msg.id, msg, undefined);
30
- }
31
- }
32
- catch (e) {
33
- logger.error(`Error reading from localNode, handling msg`, {
34
- msg,
35
- err: e,
36
- });
37
- }
38
- nMsg++;
39
- }
40
- };
41
- processMessages().catch((e) => logger.error("Error in processMessages in storage", { err: e }));
42
- setTimeout(() => this.compact().catch((e) => {
43
- logger.error("Error while compacting", { err: e });
44
- }), 20000);
45
- }
46
- async sendNewContent(id, known, asDependencyOf) {
47
- let coValue = this.coValues[id];
48
- if (!coValue) {
49
- coValue = await this.loadCoValue(id, this.fs);
50
- }
51
- if (!coValue) {
52
- this.toLocalNode
53
- .push({
54
- id: id,
55
- action: "known",
56
- header: false,
57
- sessions: {},
58
- asDependencyOf,
59
- })
60
- .catch((e) => logger.error("Error while pushing known", { err: e }));
61
- return;
62
- }
63
- if (!known?.header && coValue.header?.ruleset.type === "ownedByGroup") {
64
- await this.sendNewContent(coValue.header.ruleset.group, undefined, asDependencyOf || id);
65
- }
66
- else if (!known?.header && coValue.header?.ruleset.type === "group") {
67
- const dependedOnAccountsAndGroups = new Set();
68
- for (const session of Object.values(coValue.sessionEntries)) {
69
- for (const entry of session) {
70
- for (const tx of entry.transactions) {
71
- if (tx.privacy === "trusting") {
72
- const parsedChanges = JSON.parse(tx.changes);
73
- for (const change of parsedChanges) {
74
- if (change.op === "set" && change.key.startsWith("co_")) {
75
- dependedOnAccountsAndGroups.add(change.key);
76
- }
77
- if (change.op === "set" &&
78
- change.key.startsWith("parent_co_")) {
79
- dependedOnAccountsAndGroups.add(change.key.replace("parent_", ""));
80
- }
81
- }
82
- }
83
- }
84
- }
85
- }
86
- for (const accountOrGroup of dependedOnAccountsAndGroups) {
87
- await this.sendNewContent(accountOrGroup, undefined, asDependencyOf || id);
88
- }
89
- }
90
- const newContentMessages = contentSinceChunk(id, coValue, known).map((message) => ({ ...message, asDependencyOf }));
91
- const ourKnown = chunkToKnownState(id, coValue);
92
- this.toLocalNode
93
- .push({
94
- action: "known",
95
- ...ourKnown,
96
- asDependencyOf,
97
- })
98
- .catch((e) => logger.error("Error while pushing known", { err: e }));
99
- for (const message of newContentMessages) {
100
- if (Object.keys(message.new).length === 0)
101
- continue;
102
- this.toLocalNode
103
- .push(message)
104
- .catch((e) => logger.error("Error while pushing new content", { err: e }));
105
- }
106
- this.coValues[id] = coValue;
107
- }
108
- async withWAL(handler) {
109
- if (!this.currentWal) {
110
- this.currentWal = await this.fs.createFile(`wal-${Date.now()}-${Math.random().toString(36).slice(2)}.jsonl`);
111
- }
112
- await handler(this.currentWal);
113
- }
114
- async handleNewContent(newContent) {
115
- const coValue = this.coValues[newContent.id];
116
- const newContentAsChunk = {
117
- header: newContent.header,
118
- sessionEntries: Object.fromEntries(Object.entries(newContent.new).map(([sessionID, newInSession]) => [
119
- sessionID,
120
- [
121
- {
122
- after: newInSession.after,
123
- lastSignature: newInSession.lastSignature,
124
- transactions: newInSession.newTransactions,
125
- },
126
- ],
127
- ])),
128
- };
129
- if (!coValue) {
130
- if (newContent.header) {
131
- await this.withWAL((wal) => writeToWal(wal, this.fs, newContent.id, newContentAsChunk));
132
- this.coValues[newContent.id] = newContentAsChunk;
133
- }
134
- else {
135
- logger.warn("Incontiguous incoming update for " + newContent.id);
136
- return;
137
- }
138
- }
139
- else {
140
- const merged = mergeChunks(coValue, newContentAsChunk);
141
- if (merged === "nonContigous") {
142
- console.warn("Non-contigous new content for " + newContent.id, Object.entries(coValue.sessionEntries).map(([session, entries]) => entries.map((entry) => ({
143
- session: session,
144
- after: entry.after,
145
- length: entry.transactions.length,
146
- }))), Object.entries(newContentAsChunk.sessionEntries).map(([session, entries]) => entries.map((entry) => ({
147
- session: session,
148
- after: entry.after,
149
- length: entry.transactions.length,
150
- }))));
151
- }
152
- else {
153
- await this.withWAL((wal) => writeToWal(wal, this.fs, newContent.id, newContentAsChunk));
154
- this.coValues[newContent.id] = merged;
155
- }
156
- }
157
- }
158
- async getBlockHandle(blockFile, fs) {
159
- if (!this.blockFileHandles.has(blockFile)) {
160
- this.blockFileHandles.set(blockFile, fs.openToRead(blockFile));
161
- }
162
- return this.blockFileHandles.get(blockFile);
163
- }
164
- async loadCoValue(id, fs) {
165
- const files = this.fileCache || (await fs.listFiles());
166
- this.fileCache = files;
167
- const blockFiles = files.filter((name) => name.startsWith("L")).sort();
168
- let result;
169
- for (const blockFile of blockFiles) {
170
- let cachedHeader = this.headerCache.get(blockFile);
171
- const { handle, size } = await this.getBlockHandle(blockFile, fs);
172
- if (!cachedHeader) {
173
- cachedHeader = {};
174
- const header = await readHeader(blockFile, handle, size, fs);
175
- for (const entry of header) {
176
- cachedHeader[entry.id] = {
177
- start: entry.start,
178
- length: entry.length,
179
- };
180
- }
181
- this.headerCache.set(blockFile, cachedHeader);
182
- }
183
- const headerEntry = cachedHeader[id];
184
- if (headerEntry) {
185
- const nextChunk = await readChunk(handle, headerEntry, fs);
186
- if (result) {
187
- const merged = mergeChunks(result, nextChunk);
188
- if (merged === "nonContigous") {
189
- console.warn("Non-contigous chunks while loading " + id, result, nextChunk);
190
- }
191
- else {
192
- result = merged;
193
- }
194
- }
195
- else {
196
- result = nextChunk;
197
- }
198
- }
199
- // await fs.close(handle);
200
- }
201
- return result;
202
- }
203
- async compact() {
204
- const fileNames = await this.fs.listFiles();
205
- const walFiles = fileNames.filter((name) => name.startsWith("wal-"));
206
- walFiles.sort();
207
- const coValues = new Map();
208
- if (walFiles.length === 0)
209
- return;
210
- const oldWal = this.currentWal;
211
- this.currentWal = undefined;
212
- if (oldWal) {
213
- await this.fs.close(oldWal);
214
- }
215
- for (const fileName of walFiles) {
216
- const { handle, size } = await this.fs.openToRead(fileName);
217
- if (size === 0) {
218
- await this.fs.close(handle);
219
- continue;
220
- }
221
- const bytes = await this.fs.read(handle, 0, size);
222
- const decoded = textDecoder.decode(bytes);
223
- const lines = decoded.split("\n");
224
- for (const line of lines) {
225
- if (line.length === 0)
226
- continue;
227
- const chunk = JSON.parse(line);
228
- const existingChunk = coValues.get(chunk.id);
229
- if (existingChunk) {
230
- const merged = mergeChunks(existingChunk, chunk);
231
- if (merged === "nonContigous") {
232
- console.log("Non-contigous chunks in " + chunk.id + ", " + fileName, existingChunk, chunk);
233
- }
234
- else {
235
- coValues.set(chunk.id, merged);
236
- }
237
- }
238
- else {
239
- coValues.set(chunk.id, chunk);
240
- }
241
- }
242
- await this.fs.close(handle);
243
- }
244
- const highestBlockNumber = fileNames.reduce((acc, name) => {
245
- if (name.startsWith("L" + MAX_N_LEVELS)) {
246
- const num = parseInt(name.split("-")[1]);
247
- if (num > acc) {
248
- return num;
249
- }
250
- }
251
- return acc;
252
- }, 0);
253
- await writeBlock(coValues, MAX_N_LEVELS, highestBlockNumber + 1, this.fs);
254
- for (const walFile of walFiles) {
255
- await this.fs.removeFile(walFile);
256
- }
257
- this.fileCache = undefined;
258
- const fileNames2 = await this.fs.listFiles();
259
- const blockFiles = fileNames2.filter((name) => name.startsWith("L")).sort();
260
- const blockFilesByLevelInOrder = {};
261
- for (const blockFile of blockFiles) {
262
- const level = parseInt(blockFile.split("-")[0].slice(1));
263
- if (!blockFilesByLevelInOrder[level]) {
264
- blockFilesByLevelInOrder[level] = [];
265
- }
266
- blockFilesByLevelInOrder[level].push(blockFile);
267
- }
268
- for (let level = MAX_N_LEVELS; level > 0; level--) {
269
- const nBlocksDesired = Math.pow(2, level);
270
- const blocksInLevel = blockFilesByLevelInOrder[level];
271
- if (blocksInLevel && blocksInLevel.length > nBlocksDesired) {
272
- const coValues = new Map();
273
- for (const blockFile of blocksInLevel) {
274
- const { handle, size } = await this.getBlockHandle(blockFile, this.fs);
275
- if (size === 0) {
276
- continue;
277
- }
278
- const header = await readHeader(blockFile, handle, size, this.fs);
279
- for (const entry of header) {
280
- const chunk = await readChunk(handle, entry, this.fs);
281
- const existingChunk = coValues.get(entry.id);
282
- if (existingChunk) {
283
- const merged = mergeChunks(existingChunk, chunk);
284
- if (merged === "nonContigous") {
285
- console.log("Non-contigous chunks in " + entry.id + ", " + blockFile, existingChunk, chunk);
286
- }
287
- else {
288
- coValues.set(entry.id, merged);
289
- }
290
- }
291
- else {
292
- coValues.set(entry.id, chunk);
293
- }
294
- }
295
- }
296
- let levelBelow = blockFilesByLevelInOrder[level - 1];
297
- if (!levelBelow) {
298
- levelBelow = [];
299
- blockFilesByLevelInOrder[level - 1] = levelBelow;
300
- }
301
- const highestBlockNumberInLevelBelow = levelBelow.reduce((acc, name) => {
302
- const num = parseInt(name.split("-")[1]);
303
- if (num > acc) {
304
- return num;
305
- }
306
- return acc;
307
- }, 0);
308
- const newBlockName = await writeBlock(coValues, level - 1, highestBlockNumberInLevelBelow + 1, this.fs);
309
- levelBelow.push(newBlockName);
310
- // delete blocks that went into this one
311
- for (const blockFile of blocksInLevel) {
312
- const handle = await this.getBlockHandle(blockFile, this.fs);
313
- await this.fs.close(handle.handle);
314
- await this.fs.removeFile(blockFile);
315
- this.blockFileHandles.delete(blockFile);
316
- }
317
- }
318
- }
319
- setTimeout(() => this.compact().catch((e) => {
320
- logger.error("Error while compacting", { err: e });
321
- }), 5000);
322
- }
323
- static asPeer({ fs, trace, localNodeName = "local", }) {
324
- const [localNodeAsPeer, storageAsPeer] = connectedPeers(localNodeName, "storage", {
325
- peer1role: "client",
326
- peer2role: "storage",
327
- trace,
328
- crashOnClose: true,
329
- });
330
- new LSMStorage(fs, localNodeAsPeer.incoming, localNodeAsPeer.outgoing);
331
- // return { ...storageAsPeer, priority: 200 };
332
- return storageAsPeer;
333
- }
334
- }
335
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"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"}
@@ -1,113 +0,0 @@
1
- import { CryptoProvider, StreamingHash } from "../crypto/crypto.js";
2
- import { RawCoID } from "../ids.js";
3
- import { CoValueChunk } from "./index.js";
4
-
5
- export type BlockFilename = `L${number}-${string}-${string}-H${number}.jsonl`;
6
-
7
- export type BlockHeader = { id: RawCoID; start: number; length: number }[];
8
-
9
- export type WalEntry = { id: RawCoID } & CoValueChunk;
10
-
11
- export type WalFilename = `wal-${number}.jsonl`;
12
-
13
- export interface FileSystem<WriteHandle, ReadHandle> {
14
- crypto: CryptoProvider;
15
- createFile(filename: string): Promise<WriteHandle>;
16
- append(handle: WriteHandle, data: Uint8Array): Promise<void>;
17
- close(handle: ReadHandle | WriteHandle): Promise<void>;
18
- closeAndRename(handle: WriteHandle, filename: BlockFilename): Promise<void>;
19
- openToRead(filename: string): Promise<{ handle: ReadHandle; size: number }>;
20
- read(handle: ReadHandle, offset: number, length: number): Promise<Uint8Array>;
21
- listFiles(): Promise<string[]>;
22
- removeFile(filename: BlockFilename | WalFilename): Promise<void>;
23
- }
24
-
25
- export const textEncoder = new TextEncoder();
26
- export const textDecoder = new TextDecoder();
27
-
28
- export async function readChunk<RH, FS extends FileSystem<unknown, RH>>(
29
- handle: RH,
30
- header: { start: number; length: number },
31
- fs: FS,
32
- ): Promise<CoValueChunk> {
33
- const chunkBytes = await fs.read(handle, header.start, header.length);
34
-
35
- const chunk = JSON.parse(textDecoder.decode(chunkBytes));
36
- return chunk;
37
- }
38
-
39
- export async function readHeader<RH, FS extends FileSystem<unknown, RH>>(
40
- filename: string,
41
- handle: RH,
42
- size: number,
43
- fs: FS,
44
- ): Promise<BlockHeader> {
45
- const headerLength = Number(filename.match(/-H(\d+)\.jsonl$/)![1]!);
46
-
47
- const headerBytes = await fs.read(handle, size - headerLength, headerLength);
48
-
49
- const header = JSON.parse(textDecoder.decode(headerBytes));
50
- return header;
51
- }
52
-
53
- export async function writeBlock<WH, RH, FS extends FileSystem<WH, RH>>(
54
- chunks: Map<RawCoID, CoValueChunk>,
55
- level: number,
56
- blockNumber: number,
57
- fs: FS,
58
- ): Promise<BlockFilename> {
59
- if (chunks.size === 0) {
60
- throw new Error("No chunks to write");
61
- }
62
-
63
- const blockHeader: BlockHeader = [];
64
-
65
- let offset = 0;
66
-
67
- const file = await fs.createFile(
68
- "wipBlock" + Math.random().toString(36).substring(7) + ".tmp.jsonl",
69
- );
70
- const hash = new StreamingHash(fs.crypto);
71
-
72
- const chunksSortedById = Array.from(chunks).sort(([id1], [id2]) =>
73
- id1.localeCompare(id2),
74
- );
75
-
76
- for (const [id, chunk] of chunksSortedById) {
77
- const encodedBytes = hash.update(chunk);
78
- const encodedBytesWithNewline = new Uint8Array(encodedBytes.length + 1);
79
- encodedBytesWithNewline.set(encodedBytes);
80
- encodedBytesWithNewline[encodedBytes.length] = 10;
81
- await fs.append(file, encodedBytesWithNewline);
82
- const length = encodedBytesWithNewline.length;
83
- blockHeader.push({ id, start: offset, length });
84
- offset += length;
85
- }
86
-
87
- const headerBytes = textEncoder.encode(JSON.stringify(blockHeader));
88
- await fs.append(file, headerBytes);
89
-
90
- const filename: BlockFilename = `L${level}-${(blockNumber + "").padStart(
91
- 3,
92
- "0",
93
- )}-${hash.digest().replace("hash_", "").slice(0, 15)}-H${
94
- headerBytes.length
95
- }.jsonl`;
96
- await fs.closeAndRename(file, filename);
97
-
98
- return filename;
99
- }
100
-
101
- export async function writeToWal<WH, RH, FS extends FileSystem<WH, RH>>(
102
- handle: WH,
103
- fs: FS,
104
- id: RawCoID,
105
- chunk: CoValueChunk,
106
- ) {
107
- const walEntry: WalEntry = {
108
- id,
109
- ...chunk,
110
- };
111
- const bytes = textEncoder.encode(JSON.stringify(walEntry) + "\n");
112
- return fs.append(handle, bytes);
113
- }