loro-repo 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,7 @@ LoroRepo is the collection-sync layer that sits above Flock. It keeps document m
9
9
  ## What you get
10
10
 
11
11
  - **Metadata-first coordination** – `repo.listDoc()` and `repo.watch()` expose LWW metadata so UIs can render collections before bodies arrive.
12
- - **On-demand documents** – `openCollaborativeDoc()` gives you a repo-managed `LoroDoc` that persists and syncs automatically; `openDetachedDoc()` is a read-only snapshot.
12
+ - **On-demand documents** – `openPersistedDoc()` hands back a repo-managed `LoroDoc` that persists locally and can sync once or join live rooms; `openDetachedDoc()` is a read-only snapshot.
13
13
  - **Binary asset orchestration** – `linkAsset()`/`fetchAsset()` dedupe SHA-256 addressed blobs across docs, while `gcAssets()` sweeps unreferenced payloads.
14
14
  - **Pluggable adapters** – supply your own `TransportAdapter`, `StorageAdapter`, and `AssetTransportAdapter` (or use the built-ins below) to target servers, CF Durable Objects, or local-first meshes.
15
15
  - **Consistent events** – every event includes `by: "local" | "sync" | "live"` so you can react differently to local edits, explicit sync pulls, or realtime merges.
@@ -22,36 +22,37 @@ import {
22
22
  BroadcastChannelTransportAdapter,
23
23
  IndexedDBStorageAdaptor,
24
24
  } from "loro-repo";
25
- import { LoroDoc } from "loro-crdt";
26
25
 
27
26
  type DocMeta = { title?: string; tags?: string[] };
28
27
 
29
- const repo = new LoroRepo<DocMeta>({
28
+ const repo = await LoroRepo.create<DocMeta>({
30
29
  transportAdapter: new BroadcastChannelTransportAdapter({ namespace: "notes" }),
31
30
  storageAdapter: new IndexedDBStorageAdaptor({ dbName: "notes-db" }),
32
- docFactory: async () => new LoroDoc(),
33
31
  });
34
32
 
35
- await repo.ready();
36
33
  await repo.sync({ scope: "meta" }); // metadata-first
37
34
 
38
35
  await repo.upsertDocMeta("note:welcome", { title: "Welcome" });
39
36
 
40
- const handle = await repo.openCollaborativeDoc("note:welcome");
41
- await handle.whenSyncedWithRemote;
37
+ const handle = await repo.openPersistedDoc("note:welcome");
38
+ await handle.syncOnce(); // optional: fetch body once
39
+ const room = await handle.joinRoom(); // optional: live updates
42
40
  handle.doc.getText("content").insert(0, "Hello from LoroRepo");
43
41
  handle.doc.commit();
44
- await handle.close();
42
+ room.unsubscribe();
43
+ await repo.unloadDoc("note:welcome");
45
44
  ```
46
45
 
47
46
  ## Using the API
48
47
 
49
- - **Define your metadata contract** once via `new LoroRepo<Meta>()`. All metadata helpers (`upsertDocMeta`, `getDocMeta`, `listDoc`, `watch`) stay type-safe.
48
+ - **Create a repo** with `await LoroRepo.create<Meta>({ transportAdapter?, storageAdapter?, assetTransportAdapter?, docFrontierDebounceMs? })`; metadata is hydrated automatically.
49
+ - **Define your metadata contract** once via the generic `Meta`. All metadata helpers (`upsertDocMeta`, `getDocMeta`, `listDoc`, `watch`) stay type-safe.
50
50
  - **Choose sync lanes** with `repo.sync({ scope: "meta" | "doc" | "full", docIds?: string[] })` to pull remote changes on demand.
51
+ - **Work with documents** using `openPersistedDoc(docId)` for repo-managed docs (persisted snapshots + frontier tracking) and `openDetachedDoc(docId)` for isolated snapshots; call `joinDocRoom`/`handle.joinRoom` for live sync, or `unloadDoc`/`flush` to persist and drop cached docs.
51
52
  - **Join realtime rooms** by calling `joinMetaRoom()` / `joinDocRoom(docId)`; the behaviour depends entirely on the transport adapter you injected.
52
53
  - **Manage assets** through `linkAsset`, `uploadAsset`, `fetchAsset` (alias `ensureAsset`), `listAssets`, and `gcAssets({ minKeepMs })`.
53
54
  - **React to changes** by subscribing with `repo.watch(listener, { docIds, kinds, metadataFields, by })`.
54
- - **Shut down cleanly** via `await repo.close()` to flush snapshots and dispose adapters.
55
+ - **Shut down cleanly** via `await repo.destroy()` to flush snapshots and dispose adapters.
55
56
 
56
57
  ## Built-in adapters
57
58
 
@@ -83,22 +84,22 @@ await handle.close();
83
84
  ## Core API surface
84
85
 
85
86
  **Lifecycle**
86
- - `new LoroRepo<Meta>(options)` – wire adapters (`transportAdapter`, `storageAdapter`, `assetTransportAdapter`, `docFactory`, `docFrontierDebounceMs`).
87
- - `await repo.ready()` – hydrate metadata snapshot before touching docs.
87
+ - `await LoroRepo.create<Meta>({ transportAdapter?, storageAdapter?, assetTransportAdapter?, docFrontierDebounceMs? })` – hydrate metadata and initialise adapters.
88
88
  - `await repo.sync({ scope: "meta" | "doc" | "full", docIds?: string[] })` – pull remote updates on demand.
89
- - `await repo.close()` – persist pending work and dispose adapters.
89
+ - `await repo.destroy()` – persist pending work and dispose adapters.
90
90
 
91
91
  **Metadata**
92
92
  - `await repo.upsertDocMeta(docId, patch)` – LWW merge with your `Meta` type.
93
93
  - `await repo.getDocMeta(docId)` – clone the stored metadata (or `undefined`).
94
94
  - `await repo.listDoc(query?)` – list docs by prefix/range/limit (`RepoDocMeta<Meta>[]`).
95
- - `repo.getMetaReplica()` – access raw `Flock` if you need advanced scans.
95
+ - `repo.getMeta()` – access raw `Flock` if you need advanced scans.
96
96
 
97
97
  **Documents**
98
- - `await repo.openCollaborativeDoc(docId)` – returns `{ doc, whenSyncedWithRemote, close }`; mutations persist and sync automatically.
98
+ - `await repo.openPersistedDoc(docId)` – returns `{ doc, syncOnce, joinRoom }`; mutations persist locally and frontiers are written to metadata.
99
99
  - `await repo.openDetachedDoc(docId)` – isolated snapshot handle (no persistence, no live sync) ideal for read-only tasks.
100
- - `await repo.whenDocInSyncWithRemote(docId)` – ensure a document caught up without opening it.
101
- - `await repo.joinDocRoom(docId, params?)` – spawn a realtime session through your transport; use `subscription.unsubscribe()` when done.
100
+ - `await repo.joinDocRoom(docId, params?)` or `await handle.joinRoom(auth?)` spawn a realtime session through your transport; use `subscription.unsubscribe()` when done.
101
+ - `await repo.unloadDoc(docId)` – flush pending work for a doc and evict it from memory.
102
+ - `await repo.flush()` – persist all loaded docs and flush pending frontier updates.
102
103
 
103
104
  **Assets**
104
105
  - `await repo.linkAsset(docId, { content, mime?, tag?, policy?, assetId?, createdAt? })` – upload + link, returning the SHA-256 assetId.