@echovisionlab/geul-common 0.2.1 → 0.2.3
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 +21 -0
- package/package.json +1 -1
- package/src/collaboration/block-room-codec/ai-document-field-mutations.ts +19 -1
- package/src/collaboration/block-room-codec/inline-content-mutations.ts +883 -0
- package/src/collaboration/block-room-codec/inline-content-projection.ts +381 -0
- package/src/collaboration/block-room-codec/locale-presence.ts +14 -2
- package/src/collaboration/block-room-codec/materialization.ts +4 -3
- package/src/collaboration/block-room-codec.ts +1 -0
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.
|
|
5
|
+
"version": "0.2.3",
|
|
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
|
}
|