@pygmalionjs/pygmalion 0.8.1 → 0.10.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.
Files changed (150) hide show
  1. package/README.md +34 -0
  2. package/binding-source.d.ts +25 -0
  3. package/dist-lib/{CameraLayer-B2D29VXQ.js → CameraLayer-BUOlJcUa.js} +17 -17
  4. package/dist-lib/pygmalion.js +24524 -12555
  5. package/dist-lib/{runtime-BAy8W1mJ.js → runtime-BOfDlGPR.js} +12438 -11118
  6. package/dist-lib/style.css +1 -1
  7. package/dist-lib/testing.js +19 -19
  8. package/dist-lib/types/binding/catalog.d.ts +10 -0
  9. package/dist-lib/types/binding/contracts.d.ts +202 -0
  10. package/dist-lib/types/binding/documentCommands.d.ts +38 -0
  11. package/dist-lib/types/binding/duplicateMetadata.d.ts +8 -0
  12. package/dist-lib/types/binding/index.d.ts +7 -0
  13. package/dist-lib/types/binding/preview.d.ts +37 -0
  14. package/dist-lib/types/binding/source.d.ts +109 -0
  15. package/dist-lib/types/binding/useDataProjection.d.ts +9 -0
  16. package/dist-lib/types/binding/validate.d.ts +8 -0
  17. package/dist-lib/types/core/runtime.d.ts +6 -0
  18. package/dist-lib/types/document/appearance.d.ts +112 -0
  19. package/dist-lib/types/document/assets.d.ts +204 -0
  20. package/dist-lib/types/document/components.d.ts +169 -0
  21. package/dist-lib/types/document/contracts.d.ts +171 -0
  22. package/dist-lib/types/document/engine.d.ts +20 -0
  23. package/dist-lib/types/document/exportSettings.d.ts +45 -0
  24. package/dist-lib/types/document/geometry.d.ts +11 -0
  25. package/dist-lib/types/document/layout.d.ts +53 -0
  26. package/dist-lib/types/document/prototype.d.ts +424 -0
  27. package/dist-lib/types/document/prototypeReferences.d.ts +3 -0
  28. package/dist-lib/types/document/richText.d.ts +185 -0
  29. package/dist-lib/types/document/styles.d.ts +216 -0
  30. package/dist-lib/types/document/svgImport.d.ts +17 -0
  31. package/dist-lib/types/document/vector.d.ts +222 -0
  32. package/dist-lib/types/editor/designCompiler.d.ts +7 -0
  33. package/dist-lib/types/editor/designImport.d.ts +7 -0
  34. package/dist-lib/types/editor/inspect.d.ts +8 -0
  35. package/dist-lib/types/editor/revisionCatalogInstall.d.ts +1 -1
  36. package/dist-lib/types/editor/screenInteractions.d.ts +3 -3
  37. package/dist-lib/types/editor/store.d.ts +1 -1
  38. package/dist-lib/types/host/project.d.ts +44 -0
  39. package/dist-lib/types/host/registryConnections.d.ts +11 -0
  40. package/dist-lib/types/host/sourceFilePlan.d.ts +15 -0
  41. package/dist-lib/types/host/sourceWriteback.d.ts +50 -0
  42. package/dist-lib/types/lib.d.ts +103 -3
  43. package/dist-lib/types/token-library/bindings.d.ts +62 -0
  44. package/dist-lib/types/token-library/contracts.d.ts +117 -0
  45. package/dist-lib/types/token-library/engine.d.ts +13 -0
  46. package/dist-lib/types/token-library/valueResolver.d.ts +19 -0
  47. package/dist-lib/types/workspace/WorkspaceShell.d.ts +9 -0
  48. package/dist-lib/types/workspace/application/ApplicationWorkspace.d.ts +3 -0
  49. package/dist-lib/types/workspace/configuration.d.ts +47 -0
  50. package/dist-lib/types/workspace/contracts.d.ts +64 -0
  51. package/dist-lib/types/workspace/controller.d.ts +35 -0
  52. package/dist-lib/types/workspace/documentSessions.d.ts +42 -0
  53. package/dist-lib/types/workspace/edit/AppearancePanel.d.ts +23 -0
  54. package/dist-lib/types/workspace/edit/ArrangeLayers.d.ts +10 -0
  55. package/dist-lib/types/workspace/edit/AssetsPanel.d.ts +16 -0
  56. package/dist-lib/types/workspace/edit/CanvasGuides.d.ts +19 -0
  57. package/dist-lib/types/workspace/edit/ComponentPanel.d.ts +11 -0
  58. package/dist-lib/types/workspace/edit/DataPanel.d.ts +16 -0
  59. package/dist-lib/types/workspace/edit/DesignWorkspace.d.ts +10 -0
  60. package/dist-lib/types/workspace/edit/LayerTree.d.ts +14 -0
  61. package/dist-lib/types/workspace/edit/LayoutPanel.d.ts +13 -0
  62. package/dist-lib/types/workspace/edit/PrototypePanel.d.ts +12 -0
  63. package/dist-lib/types/workspace/edit/ScopeTransferDialog.d.ts +40 -0
  64. package/dist-lib/types/workspace/edit/SelectionHandles.d.ts +52 -0
  65. package/dist-lib/types/workspace/edit/StylesPanel.d.ts +8 -0
  66. package/dist-lib/types/workspace/edit/TextEditor.d.ts +50 -0
  67. package/dist-lib/types/workspace/edit/VectorEditor.d.ts +89 -0
  68. package/dist-lib/types/workspace/edit/VectorToolbar.d.ts +5 -0
  69. package/dist-lib/types/workspace/edit/canvasGuideModel.d.ts +102 -0
  70. package/dist-lib/types/workspace/edit/clipboard.d.ts +35 -0
  71. package/dist-lib/types/workspace/edit/duplicateMetadata.d.ts +2 -0
  72. package/dist-lib/types/workspace/edit/geometryHandles.d.ts +224 -0
  73. package/dist-lib/types/workspace/edit/layerArrangement.d.ts +39 -0
  74. package/dist-lib/types/workspace/edit/layerMoves.d.ts +44 -0
  75. package/dist-lib/types/workspace/edit/projection.d.ts +12 -0
  76. package/dist-lib/types/workspace/edit/scopeTransfer.d.ts +96 -0
  77. package/dist-lib/types/workspace/edit/textStyles.d.ts +75 -0
  78. package/dist-lib/types/workspace/edit/vectorTools.d.ts +136 -0
  79. package/dist-lib/types/workspace/legacyModeAdapter.d.ts +13 -0
  80. package/dist-lib/types/workspace/source/ResponsiveLayoutPanel.d.ts +20 -0
  81. package/dist-lib/types/workspace/source/SourceReview.d.ts +11 -0
  82. package/dist-lib/types/workspace/source/appearanceSource.d.ts +19 -0
  83. package/dist-lib/types/workspace/source/compiler.d.ts +5 -0
  84. package/dist-lib/types/workspace/source/contracts.d.ts +156 -0
  85. package/dist-lib/types/workspace/source/controller.d.ts +50 -0
  86. package/dist-lib/types/workspace/source/documentRevision.d.ts +2 -0
  87. package/dist-lib/types/workspace/source/draftPreviewClient.d.ts +13 -0
  88. package/dist-lib/types/workspace/source/draftRecipe.d.ts +30 -0
  89. package/dist-lib/types/workspace/source/flowContracts.d.ts +72 -0
  90. package/dist-lib/types/workspace/source/prototypeSource.d.ts +4 -0
  91. package/dist-lib/types/workspace/source/responsive.d.ts +13 -0
  92. package/dist-lib/types/workspace/source/responsiveContracts.d.ts +78 -0
  93. package/dist-lib/types/workspace/source/structure.d.ts +21 -0
  94. package/dist-lib/types/workspace/source/textSource.d.ts +28 -0
  95. package/dist-lib/types/workspace/tokens/TokenLibraryContext.d.ts +11 -0
  96. package/dist-lib/types/workspace/tokens/TokenLibraryWorkspace.d.ts +14 -0
  97. package/dist-lib/types/workspace/tokens/contracts.d.ts +74 -0
  98. package/dist-lib/types/workspace/tokens/controller.d.ts +44 -0
  99. package/dist-lib/types/workspace/view/PrototypePlayer.d.ts +17 -0
  100. package/dist-lib/types/workspace/view/StoryboardWorkspace.d.ts +3 -0
  101. package/dist-lib/types/workspace/view/prototypePlayback.d.ts +46 -0
  102. package/draft-preview.d.ts +54 -0
  103. package/host-runtime.d.ts +73 -0
  104. package/inspect.d.ts +2 -0
  105. package/jsx-source-reconciler.d.ts +35 -0
  106. package/node/design-session.mjs +3 -0
  107. package/node/host-runtime.mjs +4 -0
  108. package/node/inspect-plugin.mjs +3 -1
  109. package/node/inspect-writeback.mjs +18 -2
  110. package/node/jsx-source-reconciler.mjs +155 -0
  111. package/node/preview-artifact-store.mjs +10 -7
  112. package/node/revision-catalog-resolver.mjs +159 -0
  113. package/node/source-archive-runtime.mjs +63 -0
  114. package/node/source-archive.mjs +88 -0
  115. package/node/source-bindings.mjs +65 -0
  116. package/node/source-file-lock.mjs +15 -0
  117. package/node/source-file-plan.mjs +162 -0
  118. package/node/source-file-proofs.mjs +44 -0
  119. package/node/source-module.mjs +17 -0
  120. package/node/source-responsive-codec.d.mts +17 -0
  121. package/node/source-responsive-codec.mjs +133 -0
  122. package/node/source-responsive.mjs +189 -0
  123. package/node/source-service-inputs.mjs +81 -0
  124. package/node/source-service-plugin.mjs +57 -0
  125. package/node/source-service.mjs +4 -0
  126. package/node/source-structure-reconcile.mjs +186 -0
  127. package/node/source-structure-wrapper-codec.d.mts +20 -0
  128. package/node/source-structure-wrapper-codec.mjs +205 -0
  129. package/node/source-structure.mjs +404 -0
  130. package/node/token-source-references.mjs +136 -0
  131. package/node/token-source-service.mjs +151 -0
  132. package/node/workspace-draft-entry.mjs +52 -0
  133. package/node/workspace-draft-preview-plugin.mjs +70 -0
  134. package/node/workspace-draft-preview.mjs +232 -0
  135. package/node/workspace-draft-process.mjs +129 -0
  136. package/node/workspace-draft-runtime.mjs +67 -0
  137. package/node/workspace-source-identity.d.mts +1 -0
  138. package/node/workspace-source-identity.mjs +21 -0
  139. package/node/workspace-source-plan.mjs +195 -0
  140. package/node/workspace-source-session.mjs +187 -0
  141. package/package.json +90 -6
  142. package/source-files.d.ts +35 -0
  143. package/source-module.d.ts +16 -0
  144. package/source-responsive.d.ts +10 -0
  145. package/source-service.d.ts +92 -0
  146. package/source-structure.d.ts +155 -0
  147. package/workspace-draft-entry.d.ts +15 -0
  148. package/workspace-source-plan.d.ts +44 -0
  149. package/docs/coverage-contracts.md +0 -444
  150. package/docs/screen-state-contract.md +0 -252
@@ -0,0 +1,424 @@
1
+ /**
2
+ * Prototype model and interpreter.
3
+ *
4
+ * Interactions live on layers (`node.properties.interactions`); flows, variables and presentation
5
+ * settings live in `document.metadata.prototype`. Both are plain DocumentValue shapes, so the
6
+ * document engine persists, validates and undoes them like any other design property. The
7
+ * interpreter is pure: `stepPrototype(document, state, event, now)` returns the next state and the
8
+ * side effects a player must perform; time enters only through `now`.
9
+ */
10
+ import type { DesignDocument, DocumentDiagnostic, DocumentDuplicateMetadataRemapper, DocumentNode, DocumentResolveOptions, DocumentTransaction, ResolvedDocumentNode } from './contracts.js';
11
+ export declare const PROTOTYPE_METADATA_KEY = "prototype";
12
+ export declare const PROTOTYPE_INTERACTIONS_PROPERTY = "interactions";
13
+ /** Upper bound for an authored transition in this player. */
14
+ export declare const PROTOTYPE_MAX_DURATION_MS = 10000;
15
+ export declare const prototypeTriggerTypes: readonly ["click", "drag", "hover", "press", "key", "mouse-enter", "mouse-leave", "mouse-down", "mouse-up", "delay"];
16
+ export type PrototypeTriggerType = typeof prototypeTriggerTypes[number];
17
+ export declare const prototypeTriggerLabels: Record<PrototypeTriggerType, string>;
18
+ export interface PrototypeTrigger {
19
+ type: PrototypeTriggerType;
20
+ key?: string;
21
+ delayMs?: number;
22
+ }
23
+ export declare const prototypeTransitionTypes: readonly ["instant", "dissolve", "smart-animate", "move-in", "move-out", "push", "slide-in", "slide-out"];
24
+ export type PrototypeTransitionType = typeof prototypeTransitionTypes[number];
25
+ export declare const prototypeTransitionLabels: Record<PrototypeTransitionType, string>;
26
+ export declare const prototypeDirectionalTransitions: ReadonlySet<PrototypeTransitionType>;
27
+ export declare const prototypeDirections: readonly ["left", "right", "up", "down"];
28
+ export type PrototypeDirection = typeof prototypeDirections[number];
29
+ export declare const prototypeEasingTypes: readonly ["linear", "ease-in", "ease-out", "ease-in-out", "ease-in-back", "ease-out-back", "ease-in-out-back", "custom-bezier", "spring"];
30
+ export type PrototypeEasingType = typeof prototypeEasingTypes[number];
31
+ export declare const prototypeSpringPresets: readonly ["gentle", "quick", "bouncy", "slow", "custom"];
32
+ export type PrototypeSpringPreset = typeof prototypeSpringPresets[number];
33
+ export type PrototypeEasing = {
34
+ type: Exclude<PrototypeEasingType, 'custom-bezier' | 'spring'>;
35
+ } | {
36
+ type: 'custom-bezier';
37
+ bezier: [number, number, number, number];
38
+ } | {
39
+ type: 'spring';
40
+ preset: PrototypeSpringPreset;
41
+ mass?: number;
42
+ stiffness?: number;
43
+ damping?: number;
44
+ };
45
+ export interface PrototypeTransition {
46
+ type: PrototypeTransitionType;
47
+ direction?: PrototypeDirection;
48
+ durationMs: number;
49
+ easing: PrototypeEasing;
50
+ /** Move, push and slide transitions may also animate layers that share a name. */
51
+ matchLayers?: boolean;
52
+ }
53
+ export declare const prototypeOverlayPositions: readonly ["center", "top-left", "top-center", "top-right", "bottom-left", "bottom-center", "bottom-right", "manual"];
54
+ export type PrototypeOverlayPosition = typeof prototypeOverlayPositions[number];
55
+ export interface PrototypeOverlaySettings {
56
+ position: PrototypeOverlayPosition;
57
+ x?: number;
58
+ y?: number;
59
+ closeOnOutsideClick: boolean;
60
+ background?: {
61
+ color: string;
62
+ opacity: number;
63
+ } | null;
64
+ }
65
+ export declare const prototypeVariableTypes: readonly ["boolean", "number", "string", "color"];
66
+ export type PrototypeVariableType = typeof prototypeVariableTypes[number];
67
+ export type PrototypeValue = boolean | number | string;
68
+ export interface PrototypeVariable {
69
+ id: string;
70
+ name: string;
71
+ type: PrototypeVariableType;
72
+ value: PrototypeValue;
73
+ description?: string;
74
+ }
75
+ export declare const prototypeBinaryOperators: readonly ["+", "-", "*", "/", "%", "==", "!=", "<", "<=", ">", ">=", "and", "or"];
76
+ export type PrototypeBinaryOperator = typeof prototypeBinaryOperators[number];
77
+ export type PrototypeExpression = {
78
+ kind: 'literal';
79
+ value: PrototypeValue;
80
+ } | {
81
+ kind: 'variable';
82
+ variableId: string;
83
+ } | {
84
+ kind: 'unary';
85
+ operator: 'not' | 'negate';
86
+ operand: PrototypeExpression;
87
+ } | {
88
+ kind: 'binary';
89
+ operator: PrototypeBinaryOperator;
90
+ left: PrototypeExpression;
91
+ right: PrototypeExpression;
92
+ };
93
+ export declare const prototypeActionTypes: readonly ["navigate", "change-to", "open-overlay", "swap-overlay", "close-overlay", "back", "scroll-to", "open-url", "set-variable", "conditional"];
94
+ export type PrototypeActionType = typeof prototypeActionTypes[number];
95
+ export declare const prototypeActionLabels: Record<PrototypeActionType, string>;
96
+ export type PrototypeAction = {
97
+ type: 'navigate';
98
+ destinationId: string;
99
+ transition: PrototypeTransition;
100
+ preserveScroll?: boolean;
101
+ }
102
+ /** Switches the enclosing instance to another component definition (a variant). */
103
+ | {
104
+ type: 'change-to';
105
+ destinationId: string;
106
+ transition: PrototypeTransition;
107
+ } | {
108
+ type: 'open-overlay';
109
+ destinationId: string;
110
+ transition: PrototypeTransition;
111
+ overlay: PrototypeOverlaySettings;
112
+ } | {
113
+ type: 'swap-overlay';
114
+ destinationId: string;
115
+ transition: PrototypeTransition;
116
+ } | {
117
+ type: 'close-overlay';
118
+ transition: PrototypeTransition;
119
+ } | {
120
+ type: 'back';
121
+ transition: PrototypeTransition;
122
+ } | {
123
+ type: 'scroll-to';
124
+ targetId: string;
125
+ transition: PrototypeTransition;
126
+ } | {
127
+ type: 'open-url';
128
+ url: string;
129
+ newTab?: boolean;
130
+ } | {
131
+ type: 'set-variable';
132
+ variableId: string;
133
+ value: PrototypeExpression;
134
+ } | {
135
+ type: 'conditional';
136
+ branches: {
137
+ condition: PrototypeExpression;
138
+ actions: PrototypeAction[];
139
+ }[];
140
+ otherwise?: PrototypeAction[];
141
+ };
142
+ export interface PrototypeInteraction {
143
+ id: string;
144
+ trigger: PrototypeTrigger;
145
+ actions: PrototypeAction[];
146
+ }
147
+ export interface PrototypeFlow {
148
+ id: string;
149
+ name: string;
150
+ startingNodeId: string;
151
+ description?: string;
152
+ }
153
+ export interface PrototypeSettings {
154
+ background?: string;
155
+ }
156
+ export interface PrototypeDocument {
157
+ version: 1;
158
+ flows: PrototypeFlow[];
159
+ variables: PrototypeVariable[];
160
+ settings?: PrototypeSettings;
161
+ }
162
+ export declare const PROTOTYPE_VARIABLE_NAME: RegExp;
163
+ export declare function defaultPrototypeTransition(type?: PrototypeTransitionType, direction?: PrototypeDirection): PrototypeTransition;
164
+ export declare function defaultPrototypeOverlaySettings(): PrototypeOverlaySettings;
165
+ export declare function defaultPrototypeAction(type: PrototypeActionType, destinationId?: string): PrototypeAction;
166
+ export declare function defaultPrototypeTrigger(type: PrototypeTriggerType): PrototypeTrigger;
167
+ /** CSS timing function for an easing; springs are approximated by the closest cubic curve. */
168
+ export declare function prototypeEasingCss(easing: PrototypeEasing): string;
169
+ /** Where an overlay sits inside its screen; manual positions are authored in screen coordinates. */
170
+ export declare function prototypeOverlayPlacement(settings: PrototypeOverlaySettings, screen: {
171
+ width: number;
172
+ height: number;
173
+ }, overlay: {
174
+ width: number;
175
+ height: number;
176
+ }): {
177
+ x: number;
178
+ y: number;
179
+ };
180
+ export type PrototypeExpressionResult = {
181
+ expression: PrototypeExpression;
182
+ error?: undefined;
183
+ } | {
184
+ expression?: undefined;
185
+ error: string;
186
+ };
187
+ /** Parses `count + 1`, `isOpen and total >= 3`, `"Hello, " + name`; variables are referenced by name. */
188
+ export declare function parsePrototypeExpression(source: string, variables: readonly PrototypeVariable[]): PrototypeExpressionResult;
189
+ /** Inverse of the parser; unknown variables print as their id so nothing is silently lost. */
190
+ export declare function formatPrototypeExpression(expression: PrototypeExpression, variables: readonly PrototypeVariable[]): string;
191
+ export type PrototypeValueType = 'boolean' | 'number' | 'string';
192
+ export type PrototypeTypeResult = {
193
+ type: PrototypeValueType;
194
+ error?: undefined;
195
+ } | {
196
+ type?: undefined;
197
+ error: string;
198
+ };
199
+ /** Static type of an expression against the declared variables. */
200
+ export declare function prototypeExpressionType(expression: PrototypeExpression, variables: readonly PrototypeVariable[]): PrototypeTypeResult;
201
+ export type PrototypeEvaluation = {
202
+ value: PrototypeValue;
203
+ error?: undefined;
204
+ } | {
205
+ value?: undefined;
206
+ error: string;
207
+ };
208
+ export declare function evaluatePrototypeExpression(expression: PrototypeExpression, values: Readonly<Record<string, PrototypeValue>>): PrototypeEvaluation;
209
+ export declare function prototypeValueAssignable(variable: PrototypeVariable, value: PrototypeValue): boolean;
210
+ export declare function isPrototypeTransition(value: unknown): value is PrototypeTransition;
211
+ export declare function isPrototypeOverlaySettings(value: unknown): value is PrototypeOverlaySettings;
212
+ export declare function isPrototypeExpression(value: unknown): value is PrototypeExpression;
213
+ export declare function isPrototypeTrigger(value: unknown): value is PrototypeTrigger;
214
+ export declare function isPrototypeAction(value: unknown, depth?: number): value is PrototypeAction;
215
+ export declare function isPrototypeInteraction(value: unknown): value is PrototypeInteraction;
216
+ export declare function isPrototypeVariable(value: unknown): value is PrototypeVariable;
217
+ export declare function isPrototypeFlow(value: unknown): value is PrototypeFlow;
218
+ export declare function isPrototypeDocument(value: unknown): value is PrototypeDocument;
219
+ export declare function emptyPrototypeDocument(): PrototypeDocument;
220
+ /** The document's prototype sidecar, or an empty one; malformed sidecars are reported by `validatePrototype`. */
221
+ export declare function readPrototypeDocument(document: DesignDocument): PrototypeDocument;
222
+ export declare function writePrototypeDocument(transaction: DocumentTransaction, value: PrototypeDocument | null): void;
223
+ /** Well-formed interactions of a (resolved or canonical) node; malformed entries are skipped here and reported by validation. */
224
+ export declare function nodeInteractions(node: Pick<DocumentNode, 'properties'>): PrototypeInteraction[];
225
+ export declare function writeNodeInteractions(transaction: DocumentTransaction, node: DocumentNode, interactions: readonly PrototypeInteraction[]): void;
226
+ export declare function hasPrototypeInteractions(node: Pick<DocumentNode, 'properties'>): boolean;
227
+ /** Remaps only explicit node destinations; variable identities remain scoped to the same prototype. */
228
+ export declare function remapPrototypeInteractions(interactions: readonly PrototypeInteraction[], nodeIds: Readonly<Record<string, string>>): PrototypeInteraction[];
229
+ /** Existing flows keep their starting nodes; duplicating a layer does not create another flow. */
230
+ export declare function prototypeDuplicateRemapper(inner?: DocumentDuplicateMetadataRemapper): DocumentDuplicateMetadataRemapper;
231
+ /** Prototype destinations are the root's container children, the equivalent of Figma's top-level frames. */
232
+ export declare function prototypeScreens(document: DesignDocument): DocumentNode[];
233
+ export declare function isPrototypeScreen(document: DesignDocument, nodeId: string): boolean;
234
+ /** The screen that contains a node (itself when it is a screen); null for the root. */
235
+ export declare function prototypeScreenOf(document: DesignDocument, nodeId: string): string | null;
236
+ export declare function prototypeUrlValid(url: string): boolean;
237
+ /** Cross-references and Figma rules for every interaction, flow and variable; codes are `prototype-*`. */
238
+ export declare function validatePrototype(document: DesignDocument): DocumentDiagnostic[];
239
+ export interface PrototypeSceneLayer {
240
+ /** Source (definition-relative) node id, the id a DOM surface reports back in event paths. */
241
+ nodeId: string;
242
+ path: string[];
243
+ /** Names from the scene root down to this layer, the smart-animate hierarchy key. */
244
+ namePath: string;
245
+ name: string;
246
+ kind: DocumentNode['kind'];
247
+ x: number;
248
+ y: number;
249
+ width: number;
250
+ height: number;
251
+ opacity: number;
252
+ fill: string | null;
253
+ node: DocumentNode;
254
+ depth: number;
255
+ }
256
+ /** Stable occurrence key. Every ID is opaque; nested instances never share canonical state. */
257
+ export declare function prototypeVariantKey(instancePath: readonly string[]): string;
258
+ /** Presentation-only variant resolution; neither the document nor shared definitions are changed. */
259
+ export declare function prototypeResolveOptions(document: DesignDocument, variants: Readonly<Record<string, string>>): DocumentResolveOptions;
260
+ /** Resolves runtime variants explicitly; invalid choices never silently render canonical state. */
261
+ export declare function resolvePrototypeScene(document: DesignDocument, rootId: string, variants?: Readonly<Record<string, string>>): ResolvedDocumentNode;
262
+ export declare function prototypeSceneLayers(document: DesignDocument, rootId: string, variants?: Readonly<Record<string, string>>): PrototypeSceneLayer[];
263
+ export interface PrototypeSmartAnimatePair {
264
+ name: string;
265
+ from: PrototypeSceneLayer;
266
+ to: PrototypeSceneLayer;
267
+ }
268
+ export interface PrototypeSmartAnimatePlan {
269
+ pairs: PrototypeSmartAnimatePair[];
270
+ leaving: PrototypeSceneLayer[];
271
+ entering: PrototypeSceneLayer[];
272
+ }
273
+ /** Smart animate pairs equal names within equal hierarchy paths. Unmatched layers fade. */
274
+ export declare function matchSmartAnimateLayers(document: DesignDocument, fromScreenId: string, toScreenId: string, variants?: Readonly<Record<string, string>>): PrototypeSmartAnimatePlan;
275
+ export interface PrototypeTimer {
276
+ id: string;
277
+ at: number;
278
+ sceneId: string;
279
+ nodeId: string;
280
+ interactionId: string;
281
+ }
282
+ export interface PrototypeOverlayState {
283
+ id: string;
284
+ nodeId: string;
285
+ settings: PrototypeOverlaySettings;
286
+ transition: PrototypeTransition;
287
+ openedAt: number;
288
+ }
289
+ export type PrototypeRevert = {
290
+ type: 'variant';
291
+ instanceId: string;
292
+ definitionId: string | null;
293
+ } | {
294
+ type: 'screen';
295
+ screenId: string;
296
+ transition: PrototypeTransition;
297
+ } | {
298
+ type: 'overlay';
299
+ overlayId: string;
300
+ };
301
+ export interface PrototypeHold {
302
+ nodeId: string;
303
+ trigger: 'hover' | 'press';
304
+ /** Screen-space bounds of the hotspot when the hold began; a surface keeps it hit-testable across navigation. */
305
+ bounds: {
306
+ sceneId: string;
307
+ x: number;
308
+ y: number;
309
+ width: number;
310
+ height: number;
311
+ } | null;
312
+ reverts: PrototypeRevert[];
313
+ }
314
+ export type PrototypeTransitionKind = 'start' | 'navigate' | 'back' | 'overlay-open' | 'overlay-close' | 'overlay-swap';
315
+ export interface PrototypeTransitionState {
316
+ kind: PrototypeTransitionKind;
317
+ fromScreenId: string | null;
318
+ toScreenId: string | null;
319
+ overlayId: string | null;
320
+ transition: PrototypeTransition;
321
+ startedAt: number;
322
+ endsAt: number;
323
+ }
324
+ export interface PrototypeState {
325
+ flowId: string | null;
326
+ screenId: string;
327
+ history: string[];
328
+ overlays: PrototypeOverlayState[];
329
+ variables: Record<string, PrototypeValue>;
330
+ /** Runtime variant choices keyed by prototypeVariantKey(outer-to-inner instance path). */
331
+ variants: Record<string, string>;
332
+ scroll: Record<string, {
333
+ x: number;
334
+ y: number;
335
+ }>;
336
+ scrollTarget: {
337
+ sceneId: string;
338
+ targetId: string;
339
+ transition: PrototypeTransition;
340
+ at: number;
341
+ } | null;
342
+ timers: PrototypeTimer[];
343
+ holds: PrototypeHold[];
344
+ transition: PrototypeTransitionState | null;
345
+ sequence: number;
346
+ startedAt: number;
347
+ now: number;
348
+ }
349
+ export type PrototypePointerEventType = 'click' | 'drag' | 'mouse-enter' | 'mouse-leave' | 'mouse-down' | 'mouse-up' | 'hover-start' | 'hover-end' | 'press-start' | 'press-end';
350
+ export type PrototypeEvent =
351
+ /** `path` lists source node ids from the hit layer up to its scene root. */
352
+ {
353
+ type: PrototypePointerEventType;
354
+ path: readonly string[];
355
+ } | {
356
+ type: 'key';
357
+ key: string;
358
+ } | {
359
+ type: 'outside-click';
360
+ } | {
361
+ type: 'tick';
362
+ } | {
363
+ type: 'scroll';
364
+ sceneId: string;
365
+ x: number;
366
+ y: number;
367
+ } | {
368
+ type: 'restart';
369
+ flowId?: string | null;
370
+ };
371
+ export type PrototypeEffect = {
372
+ type: 'fired';
373
+ nodeId: string;
374
+ interactionId: string;
375
+ trigger: PrototypeTriggerType;
376
+ } | {
377
+ type: 'navigated';
378
+ kind: PrototypeTransitionKind;
379
+ fromScreenId: string | null;
380
+ toScreenId: string;
381
+ transition: PrototypeTransition;
382
+ } | {
383
+ type: 'overlay';
384
+ kind: 'opened' | 'closed' | 'swapped';
385
+ overlayId: string;
386
+ nodeId: string;
387
+ } | {
388
+ type: 'variable';
389
+ variableId: string;
390
+ value: PrototypeValue;
391
+ } | {
392
+ type: 'variant';
393
+ instanceId: string;
394
+ definitionId: string | null;
395
+ } | {
396
+ type: 'scroll-to';
397
+ sceneId: string;
398
+ targetId: string;
399
+ transition: PrototypeTransition;
400
+ } | {
401
+ type: 'open-url';
402
+ url: string;
403
+ newTab: boolean;
404
+ } | {
405
+ type: 'diagnostic';
406
+ code: string;
407
+ message: string;
408
+ nodeId?: string;
409
+ };
410
+ export interface PrototypeStepResult {
411
+ state: PrototypeState;
412
+ effects: PrototypeEffect[];
413
+ }
414
+ export interface PrototypeStartOptions {
415
+ flowId?: string | null;
416
+ startingNodeId?: string;
417
+ now?: number;
418
+ }
419
+ /** The initial state of a flow (or of an explicit starting screen); delay triggers on the screen are armed. */
420
+ export declare function createPrototypeState(document: DesignDocument, options?: PrototypeStartOptions): PrototypeState;
421
+ /** The earliest moment the state changes without input, or null when it is at rest. */
422
+ export declare function prototypeNextDeadline(state: PrototypeState): number | null;
423
+ /** One pure step: the event (or the passage of time) against a frozen document; time is `now`. */
424
+ export declare function stepPrototype(document: DesignDocument, previous: PrototypeState, event: PrototypeEvent, now: number): PrototypeStepResult;
@@ -0,0 +1,3 @@
1
+ import type { DocumentValue } from './contracts.js';
2
+ /** Known prototype destinations follow copied layers. External destinations and variable IDs stay shared. */
3
+ export declare function remapPrototypeProperties(properties: Record<string, DocumentValue>, nodeIds: Readonly<Record<string, string>>): Record<string, DocumentValue>;
@@ -0,0 +1,185 @@
1
+ import type { DesignDocument, DocumentNode, DocumentValue } from './contracts.js';
2
+ /**
3
+ * Rich text for `kind: 'text'` nodes.
4
+ *
5
+ * The plain string `properties.text` stays the canonical content that bindings and the
6
+ * visual source compiler read. `properties.richText` is an optional sidecar that holds
7
+ * per-range character styles and per-paragraph styles; `normalizeTextProperties` is the
8
+ * single function that keeps the two in sync and it is the only writer either path uses.
9
+ *
10
+ * Style that applies to the whole layer is stored on node-level properties, never in runs.
11
+ * Normalization hoists any key shared by every run (or every paragraph) to the node level
12
+ * and drops the sidecar when nothing per-range remains, so a stored `richText` always
13
+ * means "this layer has mixed styling" — the exact condition that blocks plain source output.
14
+ */
15
+ export type RichTextCase = 'none' | 'upper' | 'lower' | 'title';
16
+ export type RichTextList = 'none' | 'bullet' | 'numbered';
17
+ export type RichTextAlign = 'start' | 'center' | 'end' | 'justify';
18
+ /** The component measures; the document records only the mode. */
19
+ export type TextResizeMode = 'fixed' | 'auto-width' | 'auto-height';
20
+ export interface RichTextCharacterStyle {
21
+ fontFamily?: string;
22
+ /** CSS numeric weight, 1–1000. */
23
+ fontWeight?: number;
24
+ /** Pixels. Node-level `fontSize` may also be a permitted CSS token string. */
25
+ fontSize?: number;
26
+ italic?: boolean;
27
+ underline?: boolean;
28
+ strikethrough?: boolean;
29
+ textCase?: RichTextCase;
30
+ color?: string;
31
+ /** A link target; only http(s), mailto, tel, and relative targets validate. */
32
+ link?: string;
33
+ }
34
+ export interface RichTextParagraphStyle {
35
+ align?: RichTextAlign;
36
+ /** Unitless multiplier. */
37
+ lineHeight?: number;
38
+ /** Pixels; negative values tighten. */
39
+ letterSpacing?: number;
40
+ list?: RichTextList;
41
+ /** Indent level, 0–10. */
42
+ indent?: number;
43
+ }
44
+ export interface RichTextRun {
45
+ text: string;
46
+ style: RichTextCharacterStyle;
47
+ }
48
+ export interface RichTextParagraph {
49
+ runs: RichTextRun[];
50
+ style: RichTextParagraphStyle;
51
+ }
52
+ export interface RichText {
53
+ version: 1;
54
+ paragraphs: RichTextParagraph[];
55
+ }
56
+ /** Offsets into the plain projection, where paragraphs are joined by one `\n`. */
57
+ export interface RichTextRange {
58
+ start: number;
59
+ end: number;
60
+ }
61
+ /** Node-level defaults; `fontSize` may be a CSS token the visual compiler already accepts. */
62
+ export interface TextNodeCharacterStyle extends Omit<RichTextCharacterStyle, 'fontSize'> {
63
+ fontSize?: number | string;
64
+ }
65
+ export interface TextNodeStyle {
66
+ character: TextNodeCharacterStyle;
67
+ paragraph: RichTextParagraphStyle;
68
+ }
69
+ export declare const TEXT_CHARACTER_KEYS: readonly ["fontFamily", "fontWeight", "fontSize", "italic", "underline", "strikethrough", "textCase", "color", "link"];
70
+ export declare const TEXT_PARAGRAPH_KEYS: readonly ["align", "lineHeight", "letterSpacing", "list", "indent"];
71
+ export type RichTextCharacterKey = typeof TEXT_CHARACTER_KEYS[number];
72
+ export type RichTextParagraphKey = typeof TEXT_PARAGRAPH_KEYS[number];
73
+ export declare const TEXT_RESIZE_MODES: readonly TextResizeMode[];
74
+ export declare const RICH_TEXT_CASES: readonly RichTextCase[];
75
+ export declare const RICH_TEXT_LISTS: readonly RichTextList[];
76
+ export declare const RICH_TEXT_ALIGNMENTS: readonly RichTextAlign[];
77
+ /** Node property names for paragraph keys; alignment is `textAlign` so it never reads as layout alignment. */
78
+ export declare const TEXT_PARAGRAPH_PROPERTY: Readonly<Record<RichTextParagraphKey, string>>;
79
+ /** Every node-level typography property, including the resize mode. */
80
+ export declare const TEXT_NODE_PROPERTY_KEYS: readonly string[];
81
+ export declare const isTextLink: (value: unknown) => value is string;
82
+ export declare const isTextResizeMode: (value: unknown) => value is TextResizeMode;
83
+ export declare const isRichTextCharacterValue: (key: RichTextCharacterKey, value: unknown) => boolean;
84
+ export declare const isRichTextParagraphValue: (key: RichTextParagraphKey, value: unknown) => boolean;
85
+ export declare function isRichTextCharacterStyle(value: unknown): value is RichTextCharacterStyle;
86
+ export declare function isRichTextParagraphStyle(value: unknown): value is RichTextParagraphStyle;
87
+ export declare function isRichTextRun(value: unknown): value is RichTextRun;
88
+ export declare function isRichTextParagraph(value: unknown): value is RichTextParagraph;
89
+ export declare function isRichText(value: unknown): value is RichText;
90
+ export declare function richTextPlain(model: RichText): string;
91
+ export declare function richTextLength(model: RichText): number;
92
+ export declare function richTextFromPlain(text: string, style?: RichTextCharacterStyle, paragraphStyle?: RichTextParagraphStyle): RichText;
93
+ /** Merges adjacent runs with equal styles and drops empty runs; an empty paragraph keeps one empty run for its pending style. */
94
+ export declare function normalizeRichText(model: RichText): RichText;
95
+ /** Sets the defined keys of `style` on every character in the range; a collapsed range changes nothing. */
96
+ export declare function applyRichTextCharacterStyle(model: RichText, range: RichTextRange, style: RichTextCharacterStyle): RichText;
97
+ export declare function clearRichTextCharacterStyle(model: RichText, range: RichTextRange, keys?: readonly RichTextCharacterKey[]): RichText;
98
+ /** Sets the defined keys on every paragraph the range touches; a collapsed range targets its own paragraph. */
99
+ export declare function setRichTextParagraphStyle(model: RichText, range: RichTextRange, style: RichTextParagraphStyle): RichText;
100
+ export declare function clearRichTextParagraphStyle(model: RichText, range: RichTextRange, keys?: readonly RichTextParagraphKey[]): RichText;
101
+ /** The style typed text inherits at `offset`: the run before the caret, or the run after it at a paragraph start. */
102
+ export declare function richTextInheritedStyle(model: RichText, offset: number): RichTextCharacterStyle;
103
+ /** Inserts plain text; each `\n` starts a new paragraph that copies the split paragraph's style. */
104
+ export declare function insertRichText(model: RichText, offset: number, text: string, style?: RichTextCharacterStyle): RichText;
105
+ /** Deletes a range; a boundary inside the range merges its paragraphs under the first paragraph's style. */
106
+ export declare function deleteRichText(model: RichText, range: RichTextRange): RichText;
107
+ /** Replaces a range with plain text that inherits the replaced text's style. */
108
+ export declare function replaceRichText(model: RichText, range: RichTextRange, text: string, style?: RichTextCharacterStyle): RichText;
109
+ export declare function splitRichTextParagraph(model: RichText, offset: number): RichText;
110
+ /** Merges paragraph `index` with the one after it. */
111
+ export declare function mergeRichTextParagraphs(model: RichText, index: number): RichText;
112
+ /**
113
+ * Applies a plain-text edit (the textarea result) while runs elsewhere keep their styles. When the paragraph
114
+ * count is unchanged, every changed paragraph is one span replacement, so edits on different lines committed
115
+ * together each inherit their own neighbour; otherwise the whole differing span is replaced once.
116
+ */
117
+ export declare function applyPlainTextEdit(model: RichText, nextText: string): RichText;
118
+ export interface RichTextStyleSummary<T> {
119
+ style: T;
120
+ mixed: readonly (keyof T)[];
121
+ }
122
+ /** Explicit run styles inside the range (the inherited style at a collapsed range); keys that differ are reported as mixed. */
123
+ export declare function richTextCharacterStyleAt(model: RichText, range: RichTextRange): RichTextStyleSummary<RichTextCharacterStyle>;
124
+ export declare function richTextParagraphStyleAt(model: RichText, range: RichTextRange): RichTextStyleSummary<RichTextParagraphStyle>;
125
+ /** Keys that vary across the whole model — the exact reason plain source output is blocked. */
126
+ export declare function richTextVaryingKeys(model: RichText): {
127
+ character: readonly RichTextCharacterKey[];
128
+ paragraph: readonly RichTextParagraphKey[];
129
+ };
130
+ /** Reads the validated node-level typography; invalid values are ignored rather than rendered. */
131
+ export declare function textNodeStyle(properties: Readonly<Record<string, DocumentValue>>): TextNodeStyle;
132
+ export declare function textResizeMode(properties: Readonly<Record<string, DocumentValue>>): TextResizeMode;
133
+ /** The written string; bound content is projected by the canvas and never stored here. */
134
+ export declare function textNodePlain(properties: Readonly<Record<string, DocumentValue>>): string;
135
+ /** The editable model. A sidecar that disagrees with the written text is dropped, because the written text is what bindings and source read. */
136
+ export declare function textNodeModel(properties: Readonly<Record<string, DocumentValue>>): RichText;
137
+ export declare const isRichTextTrivial: (model: RichText) => boolean;
138
+ /** Moves styles shared by the whole text to the node level and drops run keys that repeat the node default. */
139
+ export declare function hoistRichTextStyle(model: RichText, base: TextNodeStyle): {
140
+ model: RichText;
141
+ character: TextNodeCharacterStyle;
142
+ paragraph: RichTextParagraphStyle;
143
+ };
144
+ /** A JSON round trip drops `undefined` and prototypes so the engine accepts the value. */
145
+ export declare const richTextValue: (model: RichText) => DocumentValue;
146
+ /**
147
+ * The single writer for text properties. Given a model (or the stored sidecar), it hoists
148
+ * whole-text styles to node properties, writes the plain projection to `text`, and keeps
149
+ * `richText` only while per-range styling remains. Node-level defaults are removed rather
150
+ * than written, so a layer without styling has no typography keys at all.
151
+ */
152
+ export declare function normalizeTextProperties(properties: Readonly<Record<string, DocumentValue>>, model?: RichText): Record<string, DocumentValue>;
153
+ /** Bound text never carries runs: the projected value replaces the written text at render time. */
154
+ export declare function plainTextProperties(properties: Readonly<Record<string, DocumentValue>>, text: string): Record<string, DocumentValue>;
155
+ export interface TextFontRequirement {
156
+ family: string;
157
+ weights: readonly number[];
158
+ }
159
+ export interface TextFontRequest {
160
+ family: string;
161
+ weight: number;
162
+ }
163
+ export interface TextFontLoader {
164
+ load(request: TextFontRequest): Promise<boolean>;
165
+ }
166
+ export interface TextFontLoadReport {
167
+ loaded: readonly TextFontRequest[];
168
+ unavailable: readonly TextFontRequest[];
169
+ failed: readonly (TextFontRequest & {
170
+ message: string;
171
+ })[];
172
+ }
173
+ /** Families and weights the text needs; runs without a family use the node's, and a missing family means the platform default. */
174
+ export declare function textFontRequirements(model: RichText, base?: TextNodeCharacterStyle): TextFontRequirement[];
175
+ export declare function documentFontRequirements(document: DesignDocument): TextFontRequirement[];
176
+ /** Resolves every required face through the injected loader; nothing here touches the network on its own. */
177
+ export declare function loadTextFonts(requirements: readonly TextFontRequirement[], loader: TextFontLoader): Promise<TextFontLoadReport>;
178
+ export declare function loadDocumentFonts(document: DesignDocument, loader: TextFontLoader): Promise<TextFontLoadReport>;
179
+ /** Adapts the browser `document.fonts` set when the host runs in a browser; returns null elsewhere. */
180
+ export declare function fontFaceSetLoader(fonts: {
181
+ load(font: string): Promise<unknown[]>;
182
+ check(font: string): boolean;
183
+ } | undefined | null): TextFontLoader | null;
184
+ /** A convenience for text nodes: the node's own font needs. */
185
+ export declare function textNodeFontRequirements(node: DocumentNode): TextFontRequirement[];