loro-repo 0.2.0 → 0.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/README.md +18 -17
- package/dist/index.cjs +501 -233
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -49
- package/dist/index.d.ts +103 -50
- package/dist/index.js +491 -231
- package/dist/index.js.map +1 -1
- package/package.json +10 -7
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** – `
|
|
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 =
|
|
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.
|
|
41
|
-
await handle.
|
|
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
|
-
|
|
42
|
+
room.unsubscribe();
|
|
43
|
+
await repo.unloadDoc("note:welcome");
|
|
45
44
|
```
|
|
46
45
|
|
|
47
46
|
## Using the API
|
|
48
47
|
|
|
49
|
-
- **
|
|
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.
|
|
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
|
-
- `
|
|
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.
|
|
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.
|
|
95
|
+
- `repo.getMeta()` – access raw `Flock` if you need advanced scans.
|
|
96
96
|
|
|
97
97
|
**Documents**
|
|
98
|
-
- `await repo.
|
|
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.
|
|
101
|
-
- `await repo.
|
|
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.
|