@neta-art/cohub 6.0.0 → 8.0.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 +6 -5
- package/dist/board/animation.d.ts +2 -1
- package/dist/board/animation.js +0 -1
- package/dist/board/core/connections.js +4 -4
- package/dist/board/core/export-plan.js +1 -1
- package/dist/board/core/shape-types.js +0 -1
- package/dist/board/index.d.ts +6 -5
- package/dist/board/index.js +7 -7
- package/dist/board/mutation.d.ts +2 -11
- package/dist/board/mutation.js +2 -56
- package/dist/board/render/renderers/text-card-renderer.js +1 -1
- package/dist/board/semantic-document.d.ts +30 -0
- package/dist/board/semantic-document.js +271 -0
- package/dist/board/semantic-mutation.d.ts +10 -0
- package/dist/board/semantic-mutation.js +203 -0
- package/dist/chunks/http.d.ts +340 -317
- package/dist/chunks/http.js +477 -1784
- package/dist/chunks/transport.js +1 -1
- package/dist/chunks/websocket.d.ts +3677 -3151
- package/dist/chunks/websocket.js +1 -1
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +165 -119
- package/dist/index.js +1419 -446
- package/dist/protocol/dist/board-authoring.d.ts +1305 -1
- package/dist/protocol/dist/board-authoring.js +80 -6
- package/dist/protocol/dist/board-codec.d.ts +2 -2
- package/dist/protocol/dist/board-codec.js +19 -4
- package/dist/protocol/dist/board-composition.d.ts +126 -1
- package/dist/protocol/dist/board-composition.js +1 -9
- package/dist/protocol/dist/board-connection.d.ts +16 -16
- package/dist/protocol/dist/board-connection.js +16 -16
- package/dist/protocol/dist/board-document.d.ts +34 -3
- package/dist/protocol/dist/board-document.js +3 -1
- package/dist/protocol/dist/board-effect.d.ts +94 -0
- package/dist/protocol/dist/board-effect.js +53 -0
- package/dist/protocol/dist/board-json.js +16 -0
- package/dist/protocol/dist/board.d.ts +34 -164
- package/dist/protocol/dist/board.js +44 -45
- package/dist/protocol/dist/index.d.ts +8 -8
- package/dist/protocol/dist/realtime/types.d.ts +1 -1
- package/dist/types.d.ts +3 -1
- package/package.json +1 -2
- package/dist/board/codec.d.ts +0 -27
- package/dist/board/codec.js +0 -277
- package/dist/protocol/dist/board-content.js +0 -26
- package/dist/protocol/dist/board-upgrade.js +0 -2
- package/dist/protocol/dist/identifiers.js +0 -10
- package/dist/protocol/dist/index.js +0 -19
- package/dist/protocol/dist/provenance.js +0 -15
- package/dist/protocol/dist/public-identifiers.js +0 -38
- package/dist/protocol/dist/realtime/board-awareness.js +0 -119
- package/dist/protocol/dist/ui-command.js +0 -2
- package/dist/protocol/dist/work-promotion-stats.js +0 -11
- package/dist/protocol/dist/work-surface.js +0 -2
- package/dist/protocol/dist/work-view-stats.js +0 -3
- package/dist/protocol/dist/work.d.ts +0 -1
- /package/dist/protocol/dist/{board-upgrade.d.ts → app.d.ts} +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { BoardAuthoringItemSchema } from "../protocol/dist/board-authoring.js";
|
|
2
|
+
import { BoardAppearanceSchema, isUnknownItem } from "../protocol/dist/board-document.js";
|
|
3
|
+
import { applyBoardItemPatch } from "../protocol/dist/board-codec.js";
|
|
4
|
+
import { boardJsonEquals } from "../protocol/dist/board-json.js";
|
|
5
|
+
import { boardAuthoringItemToDocumentItem, boardItemToAuthoringItem } from "./semantic-document.js";
|
|
6
|
+
//#region src/board/semantic-mutation.ts
|
|
7
|
+
function semanticItem(item) {
|
|
8
|
+
const value = boardItemToAuthoringItem(item);
|
|
9
|
+
if (value) return value;
|
|
10
|
+
const raw = isUnknownItem(item) ? BoardAuthoringItemSchema.safeParse(item.raw) : null;
|
|
11
|
+
if (raw?.success) return raw.data;
|
|
12
|
+
throw new Error(`Cannot author unknown Board item ${item.id}; the item has no semantic extension schema`);
|
|
13
|
+
}
|
|
14
|
+
function mergePatchValue(before, after) {
|
|
15
|
+
if (boardJsonEquals(before, after)) return void 0;
|
|
16
|
+
if (after === void 0) return null;
|
|
17
|
+
if (before && after && typeof before === "object" && typeof after === "object" && !Array.isArray(before) && !Array.isArray(after)) {
|
|
18
|
+
const patch = {};
|
|
19
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)]);
|
|
20
|
+
for (const key of keys) {
|
|
21
|
+
const value = mergePatchValue(before[key], after[key]);
|
|
22
|
+
if (value !== void 0) patch[key] = value;
|
|
23
|
+
}
|
|
24
|
+
return patch;
|
|
25
|
+
}
|
|
26
|
+
return after;
|
|
27
|
+
}
|
|
28
|
+
function itemPatch(before, after) {
|
|
29
|
+
const beforeAuthoring = semanticItem(before);
|
|
30
|
+
const afterAuthoring = semanticItem(after);
|
|
31
|
+
const patch = {};
|
|
32
|
+
if (!boardJsonEquals(before.frame, after.frame)) patch.frame = after.frame;
|
|
33
|
+
const beforeParent = before.parentId ?? null;
|
|
34
|
+
const afterParent = after.parentId ?? null;
|
|
35
|
+
if (beforeParent !== afterParent) patch.parentId = afterParent;
|
|
36
|
+
if ((before.locked ?? false) !== (after.locked ?? false)) patch.locked = after.locked ?? null;
|
|
37
|
+
const metadata = mergePatchValue(before.metadata, after.metadata);
|
|
38
|
+
if (metadata !== void 0) patch.metadata = after.metadata === void 0 ? null : metadata;
|
|
39
|
+
const props = mergePatchValue(beforeAuthoring.props, afterAuthoring.props);
|
|
40
|
+
if (props !== void 0) patch.props = props;
|
|
41
|
+
const beforeStyle = "style" in beforeAuthoring ? beforeAuthoring.style : void 0;
|
|
42
|
+
const afterStyle = "style" in afterAuthoring ? afterAuthoring.style : void 0;
|
|
43
|
+
const style = mergePatchValue(beforeStyle, afterStyle);
|
|
44
|
+
if (style !== void 0) patch.style = afterStyle === void 0 ? null : style;
|
|
45
|
+
const beforeSource = "source" in beforeAuthoring ? beforeAuthoring.source : void 0;
|
|
46
|
+
const afterSource = "source" in afterAuthoring ? afterAuthoring.source : void 0;
|
|
47
|
+
const source = mergePatchValue(beforeSource, afterSource);
|
|
48
|
+
if (source !== void 0) patch.source = afterSource === void 0 ? null : source;
|
|
49
|
+
return Object.keys(patch).length ? patch : null;
|
|
50
|
+
}
|
|
51
|
+
function connectionPatch(before, after) {
|
|
52
|
+
const patch = {};
|
|
53
|
+
for (const key of [
|
|
54
|
+
"source",
|
|
55
|
+
"target",
|
|
56
|
+
"relation",
|
|
57
|
+
"direction",
|
|
58
|
+
"label",
|
|
59
|
+
"routing",
|
|
60
|
+
"style",
|
|
61
|
+
"metadata"
|
|
62
|
+
]) if (!boardJsonEquals(before[key], after[key])) patch[key] = after[key];
|
|
63
|
+
return Object.keys(patch).length ? patch : null;
|
|
64
|
+
}
|
|
65
|
+
/** Compile an editor document delta to the public semantic mutation command set. */
|
|
66
|
+
function boardDocumentToSemanticCommands(before, after) {
|
|
67
|
+
const commands = [];
|
|
68
|
+
if (!boardJsonEquals(before.appearance, after.appearance)) commands.push({
|
|
69
|
+
type: "board.patch",
|
|
70
|
+
patch: { metadataPatch: { appearance: after.appearance } }
|
|
71
|
+
});
|
|
72
|
+
const beforeConnections = new Map(before.connections.map((connection) => [connection.id, connection]));
|
|
73
|
+
const afterConnections = new Map(after.connections.map((connection) => [connection.id, connection]));
|
|
74
|
+
const beforeItems = new Map(before.items.map((item) => [item.id, item]));
|
|
75
|
+
const afterItems = new Map(after.items.map((item) => [item.id, item]));
|
|
76
|
+
for (const [id] of beforeConnections) if (!afterConnections.has(id)) commands.push({
|
|
77
|
+
type: "connection.delete",
|
|
78
|
+
connectionId: id
|
|
79
|
+
});
|
|
80
|
+
for (const item of after.items) {
|
|
81
|
+
const previous = beforeItems.get(item.id);
|
|
82
|
+
if (!previous) {
|
|
83
|
+
commands.push({
|
|
84
|
+
type: "item.create",
|
|
85
|
+
item: semanticItem(item)
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (previous.type !== item.type) {
|
|
90
|
+
commands.push({
|
|
91
|
+
type: "item.replace",
|
|
92
|
+
itemId: item.id,
|
|
93
|
+
item: semanticItem(item)
|
|
94
|
+
});
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const patch = itemPatch(previous, item);
|
|
98
|
+
if (patch) commands.push({
|
|
99
|
+
type: "item.patch",
|
|
100
|
+
itemId: item.id,
|
|
101
|
+
patch
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
for (const [id] of beforeItems) if (!afterItems.has(id)) commands.push({
|
|
105
|
+
type: "item.delete",
|
|
106
|
+
itemId: id,
|
|
107
|
+
cascade: false
|
|
108
|
+
});
|
|
109
|
+
const workingOrder = before.items.map((item) => item.id);
|
|
110
|
+
for (const item of after.items) if (!beforeItems.has(item.id)) workingOrder.push(item.id);
|
|
111
|
+
for (const [id] of beforeItems) if (!afterItems.has(id)) workingOrder.splice(workingOrder.indexOf(id), 1);
|
|
112
|
+
for (let index = 0; index < after.items.length; index += 1) {
|
|
113
|
+
const id = after.items[index]?.id;
|
|
114
|
+
if (!id || workingOrder[index] === id) continue;
|
|
115
|
+
const previousIndex = workingOrder.indexOf(id);
|
|
116
|
+
if (previousIndex < 0) continue;
|
|
117
|
+
workingOrder.splice(previousIndex, 1);
|
|
118
|
+
workingOrder.splice(index, 0, id);
|
|
119
|
+
commands.push({
|
|
120
|
+
type: "item.reorder",
|
|
121
|
+
itemId: id,
|
|
122
|
+
index
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
for (const connection of after.connections) {
|
|
126
|
+
const previous = beforeConnections.get(connection.id);
|
|
127
|
+
if (!previous) {
|
|
128
|
+
commands.push({
|
|
129
|
+
type: "connection.create",
|
|
130
|
+
connection
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const patch = connectionPatch(previous, connection);
|
|
135
|
+
if (patch) commands.push({
|
|
136
|
+
type: "connection.patch",
|
|
137
|
+
connectionId: connection.id,
|
|
138
|
+
patch
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return commands;
|
|
142
|
+
}
|
|
143
|
+
/** Apply public semantic commands to the local render document (undo/rebase). */
|
|
144
|
+
function applyBoardSemanticCommands(document, commands) {
|
|
145
|
+
let items = [...document.items];
|
|
146
|
+
let connections = [...document.connections];
|
|
147
|
+
let appearance = document.appearance;
|
|
148
|
+
for (const command of commands) {
|
|
149
|
+
if (command.type === "board.patch") {
|
|
150
|
+
const candidate = command.patch.metadataPatch?.appearance ?? command.patch.metadata?.appearance;
|
|
151
|
+
if (candidate !== void 0) {
|
|
152
|
+
const parsed = BoardAppearanceSchema.safeParse(candidate);
|
|
153
|
+
if (parsed.success) appearance = parsed.data;
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (command.type === "item.create") {
|
|
158
|
+
if (!items.some((item) => item.id === command.item.id)) items.push(boardAuthoringItemToDocumentItem(command.item));
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (command.type === "item.patch") {
|
|
162
|
+
items = items.map((item) => item.id === command.itemId ? boardAuthoringItemToDocumentItem(applyBoardItemPatch(semanticItem(item), command.patch)) : item);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (command.type === "item.replace") {
|
|
166
|
+
items = items.map((item) => item.id === command.itemId ? boardAuthoringItemToDocumentItem(command.item) : item);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (command.type === "item.delete") {
|
|
170
|
+
items = items.filter((item) => item.id !== command.itemId);
|
|
171
|
+
connections = connections.filter((connection) => connection.source.itemId !== command.itemId && connection.target.itemId !== command.itemId);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (command.type === "item.reorder") {
|
|
175
|
+
const index = items.findIndex((item) => item.id === command.itemId);
|
|
176
|
+
if (index < 0) continue;
|
|
177
|
+
const [item] = items.splice(index, 1);
|
|
178
|
+
if (item) items.splice(Math.min(command.index, items.length), 0, item);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (command.type === "connection.create") {
|
|
182
|
+
if (!connections.some((connection) => connection.id === command.connection.id)) connections.push(command.connection);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (command.type === "connection.patch") {
|
|
186
|
+
connections = connections.map((connection) => connection.id === command.connectionId ? {
|
|
187
|
+
...connection,
|
|
188
|
+
...command.patch,
|
|
189
|
+
id: connection.id
|
|
190
|
+
} : connection);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (command.type === "connection.delete") connections = connections.filter((connection) => connection.id !== command.connectionId);
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
...document,
|
|
197
|
+
appearance,
|
|
198
|
+
items,
|
|
199
|
+
connections
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
export { applyBoardSemanticCommands, boardDocumentToSemanticCommands };
|