@xnetjs/data 2.3.0 → 2.5.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/dist/auth/index.d.ts +4 -4
- package/dist/{chunk-Y2XWK7AA.js → chunk-JF4VCZER.js} +14 -0
- package/dist/{chunk-32IVMT6Z.js → chunk-MAB662PR.js} +2 -2
- package/dist/{chunk-27AF2RSY.js → chunk-ODOPVGUX.js} +12 -0
- package/dist/{chunk-56EXPOJ4.js → chunk-TW5XJHNF.js} +25 -10
- package/dist/{clone-rOJgldM-.d.ts → clone-VRVODkBn.d.ts} +16 -6
- package/dist/database/index.d.ts +17 -5
- package/dist/database/index.js +2 -2
- package/dist/{form-types-BrHYdpi0.d.ts → form-types-Dkqm9UO2.d.ts} +1 -1
- package/dist/{grant-expiration-cleaner-CRS9OyhV.d.ts → grant-expiration-cleaner-CTsW0hvU.d.ts} +3 -3
- package/dist/index.d.ts +319 -8
- package/dist/index.js +723 -72
- package/dist/{page-RUS2BKMX.js → page-MADZ5OHM.js} +1 -1
- package/dist/{query-ast-DQJO7yRV.d.ts → query-ast-h31svZnG.d.ts} +1 -1
- package/dist/{registry-C9IRLLeR.d.ts → registry-Dh4Kr3fo.d.ts} +1 -1
- package/dist/schema/index.d.ts +15 -6
- package/dist/schema/index.js +2 -2
- package/dist/store/index.d.ts +4 -4
- package/dist/store/index.js +1 -1
- package/dist/{store-BYkdPZRJ.d.ts → store-jukJYsvr.d.ts} +9 -1
- package/dist/{types-gws1tSf-.d.ts → types-Z9dUzbDF.d.ts} +1 -1
- package/package.json +11 -7
package/dist/index.js
CHANGED
|
@@ -222,7 +222,73 @@ import {
|
|
|
222
222
|
validateJsonData,
|
|
223
223
|
validateRollupConfig,
|
|
224
224
|
visibleFormQuestions
|
|
225
|
-
} from "./chunk-
|
|
225
|
+
} from "./chunk-TW5XJHNF.js";
|
|
226
|
+
import {
|
|
227
|
+
MemoryNodeStorageAdapter,
|
|
228
|
+
NodeStore,
|
|
229
|
+
PermissionError,
|
|
230
|
+
QUERY_AST_VERSION,
|
|
231
|
+
SQLiteNodeStorageAdapter,
|
|
232
|
+
TEMP_ID_PREFIX,
|
|
233
|
+
and,
|
|
234
|
+
avg,
|
|
235
|
+
between,
|
|
236
|
+
contains,
|
|
237
|
+
count,
|
|
238
|
+
countDistinct,
|
|
239
|
+
createNodeStorageAdapter,
|
|
240
|
+
createSchemaLookup,
|
|
241
|
+
dashboardQuerySet,
|
|
242
|
+
defineNodeQueryAST,
|
|
243
|
+
defineQuerySetAST,
|
|
244
|
+
defineSavedViewDescriptor,
|
|
245
|
+
eq,
|
|
246
|
+
evaluateQueryASTPlannerGate,
|
|
247
|
+
executeQueryASTLoadedAggregates,
|
|
248
|
+
filterQueryASTLoadedRows,
|
|
249
|
+
follow,
|
|
250
|
+
from,
|
|
251
|
+
getQueryASTRelationIndexRequirements,
|
|
252
|
+
groupBy,
|
|
253
|
+
gt,
|
|
254
|
+
gte,
|
|
255
|
+
having,
|
|
256
|
+
includesAny,
|
|
257
|
+
isNotNull,
|
|
258
|
+
isNull,
|
|
259
|
+
isTempId,
|
|
260
|
+
lt,
|
|
261
|
+
lte,
|
|
262
|
+
matchesQueryASTLoadedRow,
|
|
263
|
+
max,
|
|
264
|
+
min,
|
|
265
|
+
neq,
|
|
266
|
+
not,
|
|
267
|
+
or,
|
|
268
|
+
planQueryASTAggregates,
|
|
269
|
+
queryOperators,
|
|
270
|
+
querySetCount,
|
|
271
|
+
resolveTempIds,
|
|
272
|
+
startsWith,
|
|
273
|
+
sum,
|
|
274
|
+
validateQueryAST,
|
|
275
|
+
validateSavedViewDescriptor
|
|
276
|
+
} from "./chunk-ODOPVGUX.js";
|
|
277
|
+
import {
|
|
278
|
+
applyNodeQueryDescriptor,
|
|
279
|
+
createNodeQueryDescriptor,
|
|
280
|
+
decodeNodeQueryCursor,
|
|
281
|
+
encodeNodeQueryCursor,
|
|
282
|
+
filterNodeQueryResults,
|
|
283
|
+
getNodeQuerySearchTokens,
|
|
284
|
+
matchesNodeQueryDescriptor,
|
|
285
|
+
nodeQueryDescriptorNeedsBoundedReload,
|
|
286
|
+
nodeQueryDescriptorToOptions,
|
|
287
|
+
serializeNodeQueryDescriptor,
|
|
288
|
+
sortNodeQueryResults,
|
|
289
|
+
withoutNodeQueryMaterializedView,
|
|
290
|
+
withoutNodeQueryPagination
|
|
291
|
+
} from "./chunk-WOEFYS7Y.js";
|
|
226
292
|
import {
|
|
227
293
|
LensRegistry,
|
|
228
294
|
MAX_LINK_PREVIEWS_PER_MESSAGE,
|
|
@@ -291,7 +357,7 @@ import {
|
|
|
291
357
|
taskBranchName,
|
|
292
358
|
transform,
|
|
293
359
|
when
|
|
294
|
-
} from "./chunk-
|
|
360
|
+
} from "./chunk-MAB662PR.js";
|
|
295
361
|
import {
|
|
296
362
|
AbuseReportSchema,
|
|
297
363
|
AppealSchema,
|
|
@@ -544,7 +610,7 @@ import {
|
|
|
544
610
|
} from "./chunk-R2AZXT3D.js";
|
|
545
611
|
import {
|
|
546
612
|
PageSchema
|
|
547
|
-
} from "./chunk-
|
|
613
|
+
} from "./chunk-JF4VCZER.js";
|
|
548
614
|
import {
|
|
549
615
|
FOLDER_SCHEMA_IRI,
|
|
550
616
|
FolderSchema,
|
|
@@ -599,72 +665,6 @@ import {
|
|
|
599
665
|
DatabaseViewSchema
|
|
600
666
|
} from "./chunk-UFV5QWCL.js";
|
|
601
667
|
import "./chunk-RLRAWZJE.js";
|
|
602
|
-
import {
|
|
603
|
-
MemoryNodeStorageAdapter,
|
|
604
|
-
NodeStore,
|
|
605
|
-
PermissionError,
|
|
606
|
-
QUERY_AST_VERSION,
|
|
607
|
-
SQLiteNodeStorageAdapter,
|
|
608
|
-
TEMP_ID_PREFIX,
|
|
609
|
-
and,
|
|
610
|
-
avg,
|
|
611
|
-
between,
|
|
612
|
-
contains,
|
|
613
|
-
count,
|
|
614
|
-
countDistinct,
|
|
615
|
-
createNodeStorageAdapter,
|
|
616
|
-
createSchemaLookup,
|
|
617
|
-
dashboardQuerySet,
|
|
618
|
-
defineNodeQueryAST,
|
|
619
|
-
defineQuerySetAST,
|
|
620
|
-
defineSavedViewDescriptor,
|
|
621
|
-
eq,
|
|
622
|
-
evaluateQueryASTPlannerGate,
|
|
623
|
-
executeQueryASTLoadedAggregates,
|
|
624
|
-
filterQueryASTLoadedRows,
|
|
625
|
-
follow,
|
|
626
|
-
from,
|
|
627
|
-
getQueryASTRelationIndexRequirements,
|
|
628
|
-
groupBy,
|
|
629
|
-
gt,
|
|
630
|
-
gte,
|
|
631
|
-
having,
|
|
632
|
-
includesAny,
|
|
633
|
-
isNotNull,
|
|
634
|
-
isNull,
|
|
635
|
-
isTempId,
|
|
636
|
-
lt,
|
|
637
|
-
lte,
|
|
638
|
-
matchesQueryASTLoadedRow,
|
|
639
|
-
max,
|
|
640
|
-
min,
|
|
641
|
-
neq,
|
|
642
|
-
not,
|
|
643
|
-
or,
|
|
644
|
-
planQueryASTAggregates,
|
|
645
|
-
queryOperators,
|
|
646
|
-
querySetCount,
|
|
647
|
-
resolveTempIds,
|
|
648
|
-
startsWith,
|
|
649
|
-
sum,
|
|
650
|
-
validateQueryAST,
|
|
651
|
-
validateSavedViewDescriptor
|
|
652
|
-
} from "./chunk-27AF2RSY.js";
|
|
653
|
-
import {
|
|
654
|
-
applyNodeQueryDescriptor,
|
|
655
|
-
createNodeQueryDescriptor,
|
|
656
|
-
decodeNodeQueryCursor,
|
|
657
|
-
encodeNodeQueryCursor,
|
|
658
|
-
filterNodeQueryResults,
|
|
659
|
-
getNodeQuerySearchTokens,
|
|
660
|
-
matchesNodeQueryDescriptor,
|
|
661
|
-
nodeQueryDescriptorNeedsBoundedReload,
|
|
662
|
-
nodeQueryDescriptorToOptions,
|
|
663
|
-
serializeNodeQueryDescriptor,
|
|
664
|
-
sortNodeQueryResults,
|
|
665
|
-
withoutNodeQueryMaterializedView,
|
|
666
|
-
withoutNodeQueryPagination
|
|
667
|
-
} from "./chunk-WOEFYS7Y.js";
|
|
668
668
|
import {
|
|
669
669
|
evaluateLedgerWrite,
|
|
670
670
|
foldAccountRecord,
|
|
@@ -2049,9 +2049,646 @@ var BlobService = class {
|
|
|
2049
2049
|
}
|
|
2050
2050
|
};
|
|
2051
2051
|
|
|
2052
|
+
// src/portability/types.ts
|
|
2053
|
+
var XNETPACK_FORMAT_VERSION = "xnetpack/1";
|
|
2054
|
+
var BUNDLE_ENTRY = {
|
|
2055
|
+
manifest: "manifest.json",
|
|
2056
|
+
changes: "changes.ndjson",
|
|
2057
|
+
blobIndex: "blobs.ndjson",
|
|
2058
|
+
yjsDocs: "yjs/docs.ndjson"
|
|
2059
|
+
};
|
|
2060
|
+
var FRONTIER_HEADS_CAP = 32;
|
|
2061
|
+
|
|
2062
|
+
// src/portability/serialize.ts
|
|
2063
|
+
import { bytesToBase64, base64ToBytes, hash, hashHex } from "@xnetjs/crypto";
|
|
2064
|
+
var textEncoder = new TextEncoder();
|
|
2065
|
+
var textDecoder = new TextDecoder();
|
|
2066
|
+
function toPortableChangeRecord(change) {
|
|
2067
|
+
const record = {
|
|
2068
|
+
id: change.id,
|
|
2069
|
+
type: change.type,
|
|
2070
|
+
hash: change.hash,
|
|
2071
|
+
nodeId: change.payload.nodeId,
|
|
2072
|
+
schemaId: change.payload.schemaId,
|
|
2073
|
+
lamportTime: change.lamport,
|
|
2074
|
+
authorDid: change.authorDID,
|
|
2075
|
+
wallTime: change.wallTime,
|
|
2076
|
+
parentHash: change.parentHash,
|
|
2077
|
+
payload: change.payload,
|
|
2078
|
+
signatureB64: bytesToBase64(change.signature),
|
|
2079
|
+
// protocolVersion is part of the hashed fields — dropping it makes the
|
|
2080
|
+
// record fail verifyChangeHash on the importing side.
|
|
2081
|
+
protocolVersion: change.protocolVersion,
|
|
2082
|
+
batchId: change.batchId,
|
|
2083
|
+
batchIndex: change.batchIndex,
|
|
2084
|
+
batchSize: change.batchSize
|
|
2085
|
+
};
|
|
2086
|
+
return record;
|
|
2087
|
+
}
|
|
2088
|
+
function fromPortableChangeRecord(record) {
|
|
2089
|
+
const payload = record.payload && !record.payload.schemaId && record.schemaId ? { ...record.payload, schemaId: record.schemaId } : record.payload;
|
|
2090
|
+
return {
|
|
2091
|
+
id: record.id,
|
|
2092
|
+
type: record.type,
|
|
2093
|
+
hash: record.hash,
|
|
2094
|
+
parentHash: record.parentHash,
|
|
2095
|
+
authorDID: record.authorDid,
|
|
2096
|
+
signature: base64ToBytes(record.signatureB64),
|
|
2097
|
+
wallTime: record.wallTime,
|
|
2098
|
+
lamport: record.lamportTime,
|
|
2099
|
+
payload,
|
|
2100
|
+
protocolVersion: record.protocolVersion,
|
|
2101
|
+
batchId: record.batchId,
|
|
2102
|
+
batchIndex: record.batchIndex,
|
|
2103
|
+
batchSize: record.batchSize
|
|
2104
|
+
};
|
|
2105
|
+
}
|
|
2106
|
+
function sortObjectKeys(obj) {
|
|
2107
|
+
if (obj === null || typeof obj !== "object") return obj;
|
|
2108
|
+
if (Array.isArray(obj)) return obj.map(sortObjectKeys);
|
|
2109
|
+
const sorted = {};
|
|
2110
|
+
for (const key of Object.keys(obj).sort()) {
|
|
2111
|
+
sorted[key] = sortObjectKeys(obj[key]);
|
|
2112
|
+
}
|
|
2113
|
+
return sorted;
|
|
2114
|
+
}
|
|
2115
|
+
function canonicalManifestBytes(manifest) {
|
|
2116
|
+
const unsigned = { ...manifest };
|
|
2117
|
+
delete unsigned.signatureB64;
|
|
2118
|
+
return textEncoder.encode(JSON.stringify(sortObjectKeys(unsigned)));
|
|
2119
|
+
}
|
|
2120
|
+
function createNdjsonDigest() {
|
|
2121
|
+
const lineDigests = [];
|
|
2122
|
+
return {
|
|
2123
|
+
addLine(line) {
|
|
2124
|
+
lineDigests.push(hash(textEncoder.encode(line)));
|
|
2125
|
+
},
|
|
2126
|
+
finish() {
|
|
2127
|
+
const concat = new Uint8Array(lineDigests.length * 32);
|
|
2128
|
+
lineDigests.forEach((d, i) => concat.set(d, i * 32));
|
|
2129
|
+
return hashHex(concat);
|
|
2130
|
+
},
|
|
2131
|
+
lineCount() {
|
|
2132
|
+
return lineDigests.length;
|
|
2133
|
+
}
|
|
2134
|
+
};
|
|
2135
|
+
}
|
|
2136
|
+
function digestEntryBytes(bytes) {
|
|
2137
|
+
return hashHex(bytes);
|
|
2138
|
+
}
|
|
2139
|
+
function combineEntryDigests(entries) {
|
|
2140
|
+
const lines = [...entries.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([path, digest]) => `${path}
|
|
2141
|
+
${digest}
|
|
2142
|
+
`);
|
|
2143
|
+
return hashHex(textEncoder.encode(lines.join("")));
|
|
2144
|
+
}
|
|
2145
|
+
function encodeNdjsonLine(value) {
|
|
2146
|
+
return JSON.stringify(value);
|
|
2147
|
+
}
|
|
2148
|
+
function decodeUtf8(bytes) {
|
|
2149
|
+
return textDecoder.decode(bytes);
|
|
2150
|
+
}
|
|
2151
|
+
function encodeUtf8(text2) {
|
|
2152
|
+
return textEncoder.encode(text2);
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
// src/portability/write.ts
|
|
2156
|
+
import { compareChangeApplicationOrder } from "@xnetjs/core";
|
|
2157
|
+
import { CURRENT_PROTOCOL_VERSION } from "@xnetjs/sync";
|
|
2158
|
+
import { bytesToBase64 as bytesToBase642 } from "@xnetjs/crypto";
|
|
2159
|
+
function blobEntryPath(cid) {
|
|
2160
|
+
const match = /^cid:([a-z0-9-]+):([0-9a-f]+)$/i.exec(cid);
|
|
2161
|
+
if (match) return `blobs/${match[1]}/${match[2]}`;
|
|
2162
|
+
return `blobs/raw/${encodeURIComponent(cid)}`;
|
|
2163
|
+
}
|
|
2164
|
+
function frontierOf(changes) {
|
|
2165
|
+
let lamport = 0;
|
|
2166
|
+
for (const change of changes) if (change.lamport > lamport) lamport = change.lamport;
|
|
2167
|
+
const heads = changes.filter((c) => c.lamport === lamport).slice(0, FRONTIER_HEADS_CAP).map((c) => c.hash);
|
|
2168
|
+
return { lamport, heads, changeCount: changes.length };
|
|
2169
|
+
}
|
|
2170
|
+
function spaceOf(properties) {
|
|
2171
|
+
return properties["space"];
|
|
2172
|
+
}
|
|
2173
|
+
async function collectScopedNodeIds(store, scope) {
|
|
2174
|
+
if (scope.kind === "nodes") return [...scope.nodeIds];
|
|
2175
|
+
if (scope.kind === "schemas") {
|
|
2176
|
+
const ids2 = [];
|
|
2177
|
+
for (const schemaId of scope.schemaIds) {
|
|
2178
|
+
const nodes = await store.list({ schemaId, includeDeleted: true });
|
|
2179
|
+
for (const node of nodes) ids2.push(node.id);
|
|
2180
|
+
}
|
|
2181
|
+
return ids2;
|
|
2182
|
+
}
|
|
2183
|
+
if (scope.kind !== "space") return [];
|
|
2184
|
+
const all = await store.list({ includeDeleted: true });
|
|
2185
|
+
const ids = [];
|
|
2186
|
+
for (const node of all) {
|
|
2187
|
+
if (node.id === scope.spaceId) {
|
|
2188
|
+
ids.push(node.id);
|
|
2189
|
+
continue;
|
|
2190
|
+
}
|
|
2191
|
+
const space = spaceOf(node.properties);
|
|
2192
|
+
if (space === scope.spaceId) ids.push(node.id);
|
|
2193
|
+
else if (Array.isArray(space) && space.includes(scope.spaceId)) ids.push(node.id);
|
|
2194
|
+
}
|
|
2195
|
+
return ids;
|
|
2196
|
+
}
|
|
2197
|
+
async function collectChanges(store, scope, since) {
|
|
2198
|
+
let changes;
|
|
2199
|
+
if (scope.kind === "full") {
|
|
2200
|
+
changes = since ? await store.getChangesSince(since.lamport) : await store.getAllChanges();
|
|
2201
|
+
} else {
|
|
2202
|
+
const nodeIds = await collectScopedNodeIds(store, scope);
|
|
2203
|
+
const byHash = /* @__PURE__ */ new Map();
|
|
2204
|
+
for (const nodeId of nodeIds) {
|
|
2205
|
+
for (const change of await store.getChanges(nodeId)) {
|
|
2206
|
+
if (!since || change.lamport > since.lamport) byHash.set(change.hash, change);
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
changes = [...byHash.values()];
|
|
2210
|
+
}
|
|
2211
|
+
return changes.sort(
|
|
2212
|
+
(a, b) => compareChangeApplicationOrder(
|
|
2213
|
+
{ lamport: a.lamport, author: a.authorDID },
|
|
2214
|
+
{ lamport: b.lamport, author: b.authorDID }
|
|
2215
|
+
)
|
|
2216
|
+
);
|
|
2217
|
+
}
|
|
2218
|
+
async function writeBundle(store, scope, sink, options) {
|
|
2219
|
+
const entryDigests = /* @__PURE__ */ new Map();
|
|
2220
|
+
const changes = await collectChanges(store, scope, options.since);
|
|
2221
|
+
const changesDigest = createNdjsonDigest();
|
|
2222
|
+
const changeLines = [];
|
|
2223
|
+
for (const change of changes) {
|
|
2224
|
+
const line = encodeNdjsonLine(toPortableChangeRecord(change));
|
|
2225
|
+
changesDigest.addLine(line);
|
|
2226
|
+
changeLines.push(line);
|
|
2227
|
+
}
|
|
2228
|
+
await sink.writeEntry(
|
|
2229
|
+
BUNDLE_ENTRY.changes,
|
|
2230
|
+
encodeUtf8(changeLines.join("\n") + (changeLines.length ? "\n" : ""))
|
|
2231
|
+
);
|
|
2232
|
+
entryDigests.set(BUNDLE_ENTRY.changes, changesDigest.finish());
|
|
2233
|
+
let blobCount = 0;
|
|
2234
|
+
const blobIndexDigest = createNdjsonDigest();
|
|
2235
|
+
const blobIndexLines = [];
|
|
2236
|
+
if (options.blobPort) {
|
|
2237
|
+
for await (const blob of options.blobPort.list()) {
|
|
2238
|
+
const path = blobEntryPath(blob.cid);
|
|
2239
|
+
await sink.writeEntry(path, blob.bytes);
|
|
2240
|
+
entryDigests.set(path, digestEntryBytes(blob.bytes));
|
|
2241
|
+
const record = {
|
|
2242
|
+
cid: blob.cid,
|
|
2243
|
+
path,
|
|
2244
|
+
size: blob.bytes.byteLength,
|
|
2245
|
+
mimeType: blob.mimeType
|
|
2246
|
+
};
|
|
2247
|
+
const line = encodeNdjsonLine(record);
|
|
2248
|
+
blobIndexDigest.addLine(line);
|
|
2249
|
+
blobIndexLines.push(line);
|
|
2250
|
+
blobCount++;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
await sink.writeEntry(
|
|
2254
|
+
BUNDLE_ENTRY.blobIndex,
|
|
2255
|
+
encodeUtf8(blobIndexLines.join("\n") + (blobIndexLines.length ? "\n" : ""))
|
|
2256
|
+
);
|
|
2257
|
+
entryDigests.set(BUNDLE_ENTRY.blobIndex, blobIndexDigest.finish());
|
|
2258
|
+
let yjsCount = 0;
|
|
2259
|
+
const yjsDigest = createNdjsonDigest();
|
|
2260
|
+
const yjsLines = [];
|
|
2261
|
+
if (options.yjsPort) {
|
|
2262
|
+
for await (const doc of options.yjsPort.list()) {
|
|
2263
|
+
const line = encodeNdjsonLine({ nodeId: doc.nodeId, updateB64: bytesToBase642(doc.update) });
|
|
2264
|
+
yjsDigest.addLine(line);
|
|
2265
|
+
yjsLines.push(line);
|
|
2266
|
+
yjsCount++;
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
await sink.writeEntry(
|
|
2270
|
+
BUNDLE_ENTRY.yjsDocs,
|
|
2271
|
+
encodeUtf8(yjsLines.join("\n") + (yjsLines.length ? "\n" : ""))
|
|
2272
|
+
);
|
|
2273
|
+
entryDigests.set(BUNDLE_ENTRY.yjsDocs, yjsDigest.finish());
|
|
2274
|
+
const manifest = {
|
|
2275
|
+
formatVersion: XNETPACK_FORMAT_VERSION,
|
|
2276
|
+
protocolVersion: { change: CURRENT_PROTOCOL_VERSION },
|
|
2277
|
+
ownerDid: options.ownerDid,
|
|
2278
|
+
scope,
|
|
2279
|
+
createdAt: Date.now(),
|
|
2280
|
+
frontier: frontierOf(changes),
|
|
2281
|
+
prerequisites: options.since,
|
|
2282
|
+
counts: { changes: changes.length, blobs: blobCount, yjsDocs: yjsCount },
|
|
2283
|
+
contentDigest: combineEntryDigests(entryDigests)
|
|
2284
|
+
};
|
|
2285
|
+
if (options.manifestSigner) {
|
|
2286
|
+
const signature = await options.manifestSigner(canonicalManifestBytes(manifest));
|
|
2287
|
+
manifest.signatureB64 = bytesToBase642(signature);
|
|
2288
|
+
}
|
|
2289
|
+
await sink.writeEntry(BUNDLE_ENTRY.manifest, encodeUtf8(JSON.stringify(manifest, null, 2)));
|
|
2290
|
+
return manifest;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
// src/portability/verify.ts
|
|
2294
|
+
import { verifyChange, verifyChangeHash, CURRENT_PROTOCOL_VERSION as CURRENT_PROTOCOL_VERSION2 } from "@xnetjs/sync";
|
|
2295
|
+
import { base64ToBytes as base64ToBytes2, verify as verifySignature } from "@xnetjs/crypto";
|
|
2296
|
+
import { parseDID } from "@xnetjs/identity";
|
|
2297
|
+
function parseCidHex(path) {
|
|
2298
|
+
const match = /^blobs\/([a-z0-9-]+)\/([0-9a-f]+)$/i.exec(path);
|
|
2299
|
+
if (!match || match[1] === "raw") return null;
|
|
2300
|
+
return { algo: match[1], hex: match[2] };
|
|
2301
|
+
}
|
|
2302
|
+
async function verifyBundle(source, options = {}) {
|
|
2303
|
+
const verifyChangeSignatures = options.verifyChangeSignatures ?? true;
|
|
2304
|
+
const issues = [];
|
|
2305
|
+
const error = (code, detail, subject) => issues.push({ severity: "error", code, detail, subject });
|
|
2306
|
+
const warning = (code, detail, subject) => issues.push({ severity: "warning", code, detail, subject });
|
|
2307
|
+
const manifestBytes = await source.readEntry(BUNDLE_ENTRY.manifest);
|
|
2308
|
+
if (!manifestBytes) {
|
|
2309
|
+
error("unknown-format", "bundle has no manifest.json");
|
|
2310
|
+
return { ok: false, manifest: null, issues, danglingParents: 0 };
|
|
2311
|
+
}
|
|
2312
|
+
let manifest;
|
|
2313
|
+
try {
|
|
2314
|
+
manifest = JSON.parse(decodeUtf8(manifestBytes));
|
|
2315
|
+
} catch (err) {
|
|
2316
|
+
error("unknown-format", `manifest.json is not valid JSON: ${err.message}`);
|
|
2317
|
+
return { ok: false, manifest: null, issues, danglingParents: 0 };
|
|
2318
|
+
}
|
|
2319
|
+
if (manifest.formatVersion !== XNETPACK_FORMAT_VERSION) {
|
|
2320
|
+
error("unknown-format", `unsupported formatVersion "${manifest.formatVersion}"`);
|
|
2321
|
+
return { ok: false, manifest, issues, danglingParents: 0 };
|
|
2322
|
+
}
|
|
2323
|
+
if ((manifest.protocolVersion?.change ?? 0) > CURRENT_PROTOCOL_VERSION2) {
|
|
2324
|
+
error(
|
|
2325
|
+
"future-protocol",
|
|
2326
|
+
`bundle uses change protocol v${manifest.protocolVersion.change}, this build supports v${CURRENT_PROTOCOL_VERSION2}`
|
|
2327
|
+
);
|
|
2328
|
+
}
|
|
2329
|
+
if (!manifest.signatureB64) {
|
|
2330
|
+
warning("manifest-unsigned", "manifest carries no signature");
|
|
2331
|
+
} else {
|
|
2332
|
+
try {
|
|
2333
|
+
const publicKey = parseDID(manifest.ownerDid);
|
|
2334
|
+
const signature = base64ToBytes2(manifest.signatureB64);
|
|
2335
|
+
if (!verifySignature(canonicalManifestBytes(manifest), signature, publicKey)) {
|
|
2336
|
+
error(
|
|
2337
|
+
"manifest-signature-invalid",
|
|
2338
|
+
`manifest signature does not verify against ${manifest.ownerDid}`
|
|
2339
|
+
);
|
|
2340
|
+
}
|
|
2341
|
+
} catch (err) {
|
|
2342
|
+
error(
|
|
2343
|
+
"manifest-signature-invalid",
|
|
2344
|
+
`cannot verify manifest signature: ${err.message}`
|
|
2345
|
+
);
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
const entryDigests = /* @__PURE__ */ new Map();
|
|
2349
|
+
const changesDigest = createNdjsonDigest();
|
|
2350
|
+
const presentHashes = /* @__PURE__ */ new Set();
|
|
2351
|
+
const parentHashes = [];
|
|
2352
|
+
let lineNumber = 0;
|
|
2353
|
+
for await (const line of source.readLines(BUNDLE_ENTRY.changes)) {
|
|
2354
|
+
lineNumber++;
|
|
2355
|
+
changesDigest.addLine(line);
|
|
2356
|
+
let record;
|
|
2357
|
+
try {
|
|
2358
|
+
record = JSON.parse(line);
|
|
2359
|
+
} catch {
|
|
2360
|
+
error(
|
|
2361
|
+
"change-unparseable",
|
|
2362
|
+
`changes.ndjson line ${lineNumber} is not valid JSON`,
|
|
2363
|
+
`line:${lineNumber}`
|
|
2364
|
+
);
|
|
2365
|
+
continue;
|
|
2366
|
+
}
|
|
2367
|
+
let change;
|
|
2368
|
+
try {
|
|
2369
|
+
change = fromPortableChangeRecord(record);
|
|
2370
|
+
} catch (err) {
|
|
2371
|
+
error("change-unparseable", `line ${lineNumber}: ${err.message}`, record.hash);
|
|
2372
|
+
continue;
|
|
2373
|
+
}
|
|
2374
|
+
if (verifyChangeSignatures) {
|
|
2375
|
+
if (!verifyChangeHash(change)) {
|
|
2376
|
+
error(
|
|
2377
|
+
"change-hash-invalid",
|
|
2378
|
+
`change ${change.id} fails hash re-computation (tampered?)`,
|
|
2379
|
+
record.hash
|
|
2380
|
+
);
|
|
2381
|
+
continue;
|
|
2382
|
+
}
|
|
2383
|
+
try {
|
|
2384
|
+
const publicKey = parseDID(change.authorDID);
|
|
2385
|
+
if (!verifyChange(change, publicKey)) {
|
|
2386
|
+
error(
|
|
2387
|
+
"change-signature-invalid",
|
|
2388
|
+
`change ${change.id} signature does not match ${change.authorDID}`,
|
|
2389
|
+
record.hash
|
|
2390
|
+
);
|
|
2391
|
+
continue;
|
|
2392
|
+
}
|
|
2393
|
+
} catch (err) {
|
|
2394
|
+
error(
|
|
2395
|
+
"change-signature-invalid",
|
|
2396
|
+
`change ${change.id}: ${err.message}`,
|
|
2397
|
+
record.hash
|
|
2398
|
+
);
|
|
2399
|
+
continue;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
presentHashes.add(change.hash);
|
|
2403
|
+
parentHashes.push(change.parentHash);
|
|
2404
|
+
}
|
|
2405
|
+
entryDigests.set(BUNDLE_ENTRY.changes, changesDigest.finish());
|
|
2406
|
+
if (changesDigest.lineCount() !== manifest.counts.changes) {
|
|
2407
|
+
error(
|
|
2408
|
+
"count-mismatch",
|
|
2409
|
+
`manifest declares ${manifest.counts.changes} changes, bundle has ${changesDigest.lineCount()}`
|
|
2410
|
+
);
|
|
2411
|
+
}
|
|
2412
|
+
const prerequisiteHeads = new Set(manifest.prerequisites?.heads ?? []);
|
|
2413
|
+
let danglingParents = 0;
|
|
2414
|
+
for (const parent of parentHashes) {
|
|
2415
|
+
if (parent !== null && !presentHashes.has(parent) && !prerequisiteHeads.has(parent)) {
|
|
2416
|
+
danglingParents++;
|
|
2417
|
+
}
|
|
2418
|
+
}
|
|
2419
|
+
if (danglingParents > 0) {
|
|
2420
|
+
warning(
|
|
2421
|
+
"dangling-parent",
|
|
2422
|
+
`${danglingParents} change(s) reference parents outside the bundle (expected for scoped/incremental exports)`
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
const blobIndexDigest = createNdjsonDigest();
|
|
2426
|
+
const indexedPaths = /* @__PURE__ */ new Set();
|
|
2427
|
+
for await (const line of source.readLines(BUNDLE_ENTRY.blobIndex)) {
|
|
2428
|
+
blobIndexDigest.addLine(line);
|
|
2429
|
+
try {
|
|
2430
|
+
const record = JSON.parse(line);
|
|
2431
|
+
indexedPaths.add(record.path);
|
|
2432
|
+
} catch {
|
|
2433
|
+
error("change-unparseable", "blobs.ndjson contains an unparseable line");
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
entryDigests.set(BUNDLE_ENTRY.blobIndex, blobIndexDigest.finish());
|
|
2437
|
+
if (blobIndexDigest.lineCount() !== manifest.counts.blobs) {
|
|
2438
|
+
error(
|
|
2439
|
+
"count-mismatch",
|
|
2440
|
+
`manifest declares ${manifest.counts.blobs} blobs, index has ${blobIndexDigest.lineCount()}`
|
|
2441
|
+
);
|
|
2442
|
+
}
|
|
2443
|
+
for (const path of await source.listEntries("blobs/")) {
|
|
2444
|
+
if (path === BUNDLE_ENTRY.blobIndex) continue;
|
|
2445
|
+
const bytes = await source.readEntry(path);
|
|
2446
|
+
if (!bytes) continue;
|
|
2447
|
+
entryDigests.set(path, digestEntryBytes(bytes));
|
|
2448
|
+
const cid = parseCidHex(path);
|
|
2449
|
+
if (cid && cid.algo === "blake3" && digestEntryBytes(bytes) !== cid.hex.toLowerCase()) {
|
|
2450
|
+
error("blob-digest-mismatch", `blob ${path} bytes do not hash to their filename`, path);
|
|
2451
|
+
}
|
|
2452
|
+
if (!indexedPaths.has(path)) {
|
|
2453
|
+
warning("count-mismatch", `blob entry ${path} is not listed in blobs.ndjson`, path);
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
const yjsDigest = createNdjsonDigest();
|
|
2457
|
+
for await (const line of source.readLines(BUNDLE_ENTRY.yjsDocs)) {
|
|
2458
|
+
yjsDigest.addLine(line);
|
|
2459
|
+
}
|
|
2460
|
+
entryDigests.set(BUNDLE_ENTRY.yjsDocs, yjsDigest.finish());
|
|
2461
|
+
if (yjsDigest.lineCount() !== manifest.counts.yjsDocs) {
|
|
2462
|
+
error(
|
|
2463
|
+
"count-mismatch",
|
|
2464
|
+
`manifest declares ${manifest.counts.yjsDocs} yjs docs, bundle has ${yjsDigest.lineCount()}`
|
|
2465
|
+
);
|
|
2466
|
+
}
|
|
2467
|
+
if (combineEntryDigests(entryDigests) !== manifest.contentDigest) {
|
|
2468
|
+
error("content-digest-mismatch", "entry digests do not match manifest.contentDigest");
|
|
2469
|
+
}
|
|
2470
|
+
return {
|
|
2471
|
+
ok: !issues.some((i) => i.severity === "error"),
|
|
2472
|
+
manifest,
|
|
2473
|
+
issues,
|
|
2474
|
+
danglingParents
|
|
2475
|
+
};
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
// src/portability/apply.ts
|
|
2479
|
+
import { compareChangeApplicationOrder as compareChangeApplicationOrder2 } from "@xnetjs/core";
|
|
2480
|
+
import { base64ToBytes as base64ToBytes3 } from "@xnetjs/crypto";
|
|
2481
|
+
var BundleImportError = class extends Error {
|
|
2482
|
+
constructor(message, code) {
|
|
2483
|
+
super(message);
|
|
2484
|
+
this.code = code;
|
|
2485
|
+
this.name = "BundleImportError";
|
|
2486
|
+
}
|
|
2487
|
+
};
|
|
2488
|
+
var APPLY_BATCH_SIZE = 500;
|
|
2489
|
+
async function applyBundle(store, source, options) {
|
|
2490
|
+
const verifyReport = await verifyBundle(source, { verifyChangeSignatures: false });
|
|
2491
|
+
if (!verifyReport.ok || !verifyReport.manifest) {
|
|
2492
|
+
const details = verifyReport.issues.filter((i) => i.severity === "error").map((i) => i.detail).join("; ");
|
|
2493
|
+
throw new BundleImportError(`bundle failed verification: ${details}`, "verify-failed");
|
|
2494
|
+
}
|
|
2495
|
+
const manifest = verifyReport.manifest;
|
|
2496
|
+
if (!manifest.signatureB64 && !options.allowUnsigned) {
|
|
2497
|
+
throw new BundleImportError(
|
|
2498
|
+
"bundle manifest is unsigned \u2014 pass allowUnsigned to import anyway",
|
|
2499
|
+
"unsigned-manifest"
|
|
2500
|
+
);
|
|
2501
|
+
}
|
|
2502
|
+
if (manifest.ownerDid !== options.importerDid && !options.allowForeignOwner) {
|
|
2503
|
+
throw new BundleImportError(
|
|
2504
|
+
`bundle is owned by ${manifest.ownerDid} but the importer is ${options.importerDid} \u2014 pass allowForeignOwner to import a bundle from another identity`,
|
|
2505
|
+
"foreign-owner"
|
|
2506
|
+
);
|
|
2507
|
+
}
|
|
2508
|
+
const missingPrerequisites = [];
|
|
2509
|
+
if (manifest.prerequisites) {
|
|
2510
|
+
for (const head of manifest.prerequisites.heads) {
|
|
2511
|
+
if (!await store.hasChange(head)) missingPrerequisites.push(head);
|
|
2512
|
+
}
|
|
2513
|
+
if (missingPrerequisites.length > 0 && !options.ignoreMissingPrerequisites) {
|
|
2514
|
+
throw new BundleImportError(
|
|
2515
|
+
`store is missing ${missingPrerequisites.length} prerequisite head(s) \u2014 this incremental bundle needs its base bundle imported first (or pass ignoreMissingPrerequisites)`,
|
|
2516
|
+
"missing-prerequisites"
|
|
2517
|
+
);
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
const quarantined = [];
|
|
2521
|
+
const quarantine = (record) => {
|
|
2522
|
+
quarantined.push(record);
|
|
2523
|
+
options.onQuarantine?.(record);
|
|
2524
|
+
};
|
|
2525
|
+
const changes = [];
|
|
2526
|
+
for await (const line of source.readLines(BUNDLE_ENTRY.changes)) {
|
|
2527
|
+
try {
|
|
2528
|
+
changes.push(fromPortableChangeRecord(JSON.parse(line)));
|
|
2529
|
+
} catch (err) {
|
|
2530
|
+
quarantine({ kind: "change", subject: line.slice(0, 80), reason: err.message });
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
changes.sort(
|
|
2534
|
+
(a, b) => compareChangeApplicationOrder2(
|
|
2535
|
+
{ lamport: a.lamport, author: a.authorDID },
|
|
2536
|
+
{ lamport: b.lamport, author: b.authorDID }
|
|
2537
|
+
)
|
|
2538
|
+
);
|
|
2539
|
+
let applied = 0;
|
|
2540
|
+
let duplicates = 0;
|
|
2541
|
+
for (let i = 0; i < changes.length; i += APPLY_BATCH_SIZE) {
|
|
2542
|
+
for (const change of changes.slice(i, i + APPLY_BATCH_SIZE)) {
|
|
2543
|
+
try {
|
|
2544
|
+
if (await store.hasChange(change.hash)) {
|
|
2545
|
+
duplicates++;
|
|
2546
|
+
continue;
|
|
2547
|
+
}
|
|
2548
|
+
await store.applyRemoteChange(change);
|
|
2549
|
+
applied++;
|
|
2550
|
+
} catch (err) {
|
|
2551
|
+
quarantine({
|
|
2552
|
+
kind: "change",
|
|
2553
|
+
subject: change.hash,
|
|
2554
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
let blobsInstalled = 0;
|
|
2560
|
+
if (options.blobPort) {
|
|
2561
|
+
for await (const line of source.readLines(BUNDLE_ENTRY.blobIndex)) {
|
|
2562
|
+
let record;
|
|
2563
|
+
try {
|
|
2564
|
+
record = JSON.parse(line);
|
|
2565
|
+
} catch (err) {
|
|
2566
|
+
quarantine({ kind: "blob", subject: line.slice(0, 80), reason: err.message });
|
|
2567
|
+
continue;
|
|
2568
|
+
}
|
|
2569
|
+
try {
|
|
2570
|
+
if (await options.blobPort.has(record.cid)) continue;
|
|
2571
|
+
const bytes = await source.readEntry(record.path);
|
|
2572
|
+
if (!bytes) {
|
|
2573
|
+
quarantine({
|
|
2574
|
+
kind: "blob",
|
|
2575
|
+
subject: record.cid,
|
|
2576
|
+
reason: `bundle entry ${record.path} missing`
|
|
2577
|
+
});
|
|
2578
|
+
continue;
|
|
2579
|
+
}
|
|
2580
|
+
await options.blobPort.put(bytes, { cid: record.cid, mimeType: record.mimeType });
|
|
2581
|
+
blobsInstalled++;
|
|
2582
|
+
} catch (err) {
|
|
2583
|
+
quarantine({ kind: "blob", subject: record.cid, reason: err.message });
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
let yjsDocsApplied = 0;
|
|
2588
|
+
if (options.yjsPort) {
|
|
2589
|
+
for await (const line of source.readLines(BUNDLE_ENTRY.yjsDocs)) {
|
|
2590
|
+
let record;
|
|
2591
|
+
try {
|
|
2592
|
+
record = JSON.parse(line);
|
|
2593
|
+
} catch (err) {
|
|
2594
|
+
quarantine({ kind: "yjs-doc", subject: line.slice(0, 80), reason: err.message });
|
|
2595
|
+
continue;
|
|
2596
|
+
}
|
|
2597
|
+
try {
|
|
2598
|
+
await options.yjsPort.apply(record.nodeId, base64ToBytes3(record.updateB64));
|
|
2599
|
+
yjsDocsApplied++;
|
|
2600
|
+
} catch (err) {
|
|
2601
|
+
quarantine({ kind: "yjs-doc", subject: record.nodeId, reason: err.message });
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
return { applied, duplicates, quarantined, blobsInstalled, yjsDocsApplied, missingPrerequisites };
|
|
2606
|
+
}
|
|
2607
|
+
async function readBundleManifest(source) {
|
|
2608
|
+
const bytes = await source.readEntry(BUNDLE_ENTRY.manifest);
|
|
2609
|
+
if (!bytes) return null;
|
|
2610
|
+
try {
|
|
2611
|
+
return JSON.parse(decodeUtf8(bytes));
|
|
2612
|
+
} catch {
|
|
2613
|
+
return null;
|
|
2614
|
+
}
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2617
|
+
// src/portability/memory-bundle.ts
|
|
2618
|
+
var MemoryBundleSink = class {
|
|
2619
|
+
entries = /* @__PURE__ */ new Map();
|
|
2620
|
+
writeEntry(path, data) {
|
|
2621
|
+
this.entries.set(path, data);
|
|
2622
|
+
}
|
|
2623
|
+
toSource() {
|
|
2624
|
+
return new MemoryBundleSource(this.entries);
|
|
2625
|
+
}
|
|
2626
|
+
};
|
|
2627
|
+
var MemoryBundleSource = class {
|
|
2628
|
+
constructor(entries) {
|
|
2629
|
+
this.entries = entries;
|
|
2630
|
+
}
|
|
2631
|
+
async readEntry(path) {
|
|
2632
|
+
return this.entries.get(path) ?? null;
|
|
2633
|
+
}
|
|
2634
|
+
async *readLines(path) {
|
|
2635
|
+
const bytes = this.entries.get(path);
|
|
2636
|
+
if (!bytes) return;
|
|
2637
|
+
let start = 0;
|
|
2638
|
+
const text2 = decodeUtf8(bytes);
|
|
2639
|
+
while (start < text2.length) {
|
|
2640
|
+
let end = text2.indexOf("\n", start);
|
|
2641
|
+
if (end === -1) end = text2.length;
|
|
2642
|
+
const line = text2.slice(start, end);
|
|
2643
|
+
if (line.length > 0) yield line;
|
|
2644
|
+
start = end + 1;
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
async listEntries(prefix) {
|
|
2648
|
+
return [...this.entries.keys()].filter((p) => p.startsWith(prefix)).sort();
|
|
2649
|
+
}
|
|
2650
|
+
};
|
|
2651
|
+
|
|
2652
|
+
// src/portability/store-yjs-port.ts
|
|
2653
|
+
import * as Y2 from "yjs";
|
|
2654
|
+
function createStoreYjsPort(store) {
|
|
2655
|
+
return {
|
|
2656
|
+
async *list() {
|
|
2657
|
+
const nodes = await store.list({ includeDeleted: true });
|
|
2658
|
+
for (const node of nodes) {
|
|
2659
|
+
const content = await store.getDocumentContent(node.id);
|
|
2660
|
+
if (content && content.byteLength > 0) {
|
|
2661
|
+
yield { nodeId: node.id, update: content };
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
},
|
|
2665
|
+
async apply(nodeId, update) {
|
|
2666
|
+
const existing = await store.getDocumentContent(nodeId);
|
|
2667
|
+
if (!existing || existing.byteLength === 0) {
|
|
2668
|
+
await store.setDocumentContent(nodeId, update);
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2671
|
+
let merged;
|
|
2672
|
+
const doc = new Y2.Doc();
|
|
2673
|
+
try {
|
|
2674
|
+
Y2.applyUpdate(doc, existing);
|
|
2675
|
+
Y2.applyUpdate(doc, update);
|
|
2676
|
+
merged = Y2.encodeStateAsUpdate(doc);
|
|
2677
|
+
} catch (err) {
|
|
2678
|
+
throw new Error(
|
|
2679
|
+
`document content for ${nodeId} is not a mergeable Yjs update (${err.message}); left the existing content untouched`
|
|
2680
|
+
);
|
|
2681
|
+
} finally {
|
|
2682
|
+
doc.destroy();
|
|
2683
|
+
}
|
|
2684
|
+
await store.setDocumentContent(nodeId, merged);
|
|
2685
|
+
}
|
|
2686
|
+
};
|
|
2687
|
+
}
|
|
2688
|
+
|
|
2052
2689
|
// src/index.ts
|
|
2053
2690
|
import {
|
|
2054
|
-
Doc,
|
|
2691
|
+
Doc as Doc2,
|
|
2055
2692
|
Map as Map3,
|
|
2056
2693
|
Array as Array2,
|
|
2057
2694
|
Text,
|
|
@@ -2092,8 +2729,10 @@ export {
|
|
|
2092
2729
|
AgentSessionSchema,
|
|
2093
2730
|
AppealSchema,
|
|
2094
2731
|
BUDGET_SCHEMA_IRI,
|
|
2732
|
+
BUNDLE_ENTRY,
|
|
2095
2733
|
BlobService,
|
|
2096
2734
|
BudgetSchema,
|
|
2735
|
+
BundleImportError,
|
|
2097
2736
|
CELL_PREFIX,
|
|
2098
2737
|
CHANNEL_KINDS,
|
|
2099
2738
|
CHECKPOINT_SCHEMA_IRI,
|
|
@@ -2196,6 +2835,8 @@ export {
|
|
|
2196
2835
|
MediaAssetSchema,
|
|
2197
2836
|
MeetingSchema,
|
|
2198
2837
|
MeetingTranscriptSchema,
|
|
2838
|
+
MemoryBundleSink,
|
|
2839
|
+
MemoryBundleSource,
|
|
2199
2840
|
MemoryItemSchema,
|
|
2200
2841
|
MemoryNodeStorageAdapter,
|
|
2201
2842
|
MessageRequestSchema,
|
|
@@ -2284,8 +2925,9 @@ export {
|
|
|
2284
2925
|
TranscriptionSchema,
|
|
2285
2926
|
UserWidgetSchema,
|
|
2286
2927
|
WorkspaceSchema,
|
|
2928
|
+
XNETPACK_FORMAT_VERSION,
|
|
2287
2929
|
Array2 as YArray,
|
|
2288
|
-
|
|
2930
|
+
Doc2 as YDoc,
|
|
2289
2931
|
Map3 as YMap,
|
|
2290
2932
|
Text as YText,
|
|
2291
2933
|
XmlElement as YXmlElement,
|
|
@@ -2306,6 +2948,7 @@ export {
|
|
|
2306
2948
|
agentSessionId,
|
|
2307
2949
|
aggregate,
|
|
2308
2950
|
and,
|
|
2951
|
+
applyBundle,
|
|
2309
2952
|
applyNodeQueryDescriptor,
|
|
2310
2953
|
applySignedUpdate,
|
|
2311
2954
|
asRowHeight,
|
|
@@ -2313,6 +2956,7 @@ export {
|
|
|
2313
2956
|
avg,
|
|
2314
2957
|
batchComputeRollups,
|
|
2315
2958
|
between,
|
|
2959
|
+
blobEntryPath,
|
|
2316
2960
|
bucketPresenceCount,
|
|
2317
2961
|
buildDatabaseSchema,
|
|
2318
2962
|
buildEffectiveSchema,
|
|
@@ -2328,6 +2972,7 @@ export {
|
|
|
2328
2972
|
bumpSchemaVersion,
|
|
2329
2973
|
canManageSpace,
|
|
2330
2974
|
canModifyColumn,
|
|
2975
|
+
canonicalManifestBytes,
|
|
2331
2976
|
captureUpdate,
|
|
2332
2977
|
cellKey,
|
|
2333
2978
|
cellValueToText,
|
|
@@ -2383,6 +3028,7 @@ export {
|
|
|
2383
3028
|
createSelectOption,
|
|
2384
3029
|
createSort,
|
|
2385
3030
|
createSortQuery,
|
|
3031
|
+
createStoreYjsPort,
|
|
2386
3032
|
createVersionEntry,
|
|
2387
3033
|
createView2 as createView,
|
|
2388
3034
|
createView as createViewNode,
|
|
@@ -2458,6 +3104,7 @@ export {
|
|
|
2458
3104
|
formatValue,
|
|
2459
3105
|
from,
|
|
2460
3106
|
fromCellProperties,
|
|
3107
|
+
fromPortableChangeRecord,
|
|
2461
3108
|
gameSchemas,
|
|
2462
3109
|
generateColumnIdMap,
|
|
2463
3110
|
generateSortKey,
|
|
@@ -2626,6 +3273,7 @@ export {
|
|
|
2626
3273
|
queryOperators,
|
|
2627
3274
|
queryRows,
|
|
2628
3275
|
querySetCount,
|
|
3276
|
+
readBundleManifest,
|
|
2629
3277
|
rebalanceDatabase,
|
|
2630
3278
|
rebalanceSortKeys,
|
|
2631
3279
|
recoveryRecordId,
|
|
@@ -2697,6 +3345,7 @@ export {
|
|
|
2697
3345
|
toCellProperties,
|
|
2698
3346
|
toColumnDefinitions,
|
|
2699
3347
|
toFieldNode,
|
|
3348
|
+
toPortableChangeRecord,
|
|
2700
3349
|
toSelectOptionNode,
|
|
2701
3350
|
toggleGroupCollapsed,
|
|
2702
3351
|
toggleGroupCollapsed2 as toggleGroupCollapsedState,
|
|
@@ -2719,11 +3368,13 @@ export {
|
|
|
2719
3368
|
validateRollupConfig,
|
|
2720
3369
|
validateSavedViewDescriptor,
|
|
2721
3370
|
validateSchemaDefinitionNode,
|
|
3371
|
+
verifyBundle,
|
|
2722
3372
|
verifyUpdate,
|
|
2723
3373
|
visibleFormQuestions,
|
|
2724
3374
|
when,
|
|
2725
3375
|
withoutNodeQueryMaterializedView,
|
|
2726
3376
|
withoutNodeQueryPagination,
|
|
2727
3377
|
wouldCreateFolderCycle,
|
|
2728
|
-
wouldCreateSpaceCycle
|
|
3378
|
+
wouldCreateSpaceCycle,
|
|
3379
|
+
writeBundle
|
|
2729
3380
|
};
|