loro-repo 0.5.2 → 0.5.3
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.cjs +175 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +175 -46
- package/dist/index.js.map +1 -1
- package/dist/storage/filesystem.cjs +43 -10
- package/dist/storage/filesystem.cjs.map +1 -1
- package/dist/storage/filesystem.d.cts +6 -1
- package/dist/storage/filesystem.d.ts +6 -1
- package/dist/storage/filesystem.js +43 -10
- package/dist/storage/filesystem.js.map +1 -1
- package/dist/storage/indexeddb.cjs +47 -9
- package/dist/storage/indexeddb.cjs.map +1 -1
- package/dist/storage/indexeddb.d.cts +5 -0
- package/dist/storage/indexeddb.d.ts +5 -0
- package/dist/storage/indexeddb.js +47 -9
- package/dist/storage/indexeddb.js.map +1 -1
- package/dist/types.d.cts +5 -0
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ declare class LoroRepo<Meta extends JsonObject = JsonObject> {
|
|
|
17
17
|
private readonly flockHydrator;
|
|
18
18
|
private readonly state;
|
|
19
19
|
private readonly syncRunner;
|
|
20
|
+
private readonly metaPersister;
|
|
20
21
|
private constructor();
|
|
21
22
|
static create<Meta extends JsonObject = JsonObject>(options: LoroRepoOptions): Promise<LoroRepo<Meta>>;
|
|
22
23
|
/**
|
|
@@ -85,7 +86,6 @@ declare class LoroRepo<Meta extends JsonObject = JsonObject> {
|
|
|
85
86
|
listAssets(docId: string): Promise<RepoAssetMetadata[]>;
|
|
86
87
|
ensureAsset(assetId: AssetId): Promise<AssetDownload>;
|
|
87
88
|
gcAssets(options?: GarbageCollectionOptions): Promise<number>;
|
|
88
|
-
private persistMeta;
|
|
89
89
|
get destroyed(): boolean;
|
|
90
90
|
destroy(): Promise<void>;
|
|
91
91
|
}
|
package/dist/index.js
CHANGED
|
@@ -65,7 +65,6 @@ var DocManager = class {
|
|
|
65
65
|
docFrontierDebounceMs;
|
|
66
66
|
getMetaFlock;
|
|
67
67
|
eventBus;
|
|
68
|
-
persistMeta;
|
|
69
68
|
docs = /* @__PURE__ */ new Map();
|
|
70
69
|
docSubscriptions = /* @__PURE__ */ new Map();
|
|
71
70
|
docFrontierUpdates = /* @__PURE__ */ new Map();
|
|
@@ -75,7 +74,6 @@ var DocManager = class {
|
|
|
75
74
|
this.docFrontierDebounceMs = options.docFrontierDebounceMs;
|
|
76
75
|
this.getMetaFlock = options.getMetaFlock;
|
|
77
76
|
this.eventBus = options.eventBus;
|
|
78
|
-
this.persistMeta = options.persistMeta;
|
|
79
77
|
}
|
|
80
78
|
async openPersistedDoc(docId) {
|
|
81
79
|
return await this.ensureDoc(docId);
|
|
@@ -136,16 +134,13 @@ var DocManager = class {
|
|
|
136
134
|
], f.counter);
|
|
137
135
|
mutated = true;
|
|
138
136
|
}
|
|
139
|
-
if (mutated) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
]);
|
|
147
|
-
}
|
|
148
|
-
await this.persistMeta();
|
|
137
|
+
if (mutated) for (const [peer, counter] of existingFrontiers) {
|
|
138
|
+
const docCounterEnd = vv.get(peer);
|
|
139
|
+
if (docCounterEnd != null && docCounterEnd > counter) metaFlock.delete([
|
|
140
|
+
"f",
|
|
141
|
+
docId,
|
|
142
|
+
peer
|
|
143
|
+
]);
|
|
149
144
|
}
|
|
150
145
|
const by = this.eventBus.resolveEventBy(defaultBy);
|
|
151
146
|
this.eventBus.emit({
|
|
@@ -499,12 +494,10 @@ function matchesQuery(docId, _metadata, query) {
|
|
|
499
494
|
var MetadataManager = class {
|
|
500
495
|
getMetaFlock;
|
|
501
496
|
eventBus;
|
|
502
|
-
persistMeta;
|
|
503
497
|
state;
|
|
504
498
|
constructor(options) {
|
|
505
499
|
this.getMetaFlock = options.getMetaFlock;
|
|
506
500
|
this.eventBus = options.eventBus;
|
|
507
|
-
this.persistMeta = options.persistMeta;
|
|
508
501
|
this.state = options.state;
|
|
509
502
|
}
|
|
510
503
|
getDocIds() {
|
|
@@ -561,7 +554,6 @@ var MetadataManager = class {
|
|
|
561
554
|
if (rawValue === void 0) continue;
|
|
562
555
|
if (jsonEquals(base ? base[key] : void 0, rawValue)) continue;
|
|
563
556
|
const storageKey = key === "tombstone" ? "$tombstone" : key;
|
|
564
|
-
console.log("upserting", rawValue);
|
|
565
557
|
this.metaFlock.put([
|
|
566
558
|
"m",
|
|
567
559
|
docId,
|
|
@@ -576,7 +568,6 @@ var MetadataManager = class {
|
|
|
576
568
|
return;
|
|
577
569
|
}
|
|
578
570
|
this.state.metadata.set(docId, next);
|
|
579
|
-
await this.persistMeta();
|
|
580
571
|
this.eventBus.emit({
|
|
581
572
|
kind: "doc-metadata",
|
|
582
573
|
docId,
|
|
@@ -702,7 +693,6 @@ var AssetManager = class {
|
|
|
702
693
|
assetTransport;
|
|
703
694
|
getMetaFlock;
|
|
704
695
|
eventBus;
|
|
705
|
-
persistMeta;
|
|
706
696
|
state;
|
|
707
697
|
get docAssets() {
|
|
708
698
|
return this.state.docAssets;
|
|
@@ -721,7 +711,6 @@ var AssetManager = class {
|
|
|
721
711
|
this.assetTransport = options.assetTransport;
|
|
722
712
|
this.getMetaFlock = options.getMetaFlock;
|
|
723
713
|
this.eventBus = options.eventBus;
|
|
724
|
-
this.persistMeta = options.persistMeta;
|
|
725
714
|
this.state = options.state;
|
|
726
715
|
}
|
|
727
716
|
async uploadAsset(params) {
|
|
@@ -758,7 +747,6 @@ var AssetManager = class {
|
|
|
758
747
|
if (metadataMutated) {
|
|
759
748
|
existing.metadata = metadata$1;
|
|
760
749
|
this.metaFlock.put(["a", assetId], assetMetaToJson(metadata$1));
|
|
761
|
-
await this.persistMeta();
|
|
762
750
|
this.eventBus.emit({
|
|
763
751
|
kind: "asset-metadata",
|
|
764
752
|
asset: this.createAssetDownload(assetId, metadata$1, bytes),
|
|
@@ -795,7 +783,6 @@ var AssetManager = class {
|
|
|
795
783
|
this.markAssetAsOrphan(assetId, metadata);
|
|
796
784
|
this.updateDocAssetMetadata(assetId, metadata);
|
|
797
785
|
this.metaFlock.put(["a", assetId], assetMetaToJson(metadata));
|
|
798
|
-
await this.persistMeta();
|
|
799
786
|
this.eventBus.emit({
|
|
800
787
|
kind: "asset-metadata",
|
|
801
788
|
asset: this.createAssetDownload(assetId, metadata, storedBytes),
|
|
@@ -854,7 +841,6 @@ var AssetManager = class {
|
|
|
854
841
|
existing.metadata = nextMetadata;
|
|
855
842
|
metadata = nextMetadata;
|
|
856
843
|
this.metaFlock.put(["a", assetId], assetMetaToJson(metadata));
|
|
857
|
-
await this.persistMeta();
|
|
858
844
|
this.eventBus.emit({
|
|
859
845
|
kind: "asset-metadata",
|
|
860
846
|
asset: this.createAssetDownload(assetId, metadata, bytes),
|
|
@@ -901,7 +887,6 @@ var AssetManager = class {
|
|
|
901
887
|
docId,
|
|
902
888
|
assetId
|
|
903
889
|
], true);
|
|
904
|
-
await this.persistMeta();
|
|
905
890
|
this.eventBus.emit({
|
|
906
891
|
kind: "asset-link",
|
|
907
892
|
docId,
|
|
@@ -926,7 +911,6 @@ var AssetManager = class {
|
|
|
926
911
|
assetId
|
|
927
912
|
]);
|
|
928
913
|
this.removeDocAssetReference(assetId, docId);
|
|
929
|
-
await this.persistMeta();
|
|
930
914
|
this.eventBus.emit({
|
|
931
915
|
kind: "asset-unlink",
|
|
932
916
|
docId,
|
|
@@ -1210,7 +1194,6 @@ var AssetManager = class {
|
|
|
1210
1194
|
this.assets.set(assetId, { metadata });
|
|
1211
1195
|
this.updateDocAssetMetadata(assetId, metadata);
|
|
1212
1196
|
this.metaFlock.put(["a", assetId], assetMetaToJson(metadata));
|
|
1213
|
-
await this.persistMeta();
|
|
1214
1197
|
if (this.storage) await this.storage.save({
|
|
1215
1198
|
type: "asset",
|
|
1216
1199
|
assetId,
|
|
@@ -1366,7 +1349,6 @@ var SyncRunner = class {
|
|
|
1366
1349
|
flockHydrator;
|
|
1367
1350
|
getMetaFlock;
|
|
1368
1351
|
replaceMetaFlock;
|
|
1369
|
-
persistMeta;
|
|
1370
1352
|
readyPromise;
|
|
1371
1353
|
metaRoomSubscription;
|
|
1372
1354
|
unsubscribeMetaFlock;
|
|
@@ -1381,7 +1363,6 @@ var SyncRunner = class {
|
|
|
1381
1363
|
this.flockHydrator = options.flockHydrator;
|
|
1382
1364
|
this.getMetaFlock = options.getMetaFlock;
|
|
1383
1365
|
this.replaceMetaFlock = options.mergeFlock;
|
|
1384
|
-
this.persistMeta = options.persistMeta;
|
|
1385
1366
|
}
|
|
1386
1367
|
async ready() {
|
|
1387
1368
|
if (!this.readyPromise) this.readyPromise = this.initialize();
|
|
@@ -1403,7 +1384,6 @@ var SyncRunner = class {
|
|
|
1403
1384
|
if (!(await this.transport.syncMeta(this.metaFlock)).ok) throw new Error("Metadata sync failed");
|
|
1404
1385
|
if (recordedEvents.length > 0) this.flockHydrator.applyEvents(recordedEvents, "sync");
|
|
1405
1386
|
else this.flockHydrator.hydrateAll("sync");
|
|
1406
|
-
await this.persistMeta();
|
|
1407
1387
|
} finally {
|
|
1408
1388
|
unsubscribe();
|
|
1409
1389
|
this.eventBus.popEventBy();
|
|
@@ -1449,7 +1429,6 @@ var SyncRunner = class {
|
|
|
1449
1429
|
subscription.firstSyncedWithRemote.then(async () => {
|
|
1450
1430
|
const by = this.eventBus.resolveEventBy("live");
|
|
1451
1431
|
this.flockHydrator.hydrateAll(by);
|
|
1452
|
-
await this.persistMeta();
|
|
1453
1432
|
}).catch(logAsyncError("meta room first sync"));
|
|
1454
1433
|
return wrapped;
|
|
1455
1434
|
}
|
|
@@ -1505,7 +1484,6 @@ var SyncRunner = class {
|
|
|
1505
1484
|
const by = this.eventBus.resolveEventBy("live");
|
|
1506
1485
|
(async () => {
|
|
1507
1486
|
this.flockHydrator.applyEvents(batch.events, by);
|
|
1508
|
-
await this.persistMeta();
|
|
1509
1487
|
})().catch(logAsyncError("meta live monitor sync"));
|
|
1510
1488
|
});
|
|
1511
1489
|
}
|
|
@@ -1527,8 +1505,154 @@ function createRepoState() {
|
|
|
1527
1505
|
}
|
|
1528
1506
|
|
|
1529
1507
|
//#endregion
|
|
1530
|
-
//#region src/
|
|
1508
|
+
//#region src/internal/meta-persister.ts
|
|
1531
1509
|
const textEncoder = new TextEncoder();
|
|
1510
|
+
const DEFAULT_META_PERSIST_DEBOUNCE_MS = 5e3;
|
|
1511
|
+
var MetaPersister = class {
|
|
1512
|
+
getMetaFlock;
|
|
1513
|
+
storage;
|
|
1514
|
+
debounceMs;
|
|
1515
|
+
lastPersistedVersion;
|
|
1516
|
+
unsubscribe;
|
|
1517
|
+
flushPromise = Promise.resolve();
|
|
1518
|
+
flushTimer;
|
|
1519
|
+
forceFullOnNextFlush = false;
|
|
1520
|
+
destroyed = false;
|
|
1521
|
+
constructor(options) {
|
|
1522
|
+
this.getMetaFlock = options.getMetaFlock;
|
|
1523
|
+
this.storage = options.storage;
|
|
1524
|
+
const configuredDebounce = options.debounceMs;
|
|
1525
|
+
this.debounceMs = typeof configuredDebounce === "number" && Number.isFinite(configuredDebounce) && configuredDebounce >= 0 ? configuredDebounce : DEFAULT_META_PERSIST_DEBOUNCE_MS;
|
|
1526
|
+
}
|
|
1527
|
+
start(initialVersion) {
|
|
1528
|
+
this.lastPersistedVersion = initialVersion;
|
|
1529
|
+
if (this.unsubscribe) return;
|
|
1530
|
+
this.unsubscribe = this.metaFlock.subscribe(() => {
|
|
1531
|
+
this.scheduleFlush();
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
async destroy() {
|
|
1535
|
+
this.destroyed = true;
|
|
1536
|
+
if (this.flushTimer) {
|
|
1537
|
+
clearTimeout(this.flushTimer);
|
|
1538
|
+
this.flushTimer = void 0;
|
|
1539
|
+
}
|
|
1540
|
+
if (this.unsubscribe) {
|
|
1541
|
+
this.unsubscribe();
|
|
1542
|
+
this.unsubscribe = void 0;
|
|
1543
|
+
}
|
|
1544
|
+
await this.flushNow();
|
|
1545
|
+
}
|
|
1546
|
+
async flushNow(forceFull = false) {
|
|
1547
|
+
if (this.flushTimer) {
|
|
1548
|
+
clearTimeout(this.flushTimer);
|
|
1549
|
+
this.flushTimer = void 0;
|
|
1550
|
+
}
|
|
1551
|
+
await this.flush(forceFull);
|
|
1552
|
+
}
|
|
1553
|
+
scheduleFlush() {
|
|
1554
|
+
if (this.destroyed) return;
|
|
1555
|
+
if (this.debounceMs === 0) {
|
|
1556
|
+
this.flush();
|
|
1557
|
+
return;
|
|
1558
|
+
}
|
|
1559
|
+
if (this.flushTimer) clearTimeout(this.flushTimer);
|
|
1560
|
+
this.flushTimer = setTimeout(() => {
|
|
1561
|
+
this.flushTimer = void 0;
|
|
1562
|
+
this.flush();
|
|
1563
|
+
}, this.debounceMs);
|
|
1564
|
+
}
|
|
1565
|
+
async flush(forceFull = false) {
|
|
1566
|
+
if (forceFull) this.forceFullOnNextFlush = true;
|
|
1567
|
+
const run = this.flushPromise.catch(() => {}).then(() => this.flushInternal());
|
|
1568
|
+
this.flushPromise = run;
|
|
1569
|
+
await run;
|
|
1570
|
+
}
|
|
1571
|
+
async flushInternal() {
|
|
1572
|
+
const flock = this.metaFlock;
|
|
1573
|
+
const currentVersion = flock.version();
|
|
1574
|
+
if (this.lastPersistedVersion && this.versionsEqual(currentVersion, this.lastPersistedVersion)) {
|
|
1575
|
+
this.forceFullOnNextFlush = false;
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1578
|
+
const baseline = this.forceFullOnNextFlush ? void 0 : this.lastPersistedVersion;
|
|
1579
|
+
const rawBundle = baseline ? flock.exportJson(baseline) : flock.exportJson();
|
|
1580
|
+
const bundle = baseline ? this.stripUnchangedEntries(rawBundle, baseline) : rawBundle;
|
|
1581
|
+
if (Object.keys(bundle.entries).length === 0) {
|
|
1582
|
+
this.forceFullOnNextFlush = false;
|
|
1583
|
+
this.lastPersistedVersion = currentVersion;
|
|
1584
|
+
return;
|
|
1585
|
+
}
|
|
1586
|
+
const encoded = textEncoder.encode(JSON.stringify(bundle));
|
|
1587
|
+
if (!this.storage) {
|
|
1588
|
+
this.lastPersistedVersion = currentVersion;
|
|
1589
|
+
this.forceFullOnNextFlush = false;
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1592
|
+
try {
|
|
1593
|
+
await this.storage.save({
|
|
1594
|
+
type: "meta",
|
|
1595
|
+
update: encoded
|
|
1596
|
+
});
|
|
1597
|
+
} catch (error) {
|
|
1598
|
+
throw error;
|
|
1599
|
+
}
|
|
1600
|
+
this.lastPersistedVersion = currentVersion;
|
|
1601
|
+
this.forceFullOnNextFlush = false;
|
|
1602
|
+
}
|
|
1603
|
+
get metaFlock() {
|
|
1604
|
+
return this.getMetaFlock();
|
|
1605
|
+
}
|
|
1606
|
+
stripUnchangedEntries(bundle, baseline) {
|
|
1607
|
+
const entries = {};
|
|
1608
|
+
for (const [key, record] of Object.entries(bundle.entries)) {
|
|
1609
|
+
const clock = this.parseClock(record.c);
|
|
1610
|
+
if (!clock) {
|
|
1611
|
+
entries[key] = record;
|
|
1612
|
+
continue;
|
|
1613
|
+
}
|
|
1614
|
+
const baselineEntry = baseline[clock.peerIdHex];
|
|
1615
|
+
if (!baselineEntry) {
|
|
1616
|
+
entries[key] = record;
|
|
1617
|
+
continue;
|
|
1618
|
+
}
|
|
1619
|
+
if (clock.physicalTime > baselineEntry.physicalTime || clock.physicalTime === baselineEntry.physicalTime && clock.logicalCounter > baselineEntry.logicalCounter) entries[key] = record;
|
|
1620
|
+
}
|
|
1621
|
+
return {
|
|
1622
|
+
version: bundle.version,
|
|
1623
|
+
entries
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
parseClock(raw) {
|
|
1627
|
+
if (typeof raw !== "string") return void 0;
|
|
1628
|
+
const [physicalTimeStr, logicalCounterStr, peerIdHex] = raw.split(",");
|
|
1629
|
+
if (!physicalTimeStr || !logicalCounterStr || !peerIdHex) return void 0;
|
|
1630
|
+
const physicalTime = Number(physicalTimeStr);
|
|
1631
|
+
const logicalCounter = Number(logicalCounterStr);
|
|
1632
|
+
if (!Number.isFinite(physicalTime) || !Number.isFinite(logicalCounter)) return void 0;
|
|
1633
|
+
return {
|
|
1634
|
+
physicalTime,
|
|
1635
|
+
logicalCounter,
|
|
1636
|
+
peerIdHex
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
versionsEqual(a, b) {
|
|
1640
|
+
if (!a || !b) return false;
|
|
1641
|
+
const aKeys = Object.keys(a);
|
|
1642
|
+
const bKeys = Object.keys(b);
|
|
1643
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
1644
|
+
for (const key of aKeys) {
|
|
1645
|
+
const aEntry = a[key];
|
|
1646
|
+
const bEntry = b[key];
|
|
1647
|
+
if (!aEntry || !bEntry) return false;
|
|
1648
|
+
if (aEntry.physicalTime !== bEntry.physicalTime || aEntry.logicalCounter !== bEntry.logicalCounter) return false;
|
|
1649
|
+
}
|
|
1650
|
+
return true;
|
|
1651
|
+
}
|
|
1652
|
+
};
|
|
1653
|
+
|
|
1654
|
+
//#endregion
|
|
1655
|
+
//#region src/index.ts
|
|
1532
1656
|
const DEFAULT_DOC_FRONTIER_DEBOUNCE_MS = 1e3;
|
|
1533
1657
|
var LoroRepo = class LoroRepo {
|
|
1534
1658
|
options;
|
|
@@ -1544,6 +1668,7 @@ var LoroRepo = class LoroRepo {
|
|
|
1544
1668
|
flockHydrator;
|
|
1545
1669
|
state;
|
|
1546
1670
|
syncRunner;
|
|
1671
|
+
metaPersister;
|
|
1547
1672
|
constructor(options) {
|
|
1548
1673
|
this.options = options;
|
|
1549
1674
|
this.transport = options.transportAdapter;
|
|
@@ -1557,13 +1682,11 @@ var LoroRepo = class LoroRepo {
|
|
|
1557
1682
|
storage: this.storage,
|
|
1558
1683
|
docFrontierDebounceMs,
|
|
1559
1684
|
getMetaFlock: () => this.metaFlock,
|
|
1560
|
-
eventBus: this.eventBus
|
|
1561
|
-
persistMeta: () => this.persistMeta()
|
|
1685
|
+
eventBus: this.eventBus
|
|
1562
1686
|
});
|
|
1563
1687
|
this.metadataManager = new MetadataManager({
|
|
1564
1688
|
getMetaFlock: () => this.metaFlock,
|
|
1565
1689
|
eventBus: this.eventBus,
|
|
1566
|
-
persistMeta: () => this.persistMeta(),
|
|
1567
1690
|
state: this.state
|
|
1568
1691
|
});
|
|
1569
1692
|
this.assetManager = new AssetManager({
|
|
@@ -1571,9 +1694,13 @@ var LoroRepo = class LoroRepo {
|
|
|
1571
1694
|
assetTransport: this.assetTransport,
|
|
1572
1695
|
getMetaFlock: () => this.metaFlock,
|
|
1573
1696
|
eventBus: this.eventBus,
|
|
1574
|
-
persistMeta: () => this.persistMeta(),
|
|
1575
1697
|
state: this.state
|
|
1576
1698
|
});
|
|
1699
|
+
this.metaPersister = new MetaPersister({
|
|
1700
|
+
getMetaFlock: () => this.metaFlock,
|
|
1701
|
+
storage: this.storage,
|
|
1702
|
+
debounceMs: options.metaPersistDebounceMs
|
|
1703
|
+
});
|
|
1577
1704
|
this.flockHydrator = new FlockHydrator({
|
|
1578
1705
|
getMetaFlock: () => this.metaFlock,
|
|
1579
1706
|
metadataManager: this.metadataManager,
|
|
@@ -1591,8 +1718,7 @@ var LoroRepo = class LoroRepo {
|
|
|
1591
1718
|
getMetaFlock: () => this.metaFlock,
|
|
1592
1719
|
mergeFlock: (snapshot) => {
|
|
1593
1720
|
this.metaFlock.merge(snapshot);
|
|
1594
|
-
}
|
|
1595
|
-
persistMeta: () => this.persistMeta()
|
|
1721
|
+
}
|
|
1596
1722
|
});
|
|
1597
1723
|
}
|
|
1598
1724
|
static async create(options) {
|
|
@@ -1609,6 +1735,7 @@ var LoroRepo = class LoroRepo {
|
|
|
1609
1735
|
*/
|
|
1610
1736
|
async ready() {
|
|
1611
1737
|
await this.syncRunner.ready();
|
|
1738
|
+
this.metaPersister.start(this.metaFlock.version());
|
|
1612
1739
|
}
|
|
1613
1740
|
/**
|
|
1614
1741
|
* Sync selected data via the transport adaptor
|
|
@@ -1624,7 +1751,16 @@ var LoroRepo = class LoroRepo {
|
|
|
1624
1751
|
* @returns
|
|
1625
1752
|
*/
|
|
1626
1753
|
async joinMetaRoom(params) {
|
|
1627
|
-
|
|
1754
|
+
const subscription = await this.syncRunner.joinMetaRoom(params);
|
|
1755
|
+
return {
|
|
1756
|
+
unsubscribe: subscription.unsubscribe,
|
|
1757
|
+
get connected() {
|
|
1758
|
+
return subscription.connected;
|
|
1759
|
+
},
|
|
1760
|
+
firstSyncedWithRemote: subscription.firstSyncedWithRemote.then(async () => {
|
|
1761
|
+
await this.metaPersister.flushNow();
|
|
1762
|
+
})
|
|
1763
|
+
};
|
|
1628
1764
|
}
|
|
1629
1765
|
/**
|
|
1630
1766
|
* Start syncing the given doc. It will establish a realtime connection to the transport adaptor.
|
|
@@ -1696,6 +1832,7 @@ var LoroRepo = class LoroRepo {
|
|
|
1696
1832
|
}
|
|
1697
1833
|
async flush() {
|
|
1698
1834
|
await this.docManager.flush();
|
|
1835
|
+
await this.metaPersister.flushNow();
|
|
1699
1836
|
}
|
|
1700
1837
|
async uploadAsset(params) {
|
|
1701
1838
|
return this.assetManager.uploadAsset(params);
|
|
@@ -1718,21 +1855,13 @@ var LoroRepo = class LoroRepo {
|
|
|
1718
1855
|
async gcAssets(options = {}) {
|
|
1719
1856
|
return this.assetManager.gcAssets(options);
|
|
1720
1857
|
}
|
|
1721
|
-
async persistMeta() {
|
|
1722
|
-
if (!this.storage) return;
|
|
1723
|
-
const bundle = this.metaFlock.exportJson();
|
|
1724
|
-
const encoded = textEncoder.encode(JSON.stringify(bundle));
|
|
1725
|
-
await this.storage.save({
|
|
1726
|
-
type: "meta",
|
|
1727
|
-
update: encoded
|
|
1728
|
-
});
|
|
1729
|
-
}
|
|
1730
1858
|
get destroyed() {
|
|
1731
1859
|
return this._destroyed;
|
|
1732
1860
|
}
|
|
1733
1861
|
async destroy() {
|
|
1734
1862
|
if (this._destroyed) return;
|
|
1735
1863
|
this._destroyed = true;
|
|
1864
|
+
await this.metaPersister.destroy();
|
|
1736
1865
|
await this.syncRunner.destroy();
|
|
1737
1866
|
this.assetTransport?.close?.();
|
|
1738
1867
|
this.storage?.close?.();
|