@pygmalionjs/pygmalion 0.12.0 → 0.13.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.
@@ -1,6 +1,6 @@
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
- const v = {
1
+ import { bY as l, T as u } from "./runtime-DkCf4iKe.js";
2
+ import { bk as y, ce as b, cf as E, cg as P, bg as T, as as $ } from "./runtime-DkCf4iKe.js";
3
+ const f = {
4
4
  mirror: ["status", "refresh", "refs"],
5
5
  session: ["open", "check", "previewVisual", "applyVisual", "revertVisual"],
6
6
  inspect: ["impact"],
@@ -8,12 +8,12 @@ const v = {
8
8
  preview: ["artifact", "progress", "catalog"],
9
9
  storyboard: ["environment", "sourceUsage", "componentBranches"]
10
10
  };
11
- function g(m = {}, t = {}) {
12
- const n = [], d = t.origin ?? "", e = (r) => {
11
+ function v(m = {}, t = {}) {
12
+ const n = [], d = t.origin ?? "", r = (e) => {
13
13
  var a;
14
14
  const i = {};
15
- for (const o of v[r]) {
16
- const s = `${r}.${String(o)}`, c = (a = m[r]) == null ? void 0 : a[o];
15
+ for (const o of f[e]) {
16
+ const s = `${e}.${String(o)}`, c = (a = m[e]) == null ? void 0 : a[o];
17
17
  i[String(o)] = (...p) => (n.push({ operation: s, request: p[0] }), c ? Promise.resolve(c(...p)) : Promise.reject(
18
18
  new u({
19
19
  operation: s,
@@ -27,13 +27,13 @@ function g(m = {}, t = {}) {
27
27
  return {
28
28
  calls: n,
29
29
  endpoints: l(t.endpoints),
30
- resolveUrl: (r) => `${d}${r}`,
31
- mirror: e("mirror"),
32
- session: e("session"),
33
- inspect: e("inspect"),
34
- qa: e("qa"),
35
- preview: e("preview"),
36
- storyboard: e("storyboard")
30
+ resolveUrl: (e) => `${d}${e}`,
31
+ mirror: r("mirror"),
32
+ session: r("session"),
33
+ inspect: r("inspect"),
34
+ qa: r("qa"),
35
+ preview: r("preview"),
36
+ storyboard: r("storyboard")
37
37
  };
38
38
  }
39
39
  export {
@@ -42,6 +42,6 @@ export {
42
42
  E as FrozenRoutePreviewView,
43
43
  P as NodeModel,
44
44
  T as createEditorRuntime,
45
- g as createMemoryTransport,
45
+ v as createMemoryTransport,
46
46
  $ as serializeNode
47
47
  };
@@ -10,6 +10,10 @@ export type { StylesPanelProps } from './workspace/edit/StylesPanel.js';
10
10
  export { TokenLibraryProvider, useTokenLibraryController, useHasTokenLibraryProvider } from './workspace/tokens/TokenLibraryContext.js';
11
11
  export { createTokenLibraryEngine, reopenTokenLibrary, validateTokenLibraryDocument, resolveTokenLibraryValue, tokenValueEditability, TokenLibraryValidationError } from './token-library/engine.js';
12
12
  export type * from './token-library/contracts.js';
13
+ export { createTokenLibraryCache } from './token-library/cache.js';
14
+ export type { TokenLibraryTextResolver, TokenLibraryPreviewContext, TokenLibraryCacheOptions, TokenLibraryCache } from './token-library/cache.js';
15
+ export { formatTokenReferences, TokenReferenceFormatError } from './token-library/formatReferences.js';
16
+ export type { TokenReferenceFormatContext } from './token-library/formatReferences.js';
13
17
  export { createTokenValueResolver } from './token-library/valueResolver.js';
14
18
  export type { TokenValueReferenceRange, TokenValueResolverOptions, ResolvedTokenText } from './token-library/valueResolver.js';
15
19
  export type * from './workspace/tokens/contracts.js';
@@ -429,5 +433,6 @@ export { PrototypePanel } from './workspace/edit/PrototypePanel.js';
429
433
  export { PrototypePlayer } from './workspace/view/PrototypePlayer.js';
430
434
  export type { PrototypePlayerProps } from './workspace/view/PrototypePlayer.js';
431
435
  export * from './workspace/view/prototypePlayback.js';
436
+ export type { PrototypeInputFrame } from './workspace/view/prototypeInputFrame.js';
432
437
  export { createPrototypeProjectionContext } from './workspace/edit/prototypeProjection.js';
433
438
  export type { PrototypeProjectionContext } from './workspace/edit/prototypeProjection.js';
@@ -0,0 +1,20 @@
1
+ import type { TokenLibraryDocument } from './contracts.js';
2
+ import type { ResolvedTokenText } from './valueResolver.js';
3
+ export type TokenLibraryTextResolver = (tokenId: string, modeId: string) => ResolvedTokenText;
4
+ export interface TokenLibraryPreviewContext {
5
+ document: TokenLibraryDocument;
6
+ modeId: string;
7
+ resolve: TokenLibraryTextResolver;
8
+ }
9
+ export interface TokenLibraryCacheOptions<Preview> {
10
+ createResolver(document: TokenLibraryDocument): TokenLibraryTextResolver;
11
+ createPreview(context: TokenLibraryPreviewContext): Preview;
12
+ }
13
+ export interface TokenLibraryCache<Preview> {
14
+ resolver(document: TokenLibraryDocument): TokenLibraryTextResolver;
15
+ preview(document: TokenLibraryDocument, modeId: string): Preview;
16
+ /** Invalidate callbacks' external baseline inputs; previously returned resolvers remain usable. */
17
+ clear(): void;
18
+ }
19
+ /** Cache immutable document snapshots by object identity without retaining discarded snapshots. */
20
+ export declare function createTokenLibraryCache<Preview>(options: TokenLibraryCacheOptions<Preview>): TokenLibraryCache<Preview>;
@@ -0,0 +1,12 @@
1
+ import type { TokenReferenceSpan, TokenValue } from './contracts.js';
2
+ export interface TokenReferenceFormatContext {
3
+ readonly reference: Readonly<TokenReferenceSpan>;
4
+ /** The exact original UTF-16 slice, unaffected by replacements of other spans. */
5
+ readonly original: string;
6
+ }
7
+ export declare class TokenReferenceFormatError extends Error {
8
+ readonly code: 'invalid-range' | 'invalid-replacement';
9
+ constructor(code: TokenReferenceFormatError['code'], message: string);
10
+ }
11
+ /** Validate every span before invoking a syntax-specific replacement callback. */
12
+ export declare function formatTokenReferences(value: Pick<TokenValue, 'text' | 'references'>, replace: (context: TokenReferenceFormatContext) => string): string;
@@ -0,0 +1,7 @@
1
+ import type { EditorDeclarations } from '../editor/declarations.js';
2
+
3
+ export interface WorkspaceConditionsProps {
4
+ declarations: Pick<EditorDeclarations, 'getSessionPresets' | 'getSelectedSessionPreset' | 'selectSessionPreset' | 'subscribeSessionPresets' | 'getPreviewEnvironmentControls' | 'getPreviewEnvironmentControlValue' | 'getPreviewEnvironmentControlSelections' | 'setPreviewEnvironmentControlValue' | 'clearPreviewEnvironmentControlValues' | 'subscribePreviewEnvironmentControls' | 'getPreviewEnvironmentControlRevision'>;
5
+ }
6
+ /** Present declared catalog sessions and preview values without interpreting product policy. */
7
+ export declare function WorkspaceConditions({ declarations }: WorkspaceConditionsProps): import("react").JSX.Element | null;
@@ -1,4 +1,4 @@
1
- import type { WorkspaceConfiguration } from './configuration.js';
1
+ import { type WorkspaceConfiguration } from './configuration.js';
2
2
 
3
3
  export interface WorkspaceShellProps {
4
4
  configuration: WorkspaceConfiguration;
@@ -1,3 +1,5 @@
1
- export declare const StoryboardWorkspace: import("react").FunctionComponent<{
1
+ export interface StoryboardWorkspaceProps {
2
2
  sourceRevision: string;
3
- }>;
3
+ canEditSelected: boolean;
4
+ }
5
+ export declare const StoryboardWorkspace: import("react").FunctionComponent<StoryboardWorkspaceProps>;
@@ -0,0 +1,13 @@
1
+ /** Frame scheduling only. Input timestamps continue to come from the playback clock. */
2
+ export interface PrototypeInputFrame {
3
+ request(callback: () => void): unknown;
4
+ cancel(handle: unknown): void;
5
+ }
6
+ /** Retain one latest value and publish it at most once per requested frame.
7
+ * Flush is for an owned release; cancel discards input on lifecycle changes.
8
+ * Generation checks also reject callbacks delivered after scheduler cancellation. */
9
+ export declare function createPrototypeInputFrame<T>(frame: PrototypeInputFrame, publish: (value: T) => void): {
10
+ push(value: T): void;
11
+ flush: () => void;
12
+ cancel: () => void;
13
+ };
@@ -1,6 +1,7 @@
1
1
  import type { DesignDocument, DocumentNode, ResolvedDocumentNode } from '../../document/contracts.js';
2
2
  import { type PrototypeEffect, type PrototypeEvent, type PrototypeRuntimeContext, type PrototypeStartOptions, type PrototypeState } from '../../document/prototype.js';
3
3
  import { type PrototypeDragFinishInput, type PrototypeDragStartInput } from '../../document/prototypeDrag.js';
4
+ import { type PrototypeInputFrame } from './prototypeInputFrame.js';
4
5
  export interface PrototypeClock {
5
6
  now(): number;
6
7
  schedule(callback: () => void, delayMs: number): unknown;
@@ -21,6 +22,8 @@ export interface PrototypePlayerSnapshot {
21
22
  }
22
23
  export interface PrototypePlayerOptions extends PrototypeStartOptions {
23
24
  clock: PrototypeClock;
25
+ /** Optional presentation batching; raw samples still use this player's clock immediately. */
26
+ inputFrame?: PrototypeInputFrame;
24
27
  /** Effects describe intended links and scrolling; the adapter decides how to execute them. */
25
28
  onEffect?(effect: PrototypeEffect): void;
26
29
  }
@@ -0,0 +1,42 @@
1
+ import type { PageModel } from '../../editor/store.js';
2
+ import type { StoryboardGraph, StoryboardGraphEdge } from '../../editor/storyboardGraph.js';
3
+ import type { WorkspaceCamera } from '../contracts.js';
4
+ export interface StoryboardBounds {
5
+ x: number;
6
+ y: number;
7
+ width: number;
8
+ height: number;
9
+ }
10
+ export interface StoryboardViewport {
11
+ width: number;
12
+ height: number;
13
+ }
14
+ export interface StoryboardArtboard extends StoryboardBounds {
15
+ page: PageModel;
16
+ screenId: string;
17
+ group: string;
18
+ }
19
+ export interface StoryboardConnection {
20
+ edge: StoryboardGraphEdge;
21
+ from: StoryboardArtboard;
22
+ to: StoryboardArtboard;
23
+ path: string;
24
+ labelX: number;
25
+ labelY: number;
26
+ }
27
+ export declare const storyboardFlow: (page: PageModel) => string;
28
+ /** Arrange source-sized screens in flow lanes; never rewrite authored page geometry. */
29
+ export declare function layoutStoryboard(pages: readonly PageModel[]): {
30
+ frames: StoryboardArtboard[];
31
+ bounds: StoryboardBounds;
32
+ };
33
+ export declare function storyboardFrameBounds(frame: StoryboardBounds): StoryboardBounds;
34
+ export declare function fitStoryboard(bounds: StoryboardBounds, viewport: StoryboardViewport): WorkspaceCamera;
35
+ /** Preserve the world point under the pointer when zooming. */
36
+ export declare function zoomStoryboard(camera: WorkspaceCamera, point: {
37
+ x: number;
38
+ y: number;
39
+ }, requested: number): WorkspaceCamera;
40
+ export declare function visibleStoryboardFrames(frames: readonly StoryboardArtboard[], camera: WorkspaceCamera, viewport: StoryboardViewport): StoryboardArtboard[];
41
+ /** A line means an authored transition. Layout proximity never creates an edge. */
42
+ export declare function storyboardConnections(frames: readonly StoryboardArtboard[], graph: StoryboardGraph | null): StoryboardConnection[];
@@ -0,0 +1,26 @@
1
+ import type { EditorRuntime } from '../../core/runtime.js';
2
+ import { type CaptureSupplyDriverDeps } from '../../editor/captureSupply.js';
3
+ import type { RoutePreviewArtifactOutcome } from '../../editor/routePreview.js';
4
+ import type { PageModel } from '../../editor/store.js';
5
+ type Runtime = Pick<EditorRuntime, 'host' | 'previews' | 'declarations'>;
6
+ export interface StoryboardCaptureDemand {
7
+ sourceRevision: string;
8
+ /** Only frames intersecting the canvas viewport, after its catalog filters. */
9
+ pages: readonly PageModel[];
10
+ selected?: PageModel;
11
+ }
12
+ export interface StoryboardCaptureState {
13
+ outcome: RoutePreviewArtifactOutcome | null;
14
+ status: 'missing' | 'generating' | 'ready' | 'stale' | 'failed';
15
+ message?: string;
16
+ retry(): void;
17
+ }
18
+ /** Demand comes from the canvas; transport, deduplication and bounded readiness retries remain shared. */
19
+ export declare function createStoryboardCaptureController(runtime: Runtime, timers?: Pick<CaptureSupplyDriverDeps, 'setTimeout' | 'clearTimeout'>): {
20
+ update: (next: StoryboardCaptureDemand, retryId?: string) => void;
21
+ dispose: () => void;
22
+ subscribe: (listener: () => void) => () => void;
23
+ getSnapshot: () => import("../../editor/captureSupply.js").CaptureSupplyStatus;
24
+ capture(page: PageModel, sourceRevision?: string): StoryboardCaptureState;
25
+ };
26
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { EditorRuntime } from '../../core/runtime.js';
2
+ import type { PageModel } from '../../editor/store.js';
3
+ import { type StoryboardCaptureDemand } from './storyboardCaptures.js';
4
+ /** Canvas visibility is supplied by its layout; repeated renders cannot enqueue another identical plan. */
5
+ export declare function useStoryboardCaptures(runtime: EditorRuntime, demand: StoryboardCaptureDemand): (page: PageModel) => import("./storyboardCaptures.js").StoryboardCaptureState;
@@ -231,6 +231,7 @@ export function createPreviewCaptureWorkerChannel({
231
231
  let degraded = false;
232
232
  let disposed = false;
233
233
  let idleTimer = null;
234
+ let restartWait = null;
234
235
  let requestCounter = 0;
235
236
  const crashTimestamps = [];
236
237
 
@@ -441,14 +442,21 @@ export function createPreviewCaptureWorkerChannel({
441
442
  // The wedged worker was killed and the crash recorded. When that
442
443
  // crash exhausted the restart budget, the caller takes the degraded
443
444
  // path; otherwise fall through to a fresh spawn below.
445
+ if (disposed) throw new Error('Preview capture worker channel is disposed.');
444
446
  if (degraded) return null;
445
447
  }
446
448
  }
447
449
  const backoff = restartBackoffMs();
448
450
  if (backoff > 0) {
449
- await new Promise((resolve) => {
450
- const timer = setTimeout(resolve, backoff);
451
- timer.unref?.();
451
+ await new Promise((resolve, reject) => {
452
+ const pending = { timer: null, reject };
453
+ // There is no child process during backoff. The active capture owns
454
+ // this delay until it completes or dispose cancels the request.
455
+ pending.timer = setTimeout(() => {
456
+ if (restartWait === pending) restartWait = null;
457
+ resolve();
458
+ }, backoff);
459
+ restartWait = pending;
452
460
  });
453
461
  }
454
462
  if (disposed) {
@@ -595,6 +603,12 @@ export function createPreviewCaptureWorkerChannel({
595
603
  if (disposed) return;
596
604
  disposed = true;
597
605
  clearIdleTimer();
606
+ if (restartWait) {
607
+ const pending = restartWait;
608
+ restartWait = null;
609
+ clearTimeout(pending.timer);
610
+ pending.reject(new Error('Preview capture worker channel is disposed.'));
611
+ }
598
612
  await stopWorker();
599
613
  }
600
614
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pygmalionjs/pygmalion",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Code-backed DOM design sandbox and visual QA editor",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {