|
1 | | - # Loro Mirror — API Reference |
2 | | - |
3 | | - This is the complete API reference for the `loro-mirror` package. It covers the public classes, functions, types, and utilities exported from the package entry and includes practical tips for effective usage. |
4 | | - |
5 | | - Contents |
6 | | - |
7 | | - - Installation & Imports |
| 1 | +# Loro Mirror — API Reference |
| 2 | + |
| 3 | +This is the complete API reference for the `loro-mirror` package. It covers the public classes, functions, types, and utilities exported from the package entry and includes practical tips for effective usage. |
| 4 | + |
| 5 | +Contents |
| 6 | + |
| 7 | +- Installation & Imports |
8 | 8 | - Core: Mirror |
9 | | - - Schema Builder |
10 | | - - Validation & Defaults |
11 | | - - Utilities (Advanced) |
12 | | - - Types & Constants |
13 | | - - Tips & Recipes |
14 | | - |
15 | | - ## Installation & Imports |
16 | | - |
17 | | - - Install: `npm install loro-mirror loro-crdt` |
| 9 | +- Schema Builder |
| 10 | +- Validation & Defaults |
| 11 | +- Utilities (Advanced) |
| 12 | +- Types & Constants |
| 13 | +- Tips & Recipes |
| 14 | + |
| 15 | +## Installation & Imports |
| 16 | + |
| 17 | +- Install: `npm install loro-mirror loro-crdt` |
18 | 18 | - Import styles: |
19 | 19 | - Named imports (recommended): `import { Mirror, schema } from "loro-mirror"` |
20 | | - - Default (convenience bundle of `schema` + `core`): `import loroMirror from "loro-mirror"` |
21 | | - |
| 20 | + - Default (convenience bundle of `schema` + `core`): `import loroMirror from "loro-mirror"` |
| 21 | + |
22 | 22 | ## Core: Mirror |
23 | | - |
24 | | - ### Mirror |
25 | | - |
26 | | - - Constructor: `new Mirror(options)` |
27 | | - - `options: MirrorOptions<S>` |
28 | | - - `doc: LoroDoc` — the Loro document to sync with |
29 | | - - `schema?: S` — root schema (enables validation, typed defaults) |
| 23 | + |
| 24 | +### Mirror |
| 25 | + |
| 26 | +- Constructor: `new Mirror(options)` |
| 27 | + - `options: MirrorOptions<S>` |
| 28 | + - `doc: LoroDoc` — the Loro document to sync with |
| 29 | + - `schema?: S` — root schema (enables validation, typed defaults) |
30 | 30 | - `initialState?: Partial<InferInputType<S>>` — shallow overlay onto doc snapshot and schema defaults (does not write to Loro) |
31 | | - - `validateUpdates?: boolean` (default `true`) — validate on `setState` |
32 | | - - `throwOnValidationError?: boolean` (default `false`) — throw on schema validation errors |
33 | | - - `debug?: boolean` — verbose logging to console for diagnostics |
34 | | - - `checkStateConsistency?: boolean` (default `false`) — deep checks in-memory state equals normalized `doc` JSON after `setState` |
35 | | - - `inferOptions?: { defaultLoroText?: boolean; defaultMovableList?: boolean }` — inference hints when no schema covers a field |
36 | | - |
37 | | - - Methods |
38 | | - - `getState(): InferType<S>` — returns the current mirror state (immutable snapshot) |
| 31 | + - `validateUpdates?: boolean` (default `true`) — validate on `setState` |
| 32 | + - `throwOnValidationError?: boolean` (default `false`) — throw on schema validation errors |
| 33 | + - `debug?: boolean` (default `false`) — verbose logging to console for diagnostics |
| 34 | + - `checkStateConsistency?: boolean` (default `false`) — verify after each `setState` that in-memory state matches the normalized `LoroDoc` |
| 35 | + - `inferOptions?: { defaultLoroText?: boolean; defaultMovableList?: boolean }` — inference hints when no schema covers a field |
| 36 | + |
| 37 | +- Methods |
| 38 | + - `getState(): InferType<S>` — returns the current mirror state (immutable snapshot) |
39 | 39 | - `setState(updater, options?): void` |
40 | 40 | - Synchronous; the state, validation, and subscriber notifications all finish before `setState` returns. |
41 | | - - `updater` supports both styles: |
42 | | - - Mutate a draft: `(draft: InferType<S>) => void` |
43 | | - - Return a new object: `(prev: Readonly<InferInputType<S>>) => InferInputType<S>` |
44 | | - - Shallow partial: `Partial<InferInputType<S>>` |
45 | | - - `options?: { tags?: string | string[] }` — tags surface in subscriber metadata |
46 | | - - `subscribe((state, metadata) => void): () => void` |
47 | | - - `metadata: { direction: SyncDirection; tags?: string[] }` |
48 | | - - Returns an unsubscribe function |
49 | | - - `dispose(): void` — removes all internal subscriptions and listeners |
50 | | - - `checkStateConsistency(): void` — throws if `state` diverges from normalized `doc` JSON (use with `checkStateConsistency: true`) |
51 | | - |
52 | | - - Behavior & Notes |
53 | | - - Sync directions: |
54 | | - - `FROM_LORO` — changes applied from the Loro document |
55 | | - - `TO_LORO` — changes produced by `setState` |
56 | | - - Mirror ignores events with origin `"to-loro"` to prevent feedback loops. |
57 | | - - Initial state precedence: defaults (from schema) → `doc` snapshot (normalized) → hinted shapes from `initialState` (no writes to Loro). |
58 | | - - Trees: mirror state uses `{ id: string; data: object; children: Node[] }`. Loro tree `meta` is normalized to `data`. |
59 | | - - `$cid` on maps: Mirror injects a read‑only `$cid` field into every LoroMap shape in state. It equals the Loro container ID, is not written back to Loro, and is ignored by diffs. |
60 | | - - Inference: with no schema, Mirror can infer containers from values; configure via `inferOptions`. |
61 | | - |
62 | | - - Example |
63 | | - |
64 | | - ```ts |
| 41 | + - `updater` supports both styles: |
| 42 | + - Mutate a draft: `(draft: InferType<S>) => void` |
| 43 | + - Return a new object: `(prev: Readonly<InferInputType<S>>) => InferInputType<S>` |
| 44 | + - Shallow partial: `Partial<InferInputType<S>>` |
| 45 | + - `options?: { tags?: string | string[] }` — tags surface in subscriber metadata |
| 46 | + - `subscribe((state, metadata) => void): () => void` |
| 47 | + - `metadata: { direction: SyncDirection; tags?: string[] }` |
| 48 | + - Returns an unsubscribe function |
| 49 | + - `dispose(): void` — removes all internal subscriptions and listeners |
| 50 | + - `checkStateConsistency(): void` — manually triggers the consistency assertion described above |
| 51 | + - `getContainerIds(): ContainerID[]` — advanced helper that lists registered Loro container IDs for debugging |
| 52 | + |
| 53 | +- Behavior & Notes |
| 54 | + - Sync directions: |
| 55 | + - `FROM_LORO` — changes applied from the Loro document |
| 56 | + - `TO_LORO` — changes produced by `setState` |
| 57 | + - `BIDIRECTIONAL` — manual/initial sync context |
| 58 | + - Mirror ignores events with origin `"to-loro"` to prevent feedback loops. |
| 59 | + - Initial state precedence: defaults (from schema) → `doc` snapshot (normalized) → hinted shapes from `initialState` (no writes to Loro). |
| 60 | + - Trees: mirror state uses `{ id: string; data: object; children: Node[] }`. Loro tree `meta` is normalized to `data`. |
| 61 | + - `$cid` on maps: Mirror injects a read-only `$cid` field into every LoroMap shape in state. It equals the Loro container ID, is not written back to Loro, and is ignored by diffs. |
| 62 | + - Inference: with no schema, Mirror can infer containers from values; configure via `inferOptions`. |
| 63 | + |
| 64 | +#### Example |
| 65 | + |
| 66 | +```ts |
65 | 67 | import { Mirror, schema } from "loro-mirror"; |
66 | 68 | import { LoroDoc } from "loro-crdt"; |
67 | 69 |
|
|
96 | 98 | - `definition: { [key: string]: ContainerSchemaType }` |
97 | 99 | - `options?: SchemaOptions` |
98 | 100 |
|
99 | | - - Primitives |
100 | | - - `schema.String<T = string>(options?)` |
101 | | - - `schema.Number(options?)` |
102 | | - - `schema.Boolean(options?)` |
103 | | - - `schema.Ignore<T = unknown>(options?)` — present in state, ignored for Loro diffs/validation |
| 101 | +- Primitives |
| 102 | + - `schema.String<T = string>(options?)` |
| 103 | + - `schema.Number(options?)` |
| 104 | + - `schema.Boolean(options?)` |
| 105 | + - `schema.Ignore(options?)` — present in state, ignored for Loro diffs/validation |
104 | 106 |
|
105 | 107 | - Containers |
106 | 108 | - `schema.LoroMap(definition)` |
|
156 | 158 | - `createValueFromSchema(schema, value): InferType<S>` |
157 | 159 | - Casts/wraps a value into the shape expected by a schema (primitives pass through). |
158 | 160 |
|
159 | | - ## Utilities (Advanced) |
160 | | - |
161 | | - The following helpers are exported for advanced use, tooling, or tests. Most apps do not need them directly. |
162 | | - |
163 | | - - Equality & JSON |
164 | | - - `deepEqual(a, b): boolean` — deep structural equality |
165 | | - - `toNormalizedJson(doc: LoroDoc): unknown` — `doc.toJSON()` with tree `meta` normalized to `data` |
166 | | - |
167 | | - - Path helpers |
168 | | - - `getPathValue(obj, path: string[]): unknown` — read nested path |
169 | | - - `setPathValue(obj, path: string[], value): void` — write nested path (mutates the object) |
170 | | - |
171 | | - - Container detection & IDs |
172 | | - - `valueIsContainer(v): { cid: string; value: unknown }` — check values from `doc.getDeepValueWithID()` |
173 | | - - `valueIsContainerOfType(v, suffix: string): boolean` — e.g. `":Text"`, `":Map"`, `":List"`, `":MovableList"` |
174 | | - - `containerIdToContainerType(id): ContainerType | undefined` |
175 | | - - `getRootContainerByType(doc, key, type): Container` |
176 | | - - `isTreeID(id: unknown): boolean` — test if a string looks like a Loro `TreeID` (e.g. `"0@1"`) |
177 | | - |
178 | | - - Inference helpers |
179 | | - - `schemaToContainerType(schema): ContainerType | undefined` |
180 | | - - `tryInferContainerType(value, inferOptions?): ContainerType | undefined` |
181 | | - - `inferContainerTypeFromValue(value, inferOptions?): "loro-map" | "loro-list" | "loro-text" | "loro-movable-list" | undefined` |
182 | | - - `isValueOfContainerType(type, value): boolean` |
183 | | - |
184 | | - - Guards & shapes |
185 | | - - `isObject(v): v is Record<string, unknown>` |
186 | | - - `isObjectLike(v): v is Record<string, unknown>` |
187 | | - - `isArrayLike(v): v is unknown[]` |
188 | | - - `isStringLike(v): v is string` |
189 | | - - `isStateAndSchemaOfType(values, stateGuard, schemaGuard)` — generic narrow helper |
190 | | - - Schema guards |
191 | | - - `isContainerSchema(schema?): schema is ContainerSchemaType` |
192 | | - - `isRootSchemaType(schema): schema is RootSchemaType` |
193 | | - - `isLoroMapSchema(schema): schema is LoroMapSchema` |
194 | | - - `isLoroListSchema(schema): schema is LoroListSchema` |
195 | | - - `isListLikeSchema(schema): schema is LoroListSchema | LoroMovableListSchema` |
196 | | - - `isLoroMovableListSchema(schema): schema is LoroMovableListSchema` |
197 | | - - `isLoroTextSchema(schema): schema is LoroTextSchemaType` |
198 | | - - `isLoroTreeSchema(schema): schema is LoroTreeSchema` |
199 | | - |
200 | | - - Change helpers (primarily internal) |
201 | | - - `insertChildToMap(containerId, key, value): Change` — produce a map change (container‑aware) |
202 | | - - `tryUpdateToContainer(change, enable, schema?): Change` — upgrade an insert/set to a container operation based on schema/value |
203 | | - |
204 | | - ## Types & Constants |
205 | | - |
206 | | - - `SyncDirection` — enum: `FROM_LORO`, `TO_LORO`, `BIDIRECTIONAL` |
| 161 | +## Utilities (Advanced) |
| 162 | + |
| 163 | +Most applications will not need the low-level helpers below, but they are part of the published surface for tooling and testing. |
| 164 | + |
| 165 | +- `toNormalizedJson(doc: LoroDoc): unknown` — returns `doc.toJSON()` with tree `meta` data normalized into `data` so it matches Mirror state. |
| 166 | +- Schema guards exported from `schema/validators`: |
| 167 | + - `isContainerSchema`, `isRootSchemaType`, `isLoroMapSchema`, `isLoroListSchema`, `isListLikeSchema`, `isLoroMovableListSchema`, `isLoroTextSchema`, `isLoroTreeSchema` |
| 168 | + |
| 169 | +## Types & Constants |
| 170 | + |
| 171 | +- `SyncDirection` — enum: `FROM_LORO`, `TO_LORO`, `BIDIRECTIONAL` |
207 | 172 | - `MirrorOptions<S>` — constructor options for `Mirror` |
208 | 173 | - `SetStateOptions` — `{ tags?: string | string[] }` |
209 | 174 | - `UpdateMetadata` — `{ direction: SyncDirection; tags?: string[] }` |
|
213 | 178 | - `SubscriberCallback<T>` — `(state: T, metadata: UpdateMetadata) => void` |
214 | 179 | - Change types (advanced): `ChangeKinds`, `Change`, `MapChangeKinds`, `ListChangeKinds`, `MovableListChangeKinds`, `TreeChangeKinds`, `TextChangeKinds` |
215 | 180 | - Schema types: `SchemaType`, `ContainerSchemaType`, `RootSchemaType`, `LoroMapSchema`, `LoroListSchema`, `LoroMovableListSchema`, `LoroTextSchemaType`, `LoroTreeSchema`, `SchemaOptions`, … |
216 | | -- `CID_KEY` — the literal string `"$cid"` used by mirrored maps |
217 | 181 |
|
218 | 182 | ## Tips & Recipes |
219 | 183 |
|
|
0 commit comments