meridian-sdk 1.2.0 → 1.3.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -0
  3. package/dist/agents.d.ts +143 -8
  4. package/dist/agents.d.ts.map +1 -1
  5. package/dist/agents.js +141 -14
  6. package/dist/agents.js.map +1 -1
  7. package/dist/client.d.ts +35 -2
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +45 -3
  10. package/dist/client.js.map +1 -1
  11. package/dist/conflict/types.d.ts +54 -0
  12. package/dist/conflict/types.d.ts.map +1 -0
  13. package/dist/conflict/types.js +9 -0
  14. package/dist/conflict/types.js.map +1 -0
  15. package/dist/crdt/rga.d.ts +20 -4
  16. package/dist/crdt/rga.d.ts.map +1 -1
  17. package/dist/crdt/rga.js +42 -6
  18. package/dist/crdt/rga.js.map +1 -1
  19. package/dist/crdt/tree.d.ts +128 -0
  20. package/dist/crdt/tree.d.ts.map +1 -0
  21. package/dist/crdt/tree.js +304 -0
  22. package/dist/crdt/tree.js.map +1 -0
  23. package/dist/index.d.ts +13 -4
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +10 -3
  26. package/dist/index.js.map +1 -1
  27. package/dist/schema.d.ts +63 -3
  28. package/dist/schema.d.ts.map +1 -1
  29. package/dist/schema.js +18 -1
  30. package/dist/schema.js.map +1 -1
  31. package/dist/sync/delta.d.ts +35 -0
  32. package/dist/sync/delta.d.ts.map +1 -1
  33. package/dist/sync/delta.js +4 -0
  34. package/dist/sync/delta.js.map +1 -1
  35. package/dist/undo/UndoManager.d.ts +74 -0
  36. package/dist/undo/UndoManager.d.ts.map +1 -0
  37. package/dist/undo/UndoManager.js +318 -0
  38. package/dist/undo/UndoManager.js.map +1 -0
  39. package/dist/undo/types.d.ts +63 -0
  40. package/dist/undo/types.d.ts.map +1 -0
  41. package/dist/undo/types.js +9 -0
  42. package/dist/undo/types.js.map +1 -0
  43. package/dist/utils/fractional.d.ts +78 -0
  44. package/dist/utils/fractional.d.ts.map +1 -0
  45. package/dist/utils/fractional.js +159 -0
  46. package/dist/utils/fractional.js.map +1 -0
  47. package/dist/validation/index.d.ts +107 -0
  48. package/dist/validation/index.d.ts.map +1 -0
  49. package/dist/validation/index.js +123 -0
  50. package/dist/validation/index.js.map +1 -0
  51. package/package.json +1 -1
  52. package/src/agents.ts +224 -15
  53. package/src/client.ts +52 -3
  54. package/src/conflict/types.ts +60 -0
  55. package/src/crdt/rga.ts +46 -7
  56. package/src/crdt/tree.ts +367 -0
  57. package/src/index.ts +31 -1
  58. package/src/schema.ts +24 -1
  59. package/src/sync/delta.ts +30 -1
  60. package/src/undo/UndoManager.ts +369 -0
  61. package/src/undo/types.ts +74 -0
  62. package/src/utils/fractional.ts +166 -0
  63. package/src/validation/index.ts +137 -0
  64. package/test/conflict.test.ts +242 -0
  65. package/test/fractional.test.ts +127 -0
  66. package/test/undo.test.ts +272 -0
  67. package/test/validation.test.ts +137 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # meridian-sdk
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 48647ce: **meridian-sdk**: Add granular permissions V2 schema (`PermissionsV2`, `PermEntry`, `OpMask`), multi-provider AI agent adapters (`executeOpenAITool`, `executeGeminiTool`, `OpenAIToolCall`, `GeminiFunctionCall`), and fix ORSet delta sync to return real deltas based on VectorClock instead of full state.
8
+
9
+ **meridian-devtools**: Add colors for `rga` (orange) and `tree` (sky) CRDT types in the visualization panel.
10
+
11
+ **meridian-react**: Compatibility update for granular permissions V2 and ORSet delta sync improvements in meridian-sdk.
12
+
13
+ ## 1.2.1
14
+
15
+ ### Minor Changes
16
+
17
+ - 3086c3d: feat(crdt): add TreeCRDT for hierarchical collaborative editing
18
+
19
+ Implements a convergent hierarchical tree CRDT based on Kleppmann et al. (2021). Supports addNode, moveNode, updateNode, and deleteNode operations with cycle detection, LWW value updates, and tombstone deletes. The `client.tree(id)` factory and `useTree()` React hook are now available.
20
+
3
21
  ## 1.2.0
