@loro-dev/flock-wasm 0.1.5 → 0.2.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/README.md CHANGED
@@ -135,7 +135,6 @@ import {
135
135
  type VersionVector,
136
136
  type VersionVectorEntry,
137
137
  type ExportBundle,
138
- type ImportReport,
139
138
  type ScanOptions,
140
139
  type ScanRow,
141
140
  type ScanBound,
@@ -613,27 +612,26 @@ const signed = await flock.exportJson({
613
612
  });
614
613
  ```
615
614
 
616
- #### `importJson(bundle: ExportBundle): ImportReport`
615
+ #### `importJson(bundle: ExportBundle): void`
617
616
 
618
617
  Imports a JSON bundle, merging entries using LWW semantics.
619
618
 
620
619
  - **`bundle`**: An `ExportBundle` from `exportJson()`.
621
- - **Returns**: `ImportReport` with `{ accepted: number, skipped: Array<{ key, reason }> }`.
622
- - **`accepted` counts records processed**, not records that changed state. Re-importing the same bundle may still report a positive `accepted` count even though no state changed and no events are emitted. Do not use `accepted` as a reliable indicator of whether new data was applied — use event listeners for that.
623
- - **Events**: Emits event batches for newly accepted entries.
620
+ - **Returns**: `void`.
621
+ - **Events**: Emits event batches for newly applied entries.
624
622
  - **Effect on debounce**: If `autoDebounceCommit` is active, any pending local events are flushed before the import events are delivered.
625
623
 
626
- #### `importJson(options: ImportOptions): Promise<ImportReport>`
624
+ #### `importJson(options: ImportOptions): Promise<void>`
627
625
 
628
626
  Imports with preprocessing hooks (async).
629
627
 
630
628
  - **`options.bundle`**: The export bundle.
631
629
  - **`options.hooks.preprocess`**: Async function `(context, payload) => ImportDecision` to validate each entry before import.
632
- - **Returns**: `Promise<ImportReport>`.
630
+ - **Returns**: `Promise<void>`.
633
631
  - **Use case**: Validate signatures, check authorization, or reject untrusted entries.
634
632
 
635
633
  ```ts
636
- const report = await flock.importJson({
634
+ await flock.importJson({
637
635
  bundle,
638
636
  hooks: {
639
637
  preprocess: async (ctx, payload) => {
@@ -644,15 +642,14 @@ const report = await flock.importJson({
644
642
  },
645
643
  },
646
644
  });
647
- console.log(report.skipped); // entries rejected by the hook
648
645
  ```
649
646
 
650
- #### `importJsonStr(bundle: string): ImportReport`
647
+ #### `importJsonStr(bundle: string): void`
651
648
 
652
649
  Convenience method that parses a JSON string and imports it.
653
650
 
654
651
  - **`bundle`**: JSON string representation of an `ExportBundle`.
655
- - **Returns**: `ImportReport`.
652
+ - **Returns**: `void`.
656
653
  - **Use case**: Import directly from a network response or file read without manual parsing.
657
654
 
658
655
  #### `kvToJson(): ExportBundle`
@@ -714,7 +711,7 @@ type ImportOptions = {
714
711
  - **`context`**: `{ key: KeyPart[], clock: EntryClock, raw: ExportRecord }`.
715
712
  - **`payload`**: `{ data?: Value, metadata?: MetadataMap }` — a cloned copy for inspection (not mutation).
716
713
  - **`ImportDecision`**: Return `{ accept: true }`, `{ accept: false, reason: string }`, or `void` (treated as accept).
717
- - **Behavior**: Called once per entry before import. Rejected entries are excluded from the merge and reported in `ImportReport.skipped`.
714
+ - **Behavior**: Called once per entry before import. Rejected entries are excluded from the merge.
718
715
  - **Use case**: Validate signatures, enforce ACLs, or reject entries from untrusted peers.
719
716
 
720
717
  ---
@@ -937,12 +934,7 @@ type ExportBundle = {
937
934
  entries: Record<string, ExportRecord>; // Key (stringified) → record
938
935
  };
939
936
 
940
- type ImportReport = {
941
- accepted: number; // Number of entries processed (not necessarily changed)
942
- skipped: Array<{ key: KeyPart[]; reason: string }>; // Rejected entries with reasons
943
- };
944
937
  ```
945
-
946
938
  ### Hook Types
947
939
 
948
940
  ```ts
@@ -1084,8 +1076,7 @@ const bobVersion = bob.version();
1084
1076
  const delta = alice.exportJson(bobVersion);
1085
1077
 
1086
1078
  // Step 3: Bob imports the delta
1087
- const report = bob.importJson(delta);
1088
- console.log(`Imported ${report.accepted} new entries`);
1079
+ bob.importJson(delta);
1089
1080
 
1090
1081
  // Step 4: Reverse direction
1091
1082
  const aliceVersion = alice.version();
@@ -231,20 +231,20 @@ function getArrayU8FromWasm0(ptr, len) {
231
231
  return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
232
232
  }
233
233
 
234
- function _assertClass(instance, klass) {
235
- if (!(instance instanceof klass)) {
236
- throw new Error(`expected instance of ${klass.name}`);
237
- }
238
- }
239
-
240
234
  function passArray8ToWasm0(arg, malloc) {
241
235
  const ptr = malloc(arg.length * 1, 1) >>> 0;
242
236
  getUint8ArrayMemory0().set(arg, ptr / 1);
243
237
  WASM_VECTOR_LEN = arg.length;
244
238
  return ptr;
245
239
  }
240
+
241
+ function _assertClass(instance, klass) {
242
+ if (!(instance instanceof klass)) {
243
+ throw new Error(`expected instance of ${klass.name}`);
244
+ }
245
+ }
246
246
  function __wbg_adapter_56(arg0, arg1, arg2) {
247
- wasm.closure43_externref_shim(arg0, arg1, arg2);
247
+ wasm.closure32_externref_shim(arg0, arg1, arg2);
248
248
  }
249
249
 
250
250
  const RawFlockFinalization = (typeof FinalizationRegistry === 'undefined')
@@ -333,6 +333,17 @@ export class RawFlock {
333
333
  }
334
334
  return takeFromExternrefTable0(ret[0]);
335
335
  }
336
+ /**
337
+ * @param {Uint8Array} bytes
338
+ */
339
+ importFile(bytes) {
340
+ const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
341
+ const len0 = WASM_VECTOR_LEN;
342
+ const ret = wasm.rawflock_importFile(this.__wbg_ptr, ptr0, len0);
343
+ if (ret[1]) {
344
+ throw takeFromExternrefTable0(ret[0]);
345
+ }
346
+ }
336
347
  /**
337
348
  * Imports a JSON bundle into this flock instance.
338
349
  *
@@ -340,22 +351,16 @@ export class RawFlock {
340
351
  *
341
352
  * * `bundle` - The export bundle to import
342
353
  *
343
- * # Returns
344
- *
345
- * An import report containing counts of accepted and skipped entries.
346
- *
347
354
  * # Errors
348
355
  *
349
356
  * Returns an error if the bundle is invalid or import fails.
350
357
  * @param {any} bundle
351
- * @returns {any}
352
358
  */
353
359
  importJson(bundle) {
354
360
  const ret = wasm.rawflock_importJson(this.__wbg_ptr, bundle);
355
- if (ret[2]) {
356
- throw takeFromExternrefTable0(ret[1]);
361
+ if (ret[1]) {
362
+ throw takeFromExternrefTable0(ret[0]);
357
363
  }
358
- return takeFromExternrefTable0(ret[0]);
359
364
  }
360
365
  /**
361
366
  * Sets a new peer ID for this flock instance.
@@ -563,23 +568,17 @@ export class RawFlock {
563
568
  *
564
569
  * * `other` - The other flock instance to merge from
565
570
  *
566
- * # Returns
567
- *
568
- * An import report containing counts of accepted and skipped entries.
569
- *
570
571
  * # Errors
571
572
  *
572
573
  * Returns an error if the merge operation fails.
573
574
  * @param {RawFlock} other
574
- * @returns {any}
575
575
  */
576
576
  merge(other) {
577
577
  _assertClass(other, RawFlock);
578
578
  const ret = wasm.rawflock_merge(this.__wbg_ptr, other.__wbg_ptr);
579
- if (ret[2]) {
580
- throw takeFromExternrefTable0(ret[1]);
579
+ if (ret[1]) {
580
+ throw takeFromExternrefTable0(ret[0]);
581
581
  }
582
- return takeFromExternrefTable0(ret[0]);
583
582
  }
584
583
  /**
585
584
  * Deletes the value at the specified key (creates a tombstone).
@@ -637,6 +636,13 @@ export class RawFlock {
637
636
  }
638
637
  return takeFromExternrefTable0(ret[0]);
639
638
  }
639
+ /**
640
+ * @returns {boolean}
641
+ */
642
+ isEmpty() {
643
+ const ret = wasm.rawflock_isEmpty(this.__wbg_ptr);
644
+ return ret !== 0;
645
+ }
640
646
  /**
641
647
  * Creates a new flock instance from a file bytes array.
642
648
  *
@@ -993,8 +999,8 @@ function __wbg_get_imports() {
993
999
  const ret = false;
994
1000
  return ret;
995
1001
  };
996
- imports.wbg.__wbindgen_closure_wrapper303 = function(arg0, arg1, arg2) {
997
- const ret = makeMutClosure(arg0, arg1, 44, __wbg_adapter_56);
1002
+ imports.wbg.__wbindgen_closure_wrapper229 = function(arg0, arg1, arg2) {
1003
+ const ret = makeMutClosure(arg0, arg1, 33, __wbg_adapter_56);
998
1004
  return ret;
999
1005
  };
1000
1006
  imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
package/base64/index.d.ts CHANGED
@@ -67,13 +67,6 @@ export type ImportDecision = ImportAccept | ImportSkip | ImportPayload | void;
67
67
  export type ImportHooks = {
68
68
  preprocess?: (context: ImportHookContext, payload: ImportPayload) => MaybePromise<ImportDecision>;
69
69
  };
70
- export type ImportReport = {
71
- accepted: number;
72
- skipped: Array<{
73
- key: KeyPart[];
74
- reason: string;
75
- }>;
76
- };
77
70
  export type PutPayload = ExportPayload;
78
71
  export type PutHookContext = {
79
72
  key: KeyPart[];
@@ -126,6 +119,7 @@ export declare class Flock {
126
119
  private static fromInner;
127
120
  static fromJson(bundle: ExportBundle, peerId: string): Flock;
128
121
  static fromFile(bytes: Uint8Array, peerId?: string): Flock;
122
+ isEmpty(): boolean;
129
123
  checkInvariants(): void;
130
124
  setPeerId(peerId: string): void;
131
125
  private putWithMetaInternal;
@@ -183,9 +177,10 @@ export declare class Flock {
183
177
  exportJson(options: ExportOptions): Promise<ExportBundle>;
184
178
  private importJsonInternal;
185
179
  private importJsonWithHooks;
186
- importJson(bundle: ExportBundle): ImportReport;
187
- importJson(options: ImportOptions): Promise<ImportReport>;
188
- importJsonStr(bundle: string): ImportReport;
180
+ importJson(bundle: ExportBundle): void;
181
+ importJson(options: ImportOptions): Promise<void>;
182
+ importFile(bytes: Uint8Array): void;
183
+ importJsonStr(bundle: string): void;
189
184
  getMaxPhysicalTime(): number;
190
185
  peerId(): string;
191
186
  kvToJson(): ExportBundle;
package/base64/index.js CHANGED
@@ -502,20 +502,6 @@ function normalizeImportDecision(decision) {
502
502
  }
503
503
  return { accept: true };
504
504
  }
505
- function decodeImportReport(raw) {
506
- if (!raw || typeof raw !== "object") {
507
- return { accepted: 0, skipped: [] };
508
- }
509
- const report = raw;
510
- const accepted = typeof report.accepted === "number" ? report.accepted : 0;
511
- const skippedRaw = Array.isArray(report.skipped) ? report.skipped : [];
512
- const skipped = skippedRaw.map((entry) => {
513
- const key = entry && Array.isArray(entry.key) ? entry.key : [];
514
- const reason = entry && typeof entry.reason === "string" ? entry.reason : "unknown";
515
- return { key, reason };
516
- });
517
- return { accepted, skipped };
518
- }
519
505
  function cloneBundle(bundle) {
520
506
  const next = { version: bundle.version, entries: {} };
521
507
  for (const [key, record] of Object.entries(bundle.entries)) {
@@ -576,6 +562,9 @@ export class Flock {
576
562
  const inner = RawFlock.fromFile(normalizePeerId(peerId), bytes);
577
563
  return Flock.fromInner(inner);
578
564
  }
565
+ isEmpty() {
566
+ return this.inner.isEmpty();
567
+ }
579
568
  checkInvariants() {
580
569
  void this.version();
581
570
  void this.inclusiveVersion();
@@ -647,7 +636,7 @@ export class Flock {
647
636
  }
648
637
  merge(other) {
649
638
  this.eventBatcher.beforeImport();
650
- void this.inner.merge(other.inner);
639
+ this.inner.merge(other.inner);
651
640
  }
652
641
  /**
653
642
  * Returns the exclusive/visible version vector.
@@ -706,13 +695,11 @@ export class Flock {
706
695
  }
707
696
  importJsonInternal(bundle) {
708
697
  this.eventBatcher.beforeImport();
709
- const report = this.inner.importJson(bundle);
710
- return decodeImportReport(report);
698
+ this.inner.importJson(bundle);
711
699
  }
712
700
  async importJsonWithHooks(options) {
713
701
  const preprocess = options.hooks?.preprocess;
714
702
  const working = preprocess ? cloneBundle(options.bundle) : options.bundle;
715
- const skippedByHooks = [];
716
703
  if (preprocess) {
717
704
  for (const key of Object.keys(working.entries)) {
718
705
  const record = working.entries[key];
@@ -724,18 +711,13 @@ export class Flock {
724
711
  const decision = await preprocess(context, clonePayload(basePayload));
725
712
  const normalized = normalizeImportDecision(decision);
726
713
  if (!normalized.accept) {
727
- skippedByHooks.push({ key: context.key, reason: normalized.reason });
728
714
  delete working.entries[key];
729
715
  continue;
730
716
  }
731
717
  working.entries[key] = buildRecord(record.c, basePayload);
732
718
  }
733
719
  }
734
- const coreReport = this.importJsonInternal(working);
735
- return {
736
- accepted: coreReport.accepted,
737
- skipped: skippedByHooks.concat(coreReport.skipped),
738
- };
720
+ this.importJsonInternal(working);
739
721
  }
740
722
  importJson(arg) {
741
723
  if (isImportOptions(arg)) {
@@ -743,9 +725,13 @@ export class Flock {
743
725
  }
744
726
  return this.importJsonInternal(arg);
745
727
  }
728
+ importFile(bytes) {
729
+ this.eventBatcher.beforeImport();
730
+ this.inner.importFile(bytes);
731
+ }
746
732
  importJsonStr(bundle) {
747
733
  const parsed = JSON.parse(bundle);
748
- return this.importJson(parsed);
734
+ this.importJson(parsed);
749
735
  }
750
736
  getMaxPhysicalTime() {
751
737
  return Number(this.inner.getMaxPhysicalTime());
package/base64/wasm.d.ts CHANGED
@@ -2,6 +2,7 @@ export declare class RawFlock {
2
2
  constructor(peerId: string);
3
3
  static fromJson(bundle: unknown, peerId: string): RawFlock;
4
4
  static fromFile(peerId: string, bytes: Uint8Array): RawFlock;
5
+ isEmpty(): boolean;
5
6
  peerId(): string;
6
7
  setPeerId(peerId: string): void;
7
8
  getMaxPhysicalTime(): number;
@@ -21,8 +22,9 @@ export declare class RawFlock {
21
22
  pruneTombstonesBefore?: number,
22
23
  peerId?: string,
23
24
  ): unknown;
24
- importJson(bundle: unknown): unknown;
25
- merge(other: RawFlock): unknown;
25
+ importJson(bundle: unknown): void;
26
+ importFile(bytes: Uint8Array): void;
27
+ merge(other: RawFlock): void;
26
28
  version(): unknown;
27
29
  inclusiveVersion(): unknown;
28
30
  exportFile(): Uint8Array;