@pygmalionjs/pygmalion 0.10.0 → 0.11.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/dist-lib/{CameraLayer-BUOlJcUa.js → CameraLayer-BZ8HgrUG.js} +1 -1
- package/dist-lib/pygmalion.js +9500 -9329
- package/dist-lib/{runtime-BOfDlGPR.js → runtime-Bxn8116i.js} +1755 -1748
- package/dist-lib/testing.js +2 -2
- package/dist-lib/types/document/contracts.d.ts +10 -0
- package/dist-lib/types/document/prototype.d.ts +26 -5
- package/dist-lib/types/document/prototypeOccurrence.d.ts +18 -0
- package/dist-lib/types/lib.d.ts +2 -0
- package/dist-lib/types/workspace/edit/clipboard.d.ts +1 -1
- package/dist-lib/types/workspace/edit/projection.d.ts +1 -1
- package/dist-lib/types/workspace/edit/prototypeProjection.d.ts +7 -0
- package/dist-lib/types/workspace/view/PrototypePlayer.d.ts +4 -3
- package/dist-lib/types/workspace/view/prototypePlayback.d.ts +2 -2
- package/jsx-source-reconciler.d.ts +3 -0
- package/node/jsx-source-reconciler.mjs +13 -5
- package/package.json +1 -1
package/dist-lib/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { bW as l, T as u } from "./runtime-
|
|
2
|
-
import { bi as y, cc as b, cd as E, ce as P, be as T, as as $ } from "./runtime-
|
|
1
|
+
import { bW as l, T as u } from "./runtime-Bxn8116i.js";
|
|
2
|
+
import { bi as y, cc as b, cd as E, ce as P, be as T, as as $ } from "./runtime-Bxn8116i.js";
|
|
3
3
|
const v = {
|
|
4
4
|
mirror: ["status", "refresh", "refs"],
|
|
5
5
|
session: ["open", "check", "previewVisual", "applyVisual", "revertVisual"],
|
|
@@ -158,6 +158,16 @@ export interface ResolvedDocumentNode {
|
|
|
158
158
|
}
|
|
159
159
|
/** Optional presentation-time instance resolution; normal editing uses canonical definitions. */
|
|
160
160
|
export interface DocumentResolveOptions {
|
|
161
|
+
/**
|
|
162
|
+
* Expand a source occurrence before resolving its component subtree. The
|
|
163
|
+
* continuation retains inherited overrides and cycle checks, skips this
|
|
164
|
+
* occurrence's expansion hook, and accepts callback overrides for its subtree.
|
|
165
|
+
* A definition root is resolved through its instance, not expanded separately.
|
|
166
|
+
*/
|
|
167
|
+
expandNode?: (input: {
|
|
168
|
+
node: DocumentNode;
|
|
169
|
+
instancePath: readonly string[];
|
|
170
|
+
}, resolve: (options?: DocumentResolveOptions) => ResolvedDocumentNode) => readonly ResolvedDocumentNode[];
|
|
161
171
|
resolveInstance?: (input: {
|
|
162
172
|
node: DocumentNode;
|
|
163
173
|
/** Outer-to-inner instance IDs. IDs remain opaque, including slashes. */
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* side effects a player must perform; time enters only through `now`.
|
|
9
9
|
*/
|
|
10
10
|
import type { DesignDocument, DocumentDiagnostic, DocumentDuplicateMetadataRemapper, DocumentNode, DocumentResolveOptions, DocumentTransaction, ResolvedDocumentNode } from './contracts.js';
|
|
11
|
+
import type { PrototypeOccurrence, PrototypeRowPath } from './prototypeOccurrence.js';
|
|
12
|
+
export type { PrototypeOccurrence, PrototypeRowPath } from './prototypeOccurrence.js';
|
|
11
13
|
export declare const PROTOTYPE_METADATA_KEY = "prototype";
|
|
12
14
|
export declare const PROTOTYPE_INTERACTIONS_PROPERTY = "interactions";
|
|
13
15
|
/** Upper bound for an authored transition in this player. */
|
|
@@ -252,14 +254,28 @@ export interface PrototypeSceneLayer {
|
|
|
252
254
|
fill: string | null;
|
|
253
255
|
node: DocumentNode;
|
|
254
256
|
depth: number;
|
|
257
|
+
occurrence?: PrototypeOccurrence;
|
|
258
|
+
}
|
|
259
|
+
export interface PrototypeResolvedSceneNode extends Omit<ResolvedDocumentNode, 'children'> {
|
|
260
|
+
rowPath: PrototypeRowPath;
|
|
261
|
+
instancePath?: readonly string[];
|
|
262
|
+
children: PrototypeResolvedSceneNode[];
|
|
263
|
+
}
|
|
264
|
+
/** Supplies the same expanded scene used by the rendering surface, without owning authoring data. */
|
|
265
|
+
export interface PrototypeRuntimeContext {
|
|
266
|
+
resolveScene(document: DesignDocument, state: PrototypeState, rootId: string, sceneId: string): PrototypeResolvedSceneNode;
|
|
255
267
|
}
|
|
256
268
|
/** Stable occurrence key. Every ID is opaque; nested instances never share canonical state. */
|
|
257
|
-
export declare function prototypeVariantKey(instancePath: readonly string[]): string;
|
|
269
|
+
export declare function prototypeVariantKey(instancePath: readonly string[], occurrence?: PrototypeOccurrence): string;
|
|
258
270
|
/** Presentation-only variant resolution; neither the document nor shared definitions are changed. */
|
|
259
|
-
export declare function prototypeResolveOptions(document: DesignDocument, variants: Readonly<Record<string, string
|
|
271
|
+
export declare function prototypeResolveOptions(document: DesignDocument, variants: Readonly<Record<string, string>>, occurrence?: PrototypeOccurrence): DocumentResolveOptions;
|
|
260
272
|
/** Resolves runtime variants explicitly; invalid choices never silently render canonical state. */
|
|
261
273
|
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
|
|
274
|
+
export declare function prototypeSceneLayers(document: DesignDocument, rootId: string, variants?: Readonly<Record<string, string>>, options?: {
|
|
275
|
+
state: PrototypeState;
|
|
276
|
+
sceneId?: string;
|
|
277
|
+
context?: PrototypeRuntimeContext;
|
|
278
|
+
}): PrototypeSceneLayer[];
|
|
263
279
|
export interface PrototypeSmartAnimatePair {
|
|
264
280
|
name: string;
|
|
265
281
|
from: PrototypeSceneLayer;
|
|
@@ -301,6 +317,7 @@ export type PrototypeRevert = {
|
|
|
301
317
|
export interface PrototypeHold {
|
|
302
318
|
nodeId: string;
|
|
303
319
|
trigger: 'hover' | 'press';
|
|
320
|
+
occurrence?: PrototypeOccurrence;
|
|
304
321
|
/** Screen-space bounds of the hotspot when the hold began; a surface keeps it hit-testable across navigation. */
|
|
305
322
|
bounds: {
|
|
306
323
|
sceneId: string;
|
|
@@ -327,7 +344,7 @@ export interface PrototypeState {
|
|
|
327
344
|
history: string[];
|
|
328
345
|
overlays: PrototypeOverlayState[];
|
|
329
346
|
variables: Record<string, PrototypeValue>;
|
|
330
|
-
/** Runtime variant choices keyed by
|
|
347
|
+
/** Runtime variant choices keyed by the authored instance path and optional scene/row occurrence. */
|
|
331
348
|
variants: Record<string, string>;
|
|
332
349
|
scroll: Record<string, {
|
|
333
350
|
x: number;
|
|
@@ -338,6 +355,7 @@ export interface PrototypeState {
|
|
|
338
355
|
targetId: string;
|
|
339
356
|
transition: PrototypeTransition;
|
|
340
357
|
at: number;
|
|
358
|
+
occurrence?: PrototypeOccurrence;
|
|
341
359
|
} | null;
|
|
342
360
|
timers: PrototypeTimer[];
|
|
343
361
|
holds: PrototypeHold[];
|
|
@@ -352,6 +370,7 @@ export type PrototypeEvent =
|
|
|
352
370
|
{
|
|
353
371
|
type: PrototypePointerEventType;
|
|
354
372
|
path: readonly string[];
|
|
373
|
+
occurrence?: PrototypeOccurrence;
|
|
355
374
|
} | {
|
|
356
375
|
type: 'key';
|
|
357
376
|
key: string;
|
|
@@ -397,6 +416,7 @@ export type PrototypeEffect = {
|
|
|
397
416
|
sceneId: string;
|
|
398
417
|
targetId: string;
|
|
399
418
|
transition: PrototypeTransition;
|
|
419
|
+
occurrence?: PrototypeOccurrence;
|
|
400
420
|
} | {
|
|
401
421
|
type: 'open-url';
|
|
402
422
|
url: string;
|
|
@@ -415,10 +435,11 @@ export interface PrototypeStartOptions {
|
|
|
415
435
|
flowId?: string | null;
|
|
416
436
|
startingNodeId?: string;
|
|
417
437
|
now?: number;
|
|
438
|
+
context?: PrototypeRuntimeContext;
|
|
418
439
|
}
|
|
419
440
|
/** The initial state of a flow (or of an explicit starting screen); delay triggers on the screen are armed. */
|
|
420
441
|
export declare function createPrototypeState(document: DesignDocument, options?: PrototypeStartOptions): PrototypeState;
|
|
421
442
|
/** The earliest moment the state changes without input, or null when it is at rest. */
|
|
422
443
|
export declare function prototypeNextDeadline(state: PrototypeState): number | null;
|
|
423
444
|
/** 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;
|
|
445
|
+
export declare function stepPrototype(document: DesignDocument, previous: PrototypeState, event: PrototypeEvent, now: number, runtime?: PrototypeRuntimeContext): PrototypeStepResult;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** A stable row address, ordered from the outer repeat to the inner repeat. */
|
|
2
|
+
export type PrototypeRowPath = readonly {
|
|
3
|
+
repeatId: string;
|
|
4
|
+
key: string | number;
|
|
5
|
+
}[];
|
|
6
|
+
/** A rendered occurrence. Overlay scene IDs distinguish separate openings of one screen. */
|
|
7
|
+
export interface PrototypeOccurrence {
|
|
8
|
+
sceneId: string;
|
|
9
|
+
rowPath: PrototypeRowPath;
|
|
10
|
+
}
|
|
11
|
+
export declare function prototypeOccurrenceValid(value: unknown): value is PrototypeOccurrence;
|
|
12
|
+
export declare function prototypeRowPathPrefix(prefix: PrototypeRowPath, path: PrototypeRowPath): boolean;
|
|
13
|
+
export declare function prototypeOccurrenceEqual(left: PrototypeOccurrence | undefined, right: PrototypeOccurrence | undefined): boolean;
|
|
14
|
+
export declare function encodePrototypeVariantKey(instancePath: readonly string[], occurrence?: PrototypeOccurrence): string;
|
|
15
|
+
export declare function decodePrototypeVariantKey(key: string): {
|
|
16
|
+
instancePath: string[];
|
|
17
|
+
occurrence?: PrototypeOccurrence;
|
|
18
|
+
} | null;
|
package/dist-lib/types/lib.d.ts
CHANGED
|
@@ -424,3 +424,5 @@ export { PrototypePanel } from './workspace/edit/PrototypePanel.js';
|
|
|
424
424
|
export { PrototypePlayer } from './workspace/view/PrototypePlayer.js';
|
|
425
425
|
export type { PrototypePlayerProps } from './workspace/view/PrototypePlayer.js';
|
|
426
426
|
export * from './workspace/view/prototypePlayback.js';
|
|
427
|
+
export { createPrototypeProjectionContext } from './workspace/edit/prototypeProjection.js';
|
|
428
|
+
export type { PrototypeProjectionContext } from './workspace/edit/prototypeProjection.js';
|
|
@@ -22,7 +22,7 @@ export interface PasteDesignResult {
|
|
|
22
22
|
nodeIds: Record<string, string>;
|
|
23
23
|
}
|
|
24
24
|
/** Pure paste plan; commit the returned same-identity snapshot as one undoable transaction. */
|
|
25
|
-
export declare function pasteDesignSubtrees(
|
|
25
|
+
export declare function pasteDesignSubtrees(targetInput: DesignDocument, payloadInput: DesignClipboard, options: {
|
|
26
26
|
parentId: string;
|
|
27
27
|
allocateId: (sourceId: string) => string;
|
|
28
28
|
offset?: {
|
|
@@ -9,4 +9,4 @@ export interface ProjectedDocumentNode {
|
|
|
9
9
|
children: ProjectedDocumentNode[];
|
|
10
10
|
}
|
|
11
11
|
/** Fixture rows affect this disposable scene only, never canonical document geometry. */
|
|
12
|
-
export declare function projectDocumentScene(document: DesignDocument, data: DataProjection | null, resolveOptions?: DocumentResolveOptions): ProjectedDocumentNode;
|
|
12
|
+
export declare function projectDocumentScene(document: DesignDocument, data: DataProjection | null, resolveOptions?: DocumentResolveOptions, resolveRowOptions?: (rowPath: BindingRuntimeScope['rowPath']) => DocumentResolveOptions): ProjectedDocumentNode;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DataProjection } from '../../binding/preview.js';
|
|
2
|
+
import type { PrototypeRuntimeContext } from '../../document/prototype.js';
|
|
3
|
+
export interface PrototypeProjectionContext extends PrototypeRuntimeContext {
|
|
4
|
+
readonly projection: DataProjection | null;
|
|
5
|
+
}
|
|
6
|
+
/** One captured data projection supplies runtime hit testing, layout and presentation rendering. */
|
|
7
|
+
export declare function createPrototypeProjectionContext(data: DataProjection | null): PrototypeProjectionContext;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { DesignDocument } from '../../document/contracts.js';
|
|
3
|
-
import { type PrototypeState } from '../../document/prototype.js';
|
|
3
|
+
import { type PrototypeRuntimeContext, type PrototypeState } from '../../document/prototype.js';
|
|
4
4
|
import { type PrototypeClock } from './prototypePlayback.js';
|
|
5
5
|
|
|
6
6
|
export interface PrototypePlayerProps {
|
|
7
7
|
document: DesignDocument;
|
|
8
8
|
/** Uses the same document/component renderer as Edit, with authoring controls disabled. */
|
|
9
|
-
renderScene(rootId: string, state: PrototypeState): ReactNode;
|
|
10
|
-
sceneSize?(rootId: string, state: PrototypeState): {
|
|
9
|
+
renderScene(rootId: string, state: PrototypeState, sceneId?: string): ReactNode;
|
|
10
|
+
sceneSize?(rootId: string, state: PrototypeState, sceneId?: string): {
|
|
11
11
|
width: number;
|
|
12
12
|
height: number;
|
|
13
13
|
} | undefined;
|
|
14
|
+
context?: PrototypeRuntimeContext;
|
|
14
15
|
onClose(): void;
|
|
15
16
|
clock?: PrototypeClock;
|
|
16
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DesignDocument, DocumentNode, ResolvedDocumentNode } from '../../document/contracts.js';
|
|
2
|
-
import { type PrototypeEffect, type PrototypeEvent, type PrototypeStartOptions, type PrototypeState } from '../../document/prototype.js';
|
|
2
|
+
import { type PrototypeEffect, type PrototypeEvent, type PrototypeRuntimeContext, type PrototypeStartOptions, type PrototypeState } from '../../document/prototype.js';
|
|
3
3
|
export interface PrototypeClock {
|
|
4
4
|
now(): number;
|
|
5
5
|
schedule(callback: () => void, delayMs: number): unknown;
|
|
@@ -38,7 +38,7 @@ export interface PrototypePresentationScene {
|
|
|
38
38
|
opacity: number;
|
|
39
39
|
} | null;
|
|
40
40
|
}
|
|
41
|
-
export declare function prototypeScene(document: DesignDocument, state: PrototypeState): PrototypePresentationScene[];
|
|
41
|
+
export declare function prototypeScene(document: DesignDocument, state: PrototypeState, context?: PrototypeRuntimeContext): PrototypePresentationScene[];
|
|
42
42
|
export declare function prototypeFlowOptions(document: DesignDocument): {
|
|
43
43
|
id: string;
|
|
44
44
|
label: string;
|
|
@@ -8,6 +8,9 @@ export interface ReconcileSourceProjection { anchors: JsxStructureAnchor[]; node
|
|
|
8
8
|
export interface JsxSourceReconcilerOptions {
|
|
9
9
|
file: string;
|
|
10
10
|
identityFile: string;
|
|
11
|
+
/** Additional nullable inputs, captured at construction. Each requires an own input key and proof on both sides.
|
|
12
|
+
* Names must be unique, nonblank, and different from file. identityFile is always included and may appear once. Default: []. */
|
|
13
|
+
optionalInputFiles?: readonly string[];
|
|
11
14
|
rootId: string;
|
|
12
15
|
definitionId: string;
|
|
13
16
|
screenId: string;
|
|
@@ -19,7 +19,7 @@ const sourceLayout = layout => layout ? { direction: layout.direction, gap: layo
|
|
|
19
19
|
export function createJsxSourceReconciler({
|
|
20
20
|
file, identityFile, rootId, definitionId, screenId, documentId, opaqueNodeIds,
|
|
21
21
|
projectSource, resolveWrapper = () => undefined, compileDocumentSource,
|
|
22
|
-
allowUnchangedIslandRelocation = false,
|
|
22
|
+
allowUnchangedIslandRelocation = false, optionalInputFiles = [],
|
|
23
23
|
}) {
|
|
24
24
|
if ([file, identityFile, rootId, definitionId, screenId, documentId].some(value => typeof value !== 'string' || !value)
|
|
25
25
|
|| file === identityFile || !Array.isArray(opaqueNodeIds) || new Set(opaqueNodeIds).size !== opaqueNodeIds.length
|
|
@@ -27,13 +27,19 @@ export function createJsxSourceReconciler({
|
|
|
27
27
|
|| ![projectSource, resolveWrapper, compileDocumentSource].every(value => typeof value === 'function')) {
|
|
28
28
|
throw new TypeError('A source reconciler requires explicit files, node identities, and projection/compiler callbacks.');
|
|
29
29
|
}
|
|
30
|
+
const optionalInputs = Array.isArray(optionalInputFiles) ? [...optionalInputFiles] : null;
|
|
31
|
+
if (!optionalInputs || new Set(optionalInputs).size !== optionalInputs.length
|
|
32
|
+
|| optionalInputs.some(value => typeof value !== 'string' || !value.trim() || value === file)) {
|
|
33
|
+
throw new TypeError('Optional source inputs must be unique nonempty file names excluding the main source file.');
|
|
34
|
+
}
|
|
35
|
+
const nullableInputs = new Set([identityFile, ...optionalInputs]);
|
|
30
36
|
opaqueNodeIds = [...opaqueNodeIds];
|
|
31
37
|
function capturedInputs(value) {
|
|
32
|
-
if (!record(value) || Object.keys(value).length > 500 || !Object.hasOwn(value,
|
|
33
|
-
|| typeof value[file] !== 'string' || !value[file]) fail('inputs-invalid', 'Complete source and
|
|
38
|
+
if (!record(value) || Object.keys(value).length > 500 || [...nullableInputs].some(inputFile => !Object.hasOwn(value, inputFile))
|
|
39
|
+
|| typeof value[file] !== 'string' || !value[file]) fail('inputs-invalid', 'Complete source, identity, and declared optional inputs are required.');
|
|
34
40
|
let size = 0;
|
|
35
41
|
for (const [inputFile, content] of Object.entries(value)) {
|
|
36
|
-
if (content === null && inputFile
|
|
42
|
+
if (content === null && nullableInputs.has(inputFile)) continue;
|
|
37
43
|
if (typeof content !== 'string' || Buffer.from(content).toString('utf8') !== content) fail('inputs-invalid', 'Source inputs must be UTF-8 strings.', inputFile);
|
|
38
44
|
size += Buffer.byteLength(content);
|
|
39
45
|
}
|
|
@@ -92,7 +98,9 @@ export function createJsxSourceReconciler({
|
|
|
92
98
|
}
|
|
93
99
|
seen.add(proof.file);
|
|
94
100
|
}
|
|
95
|
-
if (!seen.has(file) || !seen.has(
|
|
101
|
+
if (!seen.has(file) || [...nullableInputs].some(inputFile => !seen.has(inputFile))) {
|
|
102
|
+
fail('proofs-invalid', 'Source, identity, and declared optional input proofs are required.');
|
|
103
|
+
}
|
|
96
104
|
}
|
|
97
105
|
function verifyProjection(document, projection) {
|
|
98
106
|
for (const node of projection.nodes) {
|