4
22
 
5
23
  ### Minor Changes
package/README.md CHANGED
@@ -96,6 +96,7 @@ await Effect.runPromise(
96
96
  | `client.crdtmap(id)` | `CRDTMapHandle` | — |
97
97
  | `client.awareness(key, schema?)` | `AwarenessHandle<T>` | Optional |
98
98
  | `client.rga(id)` | `RGAHandle` | — |
99
+ | `client.tree(id)` | `TreeHandle` | — |
99
100
 
100
101
  Without a schema, `T = unknown`. With a schema, incoming deltas are validated at runtime via `Schema.decodeUnknownSync`.
101
102
 
package/dist/agents.d.ts CHANGED
@@ -1,18 +1,41 @@
1
1
  /**
2
- * Meridian × Anthropic Claude tool use helpers.
2
+ * Meridian AI agent tool use helpers.
3
3
  *
4
- * Generates Anthropic-compatible `Tool` definitions from a list of CRDT IDs
4
+ * Generates provider-compatible tool definitions from a list of CRDT IDs
5
5
  * and executes tool calls against a Meridian server via HTTP (no WebSocket).
6
6
  *
7
- * Usage:
7
+ * Supported providers:
8
+ * - Anthropic Claude — `getMeridianTools()` (default)
9
+ * - OpenAI GPT — `toOpenAITools(getMeridianTools(...))`
10
+ * - Google Gemini — `toGeminiTools(getMeridianTools(...))`
11
+ *
12
+ * Usage (Anthropic):
8
13
  * ```ts
9
14
  * import { getMeridianTools, executeMeridianTool } from "meridian-sdk";
10
15
  *
11
- * const tools = getMeridianTools({ baseUrl, token, namespace, crdtIds: ["counter", "tasks"] });
16
+ * const tools = getMeridianTools(config, ["counter", "tasks"]);
17
+ * // Pass to Anthropic messages.create({ tools })
18
+ * const result = await executeMeridianTool(config, toolUseBlock);
19
+ * ```
20
+ *
21
+ * Usage (OpenAI):
22
+ * ```ts
23
+ * import { getMeridianTools, toOpenAITools, executeOpenAITool } from "meridian-sdk";
24
+ *
25
+ * const tools = toOpenAITools(getMeridianTools(config, ["counter", "tasks"]));
26
+ * // Pass to openai.chat.completions.create({ tools })
27
+ * // For each tool_call in the response — pass directly, no wrapping:
28
+ * const result = await executeOpenAITool(config, call);
29
+ * ```
30
+ *
31
+ * Usage (Gemini):
32
+ * ```ts
33
+ * import { getMeridianTools, toGeminiTools, executeGeminiTool } from "meridian-sdk";
12
34
  *
13
- * // Pass tools to Anthropic messages.create(...)
14
- * // Then for each tool_use block in the response:
15
- * const result = await executeMeridianTool({ baseUrl, token, namespace }, toolUseBlock);
35
+ * const tools = toGeminiTools(getMeridianTools(config, ["counter", "tasks"]));
36
+ * // Pass to model.generateContent({ tools })
37
+ * // For each functionCall part pass directly, no wrapping:
38
+ * const result = await executeGeminiTool(config, part.functionCall);
16
39
  * ```
17
40
  */
18
41
  export interface Tool {
@@ -27,12 +50,85 @@ export interface Tool {
27
50
  required?: string[];
28
51
  };
29
52
  }
53
+ /** OpenAI-compatible tool definition (Chat Completions `tools` array entry). */
54
+ export interface OpenAITool {
55
+ type: "function";
56
+ function: {
57
+ name: string;
58
+ description: string;
59
+ parameters: {
60
+ type: "object";
61
+ properties: Record<string, {
62
+ type: string;
63
+ description: string;
64
+ }>;
65
+ required?: string[];
66
+ };
67
+ };
68
+ }
69
+ /**
70
+ * Convert Meridian tools to OpenAI Chat Completions format.
71
+ *
72
+ * ```ts
73
+ * const tools = toOpenAITools(getMeridianTools(config, crdtIds));
74
+ * // openai.chat.completions.create({ tools })
75
+ * ```
76
+ */
77
+ export declare function toOpenAITools(tools: Tool[]): OpenAITool[];
78
+ /** Gemini FunctionDeclaration (single entry inside a `Tool.functionDeclarations` array). */
79
+ export interface GeminiFunctionDeclaration {
80
+ name: string;
81
+ description: string;
82
+ parameters: {
83
+ type: "OBJECT";
84
+ properties: Record<string, {
85
+ type: string;
86
+ description: string;
87
+ }>;
88
+ required?: string[];
89
+ };
90
+ }
91
+ /** Gemini `Tool` wrapper passed to `model.generateContent({ tools })`. */
92
+ export interface GeminiTool {
93
+ functionDeclarations: GeminiFunctionDeclaration[];
94
+ }
95
+ /**
96
+ * Convert Meridian tools to Google Gemini format.
97
+ *
98
+ * ```ts
99
+ * const tools = toGeminiTools(getMeridianTools(config, crdtIds));
100
+ * // model.generateContent({ tools })
101
+ * ```
102
+ */
103
+ export declare function toGeminiTools(tools: Tool[]): GeminiTool;
104
+ /** Anthropic tool_use block — matches `ContentBlock` from `@anthropic-ai/sdk`. */
30
105
  export interface ToolUseBlock {
31
106
  type: "tool_use";
32
107
  id: string;
33
108
  name: string;
34
109
  input: Record<string, unknown>;
35
110
  }
111
+ /**
112
+ * OpenAI tool call — structurally matches `ChatCompletionMessageToolCall`
113
+ * from the `openai` package. Pass directly from `response.choices[0].message.tool_calls`.
114
+ */
115
+ export interface OpenAIToolCall {
116
+ id: string;
117
+ type: "function";
118
+ function: {
119
+ name: string;
120
+ /** JSON-encoded arguments string, as returned by the OpenAI API. */
121
+ arguments: string;
122
+ };
123
+ }
124
+ /**
125
+ * Gemini function call — structurally matches `FunctionCall` from
126
+ * `@google/generative-ai`. Pass directly from `part.functionCall`.
127
+ */
128
+ export interface GeminiFunctionCall {
129
+ name: string;
130
+ args: Record<string, unknown>;
131
+ }
36
132
  export interface MeridianAgentConfig {
37
133
  /** HTTP base URL of the Meridian server (e.g. https://meridian.example.com) */
38
134
  baseUrl: string;
@@ -52,9 +148,48 @@ export interface MeridianAgentConfig {
52
148
  */
53
149
  export declare function getMeridianTools(config: MeridianAgentConfig, crdtIds: string[]): Tool[];
54
150
  /**
55
- * Execute a Meridian tool call returned by Claude.
151
+ * Execute a Meridian tool call returned by **Anthropic Claude**.
56
152
  *
57
153
  * Returns a JSON string suitable for the `content` field of a `tool_result` block.
154
+ *
155
+ * ```ts
156
+ * for (const block of response.content) {
157
+ * if (block.type === "tool_use") {
158
+ * const result = await executeMeridianTool(config, block);
159
+ * toolResults.push({ type: "tool_result", tool_use_id: block.id, content: result });
160
+ * }
161
+ * }
162
+ * ```
58
163
  */
59
164
  export declare function executeMeridianTool(config: MeridianAgentConfig, toolUse: ToolUseBlock): Promise<string>;
165
+ /**
166
+ * Execute a Meridian tool call returned by **OpenAI**.
167
+ *
168
+ * Pass `tool_call` directly from `response.choices[0].message.tool_calls` —
169
+ * no wrapping required. Returns a JSON string for the `tool` role message content.
170
+ *
171
+ * ```ts
172
+ * for (const call of response.choices[0].message.tool_calls ?? []) {
173
+ * const result = await executeOpenAITool(config, call);
174
+ * messages.push({ role: "tool", tool_call_id: call.id, content: result });
175
+ * }
176
+ * ```
177
+ */
178
+ export declare function executeOpenAITool(config: MeridianAgentConfig, toolCall: OpenAIToolCall): Promise<string>;
179
+ /**
180
+ * Execute a Meridian tool call returned by **Google Gemini**.
181
+ *
182
+ * Pass `part.functionCall` directly — no wrapping, no id hack required.
183
+ * Returns a JSON string for the `functionResponse` part content.
184
+ *
185
+ * ```ts
186
+ * for (const part of response.candidates?.[0].content.parts ?? []) {
187
+ * if (part.functionCall) {
188
+ * const result = await executeGeminiTool(config, part.functionCall);
189
+ * // pass result back as functionResponse part
190
+ * }
191
+ * }
192
+ * ```
193
+ */
194
+ export declare function executeGeminiTool(config: MeridianAgentConfig, functionCall: GeminiFunctionCall): Promise<string>;
60
195
  //# sourceMappingURL=agents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAClE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,MAAM,EAAE,GAChB,IAAI,EAAE,CAwDR;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,CA0CjB"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
package/dist/agents.js CHANGED
@@ -1,21 +1,87 @@
1
1
  /**
2
- * Meridian × Anthropic Claude tool use helpers.
2
+ * Meridian AI agent tool use helpers.
3
3
  *
4
- * Generates Anthropic-compatible `Tool` definitions from a list of CRDT IDs
4
+ * Generates provider-compatible tool definitions from a list of CRDT IDs
5
5
  * and executes tool calls against a Meridian server via HTTP (no WebSocket).
6
6
  *
7
- * Usage:
7
+ * Supported providers:
8
+ * - Anthropic Claude — `getMeridianTools()` (default)
9
+ * - OpenAI GPT — `toOpenAITools(getMeridianTools(...))`
10
+ * - Google Gemini — `toGeminiTools(getMeridianTools(...))`
11
+ *
12
+ * Usage (Anthropic):
8
13
  * ```ts
9
14
  * import { getMeridianTools, executeMeridianTool } from "meridian-sdk";
10
15
  *
11
- * const tools = getMeridianTools({ baseUrl, token, namespace, crdtIds: ["counter", "tasks"] });
16
+ * const tools = getMeridianTools(config, ["counter", "tasks"]);
17
+ * // Pass to Anthropic messages.create({ tools })
18
+ * const result = await executeMeridianTool(config, toolUseBlock);
19
+ * ```
20
+ *
21
+ * Usage (OpenAI):
22
+ * ```ts
23
+ * import { getMeridianTools, toOpenAITools, executeOpenAITool } from "meridian-sdk";
24
+ *
25
+ * const tools = toOpenAITools(getMeridianTools(config, ["counter", "tasks"]));
26
+ * // Pass to openai.chat.completions.create({ tools })
27
+ * // For each tool_call in the response — pass directly, no wrapping:
28
+ * const result = await executeOpenAITool(config, call);
29
+ * ```
30
+ *
31
+ * Usage (Gemini):
32
+ * ```ts
33
+ * import { getMeridianTools, toGeminiTools, executeGeminiTool } from "meridian-sdk";
12
34
  *
13
- * // Pass tools to Anthropic messages.create(...)
14
- * // Then for each tool_use block in the response:
15
- * const result = await executeMeridianTool({ baseUrl, token, namespace }, toolUseBlock);
35
+ * const tools = toGeminiTools(getMeridianTools(config, ["counter", "tasks"]));
36
+ * // Pass to model.generateContent({ tools })
37
+ * // For each functionCall part pass directly, no wrapping:
38
+ * const result = await executeGeminiTool(config, part.functionCall);
16
39
  * ```
17
40
  */
18
41
  import { encode, uuidToBytes } from "./codec.js";
42
+ /**
43
+ * Convert Meridian tools to OpenAI Chat Completions format.
44
+ *
45
+ * ```ts
46
+ * const tools = toOpenAITools(getMeridianTools(config, crdtIds));
47
+ * // openai.chat.completions.create({ tools })
48
+ * ```
49
+ */
50
+ export function toOpenAITools(tools) {
51
+ return tools.map(t => ({
52
+ type: "function",
53
+ function: {
54
+ name: t.name,
55
+ description: t.description,
56
+ parameters: {
57
+ type: "object",
58
+ properties: t.input_schema.properties,
59
+ ...(t.input_schema.required ? { required: t.input_schema.required } : {}),
60
+ },
61
+ },
62
+ }));
63
+ }
64
+ /**
65
+ * Convert Meridian tools to Google Gemini format.
66
+ *
67
+ * ```ts
68
+ * const tools = toGeminiTools(getMeridianTools(config, crdtIds));
69
+ * // model.generateContent({ tools })
70
+ * ```
71
+ */
72
+ export function toGeminiTools(tools) {
73
+ return {
74
+ functionDeclarations: tools.map(t => ({
75
+ name: t.name,
76
+ description: t.description,
77
+ parameters: {
78
+ type: "OBJECT",
79
+ properties: t.input_schema.properties,
80
+ ...(t.input_schema.required ? { required: t.input_schema.required } : {}),
81
+ },
82
+ })),
83
+ };
84
+ }
19
85
  /**
20
86
  * Returns an Anthropic `Tool[]` array for the given CRDT IDs.
21
87
  *
@@ -76,15 +142,15 @@ export function getMeridianTools(config, crdtIds) {
76
142
  }
77
143
  return tools;
78
144
  }
145
+ // ---------------------------------------------------------------------------
146
+ // Shared dispatcher (private)
147
+ // ---------------------------------------------------------------------------
79
148
  /**
80
- * Execute a Meridian tool call returned by Claude.
81
- *
82
- * Returns a JSON string suitable for the `content` field of a `tool_result` block.
149
+ * Core dispatch logic — routes a (name, input) pair to the right HTTP operation.
150
+ * All provider-specific executors delegate here.
83
151
  */
84
- export async function executeMeridianTool(config, toolUse) {
152
+ async function dispatchTool(config, name, input) {
85
153
  const { baseUrl, token, namespace } = config;
86
- const { name, input } = toolUse;
87
- // Detect operation type and crdt_id from tool name
88
154
  const readMatch = name.match(/^meridian_read_(.+)$/);
89
155
  const incrementMatch = name.match(/^meridian_increment_(.+)$/);
90
156
  const setMatch = name.match(/^meridian_set_(.+)$/);
@@ -115,7 +181,7 @@ export async function executeMeridianTool(config, toolUse) {
115
181
  if (addMatch?.[1]) {
116
182
  const crdtId = addMatch[1].replace(/_/g, "-");
117
183
  // Always store as a string so useORSet<string> can read it back directly.
118
- // If Claude passes a JSON object, re-serialize it to a stable string.
184
+ // If the model passes a JSON object, re-serialize it to a stable string.
119
185
  const rawEl = input.element;
120
186
  const element = typeof rawEl === "string" ? rawEl : JSON.stringify(rawEl ?? null);
121
187
  const clientId = Number(input.client_id ?? 1);
@@ -123,6 +189,67 @@ export async function executeMeridianTool(config, toolUse) {
123
189
  }
124
190
  return JSON.stringify({ error: `Unknown tool: ${name}` });
125
191
  }
192
+ // ---------------------------------------------------------------------------
193
+ // Provider executors
194
+ // ---------------------------------------------------------------------------
195
+ /**
196
+ * Execute a Meridian tool call returned by **Anthropic Claude**.
197
+ *
198
+ * Returns a JSON string suitable for the `content` field of a `tool_result` block.
199
+ *
200
+ * ```ts
201
+ * for (const block of response.content) {
202
+ * if (block.type === "tool_use") {
203
+ * const result = await executeMeridianTool(config, block);
204
+ * toolResults.push({ type: "tool_result", tool_use_id: block.id, content: result });
205
+ * }
206
+ * }
207
+ * ```
208
+ */
209
+ export async function executeMeridianTool(config, toolUse) {
210
+ return dispatchTool(config, toolUse.name, toolUse.input);
211
+ }
212
+ /**
213
+ * Execute a Meridian tool call returned by **OpenAI**.
214
+ *
215
+ * Pass `tool_call` directly from `response.choices[0].message.tool_calls` —
216
+ * no wrapping required. Returns a JSON string for the `tool` role message content.
217
+ *
218
+ * ```ts
219
+ * for (const call of response.choices[0].message.tool_calls ?? []) {
220
+ * const result = await executeOpenAITool(config, call);
221
+ * messages.push({ role: "tool", tool_call_id: call.id, content: result });
222
+ * }
223
+ * ```
224
+ */
225
+ export async function executeOpenAITool(config, toolCall) {
226
+ let input;
227
+ try {
228
+ input = JSON.parse(toolCall.function.arguments);
229
+ }
230
+ catch {
231
+ return JSON.stringify({ error: "Failed to parse tool call arguments" });
232
+ }
233
+ return dispatchTool(config, toolCall.function.name, input);
234
+ }
235
+ /**
236
+ * Execute a Meridian tool call returned by **Google Gemini**.
237
+ *
238
+ * Pass `part.functionCall` directly — no wrapping, no id hack required.
239
+ * Returns a JSON string for the `functionResponse` part content.
240
+ *
241
+ * ```ts
242
+ * for (const part of response.candidates?.[0].content.parts ?? []) {
243
+ * if (part.functionCall) {
244
+ * const result = await executeGeminiTool(config, part.functionCall);
245
+ * // pass result back as functionResponse part
246
+ * }
247
+ * }
248
+ * ```
249
+ */
250
+ export async function executeGeminiTool(config, functionCall) {
251
+ return dispatchTool(config, functionCall.name, functionCall.args);
252
+ }
126
253
  async function readCrdt(baseUrl, token, ns, id) {
127
254
  const res = await fetch(`${baseUrl}/v1/namespaces/${ns}/crdts/${id}`, {
128
255
  headers: { Authorization: `Bearer ${token}` },
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AA4BjD;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA2B,EAC3B,OAAiB;IAEjB,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QAEnD,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,iBAAiB,QAAQ,EAAE;YACjC,WAAW,EAAE,kCAAkC,EAAE,wBAAwB,MAAM,CAAC,SAAS,+CAA+C;YACxI,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE;aACf;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,sBAAsB,QAAQ,EAAE;YACtC,WAAW,EAAE,kBAAkB,EAAE,4GAA4G;YAC7I,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qFAAqF,EAAE;oBAC9H,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kDAAkD,EAAE;iBAC/F;gBACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,WAAW,CAAC;aAClC;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,gBAAgB,QAAQ,EAAE;YAChC,WAAW,EAAE,yBAAyB,EAAE,gEAAgE;YACxG,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qEAAqE,EAAE;oBAC7G,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;iBACtF;gBACD,QAAQ,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;aACjC;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,gBAAgB,QAAQ,EAAE;YAChC,WAAW,EAAE,0BAA0B,EAAE,eAAe;YACxD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE;oBACjF,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;iBACtF;gBACD,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC;aACnC;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAA2B,EAC3B,OAAqB;IAErB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEhC,mDAAmD;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAEnD,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;QAC1C,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,KAAK,GAAG,GAAG,CAAC;QAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC9C,0EAA0E;QAC1E,sEAAsE;QACtE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC;QAC5B,MAAM,OAAO,GAAW,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;QAC1F,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;QAC9C,OAAO,YAAY,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,OAAe,EACf,KAAa,EACb,EAAU,EACV,EAAU;IAEV,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE,UAAU,EAAE,EAAE,EAAE;QACpE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,OAAe,EACf,KAAa,EACb,EAAU,EACV,EAAU,EACV,QAAgB,EAChB,MAAc;IAEd,8DAA8D;IAC9D,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC;QACpB,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;QAC/C,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;IAEnD,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE;QACxE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,cAAc,EAAE,qBAAqB;SACtC;QACD,IAAI;KACL,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;AAC5E,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,OAAe,EACf,KAAa,EACb,EAAU,EACV,EAAU,EACV,QAAgB,EAChB,KAAc;IAEd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,EAAE,GAAG;QACT,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;YAChB,KAAK;YACL,GAAG,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE;SACvD;KACF,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE;QACxE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,cAAc,EAAE,qBAAqB;SACtC;QACD,IAAI;KACL,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,OAAe,EACf,KAAa,EACb,EAAU,EACV,EAAU,EACV,QAAgB,EAChB,OAAgB;IAEhB,MAAM,EAAE,GAAG;QACT,KAAK,EAAE;YACL,GAAG,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,EAAE;SAC7E;KACF,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE,UAAU,EAAE,MAAM,EAAE;QACxE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,cAAc,EAAE,qBAAqB;SACtC;QACD,IAAI;KACL,CAAC,CAAC;IAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AACvE,CAAC"}
1
+ {"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -10,6 +10,9 @@ import { PresenceHandle } from "./crdt/presence.js";
10
10
  import { CRDTMapHandle } from "./crdt/crdtmap.js";
11
11
  import { AwarenessHandle } from "./crdt/awareness.js";
12
12
  import { RGAHandle } from "./crdt/rga.js";
13
+ import { TreeHandle } from "./crdt/tree.js";
14
+ import type { CrdtValidator } from "./validation/index.js";
15
+ import type { TreeNodeValue } from "./sync/delta.js";
13
16
  import type { TokenClaims } from "./schema.js";
14
17
  import type { TokenParseError, TokenExpiredError } from "./errors.js";
15
18
  export interface GCounterSnapshotEntry {
@@ -56,7 +59,12 @@ export interface RGASnapshotEntry {
56
59
  crdtId: string;
57
60
  text: string;
58
61
  }
59
- export type CRDTSnapshotEntry = GCounterSnapshotEntry | PNCounterSnapshotEntry | ORSetSnapshotEntry | LwwRegisterSnapshotEntry | PresenceSnapshotEntry | CRDTMapSnapshotEntry | RGASnapshotEntry;
62
+ export interface TreeSnapshotEntry {
63
+ type: "tree";
64
+ crdtId: string;
65
+ roots: TreeNodeValue[];
66
+ }
67
+ export type CRDTSnapshotEntry = GCounterSnapshotEntry | PNCounterSnapshotEntry | ORSetSnapshotEntry | LwwRegisterSnapshotEntry | PresenceSnapshotEntry | CRDTMapSnapshotEntry | RGASnapshotEntry | TreeSnapshotEntry;
60
68
  export interface DeltaEvent {
61
69
  crdtId: string;
62
70
  type: CRDTSnapshotEntry["type"];
@@ -115,6 +123,7 @@ export declare class MeridianClient {
115
123
  private readonly cmHandles;
116
124
  private readonly awHandles;
117
125
  private readonly rgaHandles;
126
+ private readonly treeHandles;
118
127
  private readonly anyListeners;
119
128
  private readonly deltaListeners;
120
129
  private readonly handleUnsubs;
@@ -264,7 +273,31 @@ export declare class MeridianClient {
264
273
  * doc.onChange(text => console.log(text));
265
274
  * ```
266
275
  */
267
- rga(crdtId: string): RGAHandle;
276
+ rga(crdtId: string, opts?: {
277
+ validator?: CrdtValidator;
278
+ }): RGAHandle;
279
+ /**
280
+ * Returns a handle for a TreeCRDT — a convergent hierarchical tree.
281
+ *
282
+ * Use this for outlines, document trees, mind maps, or any nested structure
283
+ * that needs concurrent editing. Concurrent moves use Kleppmann (2021)
284
+ * move semantics: cycle-creating moves are discarded, all replicas converge.
285
+ *
286
+ * Handles are cached by `crdtId`; the same handle is returned for repeated calls.
287
+ *
288
+ * @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
289
+ *
290
+ * @example
291
+ * ```ts
292
+ * const tree = client.tree('doc:outline');
293
+ * const rootId = tree.addNode(null, 'a0', 'Introduction');
294
+ * const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
295
+ * tree.onChange(t => console.log(t.roots));
296
+ * ```
297
+ */
298
+ tree(crdtId: string, opts?: {
299
+ validator?: CrdtValidator;
300
+ }): TreeHandle;
268
301
  /**
269
302
  * Returns a handle for an ephemeral awareness channel.
270
303
  *
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -9,7 +9,8 @@ import { PresenceHandle } from "./crdt/presence.js";
9
9
  import { CRDTMapHandle } from "./crdt/crdtmap.js";
10
10
  import { AwarenessHandle } from "./crdt/awareness.js";
11
11
  import { RGAHandle } from "./crdt/rga.js";
12
- import { decodeGCounterDelta, decodePNCounterDelta, decodeORSetDelta, decodeLwwDelta, decodePresenceDelta, decodeCRDTMapDelta, decodeRGADelta, } from "./sync/delta.js";
12
+ import { TreeHandle } from "./crdt/tree.js";
13
+ import { decodeGCounterDelta, decodePNCounterDelta, decodeORSetDelta, decodeLwwDelta, decodePresenceDelta, decodeCRDTMapDelta, decodeRGADelta, decodeTreeDelta, } from "./sync/delta.js";
13
14
  import { parseAndValidateToken } from "./auth/token.js";
14
15
  /**
15
16
  * The main entry point for the Meridian real-time CRDT SDK.
@@ -52,6 +53,7 @@ export class MeridianClient {
52
53
  cmHandles = new Map();
53
54
  awHandles = new Map();
54
55
  rgaHandles = new Map();
56
+ treeHandles = new Map();
55
57
  anyListeners = new Set();
56
58
  deltaListeners = new Set();
57
59
  handleUnsubs = [];
@@ -280,16 +282,45 @@ export class MeridianClient {
280
282
  * doc.onChange(text => console.log(text));
281
283
  * ```
282
284
  */
283
- rga(crdtId) {
285
+ rga(crdtId, opts) {
284
286
  let handle = this.rgaHandles.get(crdtId);
285
287
  if (!handle) {
286
- handle = new RGAHandle({ crdtId, clientId: this.clientId, transport: this.transport });
288
+ handle = new RGAHandle({ crdtId, clientId: this.clientId, transport: this.transport, ...(opts?.validator !== undefined && { validator: opts.validator }) });
287
289
  this.rgaHandles.set(crdtId, handle);
288
290
  this.transport.subscribe(crdtId);
289
291
  this.handleUnsubs.push(handle.onChange(() => { this.notifyAnyChange(); }));
290
292
  }
291
293
  return handle;
292
294
  }
295
+ /**
296
+ * Returns a handle for a TreeCRDT — a convergent hierarchical tree.
297
+ *
298
+ * Use this for outlines, document trees, mind maps, or any nested structure
299
+ * that needs concurrent editing. Concurrent moves use Kleppmann (2021)
300
+ * move semantics: cycle-creating moves are discarded, all replicas converge.
301
+ *
302
+ * Handles are cached by `crdtId`; the same handle is returned for repeated calls.
303
+ *
304
+ * @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
305
+ *
306
+ * @example
307
+ * ```ts
308
+ * const tree = client.tree('doc:outline');
309
+ * const rootId = tree.addNode(null, 'a0', 'Introduction');
310
+ * const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
311
+ * tree.onChange(t => console.log(t.roots));
312
+ * ```
313
+ */
314
+ tree(crdtId, opts) {
315
+ let handle = this.treeHandles.get(crdtId);
316
+ if (!handle) {
317
+ handle = new TreeHandle({ crdtId, clientId: this.clientId, transport: this.transport, ...(opts?.validator !== undefined && { validator: opts.validator }) });
318
+ this.treeHandles.set(crdtId, handle);
319
+ this.transport.subscribe(crdtId);
320
+ this.handleUnsubs.push(handle.onChange(() => { this.notifyAnyChange(); }));
321
+ }
322
+ return handle;
323
+ }
293
324
  /**
294
325
  * Returns a handle for an ephemeral awareness channel.
295
326
  *
@@ -378,6 +409,8 @@ export class MeridianClient {
378
409
  crdts.push({ type: "crdtmap", crdtId, value: h.value() });
379
410
  for (const [crdtId, h] of this.rgaHandles)
380
411
  crdts.push({ type: "rga", crdtId, text: h.value() });
412
+ for (const [crdtId, h] of this.treeHandles)
413
+ crdts.push({ type: "tree", crdtId, roots: h.value().roots });
381
414
  return {
382
415
  namespace: this.namespace,
383
416
  clientId: this.clientId,
@@ -479,6 +512,15 @@ export class MeridianClient {
479
512
  }
480
513
  catch { /* stale */ }
481
514
  this.notifyDelta(crdt_id, "rga");
515
+ return;
516
+ }
517
+ const treeHandle = this.treeHandles.get(crdt_id);
518
+ if (treeHandle) {
519
+ try {
520
+ treeHandle.applyDelta(decodeTreeDelta(delta_bytes));
521
+ }
522
+ catch { /* stale */ }
523
+ this.notifyDelta(crdt_id, "tree");
482
524
  }
483
525
  }
484
526
  notifyDelta(crdtId, type) {