@peerbit/native-backbone 0.1.0
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/LICENSE +202 -0
- package/README.md +27 -0
- package/dist/src/benchmark.d.ts +19 -0
- package/dist/src/benchmark.d.ts.map +1 -0
- package/dist/src/benchmark.js +12 -0
- package/dist/src/benchmark.js.map +1 -0
- package/dist/src/index.d.ts +1561 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +3406 -0
- package/dist/src/index.js.map +1 -0
- package/dist/wasm/README.md +27 -0
- package/dist/wasm/native_backbone.d.ts +1609 -0
- package/dist/wasm/native_backbone.js +10221 -0
- package/dist/wasm/native_backbone_bg.wasm +0 -0
- package/dist/wasm/native_backbone_bg.wasm.d.ts +625 -0
- package/package.json +64 -0
- package/src/append_tx/committed_latest.rs +2063 -0
- package/src/append_tx/committed_no_next.rs +1165 -0
- package/src/append_tx/facts.rs +791 -0
- package/src/append_tx/mod.rs +751 -0
- package/src/append_tx/storage.rs +599 -0
- package/src/benchmark.ts +58 -0
- package/src/coordinates.rs +422 -0
- package/src/documents.rs +1698 -0
- package/src/graph_blocks.rs +362 -0
- package/src/index.ts +9134 -0
- package/src/js_interop.rs +448 -0
- package/src/lib.rs +144 -0
- package/src/profile.rs +164 -0
- package/src/raw_receive.rs +1724 -0
- package/src/shared_log_plan.rs +1464 -0
- package/src/sync_send.rs +180 -0
- package/src/wire_sync.rs +727 -0
|
@@ -0,0 +1,3406 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { calculateRawCid, cidifyString } from "@peerbit/blocks-interface";
|
|
10
|
+
const nativeBackboneHeadFlagsToBytes = (headFlags) => headFlags instanceof Uint8Array
|
|
11
|
+
? headFlags
|
|
12
|
+
: new Uint8Array(headFlags.map((head) => (head ? 1 : 0)));
|
|
13
|
+
let wasmModulePromise;
|
|
14
|
+
let wasmInitialized = false;
|
|
15
|
+
const loadWasm = async () => {
|
|
16
|
+
if (!wasmModulePromise) {
|
|
17
|
+
const wasmModulePath = "../wasm/native_backbone.js";
|
|
18
|
+
wasmModulePromise = import(__rewriteRelativeImportExtension(
|
|
19
|
+
/* @vite-ignore */ wasmModulePath));
|
|
20
|
+
}
|
|
21
|
+
const wasm = await wasmModulePromise;
|
|
22
|
+
if (!wasmInitialized) {
|
|
23
|
+
const processLike = globalThis.process;
|
|
24
|
+
if (processLike?.versions?.node) {
|
|
25
|
+
const fsPromises = "fs/promises";
|
|
26
|
+
const { readFile } = (await import(__rewriteRelativeImportExtension(
|
|
27
|
+
/* @vite-ignore */ fsPromises)));
|
|
28
|
+
const bytes = await readFile(new URL("../wasm/native_backbone_bg.wasm", import.meta.url));
|
|
29
|
+
wasm.initSync({ module: bytes });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
await wasm.default({
|
|
33
|
+
module_or_path: new URL("../wasm/native_backbone_bg.wasm", import.meta.url),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
wasmInitialized = true;
|
|
37
|
+
}
|
|
38
|
+
return wasm;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Per-node receive-fusion session (`NativeWireSyncSession` in the wasm
|
|
42
|
+
* module). `decodeAndVerifyBatch` is a drop-in for the `nativeWire` option of
|
|
43
|
+
* `@peerbit/stream`'s DirectStream; frames carrying shared-log raw
|
|
44
|
+
* exchange-head payloads for registered topics are kept in wasm memory and
|
|
45
|
+
* consumed by `NativePeerbitBackbone.prepareStashedRawReceive*` without a
|
|
46
|
+
* second boundary copy. Shared-log programs register their RPC topic on open
|
|
47
|
+
* and release stash entries once a message is processed.
|
|
48
|
+
*/
|
|
49
|
+
export class NativeBackboneWireSyncSession {
|
|
50
|
+
/** Raw wasm handle; consumed by `NativePeerbitBackbone.prepareStashedRawReceive*`. */
|
|
51
|
+
handle;
|
|
52
|
+
constructor(handle) {
|
|
53
|
+
this.handle = handle;
|
|
54
|
+
}
|
|
55
|
+
static async create(options) {
|
|
56
|
+
const wasm = await loadWasm();
|
|
57
|
+
return new NativeBackboneWireSyncSession(new wasm.NativeWireSyncSession(options.selfHash));
|
|
58
|
+
}
|
|
59
|
+
registerTopic(topic) {
|
|
60
|
+
this.handle.register_topic(topic);
|
|
61
|
+
}
|
|
62
|
+
unregisterTopic(topic) {
|
|
63
|
+
return this.handle.unregister_topic(topic);
|
|
64
|
+
}
|
|
65
|
+
get topicCount() {
|
|
66
|
+
return this.handle.topic_count();
|
|
67
|
+
}
|
|
68
|
+
decodeAndVerifyBatch(frames, nowMs) {
|
|
69
|
+
return this.handle.decode_and_verify_batch(frames, nowMs);
|
|
70
|
+
}
|
|
71
|
+
stashedMeta(id) {
|
|
72
|
+
const row = this.handle.stashed_meta(id);
|
|
73
|
+
if (!row) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const [hashes, gidRefrences, byteLengths, reserved, payloadLength] = row;
|
|
77
|
+
return { hashes, gidRefrences, byteLengths, reserved, payloadLength };
|
|
78
|
+
}
|
|
79
|
+
stashedBlocks(id, indexes) {
|
|
80
|
+
return this.handle.stashed_blocks(id, indexes) ?? undefined;
|
|
81
|
+
}
|
|
82
|
+
release(id) {
|
|
83
|
+
return this.handle.release(id);
|
|
84
|
+
}
|
|
85
|
+
get stashLength() {
|
|
86
|
+
return this.handle.stash_len();
|
|
87
|
+
}
|
|
88
|
+
counters() {
|
|
89
|
+
const [stashed, evicted, metaReads, blockCopyOuts, released] = this.handle.counters();
|
|
90
|
+
return {
|
|
91
|
+
stashed: stashed,
|
|
92
|
+
evicted: evicted,
|
|
93
|
+
metaReads: metaReads,
|
|
94
|
+
blockCopyOuts: blockCopyOuts,
|
|
95
|
+
released: released,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export const createNativeWireSyncSession = NativeBackboneWireSyncSession.create;
|
|
100
|
+
const nativeBackboneAppendProfileKeys = [
|
|
101
|
+
"nativeBackboneStorageAppendInnerMs",
|
|
102
|
+
"nativeBackboneInputCopyMs",
|
|
103
|
+
"nativeBackboneLogTotalMs",
|
|
104
|
+
"nativeBackboneLogNextCloneMs",
|
|
105
|
+
"nativeBackboneLogEntryCoreMs",
|
|
106
|
+
"nativeBackboneLogEncodeMetaMs",
|
|
107
|
+
"nativeBackboneLogEncodePayloadMs",
|
|
108
|
+
"nativeBackboneLogEncodeSignableMs",
|
|
109
|
+
"nativeBackboneLogSignMs",
|
|
110
|
+
"nativeBackboneLogEncodeSignatureMs",
|
|
111
|
+
"nativeBackboneLogEncodeStorageMs",
|
|
112
|
+
"nativeBackboneLogCidMs",
|
|
113
|
+
"nativeBackboneLogCidHashMs",
|
|
114
|
+
"nativeBackboneLogCidStringMs",
|
|
115
|
+
"nativeBackboneLogIndexEntryMs",
|
|
116
|
+
"nativeBackboneLogFactsMs",
|
|
117
|
+
"nativeBackboneLogBlockPutMs",
|
|
118
|
+
"nativeBackboneLogGraphPutMs",
|
|
119
|
+
"nativeBackboneLogTrimMs",
|
|
120
|
+
"nativeBackboneEntryRowMs",
|
|
121
|
+
"nativeBackboneTrimRowsMs",
|
|
122
|
+
"nativeBackboneHashNumberMs",
|
|
123
|
+
"nativeBackboneCoordinatePlanMs",
|
|
124
|
+
"nativeBackboneCoordinateCoreMs",
|
|
125
|
+
"nativeBackboneCoordinateFieldsBuildMs",
|
|
126
|
+
"nativeBackboneCoordinateValueEncodeMs",
|
|
127
|
+
"nativeBackboneCoordinateJournalPutMs",
|
|
128
|
+
"nativeBackboneCoordinateIndexPutMs",
|
|
129
|
+
"nativeBackboneCoordinateValuePutMs",
|
|
130
|
+
"nativeBackboneCoordinateDeleteMs",
|
|
131
|
+
"nativeBackboneDocumentIndexCommitMs",
|
|
132
|
+
"nativeBackboneDocumentIndexContextEncodeMs",
|
|
133
|
+
"nativeBackboneDocumentIndexExtractMs",
|
|
134
|
+
"nativeBackboneDocumentIndexValueBuildMs",
|
|
135
|
+
"nativeBackboneDocumentIndexPutMs",
|
|
136
|
+
"nativeBackboneDocumentValuePutMs",
|
|
137
|
+
"nativeBackboneDocumentIndexTrimDeleteMs",
|
|
138
|
+
"nativeBackboneResultRowMs",
|
|
139
|
+
"nativeBackboneRawReceiveInputCopyMs",
|
|
140
|
+
"nativeBackboneRawReceivePrepareMs",
|
|
141
|
+
"nativeBackboneRawReceiveDigestMs",
|
|
142
|
+
"nativeBackboneRawReceiveCidStringMs",
|
|
143
|
+
"nativeBackboneRawReceiveExpectedCidMs",
|
|
144
|
+
"nativeBackboneRawReceiveStorageParseMs",
|
|
145
|
+
"nativeBackboneRawReceiveMetaParseMs",
|
|
146
|
+
"nativeBackboneRawReceivePayloadParseMs",
|
|
147
|
+
"nativeBackboneRawReceiveSignatureParseMs",
|
|
148
|
+
"nativeBackboneRawReceiveSignableMs",
|
|
149
|
+
"nativeBackboneRawReceiveVerifyBatchMs",
|
|
150
|
+
"nativeBackboneRawReceiveVerifyFallbackMs",
|
|
151
|
+
"nativeBackboneRawReceivePrepareColumnsMs",
|
|
152
|
+
"nativeBackboneRawReceivePendingCheckMs",
|
|
153
|
+
"nativeBackboneRawReceiveVerifyMs",
|
|
154
|
+
"nativeBackboneRawReceiveVerifyStatusMs",
|
|
155
|
+
"nativeBackboneRawReceiveJoinPlanMs",
|
|
156
|
+
"nativeBackboneRawReceiveRemoveMs",
|
|
157
|
+
"nativeBackboneRawReceiveBlockPutMs",
|
|
158
|
+
"nativeBackboneRawReceiveGraphPutMs",
|
|
159
|
+
"nativeBackboneRawReceiveCoordinateCommitMs",
|
|
160
|
+
];
|
|
161
|
+
const nativeBackboneCoordinatePersistenceFiles = {
|
|
162
|
+
snapshot: "coordinates.bin",
|
|
163
|
+
journal: "coordinates.wal",
|
|
164
|
+
documentSnapshot: "document-values.bin",
|
|
165
|
+
documentJournal: "document-values.wal",
|
|
166
|
+
documentSignerSnapshot: "document-signers.bin",
|
|
167
|
+
documentSignerJournal: "document-signers.wal",
|
|
168
|
+
};
|
|
169
|
+
export const defaultNativeBackboneCoordinateFlushMaxPendingBytes = 1024 * 1024;
|
|
170
|
+
export const defaultNativeBackboneCoordinateCompactMaxJournalBytes = 64 * 1024 * 1024;
|
|
171
|
+
const resolveCoordinateFlushMaxPendingBytes = (options) => options.flushMaxPendingBytes != null
|
|
172
|
+
? Math.max(0, options.flushMaxPendingBytes)
|
|
173
|
+
: options.flushOnAppend === false
|
|
174
|
+
? defaultNativeBackboneCoordinateFlushMaxPendingBytes
|
|
175
|
+
: undefined;
|
|
176
|
+
const isNotFoundError = (error) => {
|
|
177
|
+
const maybeError = error;
|
|
178
|
+
return maybeError?.code === "ENOENT" || maybeError?.name === "NotFoundError";
|
|
179
|
+
};
|
|
180
|
+
let nodeFsModule;
|
|
181
|
+
const importNodeFs = () => (nodeFsModule ??= import("node:fs/promises"));
|
|
182
|
+
let nodePathJoin;
|
|
183
|
+
const importNodePathJoin = () => (nodePathJoin ??= import("node:path").then((mod) => mod.join));
|
|
184
|
+
const validateCoordinatePersistenceName = (name) => {
|
|
185
|
+
if (name.length === 0 ||
|
|
186
|
+
name === "." ||
|
|
187
|
+
name === ".." ||
|
|
188
|
+
name.includes("/") ||
|
|
189
|
+
name.includes("\\")) {
|
|
190
|
+
throw new Error(`Invalid native backbone coordinate persistence file: ${name}`);
|
|
191
|
+
}
|
|
192
|
+
return name;
|
|
193
|
+
};
|
|
194
|
+
const concatBytes = (chunks) => {
|
|
195
|
+
const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
196
|
+
const out = new Uint8Array(total);
|
|
197
|
+
let offset = 0;
|
|
198
|
+
for (const chunk of chunks) {
|
|
199
|
+
out.set(chunk, offset);
|
|
200
|
+
offset += chunk.byteLength;
|
|
201
|
+
}
|
|
202
|
+
return out;
|
|
203
|
+
};
|
|
204
|
+
const copyBytes = (bytes) => new Uint8Array(bytes);
|
|
205
|
+
const rowsToNumbers = (resolution, rows) => rows.map((row) => {
|
|
206
|
+
const value = row;
|
|
207
|
+
return resolution === "u64" ? BigInt(value) : Number(value);
|
|
208
|
+
});
|
|
209
|
+
const rowsToHashNumberMap = (rows) => {
|
|
210
|
+
const out = new Map();
|
|
211
|
+
for (const row of rows) {
|
|
212
|
+
const [hashNumber, hashes] = row;
|
|
213
|
+
out.set(BigInt(hashNumber), hashes);
|
|
214
|
+
}
|
|
215
|
+
return out;
|
|
216
|
+
};
|
|
217
|
+
const rowsToSamples = (rows) => {
|
|
218
|
+
if (!rows) {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
const out = new Map();
|
|
222
|
+
for (const row of rows) {
|
|
223
|
+
const [hash, intersecting] = row;
|
|
224
|
+
out.set(hash, { intersecting });
|
|
225
|
+
}
|
|
226
|
+
return out;
|
|
227
|
+
};
|
|
228
|
+
const rowsToRepairDispatchPlan = (rows) => {
|
|
229
|
+
const plan = new Map();
|
|
230
|
+
for (const row of rows) {
|
|
231
|
+
const [mode, target, hashes] = row;
|
|
232
|
+
let targets = plan.get(mode);
|
|
233
|
+
if (!targets) {
|
|
234
|
+
targets = new Map();
|
|
235
|
+
plan.set(mode, targets);
|
|
236
|
+
}
|
|
237
|
+
targets.set(target, hashes);
|
|
238
|
+
}
|
|
239
|
+
return plan;
|
|
240
|
+
};
|
|
241
|
+
// Coordinate plans frequently cross the wasm boundary with many decimal-string
|
|
242
|
+
// values while callers typically read only one representation, so the numeric
|
|
243
|
+
// and string views are materialized lazily on first access (and cached, so
|
|
244
|
+
// repeated reads return the same array instance).
|
|
245
|
+
const lazyCoordinatePlan = (resolution, hash, hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas) => {
|
|
246
|
+
let hashNumberValue;
|
|
247
|
+
let coordinates;
|
|
248
|
+
let coordinateStrings;
|
|
249
|
+
return {
|
|
250
|
+
hash,
|
|
251
|
+
get hashNumber() {
|
|
252
|
+
return (hashNumberValue ??= rowsToNumbers(resolution, [hashNumber])[0]);
|
|
253
|
+
},
|
|
254
|
+
set hashNumber(value) {
|
|
255
|
+
hashNumberValue = value;
|
|
256
|
+
},
|
|
257
|
+
hashNumberString: typeof hashNumber === "string" ? hashNumber : String(hashNumber),
|
|
258
|
+
gid,
|
|
259
|
+
get coordinates() {
|
|
260
|
+
return (coordinates ??= rowsToNumbers(resolution, coordinateRows));
|
|
261
|
+
},
|
|
262
|
+
set coordinates(value) {
|
|
263
|
+
coordinates = value;
|
|
264
|
+
},
|
|
265
|
+
get coordinateStrings() {
|
|
266
|
+
return (coordinateStrings ??= coordinateRows.map((coordinate) => String(coordinate)));
|
|
267
|
+
},
|
|
268
|
+
set coordinateStrings(value) {
|
|
269
|
+
coordinateStrings = value;
|
|
270
|
+
},
|
|
271
|
+
assignedToRangeBoundary,
|
|
272
|
+
requestedReplicas,
|
|
273
|
+
};
|
|
274
|
+
};
|
|
275
|
+
const lazyLeaderPlanFromRows = (resolution, coordinateRows, leaderRows) => {
|
|
276
|
+
let coordinates;
|
|
277
|
+
let coordinateStrings;
|
|
278
|
+
return {
|
|
279
|
+
get coordinates() {
|
|
280
|
+
return (coordinates ??= rowsToNumbers(resolution, coordinateRows));
|
|
281
|
+
},
|
|
282
|
+
set coordinates(value) {
|
|
283
|
+
coordinates = value;
|
|
284
|
+
},
|
|
285
|
+
get coordinateStrings() {
|
|
286
|
+
return (coordinateStrings ??= coordinateRows.map((coordinate) => String(coordinate)));
|
|
287
|
+
},
|
|
288
|
+
set coordinateStrings(value) {
|
|
289
|
+
coordinateStrings = value;
|
|
290
|
+
},
|
|
291
|
+
leaders: rowsToSamples(leaderRows) ?? new Map(),
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
const appendCoordinatePlanFromRow = (resolution, row) => {
|
|
295
|
+
const [hash, hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas,] = row;
|
|
296
|
+
return lazyCoordinatePlan(resolution, hash, hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas);
|
|
297
|
+
};
|
|
298
|
+
const appendCoordinatePlanFromCompactNoNextRow = (resolution, hash, row) => {
|
|
299
|
+
const [hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas,] = row;
|
|
300
|
+
return lazyCoordinatePlan(resolution, hash, hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas);
|
|
301
|
+
};
|
|
302
|
+
const documentContextFactsFromRow = (row) => {
|
|
303
|
+
if (!row) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
const [created, modified, head, gid, size] = row;
|
|
307
|
+
return {
|
|
308
|
+
created: BigInt(created),
|
|
309
|
+
modified: BigInt(modified),
|
|
310
|
+
head,
|
|
311
|
+
gid,
|
|
312
|
+
size,
|
|
313
|
+
};
|
|
314
|
+
};
|
|
315
|
+
const coordinateFieldsFromRow = (resolution, row) => {
|
|
316
|
+
const [hash, hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas, wallTime, metaBytes,] = row;
|
|
317
|
+
// Extend the lazy plan in place; spreading it would eagerly invoke the
|
|
318
|
+
// memoized getters and defeat the lazy materialization.
|
|
319
|
+
const fields = appendCoordinatePlanFromRow(resolution, [
|
|
320
|
+
hash,
|
|
321
|
+
hashNumber,
|
|
322
|
+
gid,
|
|
323
|
+
coordinateRows,
|
|
324
|
+
assignedToRangeBoundary,
|
|
325
|
+
requestedReplicas,
|
|
326
|
+
]);
|
|
327
|
+
const wallTimeString = typeof wallTime === "string" ? wallTime : String(wallTime);
|
|
328
|
+
let wallTimeValue;
|
|
329
|
+
Object.defineProperty(fields, "wallTime", {
|
|
330
|
+
configurable: true,
|
|
331
|
+
enumerable: true,
|
|
332
|
+
get: () => (wallTimeValue ??= BigInt(wallTimeString)),
|
|
333
|
+
set: (value) => {
|
|
334
|
+
wallTimeValue = value;
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
fields.wallTimeString = wallTimeString;
|
|
338
|
+
fields.metaBytes = metaBytes;
|
|
339
|
+
return fields;
|
|
340
|
+
};
|
|
341
|
+
const appendDeliveryPlanFromRow = (row) => ({
|
|
342
|
+
hasRemoteRecipients: row[0],
|
|
343
|
+
noPeerError: row[1],
|
|
344
|
+
defaultSendSilent: row[2],
|
|
345
|
+
sendTo: row[3],
|
|
346
|
+
ackTo: row[4],
|
|
347
|
+
silentTo: row[5],
|
|
348
|
+
repairTargets: row[6],
|
|
349
|
+
authoritativeRecipients: row[7],
|
|
350
|
+
});
|
|
351
|
+
const committedEntryFromRow = (row) => {
|
|
352
|
+
const [hash, metaBytes, byteLength, hashDigestBytes] = row;
|
|
353
|
+
return {
|
|
354
|
+
cid: hash,
|
|
355
|
+
hash,
|
|
356
|
+
next: [],
|
|
357
|
+
metaBytes,
|
|
358
|
+
byteLength,
|
|
359
|
+
hashDigestBytes,
|
|
360
|
+
};
|
|
361
|
+
};
|
|
362
|
+
const committedStorageFactsEntryFromRow = (row) => {
|
|
363
|
+
if (row.length === 4) {
|
|
364
|
+
return committedEntryFromRow(row);
|
|
365
|
+
}
|
|
366
|
+
const [hash, next, metaBytes, byteLength, hashDigestBytes] = row;
|
|
367
|
+
return {
|
|
368
|
+
cid: hash,
|
|
369
|
+
hash,
|
|
370
|
+
next,
|
|
371
|
+
metaBytes,
|
|
372
|
+
byteLength,
|
|
373
|
+
hashDigestBytes,
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
const storageFactsEntryFromRow = (row) => {
|
|
377
|
+
const [bytes, cid, next, byteLength, metaBytes, hashDigestBytes] = row;
|
|
378
|
+
return {
|
|
379
|
+
cid,
|
|
380
|
+
hash: cid,
|
|
381
|
+
next,
|
|
382
|
+
bytes,
|
|
383
|
+
byteLength,
|
|
384
|
+
metaBytes,
|
|
385
|
+
hashDigestBytes,
|
|
386
|
+
};
|
|
387
|
+
};
|
|
388
|
+
const trimmedEntryFromRow = (row) => {
|
|
389
|
+
const [hash, gid, next, type, wallTime, logical, payloadSize, data] = row;
|
|
390
|
+
return {
|
|
391
|
+
hash,
|
|
392
|
+
gid,
|
|
393
|
+
next,
|
|
394
|
+
type,
|
|
395
|
+
payloadSize,
|
|
396
|
+
data,
|
|
397
|
+
clock: {
|
|
398
|
+
timestamp: {
|
|
399
|
+
wallTime: BigInt(wallTime),
|
|
400
|
+
logical,
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
};
|
|
405
|
+
const trimmedHashFromRow = (row) => row[0];
|
|
406
|
+
const trimmedRowsResult = (rows) => {
|
|
407
|
+
let trimmed;
|
|
408
|
+
const trimmedHashes = rows.map(trimmedHashFromRow);
|
|
409
|
+
return {
|
|
410
|
+
get trimmed() {
|
|
411
|
+
return (trimmed ??= rows.map(trimmedEntryFromRow));
|
|
412
|
+
},
|
|
413
|
+
trimmedHashes,
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
const trimmedRowsAndHashesResult = (rows, hashRows) => {
|
|
417
|
+
if (!hashRows) {
|
|
418
|
+
return trimmedRowsResult(rows);
|
|
419
|
+
}
|
|
420
|
+
let trimmed;
|
|
421
|
+
const trimmedHashes = hashRows;
|
|
422
|
+
return {
|
|
423
|
+
get trimmed() {
|
|
424
|
+
return (trimmed ??= rows.map(trimmedEntryFromRow));
|
|
425
|
+
},
|
|
426
|
+
trimmedHashes,
|
|
427
|
+
};
|
|
428
|
+
};
|
|
429
|
+
const nativeLogEntryFromTrimRow = (row) => {
|
|
430
|
+
const entry = trimmedEntryFromRow(row);
|
|
431
|
+
return {
|
|
432
|
+
...entry,
|
|
433
|
+
clock: {
|
|
434
|
+
timestamp: {
|
|
435
|
+
wallTime: entry.clock.timestamp.wallTime,
|
|
436
|
+
logical: entry.clock.timestamp.logical,
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
};
|
|
440
|
+
};
|
|
441
|
+
const headEntryFromRow = (row) => {
|
|
442
|
+
const [hash, gid, wallTime, logical] = row;
|
|
443
|
+
return {
|
|
444
|
+
hash,
|
|
445
|
+
meta: {
|
|
446
|
+
gid,
|
|
447
|
+
clock: { timestamp: { wallTime: BigInt(wallTime), logical } },
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
};
|
|
451
|
+
const joinHeadEntryFromRow = (row) => {
|
|
452
|
+
const [hash, gid, wallTime, logical, type, next] = row;
|
|
453
|
+
return {
|
|
454
|
+
hash,
|
|
455
|
+
meta: {
|
|
456
|
+
gid,
|
|
457
|
+
type,
|
|
458
|
+
next,
|
|
459
|
+
clock: { timestamp: { wallTime: BigInt(wallTime), logical } },
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
};
|
|
463
|
+
const headDataEntryFromRow = (row) => {
|
|
464
|
+
const [hash, data] = row;
|
|
465
|
+
return { hash, meta: { data } };
|
|
466
|
+
};
|
|
467
|
+
const metadataEntryFromRow = (row) => {
|
|
468
|
+
if (row == null) {
|
|
469
|
+
return undefined;
|
|
470
|
+
}
|
|
471
|
+
const [hash, gid, data, replicas] = row;
|
|
472
|
+
const entry = { hash, gid, data };
|
|
473
|
+
if (replicas != null) {
|
|
474
|
+
entry.replicas = replicas;
|
|
475
|
+
}
|
|
476
|
+
return entry;
|
|
477
|
+
};
|
|
478
|
+
const requestPruneEntryFromRow = (row) => {
|
|
479
|
+
const [hash, gid, replicas, data] = row;
|
|
480
|
+
const entry = { hash, gid };
|
|
481
|
+
if (replicas != null) {
|
|
482
|
+
entry.replicas = replicas;
|
|
483
|
+
}
|
|
484
|
+
if (data != null) {
|
|
485
|
+
entry.data = data;
|
|
486
|
+
}
|
|
487
|
+
return entry;
|
|
488
|
+
};
|
|
489
|
+
const storageAppendResultFromRow = (resolution, row) => {
|
|
490
|
+
const [entryRow, leaderRows, isLeader, assignedToRangeBoundary, coordinateRow, trimRows, trimHashRows, documentTrimmedHeadsProcessed, documentPreviousContextRow,] = row;
|
|
491
|
+
return {
|
|
492
|
+
entry: storageFactsEntryFromRow(entryRow),
|
|
493
|
+
leaders: rowsToSamples(leaderRows),
|
|
494
|
+
isLeader,
|
|
495
|
+
assignedToRangeBoundary,
|
|
496
|
+
coordinate: appendCoordinatePlanFromRow(resolution, coordinateRow),
|
|
497
|
+
...trimmedRowsAndHashesResult(trimRows, trimHashRows),
|
|
498
|
+
documentTrimmedHeadsProcessed,
|
|
499
|
+
documentPreviousContext: documentContextFactsFromRow(documentPreviousContextRow),
|
|
500
|
+
};
|
|
501
|
+
};
|
|
502
|
+
const committedStorageAppendResultFromRow = (resolution, row) => {
|
|
503
|
+
const [entryRow, leaderRows, isLeader, assignedToRangeBoundary, coordinateRow, trimRows, trimHashRows, documentTrimmedHeadsProcessed, documentPreviousContextRow,] = row;
|
|
504
|
+
return {
|
|
505
|
+
entry: committedStorageFactsEntryFromRow(entryRow),
|
|
506
|
+
leaders: rowsToSamples(leaderRows),
|
|
507
|
+
isLeader,
|
|
508
|
+
assignedToRangeBoundary,
|
|
509
|
+
coordinate: appendCoordinatePlanFromRow(resolution, coordinateRow),
|
|
510
|
+
...trimmedRowsAndHashesResult(trimRows, trimHashRows),
|
|
511
|
+
documentTrimmedHeadsProcessed,
|
|
512
|
+
documentPreviousContext: documentContextFactsFromRow(documentPreviousContextRow),
|
|
513
|
+
};
|
|
514
|
+
};
|
|
515
|
+
const compactCommittedNoNextStorageAppendResultFromRow = (resolution, row) => {
|
|
516
|
+
const [hash, byteLength, metaBytes, fourth] = row;
|
|
517
|
+
const hasDigestRow = fourth instanceof Uint8Array;
|
|
518
|
+
const hashDigestBytes = hasDigestRow ? fourth : undefined;
|
|
519
|
+
const rest = row.slice(hasDigestRow ? 4 : 3);
|
|
520
|
+
const usesNestedCoordinateRow = Array.isArray(rest[0]);
|
|
521
|
+
let coordinate;
|
|
522
|
+
let leaderRows;
|
|
523
|
+
let isLeader;
|
|
524
|
+
let trimHashRows;
|
|
525
|
+
let documentTrimmedHeadsProcessed;
|
|
526
|
+
let bytes;
|
|
527
|
+
if (usesNestedCoordinateRow) {
|
|
528
|
+
const [coordinateRow, nestedLeaderRows, nestedIsLeader, nestedTrimHashRows, nestedDocumentTrimmedHeadsProcessed, nestedBytes,] = rest;
|
|
529
|
+
coordinate = appendCoordinatePlanFromRow(resolution, coordinateRow);
|
|
530
|
+
leaderRows = nestedLeaderRows;
|
|
531
|
+
isLeader = nestedIsLeader;
|
|
532
|
+
trimHashRows = nestedTrimHashRows;
|
|
533
|
+
documentTrimmedHeadsProcessed = nestedDocumentTrimmedHeadsProcessed;
|
|
534
|
+
bytes = nestedBytes instanceof Uint8Array ? nestedBytes : undefined;
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
const [hashNumber, gid, coordinateRows, assignedToRangeBoundary, requestedReplicas, flatLeaderRows, flatIsLeader, flatTrimHashRows, flatDocumentTrimmedHeadsProcessed, flatBytes,] = rest;
|
|
538
|
+
coordinate = appendCoordinatePlanFromCompactNoNextRow(resolution, hash, [
|
|
539
|
+
hashNumber,
|
|
540
|
+
gid,
|
|
541
|
+
coordinateRows,
|
|
542
|
+
assignedToRangeBoundary,
|
|
543
|
+
requestedReplicas,
|
|
544
|
+
]);
|
|
545
|
+
leaderRows = flatLeaderRows;
|
|
546
|
+
isLeader = flatIsLeader;
|
|
547
|
+
trimHashRows = flatTrimHashRows;
|
|
548
|
+
documentTrimmedHeadsProcessed = flatDocumentTrimmedHeadsProcessed;
|
|
549
|
+
bytes = flatBytes instanceof Uint8Array ? flatBytes : undefined;
|
|
550
|
+
}
|
|
551
|
+
return {
|
|
552
|
+
entry: {
|
|
553
|
+
cid: hash,
|
|
554
|
+
hash,
|
|
555
|
+
next: [],
|
|
556
|
+
bytes,
|
|
557
|
+
metaBytes,
|
|
558
|
+
byteLength,
|
|
559
|
+
hashDigestBytes,
|
|
560
|
+
},
|
|
561
|
+
leaders: rowsToSamples(leaderRows),
|
|
562
|
+
isLeader,
|
|
563
|
+
assignedToRangeBoundary: coordinate.assignedToRangeBoundary,
|
|
564
|
+
coordinate,
|
|
565
|
+
trimmed: [],
|
|
566
|
+
trimmedHashes: trimHashRows ?? [],
|
|
567
|
+
documentTrimmedHeadsProcessed,
|
|
568
|
+
};
|
|
569
|
+
};
|
|
570
|
+
const compactCommittedLatestStorageAppendResultFromRow = (resolution, row) => {
|
|
571
|
+
const [hash, byteLength, metaBytes, fourth, fifth, sixth, seventh, eighth, ninth, tenth, eleventh, twelfth,] = row;
|
|
572
|
+
const hasDigestRow = fourth instanceof Uint8Array;
|
|
573
|
+
const hashDigestBytes = hasDigestRow ? fourth : undefined;
|
|
574
|
+
const next = (hasDigestRow ? fifth : fourth);
|
|
575
|
+
const coordinateRow = (hasDigestRow ? sixth : fifth);
|
|
576
|
+
const leaderRows = (hasDigestRow ? seventh : sixth);
|
|
577
|
+
const isLeader = (hasDigestRow ? eighth : seventh);
|
|
578
|
+
const trimHashRows = (hasDigestRow ? ninth : eighth);
|
|
579
|
+
const documentTrimmedHeadsProcessed = (hasDigestRow ? tenth : ninth);
|
|
580
|
+
const documentPreviousContextRow = (hasDigestRow ? eleventh : tenth);
|
|
581
|
+
const bytes = (hasDigestRow ? twelfth : eleventh);
|
|
582
|
+
const coordinate = appendCoordinatePlanFromRow(resolution, coordinateRow);
|
|
583
|
+
return {
|
|
584
|
+
entry: {
|
|
585
|
+
cid: hash,
|
|
586
|
+
hash,
|
|
587
|
+
next,
|
|
588
|
+
bytes: bytes instanceof Uint8Array ? bytes : undefined,
|
|
589
|
+
metaBytes,
|
|
590
|
+
byteLength,
|
|
591
|
+
hashDigestBytes,
|
|
592
|
+
},
|
|
593
|
+
leaders: rowsToSamples(leaderRows),
|
|
594
|
+
isLeader,
|
|
595
|
+
assignedToRangeBoundary: coordinate.assignedToRangeBoundary,
|
|
596
|
+
coordinate,
|
|
597
|
+
trimmed: [],
|
|
598
|
+
trimmedHashes: trimHashRows ?? [],
|
|
599
|
+
documentTrimmedHeadsProcessed,
|
|
600
|
+
documentPreviousContext: documentContextFactsFromRow(documentPreviousContextRow),
|
|
601
|
+
};
|
|
602
|
+
};
|
|
603
|
+
const preparedCommitFactsFromRow = (row) => {
|
|
604
|
+
const isTrimRow = Array.isArray(row) &&
|
|
605
|
+
row.length === 2 &&
|
|
606
|
+
Array.isArray(row[0]) &&
|
|
607
|
+
Array.isArray(row[1]);
|
|
608
|
+
const entryRow = (isTrimRow ? row[0] : row);
|
|
609
|
+
const prepared = committedStorageFactsEntryFromRow(entryRow);
|
|
610
|
+
if (isTrimRow) {
|
|
611
|
+
return {
|
|
612
|
+
...prepared,
|
|
613
|
+
trimmedEntries: row[1].map(nativeLogEntryFromTrimRow),
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
return prepared;
|
|
617
|
+
};
|
|
618
|
+
const preparedCommitFactsWithLatestDocumentContextFromRow = (row) => {
|
|
619
|
+
const [entryRow, trimHashRows, documentTrimmedHeadsProcessed, contextRow] = row;
|
|
620
|
+
return {
|
|
621
|
+
...committedStorageFactsEntryFromRow(entryRow),
|
|
622
|
+
trimmedEntryHashes: trimHashRows ?? [],
|
|
623
|
+
documentTrimmedHeadsProcessed,
|
|
624
|
+
documentPreviousContext: documentContextFactsFromRow(contextRow),
|
|
625
|
+
};
|
|
626
|
+
};
|
|
627
|
+
const compactPreparedCommitFactsWithTrimHashesFromRow = (row) => {
|
|
628
|
+
const [hash, byteLength, metaBytes, fourth] = row;
|
|
629
|
+
const hasDigestRow = fourth instanceof Uint8Array;
|
|
630
|
+
const hashDigestBytes = hasDigestRow ? fourth : undefined;
|
|
631
|
+
const trimHashOffset = hasDigestRow ? 4 : 3;
|
|
632
|
+
const trimHashRows = row[trimHashOffset];
|
|
633
|
+
const documentTrimmedHeadsProcessed = row[trimHashOffset + 1];
|
|
634
|
+
return {
|
|
635
|
+
cid: hash,
|
|
636
|
+
hash,
|
|
637
|
+
next: [],
|
|
638
|
+
metaBytes,
|
|
639
|
+
byteLength,
|
|
640
|
+
hashDigestBytes,
|
|
641
|
+
trimmedEntryHashes: trimHashRows ?? [],
|
|
642
|
+
documentTrimmedHeadsProcessed,
|
|
643
|
+
};
|
|
644
|
+
};
|
|
645
|
+
const nativeLogCommitEntryColumns = (entries) => {
|
|
646
|
+
const hashes = new Array(entries.length);
|
|
647
|
+
const blockBytes = new Array(entries.length);
|
|
648
|
+
const gids = new Array(entries.length);
|
|
649
|
+
const nexts = new Array(entries.length);
|
|
650
|
+
const entryTypes = new Uint8Array(entries.length);
|
|
651
|
+
const wallTimes = new BigUint64Array(entries.length);
|
|
652
|
+
const logicals = new Uint32Array(entries.length);
|
|
653
|
+
const payloadSizes = new Uint32Array(entries.length);
|
|
654
|
+
const heads = new Uint8Array(entries.length);
|
|
655
|
+
const datas = new Array(entries.length);
|
|
656
|
+
for (let i = 0; i < entries.length; i++) {
|
|
657
|
+
const entry = entries[i];
|
|
658
|
+
hashes[i] = entry.hash;
|
|
659
|
+
blockBytes[i] = entry.bytes;
|
|
660
|
+
gids[i] = entry.gid;
|
|
661
|
+
nexts[i] = entry.next;
|
|
662
|
+
entryTypes[i] = entry.type;
|
|
663
|
+
wallTimes[i] = BigInt(entry.clock.timestamp.wallTime);
|
|
664
|
+
logicals[i] = entry.clock.timestamp.logical ?? 0;
|
|
665
|
+
payloadSizes[i] = entry.payloadSize ?? 0;
|
|
666
|
+
heads[i] = (entry.head ?? true) ? 1 : 0;
|
|
667
|
+
datas[i] = entry.data;
|
|
668
|
+
}
|
|
669
|
+
return {
|
|
670
|
+
hashes,
|
|
671
|
+
blockBytes,
|
|
672
|
+
gids,
|
|
673
|
+
nexts,
|
|
674
|
+
entryTypes,
|
|
675
|
+
wallTimes,
|
|
676
|
+
logicals,
|
|
677
|
+
payloadSizes,
|
|
678
|
+
heads,
|
|
679
|
+
datas,
|
|
680
|
+
};
|
|
681
|
+
};
|
|
682
|
+
const validateNativeBackboneCoordinateCommitColumns = (columns) => {
|
|
683
|
+
const length = columns.hashes.length;
|
|
684
|
+
if (columns.gids.length !== length ||
|
|
685
|
+
columns.nextHashBatches.length !== length ||
|
|
686
|
+
columns.assignedToRangeBoundaries.length !== length) {
|
|
687
|
+
throw new Error("Expected equal native coordinate commit column lengths");
|
|
688
|
+
}
|
|
689
|
+
if (columns.hashNumberValues || columns.coordinateCounts || columns.coordinateValues) {
|
|
690
|
+
if (!columns.hashNumberValues ||
|
|
691
|
+
!columns.coordinateCounts ||
|
|
692
|
+
!columns.coordinateValues ||
|
|
693
|
+
columns.hashNumberValues.length !== length ||
|
|
694
|
+
columns.coordinateCounts.length !== length) {
|
|
695
|
+
throw new Error("Expected equal native coordinate numeric column lengths");
|
|
696
|
+
}
|
|
697
|
+
let coordinateCount = 0;
|
|
698
|
+
for (const count of columns.coordinateCounts) {
|
|
699
|
+
coordinateCount += count;
|
|
700
|
+
}
|
|
701
|
+
if (coordinateCount !== columns.coordinateValues.length) {
|
|
702
|
+
throw new Error("Expected equal native coordinate value lengths");
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
if (columns.requestedReplicaValues &&
|
|
706
|
+
columns.requestedReplicaValues.length !== length) {
|
|
707
|
+
throw new Error("Expected equal native coordinate replica column lengths");
|
|
708
|
+
}
|
|
709
|
+
if (columns.hashNumbers || columns.coordinateBatches || columns.requestedReplicas) {
|
|
710
|
+
if (!columns.hashNumbers ||
|
|
711
|
+
!columns.coordinateBatches ||
|
|
712
|
+
!columns.requestedReplicas ||
|
|
713
|
+
columns.hashNumbers.length !== length ||
|
|
714
|
+
columns.coordinateBatches.length !== length ||
|
|
715
|
+
columns.requestedReplicas.length !== length) {
|
|
716
|
+
throw new Error("Expected equal native coordinate string column lengths");
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
const emptyNativeBackboneCoordinateCommitColumns = () => ({
|
|
721
|
+
hashes: [],
|
|
722
|
+
gids: [],
|
|
723
|
+
nextHashBatches: [],
|
|
724
|
+
assignedToRangeBoundaries: new Uint8Array(0),
|
|
725
|
+
hashNumberValues: new BigUint64Array(0),
|
|
726
|
+
coordinateCounts: new Uint32Array(0),
|
|
727
|
+
coordinateValues: new BigUint64Array(0),
|
|
728
|
+
requestedReplicaValues: new Uint32Array(0),
|
|
729
|
+
});
|
|
730
|
+
const hasNativeBackboneNumericCoordinateCommitColumns = (columns) => !!columns.hashNumberValues &&
|
|
731
|
+
!!columns.coordinateCounts &&
|
|
732
|
+
!!columns.coordinateValues &&
|
|
733
|
+
!!columns.requestedReplicaValues;
|
|
734
|
+
const nativeBackboneCoordinateCommitStringColumns = (columns) => {
|
|
735
|
+
if (columns.hashNumbers && columns.coordinateBatches && columns.requestedReplicas) {
|
|
736
|
+
return {
|
|
737
|
+
hashNumbers: columns.hashNumbers,
|
|
738
|
+
coordinateBatches: columns.coordinateBatches,
|
|
739
|
+
requestedReplicas: columns.requestedReplicas,
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
if (!hasNativeBackboneNumericCoordinateCommitColumns(columns)) {
|
|
743
|
+
throw new Error("Missing native coordinate commit columns");
|
|
744
|
+
}
|
|
745
|
+
const hashNumbers = Array.from(columns.hashNumberValues, (value) => value.toString());
|
|
746
|
+
const coordinateBatches = new Array(columns.hashes.length);
|
|
747
|
+
let coordinateOffset = 0;
|
|
748
|
+
for (let i = 0; i < columns.hashes.length; i++) {
|
|
749
|
+
const count = columns.coordinateCounts[i];
|
|
750
|
+
const coordinates = new Array(count);
|
|
751
|
+
for (let j = 0; j < count; j++) {
|
|
752
|
+
coordinates[j] = columns.coordinateValues[coordinateOffset++].toString();
|
|
753
|
+
}
|
|
754
|
+
coordinateBatches[i] = coordinates;
|
|
755
|
+
}
|
|
756
|
+
return {
|
|
757
|
+
hashNumbers,
|
|
758
|
+
coordinateBatches,
|
|
759
|
+
requestedReplicas: Array.from(columns.requestedReplicaValues),
|
|
760
|
+
};
|
|
761
|
+
};
|
|
762
|
+
const rawReceivePreparedFactsFromRow = ([cid, hashDigestBytes, byteLength, clockId, wallTime, logical, gid, next, type, metaBytes, metaData, payloadByteLength, signatureVerified, requestedReplicas, hashNumber,]) => ({
|
|
763
|
+
cid,
|
|
764
|
+
hashDigestBytes,
|
|
765
|
+
byteLength,
|
|
766
|
+
clockId,
|
|
767
|
+
wallTime: BigInt(wallTime),
|
|
768
|
+
logical,
|
|
769
|
+
gid,
|
|
770
|
+
next,
|
|
771
|
+
type,
|
|
772
|
+
metaBytes,
|
|
773
|
+
metaData,
|
|
774
|
+
payloadByteLength,
|
|
775
|
+
signatureVerified,
|
|
776
|
+
requestedReplicas,
|
|
777
|
+
hashNumber,
|
|
778
|
+
});
|
|
779
|
+
const rawReceivePreparedFactsFromColumns = ([cids, hashDigestBytes, byteLengths, clockIds, wallTimes, logicals, gids, nexts, types, metaBytes, metaDatas, payloadByteLengths, signatureVerified, requestedReplicas, hashNumbers,]) => {
|
|
780
|
+
const length = cids.length;
|
|
781
|
+
if (hashDigestBytes.length !== length ||
|
|
782
|
+
byteLengths.length !== length ||
|
|
783
|
+
clockIds.length !== length ||
|
|
784
|
+
wallTimes.length !== length ||
|
|
785
|
+
logicals.length !== length ||
|
|
786
|
+
gids.length !== length ||
|
|
787
|
+
nexts.length !== length ||
|
|
788
|
+
types.length !== length ||
|
|
789
|
+
metaBytes.length !== length ||
|
|
790
|
+
metaDatas.length !== length ||
|
|
791
|
+
payloadByteLengths.length !== length ||
|
|
792
|
+
signatureVerified.length !== length ||
|
|
793
|
+
requestedReplicas.length !== length ||
|
|
794
|
+
hashNumbers.length !== length) {
|
|
795
|
+
throw new Error("Expected equal raw receive prepared column lengths");
|
|
796
|
+
}
|
|
797
|
+
const out = new Array(length);
|
|
798
|
+
for (let i = 0; i < length; i++) {
|
|
799
|
+
out[i] = {
|
|
800
|
+
cid: cids[i],
|
|
801
|
+
hashDigestBytes: hashDigestBytes[i] ?? cidifyString(cids[i]).multihash.digest,
|
|
802
|
+
byteLength: byteLengths[i],
|
|
803
|
+
clockId: clockIds[i],
|
|
804
|
+
wallTime: wallTimes[i],
|
|
805
|
+
logical: logicals[i],
|
|
806
|
+
gid: gids[i],
|
|
807
|
+
next: nexts[i],
|
|
808
|
+
type: types[i],
|
|
809
|
+
metaBytes: metaBytes[i],
|
|
810
|
+
metaData: metaDatas[i],
|
|
811
|
+
payloadByteLength: payloadByteLengths[i],
|
|
812
|
+
signatureVerified: signatureVerified[i] !== 0,
|
|
813
|
+
requestedReplicas: requestedReplicas[i] && requestedReplicas[i] > 0
|
|
814
|
+
? requestedReplicas[i]
|
|
815
|
+
: undefined,
|
|
816
|
+
hashNumber: hashNumbers[i] == null ? undefined : String(hashNumbers[i]),
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
return out;
|
|
820
|
+
};
|
|
821
|
+
const rawReceiveGroupPlanFromRow = ([gid, hashes, requestedReplicas, latestHash, maxReplicasFromHead, maxReplicasFromNewEntries, maxMaxReplicas,]) => ({
|
|
822
|
+
gid,
|
|
823
|
+
hashes,
|
|
824
|
+
requestedReplicas: Array.from(requestedReplicas),
|
|
825
|
+
latestHash,
|
|
826
|
+
maxReplicasFromHead,
|
|
827
|
+
maxReplicasFromNewEntries,
|
|
828
|
+
maxMaxReplicas,
|
|
829
|
+
});
|
|
830
|
+
const rawReceiveGroupIndexPlanFromRow = ([gid, indexes, requestedReplicas, latestIndex, maxReplicasFromHead, maxReplicasFromNewEntries, maxMaxReplicas,]) => ({
|
|
831
|
+
gid,
|
|
832
|
+
indexes,
|
|
833
|
+
requestedReplicas: Array.from(requestedReplicas),
|
|
834
|
+
latestIndex,
|
|
835
|
+
maxReplicasFromHead,
|
|
836
|
+
maxReplicasFromNewEntries,
|
|
837
|
+
maxMaxReplicas,
|
|
838
|
+
});
|
|
839
|
+
const rawReceiveGroupLeaderPlanFromRow = (resolution, [gid, indexes, requestedReplicas, latestIndex, maxReplicasFromHead, maxReplicasFromNewEntries, maxMaxReplicas, coordinateRows, leaderRows,]) => {
|
|
840
|
+
let coordinates;
|
|
841
|
+
let coordinateStrings;
|
|
842
|
+
return {
|
|
843
|
+
gid,
|
|
844
|
+
indexes,
|
|
845
|
+
requestedReplicas: Array.from(requestedReplicas),
|
|
846
|
+
latestIndex,
|
|
847
|
+
maxReplicasFromHead,
|
|
848
|
+
maxReplicasFromNewEntries,
|
|
849
|
+
maxMaxReplicas,
|
|
850
|
+
get coordinates() {
|
|
851
|
+
return (coordinates ??= rowsToNumbers(resolution, coordinateRows));
|
|
852
|
+
},
|
|
853
|
+
set coordinates(value) {
|
|
854
|
+
coordinates = value;
|
|
855
|
+
},
|
|
856
|
+
get coordinateStrings() {
|
|
857
|
+
return (coordinateStrings ??= coordinateRows.map((coordinate) => String(coordinate)));
|
|
858
|
+
},
|
|
859
|
+
set coordinateStrings(value) {
|
|
860
|
+
coordinateStrings = value;
|
|
861
|
+
},
|
|
862
|
+
leaders: rowsToSamples(leaderRows) ?? new Map(),
|
|
863
|
+
};
|
|
864
|
+
};
|
|
865
|
+
const rawReceiveGroupAssignmentPlanFromRow = (resolution, [gid, indexes, requestedReplicas, latestIndex, maxReplicasFromHead, maxReplicasFromNewEntries, maxMaxReplicas, coordinateRows, isLeader, fromIsLeader, assignedToRangeBoundary,]) => {
|
|
866
|
+
let coordinates;
|
|
867
|
+
let coordinateStrings;
|
|
868
|
+
return {
|
|
869
|
+
gid,
|
|
870
|
+
indexes,
|
|
871
|
+
requestedReplicas: Array.from(requestedReplicas),
|
|
872
|
+
latestIndex,
|
|
873
|
+
maxReplicasFromHead,
|
|
874
|
+
maxReplicasFromNewEntries,
|
|
875
|
+
maxMaxReplicas,
|
|
876
|
+
get coordinates() {
|
|
877
|
+
return (coordinates ??= rowsToNumbers(resolution, coordinateRows));
|
|
878
|
+
},
|
|
879
|
+
set coordinates(value) {
|
|
880
|
+
coordinates = value;
|
|
881
|
+
},
|
|
882
|
+
get coordinateStrings() {
|
|
883
|
+
return (coordinateStrings ??= coordinateRows.map((coordinate) => String(coordinate)));
|
|
884
|
+
},
|
|
885
|
+
set coordinateStrings(value) {
|
|
886
|
+
coordinateStrings = value;
|
|
887
|
+
},
|
|
888
|
+
isLeader,
|
|
889
|
+
fromIsLeader,
|
|
890
|
+
assignedToRangeBoundary,
|
|
891
|
+
};
|
|
892
|
+
};
|
|
893
|
+
const rawReceiveSelectionFromRow = (resolution, [retainedHashes, droppedHashes, groupCount, plannedHashCount, usedNativeFastDropPlan, usedLeaderSamplePlans, retainedGroupLeaderPlanRows, retainedIndexes, droppedIndexes,]) => {
|
|
894
|
+
const plan = {
|
|
895
|
+
retainedHashes,
|
|
896
|
+
droppedHashes,
|
|
897
|
+
groupCount,
|
|
898
|
+
plannedHashCount,
|
|
899
|
+
usedNativeFastDropPlan,
|
|
900
|
+
usedLeaderSamplePlans,
|
|
901
|
+
};
|
|
902
|
+
if (retainedIndexes) {
|
|
903
|
+
plan.retainedIndexes = retainedIndexes;
|
|
904
|
+
}
|
|
905
|
+
if (droppedIndexes) {
|
|
906
|
+
plan.droppedIndexes = droppedIndexes;
|
|
907
|
+
}
|
|
908
|
+
if (retainedGroupLeaderPlanRows) {
|
|
909
|
+
plan.retainedGroupLeaderPlans = retainedGroupLeaderPlanRows.map((row) => rawReceiveGroupLeaderPlanFromRow(resolution, row));
|
|
910
|
+
}
|
|
911
|
+
return plan;
|
|
912
|
+
};
|
|
913
|
+
class NativeBackboneLogGraph {
|
|
914
|
+
native;
|
|
915
|
+
options;
|
|
916
|
+
constructor(native, options) {
|
|
917
|
+
this.native = native;
|
|
918
|
+
this.options = options;
|
|
919
|
+
}
|
|
920
|
+
get length() {
|
|
921
|
+
return this.native.log_len();
|
|
922
|
+
}
|
|
923
|
+
has(hash) {
|
|
924
|
+
return this.native.has_log_entry(hash);
|
|
925
|
+
}
|
|
926
|
+
hasMany(hashes) {
|
|
927
|
+
return new Set(this.native.graph_has_many([...hashes]));
|
|
928
|
+
}
|
|
929
|
+
put(entry) {
|
|
930
|
+
this.native.graph_put(entry.hash, entry.gid, entry.next, entry.type, BigInt(entry.clock.timestamp.wallTime), entry.clock.timestamp.logical ?? 0, entry.payloadSize ?? 0, entry.head ?? true, entry.data);
|
|
931
|
+
}
|
|
932
|
+
putBatch(entries) {
|
|
933
|
+
if (entries.length === 0) {
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
const hashes = new Array(entries.length);
|
|
937
|
+
const gids = new Array(entries.length);
|
|
938
|
+
const nexts = new Array(entries.length);
|
|
939
|
+
const entryTypes = new Uint8Array(entries.length);
|
|
940
|
+
const wallTimes = new BigUint64Array(entries.length);
|
|
941
|
+
const logicals = new Uint32Array(entries.length);
|
|
942
|
+
const payloadSizes = new Uint32Array(entries.length);
|
|
943
|
+
const heads = new Uint8Array(entries.length);
|
|
944
|
+
const datas = new Array(entries.length);
|
|
945
|
+
for (let i = 0; i < entries.length; i++) {
|
|
946
|
+
const entry = entries[i];
|
|
947
|
+
hashes[i] = entry.hash;
|
|
948
|
+
gids[i] = entry.gid;
|
|
949
|
+
nexts[i] = entry.next;
|
|
950
|
+
entryTypes[i] = entry.type;
|
|
951
|
+
wallTimes[i] = BigInt(entry.clock.timestamp.wallTime);
|
|
952
|
+
logicals[i] = entry.clock.timestamp.logical ?? 0;
|
|
953
|
+
payloadSizes[i] = entry.payloadSize ?? 0;
|
|
954
|
+
heads[i] = (entry.head ?? true) ? 1 : 0;
|
|
955
|
+
datas[i] = entry.data;
|
|
956
|
+
}
|
|
957
|
+
this.native.graph_put_batch(hashes, gids, nexts, entryTypes, wallTimes, logicals, payloadSizes, heads, datas);
|
|
958
|
+
}
|
|
959
|
+
putAppendChain(entries) {
|
|
960
|
+
if (entries.length === 0) {
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
const first = entries[0];
|
|
964
|
+
const hashes = new Array(entries.length);
|
|
965
|
+
const wallTimes = new BigUint64Array(entries.length);
|
|
966
|
+
const logicals = new Uint32Array(entries.length);
|
|
967
|
+
const payloadSizes = new Uint32Array(entries.length);
|
|
968
|
+
const datas = new Array(entries.length);
|
|
969
|
+
for (let i = 0; i < entries.length; i++) {
|
|
970
|
+
const entry = entries[i];
|
|
971
|
+
hashes[i] = entry.hash;
|
|
972
|
+
wallTimes[i] = BigInt(entry.clock.timestamp.wallTime);
|
|
973
|
+
logicals[i] = entry.clock.timestamp.logical ?? 0;
|
|
974
|
+
payloadSizes[i] = entry.payloadSize ?? 0;
|
|
975
|
+
datas[i] = entry.data;
|
|
976
|
+
}
|
|
977
|
+
this.native.graph_put_append_chain(hashes, first.gid, first.next, first.type, wallTimes, logicals, payloadSizes, datas);
|
|
978
|
+
}
|
|
979
|
+
commitBlocksAndGraphBatch(entries) {
|
|
980
|
+
if (entries.length === 0) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
const columns = nativeLogCommitEntryColumns(entries);
|
|
984
|
+
this.native.commit_log_blocks_and_graph_batch(columns.hashes, columns.blockBytes, columns.gids, columns.nexts, columns.entryTypes, columns.wallTimes, columns.logicals, columns.payloadSizes, columns.heads, columns.datas);
|
|
985
|
+
}
|
|
986
|
+
commitBlocksGraphAndCoordinatesBatch(entries, coordinates) {
|
|
987
|
+
if (entries.length === 0) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
validateNativeBackboneCoordinateCommitColumns(coordinates);
|
|
991
|
+
const coordinateStringColumns = nativeBackboneCoordinateCommitStringColumns(coordinates);
|
|
992
|
+
const columns = nativeLogCommitEntryColumns(entries);
|
|
993
|
+
this.native.commit_log_blocks_graph_and_coordinates_batch(columns.hashes, columns.blockBytes, columns.gids, columns.nexts, columns.entryTypes, columns.wallTimes, columns.logicals, columns.payloadSizes, columns.heads, columns.datas, coordinates.hashes, coordinates.gids, coordinateStringColumns.hashNumbers, coordinateStringColumns.coordinateBatches, coordinates.nextHashBatches, coordinates.assignedToRangeBoundaries, coordinateStringColumns.requestedReplicas);
|
|
994
|
+
}
|
|
995
|
+
commitPreparedRawReceiveBatch(hashes, headFlags, coordinates) {
|
|
996
|
+
if (hashes.length === 0) {
|
|
997
|
+
return true;
|
|
998
|
+
}
|
|
999
|
+
if (hashes.length !== headFlags.length) {
|
|
1000
|
+
throw new Error("Expected equal raw receive hash and head lengths");
|
|
1001
|
+
}
|
|
1002
|
+
const coordinateColumns = coordinates ?? emptyNativeBackboneCoordinateCommitColumns();
|
|
1003
|
+
validateNativeBackboneCoordinateCommitColumns(coordinateColumns);
|
|
1004
|
+
if (this.native.commit_prepared_raw_receive_batch_u64 &&
|
|
1005
|
+
hasNativeBackboneNumericCoordinateCommitColumns(coordinateColumns)) {
|
|
1006
|
+
return this.native.commit_prepared_raw_receive_batch_u64(hashes, nativeBackboneHeadFlagsToBytes(headFlags), coordinateColumns.hashes, coordinateColumns.gids, coordinateColumns.hashNumberValues, coordinateColumns.coordinateCounts, coordinateColumns.coordinateValues, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateColumns.requestedReplicaValues);
|
|
1007
|
+
}
|
|
1008
|
+
const coordinateStringColumns = nativeBackboneCoordinateCommitStringColumns(coordinateColumns);
|
|
1009
|
+
return this.native.commit_prepared_raw_receive_batch(hashes, nativeBackboneHeadFlagsToBytes(headFlags), coordinateColumns.hashes, coordinateColumns.gids, coordinateStringColumns.hashNumbers, coordinateStringColumns.coordinateBatches, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateStringColumns.requestedReplicas);
|
|
1010
|
+
}
|
|
1011
|
+
commitPreparedRawReceiveJoinBatch(hashes, headFlags, coordinates) {
|
|
1012
|
+
if (hashes.length === 0) {
|
|
1013
|
+
return true;
|
|
1014
|
+
}
|
|
1015
|
+
if (hashes.length !== headFlags.length) {
|
|
1016
|
+
throw new Error("Expected equal raw receive hash and head lengths");
|
|
1017
|
+
}
|
|
1018
|
+
if (!this.native.commit_prepared_raw_receive_join_batch) {
|
|
1019
|
+
return undefined;
|
|
1020
|
+
}
|
|
1021
|
+
const coordinateColumns = coordinates ?? emptyNativeBackboneCoordinateCommitColumns();
|
|
1022
|
+
validateNativeBackboneCoordinateCommitColumns(coordinateColumns);
|
|
1023
|
+
if (this.native.commit_prepared_raw_receive_join_batch_u64 &&
|
|
1024
|
+
hasNativeBackboneNumericCoordinateCommitColumns(coordinateColumns)) {
|
|
1025
|
+
return this.native.commit_prepared_raw_receive_join_batch_u64(hashes, nativeBackboneHeadFlagsToBytes(headFlags), coordinateColumns.hashes, coordinateColumns.gids, coordinateColumns.hashNumberValues, coordinateColumns.coordinateCounts, coordinateColumns.coordinateValues, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateColumns.requestedReplicaValues);
|
|
1026
|
+
}
|
|
1027
|
+
const coordinateStringColumns = nativeBackboneCoordinateCommitStringColumns(coordinateColumns);
|
|
1028
|
+
return this.native.commit_prepared_raw_receive_join_batch(hashes, nativeBackboneHeadFlagsToBytes(headFlags), coordinateColumns.hashes, coordinateColumns.gids, coordinateStringColumns.hashNumbers, coordinateStringColumns.coordinateBatches, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateStringColumns.requestedReplicas);
|
|
1029
|
+
}
|
|
1030
|
+
commitVerifiedPreparedRawReceiveJoinBatch(hashes, headFlags, verifyHashes, coordinates) {
|
|
1031
|
+
if (hashes.length === 0) {
|
|
1032
|
+
return true;
|
|
1033
|
+
}
|
|
1034
|
+
if (hashes.length !== headFlags.length) {
|
|
1035
|
+
throw new Error("Expected equal raw receive hash and head lengths");
|
|
1036
|
+
}
|
|
1037
|
+
if (!this.native.commit_verified_prepared_raw_receive_join_batch) {
|
|
1038
|
+
return undefined;
|
|
1039
|
+
}
|
|
1040
|
+
const coordinateColumns = coordinates ?? emptyNativeBackboneCoordinateCommitColumns();
|
|
1041
|
+
validateNativeBackboneCoordinateCommitColumns(coordinateColumns);
|
|
1042
|
+
if (this.native.commit_verified_prepared_raw_receive_join_batch_u64 &&
|
|
1043
|
+
hasNativeBackboneNumericCoordinateCommitColumns(coordinateColumns)) {
|
|
1044
|
+
return this.native.commit_verified_prepared_raw_receive_join_batch_u64(hashes, nativeBackboneHeadFlagsToBytes(headFlags), verifyHashes, coordinateColumns.hashes, coordinateColumns.gids, coordinateColumns.hashNumberValues, coordinateColumns.coordinateCounts, coordinateColumns.coordinateValues, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateColumns.requestedReplicaValues);
|
|
1045
|
+
}
|
|
1046
|
+
const coordinateStringColumns = nativeBackboneCoordinateCommitStringColumns(coordinateColumns);
|
|
1047
|
+
return this.native.commit_verified_prepared_raw_receive_join_batch(hashes, nativeBackboneHeadFlagsToBytes(headFlags), verifyHashes, coordinateColumns.hashes, coordinateColumns.gids, coordinateStringColumns.hashNumbers, coordinateStringColumns.coordinateBatches, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateStringColumns.requestedReplicas);
|
|
1048
|
+
}
|
|
1049
|
+
commitVerifiedAllPreparedRawReceiveJoinBatch(hashes, headFlags, coordinates) {
|
|
1050
|
+
if (hashes.length === 0) {
|
|
1051
|
+
return true;
|
|
1052
|
+
}
|
|
1053
|
+
if (hashes.length !== headFlags.length) {
|
|
1054
|
+
throw new Error("Expected equal raw receive hash and head lengths");
|
|
1055
|
+
}
|
|
1056
|
+
if (!this.native.commit_verified_all_prepared_raw_receive_join_batch) {
|
|
1057
|
+
return undefined;
|
|
1058
|
+
}
|
|
1059
|
+
const coordinateColumns = coordinates ?? emptyNativeBackboneCoordinateCommitColumns();
|
|
1060
|
+
validateNativeBackboneCoordinateCommitColumns(coordinateColumns);
|
|
1061
|
+
if (this.native.commit_verified_all_prepared_raw_receive_join_batch_u64 &&
|
|
1062
|
+
hasNativeBackboneNumericCoordinateCommitColumns(coordinateColumns)) {
|
|
1063
|
+
return this.native.commit_verified_all_prepared_raw_receive_join_batch_u64(hashes, nativeBackboneHeadFlagsToBytes(headFlags), coordinateColumns.hashes, coordinateColumns.gids, coordinateColumns.hashNumberValues, coordinateColumns.coordinateCounts, coordinateColumns.coordinateValues, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateColumns.requestedReplicaValues);
|
|
1064
|
+
}
|
|
1065
|
+
const coordinateStringColumns = nativeBackboneCoordinateCommitStringColumns(coordinateColumns);
|
|
1066
|
+
return this.native.commit_verified_all_prepared_raw_receive_join_batch(hashes, nativeBackboneHeadFlagsToBytes(headFlags), coordinateColumns.hashes, coordinateColumns.gids, coordinateStringColumns.hashNumbers, coordinateStringColumns.coordinateBatches, coordinateColumns.nextHashBatches, coordinateColumns.assignedToRangeBoundaries, coordinateStringColumns.requestedReplicas);
|
|
1067
|
+
}
|
|
1068
|
+
clearPreparedRawReceiveEntries(hashes) {
|
|
1069
|
+
return this.native.clear_prepared_raw_receive_entries(iterableToArray(hashes));
|
|
1070
|
+
}
|
|
1071
|
+
verifyPreparedRawReceiveEntries(hashes) {
|
|
1072
|
+
const normalized = iterableToArray(hashes);
|
|
1073
|
+
if (normalized.length === 0) {
|
|
1074
|
+
return [];
|
|
1075
|
+
}
|
|
1076
|
+
const verified = this.native.verify_prepared_raw_receive_entries?.(normalized);
|
|
1077
|
+
return verified ? Array.from(verified, (value) => value !== 0) : undefined;
|
|
1078
|
+
}
|
|
1079
|
+
prepareEntryV0PlainEntryCommit(input, _blockStore) {
|
|
1080
|
+
if (this.options?.commitBlocks === false) {
|
|
1081
|
+
return undefined;
|
|
1082
|
+
}
|
|
1083
|
+
if (input.includeMaterializationBytes !== false ||
|
|
1084
|
+
input.includeAppendFactsBytes !== true) {
|
|
1085
|
+
return undefined;
|
|
1086
|
+
}
|
|
1087
|
+
const wallTime = BigInt(input.wallTime);
|
|
1088
|
+
const logical = input.logical ?? 0;
|
|
1089
|
+
const entryType = input.type ?? 0;
|
|
1090
|
+
const hasNoNext = input.next == null || input.next.length === 0;
|
|
1091
|
+
const documentIndex = input.documentIndex;
|
|
1092
|
+
const documentIndexArgs = nativeDocumentIndexArgs(documentIndex);
|
|
1093
|
+
const projection = documentIndex?.projection;
|
|
1094
|
+
if (documentIndex?.useLatestContext &&
|
|
1095
|
+
documentIndexArgs &&
|
|
1096
|
+
input.resolveTrimmedEntries === false) {
|
|
1097
|
+
if (projection && this.options?.documentProjectionPlanId) {
|
|
1098
|
+
return preparedCommitFactsWithLatestDocumentContextFromRow(this.native.prepare_plain_entry_commit_latest_facts_document_index_cached_plan_trim_hashes(wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, input.trimLengthTo, documentIndex.key, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, this.options.documentProjectionPlanId(projection.plan), projection.encodedDocument, projection.signer));
|
|
1099
|
+
}
|
|
1100
|
+
return preparedCommitFactsWithLatestDocumentContextFromRow(this.native.prepare_plain_entry_commit_latest_facts_document_index_trim_hashes(wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, input.trimLengthTo, documentIndex.key, documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projection?.plan, projection?.encodedDocument, projection?.signer));
|
|
1101
|
+
}
|
|
1102
|
+
if (documentIndexArgs &&
|
|
1103
|
+
projection &&
|
|
1104
|
+
this.options?.documentProjectionPlanId &&
|
|
1105
|
+
input.resolveTrimmedEntries === false &&
|
|
1106
|
+
input.trimLengthTo != null &&
|
|
1107
|
+
hasNoNext) {
|
|
1108
|
+
const projectionPlanId = this.options.documentProjectionPlanId(projection.plan);
|
|
1109
|
+
const plainPutPayloadCommit = this.native
|
|
1110
|
+
.prepare_plain_entry_commit_no_next_facts_document_index_cached_plan_compact_trim_hashes_plain_put_payload;
|
|
1111
|
+
if (plainPutPayloadCommit) {
|
|
1112
|
+
return compactPreparedCommitFactsWithTrimHashesFromRow(plainPutPayloadCommit.call(this.native, wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, input.trimLengthTo, documentIndex.key, documentIndex.existingCreated == null
|
|
1113
|
+
? ""
|
|
1114
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.signer));
|
|
1115
|
+
}
|
|
1116
|
+
return compactPreparedCommitFactsWithTrimHashesFromRow(this.native.prepare_plain_entry_commit_no_next_facts_document_index_cached_plan_compact_trim_hashes(wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, input.trimLengthTo, documentIndex.key, documentIndex.existingCreated == null
|
|
1117
|
+
? ""
|
|
1118
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.encodedDocument, projection.signer));
|
|
1119
|
+
}
|
|
1120
|
+
if (documentIndexArgs &&
|
|
1121
|
+
projection &&
|
|
1122
|
+
this.options?.documentProjectionPlanId &&
|
|
1123
|
+
input.trimLengthTo == null &&
|
|
1124
|
+
hasNoNext) {
|
|
1125
|
+
const projectionPlanId = this.options.documentProjectionPlanId(projection.plan);
|
|
1126
|
+
const plainPutPayloadCommit = this.native
|
|
1127
|
+
.prepare_plain_entry_commit_no_next_facts_document_index_cached_plan_compact_plain_put_payload;
|
|
1128
|
+
if (plainPutPayloadCommit) {
|
|
1129
|
+
return preparedCommitFactsFromRow(plainPutPayloadCommit.call(this.native, wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, documentIndex.key, documentIndex.existingCreated == null
|
|
1130
|
+
? ""
|
|
1131
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.signer));
|
|
1132
|
+
}
|
|
1133
|
+
return preparedCommitFactsFromRow(this.native.prepare_plain_entry_commit_no_next_facts_document_index_cached_plan_compact(wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, documentIndex.key, documentIndex.existingCreated == null
|
|
1134
|
+
? ""
|
|
1135
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.encodedDocument, projection.signer));
|
|
1136
|
+
}
|
|
1137
|
+
if (documentIndexArgs &&
|
|
1138
|
+
projection &&
|
|
1139
|
+
this.options?.documentProjectionPlanId) {
|
|
1140
|
+
const baseArgs = [
|
|
1141
|
+
wallTime,
|
|
1142
|
+
logical,
|
|
1143
|
+
input.gid,
|
|
1144
|
+
input.next ?? [],
|
|
1145
|
+
entryType,
|
|
1146
|
+
input.metaData,
|
|
1147
|
+
input.payloadData,
|
|
1148
|
+
input.trimLengthTo,
|
|
1149
|
+
];
|
|
1150
|
+
return preparedCommitFactsFromRow(this.native.prepare_plain_entry_commit_facts_document_index_cached_plan(...baseArgs, documentIndex.key, documentIndex.existingCreated == null
|
|
1151
|
+
? ""
|
|
1152
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, this.options.documentProjectionPlanId(projection.plan), projection.encodedDocument, projection.signer));
|
|
1153
|
+
}
|
|
1154
|
+
if (documentIndexArgs &&
|
|
1155
|
+
input.trimLengthTo == null &&
|
|
1156
|
+
hasNoNext) {
|
|
1157
|
+
return preparedCommitFactsFromRow(this.native.prepare_plain_entry_commit_no_next_facts_document_index_compact(wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, ...documentIndexArgs));
|
|
1158
|
+
}
|
|
1159
|
+
if (documentIndexArgs &&
|
|
1160
|
+
input.resolveTrimmedEntries === false &&
|
|
1161
|
+
input.trimLengthTo != null &&
|
|
1162
|
+
hasNoNext) {
|
|
1163
|
+
return compactPreparedCommitFactsWithTrimHashesFromRow(this.native.prepare_plain_entry_commit_no_next_facts_document_index_compact_trim_hashes(wallTime, logical, input.gid, entryType, input.metaData, input.payloadData, input.trimLengthTo, ...documentIndexArgs));
|
|
1164
|
+
}
|
|
1165
|
+
const baseArgs = [
|
|
1166
|
+
wallTime,
|
|
1167
|
+
logical,
|
|
1168
|
+
input.gid,
|
|
1169
|
+
input.next ?? [],
|
|
1170
|
+
entryType,
|
|
1171
|
+
input.metaData,
|
|
1172
|
+
input.payloadData,
|
|
1173
|
+
input.trimLengthTo,
|
|
1174
|
+
];
|
|
1175
|
+
return preparedCommitFactsFromRow(documentIndexArgs
|
|
1176
|
+
? this.native.prepare_plain_entry_commit_facts_document_index(...baseArgs, ...documentIndexArgs)
|
|
1177
|
+
: this.native.prepare_plain_entry_commit_facts(...baseArgs));
|
|
1178
|
+
}
|
|
1179
|
+
prepareEntryV0PlainEntryAndPut(input) {
|
|
1180
|
+
const row = input.trimLengthTo == null
|
|
1181
|
+
? this.native.prepare_plain_entry_storage_facts_and_put(BigInt(input.wallTime), input.logical ?? 0, input.gid, input.next ?? [], input.type ?? 0, input.metaData, input.payloadData)
|
|
1182
|
+
: this.native.prepare_plain_entry_storage_facts_trim_and_put(BigInt(input.wallTime), input.logical ?? 0, input.gid, input.next ?? [], input.type ?? 0, input.metaData, input.payloadData, input.trimLengthTo);
|
|
1183
|
+
const isTrimRow = Array.isArray(row) &&
|
|
1184
|
+
row.length === 2 &&
|
|
1185
|
+
Array.isArray(row[0]) &&
|
|
1186
|
+
Array.isArray(row[1]);
|
|
1187
|
+
const entry = storageFactsEntryFromRow((isTrimRow ? row[0] : row));
|
|
1188
|
+
if (!isTrimRow) {
|
|
1189
|
+
return entry;
|
|
1190
|
+
}
|
|
1191
|
+
return {
|
|
1192
|
+
...entry,
|
|
1193
|
+
trimmedEntries: row[1].map(nativeLogEntryFromTrimRow),
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1196
|
+
delete(hash) {
|
|
1197
|
+
return this.native.graph_delete(hash);
|
|
1198
|
+
}
|
|
1199
|
+
deleteMany(hashes) {
|
|
1200
|
+
return this.native.graph_delete_many([...hashes]);
|
|
1201
|
+
}
|
|
1202
|
+
oldestEntries(limit) {
|
|
1203
|
+
return this.native
|
|
1204
|
+
.graph_oldest_entries(limit)
|
|
1205
|
+
.map(nativeLogEntryFromTrimRow);
|
|
1206
|
+
}
|
|
1207
|
+
clear() {
|
|
1208
|
+
this.native.graph_clear();
|
|
1209
|
+
}
|
|
1210
|
+
heads(gid) {
|
|
1211
|
+
return this.native.graph_heads(gid);
|
|
1212
|
+
}
|
|
1213
|
+
hasHead(gid) {
|
|
1214
|
+
return this.native.graph_has_head(gid);
|
|
1215
|
+
}
|
|
1216
|
+
hasAnyHead(gids) {
|
|
1217
|
+
return this.native.graph_has_any_head([...gids]);
|
|
1218
|
+
}
|
|
1219
|
+
hasAnyHeadBatch(gidSets) {
|
|
1220
|
+
return this.native.graph_has_any_head_batch([...gidSets].map((gids) => [...gids]));
|
|
1221
|
+
}
|
|
1222
|
+
headDataEntries(gid) {
|
|
1223
|
+
return this.native.graph_head_data_entries(gid).map(headDataEntryFromRow);
|
|
1224
|
+
}
|
|
1225
|
+
maxHeadDataU32(gid) {
|
|
1226
|
+
return this.native.graph_max_head_data_u32(gid);
|
|
1227
|
+
}
|
|
1228
|
+
maxHeadDataU32Batch(gids) {
|
|
1229
|
+
return this.native.graph_max_head_data_u32_batch([...gids]);
|
|
1230
|
+
}
|
|
1231
|
+
headEntries(gid) {
|
|
1232
|
+
return this.native.graph_head_entries(gid).map(headEntryFromRow);
|
|
1233
|
+
}
|
|
1234
|
+
joinHeadEntries(gid) {
|
|
1235
|
+
return this.native.graph_join_head_entries(gid).map(joinHeadEntryFromRow);
|
|
1236
|
+
}
|
|
1237
|
+
childJoinEntries(hash) {
|
|
1238
|
+
return this.native.graph_child_join_entries(hash).map(joinHeadEntryFromRow);
|
|
1239
|
+
}
|
|
1240
|
+
entryMetadataBatch(hashes) {
|
|
1241
|
+
return this.native
|
|
1242
|
+
.graph_entry_metadata_batch([...hashes])
|
|
1243
|
+
.map(metadataEntryFromRow);
|
|
1244
|
+
}
|
|
1245
|
+
entryMetadataHintsBatch(hashes) {
|
|
1246
|
+
return (this.native.graph_entry_metadata_hints_batch ??
|
|
1247
|
+
this.native.graph_entry_metadata_batch)([...hashes]).map((row) => {
|
|
1248
|
+
if (row == null || !this.native.graph_entry_metadata_hints_batch) {
|
|
1249
|
+
return metadataEntryFromRow(row);
|
|
1250
|
+
}
|
|
1251
|
+
return requestPruneEntryFromRow(row);
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
entrySignaturePublicKeysBatch(hashes) {
|
|
1255
|
+
const hashList = [...hashes];
|
|
1256
|
+
return (this.native.graph_entry_signature_public_key_batch?.(hashList) ??
|
|
1257
|
+
hashList.map(() => undefined));
|
|
1258
|
+
}
|
|
1259
|
+
uniqueReferenceGids(hash) {
|
|
1260
|
+
return this.native.graph_unique_reference_gids(hash);
|
|
1261
|
+
}
|
|
1262
|
+
uniqueReferenceGidRowsBatch(hashes) {
|
|
1263
|
+
return this.native.graph_unique_reference_gid_rows_batch([...hashes]);
|
|
1264
|
+
}
|
|
1265
|
+
uniqueReferenceGidRowsFlatBatch(hashes) {
|
|
1266
|
+
return this.native
|
|
1267
|
+
.graph_unique_reference_gid_rows_flat_batch?.([...hashes])
|
|
1268
|
+
?.map((row) => {
|
|
1269
|
+
const [position, hash, gid] = row;
|
|
1270
|
+
return [position, hash, gid];
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
planDeleteRecursively(hashes, skipFirst = false) {
|
|
1274
|
+
return this.native.graph_plan_delete_recursively([...hashes], skipFirst);
|
|
1275
|
+
}
|
|
1276
|
+
payloadSizeSum() {
|
|
1277
|
+
return this.native.graph_payload_size_sum();
|
|
1278
|
+
}
|
|
1279
|
+
oldestHash() {
|
|
1280
|
+
return this.native.graph_oldest_hash();
|
|
1281
|
+
}
|
|
1282
|
+
newestHash() {
|
|
1283
|
+
return this.native.graph_newest_hash();
|
|
1284
|
+
}
|
|
1285
|
+
countHasNext(next, excludeHash) {
|
|
1286
|
+
return this.native.graph_count_has_next(next, excludeHash);
|
|
1287
|
+
}
|
|
1288
|
+
shadowedGids(gid, next, excludeHash) {
|
|
1289
|
+
return this.native.graph_shadowed_gids(gid, next, excludeHash);
|
|
1290
|
+
}
|
|
1291
|
+
planJoin(hash, next, type, reset = false, cutCheck) {
|
|
1292
|
+
const [skip, missingParents, cutChecked, coveredByCut] = this.native.graph_plan_join(hash, next, type, reset, cutCheck?.gid, cutCheck?.wallTime == null ? undefined : BigInt(cutCheck.wallTime), cutCheck?.logical);
|
|
1293
|
+
return { skip, missingParents, cutChecked, coveredByCut };
|
|
1294
|
+
}
|
|
1295
|
+
planJoinBatch(entries, reset = false) {
|
|
1296
|
+
const hashes = [];
|
|
1297
|
+
const nexts = [];
|
|
1298
|
+
const gids = [];
|
|
1299
|
+
const types = new Uint8Array(entries.length);
|
|
1300
|
+
const wallTimes = new BigUint64Array(entries.length);
|
|
1301
|
+
const logicals = new Uint32Array(entries.length);
|
|
1302
|
+
let cutCheck = false;
|
|
1303
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1304
|
+
const entry = entries[i];
|
|
1305
|
+
hashes.push(entry.hash);
|
|
1306
|
+
nexts.push(entry.next);
|
|
1307
|
+
types[i] = entry.type;
|
|
1308
|
+
if (entry.cutCheck) {
|
|
1309
|
+
cutCheck = true;
|
|
1310
|
+
gids[i] = entry.cutCheck.gid;
|
|
1311
|
+
wallTimes[i] = BigInt(entry.cutCheck.wallTime);
|
|
1312
|
+
logicals[i] = entry.cutCheck.logical ?? 0;
|
|
1313
|
+
}
|
|
1314
|
+
else {
|
|
1315
|
+
gids[i] = "";
|
|
1316
|
+
wallTimes[i] = 0n;
|
|
1317
|
+
logicals[i] = 0;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
return this.native
|
|
1321
|
+
.graph_plan_join_batch(hashes, nexts, types, reset, gids, wallTimes, logicals, cutCheck)
|
|
1322
|
+
.map(([skip, missingParents, cutChecked, coveredByCut]) => ({
|
|
1323
|
+
skip,
|
|
1324
|
+
missingParents,
|
|
1325
|
+
cutChecked,
|
|
1326
|
+
coveredByCut,
|
|
1327
|
+
}));
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
class NativeBackboneBlockStore {
|
|
1331
|
+
native;
|
|
1332
|
+
constructor(native) {
|
|
1333
|
+
this.native = native;
|
|
1334
|
+
}
|
|
1335
|
+
status() {
|
|
1336
|
+
return "open";
|
|
1337
|
+
}
|
|
1338
|
+
open() { }
|
|
1339
|
+
close() { }
|
|
1340
|
+
async start() { }
|
|
1341
|
+
async stop() { }
|
|
1342
|
+
async put(data) {
|
|
1343
|
+
const prepared = data instanceof Uint8Array ? await calculateRawCid(data) : data;
|
|
1344
|
+
this.native.block_put(prepared.cid, prepared.block.bytes);
|
|
1345
|
+
return prepared.cid;
|
|
1346
|
+
}
|
|
1347
|
+
async putMany(blocks) {
|
|
1348
|
+
const prepared = await Promise.all(blocks.map((block) => block instanceof Uint8Array ? calculateRawCid(block) : block));
|
|
1349
|
+
this.native.block_put_many(prepared.map((block) => block.cid), prepared.map((block) => block.block.bytes));
|
|
1350
|
+
return prepared.map((block) => block.cid);
|
|
1351
|
+
}
|
|
1352
|
+
putKnown(cid, bytes) {
|
|
1353
|
+
this.native.block_put(cid, bytes);
|
|
1354
|
+
return cid;
|
|
1355
|
+
}
|
|
1356
|
+
putKnownMany(blocks) {
|
|
1357
|
+
if (blocks.length === 0) {
|
|
1358
|
+
return [];
|
|
1359
|
+
}
|
|
1360
|
+
const cids = new Array(blocks.length);
|
|
1361
|
+
const bytes = new Array(blocks.length);
|
|
1362
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1363
|
+
const block = blocks[i];
|
|
1364
|
+
cids[i] = block[0];
|
|
1365
|
+
bytes[i] = block[1];
|
|
1366
|
+
}
|
|
1367
|
+
return this.putKnownManyColumns(cids, bytes);
|
|
1368
|
+
}
|
|
1369
|
+
putKnownManyColumns(cids, bytes) {
|
|
1370
|
+
if (cids.length !== bytes.length) {
|
|
1371
|
+
throw new Error("Expected equal block column lengths");
|
|
1372
|
+
}
|
|
1373
|
+
if (cids.length === 0) {
|
|
1374
|
+
return [];
|
|
1375
|
+
}
|
|
1376
|
+
this.native.block_put_many(cids, bytes);
|
|
1377
|
+
return cids;
|
|
1378
|
+
}
|
|
1379
|
+
putImmutable(cid, bytes) {
|
|
1380
|
+
this.native.block_put(cid, bytes);
|
|
1381
|
+
}
|
|
1382
|
+
putManyImmutable(blocks) {
|
|
1383
|
+
this.putKnownMany(blocks);
|
|
1384
|
+
}
|
|
1385
|
+
get(cid) {
|
|
1386
|
+
return this.native.block_get(cid);
|
|
1387
|
+
}
|
|
1388
|
+
async getMany(cids) {
|
|
1389
|
+
return this.native.block_get_many(cids);
|
|
1390
|
+
}
|
|
1391
|
+
has(cid) {
|
|
1392
|
+
return this.native.has_block(cid);
|
|
1393
|
+
}
|
|
1394
|
+
async hasMany(cids) {
|
|
1395
|
+
return this.native.block_has_many(cids);
|
|
1396
|
+
}
|
|
1397
|
+
rm(cid) {
|
|
1398
|
+
this.native.block_delete(cid);
|
|
1399
|
+
}
|
|
1400
|
+
del(cid) {
|
|
1401
|
+
this.rm(cid);
|
|
1402
|
+
}
|
|
1403
|
+
async rmMany(cids) {
|
|
1404
|
+
return this.native.block_delete_many(cids);
|
|
1405
|
+
}
|
|
1406
|
+
async *iterator() {
|
|
1407
|
+
for (const [key, value] of this.native.block_entries()) {
|
|
1408
|
+
yield [key, value];
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
size() {
|
|
1412
|
+
return this.native.block_size();
|
|
1413
|
+
}
|
|
1414
|
+
persisted() {
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
waitFor() {
|
|
1418
|
+
return Promise.resolve([]);
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
const integerString = (value) => typeof value === "string"
|
|
1422
|
+
? value
|
|
1423
|
+
: typeof value === "number"
|
|
1424
|
+
? Math.trunc(value).toString()
|
|
1425
|
+
: value.toString();
|
|
1426
|
+
const iterableToArray = (values) => {
|
|
1427
|
+
if (!values) {
|
|
1428
|
+
return [];
|
|
1429
|
+
}
|
|
1430
|
+
return Array.isArray(values) ? values : [...values];
|
|
1431
|
+
};
|
|
1432
|
+
const EMPTY_UINT8_ARRAY = new Uint8Array(0);
|
|
1433
|
+
const SYNC_SEND_DEFAULT_RESERVED = new Uint8Array(4);
|
|
1434
|
+
const nativeDocumentIndexArgs = (documentIndex) => documentIndex
|
|
1435
|
+
? [
|
|
1436
|
+
documentIndex.key,
|
|
1437
|
+
documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY,
|
|
1438
|
+
documentIndex.existingCreated == null
|
|
1439
|
+
? ""
|
|
1440
|
+
: integerString(documentIndex.existingCreated),
|
|
1441
|
+
documentIndex.byteElementIndexLimit ?? 0,
|
|
1442
|
+
documentIndex.deleteTrimmedHeads === true,
|
|
1443
|
+
documentIndex.projection?.plan,
|
|
1444
|
+
documentIndex.projection?.encodedDocument,
|
|
1445
|
+
documentIndex.projection?.signer,
|
|
1446
|
+
]
|
|
1447
|
+
: undefined;
|
|
1448
|
+
const nativeNoNextAppendArgs = (input) => [
|
|
1449
|
+
BigInt(input.wallTime),
|
|
1450
|
+
input.logical ?? 0,
|
|
1451
|
+
input.gid,
|
|
1452
|
+
input.type ?? 0,
|
|
1453
|
+
input.metaData,
|
|
1454
|
+
input.payloadData,
|
|
1455
|
+
input.replicas,
|
|
1456
|
+
input.roleAgeMs ?? 0,
|
|
1457
|
+
integerString(input.now ?? Date.now()),
|
|
1458
|
+
input.selfHash ?? "",
|
|
1459
|
+
input.selfReplicating ?? true,
|
|
1460
|
+
];
|
|
1461
|
+
const nativeNoNextStorageAppendArgs = (input) => [
|
|
1462
|
+
...nativeNoNextAppendArgs(input),
|
|
1463
|
+
input.resolveTrimmedEntries !== false,
|
|
1464
|
+
];
|
|
1465
|
+
const nativeStorageAppendArgs = (input) => [
|
|
1466
|
+
BigInt(input.wallTime),
|
|
1467
|
+
input.logical ?? 0,
|
|
1468
|
+
input.gid,
|
|
1469
|
+
iterableToArray(input.next),
|
|
1470
|
+
input.type ?? 0,
|
|
1471
|
+
input.metaData,
|
|
1472
|
+
input.payloadData,
|
|
1473
|
+
input.replicas,
|
|
1474
|
+
input.roleAgeMs ?? 0,
|
|
1475
|
+
integerString(input.now ?? Date.now()),
|
|
1476
|
+
input.selfHash ?? "",
|
|
1477
|
+
input.selfReplicating ?? true,
|
|
1478
|
+
input.resolveTrimmedEntries !== false,
|
|
1479
|
+
];
|
|
1480
|
+
const optionalIterableToArray = (values) => {
|
|
1481
|
+
if (!values) {
|
|
1482
|
+
return undefined;
|
|
1483
|
+
}
|
|
1484
|
+
return Array.isArray(values) ? values : [...values];
|
|
1485
|
+
};
|
|
1486
|
+
const findLeaderArguments = (options) => [
|
|
1487
|
+
options?.roleAge ?? 0,
|
|
1488
|
+
integerString(options?.now ?? Date.now()),
|
|
1489
|
+
optionalIterableToArray(options?.peerFilter),
|
|
1490
|
+
options?.expandPeerFilter === true,
|
|
1491
|
+
options?.selfHash ?? "",
|
|
1492
|
+
options?.selfReplicating === true,
|
|
1493
|
+
options?.fullReplicaFallback === true,
|
|
1494
|
+
options?.includeStrictFullReplica !== false,
|
|
1495
|
+
];
|
|
1496
|
+
export class NativePeerbitBackbone {
|
|
1497
|
+
native;
|
|
1498
|
+
resolution;
|
|
1499
|
+
graph;
|
|
1500
|
+
storageBackedGraph;
|
|
1501
|
+
blocks;
|
|
1502
|
+
documentProjectionPlanIds = new WeakMap();
|
|
1503
|
+
documentProjectionPlanStructuralIds = new Map();
|
|
1504
|
+
constructor(native, resolution) {
|
|
1505
|
+
this.native = native;
|
|
1506
|
+
this.resolution = resolution;
|
|
1507
|
+
this.graph = new NativeBackboneLogGraph(native, {
|
|
1508
|
+
documentProjectionPlanId: this.documentProjectionPlanId.bind(this),
|
|
1509
|
+
});
|
|
1510
|
+
this.storageBackedGraph = new NativeBackboneLogGraph(native, {
|
|
1511
|
+
commitBlocks: false,
|
|
1512
|
+
documentProjectionPlanId: this.documentProjectionPlanId.bind(this),
|
|
1513
|
+
});
|
|
1514
|
+
this.blocks = new NativeBackboneBlockStore(native);
|
|
1515
|
+
}
|
|
1516
|
+
static async create(options) {
|
|
1517
|
+
const wasm = await loadWasm();
|
|
1518
|
+
const resolution = options.resolution ?? "u64";
|
|
1519
|
+
return new NativePeerbitBackbone(new wasm.NativePeerbitBackbone(resolution, options.clockId, options.privateKey, options.publicKey), resolution);
|
|
1520
|
+
}
|
|
1521
|
+
get logLength() {
|
|
1522
|
+
return this.native.log_len();
|
|
1523
|
+
}
|
|
1524
|
+
get blockLength() {
|
|
1525
|
+
return this.native.block_len();
|
|
1526
|
+
}
|
|
1527
|
+
hasLogEntry(hash) {
|
|
1528
|
+
return this.native.has_log_entry(hash);
|
|
1529
|
+
}
|
|
1530
|
+
hasBlock(hash) {
|
|
1531
|
+
return this.native.has_block(hash);
|
|
1532
|
+
}
|
|
1533
|
+
/**
|
|
1534
|
+
* Byte lengths of natively stored entry blocks (`undefined` marks a
|
|
1535
|
+
* missing block), used by the fused send path to plan raw exchange-head
|
|
1536
|
+
* message chunking without materializing block bytes in JS.
|
|
1537
|
+
*/
|
|
1538
|
+
syncSendBlockByteLengths(hashes) {
|
|
1539
|
+
if (!this.native.sync_send_block_byte_lengths) {
|
|
1540
|
+
return undefined;
|
|
1541
|
+
}
|
|
1542
|
+
const lengths = this.native.sync_send_block_byte_lengths(hashes);
|
|
1543
|
+
const out = new Array(lengths.length);
|
|
1544
|
+
for (let i = 0; i < lengths.length; i++) {
|
|
1545
|
+
const length = lengths[i];
|
|
1546
|
+
out[i] = length === 0xffffffff ? undefined : length;
|
|
1547
|
+
}
|
|
1548
|
+
return out;
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Serialize one outbound raw exchange sync payload (the full
|
|
1552
|
+
* PubSubData → RequestV0 → DecryptedThing → RawExchangeHeadsMessage
|
|
1553
|
+
* nesting) from the native block store. Returns `undefined` when the
|
|
1554
|
+
* encoder is unavailable or any head's block is not natively stored.
|
|
1555
|
+
*/
|
|
1556
|
+
encodeRawExchangeSyncPayload(properties) {
|
|
1557
|
+
if (!this.native.encode_raw_exchange_sync_payload) {
|
|
1558
|
+
return undefined;
|
|
1559
|
+
}
|
|
1560
|
+
return this.native.encode_raw_exchange_sync_payload(properties.topic, properties.strict ?? true, properties.hashes, properties.gidRefrences, properties.reserved ?? SYNC_SEND_DEFAULT_RESERVED);
|
|
1561
|
+
}
|
|
1562
|
+
prepareRawReceiveBatch(blocks) {
|
|
1563
|
+
if (blocks.length === 0) {
|
|
1564
|
+
return [];
|
|
1565
|
+
}
|
|
1566
|
+
const columns = this.prepareRawReceiveColumnsBatch(blocks);
|
|
1567
|
+
if (columns) {
|
|
1568
|
+
return rawReceivePreparedFactsFromColumns(columns);
|
|
1569
|
+
}
|
|
1570
|
+
return this.native
|
|
1571
|
+
.prepare_raw_receive_batch(blocks)
|
|
1572
|
+
.map(rawReceivePreparedFactsFromRow);
|
|
1573
|
+
}
|
|
1574
|
+
prepareRawReceiveColumnsBatch(blocks, hashes, options) {
|
|
1575
|
+
if (hashes && blocks.length !== hashes.length) {
|
|
1576
|
+
throw new Error("Expected equal raw receive block and hash lengths");
|
|
1577
|
+
}
|
|
1578
|
+
if (blocks.length === 0) {
|
|
1579
|
+
return [
|
|
1580
|
+
[],
|
|
1581
|
+
[],
|
|
1582
|
+
new Uint32Array(0),
|
|
1583
|
+
[],
|
|
1584
|
+
new BigUint64Array(0),
|
|
1585
|
+
new Uint32Array(0),
|
|
1586
|
+
[],
|
|
1587
|
+
[],
|
|
1588
|
+
new Uint8Array(0),
|
|
1589
|
+
[],
|
|
1590
|
+
[],
|
|
1591
|
+
new Uint32Array(0),
|
|
1592
|
+
new Uint8Array(0),
|
|
1593
|
+
new Uint32Array(0),
|
|
1594
|
+
new BigUint64Array(0),
|
|
1595
|
+
];
|
|
1596
|
+
}
|
|
1597
|
+
if (options?.verifySignatures === false &&
|
|
1598
|
+
hashes &&
|
|
1599
|
+
this.native.prepare_raw_receive_unverified_expected_columns_batch) {
|
|
1600
|
+
return this.native.prepare_raw_receive_unverified_expected_columns_batch(blocks, hashes);
|
|
1601
|
+
}
|
|
1602
|
+
if (options?.verifySignatures === false &&
|
|
1603
|
+
!hashes &&
|
|
1604
|
+
this.native.prepare_raw_receive_unverified_columns_batch) {
|
|
1605
|
+
return this.native.prepare_raw_receive_unverified_columns_batch(blocks);
|
|
1606
|
+
}
|
|
1607
|
+
if (hashes && this.native.prepare_raw_receive_expected_columns_batch) {
|
|
1608
|
+
return this.native.prepare_raw_receive_expected_columns_batch(blocks, hashes);
|
|
1609
|
+
}
|
|
1610
|
+
return this.native.prepare_raw_receive_columns_batch?.(blocks);
|
|
1611
|
+
}
|
|
1612
|
+
prepareRawReceiveExpectedColumnsBatch(blocks, hashes, options) {
|
|
1613
|
+
if (blocks.length !== hashes.length) {
|
|
1614
|
+
throw new Error("Expected equal raw receive block and hash lengths");
|
|
1615
|
+
}
|
|
1616
|
+
if (blocks.length === 0) {
|
|
1617
|
+
return this.prepareRawReceiveColumnsBatch(blocks, hashes, options);
|
|
1618
|
+
}
|
|
1619
|
+
if (options?.verifySignatures === false &&
|
|
1620
|
+
this.native.prepare_raw_receive_unverified_expected_compact_columns_batch) {
|
|
1621
|
+
return this.native.prepare_raw_receive_unverified_expected_compact_columns_batch(blocks, hashes);
|
|
1622
|
+
}
|
|
1623
|
+
if (this.native.prepare_raw_receive_expected_compact_columns_batch) {
|
|
1624
|
+
return this.native.prepare_raw_receive_expected_compact_columns_batch(blocks, hashes);
|
|
1625
|
+
}
|
|
1626
|
+
if (options?.verifySignatures === false &&
|
|
1627
|
+
this.native.prepare_raw_receive_unverified_expected_columns_batch) {
|
|
1628
|
+
return this.native.prepare_raw_receive_unverified_expected_columns_batch(blocks, hashes);
|
|
1629
|
+
}
|
|
1630
|
+
if (this.native.prepare_raw_receive_expected_columns_batch) {
|
|
1631
|
+
return this.native.prepare_raw_receive_expected_columns_batch(blocks, hashes);
|
|
1632
|
+
}
|
|
1633
|
+
return undefined;
|
|
1634
|
+
}
|
|
1635
|
+
prepareRawReceiveExpectedColumnsAndSelectionBatch(blocks, hashes, options) {
|
|
1636
|
+
if (blocks.length !== hashes.length) {
|
|
1637
|
+
throw new Error("Expected equal raw receive block and hash lengths");
|
|
1638
|
+
}
|
|
1639
|
+
if (options.verifySignatures !== false ||
|
|
1640
|
+
!this.native
|
|
1641
|
+
.prepare_raw_receive_unverified_expected_compact_columns_and_selection_batch) {
|
|
1642
|
+
return undefined;
|
|
1643
|
+
}
|
|
1644
|
+
const row = this.native.prepare_raw_receive_unverified_expected_compact_columns_and_selection_batch(blocks, hashes, options.minReplicas, options.maxReplicas, ...findLeaderArguments(options.leaderOptions), options.fromHash);
|
|
1645
|
+
if (!row) {
|
|
1646
|
+
return undefined;
|
|
1647
|
+
}
|
|
1648
|
+
const [columns, selectionRow] = row;
|
|
1649
|
+
return {
|
|
1650
|
+
columns,
|
|
1651
|
+
selection: selectionRow
|
|
1652
|
+
? rawReceiveSelectionFromRow(this.resolution, selectionRow)
|
|
1653
|
+
: undefined,
|
|
1654
|
+
};
|
|
1655
|
+
}
|
|
1656
|
+
/**
|
|
1657
|
+
* Stash-backed twin of `prepareRawReceiveExpectedColumnsBatch`: the entry
|
|
1658
|
+
* block bytes come from the wire-sync stash inside wasm memory instead of
|
|
1659
|
+
* a JS blocks array, so no bytes cross the JS/wasm boundary. Returns
|
|
1660
|
+
* undefined when the stash entry is gone (callers fall back to the
|
|
1661
|
+
* blocks-based path).
|
|
1662
|
+
*/
|
|
1663
|
+
prepareStashedRawReceiveExpectedColumnsBatch(session, id, indexes, hashes, options) {
|
|
1664
|
+
if (indexes.length !== hashes.length) {
|
|
1665
|
+
throw new Error("Expected equal raw receive index and hash lengths");
|
|
1666
|
+
}
|
|
1667
|
+
return this.native.prepare_stashed_raw_receive_expected_compact_columns_batch?.(session.handle, id, indexes, hashes, options?.verifySignatures !== false);
|
|
1668
|
+
}
|
|
1669
|
+
/** Stash-backed twin of `prepareRawReceiveExpectedColumnsAndSelectionBatch`. */
|
|
1670
|
+
prepareStashedRawReceiveExpectedColumnsAndSelectionBatch(session, id, indexes, hashes, options) {
|
|
1671
|
+
if (indexes.length !== hashes.length) {
|
|
1672
|
+
throw new Error("Expected equal raw receive index and hash lengths");
|
|
1673
|
+
}
|
|
1674
|
+
if (options.verifySignatures !== false ||
|
|
1675
|
+
!this.native
|
|
1676
|
+
.prepare_stashed_raw_receive_expected_compact_columns_and_selection_batch) {
|
|
1677
|
+
return undefined;
|
|
1678
|
+
}
|
|
1679
|
+
const row = this.native.prepare_stashed_raw_receive_expected_compact_columns_and_selection_batch(session.handle, id, indexes, hashes, options.minReplicas, options.maxReplicas, ...findLeaderArguments(options.leaderOptions), options.fromHash);
|
|
1680
|
+
if (!row) {
|
|
1681
|
+
return undefined;
|
|
1682
|
+
}
|
|
1683
|
+
const [columns, selectionRow] = row;
|
|
1684
|
+
return {
|
|
1685
|
+
columns,
|
|
1686
|
+
selection: selectionRow
|
|
1687
|
+
? rawReceiveSelectionFromRow(this.resolution, selectionRow)
|
|
1688
|
+
: undefined,
|
|
1689
|
+
};
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Raw entry block bytes for a hash from the pending prepared-receive
|
|
1693
|
+
* entries or the committed block store — the fallback for lazily
|
|
1694
|
+
* materialized stash-backed heads whose stash entry was already released.
|
|
1695
|
+
*/
|
|
1696
|
+
rawReceiveBlockBytes(hash) {
|
|
1697
|
+
return this.native.raw_receive_block_bytes?.(hash);
|
|
1698
|
+
}
|
|
1699
|
+
clearPreparedRawReceiveEntries(hashes) {
|
|
1700
|
+
return this.native.clear_prepared_raw_receive_entries(iterableToArray(hashes));
|
|
1701
|
+
}
|
|
1702
|
+
verifyPreparedRawReceiveEntries(hashes) {
|
|
1703
|
+
return this.graph.verifyPreparedRawReceiveEntries(hashes);
|
|
1704
|
+
}
|
|
1705
|
+
planPreparedRawReceiveGroups(hashes, options) {
|
|
1706
|
+
if (!this.native.plan_prepared_raw_receive_groups) {
|
|
1707
|
+
return undefined;
|
|
1708
|
+
}
|
|
1709
|
+
const rows = this.native.plan_prepared_raw_receive_groups(iterableToArray(hashes), options.minReplicas, options.maxReplicas);
|
|
1710
|
+
return rows?.map(rawReceiveGroupPlanFromRow);
|
|
1711
|
+
}
|
|
1712
|
+
planPreparedRawReceiveGroupIndexes(hashes, options) {
|
|
1713
|
+
if (!this.native.plan_prepared_raw_receive_group_indexes) {
|
|
1714
|
+
return undefined;
|
|
1715
|
+
}
|
|
1716
|
+
const rows = this.native.plan_prepared_raw_receive_group_indexes(iterableToArray(hashes), options.minReplicas, options.maxReplicas);
|
|
1717
|
+
return rows?.map(rawReceiveGroupIndexPlanFromRow);
|
|
1718
|
+
}
|
|
1719
|
+
planPreparedRawReceiveGroupLeaders(hashes, options, leaderOptions) {
|
|
1720
|
+
if (!this.native.plan_prepared_raw_receive_group_leaders) {
|
|
1721
|
+
return undefined;
|
|
1722
|
+
}
|
|
1723
|
+
const rows = this.native.plan_prepared_raw_receive_group_leaders(iterableToArray(hashes), options.minReplicas, options.maxReplicas, ...findLeaderArguments(leaderOptions));
|
|
1724
|
+
return rows?.map((row) => rawReceiveGroupLeaderPlanFromRow(this.resolution, row));
|
|
1725
|
+
}
|
|
1726
|
+
planPreparedRawReceiveGroupAssignments(hashes, options, leaderOptions, fromHash) {
|
|
1727
|
+
if (!this.native.plan_prepared_raw_receive_group_assignments) {
|
|
1728
|
+
return undefined;
|
|
1729
|
+
}
|
|
1730
|
+
const rows = this.native.plan_prepared_raw_receive_group_assignments(iterableToArray(hashes), options.minReplicas, options.maxReplicas, ...findLeaderArguments(leaderOptions), fromHash);
|
|
1731
|
+
return rows?.map((row) => rawReceiveGroupAssignmentPlanFromRow(this.resolution, row));
|
|
1732
|
+
}
|
|
1733
|
+
planPreparedRawReceiveFastDrop(hashes, options, leaderOptions, fromHash) {
|
|
1734
|
+
if (!this.native.plan_prepared_raw_receive_fast_drop) {
|
|
1735
|
+
return undefined;
|
|
1736
|
+
}
|
|
1737
|
+
const row = this.native.plan_prepared_raw_receive_fast_drop(iterableToArray(hashes), options.minReplicas, options.maxReplicas, ...findLeaderArguments(leaderOptions), fromHash);
|
|
1738
|
+
if (!row) {
|
|
1739
|
+
return undefined;
|
|
1740
|
+
}
|
|
1741
|
+
const [canDrop, groupCount, plannedHashCount] = row;
|
|
1742
|
+
return { canDrop, groupCount, plannedHashCount };
|
|
1743
|
+
}
|
|
1744
|
+
planPreparedRawReceiveSelection(hashes, options, leaderOptions, fromHash) {
|
|
1745
|
+
if (!this.native.plan_prepared_raw_receive_selection) {
|
|
1746
|
+
return undefined;
|
|
1747
|
+
}
|
|
1748
|
+
const row = this.native.plan_prepared_raw_receive_selection(iterableToArray(hashes), options.minReplicas, options.maxReplicas, ...findLeaderArguments(leaderOptions), fromHash);
|
|
1749
|
+
return row ? rawReceiveSelectionFromRow(this.resolution, row) : undefined;
|
|
1750
|
+
}
|
|
1751
|
+
selectPreparedRawReceiveHashes(hashes, options, leaderOptions, fromHash) {
|
|
1752
|
+
if (!this.native.select_prepared_raw_receive_hashes) {
|
|
1753
|
+
return undefined;
|
|
1754
|
+
}
|
|
1755
|
+
const row = this.native.select_prepared_raw_receive_hashes(iterableToArray(hashes), options.minReplicas, options.maxReplicas, ...findLeaderArguments(leaderOptions), fromHash);
|
|
1756
|
+
return row ? rawReceiveSelectionFromRow(this.resolution, row) : undefined;
|
|
1757
|
+
}
|
|
1758
|
+
getEntryCoordinateHashes() {
|
|
1759
|
+
return this.native.entry_coordinate_hashes();
|
|
1760
|
+
}
|
|
1761
|
+
getEntryCoordinates(hash) {
|
|
1762
|
+
const coordinates = this.native.get_entry_coordinates(hash);
|
|
1763
|
+
return coordinates
|
|
1764
|
+
? rowsToNumbers(this.resolution, coordinates)
|
|
1765
|
+
: undefined;
|
|
1766
|
+
}
|
|
1767
|
+
getEntryHashesForHashNumbers(hashNumbers) {
|
|
1768
|
+
const rows = this.native.entry_hashes_for_hash_numbers([...hashNumbers].map(integerString));
|
|
1769
|
+
return rowsToHashNumberMap(rows);
|
|
1770
|
+
}
|
|
1771
|
+
getEntryHashesForHashNumbersU64(hashNumbers) {
|
|
1772
|
+
if (typeof BigUint64Array === "undefined" ||
|
|
1773
|
+
typeof this.native.entry_hashes_for_hash_numbers_u64 !== "function") {
|
|
1774
|
+
return undefined;
|
|
1775
|
+
}
|
|
1776
|
+
return rowsToHashNumberMap(this.native.entry_hashes_for_hash_numbers_u64(hashNumbers));
|
|
1777
|
+
}
|
|
1778
|
+
getEntryHashListForHashNumbersU64(hashNumbers) {
|
|
1779
|
+
if (typeof BigUint64Array === "undefined" ||
|
|
1780
|
+
typeof this.native.entry_hashes_for_hash_numbers_flat_u64 !== "function") {
|
|
1781
|
+
return undefined;
|
|
1782
|
+
}
|
|
1783
|
+
return this.native.entry_hashes_for_hash_numbers_flat_u64(hashNumbers);
|
|
1784
|
+
}
|
|
1785
|
+
getEntryHashNumbersInRange(range) {
|
|
1786
|
+
return rowsToNumbers("u64", this.native.entry_hash_numbers_in_range(integerString(range.start1), integerString(range.end1), integerString(range.start2), integerString(range.end2)));
|
|
1787
|
+
}
|
|
1788
|
+
getEntryHashNumbersInRangeU64(range) {
|
|
1789
|
+
if (typeof BigUint64Array === "undefined" ||
|
|
1790
|
+
typeof this.native.entry_hash_numbers_in_range_u64 !== "function") {
|
|
1791
|
+
return undefined;
|
|
1792
|
+
}
|
|
1793
|
+
return this.native.entry_hash_numbers_in_range_u64(integerString(range.start1), integerString(range.end1), integerString(range.start2), integerString(range.end2));
|
|
1794
|
+
}
|
|
1795
|
+
countEntryCoordinatesInRanges(ranges, options) {
|
|
1796
|
+
const start1 = [];
|
|
1797
|
+
const end1 = [];
|
|
1798
|
+
const start2 = [];
|
|
1799
|
+
const end2 = [];
|
|
1800
|
+
for (const range of ranges) {
|
|
1801
|
+
start1.push(integerString(range.start1));
|
|
1802
|
+
end1.push(integerString(range.end1));
|
|
1803
|
+
start2.push(integerString(range.start2));
|
|
1804
|
+
end2.push(integerString(range.end2));
|
|
1805
|
+
}
|
|
1806
|
+
return this.native.count_entry_coordinates_in_ranges(start1, end1, start2, end2, options?.includeAssignedToRangeBoundary === true);
|
|
1807
|
+
}
|
|
1808
|
+
getEntryCoordinateFields() {
|
|
1809
|
+
return this.native
|
|
1810
|
+
.entry_coordinate_fields()
|
|
1811
|
+
.map((row) => coordinateFieldsFromRow(this.resolution, row));
|
|
1812
|
+
}
|
|
1813
|
+
get coordinateIndexLength() {
|
|
1814
|
+
return this.native.coordinate_index_len();
|
|
1815
|
+
}
|
|
1816
|
+
get coordinateValueLength() {
|
|
1817
|
+
return this.native.coordinate_value_len();
|
|
1818
|
+
}
|
|
1819
|
+
hasCoordinateIndexHash(hash) {
|
|
1820
|
+
return this.native.coordinate_index_has_hash(hash);
|
|
1821
|
+
}
|
|
1822
|
+
configureDocumentSchemaIr(schemaIr) {
|
|
1823
|
+
const [rootFields, nodeCount, genericNodes] = this.native.configure_document_schema_ir(schemaIr);
|
|
1824
|
+
return { rootFields, nodeCount, genericNodes };
|
|
1825
|
+
}
|
|
1826
|
+
setDocumentByteElementIndexLimit(limit) {
|
|
1827
|
+
this.native.set_document_byte_element_index_limit?.(limit);
|
|
1828
|
+
}
|
|
1829
|
+
setDocumentContextHeadField(field) {
|
|
1830
|
+
this.native.set_document_context_head_field(field);
|
|
1831
|
+
}
|
|
1832
|
+
setDocumentContextFields(fields) {
|
|
1833
|
+
this.native.set_document_context_fields(fields.created, fields.modified, fields.head, fields.gid, fields.size);
|
|
1834
|
+
}
|
|
1835
|
+
projectDocumentIndexSimple(encodedDocument, plan, context) {
|
|
1836
|
+
try {
|
|
1837
|
+
return this.native.project_document_index_simple(encodedDocument, plan, integerString(context.created), integerString(context.modified), context.head ?? "", context.gid, context.size, context.signer);
|
|
1838
|
+
}
|
|
1839
|
+
catch {
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
setAppendProfileEnabled(enabled) {
|
|
1844
|
+
this.native.set_append_profile_enabled(enabled);
|
|
1845
|
+
}
|
|
1846
|
+
resetAppendProfile() {
|
|
1847
|
+
this.native.reset_append_profile();
|
|
1848
|
+
}
|
|
1849
|
+
appendProfile() {
|
|
1850
|
+
const row = this.native.append_profile();
|
|
1851
|
+
return Object.fromEntries(nativeBackboneAppendProfileKeys.map((key, index) => [
|
|
1852
|
+
key,
|
|
1853
|
+
Number(row[index] ?? 0),
|
|
1854
|
+
]));
|
|
1855
|
+
}
|
|
1856
|
+
get documentIndexLength() {
|
|
1857
|
+
return this.native.document_index_len();
|
|
1858
|
+
}
|
|
1859
|
+
get documentValueLength() {
|
|
1860
|
+
return this.native.document_value_len();
|
|
1861
|
+
}
|
|
1862
|
+
documentExactStringFirstKey(field, value) {
|
|
1863
|
+
return this.native.document_exact_string_first_key(field, value);
|
|
1864
|
+
}
|
|
1865
|
+
documentValueBytes(key) {
|
|
1866
|
+
return this.native.document_value_bytes(key);
|
|
1867
|
+
}
|
|
1868
|
+
documentEntry(key) {
|
|
1869
|
+
return this.native.document_entry(key);
|
|
1870
|
+
}
|
|
1871
|
+
documentKeysExist(keys) {
|
|
1872
|
+
const batch = Array.isArray(keys) ? keys : Array.from(keys);
|
|
1873
|
+
if (batch.length === 0) {
|
|
1874
|
+
return new Uint8Array(0);
|
|
1875
|
+
}
|
|
1876
|
+
const exists = this.native.document_keys_exist;
|
|
1877
|
+
if (exists) {
|
|
1878
|
+
return exists.call(this.native, batch);
|
|
1879
|
+
}
|
|
1880
|
+
return Uint8Array.from(batch.map((key) => (this.documentEntry(key) ? 1 : 0)));
|
|
1881
|
+
}
|
|
1882
|
+
documentFieldValue(key, field) {
|
|
1883
|
+
return this.native.document_field_value(key, field);
|
|
1884
|
+
}
|
|
1885
|
+
documentContext(key) {
|
|
1886
|
+
return this.native.document_context(key);
|
|
1887
|
+
}
|
|
1888
|
+
documentContextBatch(keys) {
|
|
1889
|
+
const batch = this.native.document_context_batch;
|
|
1890
|
+
return batch
|
|
1891
|
+
? batch.call(this.native, keys)
|
|
1892
|
+
: keys.map((key) => this.documentContext(key));
|
|
1893
|
+
}
|
|
1894
|
+
documentPreviousSignaturePublicKey(key) {
|
|
1895
|
+
const row = this.native.document_previous_signature_public_key?.(key);
|
|
1896
|
+
if (!row) {
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
const [exists, publicKey] = row;
|
|
1900
|
+
return { exists, publicKey };
|
|
1901
|
+
}
|
|
1902
|
+
documentContextsAndPreviousSignaturePublicKeys(keys) {
|
|
1903
|
+
return this.native
|
|
1904
|
+
.document_context_previous_signature_public_key_batch?.(keys)
|
|
1905
|
+
.map(([contextRow, publicKey]) => ({
|
|
1906
|
+
context: documentContextFactsFromRow(contextRow),
|
|
1907
|
+
publicKey,
|
|
1908
|
+
}));
|
|
1909
|
+
}
|
|
1910
|
+
documentQuery(queryBytes, sortBytes) {
|
|
1911
|
+
return this.native.document_query(queryBytes, sortBytes);
|
|
1912
|
+
}
|
|
1913
|
+
documentQueryPage(queryBytes, sortBytes, offset, limit) {
|
|
1914
|
+
return this.native.document_query_page(queryBytes, sortBytes, offset, limit);
|
|
1915
|
+
}
|
|
1916
|
+
documentProjectionPlanId(plan) {
|
|
1917
|
+
const cached = this.documentProjectionPlanIds.get(plan);
|
|
1918
|
+
if (cached !== undefined) {
|
|
1919
|
+
return cached;
|
|
1920
|
+
}
|
|
1921
|
+
const structuralKey = JSON.stringify(plan);
|
|
1922
|
+
const structuralCached = this.documentProjectionPlanStructuralIds.get(structuralKey);
|
|
1923
|
+
if (structuralCached !== undefined) {
|
|
1924
|
+
this.documentProjectionPlanIds.set(plan, structuralCached);
|
|
1925
|
+
return structuralCached;
|
|
1926
|
+
}
|
|
1927
|
+
const id = this.native.register_document_projection_plan(plan);
|
|
1928
|
+
this.documentProjectionPlanIds.set(plan, id);
|
|
1929
|
+
this.documentProjectionPlanStructuralIds.set(structuralKey, id);
|
|
1930
|
+
return id;
|
|
1931
|
+
}
|
|
1932
|
+
documentCount(queryBytes) {
|
|
1933
|
+
return this.native.document_count(queryBytes);
|
|
1934
|
+
}
|
|
1935
|
+
documentSum(queryBytes, field) {
|
|
1936
|
+
return this.native.document_sum(queryBytes, field);
|
|
1937
|
+
}
|
|
1938
|
+
putDocumentEncodedPartsStored(key, valuePrefixBytes, valueSuffixBytes, byteElementIndexLimit = 0) {
|
|
1939
|
+
this.native.put_document_encoded_parts_stored(key, valuePrefixBytes, valueSuffixBytes, byteElementIndexLimit);
|
|
1940
|
+
}
|
|
1941
|
+
putDocumentEncodedPartsStoredBatch(values, byteElementIndexLimit = 0) {
|
|
1942
|
+
if (values.length === 0) {
|
|
1943
|
+
return;
|
|
1944
|
+
}
|
|
1945
|
+
const keys = new Array(values.length);
|
|
1946
|
+
const prefixes = new Array(values.length);
|
|
1947
|
+
const suffixes = new Array(values.length);
|
|
1948
|
+
for (let i = 0; i < values.length; i++) {
|
|
1949
|
+
const value = values[i];
|
|
1950
|
+
keys[i] = value.key;
|
|
1951
|
+
prefixes[i] = value.valuePrefixBytes;
|
|
1952
|
+
suffixes[i] = value.valueSuffixBytes;
|
|
1953
|
+
}
|
|
1954
|
+
this.native.put_document_encoded_parts_stored_batch(keys, prefixes, suffixes, byteElementIndexLimit);
|
|
1955
|
+
}
|
|
1956
|
+
deleteDocument(key) {
|
|
1957
|
+
return this.native.delete_document(key);
|
|
1958
|
+
}
|
|
1959
|
+
deleteDocuments(keys) {
|
|
1960
|
+
const batch = Array.isArray(keys) ? keys : Array.from(keys);
|
|
1961
|
+
if (batch.length === 0) {
|
|
1962
|
+
return 0;
|
|
1963
|
+
}
|
|
1964
|
+
return this.native.delete_documents(batch);
|
|
1965
|
+
}
|
|
1966
|
+
deleteDocumentsResult(keys) {
|
|
1967
|
+
const batch = Array.isArray(keys) ? keys : Array.from(keys);
|
|
1968
|
+
if (batch.length === 0) {
|
|
1969
|
+
return new Uint8Array(0);
|
|
1970
|
+
}
|
|
1971
|
+
return this.native.delete_documents_result(batch);
|
|
1972
|
+
}
|
|
1973
|
+
clearDocumentIndex() {
|
|
1974
|
+
this.native.clear_document_index();
|
|
1975
|
+
}
|
|
1976
|
+
get documentPendingJournalLength() {
|
|
1977
|
+
return this.native.document_pending_journal_len();
|
|
1978
|
+
}
|
|
1979
|
+
get documentPendingJournalByteLength() {
|
|
1980
|
+
return this.native.document_pending_journal_byte_len();
|
|
1981
|
+
}
|
|
1982
|
+
get documentJournalEnabled() {
|
|
1983
|
+
return this.native.document_journal_enabled();
|
|
1984
|
+
}
|
|
1985
|
+
setDocumentJournalEnabled(enabled) {
|
|
1986
|
+
this.native.set_document_journal_enabled(enabled);
|
|
1987
|
+
}
|
|
1988
|
+
documentJournalHeader() {
|
|
1989
|
+
return this.native.document_journal_header();
|
|
1990
|
+
}
|
|
1991
|
+
documentJournal() {
|
|
1992
|
+
return this.native.document_journal();
|
|
1993
|
+
}
|
|
1994
|
+
clearDocumentJournal() {
|
|
1995
|
+
this.native.clear_document_journal();
|
|
1996
|
+
}
|
|
1997
|
+
clearDocumentJournalPrefix(byteLength, recordCount) {
|
|
1998
|
+
this.native.clear_document_journal_prefix(byteLength, recordCount);
|
|
1999
|
+
}
|
|
2000
|
+
documentSnapshot() {
|
|
2001
|
+
return this.native.document_snapshot();
|
|
2002
|
+
}
|
|
2003
|
+
loadDocumentSnapshotAndJournal(snapshot, journal) {
|
|
2004
|
+
return this.native.load_document_snapshot_and_journal(snapshot ?? new Uint8Array(), journal ?? new Uint8Array());
|
|
2005
|
+
}
|
|
2006
|
+
get coordinatePendingJournalLength() {
|
|
2007
|
+
return this.native.coordinate_pending_journal_len();
|
|
2008
|
+
}
|
|
2009
|
+
get coordinatePendingJournalByteLength() {
|
|
2010
|
+
return this.native.coordinate_pending_journal_byte_len();
|
|
2011
|
+
}
|
|
2012
|
+
get coordinateJournalEnabled() {
|
|
2013
|
+
return this.native.coordinate_journal_enabled();
|
|
2014
|
+
}
|
|
2015
|
+
setCoordinateJournalEnabled(enabled) {
|
|
2016
|
+
this.native.set_coordinate_journal_enabled(enabled);
|
|
2017
|
+
}
|
|
2018
|
+
coordinateJournalHeader() {
|
|
2019
|
+
return this.native.coordinate_journal_header();
|
|
2020
|
+
}
|
|
2021
|
+
coordinateJournal() {
|
|
2022
|
+
return this.native.coordinate_journal();
|
|
2023
|
+
}
|
|
2024
|
+
clearCoordinateJournal() {
|
|
2025
|
+
this.native.clear_coordinate_journal();
|
|
2026
|
+
}
|
|
2027
|
+
clearCoordinateJournalPrefix(byteLength, recordCount) {
|
|
2028
|
+
this.native.clear_coordinate_journal_prefix(byteLength, recordCount);
|
|
2029
|
+
}
|
|
2030
|
+
coordinateSnapshot() {
|
|
2031
|
+
return this.native.coordinate_snapshot();
|
|
2032
|
+
}
|
|
2033
|
+
loadCoordinateSnapshotAndJournal(snapshot, journal) {
|
|
2034
|
+
return this.native.load_coordinate_snapshot_and_journal(snapshot ?? new Uint8Array(), journal ?? new Uint8Array());
|
|
2035
|
+
}
|
|
2036
|
+
get documentSignerPendingJournalLength() {
|
|
2037
|
+
return this.native.document_signer_pending_journal_len();
|
|
2038
|
+
}
|
|
2039
|
+
get documentSignerPendingJournalByteLength() {
|
|
2040
|
+
return this.native.document_signer_pending_journal_byte_len();
|
|
2041
|
+
}
|
|
2042
|
+
get documentSignerJournalEnabled() {
|
|
2043
|
+
return this.native.document_signer_journal_enabled();
|
|
2044
|
+
}
|
|
2045
|
+
setDocumentSignerJournalEnabled(enabled) {
|
|
2046
|
+
this.native.set_document_signer_journal_enabled(enabled);
|
|
2047
|
+
}
|
|
2048
|
+
documentSignerJournalHeader() {
|
|
2049
|
+
return this.native.document_signer_journal_header();
|
|
2050
|
+
}
|
|
2051
|
+
documentSignerJournal() {
|
|
2052
|
+
return this.native.document_signer_journal();
|
|
2053
|
+
}
|
|
2054
|
+
clearDocumentSignerJournal() {
|
|
2055
|
+
this.native.clear_document_signer_journal();
|
|
2056
|
+
}
|
|
2057
|
+
clearDocumentSignerJournalPrefix(byteLength, recordCount) {
|
|
2058
|
+
this.native.clear_document_signer_journal_prefix(byteLength, recordCount);
|
|
2059
|
+
}
|
|
2060
|
+
documentSignerSnapshot() {
|
|
2061
|
+
return this.native.document_signer_snapshot();
|
|
2062
|
+
}
|
|
2063
|
+
loadDocumentSignerSnapshotAndJournal(snapshot, journal) {
|
|
2064
|
+
return this.native.load_document_signer_snapshot_and_journal(snapshot ?? new Uint8Array(), journal ?? new Uint8Array());
|
|
2065
|
+
}
|
|
2066
|
+
clear() {
|
|
2067
|
+
this.native.clear();
|
|
2068
|
+
}
|
|
2069
|
+
clearSharedLog() {
|
|
2070
|
+
this.native.clear_shared_log();
|
|
2071
|
+
}
|
|
2072
|
+
clearEntryCoordinates() {
|
|
2073
|
+
this.native.clear_entry_coordinates();
|
|
2074
|
+
}
|
|
2075
|
+
putRange(range) {
|
|
2076
|
+
this.native.put_range(range.id, range.hash, integerString(range.timestamp), integerString(range.start1), integerString(range.end1), integerString(range.start2), integerString(range.end2), integerString(range.width), range.mode);
|
|
2077
|
+
}
|
|
2078
|
+
deleteRange(id) {
|
|
2079
|
+
return this.native.delete_range(id);
|
|
2080
|
+
}
|
|
2081
|
+
putEntryCoordinates(hash, gid, coordinates, assignedToRangeBoundary, requestedReplicas, hashNumber) {
|
|
2082
|
+
this.native.put_entry_coordinates(hash, gid, integerString(hashNumber), [...coordinates].map(integerString), assignedToRangeBoundary, requestedReplicas);
|
|
2083
|
+
}
|
|
2084
|
+
deleteEntryCoordinates(hash) {
|
|
2085
|
+
return this.native.delete_entry_coordinates(hash);
|
|
2086
|
+
}
|
|
2087
|
+
deleteEntryCoordinatesBatch(hashes) {
|
|
2088
|
+
this.native.delete_entry_coordinates_batch(iterableToArray(hashes));
|
|
2089
|
+
}
|
|
2090
|
+
commitEntryCoordinates(hash, gid, coordinates, nextHashes, assignedToRangeBoundary, requestedReplicas, hashNumber) {
|
|
2091
|
+
this.native.commit_entry_coordinates(hash, gid, integerString(hashNumber), [...coordinates].map(integerString), iterableToArray(nextHashes), assignedToRangeBoundary, requestedReplicas);
|
|
2092
|
+
}
|
|
2093
|
+
commitEntryCoordinatesBatch(entries) {
|
|
2094
|
+
const rows = [...entries].map((entry) => {
|
|
2095
|
+
const coordinates = [...entry.coordinates].map(integerString);
|
|
2096
|
+
return {
|
|
2097
|
+
hash: entry.hash,
|
|
2098
|
+
gid: entry.gid,
|
|
2099
|
+
hashNumber: integerString(entry.hashNumber),
|
|
2100
|
+
coordinates,
|
|
2101
|
+
nextHashes: iterableToArray(entry.nextHashes),
|
|
2102
|
+
assignedToRangeBoundary: entry.assignedToRangeBoundary ? 1 : 0,
|
|
2103
|
+
requestedReplicas: entry.requestedReplicas,
|
|
2104
|
+
};
|
|
2105
|
+
});
|
|
2106
|
+
if (rows.length === 0) {
|
|
2107
|
+
return;
|
|
2108
|
+
}
|
|
2109
|
+
this.commitEntryCoordinatesColumnsBatch({
|
|
2110
|
+
hashes: rows.map((row) => row.hash),
|
|
2111
|
+
gids: rows.map((row) => row.gid),
|
|
2112
|
+
hashNumbers: rows.map((row) => row.hashNumber),
|
|
2113
|
+
coordinateBatches: rows.map((row) => row.coordinates),
|
|
2114
|
+
nextHashBatches: rows.map((row) => row.nextHashes),
|
|
2115
|
+
assignedToRangeBoundaries: new Uint8Array(rows.map((row) => row.assignedToRangeBoundary)),
|
|
2116
|
+
requestedReplicas: rows.map((row) => row.requestedReplicas),
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
commitEntryCoordinatesColumnsBatch(columns) {
|
|
2120
|
+
const { hashes, gids, nextHashBatches, assignedToRangeBoundaries, } = columns;
|
|
2121
|
+
if (hashes.length === 0) {
|
|
2122
|
+
return;
|
|
2123
|
+
}
|
|
2124
|
+
validateNativeBackboneCoordinateCommitColumns(columns);
|
|
2125
|
+
if (this.native.commit_entry_coordinates_batch_u64 &&
|
|
2126
|
+
hasNativeBackboneNumericCoordinateCommitColumns(columns)) {
|
|
2127
|
+
this.native.commit_entry_coordinates_batch_u64(hashes, gids, columns.hashNumberValues, columns.coordinateCounts, columns.coordinateValues, nextHashBatches, assignedToRangeBoundaries, columns.requestedReplicaValues);
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
const coordinateStringColumns = nativeBackboneCoordinateCommitStringColumns(columns);
|
|
2131
|
+
if (!this.native.commit_entry_coordinates_batch) {
|
|
2132
|
+
for (let i = 0; i < hashes.length; i++) {
|
|
2133
|
+
this.native.commit_entry_coordinates(hashes[i], gids[i], coordinateStringColumns.hashNumbers[i], coordinateStringColumns.coordinateBatches[i], nextHashBatches[i], assignedToRangeBoundaries[i] === 1, coordinateStringColumns.requestedReplicas[i]);
|
|
2134
|
+
}
|
|
2135
|
+
return;
|
|
2136
|
+
}
|
|
2137
|
+
this.native.commit_entry_coordinates_batch(hashes, gids, coordinateStringColumns.hashNumbers, coordinateStringColumns.coordinateBatches, nextHashBatches, assignedToRangeBoundaries, coordinateStringColumns.requestedReplicas);
|
|
2138
|
+
}
|
|
2139
|
+
addGidPeers(gid, peers, reset = false) {
|
|
2140
|
+
return this.native.add_gid_peers(gid, iterableToArray(peers), reset);
|
|
2141
|
+
}
|
|
2142
|
+
removeGidPeer(peer, gid) {
|
|
2143
|
+
this.native.remove_gid_peer(peer, gid);
|
|
2144
|
+
}
|
|
2145
|
+
removeGidPeers(peer, gids) {
|
|
2146
|
+
const gidArray = iterableToArray(gids);
|
|
2147
|
+
if (this.native.remove_gid_peers) {
|
|
2148
|
+
this.native.remove_gid_peers(peer, gidArray);
|
|
2149
|
+
return;
|
|
2150
|
+
}
|
|
2151
|
+
for (const gid of gidArray) {
|
|
2152
|
+
this.native.remove_gid_peer(peer, gid);
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
deleteGidPeers(gid) {
|
|
2156
|
+
return this.native.delete_gid_peers(gid);
|
|
2157
|
+
}
|
|
2158
|
+
clearGidPeers() {
|
|
2159
|
+
this.native.clear_gid_peers();
|
|
2160
|
+
}
|
|
2161
|
+
markEntriesKnownByPeer(hashes, peer) {
|
|
2162
|
+
this.native.mark_entries_known_by_peer(iterableToArray(hashes), peer);
|
|
2163
|
+
}
|
|
2164
|
+
removeEntriesKnownByPeer(hashes, peer) {
|
|
2165
|
+
this.native.remove_entries_known_by_peer(iterableToArray(hashes), peer);
|
|
2166
|
+
}
|
|
2167
|
+
removePeerFromEntryKnownPeers(peer) {
|
|
2168
|
+
this.native.remove_peer_from_entry_known_peers(peer);
|
|
2169
|
+
}
|
|
2170
|
+
clearEntryKnownPeers() {
|
|
2171
|
+
this.native.clear_entry_known_peers();
|
|
2172
|
+
}
|
|
2173
|
+
getGrid(from, count) {
|
|
2174
|
+
return rowsToNumbers(this.resolution, this.native.get_grid(integerString(from), count));
|
|
2175
|
+
}
|
|
2176
|
+
getGidCoordinates(gid, count) {
|
|
2177
|
+
return rowsToNumbers(this.resolution, this.native.get_gid_coordinates(gid, count));
|
|
2178
|
+
}
|
|
2179
|
+
findLeaders(cursors, replicas, options) {
|
|
2180
|
+
const rows = this.native.find_leaders([...cursors].map(integerString), replicas, ...findLeaderArguments(options));
|
|
2181
|
+
return rowsToSamples(rows) ?? new Map();
|
|
2182
|
+
}
|
|
2183
|
+
findLeadersBatch(items, options) {
|
|
2184
|
+
const entries = [...items];
|
|
2185
|
+
const rows = this.native.find_leaders_batch(entries.map((entry) => [...entry.cursors].map(integerString)), entries.map((entry) => entry.replicas), ...findLeaderArguments(options));
|
|
2186
|
+
return rows.map((row) => rowsToSamples(row) ?? new Map());
|
|
2187
|
+
}
|
|
2188
|
+
planLeadersForGid(gid, replicas, options) {
|
|
2189
|
+
const [coordinateRows, leaderRows] = this.native.plan_entry_leaders_for_gid(gid, replicas, ...findLeaderArguments(options));
|
|
2190
|
+
return lazyLeaderPlanFromRows(this.resolution, coordinateRows, leaderRows);
|
|
2191
|
+
}
|
|
2192
|
+
planLeadersForGidsBatch(items, options) {
|
|
2193
|
+
const entries = [...items];
|
|
2194
|
+
const rows = this.native.plan_leaders_for_gids_batch(entries.map((entry) => entry.gid), entries.map((entry) => entry.replicas), ...findLeaderArguments(options));
|
|
2195
|
+
return rows.map(([coordinateRows, leaderRows]) => lazyLeaderPlanFromRows(this.resolution, coordinateRows, leaderRows));
|
|
2196
|
+
}
|
|
2197
|
+
planLeaderSamplesForGidsBatch(items, options) {
|
|
2198
|
+
if (!this.native.plan_leader_samples_for_gids_batch) {
|
|
2199
|
+
return undefined;
|
|
2200
|
+
}
|
|
2201
|
+
const entries = iterableToArray(items);
|
|
2202
|
+
const rows = this.native.plan_leader_samples_for_gids_batch(entries.map((entry) => entry.gid), entries.map((entry) => entry.replicas), ...findLeaderArguments(options));
|
|
2203
|
+
return rows.map((leaderRows) => rowsToSamples(leaderRows) ?? new Map());
|
|
2204
|
+
}
|
|
2205
|
+
planRequestPruneLeaderHints(hashes, skipHashes, options) {
|
|
2206
|
+
if (!this.native.plan_request_prune_leader_hints) {
|
|
2207
|
+
return undefined;
|
|
2208
|
+
}
|
|
2209
|
+
const [entryRows, presentBlockHashes, localLeaderHashes, peerHistoryGids, peerHistoryRemovedHashes,] = this.native.plan_request_prune_leader_hints([...hashes], [...skipHashes], ...findLeaderArguments(options));
|
|
2210
|
+
const entries = new Map();
|
|
2211
|
+
const replicaCounts = new Map();
|
|
2212
|
+
for (const row of entryRows) {
|
|
2213
|
+
const entry = requestPruneEntryFromRow(row);
|
|
2214
|
+
entries.set(entry.hash, entry);
|
|
2215
|
+
if (entry.replicas != null) {
|
|
2216
|
+
replicaCounts.set(entry.hash, entry.replicas);
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
return {
|
|
2220
|
+
entries,
|
|
2221
|
+
presentBlockHashes: new Set(presentBlockHashes),
|
|
2222
|
+
localLeaderHashes: new Set(localLeaderHashes),
|
|
2223
|
+
replicaCounts,
|
|
2224
|
+
peerHistoryGids,
|
|
2225
|
+
peerHistoryRemovedHashes: new Set(peerHistoryRemovedHashes),
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
planRequestPruneLeaderHintColumns(hashes, skipHashes, options) {
|
|
2229
|
+
if (!this.native.plan_request_prune_leader_hint_columns) {
|
|
2230
|
+
return undefined;
|
|
2231
|
+
}
|
|
2232
|
+
const [gids, data, presentBlockFlags, localLeaderFlags, replicaCounts, peerHistoryGids, peerHistoryRemovedFlags,] = this.native.plan_request_prune_leader_hint_columns(iterableToArray(hashes), iterableToArray(skipHashes), ...findLeaderArguments(options));
|
|
2233
|
+
return {
|
|
2234
|
+
gids,
|
|
2235
|
+
data,
|
|
2236
|
+
presentBlockFlags,
|
|
2237
|
+
localLeaderFlags,
|
|
2238
|
+
replicaCounts,
|
|
2239
|
+
peerHistoryGids,
|
|
2240
|
+
peerHistoryRemovedFlags,
|
|
2241
|
+
};
|
|
2242
|
+
}
|
|
2243
|
+
planRequestPruneAllConfirmed(hashes, prunePeer, options) {
|
|
2244
|
+
const hashArray = iterableToArray(hashes);
|
|
2245
|
+
if (options?.omitPeerHistoryGids === true &&
|
|
2246
|
+
this.native.plan_request_prune_all_confirmed_no_gid_return) {
|
|
2247
|
+
return {
|
|
2248
|
+
allConfirmed: this.native.plan_request_prune_all_confirmed_no_gid_return(hashArray, prunePeer, ...findLeaderArguments(options)),
|
|
2249
|
+
peerHistoryGids: [],
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
if (!this.native.plan_request_prune_all_confirmed) {
|
|
2253
|
+
return undefined;
|
|
2254
|
+
}
|
|
2255
|
+
const [allConfirmed, peerHistoryGids] = this.native.plan_request_prune_all_confirmed(hashArray, prunePeer, ...findLeaderArguments(options));
|
|
2256
|
+
return {
|
|
2257
|
+
allConfirmed,
|
|
2258
|
+
peerHistoryGids,
|
|
2259
|
+
};
|
|
2260
|
+
}
|
|
2261
|
+
planEntryAssignmentForGid(gid, replicas, options) {
|
|
2262
|
+
const [coordinateRows, leaderRows, assignedToRangeBoundary] = this.native.plan_entry_assignment_for_gid(gid, replicas, ...findLeaderArguments(options));
|
|
2263
|
+
return {
|
|
2264
|
+
coordinates: rowsToNumbers(this.resolution, coordinateRows),
|
|
2265
|
+
leaders: rowsToSamples(leaderRows) ?? new Map(),
|
|
2266
|
+
assignedToRangeBoundary,
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2269
|
+
planRepairDispatchForEntries(input, options) {
|
|
2270
|
+
const entries = [...input.entries];
|
|
2271
|
+
const pendingModes = [...input.pendingModes];
|
|
2272
|
+
const rows = this.native.plan_repair_dispatch_for_entries(entries.map((entry) => entry.hash), entries.map((entry) => entry.gid), entries.map((entry) => entry.requestedReplicas), entries.map((entry) => [...entry.coordinates].map(integerString)), pendingModes, pendingModes.map((mode) => [
|
|
2273
|
+
...(input.pendingPeersByMode.get(mode) ?? []),
|
|
2274
|
+
]), pendingModes.map((mode) => {
|
|
2275
|
+
const optimisticByGid = input.optimisticPeersByMode?.get(mode);
|
|
2276
|
+
return entries.map((entry) => [
|
|
2277
|
+
...(optimisticByGid?.get(entry.gid) ?? []),
|
|
2278
|
+
]);
|
|
2279
|
+
}), input.fullReplicaRepairCandidates
|
|
2280
|
+
? [...input.fullReplicaRepairCandidates]
|
|
2281
|
+
: [], input.fullReplicaRepairCandidateCount, ...findLeaderArguments({
|
|
2282
|
+
...options,
|
|
2283
|
+
selfHash: input.selfHash,
|
|
2284
|
+
}));
|
|
2285
|
+
return rowsToRepairDispatchPlan(rows);
|
|
2286
|
+
}
|
|
2287
|
+
planRepairDispatchForResidentEntries(input, options) {
|
|
2288
|
+
const pendingModes = [...input.pendingModes];
|
|
2289
|
+
const optimisticGidsByMode = [];
|
|
2290
|
+
const optimisticPeersByGidByMode = [];
|
|
2291
|
+
for (const mode of pendingModes) {
|
|
2292
|
+
const optimisticByGid = input.optimisticPeersByMode?.get(mode);
|
|
2293
|
+
const gids = [];
|
|
2294
|
+
const peersByGid = [];
|
|
2295
|
+
if (optimisticByGid) {
|
|
2296
|
+
for (const [gid, peers] of optimisticByGid) {
|
|
2297
|
+
gids.push(gid);
|
|
2298
|
+
peersByGid.push([...peers]);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
optimisticGidsByMode.push(gids);
|
|
2302
|
+
optimisticPeersByGidByMode.push(peersByGid);
|
|
2303
|
+
}
|
|
2304
|
+
const rows = this.native.plan_repair_dispatch_for_resident_entries(pendingModes, pendingModes.map((mode) => [
|
|
2305
|
+
...(input.pendingPeersByMode.get(mode) ?? []),
|
|
2306
|
+
]), optimisticGidsByMode, optimisticPeersByGidByMode, input.fullReplicaRepairCandidates
|
|
2307
|
+
? [...input.fullReplicaRepairCandidates]
|
|
2308
|
+
: [], input.fullReplicaRepairCandidateCount, ...findLeaderArguments({
|
|
2309
|
+
...options,
|
|
2310
|
+
selfHash: input.selfHash,
|
|
2311
|
+
}));
|
|
2312
|
+
return rowsToRepairDispatchPlan(rows);
|
|
2313
|
+
}
|
|
2314
|
+
planLocalAppendForGidCompact(input, options) {
|
|
2315
|
+
const [leaderRows, isLeader, assignedToRangeBoundary, coordinatePlanRow] = this.native.plan_local_append_for_gid_compact(input.entryHash, input.gid, integerString(input.hashNumber ?? 0), iterableToArray(input.nextHashes), input.replicas, ...findLeaderArguments({
|
|
2316
|
+
...options,
|
|
2317
|
+
selfHash: input.selfHash,
|
|
2318
|
+
}));
|
|
2319
|
+
const coordinate = appendCoordinatePlanFromRow(this.resolution, coordinatePlanRow);
|
|
2320
|
+
let coordinates;
|
|
2321
|
+
return {
|
|
2322
|
+
get coordinates() {
|
|
2323
|
+
return (coordinates ??= coordinate.coordinates);
|
|
2324
|
+
},
|
|
2325
|
+
set coordinates(value) {
|
|
2326
|
+
coordinates = value;
|
|
2327
|
+
},
|
|
2328
|
+
leaders: rowsToSamples(leaderRows),
|
|
2329
|
+
isLeader,
|
|
2330
|
+
assignedToRangeBoundary,
|
|
2331
|
+
coordinate,
|
|
2332
|
+
};
|
|
2333
|
+
}
|
|
2334
|
+
commitLocalAppendForGidCompact(input, options) {
|
|
2335
|
+
const [leaderRows, isLeader, assignedToRangeBoundary, coordinatePlanRow] = this.native.commit_local_append_for_gid_compact(input.entryHash, input.gid, integerString(input.hashNumber ?? 0), iterableToArray(input.nextHashes), iterableToArray(input.deleteHashes), input.replicas, ...findLeaderArguments({
|
|
2336
|
+
...options,
|
|
2337
|
+
selfHash: input.selfHash,
|
|
2338
|
+
}));
|
|
2339
|
+
const coordinate = appendCoordinatePlanFromRow(this.resolution, coordinatePlanRow);
|
|
2340
|
+
let coordinates;
|
|
2341
|
+
return {
|
|
2342
|
+
get coordinates() {
|
|
2343
|
+
return (coordinates ??= coordinate.coordinates);
|
|
2344
|
+
},
|
|
2345
|
+
set coordinates(value) {
|
|
2346
|
+
coordinates = value;
|
|
2347
|
+
},
|
|
2348
|
+
leaders: rowsToSamples(leaderRows),
|
|
2349
|
+
isLeader,
|
|
2350
|
+
assignedToRangeBoundary,
|
|
2351
|
+
coordinate,
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
planAppendForGid(input, options) {
|
|
2355
|
+
const [coordinateRows, leaderRows, isLeader, assignedToRangeBoundary, delivery, coordinatePlanRow,] = this.native.plan_append_for_gid(input.entryHash, input.gid, integerString(input.hashNumber ?? 0), iterableToArray(input.nextHashes), input.replicas, iterableToArray(input.fullReplicaCandidates), iterableToArray(input.fallbackRecipients), input.selfHash, input.deliveryEnabled, input.reliabilityAck, input.minAcks, input.requireRecipients, ...findLeaderArguments({
|
|
2356
|
+
...options,
|
|
2357
|
+
selfHash: input.selfHash,
|
|
2358
|
+
}));
|
|
2359
|
+
return {
|
|
2360
|
+
coordinates: rowsToNumbers(this.resolution, coordinateRows),
|
|
2361
|
+
leaders: rowsToSamples(leaderRows),
|
|
2362
|
+
isLeader,
|
|
2363
|
+
assignedToRangeBoundary,
|
|
2364
|
+
delivery: appendDeliveryPlanFromRow(delivery),
|
|
2365
|
+
coordinate: appendCoordinatePlanFromRow(this.resolution, coordinatePlanRow),
|
|
2366
|
+
};
|
|
2367
|
+
}
|
|
2368
|
+
planAppendForGidsBatch(input, options) {
|
|
2369
|
+
const entries = [...input.entries];
|
|
2370
|
+
const rows = this.native.plan_append_for_gids_batch(entries.map((entry) => entry.entryHash), entries.map((entry) => entry.gid), entries.map((entry) => integerString(entry.hashNumber ?? 0)), entries.map((entry) => iterableToArray(entry.nextHashes)), entries.map((entry) => entry.replicas), iterableToArray(input.fullReplicaCandidates), iterableToArray(input.fallbackRecipients), input.selfHash, input.deliveryEnabled, input.reliabilityAck, input.minAcks, input.requireRecipients, ...findLeaderArguments({
|
|
2371
|
+
...options,
|
|
2372
|
+
selfHash: input.selfHash,
|
|
2373
|
+
}));
|
|
2374
|
+
return rows.map(([coordinateRows, leaderRows, isLeader, assignedToRangeBoundary, delivery, coordinatePlanRow,]) => ({
|
|
2375
|
+
coordinates: rowsToNumbers(this.resolution, coordinateRows),
|
|
2376
|
+
leaders: rowsToSamples(leaderRows),
|
|
2377
|
+
isLeader,
|
|
2378
|
+
assignedToRangeBoundary,
|
|
2379
|
+
delivery: appendDeliveryPlanFromRow(delivery),
|
|
2380
|
+
coordinate: appendCoordinatePlanFromRow(this.resolution, coordinatePlanRow),
|
|
2381
|
+
}));
|
|
2382
|
+
}
|
|
2383
|
+
planReceiveCoordinatesForGidsBatch(input, options) {
|
|
2384
|
+
const entries = [...input.entries];
|
|
2385
|
+
const rows = this.native.plan_receive_coordinates_for_gids_batch(entries.map((entry) => entry.entryHash), entries.map((entry) => entry.gid), entries.map((entry) => integerString(entry.hashNumber ?? 0)), entries.map((entry) => iterableToArray(entry.nextHashes)), entries.map((entry) => entry.replicas), ...findLeaderArguments({
|
|
2386
|
+
...options,
|
|
2387
|
+
selfHash: input.selfHash,
|
|
2388
|
+
}));
|
|
2389
|
+
return rows.map(([coordinateRows, leaderRows, isLeader, assignedToRangeBoundary, coordinatePlanRow,]) => ({
|
|
2390
|
+
coordinates: rowsToNumbers(this.resolution, coordinateRows),
|
|
2391
|
+
leaders: rowsToSamples(leaderRows),
|
|
2392
|
+
isLeader,
|
|
2393
|
+
assignedToRangeBoundary,
|
|
2394
|
+
coordinate: appendCoordinatePlanFromRow(this.resolution, coordinatePlanRow),
|
|
2395
|
+
}));
|
|
2396
|
+
}
|
|
2397
|
+
appendPlainNoNextTransaction(input) {
|
|
2398
|
+
return this.preparePlainCommittedNoNextStorageAppendTransaction(input);
|
|
2399
|
+
}
|
|
2400
|
+
preparePlainNoNextStorageAppendTransaction(input) {
|
|
2401
|
+
const baseArgs = nativeNoNextStorageAppendArgs(input);
|
|
2402
|
+
const documentIndexArgs = nativeDocumentIndexArgs(input.documentIndex);
|
|
2403
|
+
const row = input.trimLengthTo == null
|
|
2404
|
+
? documentIndexArgs
|
|
2405
|
+
? this.native.prepare_plain_no_next_storage_append_document_index_transaction(...baseArgs, ...documentIndexArgs)
|
|
2406
|
+
: this.native.prepare_plain_no_next_storage_append_transaction(...baseArgs)
|
|
2407
|
+
: documentIndexArgs
|
|
2408
|
+
? this.native.prepare_plain_no_next_storage_append_document_index_transaction_trim(...baseArgs, ...documentIndexArgs, input.trimLengthTo)
|
|
2409
|
+
: this.native.prepare_plain_no_next_storage_append_transaction_trim(...baseArgs, input.trimLengthTo);
|
|
2410
|
+
return storageAppendResultFromRow(this.resolution, row);
|
|
2411
|
+
}
|
|
2412
|
+
preparePlainStorageAppendTransaction(input) {
|
|
2413
|
+
const baseArgs = nativeStorageAppendArgs(input);
|
|
2414
|
+
const documentIndexArgs = nativeDocumentIndexArgs(input.documentIndex);
|
|
2415
|
+
const row = input.trimLengthTo == null
|
|
2416
|
+
? documentIndexArgs
|
|
2417
|
+
? this.native.prepare_plain_storage_append_document_index_transaction(...baseArgs, ...documentIndexArgs)
|
|
2418
|
+
: this.native.prepare_plain_storage_append_transaction(...baseArgs)
|
|
2419
|
+
: documentIndexArgs
|
|
2420
|
+
? this.native.prepare_plain_storage_append_document_index_transaction_trim(...baseArgs, ...documentIndexArgs, input.trimLengthTo)
|
|
2421
|
+
: this.native.prepare_plain_storage_append_transaction_trim(...baseArgs, input.trimLengthTo);
|
|
2422
|
+
return storageAppendResultFromRow(this.resolution, row);
|
|
2423
|
+
}
|
|
2424
|
+
preparePlainCommittedStorageAppendTransaction(input) {
|
|
2425
|
+
if (input.documentDeleteKey && input.documentIndex) {
|
|
2426
|
+
throw new Error("Native backbone append cannot both put and delete a document index row");
|
|
2427
|
+
}
|
|
2428
|
+
if (input.documentDeleteKey) {
|
|
2429
|
+
const baseArgs = nativeStorageAppendArgs(input);
|
|
2430
|
+
const row = input.trimLengthTo == null
|
|
2431
|
+
? this.native.prepare_plain_committed_storage_append_document_delete_transaction(...baseArgs, input.documentDeleteKey)
|
|
2432
|
+
: this.native.prepare_plain_committed_storage_append_document_delete_transaction_trim(...baseArgs, input.documentDeleteKey, input.trimLengthTo);
|
|
2433
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2434
|
+
}
|
|
2435
|
+
const documentIndex = input.documentIndex;
|
|
2436
|
+
if (documentIndex?.useLatestContext) {
|
|
2437
|
+
if (input.resolveTrimmedEntries === false) {
|
|
2438
|
+
const requiredPreviousSignerPublicKey = documentIndex.requiredPreviousSignerPublicKey;
|
|
2439
|
+
if (requiredPreviousSignerPublicKey) {
|
|
2440
|
+
const nativeCompactRequired = this.native
|
|
2441
|
+
.prepare_plain_committed_storage_append_document_index_latest_required_previous_signer_compact_transaction;
|
|
2442
|
+
if (nativeCompactRequired) {
|
|
2443
|
+
const row = nativeCompactRequired.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, documentIndex.projection?.plan, documentIndex.projection?.encodedDocument, documentIndex.projection?.signer, requiredPreviousSignerPublicKey, input.trimLengthTo);
|
|
2444
|
+
return compactCommittedLatestStorageAppendResultFromRow(this.resolution, row);
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
const projection = documentIndex.projection;
|
|
2448
|
+
if (projection) {
|
|
2449
|
+
const projectionPlanId = this.documentProjectionPlanId(projection.plan);
|
|
2450
|
+
const nativeCompactPlainPutPayload = documentIndex.usePlainPutPayload === true
|
|
2451
|
+
? this.native
|
|
2452
|
+
.prepare_plain_committed_storage_append_document_index_latest_cached_plan_compact_plain_put_payload_transaction
|
|
2453
|
+
: undefined;
|
|
2454
|
+
if (nativeCompactPlainPutPayload) {
|
|
2455
|
+
const row = nativeCompactPlainPutPayload.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.signer, input.trimLengthTo);
|
|
2456
|
+
return compactCommittedLatestStorageAppendResultFromRow(this.resolution, row);
|
|
2457
|
+
}
|
|
2458
|
+
const nativeCompactCached = this.native
|
|
2459
|
+
.prepare_plain_committed_storage_append_document_index_latest_cached_plan_compact_transaction;
|
|
2460
|
+
if (nativeCompactCached) {
|
|
2461
|
+
const row = nativeCompactCached.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.encodedDocument, projection.signer, input.trimLengthTo);
|
|
2462
|
+
return compactCommittedLatestStorageAppendResultFromRow(this.resolution, row);
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
if (!requiredPreviousSignerPublicKey &&
|
|
2466
|
+
documentIndex.usePlainPutPayload === true) {
|
|
2467
|
+
const nativeCompactPlainPutPayload = this.native
|
|
2468
|
+
.prepare_plain_committed_storage_append_document_index_latest_compact_plain_put_payload_transaction;
|
|
2469
|
+
if (nativeCompactPlainPutPayload) {
|
|
2470
|
+
const row = nativeCompactPlainPutPayload.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, input.trimLengthTo);
|
|
2471
|
+
return compactCommittedLatestStorageAppendResultFromRow(this.resolution, row);
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
const nativeCompact = this.native
|
|
2475
|
+
.prepare_plain_committed_storage_append_document_index_latest_compact_transaction;
|
|
2476
|
+
if (nativeCompact) {
|
|
2477
|
+
const row = nativeCompact.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, documentIndex.projection?.plan, documentIndex.projection?.encodedDocument, documentIndex.projection?.signer, input.trimLengthTo);
|
|
2478
|
+
return compactCommittedLatestStorageAppendResultFromRow(this.resolution, row);
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
const requiredPreviousSignerPublicKey = documentIndex.requiredPreviousSignerPublicKey;
|
|
2482
|
+
if (requiredPreviousSignerPublicKey) {
|
|
2483
|
+
const requiredPreviousSignerTransaction = this.native
|
|
2484
|
+
.prepare_plain_committed_storage_append_document_index_latest_required_previous_signer_transaction;
|
|
2485
|
+
if (!requiredPreviousSignerTransaction) {
|
|
2486
|
+
throw new Error("Native backbone requires previous-signer policy transaction support");
|
|
2487
|
+
}
|
|
2488
|
+
const row = requiredPreviousSignerTransaction.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, input.resolveTrimmedEntries !== false, documentIndex.key, documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, documentIndex.projection?.plan, documentIndex.projection?.encodedDocument, documentIndex.projection?.signer, requiredPreviousSignerPublicKey, input.trimLengthTo);
|
|
2489
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2490
|
+
}
|
|
2491
|
+
const projection = documentIndex.projection;
|
|
2492
|
+
if (projection) {
|
|
2493
|
+
const row = this.native.prepare_plain_committed_storage_append_document_index_latest_cached_plan_transaction(BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, input.resolveTrimmedEntries !== false, documentIndex.key, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, this.documentProjectionPlanId(projection.plan), projection.encodedDocument, projection.signer, input.trimLengthTo);
|
|
2494
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2495
|
+
}
|
|
2496
|
+
const row = this.native.prepare_plain_committed_storage_append_document_index_latest_transaction(BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, input.resolveTrimmedEntries !== false, documentIndex.key, documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY, documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, documentIndex.projection?.plan, documentIndex.projection?.encodedDocument, documentIndex.projection?.signer, input.trimLengthTo);
|
|
2497
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2498
|
+
}
|
|
2499
|
+
const baseArgs = nativeStorageAppendArgs(input);
|
|
2500
|
+
const documentIndexArgs = nativeDocumentIndexArgs(documentIndex);
|
|
2501
|
+
const row = input.trimLengthTo == null
|
|
2502
|
+
? documentIndexArgs
|
|
2503
|
+
? this.native.prepare_plain_committed_storage_append_document_index_transaction(...baseArgs, ...documentIndexArgs)
|
|
2504
|
+
: this.native.prepare_plain_committed_storage_append_transaction(...baseArgs)
|
|
2505
|
+
: documentIndexArgs
|
|
2506
|
+
? this.native.prepare_plain_committed_storage_append_document_index_transaction_trim(...baseArgs, ...documentIndexArgs, input.trimLengthTo)
|
|
2507
|
+
: this.native.prepare_plain_committed_storage_append_transaction_trim(...baseArgs, input.trimLengthTo);
|
|
2508
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2509
|
+
}
|
|
2510
|
+
preparePlainCommittedStorageAppendDocumentIndexLatestBatchTransaction(input) {
|
|
2511
|
+
if (input.entries.length === 0) {
|
|
2512
|
+
return [];
|
|
2513
|
+
}
|
|
2514
|
+
const useCompact = input.resolveTrimmedEntries === false;
|
|
2515
|
+
const requiredPreviousSignerPublicKeys = input.entries
|
|
2516
|
+
.map((entry) => entry.documentIndex.requiredPreviousSignerPublicKey)
|
|
2517
|
+
.filter((key) => !!key);
|
|
2518
|
+
const requiredPreviousSignerPublicKey = requiredPreviousSignerPublicKeys[0];
|
|
2519
|
+
if (requiredPreviousSignerPublicKeys.length > 0 &&
|
|
2520
|
+
requiredPreviousSignerPublicKeys.length !== input.entries.length) {
|
|
2521
|
+
return undefined;
|
|
2522
|
+
}
|
|
2523
|
+
if (requiredPreviousSignerPublicKey &&
|
|
2524
|
+
requiredPreviousSignerPublicKeys.some((key) => key.byteLength !== requiredPreviousSignerPublicKey.byteLength ||
|
|
2525
|
+
key.some((byte, index) => byte !== requiredPreviousSignerPublicKey[index]))) {
|
|
2526
|
+
return undefined;
|
|
2527
|
+
}
|
|
2528
|
+
const projected = input.entries.every((entry) => entry.documentIndex.projection);
|
|
2529
|
+
if (projected) {
|
|
2530
|
+
const usePlainPutPayload = input.entries.every((entry) => entry.documentIndex.usePlainPutPayload === true);
|
|
2531
|
+
const baseArgs = [
|
|
2532
|
+
new BigUint64Array(input.entries.map((entry) => BigInt(entry.wallTime))),
|
|
2533
|
+
new Uint32Array(input.entries.map((entry) => entry.logical ?? 0)),
|
|
2534
|
+
input.entries.map((entry) => entry.gid),
|
|
2535
|
+
input.type ?? 0,
|
|
2536
|
+
input.entries.map((entry) => entry.metaData),
|
|
2537
|
+
input.entries.map((entry) => entry.payloadData),
|
|
2538
|
+
input.replicas,
|
|
2539
|
+
input.roleAgeMs ?? 0,
|
|
2540
|
+
integerString(input.now ?? Date.now()),
|
|
2541
|
+
input.selfHash ?? "",
|
|
2542
|
+
input.selfReplicating ?? true,
|
|
2543
|
+
];
|
|
2544
|
+
const documentPlanArgs = [
|
|
2545
|
+
input.entries.map((entry) => entry.documentIndex.key),
|
|
2546
|
+
input.documentByteElementIndexLimit ?? 0,
|
|
2547
|
+
input.documentDeleteTrimmedHeads === true,
|
|
2548
|
+
new Uint32Array(input.entries.map((entry) => this.documentProjectionPlanId(entry.documentIndex.projection.plan))),
|
|
2549
|
+
];
|
|
2550
|
+
const documentEncodedDocuments = input.entries.map((entry) => entry.documentIndex.projection.encodedDocument);
|
|
2551
|
+
const documentSigners = input.entries.map((entry) => entry.documentIndex.projection.signer);
|
|
2552
|
+
const nativeCompactCachedBatch = this.native
|
|
2553
|
+
.prepare_plain_committed_storage_append_document_index_latest_cached_plan_compact_batch_transaction;
|
|
2554
|
+
const nativeCompactCachedPlainPayloadBatch = this.native
|
|
2555
|
+
.prepare_plain_committed_storage_append_document_index_latest_cached_plan_compact_plain_put_payload_batch_transaction;
|
|
2556
|
+
if (requiredPreviousSignerPublicKey) {
|
|
2557
|
+
if (useCompact) {
|
|
2558
|
+
const nativeRequiredCompactCachedBatch = this.native
|
|
2559
|
+
.prepare_plain_committed_storage_append_document_index_latest_required_previous_signer_cached_plan_compact_batch_transaction;
|
|
2560
|
+
if (!nativeRequiredCompactCachedBatch) {
|
|
2561
|
+
return undefined;
|
|
2562
|
+
}
|
|
2563
|
+
const rows = nativeRequiredCompactCachedBatch.call(this.native, ...baseArgs, ...documentPlanArgs, documentEncodedDocuments, documentSigners, requiredPreviousSignerPublicKey, input.trimLengthTo);
|
|
2564
|
+
return rows.map((row) => compactCommittedLatestStorageAppendResultFromRow(this.resolution, row));
|
|
2565
|
+
}
|
|
2566
|
+
const nativeRequiredCachedBatch = this.native
|
|
2567
|
+
.prepare_plain_committed_storage_append_document_index_latest_required_previous_signer_cached_plan_batch_transaction;
|
|
2568
|
+
if (!nativeRequiredCachedBatch) {
|
|
2569
|
+
return undefined;
|
|
2570
|
+
}
|
|
2571
|
+
const rows = nativeRequiredCachedBatch.call(this.native, ...baseArgs, input.resolveTrimmedEntries !== false, ...documentPlanArgs, documentEncodedDocuments, documentSigners, requiredPreviousSignerPublicKey, input.trimLengthTo);
|
|
2572
|
+
return rows.map((row) => committedStorageAppendResultFromRow(this.resolution, row));
|
|
2573
|
+
}
|
|
2574
|
+
if (useCompact &&
|
|
2575
|
+
usePlainPutPayload &&
|
|
2576
|
+
nativeCompactCachedPlainPayloadBatch) {
|
|
2577
|
+
const rows = nativeCompactCachedPlainPayloadBatch.call(this.native, ...baseArgs, ...documentPlanArgs, documentSigners, input.trimLengthTo);
|
|
2578
|
+
return rows.map((row) => compactCommittedLatestStorageAppendResultFromRow(this.resolution, row));
|
|
2579
|
+
}
|
|
2580
|
+
if (useCompact && nativeCompactCachedBatch) {
|
|
2581
|
+
const rows = nativeCompactCachedBatch.call(this.native, ...baseArgs, ...documentPlanArgs, documentEncodedDocuments, documentSigners, input.trimLengthTo);
|
|
2582
|
+
return rows.map((row) => compactCommittedLatestStorageAppendResultFromRow(this.resolution, row));
|
|
2583
|
+
}
|
|
2584
|
+
const nativeCachedBatch = this.native
|
|
2585
|
+
.prepare_plain_committed_storage_append_document_index_latest_cached_plan_batch_transaction;
|
|
2586
|
+
if (!nativeCachedBatch) {
|
|
2587
|
+
return undefined;
|
|
2588
|
+
}
|
|
2589
|
+
const rows = nativeCachedBatch.call(this.native, ...baseArgs, input.resolveTrimmedEntries !== false, ...documentPlanArgs, documentEncodedDocuments, documentSigners, input.trimLengthTo);
|
|
2590
|
+
return rows.map((row) => committedStorageAppendResultFromRow(this.resolution, row));
|
|
2591
|
+
}
|
|
2592
|
+
if (input.entries.some((entry) => entry.documentIndex.projection) ||
|
|
2593
|
+
input.entries.some((entry) => !entry.documentIndex.valuePrefixBytes)) {
|
|
2594
|
+
return undefined;
|
|
2595
|
+
}
|
|
2596
|
+
const baseArgs = [
|
|
2597
|
+
new BigUint64Array(input.entries.map((entry) => BigInt(entry.wallTime))),
|
|
2598
|
+
new Uint32Array(input.entries.map((entry) => entry.logical ?? 0)),
|
|
2599
|
+
input.entries.map((entry) => entry.gid),
|
|
2600
|
+
input.type ?? 0,
|
|
2601
|
+
input.entries.map((entry) => entry.metaData),
|
|
2602
|
+
input.entries.map((entry) => entry.payloadData),
|
|
2603
|
+
input.replicas,
|
|
2604
|
+
input.roleAgeMs ?? 0,
|
|
2605
|
+
integerString(input.now ?? Date.now()),
|
|
2606
|
+
input.selfHash ?? "",
|
|
2607
|
+
input.selfReplicating ?? true,
|
|
2608
|
+
];
|
|
2609
|
+
const documentKeys = input.entries.map((entry) => entry.documentIndex.key);
|
|
2610
|
+
const usePlainPutPayload = input.entries.every((entry) => entry.documentIndex.usePlainPutPayload === true);
|
|
2611
|
+
if (!requiredPreviousSignerPublicKey &&
|
|
2612
|
+
useCompact &&
|
|
2613
|
+
usePlainPutPayload) {
|
|
2614
|
+
const nativeCompactPlainPutPayloadBatch = this.native
|
|
2615
|
+
.prepare_plain_committed_storage_append_document_index_latest_compact_plain_put_payload_batch_transaction;
|
|
2616
|
+
if (nativeCompactPlainPutPayloadBatch) {
|
|
2617
|
+
const rows = nativeCompactPlainPutPayloadBatch.call(this.native, ...baseArgs, documentKeys, input.documentByteElementIndexLimit ?? 0, input.documentDeleteTrimmedHeads === true, input.trimLengthTo);
|
|
2618
|
+
return rows.map((row) => compactCommittedLatestStorageAppendResultFromRow(this.resolution, row));
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
const documentValuePrefixBytes = input.entries.map((entry) => entry.documentIndex.valuePrefixBytes);
|
|
2622
|
+
const documentByteElementIndexLimit = input.documentByteElementIndexLimit ?? 0;
|
|
2623
|
+
const documentDeleteTrimmedHeads = input.documentDeleteTrimmedHeads === true;
|
|
2624
|
+
const documentArgs = [
|
|
2625
|
+
documentKeys,
|
|
2626
|
+
documentValuePrefixBytes,
|
|
2627
|
+
documentByteElementIndexLimit,
|
|
2628
|
+
documentDeleteTrimmedHeads,
|
|
2629
|
+
input.trimLengthTo,
|
|
2630
|
+
];
|
|
2631
|
+
if (requiredPreviousSignerPublicKey) {
|
|
2632
|
+
if (useCompact) {
|
|
2633
|
+
const nativeRequiredCompactBatch = this.native
|
|
2634
|
+
.prepare_plain_committed_storage_append_document_index_latest_required_previous_signer_compact_batch_transaction;
|
|
2635
|
+
if (!nativeRequiredCompactBatch) {
|
|
2636
|
+
return undefined;
|
|
2637
|
+
}
|
|
2638
|
+
const rows = nativeRequiredCompactBatch.call(this.native, ...baseArgs, documentKeys, documentValuePrefixBytes, documentByteElementIndexLimit, documentDeleteTrimmedHeads, requiredPreviousSignerPublicKey, input.trimLengthTo);
|
|
2639
|
+
return rows.map((row) => compactCommittedLatestStorageAppendResultFromRow(this.resolution, row));
|
|
2640
|
+
}
|
|
2641
|
+
const nativeRequiredBatch = this.native
|
|
2642
|
+
.prepare_plain_committed_storage_append_document_index_latest_required_previous_signer_batch_transaction;
|
|
2643
|
+
if (!nativeRequiredBatch) {
|
|
2644
|
+
return undefined;
|
|
2645
|
+
}
|
|
2646
|
+
const rows = nativeRequiredBatch.call(this.native, ...baseArgs, input.resolveTrimmedEntries !== false, documentKeys, documentValuePrefixBytes, documentByteElementIndexLimit, documentDeleteTrimmedHeads, requiredPreviousSignerPublicKey, input.trimLengthTo);
|
|
2647
|
+
return rows.map((row) => committedStorageAppendResultFromRow(this.resolution, row));
|
|
2648
|
+
}
|
|
2649
|
+
const nativeCompactBatch = this.native
|
|
2650
|
+
.prepare_plain_committed_storage_append_document_index_latest_compact_batch_transaction;
|
|
2651
|
+
if (useCompact && nativeCompactBatch) {
|
|
2652
|
+
const rows = nativeCompactBatch.call(this.native, ...baseArgs, ...documentArgs);
|
|
2653
|
+
return rows.map((row) => compactCommittedLatestStorageAppendResultFromRow(this.resolution, row));
|
|
2654
|
+
}
|
|
2655
|
+
const nativeBatch = this.native
|
|
2656
|
+
.prepare_plain_committed_storage_append_document_index_latest_batch_transaction;
|
|
2657
|
+
if (!nativeBatch) {
|
|
2658
|
+
return undefined;
|
|
2659
|
+
}
|
|
2660
|
+
const rows = nativeBatch.call(this.native, ...baseArgs, input.resolveTrimmedEntries !== false, ...documentArgs);
|
|
2661
|
+
return rows.map((row) => committedStorageAppendResultFromRow(this.resolution, row));
|
|
2662
|
+
}
|
|
2663
|
+
preparePlainCommittedNoNextStorageAppendTransaction(input) {
|
|
2664
|
+
const baseArgs = nativeNoNextStorageAppendArgs(input);
|
|
2665
|
+
const projection = input.documentIndex?.projection;
|
|
2666
|
+
if (input.documentIndex && projection) {
|
|
2667
|
+
const documentIndexArgs = [
|
|
2668
|
+
input.documentIndex.key,
|
|
2669
|
+
input.documentIndex.existingCreated == null
|
|
2670
|
+
? ""
|
|
2671
|
+
: integerString(input.documentIndex.existingCreated),
|
|
2672
|
+
input.documentIndex.byteElementIndexLimit ?? 0,
|
|
2673
|
+
input.documentIndex.deleteTrimmedHeads === true,
|
|
2674
|
+
this.documentProjectionPlanId(projection.plan),
|
|
2675
|
+
projection.encodedDocument,
|
|
2676
|
+
projection.signer,
|
|
2677
|
+
];
|
|
2678
|
+
const row = input.trimLengthTo == null
|
|
2679
|
+
? this.native.prepare_plain_committed_no_next_storage_append_document_index_cached_plan_transaction(...baseArgs, ...documentIndexArgs)
|
|
2680
|
+
: this.native.prepare_plain_committed_no_next_storage_append_document_index_cached_plan_transaction_trim(...baseArgs, ...documentIndexArgs, input.trimLengthTo);
|
|
2681
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2682
|
+
}
|
|
2683
|
+
const documentIndexArgs = nativeDocumentIndexArgs(input.documentIndex);
|
|
2684
|
+
const row = input.trimLengthTo == null
|
|
2685
|
+
? documentIndexArgs
|
|
2686
|
+
? this.native.prepare_plain_committed_no_next_storage_append_document_index_transaction(...baseArgs, ...documentIndexArgs)
|
|
2687
|
+
: this.native.prepare_plain_committed_no_next_storage_append_transaction(...baseArgs)
|
|
2688
|
+
: documentIndexArgs
|
|
2689
|
+
? this.native.prepare_plain_committed_no_next_storage_append_document_index_transaction_trim(...baseArgs, ...documentIndexArgs, input.trimLengthTo)
|
|
2690
|
+
: this.native.prepare_plain_committed_no_next_storage_append_transaction_trim(...baseArgs, input.trimLengthTo);
|
|
2691
|
+
return committedStorageAppendResultFromRow(this.resolution, row);
|
|
2692
|
+
}
|
|
2693
|
+
preparePlainCommittedNoNextStorageAppendDocumentIndexCompactTransaction(input) {
|
|
2694
|
+
const documentIndex = input.documentIndex;
|
|
2695
|
+
if (!documentIndex) {
|
|
2696
|
+
return this.preparePlainCommittedNoNextStorageAppendTransaction(input);
|
|
2697
|
+
}
|
|
2698
|
+
const projection = documentIndex.projection;
|
|
2699
|
+
if (projection) {
|
|
2700
|
+
const projectionPlanId = this.documentProjectionPlanId(projection.plan);
|
|
2701
|
+
const plainPutPayload = documentIndex.usePlainPutPayload === true
|
|
2702
|
+
? this.native
|
|
2703
|
+
.prepare_plain_committed_no_next_storage_append_document_index_cached_plan_compact_plain_put_payload_transaction
|
|
2704
|
+
: undefined;
|
|
2705
|
+
const row = plainPutPayload
|
|
2706
|
+
? plainPutPayload.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.existingCreated == null
|
|
2707
|
+
? ""
|
|
2708
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.signer, input.trimLengthTo)
|
|
2709
|
+
: this.native.prepare_plain_committed_no_next_storage_append_document_index_cached_plan_compact_transaction(BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.existingCreated == null
|
|
2710
|
+
? ""
|
|
2711
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, projectionPlanId, projection.encodedDocument, projection.signer, input.trimLengthTo);
|
|
2712
|
+
return compactCommittedNoNextStorageAppendResultFromRow(this.resolution, row);
|
|
2713
|
+
}
|
|
2714
|
+
if (documentIndex.usePlainPutPayload === true) {
|
|
2715
|
+
const plainPutPayload = this.native
|
|
2716
|
+
.prepare_plain_committed_no_next_storage_append_document_index_compact_plain_put_payload_transaction;
|
|
2717
|
+
if (plainPutPayload) {
|
|
2718
|
+
const row = plainPutPayload.call(this.native, BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.existingCreated == null
|
|
2719
|
+
? ""
|
|
2720
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, input.trimLengthTo);
|
|
2721
|
+
return compactCommittedNoNextStorageAppendResultFromRow(this.resolution, row);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
const row = this.native.prepare_plain_committed_no_next_storage_append_document_index_compact_transaction(BigInt(input.wallTime), input.logical ?? 0, input.gid, input.type ?? 0, input.metaData, input.payloadData, input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, documentIndex.key, documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY, documentIndex.existingCreated == null
|
|
2725
|
+
? ""
|
|
2726
|
+
: integerString(documentIndex.existingCreated), documentIndex.byteElementIndexLimit ?? 0, documentIndex.deleteTrimmedHeads === true, input.trimLengthTo);
|
|
2727
|
+
return compactCommittedNoNextStorageAppendResultFromRow(this.resolution, row);
|
|
2728
|
+
}
|
|
2729
|
+
preparePlainCommittedNoNextStorageAppendDocumentIndexCompactBatchTransaction(input) {
|
|
2730
|
+
if (input.entries.length === 0) {
|
|
2731
|
+
return [];
|
|
2732
|
+
}
|
|
2733
|
+
const projected = input.entries.every((entry) => entry.documentIndex.projection);
|
|
2734
|
+
if (projected) {
|
|
2735
|
+
const usePlainPutPayload = input.entries.every((entry) => entry.documentIndex.usePlainPutPayload === true);
|
|
2736
|
+
const baseArgs = [
|
|
2737
|
+
new BigUint64Array(input.entries.map((entry) => BigInt(entry.wallTime))),
|
|
2738
|
+
new Uint32Array(input.entries.map((entry) => entry.logical ?? 0)),
|
|
2739
|
+
input.entries.map((entry) => entry.gid),
|
|
2740
|
+
input.type ?? 0,
|
|
2741
|
+
input.entries.map((entry) => entry.metaData),
|
|
2742
|
+
input.entries.map((entry) => entry.payloadData),
|
|
2743
|
+
input.replicas,
|
|
2744
|
+
input.roleAgeMs ?? 0,
|
|
2745
|
+
integerString(input.now ?? Date.now()),
|
|
2746
|
+
input.selfHash ?? "",
|
|
2747
|
+
input.selfReplicating ?? true,
|
|
2748
|
+
input.entries.map((entry) => entry.documentIndex.key),
|
|
2749
|
+
input.entries.map((entry) => entry.documentIndex.existingCreated == null
|
|
2750
|
+
? ""
|
|
2751
|
+
: integerString(entry.documentIndex.existingCreated)),
|
|
2752
|
+
input.documentByteElementIndexLimit ?? 0,
|
|
2753
|
+
input.documentDeleteTrimmedHeads === true,
|
|
2754
|
+
new Uint32Array(input.entries.map((entry) => this.documentProjectionPlanId(entry.documentIndex.projection.plan))),
|
|
2755
|
+
];
|
|
2756
|
+
const rows = usePlainPutPayload
|
|
2757
|
+
? this.native
|
|
2758
|
+
.prepare_plain_committed_no_next_storage_append_document_index_cached_plan_compact_plain_put_payload_batch_transaction?.call(this.native, ...baseArgs, input.entries.map((entry) => entry.documentIndex.projection.signer), input.trimLengthTo)
|
|
2759
|
+
: this.native
|
|
2760
|
+
.prepare_plain_committed_no_next_storage_append_document_index_cached_plan_compact_batch_transaction?.call(this.native, ...baseArgs, input.entries.map((entry) => entry.documentIndex.projection
|
|
2761
|
+
.encodedDocument), input.entries.map((entry) => entry.documentIndex.projection.signer), input.trimLengthTo);
|
|
2762
|
+
if (!rows) {
|
|
2763
|
+
return undefined;
|
|
2764
|
+
}
|
|
2765
|
+
return rows.map((row) => compactCommittedNoNextStorageAppendResultFromRow(this.resolution, row));
|
|
2766
|
+
}
|
|
2767
|
+
if (input.entries.some((entry) => entry.documentIndex.projection) ||
|
|
2768
|
+
input.entries.some((entry) => !entry.documentIndex.valuePrefixBytes)) {
|
|
2769
|
+
return undefined;
|
|
2770
|
+
}
|
|
2771
|
+
const usePlainPutPayload = input.entries.every((entry) => entry.documentIndex.usePlainPutPayload === true);
|
|
2772
|
+
if (usePlainPutPayload) {
|
|
2773
|
+
const nativeBatch = this.native
|
|
2774
|
+
.prepare_plain_committed_no_next_storage_append_document_index_compact_plain_put_payload_batch_transaction;
|
|
2775
|
+
if (nativeBatch) {
|
|
2776
|
+
const rows = nativeBatch.call(this.native, new BigUint64Array(input.entries.map((entry) => BigInt(entry.wallTime))), new Uint32Array(input.entries.map((entry) => entry.logical ?? 0)), input.entries.map((entry) => entry.gid), input.type ?? 0, input.entries.map((entry) => entry.metaData), input.entries.map((entry) => entry.payloadData), input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, input.entries.map((entry) => entry.documentIndex.key), input.entries.map((entry) => entry.documentIndex.existingCreated == null
|
|
2777
|
+
? ""
|
|
2778
|
+
: integerString(entry.documentIndex.existingCreated)), input.documentByteElementIndexLimit ?? 0, input.documentDeleteTrimmedHeads === true, input.trimLengthTo);
|
|
2779
|
+
return rows.map((row) => compactCommittedNoNextStorageAppendResultFromRow(this.resolution, row));
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
const nativeBatch = this.native
|
|
2783
|
+
.prepare_plain_committed_no_next_storage_append_document_index_compact_batch_transaction;
|
|
2784
|
+
if (!nativeBatch) {
|
|
2785
|
+
return undefined;
|
|
2786
|
+
}
|
|
2787
|
+
const rows = nativeBatch.call(this.native, new BigUint64Array(input.entries.map((entry) => BigInt(entry.wallTime))), new Uint32Array(input.entries.map((entry) => entry.logical ?? 0)), input.entries.map((entry) => entry.gid), input.type ?? 0, input.entries.map((entry) => entry.metaData), input.entries.map((entry) => entry.payloadData), input.replicas, input.roleAgeMs ?? 0, integerString(input.now ?? Date.now()), input.selfHash ?? "", input.selfReplicating ?? true, input.entries.map((entry) => entry.documentIndex.key), input.entries.map((entry) => entry.documentIndex.valuePrefixBytes ?? EMPTY_UINT8_ARRAY), input.entries.map((entry) => entry.documentIndex.existingCreated == null
|
|
2788
|
+
? ""
|
|
2789
|
+
: integerString(entry.documentIndex.existingCreated)), input.documentByteElementIndexLimit ?? 0, input.documentDeleteTrimmedHeads === true, input.trimLengthTo);
|
|
2790
|
+
return rows.map((row) => compactCommittedNoNextStorageAppendResultFromRow(this.resolution, row));
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
export class NativeBackboneMemoryCoordinatePersistenceStore {
|
|
2794
|
+
files = new Map();
|
|
2795
|
+
async read(name) {
|
|
2796
|
+
const file = this.files.get(validateCoordinatePersistenceName(name));
|
|
2797
|
+
return file ? copyBytes(file) : undefined;
|
|
2798
|
+
}
|
|
2799
|
+
async write(name, bytes) {
|
|
2800
|
+
this.files.set(validateCoordinatePersistenceName(name), copyBytes(bytes));
|
|
2801
|
+
}
|
|
2802
|
+
async append(name, bytes) {
|
|
2803
|
+
const validName = validateCoordinatePersistenceName(name);
|
|
2804
|
+
const existing = this.files.get(validName);
|
|
2805
|
+
this.files.set(validName, existing ? concatBytes([existing, bytes]) : copyBytes(bytes));
|
|
2806
|
+
}
|
|
2807
|
+
async remove(name) {
|
|
2808
|
+
this.files.delete(validateCoordinatePersistenceName(name));
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
export class NativeBackboneNodeCoordinatePersistenceStore {
|
|
2812
|
+
directory;
|
|
2813
|
+
fs;
|
|
2814
|
+
appendHandles = new Map();
|
|
2815
|
+
filePaths = new Map();
|
|
2816
|
+
directoryEnsured = false;
|
|
2817
|
+
constructor(directory, fs) {
|
|
2818
|
+
this.directory = directory;
|
|
2819
|
+
this.fs = fs;
|
|
2820
|
+
}
|
|
2821
|
+
async nodeFs() {
|
|
2822
|
+
return this.fs ?? (await importNodeFs());
|
|
2823
|
+
}
|
|
2824
|
+
async filePath(name) {
|
|
2825
|
+
const validName = validateCoordinatePersistenceName(name);
|
|
2826
|
+
let path = this.filePaths.get(validName);
|
|
2827
|
+
if (path === undefined) {
|
|
2828
|
+
path = (await importNodePathJoin())(this.directory, validName);
|
|
2829
|
+
this.filePaths.set(validName, path);
|
|
2830
|
+
}
|
|
2831
|
+
return path;
|
|
2832
|
+
}
|
|
2833
|
+
async ensureDirectory() {
|
|
2834
|
+
const fs = await this.nodeFs();
|
|
2835
|
+
if (!this.directoryEnsured) {
|
|
2836
|
+
await fs.mkdir(this.directory, { recursive: true });
|
|
2837
|
+
this.directoryEnsured = true;
|
|
2838
|
+
}
|
|
2839
|
+
return fs;
|
|
2840
|
+
}
|
|
2841
|
+
async closeAppendHandle(path) {
|
|
2842
|
+
const handle = this.appendHandles.get(path);
|
|
2843
|
+
if (!handle) {
|
|
2844
|
+
return;
|
|
2845
|
+
}
|
|
2846
|
+
this.appendHandles.delete(path);
|
|
2847
|
+
await (await handle).close();
|
|
2848
|
+
}
|
|
2849
|
+
async appendHandle(fs, path) {
|
|
2850
|
+
if (!fs.open) {
|
|
2851
|
+
return undefined;
|
|
2852
|
+
}
|
|
2853
|
+
let handle = this.appendHandles.get(path);
|
|
2854
|
+
if (!handle) {
|
|
2855
|
+
handle = fs.open(path, "a");
|
|
2856
|
+
this.appendHandles.set(path, handle);
|
|
2857
|
+
}
|
|
2858
|
+
return handle;
|
|
2859
|
+
}
|
|
2860
|
+
async read(name) {
|
|
2861
|
+
const fs = await this.nodeFs();
|
|
2862
|
+
try {
|
|
2863
|
+
return await fs.readFile(await this.filePath(name));
|
|
2864
|
+
}
|
|
2865
|
+
catch (error) {
|
|
2866
|
+
if (isNotFoundError(error)) {
|
|
2867
|
+
return undefined;
|
|
2868
|
+
}
|
|
2869
|
+
throw error;
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
async write(name, bytes) {
|
|
2873
|
+
const fs = await this.ensureDirectory();
|
|
2874
|
+
const path = await this.filePath(name);
|
|
2875
|
+
await this.closeAppendHandle(path);
|
|
2876
|
+
await fs.writeFile(path, bytes);
|
|
2877
|
+
}
|
|
2878
|
+
async append(name, bytes) {
|
|
2879
|
+
const fs = await this.ensureDirectory();
|
|
2880
|
+
const path = await this.filePath(name);
|
|
2881
|
+
const handle = await this.appendHandle(fs, path);
|
|
2882
|
+
if (handle) {
|
|
2883
|
+
await handle.write(bytes);
|
|
2884
|
+
return;
|
|
2885
|
+
}
|
|
2886
|
+
await fs.appendFile(path, bytes);
|
|
2887
|
+
}
|
|
2888
|
+
async remove(name) {
|
|
2889
|
+
const fs = await this.nodeFs();
|
|
2890
|
+
const path = await this.filePath(name);
|
|
2891
|
+
await this.closeAppendHandle(path);
|
|
2892
|
+
try {
|
|
2893
|
+
await fs.rm(path, { force: true });
|
|
2894
|
+
}
|
|
2895
|
+
catch (error) {
|
|
2896
|
+
if (!isNotFoundError(error)) {
|
|
2897
|
+
throw error;
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
async close() {
|
|
2902
|
+
this.directoryEnsured = false;
|
|
2903
|
+
const handles = [...this.appendHandles.values()];
|
|
2904
|
+
this.appendHandles.clear();
|
|
2905
|
+
await Promise.all(handles.map(async (handle) => (await handle).close()));
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
export class NativeBackboneOPFSCoordinatePersistenceStore {
|
|
2909
|
+
directory;
|
|
2910
|
+
constructor(directory) {
|
|
2911
|
+
this.directory = directory;
|
|
2912
|
+
}
|
|
2913
|
+
static async create(options) {
|
|
2914
|
+
const root = options?.root ?? (await this.defaultRoot());
|
|
2915
|
+
let directory = root;
|
|
2916
|
+
for (const part of this.directoryParts(options?.directory)) {
|
|
2917
|
+
directory = await directory.getDirectoryHandle(part, { create: true });
|
|
2918
|
+
}
|
|
2919
|
+
return new NativeBackboneOPFSCoordinatePersistenceStore(directory);
|
|
2920
|
+
}
|
|
2921
|
+
static async defaultRoot() {
|
|
2922
|
+
const storage = globalThis.navigator?.storage;
|
|
2923
|
+
const root = await storage?.getDirectory?.();
|
|
2924
|
+
if (!root) {
|
|
2925
|
+
throw new Error("OPFS getDirectory is not available in this runtime");
|
|
2926
|
+
}
|
|
2927
|
+
return root;
|
|
2928
|
+
}
|
|
2929
|
+
static directoryParts(directory) {
|
|
2930
|
+
if (!directory) {
|
|
2931
|
+
return [];
|
|
2932
|
+
}
|
|
2933
|
+
const parts = Array.isArray(directory)
|
|
2934
|
+
? directory
|
|
2935
|
+
: directory.split("/").filter(Boolean);
|
|
2936
|
+
return parts.map(validateCoordinatePersistenceName);
|
|
2937
|
+
}
|
|
2938
|
+
async read(name) {
|
|
2939
|
+
try {
|
|
2940
|
+
const handle = await this.directory.getFileHandle(validateCoordinatePersistenceName(name), { create: false });
|
|
2941
|
+
const file = await handle.getFile();
|
|
2942
|
+
return new Uint8Array(await file.arrayBuffer());
|
|
2943
|
+
}
|
|
2944
|
+
catch (error) {
|
|
2945
|
+
if (isNotFoundError(error)) {
|
|
2946
|
+
return undefined;
|
|
2947
|
+
}
|
|
2948
|
+
throw error;
|
|
2949
|
+
}
|
|
2950
|
+
}
|
|
2951
|
+
async write(name, bytes) {
|
|
2952
|
+
const handle = await this.directory.getFileHandle(validateCoordinatePersistenceName(name), { create: true });
|
|
2953
|
+
const writable = await handle.createWritable();
|
|
2954
|
+
try {
|
|
2955
|
+
await writable.write(bytes);
|
|
2956
|
+
}
|
|
2957
|
+
finally {
|
|
2958
|
+
await writable.close();
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
async append(name, bytes) {
|
|
2962
|
+
const handle = await this.directory.getFileHandle(validateCoordinatePersistenceName(name), { create: true });
|
|
2963
|
+
if (handle.createSyncAccessHandle) {
|
|
2964
|
+
let access;
|
|
2965
|
+
try {
|
|
2966
|
+
access = await handle.createSyncAccessHandle();
|
|
2967
|
+
}
|
|
2968
|
+
catch {
|
|
2969
|
+
// Main-thread OPFS and some browser contexts do not expose sync handles.
|
|
2970
|
+
}
|
|
2971
|
+
if (access) {
|
|
2972
|
+
try {
|
|
2973
|
+
access.write(bytes, { at: access.getSize() });
|
|
2974
|
+
access.flush?.();
|
|
2975
|
+
return;
|
|
2976
|
+
}
|
|
2977
|
+
finally {
|
|
2978
|
+
access.close();
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
const file = await handle.getFile();
|
|
2983
|
+
const writable = await handle.createWritable({ keepExistingData: true });
|
|
2984
|
+
try {
|
|
2985
|
+
await writable.seek(file.size);
|
|
2986
|
+
await writable.write(bytes);
|
|
2987
|
+
}
|
|
2988
|
+
finally {
|
|
2989
|
+
await writable.close();
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
async remove(name) {
|
|
2993
|
+
try {
|
|
2994
|
+
await this.directory.removeEntry(validateCoordinatePersistenceName(name));
|
|
2995
|
+
}
|
|
2996
|
+
catch (error) {
|
|
2997
|
+
if (!isNotFoundError(error)) {
|
|
2998
|
+
throw error;
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
}
|
|
3003
|
+
export class NativeBackboneBufferedCoordinatePersistenceStore {
|
|
3004
|
+
inner;
|
|
3005
|
+
options;
|
|
3006
|
+
buffers = new Map();
|
|
3007
|
+
bufferedBytes = 0;
|
|
3008
|
+
constructor(inner, options = {}) {
|
|
3009
|
+
this.inner = inner;
|
|
3010
|
+
this.options = options;
|
|
3011
|
+
}
|
|
3012
|
+
buffer(name) {
|
|
3013
|
+
const validName = validateCoordinatePersistenceName(name);
|
|
3014
|
+
let buffer = this.buffers.get(validName);
|
|
3015
|
+
if (!buffer) {
|
|
3016
|
+
buffer = [];
|
|
3017
|
+
this.buffers.set(validName, buffer);
|
|
3018
|
+
}
|
|
3019
|
+
return buffer;
|
|
3020
|
+
}
|
|
3021
|
+
async read(name) {
|
|
3022
|
+
await this.flush(name);
|
|
3023
|
+
return this.inner.read(name);
|
|
3024
|
+
}
|
|
3025
|
+
async write(name, bytes) {
|
|
3026
|
+
await this.flush(name);
|
|
3027
|
+
await this.inner.write(name, bytes);
|
|
3028
|
+
}
|
|
3029
|
+
async append(name, bytes) {
|
|
3030
|
+
// Ownership of `bytes` is handed over by the persistence store
|
|
3031
|
+
// contract, so the chunk is buffered without a defensive copy.
|
|
3032
|
+
this.buffer(name).push(bytes);
|
|
3033
|
+
this.bufferedBytes += bytes.byteLength;
|
|
3034
|
+
if (this.options.maxBufferedBytes != null &&
|
|
3035
|
+
this.bufferedBytes >= this.options.maxBufferedBytes) {
|
|
3036
|
+
await this.flush();
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
async remove(name) {
|
|
3040
|
+
// Chunks buffered for a file that is being removed would be deleted
|
|
3041
|
+
// right after being written; discard them instead of flushing.
|
|
3042
|
+
const validName = validateCoordinatePersistenceName(name);
|
|
3043
|
+
const chunks = this.buffers.get(validName);
|
|
3044
|
+
if (chunks) {
|
|
3045
|
+
this.buffers.delete(validName);
|
|
3046
|
+
for (const chunk of chunks) {
|
|
3047
|
+
this.bufferedBytes -= chunk.byteLength;
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
await this.inner.remove?.(name);
|
|
3051
|
+
}
|
|
3052
|
+
async flush(name) {
|
|
3053
|
+
const names = name
|
|
3054
|
+
? [validateCoordinatePersistenceName(name)]
|
|
3055
|
+
: [...this.buffers.keys()];
|
|
3056
|
+
for (const fileName of names) {
|
|
3057
|
+
const chunks = this.buffers.get(fileName);
|
|
3058
|
+
if (!chunks || chunks.length === 0) {
|
|
3059
|
+
continue;
|
|
3060
|
+
}
|
|
3061
|
+
this.buffers.delete(fileName);
|
|
3062
|
+
const bytes = chunks.length === 1 ? chunks[0] : concatBytes(chunks);
|
|
3063
|
+
this.bufferedBytes -= bytes.byteLength;
|
|
3064
|
+
await this.inner.append(fileName, bytes);
|
|
3065
|
+
}
|
|
3066
|
+
await this.inner.flush?.();
|
|
3067
|
+
}
|
|
3068
|
+
async close() {
|
|
3069
|
+
await this.flush();
|
|
3070
|
+
await this.inner.close?.();
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
export class NativeBackboneCoordinatePersistence {
|
|
3074
|
+
store;
|
|
3075
|
+
flushOnAppend;
|
|
3076
|
+
flushMaxPendingBytes;
|
|
3077
|
+
flushIntervalMs;
|
|
3078
|
+
compactMaxJournalBytes;
|
|
3079
|
+
compactMaxJournalRecords;
|
|
3080
|
+
snapshotFile;
|
|
3081
|
+
journalFile;
|
|
3082
|
+
documentSnapshotFile;
|
|
3083
|
+
documentJournalFile;
|
|
3084
|
+
documentSignerSnapshotFile;
|
|
3085
|
+
documentSignerJournalFile;
|
|
3086
|
+
journalInitialized;
|
|
3087
|
+
journalByteLength = 0;
|
|
3088
|
+
journalRecordCount = 0;
|
|
3089
|
+
documentJournalInitialized;
|
|
3090
|
+
documentJournalByteLength = 0;
|
|
3091
|
+
documentJournalRecordCount = 0;
|
|
3092
|
+
documentSignerJournalInitialized;
|
|
3093
|
+
documentSignerJournalByteLength = 0;
|
|
3094
|
+
documentSignerJournalRecordCount = 0;
|
|
3095
|
+
lastFlushMs = Date.now();
|
|
3096
|
+
persistenceQueue;
|
|
3097
|
+
constructor(store, options = {}) {
|
|
3098
|
+
this.store = store;
|
|
3099
|
+
this.snapshotFile =
|
|
3100
|
+
options.snapshot ?? nativeBackboneCoordinatePersistenceFiles.snapshot;
|
|
3101
|
+
this.journalFile =
|
|
3102
|
+
options.journal ?? nativeBackboneCoordinatePersistenceFiles.journal;
|
|
3103
|
+
this.documentSnapshotFile =
|
|
3104
|
+
options.documentSnapshot ??
|
|
3105
|
+
nativeBackboneCoordinatePersistenceFiles.documentSnapshot;
|
|
3106
|
+
this.documentJournalFile =
|
|
3107
|
+
options.documentJournal ??
|
|
3108
|
+
nativeBackboneCoordinatePersistenceFiles.documentJournal;
|
|
3109
|
+
this.documentSignerSnapshotFile =
|
|
3110
|
+
options.documentSignerSnapshot ??
|
|
3111
|
+
nativeBackboneCoordinatePersistenceFiles.documentSignerSnapshot;
|
|
3112
|
+
this.documentSignerJournalFile =
|
|
3113
|
+
options.documentSignerJournal ??
|
|
3114
|
+
nativeBackboneCoordinatePersistenceFiles.documentSignerJournal;
|
|
3115
|
+
this.flushOnAppend = options.flushOnAppend ?? true;
|
|
3116
|
+
this.flushMaxPendingBytes = resolveCoordinateFlushMaxPendingBytes(options);
|
|
3117
|
+
if (options.flushIntervalMs != null) {
|
|
3118
|
+
this.flushIntervalMs = Math.max(0, options.flushIntervalMs);
|
|
3119
|
+
}
|
|
3120
|
+
if (options.compactMaxJournalBytes != null) {
|
|
3121
|
+
this.compactMaxJournalBytes = Math.max(0, options.compactMaxJournalBytes);
|
|
3122
|
+
}
|
|
3123
|
+
if (options.compactMaxJournalRecords != null) {
|
|
3124
|
+
this.compactMaxJournalRecords = Math.max(0, options.compactMaxJournalRecords);
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
async hydrate(backbone) {
|
|
3128
|
+
const [snapshot, journal, documentSnapshot, documentJournal, documentSignerSnapshot, documentSignerJournal,] = await Promise.all([
|
|
3129
|
+
this.store.read(this.snapshotFile),
|
|
3130
|
+
this.store.read(this.journalFile),
|
|
3131
|
+
this.store.read(this.documentSnapshotFile),
|
|
3132
|
+
this.store.read(this.documentJournalFile),
|
|
3133
|
+
this.store.read(this.documentSignerSnapshotFile),
|
|
3134
|
+
this.store.read(this.documentSignerJournalFile),
|
|
3135
|
+
]);
|
|
3136
|
+
const operations = backbone.loadCoordinateSnapshotAndJournal(snapshot, journal);
|
|
3137
|
+
const documentOperations = backbone.loadDocumentSnapshotAndJournal(documentSnapshot, documentJournal);
|
|
3138
|
+
const documentSignerOperations = backbone.loadDocumentSignerSnapshotAndJournal(documentSignerSnapshot, documentSignerJournal);
|
|
3139
|
+
this.journalInitialized = !!journal && journal.byteLength > 0;
|
|
3140
|
+
this.journalByteLength = journal?.byteLength ?? 0;
|
|
3141
|
+
this.journalRecordCount = operations;
|
|
3142
|
+
this.documentJournalInitialized =
|
|
3143
|
+
!!documentJournal && documentJournal.byteLength > 0;
|
|
3144
|
+
this.documentJournalByteLength = documentJournal?.byteLength ?? 0;
|
|
3145
|
+
this.documentJournalRecordCount = documentOperations;
|
|
3146
|
+
this.documentSignerJournalInitialized =
|
|
3147
|
+
!!documentSignerJournal && documentSignerJournal.byteLength > 0;
|
|
3148
|
+
this.documentSignerJournalByteLength =
|
|
3149
|
+
documentSignerJournal?.byteLength ?? 0;
|
|
3150
|
+
this.documentSignerJournalRecordCount = documentSignerOperations;
|
|
3151
|
+
backbone.setCoordinateJournalEnabled(true);
|
|
3152
|
+
backbone.setDocumentJournalEnabled(true);
|
|
3153
|
+
backbone.setDocumentSignerJournalEnabled(true);
|
|
3154
|
+
this.lastFlushMs = Date.now();
|
|
3155
|
+
return operations + documentOperations + documentSignerOperations;
|
|
3156
|
+
}
|
|
3157
|
+
shouldFlushJournalOnAppend(backbone, now = Date.now()) {
|
|
3158
|
+
if (this.flushOnAppend !== false) {
|
|
3159
|
+
return true;
|
|
3160
|
+
}
|
|
3161
|
+
const pendingLength = backbone.coordinatePendingJournalLength +
|
|
3162
|
+
backbone.documentPendingJournalLength +
|
|
3163
|
+
backbone.documentSignerPendingJournalLength;
|
|
3164
|
+
if (pendingLength === 0) {
|
|
3165
|
+
return false;
|
|
3166
|
+
}
|
|
3167
|
+
if (this.flushMaxPendingBytes != null &&
|
|
3168
|
+
backbone.coordinatePendingJournalByteLength +
|
|
3169
|
+
backbone.documentPendingJournalByteLength +
|
|
3170
|
+
backbone.documentSignerPendingJournalByteLength >=
|
|
3171
|
+
this.flushMaxPendingBytes) {
|
|
3172
|
+
return true;
|
|
3173
|
+
}
|
|
3174
|
+
return (this.flushIntervalMs != null &&
|
|
3175
|
+
now - this.lastFlushMs >= this.flushIntervalMs);
|
|
3176
|
+
}
|
|
3177
|
+
flushJournalOnAppend(backbone) {
|
|
3178
|
+
if (!this.shouldFlushJournalOnAppend(backbone)) {
|
|
3179
|
+
return 0;
|
|
3180
|
+
}
|
|
3181
|
+
return this.flushJournal(backbone);
|
|
3182
|
+
}
|
|
3183
|
+
flushJournal(backbone) {
|
|
3184
|
+
// Serialized with compact() so a flush never clears records appended to
|
|
3185
|
+
// the wasm journal while a previous flush was awaiting its disk write.
|
|
3186
|
+
return this.enqueuePersistence(() => this.flushJournalInternal(backbone));
|
|
3187
|
+
}
|
|
3188
|
+
enqueuePersistence(fn) {
|
|
3189
|
+
// Runs `fn` immediately when no other persistence operation is in
|
|
3190
|
+
// flight so the common uncontended flush starts synchronously; queued
|
|
3191
|
+
// operations still run strictly one at a time, in order.
|
|
3192
|
+
const next = this.persistenceQueue
|
|
3193
|
+
? this.persistenceQueue.then(fn)
|
|
3194
|
+
: fn();
|
|
3195
|
+
const tail = next.then(() => undefined, () => undefined);
|
|
3196
|
+
this.persistenceQueue = tail;
|
|
3197
|
+
void tail.then(() => {
|
|
3198
|
+
if (this.persistenceQueue === tail) {
|
|
3199
|
+
this.persistenceQueue = undefined;
|
|
3200
|
+
}
|
|
3201
|
+
});
|
|
3202
|
+
return next;
|
|
3203
|
+
}
|
|
3204
|
+
async flushJournalInternal(backbone) {
|
|
3205
|
+
let written = 0;
|
|
3206
|
+
const coordinateRecords = backbone.coordinateJournal();
|
|
3207
|
+
const coordinateRecordCount = backbone.coordinatePendingJournalLength;
|
|
3208
|
+
if (coordinateRecords.byteLength > 0) {
|
|
3209
|
+
if (this.journalInitialized === undefined) {
|
|
3210
|
+
const existing = await this.store.read(this.journalFile);
|
|
3211
|
+
this.journalInitialized = !!existing && existing.byteLength > 0;
|
|
3212
|
+
}
|
|
3213
|
+
const bytes = this.journalInitialized
|
|
3214
|
+
? coordinateRecords
|
|
3215
|
+
: concatBytes([backbone.coordinateJournalHeader(), coordinateRecords]);
|
|
3216
|
+
await this.store.append(this.journalFile, bytes);
|
|
3217
|
+
this.journalInitialized = true;
|
|
3218
|
+
this.journalByteLength += bytes.byteLength;
|
|
3219
|
+
this.journalRecordCount += coordinateRecordCount;
|
|
3220
|
+
backbone.clearCoordinateJournalPrefix(coordinateRecords.byteLength, coordinateRecordCount);
|
|
3221
|
+
written += coordinateRecords.byteLength;
|
|
3222
|
+
}
|
|
3223
|
+
const documentRecords = backbone.documentJournal();
|
|
3224
|
+
const documentRecordCount = backbone.documentPendingJournalLength;
|
|
3225
|
+
if (documentRecords.byteLength > 0) {
|
|
3226
|
+
if (this.documentJournalInitialized === undefined) {
|
|
3227
|
+
const existing = await this.store.read(this.documentJournalFile);
|
|
3228
|
+
this.documentJournalInitialized = !!existing && existing.byteLength > 0;
|
|
3229
|
+
}
|
|
3230
|
+
const bytes = this.documentJournalInitialized
|
|
3231
|
+
? documentRecords
|
|
3232
|
+
: concatBytes([backbone.documentJournalHeader(), documentRecords]);
|
|
3233
|
+
await this.store.append(this.documentJournalFile, bytes);
|
|
3234
|
+
this.documentJournalInitialized = true;
|
|
3235
|
+
this.documentJournalByteLength += bytes.byteLength;
|
|
3236
|
+
this.documentJournalRecordCount += documentRecordCount;
|
|
3237
|
+
backbone.clearDocumentJournalPrefix(documentRecords.byteLength, documentRecordCount);
|
|
3238
|
+
written += documentRecords.byteLength;
|
|
3239
|
+
}
|
|
3240
|
+
const signerRecords = backbone.documentSignerJournal();
|
|
3241
|
+
const signerRecordCount = backbone.documentSignerPendingJournalLength;
|
|
3242
|
+
if (signerRecords.byteLength > 0) {
|
|
3243
|
+
if (this.documentSignerJournalInitialized === undefined) {
|
|
3244
|
+
const existing = await this.store.read(this.documentSignerJournalFile);
|
|
3245
|
+
this.documentSignerJournalInitialized =
|
|
3246
|
+
!!existing && existing.byteLength > 0;
|
|
3247
|
+
}
|
|
3248
|
+
const bytes = this.documentSignerJournalInitialized
|
|
3249
|
+
? signerRecords
|
|
3250
|
+
: concatBytes([backbone.documentSignerJournalHeader(), signerRecords]);
|
|
3251
|
+
await this.store.append(this.documentSignerJournalFile, bytes);
|
|
3252
|
+
this.documentSignerJournalInitialized = true;
|
|
3253
|
+
this.documentSignerJournalByteLength += bytes.byteLength;
|
|
3254
|
+
this.documentSignerJournalRecordCount += signerRecordCount;
|
|
3255
|
+
backbone.clearDocumentSignerJournalPrefix(signerRecords.byteLength, signerRecordCount);
|
|
3256
|
+
written += signerRecords.byteLength;
|
|
3257
|
+
}
|
|
3258
|
+
if (written === 0) {
|
|
3259
|
+
this.lastFlushMs = Date.now();
|
|
3260
|
+
return 0;
|
|
3261
|
+
}
|
|
3262
|
+
this.lastFlushMs = Date.now();
|
|
3263
|
+
if (this.shouldCompactJournal()) {
|
|
3264
|
+
await this.compactInternal(backbone);
|
|
3265
|
+
}
|
|
3266
|
+
return written;
|
|
3267
|
+
}
|
|
3268
|
+
shouldCompactJournal() {
|
|
3269
|
+
return ((this.compactMaxJournalBytes != null &&
|
|
3270
|
+
this.journalByteLength +
|
|
3271
|
+
this.documentJournalByteLength +
|
|
3272
|
+
this.documentSignerJournalByteLength >=
|
|
3273
|
+
this.compactMaxJournalBytes) ||
|
|
3274
|
+
(this.compactMaxJournalRecords != null &&
|
|
3275
|
+
this.journalRecordCount +
|
|
3276
|
+
this.documentJournalRecordCount +
|
|
3277
|
+
this.documentSignerJournalRecordCount >=
|
|
3278
|
+
this.compactMaxJournalRecords));
|
|
3279
|
+
}
|
|
3280
|
+
compact(backbone) {
|
|
3281
|
+
return this.enqueuePersistence(() => this.compactInternal(backbone));
|
|
3282
|
+
}
|
|
3283
|
+
async compactInternal(backbone) {
|
|
3284
|
+
// The snapshots below cover exactly the journal records pending right
|
|
3285
|
+
// now; records appended during the awaited writes must survive the
|
|
3286
|
+
// clears at the end, so only this prefix is dropped.
|
|
3287
|
+
const coordinateJournalByteLength = backbone.coordinatePendingJournalByteLength;
|
|
3288
|
+
const coordinateJournalRecordCount = backbone.coordinatePendingJournalLength;
|
|
3289
|
+
const documentJournalByteLength = backbone.documentPendingJournalByteLength;
|
|
3290
|
+
const documentJournalRecordCount = backbone.documentPendingJournalLength;
|
|
3291
|
+
const documentSignerJournalByteLength = backbone.documentSignerPendingJournalByteLength;
|
|
3292
|
+
const documentSignerJournalRecordCount = backbone.documentSignerPendingJournalLength;
|
|
3293
|
+
await Promise.all([
|
|
3294
|
+
this.store.write(this.snapshotFile, backbone.coordinateSnapshot()),
|
|
3295
|
+
this.store.write(this.documentSnapshotFile, backbone.documentSnapshot()),
|
|
3296
|
+
this.store.write(this.documentSignerSnapshotFile, backbone.documentSignerSnapshot()),
|
|
3297
|
+
]);
|
|
3298
|
+
await Promise.all([
|
|
3299
|
+
this.store.remove?.(this.journalFile),
|
|
3300
|
+
this.store.remove?.(this.documentJournalFile),
|
|
3301
|
+
this.store.remove?.(this.documentSignerJournalFile),
|
|
3302
|
+
]);
|
|
3303
|
+
this.journalInitialized = false;
|
|
3304
|
+
this.journalByteLength = 0;
|
|
3305
|
+
this.journalRecordCount = 0;
|
|
3306
|
+
this.documentJournalInitialized = false;
|
|
3307
|
+
this.documentJournalByteLength = 0;
|
|
3308
|
+
this.documentJournalRecordCount = 0;
|
|
3309
|
+
this.documentSignerJournalInitialized = false;
|
|
3310
|
+
this.documentSignerJournalByteLength = 0;
|
|
3311
|
+
this.documentSignerJournalRecordCount = 0;
|
|
3312
|
+
backbone.clearCoordinateJournalPrefix(coordinateJournalByteLength, coordinateJournalRecordCount);
|
|
3313
|
+
backbone.clearDocumentJournalPrefix(documentJournalByteLength, documentJournalRecordCount);
|
|
3314
|
+
backbone.clearDocumentSignerJournalPrefix(documentSignerJournalByteLength, documentSignerJournalRecordCount);
|
|
3315
|
+
// Compact persists the full pending state, so it restarts the
|
|
3316
|
+
// flushIntervalMs pacing window like a flush does.
|
|
3317
|
+
this.lastFlushMs = Date.now();
|
|
3318
|
+
}
|
|
3319
|
+
async close() {
|
|
3320
|
+
await this.store.flush?.();
|
|
3321
|
+
await this.store.close?.();
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
const resolveNodeWriteBufferMaxBytes = (options) => options.writeBufferMaxBytes != null
|
|
3325
|
+
? Math.max(0, options.writeBufferMaxBytes)
|
|
3326
|
+
: options.flushOnAppend === false
|
|
3327
|
+
? resolveCoordinateFlushMaxPendingBytes(options)
|
|
3328
|
+
: undefined;
|
|
3329
|
+
export class NativeBackboneNodeCoordinatePersistence extends NativeBackboneCoordinatePersistence {
|
|
3330
|
+
writeBuffer;
|
|
3331
|
+
constructor(directory, options = {}) {
|
|
3332
|
+
const writeBufferMaxBytes = resolveNodeWriteBufferMaxBytes(options);
|
|
3333
|
+
const nodeStore = new NativeBackboneNodeCoordinatePersistenceStore(directory, options.fs);
|
|
3334
|
+
const writeBuffer = writeBufferMaxBytes != null
|
|
3335
|
+
? new NativeBackboneBufferedCoordinatePersistenceStore(nodeStore, {
|
|
3336
|
+
maxBufferedBytes: writeBufferMaxBytes,
|
|
3337
|
+
})
|
|
3338
|
+
: undefined;
|
|
3339
|
+
super(writeBuffer ?? nodeStore, options);
|
|
3340
|
+
this.writeBuffer = writeBuffer;
|
|
3341
|
+
}
|
|
3342
|
+
async flushJournalWriteBuffer(fileName) {
|
|
3343
|
+
if (fileName) {
|
|
3344
|
+
validateCoordinatePersistenceName(fileName);
|
|
3345
|
+
}
|
|
3346
|
+
await this.writeBuffer?.flush(fileName);
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
3349
|
+
const isNativeBackboneCoordinatePersistenceAdapter = (value) => typeof value.hydrate ===
|
|
3350
|
+
"function" &&
|
|
3351
|
+
typeof value.flushJournal ===
|
|
3352
|
+
"function";
|
|
3353
|
+
export const createNativeBackboneCoordinatePersistence = (config) => {
|
|
3354
|
+
if (isNativeBackboneCoordinatePersistenceAdapter(config)) {
|
|
3355
|
+
return config;
|
|
3356
|
+
}
|
|
3357
|
+
const { store, buffered, ...options } = config;
|
|
3358
|
+
const isBuffered = buffered === true || !!buffered;
|
|
3359
|
+
const resolvedStore = buffered === true
|
|
3360
|
+
? new NativeBackboneBufferedCoordinatePersistenceStore(store)
|
|
3361
|
+
: buffered
|
|
3362
|
+
? new NativeBackboneBufferedCoordinatePersistenceStore(store, buffered)
|
|
3363
|
+
: store;
|
|
3364
|
+
return new NativeBackboneCoordinatePersistence(resolvedStore, {
|
|
3365
|
+
...options,
|
|
3366
|
+
compactMaxJournalBytes: isBuffered && options.compactMaxJournalBytes == null
|
|
3367
|
+
? defaultNativeBackboneCoordinateCompactMaxJournalBytes
|
|
3368
|
+
: options.compactMaxJournalBytes,
|
|
3369
|
+
});
|
|
3370
|
+
};
|
|
3371
|
+
export const createBufferedNativeBackboneCoordinatePersistence = (store, options = {}) => {
|
|
3372
|
+
const maxBufferedBytes = options.maxBufferedBytes ??
|
|
3373
|
+
options.flushMaxPendingBytes ??
|
|
3374
|
+
defaultNativeBackboneCoordinateFlushMaxPendingBytes;
|
|
3375
|
+
const flushMaxPendingBytes = options.flushMaxPendingBytes ?? maxBufferedBytes;
|
|
3376
|
+
return new NativeBackboneCoordinatePersistence(new NativeBackboneBufferedCoordinatePersistenceStore(store, {
|
|
3377
|
+
maxBufferedBytes,
|
|
3378
|
+
}), {
|
|
3379
|
+
snapshot: options.snapshot,
|
|
3380
|
+
journal: options.journal,
|
|
3381
|
+
documentSnapshot: options.documentSnapshot,
|
|
3382
|
+
documentJournal: options.documentJournal,
|
|
3383
|
+
documentSignerSnapshot: options.documentSignerSnapshot,
|
|
3384
|
+
documentSignerJournal: options.documentSignerJournal,
|
|
3385
|
+
flushOnAppend: false,
|
|
3386
|
+
flushMaxPendingBytes,
|
|
3387
|
+
flushIntervalMs: options.flushIntervalMs,
|
|
3388
|
+
compactMaxJournalBytes: options.compactMaxJournalBytes ??
|
|
3389
|
+
defaultNativeBackboneCoordinateCompactMaxJournalBytes,
|
|
3390
|
+
compactMaxJournalRecords: options.compactMaxJournalRecords,
|
|
3391
|
+
});
|
|
3392
|
+
};
|
|
3393
|
+
export const createBufferedNativeBackboneNodeCoordinatePersistence = (directory, options = {}) => {
|
|
3394
|
+
const flushMaxPendingBytes = options.flushMaxPendingBytes ??
|
|
3395
|
+
defaultNativeBackboneCoordinateFlushMaxPendingBytes;
|
|
3396
|
+
return new NativeBackboneNodeCoordinatePersistence(directory, {
|
|
3397
|
+
...options,
|
|
3398
|
+
flushOnAppend: false,
|
|
3399
|
+
flushMaxPendingBytes,
|
|
3400
|
+
writeBufferMaxBytes: options.writeBufferMaxBytes ?? flushMaxPendingBytes,
|
|
3401
|
+
compactMaxJournalBytes: options.compactMaxJournalBytes ??
|
|
3402
|
+
defaultNativeBackboneCoordinateCompactMaxJournalBytes,
|
|
3403
|
+
});
|
|
3404
|
+
};
|
|
3405
|
+
export const createNativePeerbitBackbone = NativePeerbitBackbone.create;
|
|
3406
|
+
//# sourceMappingURL=index.js.map
|