@hatiolab/figure-model 0.3.4 → 0.4.1
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/CHANGELOG.md +7 -0
- package/README.md +3 -0
- package/dist/asset.d.ts +12 -0
- package/dist/asset.d.ts.map +1 -1
- package/dist/asset.js +15 -3
- package/dist/asset.js.map +1 -1
- package/dist/command-preview.d.ts +6 -0
- package/dist/command-preview.d.ts.map +1 -1
- package/dist/command-preview.js +35 -2
- package/dist/command-preview.js.map +1 -1
- package/dist/editor-workspace.d.ts +48 -401
- package/dist/editor-workspace.d.ts.map +1 -1
- package/dist/editor-workspace.js +55 -13
- package/dist/editor-workspace.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/kernel-version.d.ts +1 -1
- package/dist/kernel-version.js +1 -1
- package/dist/names.d.ts +19 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +47 -0
- package/dist/names.js.map +1 -0
- package/dist/package.d.ts +86 -0
- package/dist/package.d.ts.map +1 -0
- package/dist/package.js +202 -0
- package/dist/package.js.map +1 -0
- package/dist/render-lod.d.ts +12 -0
- package/dist/render-lod.d.ts.map +1 -0
- package/dist/render-lod.js +32 -0
- package/dist/render-lod.js.map +1 -0
- package/dist/shape-ops.d.ts +1 -1
- package/dist/shape-ops.d.ts.map +1 -1
- package/dist/shape-ops.js.map +1 -1
- package/dist/words.d.ts +6 -6
- package/dist/words.js +8 -8
- package/dist/words.js.map +1 -1
- package/dist/work-counter.d.ts +16 -0
- package/dist/work-counter.d.ts.map +1 -0
- package/dist/work-counter.js +13 -0
- package/dist/work-counter.js.map +1 -0
- package/docs/evaluation-performance-summary-2026-10-05.md +18 -0
- package/docs/performance-followup-2026-10-05.md +578 -0
- package/docs/shape-dimension-contract.md +10 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { compileFigureAsset } from './asset.ts';
|
|
1
2
|
import type { FigureEditRequest, FigureEditControl } from './authoring-session.ts';
|
|
2
3
|
import type { FigureBoxCreation, FigurePrimitiveCreation } from './create.ts';
|
|
3
4
|
import { type FigureProposalStep } from './proposal.ts';
|
|
@@ -20,98 +21,38 @@ export interface FigureLeaveOptions {
|
|
|
20
21
|
export interface FigureOpenOptions extends FigureLeaveOptions {
|
|
21
22
|
baseline?: string;
|
|
22
23
|
}
|
|
24
|
+
type ClosedView = {
|
|
25
|
+
context: null;
|
|
26
|
+
name: null;
|
|
27
|
+
fields: never[];
|
|
28
|
+
geometry: never[];
|
|
29
|
+
bindings: never[];
|
|
30
|
+
dirty: false;
|
|
31
|
+
revision: null;
|
|
32
|
+
canUndo?: undefined;
|
|
33
|
+
canRedo?: undefined;
|
|
34
|
+
palette?: undefined;
|
|
35
|
+
};
|
|
36
|
+
type Rendered = ReturnType<ReturnType<typeof compileFigureAsset>['evaluate']>;
|
|
37
|
+
type OpenView = {
|
|
38
|
+
context: string;
|
|
39
|
+
name: string;
|
|
40
|
+
revision: number;
|
|
41
|
+
dirty: boolean;
|
|
42
|
+
canUndo: boolean;
|
|
43
|
+
canRedo: boolean;
|
|
44
|
+
fields: Array<FigureAsset['document']['model']['inputs'][number] & {
|
|
45
|
+
value: number;
|
|
46
|
+
}>;
|
|
47
|
+
geometry: Rendered['geometry'];
|
|
48
|
+
bindings: Rendered['bindings'];
|
|
49
|
+
palette: Rendered['palette'];
|
|
50
|
+
};
|
|
23
51
|
/** One history for structural and input edits. No persistence or authentication is implied. */
|
|
24
52
|
export declare function createFigureEditorWorkspace(): {
|
|
25
|
-
read: () =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
fields: never[];
|
|
29
|
-
geometry: never[];
|
|
30
|
-
bindings: never[];
|
|
31
|
-
dirty: boolean;
|
|
32
|
-
revision: null;
|
|
33
|
-
canUndo?: undefined;
|
|
34
|
-
canRedo?: undefined;
|
|
35
|
-
palette?: undefined;
|
|
36
|
-
} | {
|
|
37
|
-
context: string;
|
|
38
|
-
name: string;
|
|
39
|
-
revision: number;
|
|
40
|
-
dirty: boolean;
|
|
41
|
-
canUndo: boolean;
|
|
42
|
-
canRedo: boolean;
|
|
43
|
-
fields: {
|
|
44
|
-
value: number;
|
|
45
|
-
id: string;
|
|
46
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
47
|
-
min: number;
|
|
48
|
-
max: number;
|
|
49
|
-
role?: "design" | "state";
|
|
50
|
-
}[];
|
|
51
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
52
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
53
|
-
palette: Record<string, string>;
|
|
54
|
-
};
|
|
55
|
-
open(text: string, { discardDesignChanges, baseline }?: FigureOpenOptions): {
|
|
56
|
-
context: null;
|
|
57
|
-
name: null;
|
|
58
|
-
fields: never[];
|
|
59
|
-
geometry: never[];
|
|
60
|
-
bindings: never[];
|
|
61
|
-
dirty: boolean;
|
|
62
|
-
revision: null;
|
|
63
|
-
canUndo?: undefined;
|
|
64
|
-
canRedo?: undefined;
|
|
65
|
-
palette?: undefined;
|
|
66
|
-
} | {
|
|
67
|
-
context: string;
|
|
68
|
-
name: string;
|
|
69
|
-
revision: number;
|
|
70
|
-
dirty: boolean;
|
|
71
|
-
canUndo: boolean;
|
|
72
|
-
canRedo: boolean;
|
|
73
|
-
fields: {
|
|
74
|
-
value: number;
|
|
75
|
-
id: string;
|
|
76
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
77
|
-
min: number;
|
|
78
|
-
max: number;
|
|
79
|
-
role?: "design" | "state";
|
|
80
|
-
}[];
|
|
81
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
82
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
83
|
-
palette: Record<string, string>;
|
|
84
|
-
};
|
|
85
|
-
close({ discardDesignChanges }?: FigureLeaveOptions): {
|
|
86
|
-
context: null;
|
|
87
|
-
name: null;
|
|
88
|
-
fields: never[];
|
|
89
|
-
geometry: never[];
|
|
90
|
-
bindings: never[];
|
|
91
|
-
dirty: boolean;
|
|
92
|
-
revision: null;
|
|
93
|
-
canUndo?: undefined;
|
|
94
|
-
canRedo?: undefined;
|
|
95
|
-
palette?: undefined;
|
|
96
|
-
} | {
|
|
97
|
-
context: string;
|
|
98
|
-
name: string;
|
|
99
|
-
revision: number;
|
|
100
|
-
dirty: boolean;
|
|
101
|
-
canUndo: boolean;
|
|
102
|
-
canRedo: boolean;
|
|
103
|
-
fields: {
|
|
104
|
-
value: number;
|
|
105
|
-
id: string;
|
|
106
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
107
|
-
min: number;
|
|
108
|
-
max: number;
|
|
109
|
-
role?: "design" | "state";
|
|
110
|
-
}[];
|
|
111
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
112
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
113
|
-
palette: Record<string, string>;
|
|
114
|
-
};
|
|
53
|
+
read: () => ClosedView | OpenView;
|
|
54
|
+
open(text: string, { discardDesignChanges, baseline }?: FigureOpenOptions): ClosedView | OpenView;
|
|
55
|
+
close({ discardDesignChanges }?: FigureLeaveOptions): ClosedView | OpenView;
|
|
115
56
|
preview({ context, ...q }: FigureEditRequest & {
|
|
116
57
|
context: string;
|
|
117
58
|
}): {
|
|
@@ -145,143 +86,27 @@ export declare function createFigureEditorWorkspace(): {
|
|
|
145
86
|
};
|
|
146
87
|
apply({ context, ...q }: FigureEditRequest & {
|
|
147
88
|
context: string;
|
|
148
|
-
}):
|
|
149
|
-
context: null;
|
|
150
|
-
name: null;
|
|
151
|
-
fields: never[];
|
|
152
|
-
geometry: never[];
|
|
153
|
-
bindings: never[];
|
|
154
|
-
dirty: boolean;
|
|
155
|
-
revision: null;
|
|
156
|
-
canUndo?: undefined;
|
|
157
|
-
canRedo?: undefined;
|
|
158
|
-
palette?: undefined;
|
|
159
|
-
} | {
|
|
160
|
-
context: string;
|
|
161
|
-
name: string;
|
|
162
|
-
revision: number;
|
|
163
|
-
dirty: boolean;
|
|
164
|
-
canUndo: boolean;
|
|
165
|
-
canRedo: boolean;
|
|
166
|
-
fields: {
|
|
167
|
-
value: number;
|
|
168
|
-
id: string;
|
|
169
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
170
|
-
min: number;
|
|
171
|
-
max: number;
|
|
172
|
-
role?: "design" | "state";
|
|
173
|
-
}[];
|
|
174
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
175
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
176
|
-
palette: Record<string, string>;
|
|
177
|
-
};
|
|
89
|
+
}): ClosedView | OpenView;
|
|
178
90
|
addBox({ context, box, ...q }: FigureEditControl & {
|
|
179
91
|
context: string;
|
|
180
92
|
box: FigureBoxCreation;
|
|
181
|
-
}):
|
|
182
|
-
context: null;
|
|
183
|
-
name: null;
|
|
184
|
-
fields: never[];
|
|
185
|
-
geometry: never[];
|
|
186
|
-
bindings: never[];
|
|
187
|
-
dirty: boolean;
|
|
188
|
-
revision: null;
|
|
189
|
-
canUndo?: undefined;
|
|
190
|
-
canRedo?: undefined;
|
|
191
|
-
palette?: undefined;
|
|
192
|
-
} | {
|
|
193
|
-
context: string;
|
|
194
|
-
name: string;
|
|
195
|
-
revision: number;
|
|
196
|
-
dirty: boolean;
|
|
197
|
-
canUndo: boolean;
|
|
198
|
-
canRedo: boolean;
|
|
199
|
-
fields: {
|
|
200
|
-
value: number;
|
|
201
|
-
id: string;
|
|
202
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
203
|
-
min: number;
|
|
204
|
-
max: number;
|
|
205
|
-
role?: "design" | "state";
|
|
206
|
-
}[];
|
|
207
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
208
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
209
|
-
palette: Record<string, string>;
|
|
210
|
-
};
|
|
93
|
+
}): ClosedView | OpenView;
|
|
211
94
|
addPrimitive({ context, part, ...q }: FigureEditControl & {
|
|
212
95
|
context: string;
|
|
213
96
|
part: FigurePrimitiveCreation;
|
|
214
|
-
}):
|
|
215
|
-
context: null;
|
|
216
|
-
name: null;
|
|
217
|
-
fields: never[];
|
|
218
|
-
geometry: never[];
|
|
219
|
-
bindings: never[];
|
|
220
|
-
dirty: boolean;
|
|
221
|
-
revision: null;
|
|
222
|
-
canUndo?: undefined;
|
|
223
|
-
canRedo?: undefined;
|
|
224
|
-
palette?: undefined;
|
|
225
|
-
} | {
|
|
226
|
-
context: string;
|
|
227
|
-
name: string;
|
|
228
|
-
revision: number;
|
|
229
|
-
dirty: boolean;
|
|
230
|
-
canUndo: boolean;
|
|
231
|
-
canRedo: boolean;
|
|
232
|
-
fields: {
|
|
233
|
-
value: number;
|
|
234
|
-
id: string;
|
|
235
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
236
|
-
min: number;
|
|
237
|
-
max: number;
|
|
238
|
-
role?: "design" | "state";
|
|
239
|
-
}[];
|
|
240
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
241
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
242
|
-
palette: Record<string, string>;
|
|
243
|
-
};
|
|
97
|
+
}): ClosedView | OpenView;
|
|
244
98
|
/** A part edit, one step of the history. Removing a part also says what else that changed (`removal`). */
|
|
245
99
|
editPart({ context, edit, ...q }: FigureEditControl & {
|
|
246
100
|
context: string;
|
|
247
101
|
edit: FigurePartEdit;
|
|
248
|
-
}): {
|
|
249
|
-
context: null;
|
|
250
|
-
name: null;
|
|
251
|
-
fields: never[];
|
|
252
|
-
geometry: never[];
|
|
253
|
-
bindings: never[];
|
|
254
|
-
dirty: boolean;
|
|
255
|
-
revision: null;
|
|
256
|
-
canUndo?: undefined;
|
|
257
|
-
canRedo?: undefined;
|
|
258
|
-
palette?: undefined;
|
|
259
|
-
} | {
|
|
260
|
-
context: string;
|
|
261
|
-
name: string;
|
|
262
|
-
revision: number;
|
|
263
|
-
dirty: boolean;
|
|
264
|
-
canUndo: boolean;
|
|
265
|
-
canRedo: boolean;
|
|
266
|
-
fields: {
|
|
267
|
-
value: number;
|
|
268
|
-
id: string;
|
|
269
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
270
|
-
min: number;
|
|
271
|
-
max: number;
|
|
272
|
-
role?: "design" | "state";
|
|
273
|
-
}[];
|
|
274
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
275
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
276
|
-
palette: Record<string, string>;
|
|
277
|
-
} | {
|
|
102
|
+
}): ClosedView | OpenView | {
|
|
278
103
|
removal: import("./authoring-actions.ts").RemovalNotice;
|
|
279
104
|
context: null;
|
|
280
105
|
name: null;
|
|
281
106
|
fields: never[];
|
|
282
107
|
geometry: never[];
|
|
283
108
|
bindings: never[];
|
|
284
|
-
dirty:
|
|
109
|
+
dirty: false;
|
|
285
110
|
revision: null;
|
|
286
111
|
canUndo?: undefined;
|
|
287
112
|
canRedo?: undefined;
|
|
@@ -294,17 +119,12 @@ export declare function createFigureEditorWorkspace(): {
|
|
|
294
119
|
dirty: boolean;
|
|
295
120
|
canUndo: boolean;
|
|
296
121
|
canRedo: boolean;
|
|
297
|
-
fields: {
|
|
122
|
+
fields: Array<FigureAsset["document"]["model"]["inputs"][number] & {
|
|
298
123
|
value: number;
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
role?: "design" | "state";
|
|
304
|
-
}[];
|
|
305
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
306
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
307
|
-
palette: Record<string, string>;
|
|
124
|
+
}>;
|
|
125
|
+
geometry: Rendered["geometry"];
|
|
126
|
+
bindings: Rendered["bindings"];
|
|
127
|
+
palette: Rendered["palette"];
|
|
308
128
|
};
|
|
309
129
|
/**
|
|
310
130
|
* One authoring command — a dimension that follows, a fastening, a motion, the room the figure takes up —
|
|
@@ -318,36 +138,7 @@ export declare function createFigureEditorWorkspace(): {
|
|
|
318
138
|
command({ context, action, ...q }: FigureEditControl & {
|
|
319
139
|
context: string;
|
|
320
140
|
action: FigureAuthoringAction;
|
|
321
|
-
}):
|
|
322
|
-
context: null;
|
|
323
|
-
name: null;
|
|
324
|
-
fields: never[];
|
|
325
|
-
geometry: never[];
|
|
326
|
-
bindings: never[];
|
|
327
|
-
dirty: boolean;
|
|
328
|
-
revision: null;
|
|
329
|
-
canUndo?: undefined;
|
|
330
|
-
canRedo?: undefined;
|
|
331
|
-
palette?: undefined;
|
|
332
|
-
} | {
|
|
333
|
-
context: string;
|
|
334
|
-
name: string;
|
|
335
|
-
revision: number;
|
|
336
|
-
dirty: boolean;
|
|
337
|
-
canUndo: boolean;
|
|
338
|
-
canRedo: boolean;
|
|
339
|
-
fields: {
|
|
340
|
-
value: number;
|
|
341
|
-
id: string;
|
|
342
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
343
|
-
min: number;
|
|
344
|
-
max: number;
|
|
345
|
-
role?: "design" | "state";
|
|
346
|
-
}[];
|
|
347
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
348
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
349
|
-
palette: Record<string, string>;
|
|
350
|
-
};
|
|
141
|
+
}): ClosedView | OpenView;
|
|
351
142
|
/**
|
|
352
143
|
* What a command would do, seen before it is done (ADR-0097 §5.5): the same command on a copy, with the values the
|
|
353
144
|
* author is looking at. No revision, no history, no clip, no consent is touched; the answer names the figure and
|
|
@@ -361,36 +152,7 @@ export declare function createFigureEditorWorkspace(): {
|
|
|
361
152
|
attachment?: Extract<FigureAuthoringAction, {
|
|
362
153
|
kind: "attach";
|
|
363
154
|
}>;
|
|
364
|
-
}):
|
|
365
|
-
context: null;
|
|
366
|
-
name: null;
|
|
367
|
-
fields: never[];
|
|
368
|
-
geometry: never[];
|
|
369
|
-
bindings: never[];
|
|
370
|
-
dirty: boolean;
|
|
371
|
-
revision: null;
|
|
372
|
-
canUndo?: undefined;
|
|
373
|
-
canRedo?: undefined;
|
|
374
|
-
palette?: undefined;
|
|
375
|
-
} | {
|
|
376
|
-
context: string;
|
|
377
|
-
name: string;
|
|
378
|
-
revision: number;
|
|
379
|
-
dirty: boolean;
|
|
380
|
-
canUndo: boolean;
|
|
381
|
-
canRedo: boolean;
|
|
382
|
-
fields: {
|
|
383
|
-
value: number;
|
|
384
|
-
id: string;
|
|
385
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
386
|
-
min: number;
|
|
387
|
-
max: number;
|
|
388
|
-
role?: "design" | "state";
|
|
389
|
-
}[];
|
|
390
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
391
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
392
|
-
palette: Record<string, string>;
|
|
393
|
-
};
|
|
155
|
+
}): ClosedView | OpenView;
|
|
394
156
|
previewCommand({ context, action }: {
|
|
395
157
|
context: string;
|
|
396
158
|
action: FigureAuthoringAction;
|
|
@@ -410,135 +172,20 @@ export declare function createFigureEditorWorkspace(): {
|
|
|
410
172
|
applyProposal({ context, steps, ...q }: FigureEditControl & {
|
|
411
173
|
context: string;
|
|
412
174
|
steps: readonly FigureProposalStep[];
|
|
413
|
-
}):
|
|
414
|
-
context: null;
|
|
415
|
-
name: null;
|
|
416
|
-
fields: never[];
|
|
417
|
-
geometry: never[];
|
|
418
|
-
bindings: never[];
|
|
419
|
-
dirty: boolean;
|
|
420
|
-
revision: null;
|
|
421
|
-
canUndo?: undefined;
|
|
422
|
-
canRedo?: undefined;
|
|
423
|
-
palette?: undefined;
|
|
424
|
-
} | {
|
|
425
|
-
context: string;
|
|
426
|
-
name: string;
|
|
427
|
-
revision: number;
|
|
428
|
-
dirty: boolean;
|
|
429
|
-
canUndo: boolean;
|
|
430
|
-
canRedo: boolean;
|
|
431
|
-
fields: {
|
|
432
|
-
value: number;
|
|
433
|
-
id: string;
|
|
434
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
435
|
-
min: number;
|
|
436
|
-
max: number;
|
|
437
|
-
role?: "design" | "state";
|
|
438
|
-
}[];
|
|
439
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
440
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
441
|
-
palette: Record<string, string>;
|
|
442
|
-
};
|
|
175
|
+
}): ClosedView | OpenView;
|
|
443
176
|
undo({ context, ...q }: FigureEditControl & {
|
|
444
177
|
context: string;
|
|
445
|
-
}):
|
|
446
|
-
context: null;
|
|
447
|
-
name: null;
|
|
448
|
-
fields: never[];
|
|
449
|
-
geometry: never[];
|
|
450
|
-
bindings: never[];
|
|
451
|
-
dirty: boolean;
|
|
452
|
-
revision: null;
|
|
453
|
-
canUndo?: undefined;
|
|
454
|
-
canRedo?: undefined;
|
|
455
|
-
palette?: undefined;
|
|
456
|
-
} | {
|
|
457
|
-
context: string;
|
|
458
|
-
name: string;
|
|
459
|
-
revision: number;
|
|
460
|
-
dirty: boolean;
|
|
461
|
-
canUndo: boolean;
|
|
462
|
-
canRedo: boolean;
|
|
463
|
-
fields: {
|
|
464
|
-
value: number;
|
|
465
|
-
id: string;
|
|
466
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
467
|
-
min: number;
|
|
468
|
-
max: number;
|
|
469
|
-
role?: "design" | "state";
|
|
470
|
-
}[];
|
|
471
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
472
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
473
|
-
palette: Record<string, string>;
|
|
474
|
-
};
|
|
178
|
+
}): ClosedView | OpenView;
|
|
475
179
|
redo({ context, ...q }: FigureEditControl & {
|
|
476
180
|
context: string;
|
|
477
|
-
}):
|
|
478
|
-
context: null;
|
|
479
|
-
name: null;
|
|
480
|
-
fields: never[];
|
|
481
|
-
geometry: never[];
|
|
482
|
-
bindings: never[];
|
|
483
|
-
dirty: boolean;
|
|
484
|
-
revision: null;
|
|
485
|
-
canUndo?: undefined;
|
|
486
|
-
canRedo?: undefined;
|
|
487
|
-
palette?: undefined;
|
|
488
|
-
} | {
|
|
489
|
-
context: string;
|
|
490
|
-
name: string;
|
|
491
|
-
revision: number;
|
|
492
|
-
dirty: boolean;
|
|
493
|
-
canUndo: boolean;
|
|
494
|
-
canRedo: boolean;
|
|
495
|
-
fields: {
|
|
496
|
-
value: number;
|
|
497
|
-
id: string;
|
|
498
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
499
|
-
min: number;
|
|
500
|
-
max: number;
|
|
501
|
-
role?: "design" | "state";
|
|
502
|
-
}[];
|
|
503
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
504
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
505
|
-
palette: Record<string, string>;
|
|
506
|
-
};
|
|
181
|
+
}): ClosedView | OpenView;
|
|
507
182
|
export({ context, captureStateDefaults }: {
|
|
508
183
|
context: string;
|
|
509
184
|
captureStateDefaults?: boolean;
|
|
510
185
|
}): FigureWorkspaceExport;
|
|
511
|
-
acknowledgeSaved({ context, revision, text }: FigureWorkspaceExport):
|
|
512
|
-
context: null;
|
|
513
|
-
name: null;
|
|
514
|
-
fields: never[];
|
|
515
|
-
geometry: never[];
|
|
516
|
-
bindings: never[];
|
|
517
|
-
dirty: boolean;
|
|
518
|
-
revision: null;
|
|
519
|
-
canUndo?: undefined;
|
|
520
|
-
canRedo?: undefined;
|
|
521
|
-
palette?: undefined;
|
|
522
|
-
} | {
|
|
523
|
-
context: string;
|
|
524
|
-
name: string;
|
|
525
|
-
revision: number;
|
|
526
|
-
dirty: boolean;
|
|
527
|
-
canUndo: boolean;
|
|
528
|
-
canRedo: boolean;
|
|
529
|
-
fields: {
|
|
530
|
-
value: number;
|
|
531
|
-
id: string;
|
|
532
|
-
unit: import("./graph-types.ts").FigureUnit;
|
|
533
|
-
min: number;
|
|
534
|
-
max: number;
|
|
535
|
-
role?: "design" | "state";
|
|
536
|
-
}[];
|
|
537
|
-
geometry: import("./asset-types.ts").FigureAssetGeometry[];
|
|
538
|
-
bindings: import("./asset-types.ts").FigureEvaluatedBinding[];
|
|
539
|
-
palette: Record<string, string>;
|
|
540
|
-
};
|
|
186
|
+
acknowledgeSaved({ context, revision, text }: FigureWorkspaceExport): ClosedView | OpenView;
|
|
541
187
|
};
|
|
542
188
|
export type FigureEditorWorkspace = ReturnType<typeof createFigureEditorWorkspace>;
|
|
543
189
|
export type FigureWorkspaceView = ReturnType<FigureEditorWorkspace['read']>;
|
|
190
|
+
export {};
|
|
544
191
|
//# sourceMappingURL=editor-workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-workspace.d.ts","sourceRoot":"","sources":["../src/editor-workspace.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"editor-workspace.d.ts","sourceRoot":"","sources":["../src/editor-workspace.ts"],"names":[],"mappings":"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"}
|
package/dist/editor-workspace.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { previewFigureCommand } from "./command-preview.js";
|
|
2
|
-
import { parseFigureAsset, serializeFigureAsset,
|
|
2
|
+
import { parseFigureAsset, serializeFigureAsset, captureFigureAuthoredInputs, captureAndCompileFigureAsset } from "./asset.js";
|
|
3
3
|
import { createFigureAuthoringSession } from "./authoring-session.js";
|
|
4
4
|
import { addFigureBox, addFigurePrimitive } from "./create.js";
|
|
5
5
|
import { editFigurePart, removePart } from "./part-edit.js";
|
|
@@ -28,8 +28,33 @@ export function createFigureEditorWorkspace() {
|
|
|
28
28
|
if (q.expectedRevision !== a.revision)
|
|
29
29
|
fail('REVISION_CONFLICT', 'editor changed since request');
|
|
30
30
|
}
|
|
31
|
+
/*
|
|
32
|
+
The same figure state is asked about by the read, the validation of the edit that made it, the next command and the
|
|
33
|
+
export. What is derived from an asset and its inputs -- the asset with them captured, its evaluation, its text -- is
|
|
34
|
+
worked out once for that pair and held by the objects themselves, which a change replaces and never edits.
|
|
35
|
+
*/
|
|
36
|
+
const texts = new WeakMap();
|
|
37
|
+
const textOf = (asset) => {
|
|
38
|
+
let text = texts.get(asset);
|
|
39
|
+
if (text === undefined)
|
|
40
|
+
texts.set(asset, (text = JSON.stringify(asset)));
|
|
41
|
+
return text;
|
|
42
|
+
};
|
|
43
|
+
const derived = new WeakMap();
|
|
44
|
+
/** The asset with the live inputs and state captured (what a command sees) and what it evaluates to. Throws what a compile throws. */
|
|
45
|
+
function derive(asset, inputs) {
|
|
46
|
+
let byInputs = derived.get(asset);
|
|
47
|
+
if (!byInputs)
|
|
48
|
+
derived.set(asset, (byInputs = new WeakMap()));
|
|
49
|
+
let one = byInputs.get(inputs);
|
|
50
|
+
if (!one) {
|
|
51
|
+
const { asset: seen, compiled } = captureAndCompileFigureAsset(asset, inputs, { captureStateDefaults: true });
|
|
52
|
+
byInputs.set(inputs, (one = { seen, rendered: compiled.evaluate() }));
|
|
53
|
+
}
|
|
54
|
+
return one;
|
|
55
|
+
}
|
|
31
56
|
function dirty() {
|
|
32
|
-
return !!active &&
|
|
57
|
+
return !!active && textOf(active.asset) !== textOf(active.baseline);
|
|
33
58
|
}
|
|
34
59
|
function leave(discard) {
|
|
35
60
|
if (dirty() && !discard)
|
|
@@ -37,7 +62,7 @@ export function createFigureEditorWorkspace() {
|
|
|
37
62
|
}
|
|
38
63
|
const snapshot = (a) => structuredClone({ asset: a.asset, inputs: a.inputs });
|
|
39
64
|
function validate(s) {
|
|
40
|
-
|
|
65
|
+
derive(s.asset, s.inputs);
|
|
41
66
|
}
|
|
42
67
|
function install(a, next) {
|
|
43
68
|
validate(next);
|
|
@@ -49,10 +74,25 @@ export function createFigureEditorWorkspace() {
|
|
|
49
74
|
a.inputs = next.inputs;
|
|
50
75
|
a.revision++;
|
|
51
76
|
}
|
|
77
|
+
/*
|
|
78
|
+
Compiling and evaluating the figure and serializing it twice for `dirty` is the cost of a read, and a modeller reads
|
|
79
|
+
several times for one selection or edit. Every change replaces `asset`, `inputs` or `baseline` rather than editing
|
|
80
|
+
them in place, so the references and the history lengths say whether the last answer still holds.
|
|
81
|
+
*/
|
|
82
|
+
let exported = null;
|
|
83
|
+
let cached = null;
|
|
52
84
|
function read() {
|
|
53
85
|
if (!active)
|
|
54
86
|
return { context: null, name: null, fields: [], geometry: [], bindings: [], dirty: false, revision: null };
|
|
55
|
-
const a = active
|
|
87
|
+
const a = active;
|
|
88
|
+
if (cached && cached.a === a && cached.asset === a.asset && cached.inputs === a.inputs && cached.baseline === a.baseline && cached.undo === a.undo.length && cached.redo === a.redo.length && cached.revision === a.revision)
|
|
89
|
+
return { ...cached.view };
|
|
90
|
+
const view = build(a);
|
|
91
|
+
cached = { a, asset: a.asset, inputs: a.inputs, baseline: a.baseline, undo: a.undo.length, redo: a.redo.length, revision: a.revision, view };
|
|
92
|
+
return { ...view };
|
|
93
|
+
}
|
|
94
|
+
function build(a) {
|
|
95
|
+
const { rendered } = derive(a.asset, a.inputs);
|
|
56
96
|
return {
|
|
57
97
|
context: a.context,
|
|
58
98
|
name: a.asset.name,
|
|
@@ -148,7 +188,7 @@ export function createFigureEditorWorkspace() {
|
|
|
148
188
|
command({ context, action, ...q }) {
|
|
149
189
|
const a = current(context);
|
|
150
190
|
control(a, q);
|
|
151
|
-
const seen =
|
|
191
|
+
const seen = derive(a.asset, a.inputs).seen;
|
|
152
192
|
const asset = applyFigureAuthoring(seen, action, q);
|
|
153
193
|
const inputs = Object.fromEntries(asset.document.model.inputs.map(i => [i.id, asset.designInputs[i.id] ?? asset.stateDefaults[i.id]]));
|
|
154
194
|
install(a, { asset, inputs });
|
|
@@ -163,7 +203,7 @@ export function createFigureEditorWorkspace() {
|
|
|
163
203
|
relocateAttached({ context, part, position, attachment, ...q }) {
|
|
164
204
|
const a = current(context);
|
|
165
205
|
control(a, q);
|
|
166
|
-
const seen =
|
|
206
|
+
const seen = derive(a.asset, a.inputs).seen;
|
|
167
207
|
const joint = seen.joints?.find(j => j.body1.part === part);
|
|
168
208
|
if (!joint || joint.type !== 'fixed' || seen.document.model.nodes.some(n => n.id === `${part}.motion`))
|
|
169
209
|
fail('EDIT_TARGET', 'only a fixed attachment can be relocated by this drag');
|
|
@@ -187,7 +227,7 @@ export function createFigureEditorWorkspace() {
|
|
|
187
227
|
},
|
|
188
228
|
previewCommand({ context, action }) {
|
|
189
229
|
const a = current(context);
|
|
190
|
-
const seen =
|
|
230
|
+
const seen = derive(a.asset, a.inputs).seen;
|
|
191
231
|
return { context, revision: a.revision, ...previewFigureCommand(seen, action, a.inputs) };
|
|
192
232
|
},
|
|
193
233
|
/**
|
|
@@ -197,7 +237,7 @@ export function createFigureEditorWorkspace() {
|
|
|
197
237
|
applyProposal({ context, steps, ...q }) {
|
|
198
238
|
const a = current(context);
|
|
199
239
|
control(a, q);
|
|
200
|
-
const seen =
|
|
240
|
+
const seen = derive(a.asset, a.inputs).seen;
|
|
201
241
|
const asset = applyFigureProposal(seen, steps, q);
|
|
202
242
|
const inputs = Object.fromEntries(asset.document.model.inputs.map(i => [i.id, asset.designInputs[i.id] ?? asset.stateDefaults[i.id]]));
|
|
203
243
|
install(a, { asset, inputs });
|
|
@@ -233,11 +273,13 @@ export function createFigureEditorWorkspace() {
|
|
|
233
273
|
},
|
|
234
274
|
export({ context, captureStateDefaults = false }) {
|
|
235
275
|
const a = current(context);
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
revision: a.revision,
|
|
239
|
-
|
|
240
|
-
};
|
|
276
|
+
const held = exported;
|
|
277
|
+
if (held && held.asset === a.asset && held.inputs === a.inputs && held.defaults === captureStateDefaults)
|
|
278
|
+
return { context, revision: a.revision, text: held.text };
|
|
279
|
+
/* The workspace's asset was compiled when it was opened or written: it is not compiled again to be exported. */
|
|
280
|
+
const text = JSON.stringify(captureAndCompileFigureAsset(a.asset, a.inputs, { captureStateDefaults }, true).asset);
|
|
281
|
+
exported = { asset: a.asset, inputs: a.inputs, defaults: captureStateDefaults, text };
|
|
282
|
+
return { context, revision: a.revision, text };
|
|
241
283
|
},
|
|
242
284
|
acknowledgeSaved({ context, revision, text }) {
|
|
243
285
|
const a = current(context);
|