@echovisionlab/geul-common 0.2.0 → 0.2.2

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
@@ -26,6 +26,27 @@ pnpm package:smoke
26
26
  local changes, `typecheck:local-contracts` and `test:local-contracts` resolve it
27
27
  from the sibling `geul-event-contracts` checkout.
28
28
 
29
+ ## Block Room inline content
30
+
31
+ Use `reconcileBlockRoomInlineContent` to set rich-text inline runs, including
32
+ their marks. It keeps the existing collaborative `Y.Text` handles and projects
33
+ character-level Y.Text attributes over the legacy per-run `styles` maps.
34
+ Deploy readers of character-level inline attributes before enabling writers.
35
+ The Web and Collab consumers use Block-room protocol version 2 to reject an
36
+ older editor before admission; the persisted canonical protobuf schema stays
37
+ unchanged.
38
+
39
+ `setAIDocumentField` routes whole inline `content` updates through this same
40
+ reconciler. `setBlockRoomAtomicValue` only writes catalog-declared scalar
41
+ fields; there is no generic payload-field setter for inline styles.
42
+
43
+ `replaceBlockRoomCollaborativeText` replaces the entire value of one
44
+ collaborative text leaf. It is intended for scalar text fields such as Page
45
+ section captions. On an inline text leaf, replacing the whole value also
46
+ removes that leaf's character-level Y.Text formatting while leaving any legacy
47
+ `styles` map in place. Use the inline reconciler when replacing inline text
48
+ that must retain or change marks.
49
+
29
50
  ## Release
30
51
 
31
52
  Release Please creates releases from `main`. npm publication uses GitHub
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@echovisionlab/geul-common",
3
3
  "description": "Shared TypeScript contracts and helpers for Geul editors, collaboration, localized content, media blocks, pages, posts, and runtime events.",
4
4
  "author": "state303 <state303@dsub.io>",
5
- "version": "0.2.0",
5
+ "version": "0.2.2",
6
6
  "private": false,
7
7
  "type": "module",
8
8
  "repository": {
@@ -15,6 +15,11 @@ import type {
15
15
  import * as Y from "yjs";
16
16
  import { fromYValue, isCollaborativeTextPath, toYValue } from "./internal.ts";
17
17
  import { blockRoomBaseNodes } from "./materialization.ts";
18
+ import { fromYInlineContent } from "./inline-content-projection.ts";
19
+ import {
20
+ isBlockRoomInlineContentRef,
21
+ reconcileBlockRoomInlineContent,
22
+ } from "./inline-content-mutations.ts";
18
23
  import {
19
24
  blockRoomLocaleValueRef,
20
25
  deleteBlockRoomLocalePresenceForBlocks,
@@ -166,6 +171,7 @@ function ensureYParent(node: Y.Map<unknown>, path: string): void {
166
171
  }
167
172
 
168
173
  function replaceYValue(
174
+ yDocument: Y.Doc,
169
175
  node: Y.Map<unknown>,
170
176
  ref: BlockRoomPayloadRef,
171
177
  value: JsonValue,
@@ -185,6 +191,15 @@ function replaceYValue(
185
191
  return;
186
192
  }
187
193
  if (current instanceof Y.Array && Array.isArray(value)) {
194
+ if (isBlockRoomInlineContentRef(ref)) {
195
+ reconcileBlockRoomInlineContent(
196
+ yDocument,
197
+ ref,
198
+ fromYInlineContent(current),
199
+ value,
200
+ );
201
+ return;
202
+ }
188
203
  if (current.length > 0) current.delete(0, current.length);
189
204
  if (value.length > 0) {
190
205
  current.insert(
@@ -301,6 +316,7 @@ function reconcileSourceTableLocale(yDocument: Y.Doc, blockId: string): void {
301
316
  };
302
317
  });
303
318
  replaceYValue(
319
+ yDocument,
304
320
  localeNode,
305
321
  { id: blockId, family: "rich_text", locale: true, path: "content" },
306
322
  { rows } as JsonValue,
@@ -346,6 +362,7 @@ function reconcileSourceImmersiveLocale(
346
362
  },
347
363
  );
348
364
  replaceYValue(
365
+ yDocument,
349
366
  localeNode,
350
367
  {
351
368
  id: blockId,
@@ -500,6 +517,7 @@ export function setAIDocumentField(
500
517
  operationFail("target_locale_scalar_required");
501
518
  }
502
519
  replaceYValue(
520
+ yDocument,
503
521
  node,
504
522
  ref,
505
523
  target.field === "table" ? sourceTableValue(next) : next,
@@ -541,7 +559,7 @@ export function attachAIDocumentFile(
541
559
  const target = blockTarget(targetValue);
542
560
  const { ref, descriptor } = fieldRef(yDocument, target, targetValue, true);
543
561
  if (descriptor?.type !== "file_attachment") operationFail("file:field");
544
- replaceYValue(roomNode(yDocument, ref), ref, {
562
+ replaceYValue(yDocument, roomNode(yDocument, ref), ref, {
545
563
  activeFileId: requiredHandle(file, "file:handle"),
546
564
  });
547
565
  }