@dxos/plugin-illustrator 0.10.0 → 0.11.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/dist/lib/IllustratorPlugin.mjs +7 -3
- package/dist/lib/IllustratorPlugin.mjs.map +1 -1
- package/dist/lib/IllustratorPlugin.node.mjs +3 -3
- package/dist/lib/IllustratorPlugin.node.mjs.map +1 -1
- package/dist/lib/IllustratorPlugin.workerd.mjs +2 -2
- package/dist/lib/IllustratorPlugin.workerd.mjs.map +1 -1
- package/dist/lib/capabilities.mjs +2 -1
- package/dist/lib/capabilities.mjs.map +1 -1
- package/dist/lib/chunk-Drawing.mjs +64 -0
- package/dist/lib/chunk-Drawing.mjs.map +1 -0
- package/dist/lib/chunk-IllustratorCapabilities.mjs +2 -2
- package/dist/lib/chunk-IllustratorCapabilities.mjs.map +1 -1
- package/dist/lib/chunk-comment-config.mjs +3 -3
- package/dist/lib/chunk-comment-config.mjs.map +1 -1
- package/dist/lib/chunk-create-object.mjs +13 -12
- package/dist/lib/chunk-create-object.mjs.map +1 -1
- package/dist/lib/chunk-create.mjs +5 -4
- package/dist/lib/chunk-create.mjs.map +1 -1
- package/dist/lib/chunk-edit.mjs +4 -4
- package/dist/lib/chunk-edit.mjs.map +1 -1
- package/dist/lib/chunk-generate.mjs +20 -0
- package/dist/lib/chunk-generate.mjs.map +1 -0
- package/dist/lib/chunk-load-drawing.mjs +35 -0
- package/dist/lib/chunk-load-drawing.mjs.map +1 -0
- package/dist/lib/chunk-meta.mjs +2 -1
- package/dist/lib/chunk-meta.mjs.map +1 -1
- package/dist/lib/chunk-migrations.mjs +23 -0
- package/dist/lib/chunk-migrations.mjs.map +1 -0
- package/dist/lib/chunk-model.mjs +387 -4
- package/dist/lib/chunk-model.mjs.map +1 -1
- package/dist/lib/chunk-react-surface.mjs +14 -13
- package/dist/lib/chunk-react-surface.mjs.map +1 -1
- package/dist/lib/chunk-read.mjs +4 -4
- package/dist/lib/chunk-read.mjs.map +1 -1
- package/dist/lib/chunk-skill-definition.mjs +2 -2
- package/dist/lib/chunk-skill-definition.mjs.map +1 -1
- package/dist/lib/chunk-skills.mjs +10 -10
- package/dist/lib/chunk-skills.mjs.map +1 -1
- package/dist/lib/chunk-types.mjs +41 -49
- package/dist/lib/chunk-types.mjs.map +1 -1
- package/dist/lib/components.mjs +6 -6
- package/dist/lib/components.mjs.map +1 -1
- package/dist/lib/containers.mjs +17 -19
- package/dist/lib/containers.mjs.map +1 -1
- package/dist/lib/index.mjs +4 -3
- package/dist/lib/model.mjs +2 -2
- package/dist/lib/operations.mjs +1 -1
- package/dist/lib/operations.mjs.map +1 -1
- package/dist/lib/skills.mjs +1 -1
- package/dist/lib/translations.mjs +13 -13
- package/dist/lib/translations.mjs.map +1 -1
- package/dist/lib/types.mjs +3 -2
- package/dist/lib/util.mjs +2 -2
- package/dist/types/src/IllustratorPlugin.d.ts.map +1 -1
- package/dist/types/src/IllustratorPlugin.node.d.ts +1 -1
- package/dist/types/src/IllustratorPlugin.test.d.ts +2 -0
- package/dist/types/src/IllustratorPlugin.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +1 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/migrations.d.ts +7 -0
- package/dist/types/src/capabilities/migrations.d.ts.map +1 -0
- package/dist/types/src/capabilities/migrations.test.d.ts +2 -0
- package/dist/types/src/capabilities/migrations.test.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -1
- package/dist/types/src/components/CreateDrawingPanel.d.ts +15 -0
- package/dist/types/src/components/CreateDrawingPanel.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/DrawingArticle/DrawingArticle.d.ts +11 -0
- package/dist/types/src/containers/DrawingArticle/DrawingArticle.d.ts.map +1 -0
- package/dist/types/src/containers/DrawingArticle/index.d.ts +2 -0
- package/dist/types/src/containers/DrawingArticle/index.d.ts.map +1 -0
- package/dist/types/src/containers/DrawingCard/DrawingCard.d.ts +10 -0
- package/dist/types/src/containers/DrawingCard/DrawingCard.d.ts.map +1 -0
- package/dist/types/src/containers/DrawingCard/index.d.ts +2 -0
- package/dist/types/src/containers/DrawingCard/index.d.ts.map +1 -0
- package/dist/types/src/containers/index.d.ts +2 -2
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/model/builder.d.ts +18 -26
- package/dist/types/src/model/builder.d.ts.map +1 -1
- package/dist/types/src/model/content.d.ts +60 -0
- package/dist/types/src/model/content.d.ts.map +1 -0
- package/dist/types/src/model/index.d.ts +2 -0
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/mermaid.d.ts +38 -0
- package/dist/types/src/model/mermaid.d.ts.map +1 -0
- package/dist/types/src/model/mermaid.test.d.ts +3 -0
- package/dist/types/src/model/mermaid.test.d.ts.map +1 -0
- package/dist/types/src/operations/create.d.ts +2 -2
- package/dist/types/src/operations/create.d.ts.map +1 -1
- package/dist/types/src/operations/edit.d.ts +2 -2
- package/dist/types/src/operations/edit.d.ts.map +1 -1
- package/dist/types/src/operations/generate.d.ts +5 -0
- package/dist/types/src/operations/generate.d.ts.map +1 -0
- package/dist/types/src/operations/index.d.ts.map +1 -1
- package/dist/types/src/operations/read.d.ts +2 -2
- package/dist/types/src/operations/read.d.ts.map +1 -1
- package/dist/types/src/skills/{sketch-skill.d.ts → drawing-skill.d.ts} +1 -1
- package/dist/types/src/skills/drawing-skill.d.ts.map +1 -0
- package/dist/types/src/skills/index.d.ts +1 -1
- package/dist/types/src/skills/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +10 -10
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/Drawing.d.ts +50 -0
- package/dist/types/src/types/Drawing.d.ts.map +1 -0
- package/dist/types/src/types/{SketchOperation.d.ts → DrawingOperation.d.ts} +111 -5
- package/dist/types/src/types/DrawingOperation.d.ts.map +1 -0
- package/dist/types/src/types/IllustratorCapabilities.d.ts +4 -4
- package/dist/types/src/types/IllustratorCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/LegacySketch.d.ts +17 -0
- package/dist/types/src/types/LegacySketch.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +3 -2
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +18 -18
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/src/util/index.d.ts +1 -1
- package/dist/types/src/util/index.d.ts.map +1 -1
- package/dist/types/src/util/load-drawing.d.ts +22 -0
- package/dist/types/src/util/load-drawing.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +1 -0
- package/package.json +21 -19
- package/src/IllustratorPlugin.node.tsx +3 -3
- package/src/IllustratorPlugin.test.ts +32 -0
- package/src/IllustratorPlugin.tsx +15 -3
- package/src/IllustratorPlugin.workerd.tsx +2 -2
- package/src/capabilities/comment-config.ts +2 -2
- package/src/capabilities/create-object.ts +16 -14
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/migrations.test.ts +142 -0
- package/src/capabilities/migrations.ts +28 -0
- package/src/capabilities/react-surface.ts +36 -0
- package/src/capabilities/skill-definition.ts +2 -2
- package/src/components/{CreateSketchPanel.tsx → CreateDrawingPanel.tsx} +7 -7
- package/src/components/index.ts +1 -1
- package/src/containers/{SketchArticle/SketchArticle.tsx → DrawingArticle/DrawingArticle.tsx} +10 -11
- package/src/containers/{SketchArticle → DrawingArticle}/index.ts +1 -1
- package/src/containers/DrawingCard/DrawingCard.tsx +38 -0
- package/src/containers/{SketchCard → DrawingCard}/index.ts +1 -1
- package/src/containers/index.ts +2 -2
- package/src/model/builder.ts +34 -26
- package/src/model/content.ts +180 -0
- package/src/model/index.ts +2 -0
- package/src/model/mermaid.test.ts +116 -0
- package/src/model/mermaid.ts +299 -0
- package/src/operations/create.ts +6 -6
- package/src/operations/edit.ts +5 -5
- package/src/operations/generate.ts +25 -0
- package/src/operations/index.ts +1 -0
- package/src/operations/read.ts +5 -5
- package/src/skills/{sketch-skill.ts → drawing-skill.ts} +7 -7
- package/src/skills/index.ts +1 -1
- package/src/translations.ts +12 -12
- package/src/types/Drawing.ts +69 -0
- package/src/types/{SketchOperation.ts → DrawingOperation.ts} +28 -9
- package/src/types/IllustratorCapabilities.ts +4 -4
- package/src/types/LegacySketch.ts +25 -0
- package/src/types/index.ts +3 -2
- package/src/types/types.ts +18 -18
- package/src/util/index.ts +1 -1
- package/src/util/load-drawing.ts +48 -0
- package/dist/lib/chunk-load-sketch.mjs +0 -64
- package/dist/lib/chunk-load-sketch.mjs.map +0 -1
- package/dist/types/src/components/CreateSketchPanel.d.ts +0 -15
- package/dist/types/src/components/CreateSketchPanel.d.ts.map +0 -1
- package/dist/types/src/containers/SketchArticle/SketchArticle.d.ts +0 -11
- package/dist/types/src/containers/SketchArticle/SketchArticle.d.ts.map +0 -1
- package/dist/types/src/containers/SketchArticle/index.d.ts +0 -2
- package/dist/types/src/containers/SketchArticle/index.d.ts.map +0 -1
- package/dist/types/src/containers/SketchCard/SketchCard.d.ts +0 -10
- package/dist/types/src/containers/SketchCard/SketchCard.d.ts.map +0 -1
- package/dist/types/src/containers/SketchCard/index.d.ts +0 -2
- package/dist/types/src/containers/SketchCard/index.d.ts.map +0 -1
- package/dist/types/src/skills/sketch-skill.d.ts.map +0 -1
- package/dist/types/src/types/Sketch.d.ts +0 -50
- package/dist/types/src/types/Sketch.d.ts.map +0 -1
- package/dist/types/src/types/SketchOperation.d.ts.map +0 -1
- package/dist/types/src/util/load-sketch.d.ts +0 -37
- package/dist/types/src/util/load-sketch.d.ts.map +0 -1
- package/src/capabilities/react-surface.tsx +0 -37
- package/src/containers/SketchCard/SketchCard.tsx +0 -41
- package/src/types/Sketch.ts +0 -69
- package/src/util/load-sketch.ts +0 -74
package/dist/lib/chunk-model.mjs
CHANGED
|
@@ -1,7 +1,148 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-rolldown-runtime.mjs";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import { t as Canvas } from "./chunk-Drawing.mjs";
|
|
3
|
+
import { Obj } from "@dxos/echo";
|
|
4
4
|
import { invariant } from "@dxos/invariant";
|
|
5
|
+
import * as Schema from "effect/Schema";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
//#region src/model/content.ts
|
|
8
|
+
var __dxlog_file$2 = "/__w/dxos/dxos/packages/plugins/plugin-illustrator/src/model/content.ts";
|
|
9
|
+
/** Apply a batch of edit commands to the canvas content (mutates `content`). */
|
|
10
|
+
var applyCommands = (content, commands, handler) => {
|
|
11
|
+
handler.scaffold?.(content);
|
|
12
|
+
const upserted = /* @__PURE__ */ new Set();
|
|
13
|
+
let removed = 0;
|
|
14
|
+
const find = (objectId) => handler.read(content).scene.objects.find((object) => object.id === objectId);
|
|
15
|
+
const merge = (object, placement) => {
|
|
16
|
+
const records = handler.render(object, placement, content);
|
|
17
|
+
if (handler.merge) handler.merge(content, records);
|
|
18
|
+
else Object.assign(content, records);
|
|
19
|
+
};
|
|
20
|
+
const remove = (predicate) => {
|
|
21
|
+
let count = 0;
|
|
22
|
+
for (const [key, record] of Object.entries(content)) {
|
|
23
|
+
const identity = handler.identify(record);
|
|
24
|
+
if (identity && predicate(identity)) {
|
|
25
|
+
const isPart = identity.part !== void 0;
|
|
26
|
+
delete content[key];
|
|
27
|
+
if (!isPart) count++;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
handler.prune?.(content);
|
|
31
|
+
return count;
|
|
32
|
+
};
|
|
33
|
+
for (const command of commands) switch (command.op) {
|
|
34
|
+
case "upsert-object": {
|
|
35
|
+
const previous = find(command.object.id);
|
|
36
|
+
removed += remove((identity) => identity.object === command.object.id);
|
|
37
|
+
merge(command.object, {
|
|
38
|
+
origin: command.object.origin ?? previous?.origin ?? {
|
|
39
|
+
x: 0,
|
|
40
|
+
y: 0
|
|
41
|
+
},
|
|
42
|
+
scale: command.object.scale ?? previous?.scale ?? 1
|
|
43
|
+
});
|
|
44
|
+
upserted.add(command.object.id);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "upsert-elements": {
|
|
48
|
+
const previous = find(command.objectId);
|
|
49
|
+
invariant(previous, `unknown object: ${command.objectId} (use upsert-object to create it)`, {
|
|
50
|
+
"~LogMeta": "~LogMeta",
|
|
51
|
+
F: __dxlog_file$2,
|
|
52
|
+
L: 128,
|
|
53
|
+
S: void 0,
|
|
54
|
+
A: ["previous", "`unknown object: ${command.objectId} (use upsert-object to create it)`"]
|
|
55
|
+
});
|
|
56
|
+
const ids = new Set(command.elements.map((element) => element.id));
|
|
57
|
+
removed += remove((identity) => identity.object === command.objectId && ids.has(identity.element));
|
|
58
|
+
merge({
|
|
59
|
+
id: command.objectId,
|
|
60
|
+
elements: command.elements
|
|
61
|
+
}, previous);
|
|
62
|
+
upserted.add(command.objectId);
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case "remove-elements": {
|
|
66
|
+
const ids = new Set(command.elementIds);
|
|
67
|
+
removed += remove((identity) => identity.object === command.objectId && ids.has(identity.element));
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case "remove-object":
|
|
71
|
+
removed += remove((identity) => identity.object === command.objectId);
|
|
72
|
+
break;
|
|
73
|
+
case "move-object": {
|
|
74
|
+
const previous = find(command.objectId);
|
|
75
|
+
invariant(previous, `unknown object: ${command.objectId}`, {
|
|
76
|
+
"~LogMeta": "~LogMeta",
|
|
77
|
+
F: __dxlog_file$2,
|
|
78
|
+
L: 149,
|
|
79
|
+
S: void 0,
|
|
80
|
+
A: ["previous", "`unknown object: ${command.objectId}`"]
|
|
81
|
+
});
|
|
82
|
+
const delta = {
|
|
83
|
+
x: command.origin.x - previous.origin.x,
|
|
84
|
+
y: command.origin.y - previous.origin.y
|
|
85
|
+
};
|
|
86
|
+
for (const record of Object.values(content)) if (handler.identify(record)?.object === command.objectId) handler.translate(record, delta);
|
|
87
|
+
upserted.add(command.objectId);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
upserted: [...upserted],
|
|
93
|
+
removed
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/** Seed a fractional-index counter past any existing `a<n>` indexes. */
|
|
97
|
+
var nextIndex = (content, isCounted = () => true) => {
|
|
98
|
+
let max = 0;
|
|
99
|
+
let count = 0;
|
|
100
|
+
for (const record of Object.values(content)) {
|
|
101
|
+
if (!record || !isCounted(record)) continue;
|
|
102
|
+
count++;
|
|
103
|
+
const match = /^a(\d+)$/.exec(record.index ?? "");
|
|
104
|
+
if (match) max = Math.max(max, Number(match[1]));
|
|
105
|
+
}
|
|
106
|
+
return Math.max(max, count);
|
|
107
|
+
};
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/model/builder.ts
|
|
110
|
+
var __dxlog_file$1 = "/__w/dxos/dxos/packages/plugins/plugin-illustrator/src/model/builder.ts";
|
|
111
|
+
/**
|
|
112
|
+
* Builds a {@link DrawingBuilder} from the renderer's {@link ContentHandler}, so a variant only
|
|
113
|
+
* supplies its record encoding and inherits the ECHO write semantics and command bookkeeping.
|
|
114
|
+
*/
|
|
115
|
+
var makeBuilder = ({ schema, handler }) => ({
|
|
116
|
+
schema,
|
|
117
|
+
read: (canvas) => {
|
|
118
|
+
invariant(Obj.instanceOf(Canvas, canvas), void 0, {
|
|
119
|
+
"~LogMeta": "~LogMeta",
|
|
120
|
+
F: __dxlog_file$1,
|
|
121
|
+
L: 38,
|
|
122
|
+
S: void 0,
|
|
123
|
+
A: ["Obj.instanceOf(Drawing.Canvas, canvas)", ""]
|
|
124
|
+
});
|
|
125
|
+
return handler.read(canvas.content);
|
|
126
|
+
},
|
|
127
|
+
apply: (canvas, commands) => {
|
|
128
|
+
invariant(Obj.instanceOf(Canvas, canvas), void 0, {
|
|
129
|
+
"~LogMeta": "~LogMeta",
|
|
130
|
+
F: __dxlog_file$1,
|
|
131
|
+
L: 42,
|
|
132
|
+
S: void 0,
|
|
133
|
+
A: ["Obj.instanceOf(Drawing.Canvas, canvas)", ""]
|
|
134
|
+
});
|
|
135
|
+
let result = {
|
|
136
|
+
upserted: [],
|
|
137
|
+
removed: 0
|
|
138
|
+
};
|
|
139
|
+
Obj.update(canvas, (canvas) => {
|
|
140
|
+
result = applyCommands(canvas.content, commands, handler);
|
|
141
|
+
});
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
//#endregion
|
|
5
146
|
//#region src/model/scene.ts
|
|
6
147
|
var scene_exports = /* @__PURE__ */ __exportAll({
|
|
7
148
|
Arc: () => Arc,
|
|
@@ -159,7 +300,7 @@ var MoveObject = Schema.Struct({
|
|
|
159
300
|
var Command = Schema.Union(UpsertObject, UpsertElements, RemoveElements, RemoveObject, MoveObject);
|
|
160
301
|
//#endregion
|
|
161
302
|
//#region src/model/dialect.ts
|
|
162
|
-
var __dxlog_file = "/
|
|
303
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-illustrator/src/model/dialect.ts";
|
|
163
304
|
/** The core dialect: input is already scene edit commands (identity compile). */
|
|
164
305
|
var sceneDialect = {
|
|
165
306
|
id: "scene",
|
|
@@ -190,13 +331,255 @@ var DialectRegistry = class {
|
|
|
190
331
|
}
|
|
191
332
|
};
|
|
192
333
|
//#endregion
|
|
334
|
+
//#region src/model/mermaid.ts
|
|
335
|
+
var mermaid_exports = /* @__PURE__ */ __exportAll({
|
|
336
|
+
compile: () => compile,
|
|
337
|
+
parse: () => parse
|
|
338
|
+
});
|
|
339
|
+
var DIRECTIONS = [
|
|
340
|
+
"TB",
|
|
341
|
+
"BT",
|
|
342
|
+
"LR",
|
|
343
|
+
"RL"
|
|
344
|
+
];
|
|
345
|
+
var NODE = /^([A-Za-z0-9_-]+)(?:\[(.*?)\]|\((.*?)\)|\{(.*?)\})?$/;
|
|
346
|
+
var EDGE = /^(.+?)\s*(-->|---|-\.->|==>)\s*(?:\|(.*?)\|\s*)?(.+)$/;
|
|
347
|
+
var SUBGRAPH = /^subgraph\s+([A-Za-z0-9_-]+)(?:\s*\[(.*?)\])?\s*$/;
|
|
348
|
+
var unquote = (value) => value.trim().replace(/^"(.*)"$/, "$1");
|
|
349
|
+
/** Parse a mermaid flowchart into a neutral graph. Unrecognised lines are ignored. */
|
|
350
|
+
var parse = (source) => {
|
|
351
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
352
|
+
const groups = [];
|
|
353
|
+
const edges = [];
|
|
354
|
+
let direction = "TB";
|
|
355
|
+
const stack = [];
|
|
356
|
+
const declare = (token) => {
|
|
357
|
+
const match = NODE.exec(token.trim());
|
|
358
|
+
if (!match) return;
|
|
359
|
+
const [, id, square, round, curly] = match;
|
|
360
|
+
const label = unquote(square ?? round ?? curly ?? id);
|
|
361
|
+
const group = stack[stack.length - 1];
|
|
362
|
+
const existing = nodes.get(id);
|
|
363
|
+
if (existing) {
|
|
364
|
+
if (square ?? round ?? curly) existing.label = label;
|
|
365
|
+
return id;
|
|
366
|
+
}
|
|
367
|
+
nodes.set(id, {
|
|
368
|
+
id,
|
|
369
|
+
label,
|
|
370
|
+
...group ? { group } : {}
|
|
371
|
+
});
|
|
372
|
+
if (group) groups.find((entry) => entry.id === group)?.children.push(id);
|
|
373
|
+
return id;
|
|
374
|
+
};
|
|
375
|
+
for (const raw of source.split("\n")) {
|
|
376
|
+
const line = raw.trim();
|
|
377
|
+
if (!line || line.startsWith("%%")) continue;
|
|
378
|
+
const header = /^(?:flowchart|graph)\s+([A-Za-z]{2})$/.exec(line);
|
|
379
|
+
if (header) {
|
|
380
|
+
const value = header[1].toUpperCase();
|
|
381
|
+
direction = DIRECTIONS.includes(value) ? value : "TB";
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const subgraph = SUBGRAPH.exec(line);
|
|
385
|
+
if (subgraph) {
|
|
386
|
+
const [, id, label] = subgraph;
|
|
387
|
+
groups.push({
|
|
388
|
+
id,
|
|
389
|
+
label: unquote(label ?? id),
|
|
390
|
+
children: []
|
|
391
|
+
});
|
|
392
|
+
stack.push(id);
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
if (line === "end") {
|
|
396
|
+
stack.pop();
|
|
397
|
+
continue;
|
|
398
|
+
}
|
|
399
|
+
const edge = EDGE.exec(line);
|
|
400
|
+
if (edge) {
|
|
401
|
+
const [, from, , label, to] = edge;
|
|
402
|
+
const fromId = declare(from);
|
|
403
|
+
const toId = declare(to);
|
|
404
|
+
if (fromId && toId) edges.push({
|
|
405
|
+
from: fromId,
|
|
406
|
+
to: toId,
|
|
407
|
+
...label ? { label: unquote(label) } : {}
|
|
408
|
+
});
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
declare(line);
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
direction,
|
|
415
|
+
nodes: [...nodes.values()],
|
|
416
|
+
groups,
|
|
417
|
+
edges
|
|
418
|
+
};
|
|
419
|
+
};
|
|
420
|
+
/** Layout constants in scene units. */
|
|
421
|
+
var NODE_W = 100;
|
|
422
|
+
var NODE_H = 50;
|
|
423
|
+
var GAP_CROSS = 40;
|
|
424
|
+
var GROUP_PAD = 24;
|
|
425
|
+
/**
|
|
426
|
+
* Edges that close a cycle, found by DFS: an edge into a node still on the stack points backwards.
|
|
427
|
+
* Ranking ignores them, so `C --> Y --> C` ranks C by its forward predecessors alone instead of
|
|
428
|
+
* chasing the loop.
|
|
429
|
+
*/
|
|
430
|
+
var backEdges = (graph) => {
|
|
431
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
432
|
+
for (const edge of graph.edges) outgoing.set(edge.from, [...outgoing.get(edge.from) ?? [], edge]);
|
|
433
|
+
const back = /* @__PURE__ */ new Set();
|
|
434
|
+
const done = /* @__PURE__ */ new Set();
|
|
435
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
436
|
+
const visit = (id) => {
|
|
437
|
+
onStack.add(id);
|
|
438
|
+
for (const edge of outgoing.get(id) ?? []) if (onStack.has(edge.to)) back.add(edge);
|
|
439
|
+
else if (!done.has(edge.to)) visit(edge.to);
|
|
440
|
+
onStack.delete(id);
|
|
441
|
+
done.add(id);
|
|
442
|
+
};
|
|
443
|
+
const targets = new Set(graph.edges.map((edge) => edge.to));
|
|
444
|
+
for (const node of graph.nodes) if (!targets.has(node.id) && !done.has(node.id)) visit(node.id);
|
|
445
|
+
for (const node of graph.nodes) if (!done.has(node.id)) visit(node.id);
|
|
446
|
+
return back;
|
|
447
|
+
};
|
|
448
|
+
/** Assign each node a rank one past its deepest forward predecessor. */
|
|
449
|
+
var rank = (graph) => {
|
|
450
|
+
const back = backEdges(graph);
|
|
451
|
+
const forward = graph.edges.filter((edge) => !back.has(edge));
|
|
452
|
+
const ranks = new Map(graph.nodes.map((node) => [node.id, 0]));
|
|
453
|
+
for (let pass = 0; pass < graph.nodes.length; pass++) {
|
|
454
|
+
let changed = false;
|
|
455
|
+
for (const edge of forward) {
|
|
456
|
+
const next = (ranks.get(edge.from) ?? 0) + 1;
|
|
457
|
+
if (next > (ranks.get(edge.to) ?? 0)) {
|
|
458
|
+
ranks.set(edge.to, next);
|
|
459
|
+
changed = true;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (!changed) break;
|
|
463
|
+
}
|
|
464
|
+
return ranks;
|
|
465
|
+
};
|
|
466
|
+
/**
|
|
467
|
+
* Compile a mermaid flowchart into scene commands: one world object per node (element `box`),
|
|
468
|
+
* one per subgraph frame, and an `edges` object holding the connectors as bound arrows.
|
|
469
|
+
*/
|
|
470
|
+
var compile = (source, options = {}) => {
|
|
471
|
+
const graph = parse(source);
|
|
472
|
+
const { origin = {
|
|
473
|
+
x: 0,
|
|
474
|
+
y: 0
|
|
475
|
+
}, scale = 1 } = options;
|
|
476
|
+
const ranks = rank(graph);
|
|
477
|
+
const horizontal = graph.direction === "LR" || graph.direction === "RL";
|
|
478
|
+
const lanes = /* @__PURE__ */ new Map();
|
|
479
|
+
for (const node of graph.nodes) {
|
|
480
|
+
const value = ranks.get(node.id) ?? 0;
|
|
481
|
+
lanes.set(value, [...lanes.get(value) ?? [], node]);
|
|
482
|
+
}
|
|
483
|
+
const widest = Math.max(...[...lanes.values()].map((lane) => lane.length), 1);
|
|
484
|
+
const positions = /* @__PURE__ */ new Map();
|
|
485
|
+
for (const [lane, members] of lanes) {
|
|
486
|
+
const span = members.length * NODE_W + (members.length - 1) * GAP_CROSS;
|
|
487
|
+
const offset = (widest * NODE_W + (widest - 1) * GAP_CROSS - span) / 2;
|
|
488
|
+
members.forEach((node, index) => {
|
|
489
|
+
const cross = offset + index * 140;
|
|
490
|
+
const main = lane * 110;
|
|
491
|
+
positions.set(node.id, horizontal ? {
|
|
492
|
+
x: main,
|
|
493
|
+
y: cross
|
|
494
|
+
} : {
|
|
495
|
+
x: cross,
|
|
496
|
+
y: main
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
const commands = [];
|
|
501
|
+
for (const group of graph.groups) {
|
|
502
|
+
const members = group.children.map((id) => positions.get(id)).filter((point) => !!point);
|
|
503
|
+
if (members.length === 0) continue;
|
|
504
|
+
const minX = Math.min(...members.map((point) => point.x)) - GROUP_PAD;
|
|
505
|
+
const minY = Math.min(...members.map((point) => point.y)) - GROUP_PAD;
|
|
506
|
+
const maxX = Math.max(...members.map((point) => point.x)) + NODE_W + GROUP_PAD;
|
|
507
|
+
const maxY = Math.max(...members.map((point) => point.y)) + NODE_H + GROUP_PAD;
|
|
508
|
+
commands.push({
|
|
509
|
+
op: "upsert-object",
|
|
510
|
+
object: {
|
|
511
|
+
id: group.id,
|
|
512
|
+
origin: {
|
|
513
|
+
x: origin.x + minX * scale,
|
|
514
|
+
y: origin.y + minY * scale
|
|
515
|
+
},
|
|
516
|
+
scale,
|
|
517
|
+
elements: [{
|
|
518
|
+
kind: "rect",
|
|
519
|
+
id: "frame",
|
|
520
|
+
x: 0,
|
|
521
|
+
y: 0,
|
|
522
|
+
w: maxX - minX,
|
|
523
|
+
h: maxY - minY,
|
|
524
|
+
stroke: "dashed",
|
|
525
|
+
color: "grey",
|
|
526
|
+
...group.label.trim() ? { text: group.label } : {}
|
|
527
|
+
}]
|
|
528
|
+
}
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
for (const node of graph.nodes) {
|
|
532
|
+
const point = positions.get(node.id);
|
|
533
|
+
commands.push({
|
|
534
|
+
op: "upsert-object",
|
|
535
|
+
object: {
|
|
536
|
+
id: node.id,
|
|
537
|
+
origin: {
|
|
538
|
+
x: origin.x + point.x * scale,
|
|
539
|
+
y: origin.y + point.y * scale
|
|
540
|
+
},
|
|
541
|
+
scale,
|
|
542
|
+
elements: [{
|
|
543
|
+
kind: "rect",
|
|
544
|
+
id: "box",
|
|
545
|
+
x: 0,
|
|
546
|
+
y: 0,
|
|
547
|
+
w: NODE_W,
|
|
548
|
+
h: NODE_H,
|
|
549
|
+
text: node.label
|
|
550
|
+
}]
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
if (graph.edges.length > 0) commands.push({
|
|
555
|
+
op: "upsert-object",
|
|
556
|
+
object: {
|
|
557
|
+
id: "edges",
|
|
558
|
+
origin,
|
|
559
|
+
scale,
|
|
560
|
+
elements: graph.edges.map((edge) => ({
|
|
561
|
+
kind: "arrow",
|
|
562
|
+
id: `${edge.from}-${edge.to}`,
|
|
563
|
+
from: `${edge.from}/box`,
|
|
564
|
+
to: `${edge.to}/box`,
|
|
565
|
+
...edge.label ? { text: edge.label } : {}
|
|
566
|
+
}))
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
return commands;
|
|
570
|
+
};
|
|
571
|
+
//#endregion
|
|
193
572
|
//#region src/model/index.ts
|
|
194
573
|
var model_exports = /* @__PURE__ */ __exportAll({
|
|
195
574
|
DialectRegistry: () => DialectRegistry,
|
|
575
|
+
Mermaid: () => mermaid_exports,
|
|
196
576
|
Scene: () => scene_exports,
|
|
577
|
+
applyCommands: () => applyCommands,
|
|
578
|
+
makeBuilder: () => makeBuilder,
|
|
579
|
+
nextIndex: () => nextIndex,
|
|
197
580
|
sceneDialect: () => sceneDialect
|
|
198
581
|
});
|
|
199
582
|
//#endregion
|
|
200
|
-
export { scene_exports as i,
|
|
583
|
+
export { scene_exports as a, nextIndex as c, sceneDialect as i, mermaid_exports as n, makeBuilder as o, DialectRegistry as r, applyCommands as s, model_exports as t };
|
|
201
584
|
|
|
202
585
|
//# sourceMappingURL=chunk-model.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-model.mjs","names":[],"sources":["../../src/model/scene.ts","../../src/model/dialect.ts","../../src/model/index.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Backend-neutral scene DSL: a diagram is a set of named world objects (\"face\", \"hat\"),\n// each composed of graphical elements (rect, ellipse, line, curve, text, arrow) authored\n// in object-local units. A backend compiler (tldraw today) maps the scene onto the\n// concrete canvas; see `render.ts` / `read.ts`.\n//\n\nimport * as Schema from 'effect/Schema';\n\nexport const Color = Schema.Literal(\n 'black',\n 'grey',\n 'light-violet',\n 'violet',\n 'blue',\n 'light-blue',\n 'yellow',\n 'orange',\n 'green',\n 'light-green',\n 'light-red',\n 'red',\n 'white',\n);\nexport type Color = Schema.Schema.Type<typeof Color>;\n\nexport const Fill = Schema.Literal('none', 'solid', 'pattern');\nexport type Fill = Schema.Schema.Type<typeof Fill>;\n\nexport const Stroke = Schema.Literal('sketchy', 'solid', 'dashed', 'dotted');\nexport type Stroke = Schema.Schema.Type<typeof Stroke>;\n\nexport const Weight = Schema.Literal('s', 'm', 'l', 'xl');\nexport type Weight = Schema.Schema.Type<typeof Weight>;\n\nexport const Point = Schema.Struct({\n x: Schema.Number,\n y: Schema.Number,\n});\nexport type Point = Schema.Schema.Type<typeof Point>;\n\n/** Style props shared by all elements; every field is optional with sensible defaults. */\nconst styleFields = {\n color: Schema.optional(Color).annotations({ description: 'Stroke/text color.' }),\n fill: Schema.optional(Fill).annotations({ description: 'Interior fill of closed shapes.' }),\n stroke: Schema.optional(Stroke).annotations({ description: 'Stroke rendering; sketchy is hand-drawn.' }),\n weight: Schema.optional(Weight).annotations({ description: 'Stroke weight / text size.' }),\n};\n\nconst id = Schema.String.annotations({\n description: 'Stable element id, unique within the object (e.g. \"left-eye\"). Used to edit or delete the element.',\n});\n\n/** Closed shape drawn inside a local bounding box. */\nexport const Box = Schema.Struct({\n kind: Schema.Literal('rect', 'ellipse', 'diamond', 'triangle'),\n id,\n x: Schema.Number.annotations({ description: 'Left edge (object-local units).' }),\n y: Schema.Number.annotations({ description: 'Top edge (object-local units).' }),\n w: Schema.Number,\n h: Schema.Number,\n rotation: Schema.optional(Schema.Number).annotations({ description: 'Clockwise rotation in degrees.' }),\n text: Schema.optional(Schema.String).annotations({ description: 'Centered label.' }),\n ...styleFields,\n});\nexport type Box = Schema.Schema.Type<typeof Box>;\n\n/** Circle sugar; reads back as an ellipse. */\nexport const Circle = Schema.Struct({\n kind: Schema.Literal('circle'),\n id,\n cx: Schema.Number.annotations({ description: 'Center x (object-local units).' }),\n cy: Schema.Number.annotations({ description: 'Center y (object-local units).' }),\n r: Schema.Number,\n text: Schema.optional(Schema.String),\n ...styleFields,\n});\nexport type Circle = Schema.Schema.Type<typeof Circle>;\n\n/** Straight segment or open polyline through the given points. */\nexport const Polyline = Schema.Struct({\n kind: Schema.Literal('line'),\n id,\n points: Schema.Array(Point).annotations({ description: 'Two or more points (object-local units).' }),\n closed: Schema.optional(Schema.Boolean).annotations({ description: 'Close the path back to the first point.' }),\n ...styleFields,\n});\nexport type Polyline = Schema.Schema.Type<typeof Polyline>;\n\n/** Smooth curve through the given points (spline). */\nexport const Curve = Schema.Struct({\n kind: Schema.Literal('curve'),\n id,\n points: Schema.Array(Point).annotations({ description: 'Control points the curve passes through.' }),\n ...styleFields,\n});\nexport type Curve = Schema.Schema.Type<typeof Curve>;\n\n/**\n * Circular arc sugar; reads back as a curve. Angles are degrees, measured clockwise from\n * the positive x-axis in screen coordinates (y grows downward): 0–180 is the lower half\n * (a smile), 180–360 the upper half (a frown).\n */\nexport const Arc = Schema.Struct({\n kind: Schema.Literal('arc'),\n id,\n cx: Schema.Number,\n cy: Schema.Number,\n r: Schema.Number,\n startAngle: Schema.Number,\n endAngle: Schema.Number,\n ...styleFields,\n});\nexport type Arc = Schema.Schema.Type<typeof Arc>;\n\n/** Free-standing text. */\nexport const Text = Schema.Struct({\n kind: Schema.Literal('text'),\n id,\n x: Schema.Number,\n y: Schema.Number,\n w: Schema.optional(Schema.Number).annotations({ description: 'Wrap width; omit for auto-size.' }),\n text: Schema.String,\n ...styleFields,\n});\nexport type Text = Schema.Schema.Type<typeof Text>;\n\n/**\n * Connector. Endpoints are element refs — `\"<elementId>\"` within the same object or\n * `\"<objectId>/<elementId>\"` across objects — or explicit local points. Bound endpoints\n * track their target when it moves.\n */\nexport const Arrow = Schema.Struct({\n kind: Schema.Literal('arrow'),\n id,\n from: Schema.optional(Schema.String).annotations({ description: 'Source element ref.' }),\n to: Schema.optional(Schema.String).annotations({ description: 'Target element ref.' }),\n start: Schema.optional(Point).annotations({ description: 'Explicit start (used when `from` is omitted).' }),\n end: Schema.optional(Point).annotations({ description: 'Explicit end (used when `to` is omitted).' }),\n text: Schema.optional(Schema.String).annotations({ description: 'Label at the arrow midpoint.' }),\n ...styleFields,\n});\nexport type Arrow = Schema.Schema.Type<typeof Arrow>;\n\nexport const Element = Schema.Union(Box, Circle, Polyline, Curve, Arc, Text, Arrow);\nexport type Element = Schema.Schema.Type<typeof Element>;\n\n/**\n * A semantic group of elements (\"face\", \"hat\") authored in its own local unit space.\n * `origin` (canvas px) and `scale` (px per unit) place it on the canvas:\n * `canvas = origin + local * scale`. On read, `origin` is derived as the top-left of the\n * object's bounding box, so the model survives users dragging shapes around.\n */\nexport const WorldObject = Schema.Struct({\n id: Schema.String.annotations({\n description: 'Stable object id naming the thing depicted (e.g. \"face\", \"hat\").',\n }),\n origin: Schema.optional(Point).annotations({\n description: 'Canvas position (px). Omit on upsert to keep the current position.',\n }),\n scale: Schema.optional(Schema.Number).annotations({ description: 'Canvas px per local unit (default 1).' }),\n elements: Schema.Array(Element),\n});\nexport type WorldObject = Schema.Schema.Type<typeof WorldObject>;\n\nexport const Scene = Schema.Struct({\n objects: Schema.Array(WorldObject),\n});\nexport type Scene = Schema.Schema.Type<typeof Scene>;\n\n//\n// Edit commands.\n//\n\nexport const UpsertObject = Schema.Struct({\n op: Schema.Literal('upsert-object'),\n object: WorldObject,\n}).annotations({ description: 'Create an object, or replace an existing one wholesale (same id).' });\n\nexport const UpsertElements = Schema.Struct({\n op: Schema.Literal('upsert-elements'),\n objectId: Schema.String,\n elements: Schema.Array(Element),\n}).annotations({ description: 'Add elements to an existing object, replacing any with matching ids.' });\n\nexport const RemoveElements = Schema.Struct({\n op: Schema.Literal('remove-elements'),\n objectId: Schema.String,\n elementIds: Schema.Array(Schema.String),\n});\n\nexport const RemoveObject = Schema.Struct({\n op: Schema.Literal('remove-object'),\n objectId: Schema.String,\n});\n\nexport const MoveObject = Schema.Struct({\n op: Schema.Literal('move-object'),\n objectId: Schema.String,\n origin: Point.annotations({ description: 'New canvas position (px) for the object top-left.' }),\n});\n\nexport const Command = Schema.Union(UpsertObject, UpsertElements, RemoveElements, RemoveObject, MoveObject);\nexport type Command = Schema.Schema.Type<typeof Command>;\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Extension point for higher-level diagram languages (mermaid, d2, sequence, uml-class, …).\n// A dialect compiles its input into scene edit commands — owning any layout it needs — so its\n// output lands as ordinary world objects and stays editable by id. Mirrors the architecture\n// shared by Mermaid/D2/Kroki: dialect → intermediate positioned model → renderer.\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\n\nimport { invariant } from '@dxos/invariant';\n\nimport * as Scene from './scene';\n\nexport type Dialect<Input = any> = {\n id: string;\n description: string;\n input: Schema.Schema<Input, any>;\n compile: (input: Input) => Effect.Effect<readonly Scene.Command[]>;\n};\n\n/** The core dialect: input is already scene edit commands (identity compile). */\nexport const sceneDialect: Dialect<readonly Scene.Command[]> = {\n id: 'scene',\n description: 'Positioned world objects and elements; the agent does the layout.',\n input: Schema.Array(Scene.Command),\n compile: Effect.succeed,\n};\n\nexport class DialectRegistry {\n readonly #dialects = new Map<string, Dialect>();\n\n constructor(dialects: Dialect[] = [sceneDialect]) {\n dialects.forEach((dialect) => this.register(dialect));\n }\n\n register(dialect: Dialect): void {\n invariant(!this.#dialects.has(dialect.id), `duplicate dialect: ${dialect.id}`);\n this.#dialects.set(dialect.id, dialect);\n }\n\n get(id: string): Dialect | undefined {\n return this.#dialects.get(id);\n }\n\n list(): Dialect[] {\n return [...this.#dialects.values()];\n }\n}\n","//\n// Copyright 2026 DXOS.org\n//\n\nexport * from './builder';\nexport * from './dialect';\nexport * as Scene from './scene';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chunk-model.mjs","names":[],"sources":["../../src/model/content.ts","../../src/model/builder.ts","../../src/model/scene.ts","../../src/model/dialect.ts","../../src/model/mermaid.ts","../../src/model/index.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Renderer-neutral command application over a canvas content map. Every renderer stores its\n// canvas as `Record<recordId, record>` and stamps DSL identity onto each managed record, so the\n// upsert/remove/move bookkeeping is identical; only the encoding differs. Renderers supply that\n// encoding via `ContentHandler` and inherit the command semantics.\n//\n\nimport { invariant } from '@dxos/invariant';\n\nimport type * as Scene from './scene';\n\n/** Opaque map of record id → renderer record. */\nexport type ContentMap = Record<string, any>;\n\n/** DSL identity stamped onto a managed record. */\nexport type Identity = {\n object: string;\n element: string;\n /** Set on companion records that belong to an element rather than being one (e.g. arrow labels). */\n part?: string;\n};\n\n/** Where an object sits on the canvas: `canvas = origin + local * scale`. */\nexport type Placement = {\n origin: Scene.Point;\n scale: number;\n};\n\n/** An object as accepted by the renderer's compiler; `upsert-elements` supplies only a subset. */\nexport type ObjectInput = Scene.WorldObject | { id: string; elements: readonly Scene.Element[] };\n\n/** A world object as derived from the canvas: placement is always resolved. */\nexport type ReadWorldObject = Scene.WorldObject & Placement;\n\nexport type ReadResult = {\n scene: { objects: ReadWorldObject[] };\n /** Records on the canvas not managed by the DSL (drawn by hand). */\n unmanaged: number;\n};\n\nexport type ApplyResult = {\n /** Object ids created or modified. */\n upserted: string[];\n /** Records removed. */\n removed: number;\n};\n\n/**\n * The renderer-specific half of command application: how records carry identity, how objects\n * compile to records, and any bookkeeping the renderer's store requires.\n */\nexport type ContentHandler = {\n /** DSL identity for a record, or undefined when the record isn't managed by the DSL. */\n identify: (record: any) => Identity | undefined;\n /** Compile an object's elements into records keyed by record id. */\n render: (object: ObjectInput, placement: Placement, content: ContentMap) => ContentMap;\n /** Derive the scene from the content map. */\n read: (content: ContentMap) => ReadResult;\n /** Translate an object move into a per-record mutation. */\n translate: (record: any, delta: Scene.Point) => void;\n /** Create any scaffolding the renderer needs before its first record (e.g. a page). */\n scaffold?: (content: ContentMap) => void;\n /** Merge compiled records into the content map; defaults to a plain assign. */\n merge?: (content: ContentMap, records: ContentMap) => void;\n /** Clean up after deletions (e.g. drop bindings left dangling). */\n prune?: (content: ContentMap) => void;\n};\n\n/** Apply a batch of edit commands to the canvas content (mutates `content`). */\nexport const applyCommands = (\n content: ContentMap,\n commands: readonly Scene.Command[],\n handler: ContentHandler,\n): ApplyResult => {\n handler.scaffold?.(content);\n const upserted = new Set<string>();\n let removed = 0;\n\n const find = (objectId: string) => handler.read(content).scene.objects.find((object) => object.id === objectId);\n\n const merge = (object: ObjectInput, placement: Placement) => {\n const records = handler.render(object, placement, content);\n if (handler.merge) {\n handler.merge(content, records);\n } else {\n Object.assign(content, records);\n }\n };\n\n // Companion records (labels) are deleted alongside their element but aren't themselves\n // elements, so they don't count toward the reported total.\n const remove = (predicate: (identity: Identity) => boolean): number => {\n let count = 0;\n for (const [key, record] of Object.entries(content)) {\n const identity = handler.identify(record);\n if (identity && predicate(identity)) {\n // Read before delete: ECHO proxies dereference lazily, so fields vanish once removed.\n const isPart = identity.part !== undefined;\n delete content[key];\n if (!isPart) {\n count++;\n }\n }\n }\n handler.prune?.(content);\n return count;\n };\n\n for (const command of commands) {\n switch (command.op) {\n case 'upsert-object': {\n const previous = find(command.object.id);\n removed += remove((identity) => identity.object === command.object.id);\n merge(command.object, {\n origin: command.object.origin ?? previous?.origin ?? { x: 0, y: 0 },\n scale: command.object.scale ?? previous?.scale ?? 1,\n });\n upserted.add(command.object.id);\n break;\n }\n\n case 'upsert-elements': {\n const previous = find(command.objectId);\n invariant(previous, `unknown object: ${command.objectId} (use upsert-object to create it)`);\n const ids = new Set(command.elements.map((element) => element.id));\n removed += remove((identity) => identity.object === command.objectId && ids.has(identity.element));\n merge({ id: command.objectId, elements: command.elements }, previous);\n upserted.add(command.objectId);\n break;\n }\n\n case 'remove-elements': {\n const ids = new Set(command.elementIds);\n removed += remove((identity) => identity.object === command.objectId && ids.has(identity.element));\n break;\n }\n\n case 'remove-object': {\n removed += remove((identity) => identity.object === command.objectId);\n break;\n }\n\n case 'move-object': {\n const previous = find(command.objectId);\n invariant(previous, `unknown object: ${command.objectId}`);\n const delta = { x: command.origin.x - previous.origin.x, y: command.origin.y - previous.origin.y };\n for (const record of Object.values(content)) {\n if (handler.identify(record)?.object === command.objectId) {\n handler.translate(record, delta);\n }\n }\n upserted.add(command.objectId);\n break;\n }\n }\n }\n\n return { upserted: [...upserted], removed };\n};\n\n/** Seed a fractional-index counter past any existing `a<n>` indexes. */\nexport const nextIndex = (content: ContentMap, isCounted: (record: any) => boolean = () => true): number => {\n let max = 0;\n let count = 0;\n for (const record of Object.values(content)) {\n if (!record || !isCounted(record)) {\n continue;\n }\n count++;\n const match = /^a(\\d+)$/.exec(record.index ?? '');\n if (match) {\n max = Math.max(max, Number(match[1]));\n }\n }\n return Math.max(max, count);\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Renderer-neutral builder contract: each variant (tldraw, excalidraw, …) implements\n// `DrawingBuilder` to compile the scene DSL onto its canvas records and derive the scene back\n// from them. Implementations are contributed via `IllustratorCapabilities.VariantProvider`.\n//\n\nimport { Obj } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\n\nimport * as Drawing from '../types/Drawing';\nimport { type ApplyResult, type ContentHandler, type ContentMap, type ReadResult, applyCommands } from './content';\nimport type * as Scene from './scene';\n\n/**\n * Maps the scene DSL onto a canvas. Geometry is derived from the live records — not a stored\n * copy — so the model stays coherent after users drag or resize shapes in the renderer's UI.\n */\nexport type DrawingBuilder = {\n /** Renderer dialect this builder handles; matched against `Canvas.schema`. */\n readonly schema: string;\n /** Derive the neutral scene from the canvas. */\n read: (canvas: Drawing.Canvas) => ReadResult;\n /** Apply a batch of edit commands atomically. */\n apply: (canvas: Drawing.Canvas, commands: readonly Scene.Command[]) => ApplyResult;\n};\n\n/**\n * Builds a {@link DrawingBuilder} from the renderer's {@link ContentHandler}, so a variant only\n * supplies its record encoding and inherits the ECHO write semantics and command bookkeeping.\n */\nexport const makeBuilder = ({ schema, handler }: { schema: string; handler: ContentHandler }): DrawingBuilder => ({\n schema,\n read: (canvas) => {\n invariant(Obj.instanceOf(Drawing.Canvas, canvas));\n return handler.read(canvas.content);\n },\n apply: (canvas, commands) => {\n invariant(Obj.instanceOf(Drawing.Canvas, canvas));\n let result: ApplyResult = { upserted: [], removed: 0 };\n Obj.update(canvas, (canvas) => {\n result = applyCommands(canvas.content as ContentMap, commands, handler);\n });\n return result;\n },\n});\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Backend-neutral scene DSL: a diagram is a set of named world objects (\"face\", \"hat\"),\n// each composed of graphical elements (rect, ellipse, line, curve, text, arrow) authored\n// in object-local units. A backend compiler (tldraw today) maps the scene onto the\n// concrete canvas; see `render.ts` / `read.ts`.\n//\n\nimport * as Schema from 'effect/Schema';\n\nexport const Color = Schema.Literal(\n 'black',\n 'grey',\n 'light-violet',\n 'violet',\n 'blue',\n 'light-blue',\n 'yellow',\n 'orange',\n 'green',\n 'light-green',\n 'light-red',\n 'red',\n 'white',\n);\nexport type Color = Schema.Schema.Type<typeof Color>;\n\nexport const Fill = Schema.Literal('none', 'solid', 'pattern');\nexport type Fill = Schema.Schema.Type<typeof Fill>;\n\nexport const Stroke = Schema.Literal('sketchy', 'solid', 'dashed', 'dotted');\nexport type Stroke = Schema.Schema.Type<typeof Stroke>;\n\nexport const Weight = Schema.Literal('s', 'm', 'l', 'xl');\nexport type Weight = Schema.Schema.Type<typeof Weight>;\n\nexport const Point = Schema.Struct({\n x: Schema.Number,\n y: Schema.Number,\n});\nexport type Point = Schema.Schema.Type<typeof Point>;\n\n/** Style props shared by all elements; every field is optional with sensible defaults. */\nconst styleFields = {\n color: Schema.optional(Color).annotations({ description: 'Stroke/text color.' }),\n fill: Schema.optional(Fill).annotations({ description: 'Interior fill of closed shapes.' }),\n stroke: Schema.optional(Stroke).annotations({ description: 'Stroke rendering; sketchy is hand-drawn.' }),\n weight: Schema.optional(Weight).annotations({ description: 'Stroke weight / text size.' }),\n};\n\nconst id = Schema.String.annotations({\n description: 'Stable element id, unique within the object (e.g. \"left-eye\"). Used to edit or delete the element.',\n});\n\n/** Closed shape drawn inside a local bounding box. */\nexport const Box = Schema.Struct({\n kind: Schema.Literal('rect', 'ellipse', 'diamond', 'triangle'),\n id,\n x: Schema.Number.annotations({ description: 'Left edge (object-local units).' }),\n y: Schema.Number.annotations({ description: 'Top edge (object-local units).' }),\n w: Schema.Number,\n h: Schema.Number,\n rotation: Schema.optional(Schema.Number).annotations({ description: 'Clockwise rotation in degrees.' }),\n text: Schema.optional(Schema.String).annotations({ description: 'Centered label.' }),\n ...styleFields,\n});\nexport type Box = Schema.Schema.Type<typeof Box>;\n\n/** Circle sugar; reads back as an ellipse. */\nexport const Circle = Schema.Struct({\n kind: Schema.Literal('circle'),\n id,\n cx: Schema.Number.annotations({ description: 'Center x (object-local units).' }),\n cy: Schema.Number.annotations({ description: 'Center y (object-local units).' }),\n r: Schema.Number,\n text: Schema.optional(Schema.String),\n ...styleFields,\n});\nexport type Circle = Schema.Schema.Type<typeof Circle>;\n\n/** Straight segment or open polyline through the given points. */\nexport const Polyline = Schema.Struct({\n kind: Schema.Literal('line'),\n id,\n points: Schema.Array(Point).annotations({ description: 'Two or more points (object-local units).' }),\n closed: Schema.optional(Schema.Boolean).annotations({ description: 'Close the path back to the first point.' }),\n ...styleFields,\n});\nexport type Polyline = Schema.Schema.Type<typeof Polyline>;\n\n/** Smooth curve through the given points (spline). */\nexport const Curve = Schema.Struct({\n kind: Schema.Literal('curve'),\n id,\n points: Schema.Array(Point).annotations({ description: 'Control points the curve passes through.' }),\n ...styleFields,\n});\nexport type Curve = Schema.Schema.Type<typeof Curve>;\n\n/**\n * Circular arc sugar; reads back as a curve. Angles are degrees, measured clockwise from\n * the positive x-axis in screen coordinates (y grows downward): 0–180 is the lower half\n * (a smile), 180–360 the upper half (a frown).\n */\nexport const Arc = Schema.Struct({\n kind: Schema.Literal('arc'),\n id,\n cx: Schema.Number,\n cy: Schema.Number,\n r: Schema.Number,\n startAngle: Schema.Number,\n endAngle: Schema.Number,\n ...styleFields,\n});\nexport type Arc = Schema.Schema.Type<typeof Arc>;\n\n/** Free-standing text. */\nexport const Text = Schema.Struct({\n kind: Schema.Literal('text'),\n id,\n x: Schema.Number,\n y: Schema.Number,\n w: Schema.optional(Schema.Number).annotations({ description: 'Wrap width; omit for auto-size.' }),\n text: Schema.String,\n ...styleFields,\n});\nexport type Text = Schema.Schema.Type<typeof Text>;\n\n/**\n * Connector. Endpoints are element refs — `\"<elementId>\"` within the same object or\n * `\"<objectId>/<elementId>\"` across objects — or explicit local points. Bound endpoints\n * track their target when it moves.\n */\nexport const Arrow = Schema.Struct({\n kind: Schema.Literal('arrow'),\n id,\n from: Schema.optional(Schema.String).annotations({ description: 'Source element ref.' }),\n to: Schema.optional(Schema.String).annotations({ description: 'Target element ref.' }),\n start: Schema.optional(Point).annotations({ description: 'Explicit start (used when `from` is omitted).' }),\n end: Schema.optional(Point).annotations({ description: 'Explicit end (used when `to` is omitted).' }),\n text: Schema.optional(Schema.String).annotations({ description: 'Label at the arrow midpoint.' }),\n ...styleFields,\n});\nexport type Arrow = Schema.Schema.Type<typeof Arrow>;\n\nexport const Element = Schema.Union(Box, Circle, Polyline, Curve, Arc, Text, Arrow);\nexport type Element = Schema.Schema.Type<typeof Element>;\n\n/**\n * A semantic group of elements (\"face\", \"hat\") authored in its own local unit space.\n * `origin` (canvas px) and `scale` (px per unit) place it on the canvas:\n * `canvas = origin + local * scale`. On read, `origin` is derived as the top-left of the\n * object's bounding box, so the model survives users dragging shapes around.\n */\nexport const WorldObject = Schema.Struct({\n id: Schema.String.annotations({\n description: 'Stable object id naming the thing depicted (e.g. \"face\", \"hat\").',\n }),\n origin: Schema.optional(Point).annotations({\n description: 'Canvas position (px). Omit on upsert to keep the current position.',\n }),\n scale: Schema.optional(Schema.Number).annotations({ description: 'Canvas px per local unit (default 1).' }),\n elements: Schema.Array(Element),\n});\nexport type WorldObject = Schema.Schema.Type<typeof WorldObject>;\n\nexport const Scene = Schema.Struct({\n objects: Schema.Array(WorldObject),\n});\nexport type Scene = Schema.Schema.Type<typeof Scene>;\n\n//\n// Edit commands.\n//\n\nexport const UpsertObject = Schema.Struct({\n op: Schema.Literal('upsert-object'),\n object: WorldObject,\n}).annotations({ description: 'Create an object, or replace an existing one wholesale (same id).' });\n\nexport const UpsertElements = Schema.Struct({\n op: Schema.Literal('upsert-elements'),\n objectId: Schema.String,\n elements: Schema.Array(Element),\n}).annotations({ description: 'Add elements to an existing object, replacing any with matching ids.' });\n\nexport const RemoveElements = Schema.Struct({\n op: Schema.Literal('remove-elements'),\n objectId: Schema.String,\n elementIds: Schema.Array(Schema.String),\n});\n\nexport const RemoveObject = Schema.Struct({\n op: Schema.Literal('remove-object'),\n objectId: Schema.String,\n});\n\nexport const MoveObject = Schema.Struct({\n op: Schema.Literal('move-object'),\n objectId: Schema.String,\n origin: Point.annotations({ description: 'New canvas position (px) for the object top-left.' }),\n});\n\nexport const Command = Schema.Union(UpsertObject, UpsertElements, RemoveElements, RemoveObject, MoveObject);\nexport type Command = Schema.Schema.Type<typeof Command>;\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Extension point for higher-level diagram languages (mermaid, d2, sequence, uml-class, …).\n// A dialect compiles its input into scene edit commands — owning any layout it needs — so its\n// output lands as ordinary world objects and stays editable by id. Mirrors the architecture\n// shared by Mermaid/D2/Kroki: dialect → intermediate positioned model → renderer.\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\n\nimport { invariant } from '@dxos/invariant';\n\nimport * as Scene from './scene';\n\nexport type Dialect<Input = any> = {\n id: string;\n description: string;\n input: Schema.Schema<Input, any>;\n compile: (input: Input) => Effect.Effect<readonly Scene.Command[]>;\n};\n\n/** The core dialect: input is already scene edit commands (identity compile). */\nexport const sceneDialect: Dialect<readonly Scene.Command[]> = {\n id: 'scene',\n description: 'Positioned world objects and elements; the agent does the layout.',\n input: Schema.Array(Scene.Command),\n compile: Effect.succeed,\n};\n\nexport class DialectRegistry {\n readonly #dialects = new Map<string, Dialect>();\n\n constructor(dialects: Dialect[] = [sceneDialect]) {\n dialects.forEach((dialect) => this.register(dialect));\n }\n\n register(dialect: Dialect): void {\n invariant(!this.#dialects.has(dialect.id), `duplicate dialect: ${dialect.id}`);\n this.#dialects.set(dialect.id, dialect);\n }\n\n get(id: string): Dialect | undefined {\n return this.#dialects.get(id);\n }\n\n list(): Dialect[] {\n return [...this.#dialects.values()];\n }\n}\n","//\n// Copyright 2026 DXOS.org\n//\n\n//\n// Mermaid flowchart dialect: parses the subset needed for block diagrams (node declarations,\n// subgraphs, directed edges) and compiles it to scene commands with a layered layout. Mermaid\n// carries no coordinates, so the dialect owns placement — see `dialect.ts` for the contract.\n//\n\nimport type * as Scene from './scene';\n\nexport type Direction = 'TB' | 'BT' | 'LR' | 'RL';\n\nexport type MermaidNode = {\n id: string;\n label: string;\n /** Enclosing subgraph id, when declared inside one. */\n group?: string;\n};\n\nexport type MermaidGroup = {\n id: string;\n label: string;\n children: string[];\n};\n\nexport type MermaidEdge = {\n from: string;\n to: string;\n label?: string;\n};\n\nexport type MermaidGraph = {\n direction: Direction;\n nodes: MermaidNode[];\n groups: MermaidGroup[];\n edges: MermaidEdge[];\n};\n\nconst DIRECTIONS: Direction[] = ['TB', 'BT', 'LR', 'RL'];\n\n// `A[Label]`, `A(Label)`, `A{Label}` or a bare `A`.\nconst NODE = /^([A-Za-z0-9_-]+)(?:\\[(.*?)\\]|\\((.*?)\\)|\\{(.*?)\\})?$/;\n// `A --> B`, `A-->|label|B`, `A --- B`.\nconst EDGE = /^(.+?)\\s*(-->|---|-\\.->|==>)\\s*(?:\\|(.*?)\\|\\s*)?(.+)$/;\nconst SUBGRAPH = /^subgraph\\s+([A-Za-z0-9_-]+)(?:\\s*\\[(.*?)\\])?\\s*$/;\n\nconst unquote = (value: string) => value.trim().replace(/^\"(.*)\"$/, '$1');\n\n/** Parse a mermaid flowchart into a neutral graph. Unrecognised lines are ignored. */\nexport const parse = (source: string): MermaidGraph => {\n const nodes = new Map<string, MermaidNode>();\n const groups: MermaidGroup[] = [];\n const edges: MermaidEdge[] = [];\n let direction: Direction = 'TB';\n const stack: string[] = [];\n\n const declare = (token: string): string | undefined => {\n const match = NODE.exec(token.trim());\n if (!match) {\n return undefined;\n }\n const [, id, square, round, curly] = match;\n const label = unquote(square ?? round ?? curly ?? id);\n const group = stack[stack.length - 1];\n const existing = nodes.get(id);\n if (existing) {\n // A later declaration with an explicit label wins; the first mention fixes the group.\n if (square ?? round ?? curly) {\n existing.label = label;\n }\n return id;\n }\n nodes.set(id, { id, label, ...(group ? { group } : {}) });\n if (group) {\n groups.find((entry) => entry.id === group)?.children.push(id);\n }\n return id;\n };\n\n for (const raw of source.split('\\n')) {\n const line = raw.trim();\n if (!line || line.startsWith('%%')) {\n continue;\n }\n\n const header = /^(?:flowchart|graph)\\s+([A-Za-z]{2})$/.exec(line);\n if (header) {\n const value = header[1].toUpperCase() as Direction;\n direction = DIRECTIONS.includes(value) ? value : 'TB';\n continue;\n }\n\n const subgraph = SUBGRAPH.exec(line);\n if (subgraph) {\n const [, id, label] = subgraph;\n groups.push({ id, label: unquote(label ?? id), children: [] });\n stack.push(id);\n continue;\n }\n\n if (line === 'end') {\n stack.pop();\n continue;\n }\n\n const edge = EDGE.exec(line);\n if (edge) {\n const [, from, , label, to] = edge;\n const fromId = declare(from);\n const toId = declare(to);\n if (fromId && toId) {\n edges.push({ from: fromId, to: toId, ...(label ? { label: unquote(label) } : {}) });\n }\n continue;\n }\n\n declare(line);\n }\n\n return { direction, nodes: [...nodes.values()], groups, edges };\n};\n\n/** Layout constants in scene units. */\nconst NODE_W = 100;\nconst NODE_H = 50;\nconst GAP_MAIN = 60;\nconst GAP_CROSS = 40;\nconst GROUP_PAD = 24;\n\n/**\n * Edges that close a cycle, found by DFS: an edge into a node still on the stack points backwards.\n * Ranking ignores them, so `C --> Y --> C` ranks C by its forward predecessors alone instead of\n * chasing the loop.\n */\nconst backEdges = (graph: MermaidGraph): Set<MermaidEdge> => {\n const outgoing = new Map<string, MermaidEdge[]>();\n for (const edge of graph.edges) {\n outgoing.set(edge.from, [...(outgoing.get(edge.from) ?? []), edge]);\n }\n\n const back = new Set<MermaidEdge>();\n const done = new Set<string>();\n const onStack = new Set<string>();\n\n const visit = (id: string) => {\n onStack.add(id);\n for (const edge of outgoing.get(id) ?? []) {\n if (onStack.has(edge.to)) {\n back.add(edge);\n } else if (!done.has(edge.to)) {\n visit(edge.to);\n }\n }\n onStack.delete(id);\n done.add(id);\n };\n\n // Roots first so the DFS classifies edges along the natural reading order of the diagram.\n const targets = new Set(graph.edges.map((edge) => edge.to));\n for (const node of graph.nodes) {\n if (!targets.has(node.id) && !done.has(node.id)) {\n visit(node.id);\n }\n }\n for (const node of graph.nodes) {\n if (!done.has(node.id)) {\n visit(node.id);\n }\n }\n return back;\n};\n\n/** Assign each node a rank one past its deepest forward predecessor. */\nconst rank = (graph: MermaidGraph): Map<string, number> => {\n const back = backEdges(graph);\n const forward = graph.edges.filter((edge) => !back.has(edge));\n const ranks = new Map(graph.nodes.map((node) => [node.id, 0]));\n for (let pass = 0; pass < graph.nodes.length; pass++) {\n let changed = false;\n for (const edge of forward) {\n const next = (ranks.get(edge.from) ?? 0) + 1;\n if (next > (ranks.get(edge.to) ?? 0)) {\n ranks.set(edge.to, next);\n changed = true;\n }\n }\n if (!changed) {\n break;\n }\n }\n return ranks;\n};\n\nexport type CompileOptions = {\n /** Canvas position of the diagram's top-left, in canvas px. */\n origin?: Scene.Point;\n /** Canvas px per scene unit. */\n scale?: number;\n};\n\n/**\n * Compile a mermaid flowchart into scene commands: one world object per node (element `box`),\n * one per subgraph frame, and an `edges` object holding the connectors as bound arrows.\n */\nexport const compile = (source: string, options: CompileOptions = {}): Scene.Command[] => {\n const graph = parse(source);\n const { origin = { x: 0, y: 0 }, scale = 1 } = options;\n const ranks = rank(graph);\n const horizontal = graph.direction === 'LR' || graph.direction === 'RL';\n\n // Group nodes by rank, preserving declaration order within each.\n const lanes = new Map<number, MermaidNode[]>();\n for (const node of graph.nodes) {\n const value = ranks.get(node.id) ?? 0;\n lanes.set(value, [...(lanes.get(value) ?? []), node]);\n }\n const widest = Math.max(...[...lanes.values()].map((lane) => lane.length), 1);\n\n const positions = new Map<string, Scene.Point>();\n for (const [lane, members] of lanes) {\n const span = members.length * NODE_W + (members.length - 1) * GAP_CROSS;\n const offset = (widest * NODE_W + (widest - 1) * GAP_CROSS - span) / 2;\n members.forEach((node, index) => {\n const cross = offset + index * (NODE_W + GAP_CROSS);\n const main = lane * (NODE_H + GAP_MAIN);\n positions.set(node.id, horizontal ? { x: main, y: cross } : { x: cross, y: main });\n });\n }\n\n const commands: Scene.Command[] = [];\n\n // Frames first so nodes paint above them.\n for (const group of graph.groups) {\n const members = group.children.map((id) => positions.get(id)).filter((point): point is Scene.Point => !!point);\n if (members.length === 0) {\n continue;\n }\n const minX = Math.min(...members.map((point) => point.x)) - GROUP_PAD;\n const minY = Math.min(...members.map((point) => point.y)) - GROUP_PAD;\n const maxX = Math.max(...members.map((point) => point.x)) + NODE_W + GROUP_PAD;\n const maxY = Math.max(...members.map((point) => point.y)) + NODE_H + GROUP_PAD;\n commands.push({\n op: 'upsert-object',\n object: {\n id: group.id,\n origin: { x: origin.x + minX * scale, y: origin.y + minY * scale },\n scale,\n elements: [\n {\n kind: 'rect',\n id: 'frame',\n x: 0,\n y: 0,\n w: maxX - minX,\n h: maxY - minY,\n stroke: 'dashed',\n color: 'grey',\n ...(group.label.trim() ? { text: group.label } : {}),\n },\n ],\n },\n });\n }\n\n for (const node of graph.nodes) {\n const point = positions.get(node.id)!;\n commands.push({\n op: 'upsert-object',\n object: {\n id: node.id,\n origin: { x: origin.x + point.x * scale, y: origin.y + point.y * scale },\n scale,\n elements: [{ kind: 'rect', id: 'box', x: 0, y: 0, w: NODE_W, h: NODE_H, text: node.label }],\n },\n });\n }\n\n if (graph.edges.length > 0) {\n commands.push({\n op: 'upsert-object',\n object: {\n id: 'edges',\n origin,\n scale,\n elements: graph.edges.map((edge) => ({\n kind: 'arrow' as const,\n id: `${edge.from}-${edge.to}`,\n from: `${edge.from}/box`,\n to: `${edge.to}/box`,\n ...(edge.label ? { text: edge.label } : {}),\n })),\n },\n });\n }\n\n return commands;\n};\n","//\n// Copyright 2026 DXOS.org\n//\n\nexport * from './builder';\nexport * from './content';\nexport * from './dialect';\nexport * as Mermaid from './mermaid';\nexport * as Scene from './scene';\n"],"mappings":"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"}
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as Drawing } from "./chunk-Drawing.mjs";
|
|
2
|
+
import "./chunk-types.mjs";
|
|
2
3
|
import { Capabilities, Capability } from "@dxos/app-framework";
|
|
3
4
|
import * as Effect from "effect/Effect";
|
|
4
|
-
import "react";
|
|
5
5
|
import { Surface } from "@dxos/app-framework/ui";
|
|
6
|
-
import { jsx } from "react/jsx-runtime";
|
|
7
6
|
import { AppSurface } from "@dxos/app-toolkit/ui";
|
|
8
|
-
import {
|
|
9
|
-
//#region src/capabilities/react-surface.
|
|
7
|
+
import { DrawingArticle, DrawingCard } from "#containers";
|
|
8
|
+
//#region src/capabilities/react-surface.ts
|
|
10
9
|
var react_surface_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(Capabilities.ReactSurface, [Surface.create({
|
|
11
|
-
id: "
|
|
12
|
-
filter: AppSurface.oneOf(AppSurface.object(AppSurface.Article,
|
|
13
|
-
component:
|
|
10
|
+
id: "drawing",
|
|
11
|
+
filter: AppSurface.oneOf(AppSurface.object(AppSurface.Article, Drawing), AppSurface.object(AppSurface.Section, Drawing), AppSurface.object(AppSurface.Slide, Drawing)),
|
|
12
|
+
component: DrawingArticle,
|
|
13
|
+
props: ({ role, data: { subject, attendableId, extrinsic } }) => ({
|
|
14
14
|
role,
|
|
15
15
|
subject,
|
|
16
16
|
attendableId,
|
|
17
17
|
extrinsic
|
|
18
18
|
})
|
|
19
19
|
}), Surface.create({
|
|
20
|
-
id: "
|
|
21
|
-
filter: AppSurface.object(AppSurface.CardContent,
|
|
22
|
-
component:
|
|
20
|
+
id: "drawingCard",
|
|
21
|
+
filter: AppSurface.object(AppSurface.CardContent, Drawing),
|
|
22
|
+
component: DrawingCard,
|
|
23
|
+
props: ({ role, data: { subject, editable } }) => ({
|
|
23
24
|
role,
|
|
24
|
-
subject
|
|
25
|
-
editable
|
|
25
|
+
subject,
|
|
26
|
+
editable
|
|
26
27
|
})
|
|
27
28
|
})])));
|
|
28
29
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/react-surface.
|
|
1
|
+
{"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/react-surface.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\n\nimport { DrawingArticle, DrawingCard } from '#containers';\n\nimport { Drawing } from '../types';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contributes(Capabilities.ReactSurface, [\n Surface.create({\n id: 'drawing',\n filter: AppSurface.oneOf(\n AppSurface.object(AppSurface.Article, Drawing.Drawing),\n AppSurface.object(AppSurface.Section, Drawing.Drawing),\n AppSurface.object(AppSurface.Slide, Drawing.Drawing),\n ),\n component: DrawingArticle,\n props: ({ role, data: { subject, attendableId, extrinsic } }) => ({ role, subject, attendableId, extrinsic }),\n }),\n Surface.create({\n id: 'drawingCard',\n filter: AppSurface.object(AppSurface.CardContent, Drawing.Drawing),\n component: DrawingCard,\n props: ({ role, data: { subject, editable } }) => ({ role, subject, editable }),\n }),\n ]),\n ),\n);\n"],"mappings":";;;;;;;;AAcA,IAAA,wBAAe,WAAW,iBACxB,OAAO,QACL,WAAW,YAAY,aAAa,cAAc,CAChD,QAAQ,OAAO;CACb,IAAI;CACJ,QAAQ,WAAW,MACjB,WAAW,OAAO,WAAW,SAAS,OAAe,GACrD,WAAW,OAAO,WAAW,SAAS,OAAe,GACrD,WAAW,OAAO,WAAW,OAAO,OAAe,CACrD;CACA,WAAW;CACX,QAAQ,EAAE,MAAM,MAAM,EAAE,SAAS,cAAc,mBAAmB;EAAE;EAAM;EAAS;EAAc;CAAU;AAC7G,CAAC,GACD,QAAQ,OAAO;CACb,IAAI;CACJ,QAAQ,WAAW,OAAO,WAAW,aAAa,OAAe;CACjE,WAAW;CACX,QAAQ,EAAE,MAAM,MAAM,EAAE,SAAS,kBAAkB;EAAE;EAAM;EAAS;CAAS;AAC/E,CAAC,CACH,CAAC,CACH,CACF"}
|
package/dist/lib/chunk-read.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { a as Read } from "./chunk-types.mjs";
|
|
2
|
+
import { r as resolveVariant } from "./chunk-load-drawing.mjs";
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
4
|
import { Operation } from "@dxos/compute";
|
|
5
5
|
//#region src/operations/read.ts
|
|
6
|
-
var handler = Read.pipe(Operation.withHandler(Effect.fn(function* ({
|
|
7
|
-
const { canvas, variant } = yield* resolveVariant(
|
|
6
|
+
var handler = Read.pipe(Operation.withHandler(Effect.fn(function* ({ drawing }) {
|
|
7
|
+
const { canvas, variant } = yield* resolveVariant(drawing);
|
|
8
8
|
return variant.builder.read(canvas);
|
|
9
9
|
})));
|
|
10
10
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-read.mjs","names":[],"sources":["../../src/operations/read.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Operation } from '@dxos/compute';\n\nimport {
|
|
1
|
+
{"version":3,"file":"chunk-read.mjs","names":[],"sources":["../../src/operations/read.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Operation } from '@dxos/compute';\n\nimport { DrawingOperation } from '../types';\nimport { resolveVariant } from '../util/load-drawing';\n\nconst handler: Operation.WithHandler<typeof DrawingOperation.Read> = DrawingOperation.Read.pipe(\n Operation.withHandler(\n Effect.fn(function* ({ drawing }) {\n const { canvas, variant } = yield* resolveVariant(drawing);\n return variant.builder.read(canvas);\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;;AAWA,IAAM,UAAA,KAAqF,KACzF,UAAU,YACR,OAAO,GAAG,WAAW,EAAE,WAAW;CAChC,MAAM,EAAE,QAAQ,YAAY,OAAO,eAAe,OAAO;CACzD,OAAO,QAAQ,QAAQ,KAAK,MAAM;AACpC,CAAC,CACH,CACF"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Capability } from "@dxos/app-framework";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
3
|
import { AppCapabilities } from "@dxos/app-toolkit";
|
|
4
|
-
import {
|
|
4
|
+
import { DrawingSkill } from "#skills";
|
|
5
5
|
//#region src/capabilities/skill-definition.ts
|
|
6
|
-
var skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition,
|
|
6
|
+
var skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition, DrawingSkill)]);
|
|
7
7
|
//#endregion
|
|
8
8
|
export { skillDefinition as default };
|
|
9
9
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-skill-definition.mjs","names":[],"sources":["../../src/capabilities/skill-definition.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\n\nimport {
|
|
1
|
+
{"version":3,"file":"chunk-skill-definition.mjs","names":[],"sources":["../../src/capabilities/skill-definition.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\n\nimport { DrawingSkill } from '#skills';\n\nconst skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition, DrawingSkill)]);\n\nexport default skillDefinition;\n"],"mappings":";;;;;AAWA,IAAM,wBAAwB,OAAO,QAAQ,CAAC,WAAW,YAAY,gBAAgB,iBAAiB,YAAY,CAAC,CAAC"}
|