@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 +10 -19
- package/base64/flock_wasm.js +31 -25
- package/base64/index.d.ts +5 -10
- package/base64/index.js +11 -25
- package/base64/wasm.d.ts +4 -2
- package/base64/wasm.js +1 -1
- package/bundler/flock_wasm.d.ts +4 -10
- package/bundler/flock_wasm_bg.js +31 -25
- package/bundler/flock_wasm_bg.wasm +0 -0
- package/bundler/flock_wasm_bg.wasm.d.ts +5 -3
- package/bundler/index.d.ts +5 -10
- package/bundler/index.js +11 -25
- package/bundler/wasm.d.ts +4 -2
- package/nodejs/flock_wasm.d.ts +4 -10
- package/nodejs/flock_wasm.js +31 -25
- package/nodejs/flock_wasm_bg.wasm +0 -0
- package/nodejs/flock_wasm_bg.wasm.d.ts +5 -3
- package/nodejs/index.d.ts +5 -10
- package/nodejs/index.js +11 -25
- package/nodejs/wasm.d.ts +4 -2
- package/package.json +1 -1
- package/web/flock_wasm.d.ts +9 -13
- package/web/flock_wasm.js +31 -25
- package/web/flock_wasm_bg.wasm +0 -0
- package/web/flock_wasm_bg.wasm.d.ts +5 -3
- package/web/index.d.ts +5 -10
- package/web/index.js +11 -25
- package/web/wasm.d.ts +4 -2
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):
|
|
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**: `
|
|
622
|
-
-
|
|
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<
|
|
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<
|
|
630
|
+
- **Returns**: `Promise<void>`.
|
|
633
631
|
- **Use case**: Validate signatures, check authorization, or reject untrusted entries.
|
|
634
632
|
|
|
635
633
|
```ts
|
|
636
|
-
|
|
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):
|
|
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**: `
|
|
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
|
|
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
|
-
|
|
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();
|
package/base64/flock_wasm.js
CHANGED
|
@@ -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.
|
|
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[
|
|
356
|
-
throw takeFromExternrefTable0(ret[
|
|
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[
|
|
580
|
-
throw takeFromExternrefTable0(ret[
|
|
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.
|
|
997
|
-
const ret = makeMutClosure(arg0, arg1,
|
|
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):
|
|
187
|
-
importJson(options: ImportOptions): Promise<
|
|
188
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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):
|
|
25
|
-
|
|
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;
|