@xnetjs/data 2.3.0 → 2.4.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/index.js CHANGED
@@ -6,223 +6,6 @@ import {
6
6
  signUpdate,
7
7
  verifyUpdate
8
8
  } from "./chunk-XHEA5UER.js";
9
- import {
10
- CELL_PREFIX,
11
- DATABASE_SCHEMA_NAMESPACE,
12
- DATABASE_SCHEMA_PREFIX,
13
- DEFAULT_DATABASE_SCHEMA_VERSION,
14
- DEFAULT_ROW_HEIGHT,
15
- FIELD_TYPES,
16
- FormulaService,
17
- MAX_VERSION_HISTORY,
18
- OPERATORS_BY_TYPE,
19
- OPERATOR_LABELS,
20
- PUBLIC_SAFE_FORM_FIELD_TYPES,
21
- RICHTEXT_PREFIX,
22
- ROW_HEIGHTS,
23
- ROW_HEIGHT_PX,
24
- SELECT_COLORS,
25
- SUMMARY_FUNCTIONS_BY_TYPE,
26
- addDefaultTableView,
27
- addDefaultTitleColumn,
28
- addOrToggleSort,
29
- addViewSort,
30
- aggregate,
31
- asRowHeight,
32
- autoColor,
33
- batchComputeRollups,
34
- buildDatabaseSchema,
35
- buildPublicFormDefinition,
36
- buildSchemaFromFields,
37
- buildSchemaIRI,
38
- bumpSchemaVersion,
39
- cellKey,
40
- cellValueToText,
41
- checkNeedsRebalancing,
42
- clearViewFilters,
43
- clearViewSorts,
44
- cloneColumns,
45
- cloneSampleRows,
46
- cloneSchema,
47
- collapseAllGroups,
48
- columnIdFromKey,
49
- combineFiltersAnd,
50
- combineFiltersOr,
51
- computeColumnSummary,
52
- computeRollup,
53
- convertCellValue,
54
- createAnyOfFilter,
55
- createColumn,
56
- createCsvBlob,
57
- createDatabaseSchemaResolver,
58
- createEqualsFilter,
59
- createExtensionField,
60
- createField,
61
- createFilterQuery,
62
- createFormulaService,
63
- createInitialSchemaMetadata,
64
- createJsonBlob,
65
- createNodeDatabaseSchemaResolver,
66
- createPaginatedQuery,
67
- createRow,
68
- createSelectOption,
69
- createSort,
70
- createSortQuery,
71
- createVersionEntry,
72
- createView,
73
- createView2,
74
- deleteColumn,
75
- deleteExtensionField,
76
- deleteField,
77
- deleteMeta,
78
- deleteRichTextCell,
79
- deleteRow,
80
- deleteSelectOption,
81
- deleteView,
82
- deleteView2,
83
- downloadCsv,
84
- downloadJson,
85
- duplicateColumn,
86
- duplicateField,
87
- duplicateView,
88
- duplicateView2,
89
- effectiveFieldSortKey,
90
- ensureSchemaExtension,
91
- escapeCSV,
92
- executeQuery,
93
- expandAllGroups,
94
- exportToCsv,
95
- exportToJson,
96
- exportToJsonArray,
97
- exportToNdjson,
98
- extractSchemaFromDoc,
99
- fieldsToStoredColumns,
100
- filterRows,
101
- flattenGroups,
102
- formatValue,
103
- fromCellProperties,
104
- generateColumnIdMap,
105
- getColumn,
106
- getColumnIndex,
107
- getColumns,
108
- getDatabaseDocumentModel,
109
- getDatabaseSchemaIRI,
110
- getDatabaseSelectOptions,
111
- getField,
112
- getFields,
113
- getMeta,
114
- getOperatorLabel,
115
- getOperatorsForType,
116
- getRichTextCell,
117
- getRichTextColumnIds,
118
- getRichTextPlainText,
119
- getRow,
120
- getSchemaIRIFromDoc,
121
- getSelectOptions,
122
- getTitleColumn,
123
- getTitleField,
124
- getTotalFromGroups,
125
- getVersionBumpType,
126
- getView,
127
- getView2,
128
- getViewByType,
129
- getViews,
130
- getViews2,
131
- groupRows,
132
- guessColumnType,
133
- hasRichTextColumns,
134
- hasRichTextContent,
135
- hideColumn,
136
- inferColumnTypes,
137
- inferColumnsFromRows,
138
- inferTypeFromValues,
139
- initializeDatabaseDoc,
140
- isAutoColumnType,
141
- isAutoFieldType,
142
- isCellKey,
143
- isCellValue,
144
- isComputedColumnType,
145
- isComputedFieldType,
146
- isDatabaseDocInitialized,
147
- isDatabaseSchemaIRI,
148
- isDateRange,
149
- isFieldType,
150
- isFileRef,
151
- isFilledValue,
152
- isFilterCondition,
153
- isFilterGroup,
154
- isFormFieldTypeAllowed,
155
- isFormQuestionVisible,
156
- isGeoPoint as isGeoPoint2,
157
- isNodeStoreColumnType,
158
- isNodeStoreFieldType,
159
- isSelectColor,
160
- isValidOperator,
161
- isYDocColumnType,
162
- isYDocFieldType,
163
- moveField,
164
- moveRow,
165
- moveSelectOption,
166
- moveView,
167
- operatorRequiresValue,
168
- parseCSV,
169
- parseCSVLine,
170
- parseDatabaseSchemaIRI,
171
- parseJSON,
172
- parseRow,
173
- parseValue,
174
- parseVersion,
175
- pruneVersionHistory,
176
- queryRows,
177
- rebalanceDatabase,
178
- remapViewColumnIds,
179
- removeSort,
180
- removeViewSort,
181
- renameExtensionField,
182
- reorderColumn,
183
- reorderViewColumns,
184
- requiresDateColumn,
185
- resolveRowHeightPx,
186
- rowHeightLabel,
187
- setColumnWidth,
188
- setFieldHidden,
189
- setMeta,
190
- setViewFieldOrder,
191
- setViewFieldWidth,
192
- setViewFilters,
193
- setViewFilters2,
194
- setViewGroupBy,
195
- setViewGroupBy2,
196
- setViewSorts,
197
- setViewSorts2,
198
- setVisibleColumns,
199
- setupDatabase,
200
- setupNewDatabase,
201
- showColumn,
202
- sortRows,
203
- submissionRowId,
204
- summaryFunctionLabel,
205
- supportsGrouping,
206
- toCellProperties,
207
- toColumnDefinitions,
208
- toFieldNode,
209
- toSelectOptionNode,
210
- toggleGroupCollapsed,
211
- toggleGroupCollapsed2,
212
- toggleSortDirection,
213
- toggleViewGroupCollapsed,
214
- updateCell,
215
- updateCells,
216
- updateColumn,
217
- updateField,
218
- updateSelectOption,
219
- updateView,
220
- updateView2,
221
- validateFormSubmission,
222
- validateJsonData,
223
- validateRollupConfig,
224
- visibleFormQuestions
225
- } from "./chunk-56EXPOJ4.js";
226
9
  import {
227
10
  LensRegistry,
228
11
  MAX_LINK_PREVIEWS_PER_MESSAGE,
@@ -291,7 +74,7 @@ import {
291
74
  taskBranchName,
292
75
  transform,
293
76
  when
294
- } from "./chunk-32IVMT6Z.js";
77
+ } from "./chunk-CNGEXCIH.js";
295
78
  import {
296
79
  AbuseReportSchema,
297
80
  AppealSchema,
@@ -564,6 +347,326 @@ import {
564
347
  import {
565
348
  DatabaseSchema
566
349
  } from "./chunk-JB6BPIVP.js";
350
+ import {
351
+ MemoryNodeStorageAdapter,
352
+ NodeStore,
353
+ PermissionError,
354
+ QUERY_AST_VERSION,
355
+ SQLiteNodeStorageAdapter,
356
+ TEMP_ID_PREFIX,
357
+ and,
358
+ avg,
359
+ between,
360
+ contains,
361
+ count,
362
+ countDistinct,
363
+ createNodeStorageAdapter,
364
+ createSchemaLookup,
365
+ dashboardQuerySet,
366
+ defineNodeQueryAST,
367
+ defineQuerySetAST,
368
+ defineSavedViewDescriptor,
369
+ eq,
370
+ evaluateQueryASTPlannerGate,
371
+ executeQueryASTLoadedAggregates,
372
+ filterQueryASTLoadedRows,
373
+ follow,
374
+ from,
375
+ getQueryASTRelationIndexRequirements,
376
+ groupBy,
377
+ gt,
378
+ gte,
379
+ having,
380
+ includesAny,
381
+ isNotNull,
382
+ isNull,
383
+ isTempId,
384
+ lt,
385
+ lte,
386
+ matchesQueryASTLoadedRow,
387
+ max,
388
+ min,
389
+ neq,
390
+ not,
391
+ or,
392
+ planQueryASTAggregates,
393
+ queryOperators,
394
+ querySetCount,
395
+ resolveTempIds,
396
+ startsWith,
397
+ sum,
398
+ validateQueryAST,
399
+ validateSavedViewDescriptor
400
+ } from "./chunk-EGGRKSRH.js";
401
+ import {
402
+ evaluateLedgerWrite,
403
+ foldAccountRecord,
404
+ ledgerAccountId,
405
+ ledgerWriteKind
406
+ } from "./chunk-3UOUVEZW.js";
407
+ import {
408
+ ACCOUNT_RECORD_SCHEMA_IRI,
409
+ AccountRecordSchema,
410
+ DEVICE_RECORD_SCHEMA_IRI,
411
+ DeviceRecordSchema,
412
+ RECOVERY_RECORD_SCHEMA_IRI,
413
+ REVOCATION_RECORD_SCHEMA_IRI,
414
+ RecoveryRecordSchema,
415
+ RevocationRecordSchema,
416
+ accountRecordId,
417
+ deviceRecipientExpander,
418
+ deviceRecordId,
419
+ isDeviceAuthorized,
420
+ recoveryRecordId,
421
+ resolveActiveDevices,
422
+ revocationRecordId,
423
+ revokedSubjects
424
+ } from "./chunk-5ECIKN6Z.js";
425
+ import {
426
+ PresenceSummarySchema,
427
+ SYSTEM_NAMESPACE_KINDS,
428
+ SYSTEM_SCHEMA_BASE_IRIS,
429
+ SYSTEM_SCHEMA_IRIS,
430
+ SchemaCompatibilitySchema,
431
+ SchemaDefinitionSchema,
432
+ SyncPolicySchema,
433
+ buildSystemNamespace,
434
+ buildSystemNodeId,
435
+ computeSchemaDefinitionContentHash,
436
+ createSchemaDefinitionSigningPayload,
437
+ isSystemNamespaceResource,
438
+ isSystemSchemaIri,
439
+ parseSystemNamespaceResource,
440
+ resolveSchemaAuthority,
441
+ validateSchemaDefinitionNode
442
+ } from "./chunk-ZNHLH7SC.js";
443
+ import {
444
+ clearLocalPresence,
445
+ createAwareness,
446
+ generateUserColor,
447
+ getAllPresences,
448
+ getLocalClientId,
449
+ getRemotePresences,
450
+ onPresenceChange,
451
+ setLocalPresence
452
+ } from "./chunk-7PDRDSFH.js";
453
+ import {
454
+ CELL_PREFIX,
455
+ DATABASE_SCHEMA_NAMESPACE,
456
+ DATABASE_SCHEMA_PREFIX,
457
+ DEFAULT_DATABASE_SCHEMA_VERSION,
458
+ DEFAULT_ROW_HEIGHT,
459
+ FIELD_TYPES,
460
+ FormulaService,
461
+ MAX_VERSION_HISTORY,
462
+ OPERATORS_BY_TYPE,
463
+ OPERATOR_LABELS,
464
+ PUBLIC_SAFE_FORM_FIELD_TYPES,
465
+ RICHTEXT_PREFIX,
466
+ ROW_HEIGHTS,
467
+ ROW_HEIGHT_PX,
468
+ SELECT_COLORS,
469
+ SUMMARY_FUNCTIONS_BY_TYPE,
470
+ addDefaultTableView,
471
+ addDefaultTitleColumn,
472
+ addOrToggleSort,
473
+ addViewSort,
474
+ aggregate,
475
+ asRowHeight,
476
+ autoColor,
477
+ batchComputeRollups,
478
+ buildDatabaseSchema,
479
+ buildPublicFormDefinition,
480
+ buildSchemaFromFields,
481
+ buildSchemaIRI,
482
+ bumpSchemaVersion,
483
+ cellKey,
484
+ cellValueToText,
485
+ checkNeedsRebalancing,
486
+ clearViewFilters,
487
+ clearViewSorts,
488
+ cloneColumns,
489
+ cloneSampleRows,
490
+ cloneSchema,
491
+ collapseAllGroups,
492
+ columnIdFromKey,
493
+ combineFiltersAnd,
494
+ combineFiltersOr,
495
+ computeColumnSummary,
496
+ computeRollup,
497
+ convertCellValue,
498
+ createAnyOfFilter,
499
+ createColumn,
500
+ createCsvBlob,
501
+ createDatabaseSchemaResolver,
502
+ createEqualsFilter,
503
+ createExtensionField,
504
+ createField,
505
+ createFilterQuery,
506
+ createFormulaService,
507
+ createInitialSchemaMetadata,
508
+ createJsonBlob,
509
+ createNodeDatabaseSchemaResolver,
510
+ createPaginatedQuery,
511
+ createRow,
512
+ createSelectOption,
513
+ createSort,
514
+ createSortQuery,
515
+ createVersionEntry,
516
+ createView,
517
+ createView2,
518
+ deleteColumn,
519
+ deleteExtensionField,
520
+ deleteField,
521
+ deleteMeta,
522
+ deleteRichTextCell,
523
+ deleteRow,
524
+ deleteSelectOption,
525
+ deleteView,
526
+ deleteView2,
527
+ downloadCsv,
528
+ downloadJson,
529
+ duplicateColumn,
530
+ duplicateField,
531
+ duplicateView,
532
+ duplicateView2,
533
+ effectiveFieldSortKey,
534
+ ensureSchemaExtension,
535
+ escapeCSV,
536
+ executeQuery,
537
+ expandAllGroups,
538
+ exportToCsv,
539
+ exportToJson,
540
+ exportToJsonArray,
541
+ exportToNdjson,
542
+ extractSchemaFromDoc,
543
+ fieldsToStoredColumns,
544
+ filterRows,
545
+ flattenGroups,
546
+ formatValue,
547
+ fromCellProperties,
548
+ generateColumnIdMap,
549
+ getColumn,
550
+ getColumnIndex,
551
+ getColumns,
552
+ getDatabaseDocumentModel,
553
+ getDatabaseSchemaIRI,
554
+ getDatabaseSelectOptions,
555
+ getField,
556
+ getFields,
557
+ getMeta,
558
+ getOperatorLabel,
559
+ getOperatorsForType,
560
+ getRichTextCell,
561
+ getRichTextColumnIds,
562
+ getRichTextPlainText,
563
+ getRow,
564
+ getSchemaIRIFromDoc,
565
+ getSelectOptions,
566
+ getTitleColumn,
567
+ getTitleField,
568
+ getTotalFromGroups,
569
+ getVersionBumpType,
570
+ getView,
571
+ getView2,
572
+ getViewByType,
573
+ getViews,
574
+ getViews2,
575
+ groupRows,
576
+ guessColumnType,
577
+ hasRichTextColumns,
578
+ hasRichTextContent,
579
+ hideColumn,
580
+ inferColumnTypes,
581
+ inferColumnsFromRows,
582
+ inferTypeFromValues,
583
+ initializeDatabaseDoc,
584
+ isAutoColumnType,
585
+ isAutoFieldType,
586
+ isCellKey,
587
+ isCellValue,
588
+ isComputedColumnType,
589
+ isComputedFieldType,
590
+ isDatabaseDocInitialized,
591
+ isDatabaseSchemaIRI,
592
+ isDateRange,
593
+ isFieldType,
594
+ isFileRef,
595
+ isFilledValue,
596
+ isFilterCondition,
597
+ isFilterGroup,
598
+ isFormFieldTypeAllowed,
599
+ isFormQuestionVisible,
600
+ isGeoPoint as isGeoPoint2,
601
+ isNodeStoreColumnType,
602
+ isNodeStoreFieldType,
603
+ isSelectColor,
604
+ isValidOperator,
605
+ isYDocColumnType,
606
+ isYDocFieldType,
607
+ moveField,
608
+ moveRow,
609
+ moveSelectOption,
610
+ moveView,
611
+ operatorRequiresValue,
612
+ parseCSV,
613
+ parseCSVLine,
614
+ parseDatabaseSchemaIRI,
615
+ parseJSON,
616
+ parseRow,
617
+ parseValue,
618
+ parseVersion,
619
+ pruneVersionHistory,
620
+ queryRows,
621
+ rebalanceDatabase,
622
+ remapViewColumnIds,
623
+ removeSort,
624
+ removeViewSort,
625
+ renameExtensionField,
626
+ reorderColumn,
627
+ reorderViewColumns,
628
+ requiresDateColumn,
629
+ resolveRowHeightPx,
630
+ rowHeightLabel,
631
+ setColumnWidth,
632
+ setFieldHidden,
633
+ setMeta,
634
+ setViewFieldOrder,
635
+ setViewFieldWidth,
636
+ setViewFilters,
637
+ setViewFilters2,
638
+ setViewGroupBy,
639
+ setViewGroupBy2,
640
+ setViewSorts,
641
+ setViewSorts2,
642
+ setVisibleColumns,
643
+ setupDatabase,
644
+ setupNewDatabase,
645
+ showColumn,
646
+ sortRows,
647
+ submissionRowId,
648
+ summaryFunctionLabel,
649
+ supportsGrouping,
650
+ toCellProperties,
651
+ toColumnDefinitions,
652
+ toFieldNode,
653
+ toSelectOptionNode,
654
+ toggleGroupCollapsed,
655
+ toggleGroupCollapsed2,
656
+ toggleSortDirection,
657
+ toggleViewGroupCollapsed,
658
+ updateCell,
659
+ updateCells,
660
+ updateColumn,
661
+ updateField,
662
+ updateSelectOption,
663
+ updateView,
664
+ updateView2,
665
+ validateFormSubmission,
666
+ validateJsonData,
667
+ validateRollupConfig,
668
+ visibleFormQuestions
669
+ } from "./chunk-56EXPOJ4.js";
567
670
  import {
568
671
  EXT_PREFIX,
569
672
  extKey,
@@ -599,57 +702,6 @@ import {
599
702
  DatabaseViewSchema
600
703
  } from "./chunk-UFV5QWCL.js";
601
704
  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
705
  import {
654
706
  applyNodeQueryDescriptor,
655
707
  createNodeQueryDescriptor,
@@ -665,58 +717,6 @@ import {
665
717
  withoutNodeQueryMaterializedView,
666
718
  withoutNodeQueryPagination
667
719
  } from "./chunk-WOEFYS7Y.js";
668
- import {
669
- evaluateLedgerWrite,
670
- foldAccountRecord,
671
- ledgerAccountId,
672
- ledgerWriteKind
673
- } from "./chunk-3UOUVEZW.js";
674
- import {
675
- ACCOUNT_RECORD_SCHEMA_IRI,
676
- AccountRecordSchema,
677
- DEVICE_RECORD_SCHEMA_IRI,
678
- DeviceRecordSchema,
679
- RECOVERY_RECORD_SCHEMA_IRI,
680
- REVOCATION_RECORD_SCHEMA_IRI,
681
- RecoveryRecordSchema,
682
- RevocationRecordSchema,
683
- accountRecordId,
684
- deviceRecipientExpander,
685
- deviceRecordId,
686
- isDeviceAuthorized,
687
- recoveryRecordId,
688
- resolveActiveDevices,
689
- revocationRecordId,
690
- revokedSubjects
691
- } from "./chunk-5ECIKN6Z.js";
692
- import {
693
- PresenceSummarySchema,
694
- SYSTEM_NAMESPACE_KINDS,
695
- SYSTEM_SCHEMA_BASE_IRIS,
696
- SYSTEM_SCHEMA_IRIS,
697
- SchemaCompatibilitySchema,
698
- SchemaDefinitionSchema,
699
- SyncPolicySchema,
700
- buildSystemNamespace,
701
- buildSystemNodeId,
702
- computeSchemaDefinitionContentHash,
703
- createSchemaDefinitionSigningPayload,
704
- isSystemNamespaceResource,
705
- isSystemSchemaIri,
706
- parseSystemNamespaceResource,
707
- resolveSchemaAuthority,
708
- validateSchemaDefinitionNode
709
- } from "./chunk-ZNHLH7SC.js";
710
- import {
711
- clearLocalPresence,
712
- createAwareness,
713
- generateUserColor,
714
- getAllPresences,
715
- getLocalClientId,
716
- getRemotePresences,
717
- onPresenceChange,
718
- setLocalPresence
719
- } from "./chunk-7PDRDSFH.js";
720
720
  import {
721
721
  SPACE_MEMBERSHIP_SCHEMA_IRI,
722
722
  SpaceMembershipSchema,
@@ -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
- Doc as YDoc,
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
  };