@pygmalionjs/pygmalion 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-lib/{CameraLayer-BZ8HgrUG.js → CameraLayer-CGW_FPQS.js} +9 -9
- package/dist-lib/pygmalion.js +13156 -11985
- package/dist-lib/{runtime-Bxn8116i.js → runtime-DkCf4iKe.js} +80 -78
- package/dist-lib/style.css +1 -1
- package/dist-lib/testing.js +15 -15
- package/dist-lib/types/lib.d.ts +5 -0
- package/dist-lib/types/token-library/cache.d.ts +20 -0
- package/dist-lib/types/token-library/formatReferences.d.ts +12 -0
- package/dist-lib/types/workspace/WorkspaceConditions.d.ts +7 -0
- package/dist-lib/types/workspace/WorkspaceShell.d.ts +1 -1
- package/dist-lib/types/workspace/edit/AppearancePanel.d.ts +3 -1
- package/dist-lib/types/workspace/edit/EditViewport.d.ts +25 -0
- package/dist-lib/types/workspace/edit/EditorToolbar.d.ts +19 -0
- package/dist-lib/types/workspace/edit/editViewportModel.d.ts +20 -0
- package/dist-lib/types/workspace/edit/editorCanvas.d.ts +27 -0
- package/dist-lib/types/workspace/view/StoryboardWorkspace.d.ts +4 -2
- package/dist-lib/types/workspace/view/prototypeInputFrame.d.ts +13 -0
- package/dist-lib/types/workspace/view/prototypePlayback.d.ts +3 -0
- package/dist-lib/types/workspace/view/storyboardCanvas.d.ts +42 -0
- package/dist-lib/types/workspace/view/storyboardCaptures.d.ts +26 -0
- package/dist-lib/types/workspace/view/useStoryboardCaptures.d.ts +5 -0
- package/node/preview-capture-worker.mjs +17 -3
- package/package.json +1 -1
package/dist-lib/testing.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
const
|
|
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
|
|
12
|
-
const n = [], d = t.origin ?? "",
|
|
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
|
|
16
|
-
const s = `${
|
|
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: (
|
|
31
|
-
mirror:
|
|
32
|
-
session:
|
|
33
|
-
inspect:
|
|
34
|
-
qa:
|
|
35
|
-
preview:
|
|
36
|
-
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
|
-
|
|
45
|
+
v as createMemoryTransport,
|
|
46
46
|
$ as serializeNode
|
|
47
47
|
};
|
package/dist-lib/types/lib.d.ts
CHANGED
|
@@ -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,12 +1,14 @@
|
|
|
1
1
|
import type { DesignDocument, DocumentEngine, DocumentNode } from '../../document/contracts.js';
|
|
2
2
|
import { appearanceToCss } from '../../document/appearance.js';
|
|
3
3
|
|
|
4
|
+
|
|
4
5
|
export interface AppearancePanelProps {
|
|
5
6
|
engine: DocumentEngine;
|
|
6
7
|
nodeId: string;
|
|
7
8
|
disabled?: boolean;
|
|
9
|
+
compact?: boolean;
|
|
8
10
|
}
|
|
9
|
-
export declare function AppearancePanel({ engine, nodeId, disabled }: AppearancePanelProps): import("react").JSX.Element | null;
|
|
11
|
+
export declare function AppearancePanel({ engine, nodeId, disabled, compact }: AppearancePanelProps): import("react").JSX.Element | null;
|
|
10
12
|
/** Separate decorative layers preserve each paint's opacity independently of the content. */
|
|
11
13
|
export declare function AppearanceSurface({ node, document }: {
|
|
12
14
|
node: DocumentNode;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { WorkspaceCamera } from '../contracts.js';
|
|
3
|
+
import { type EditViewportBounds } from './editViewportModel.js';
|
|
4
|
+
|
|
5
|
+
export interface EditViewportHandle {
|
|
6
|
+
fitAll(): void;
|
|
7
|
+
fitSelection(): void;
|
|
8
|
+
actualSize(): void;
|
|
9
|
+
zoomIn(): void;
|
|
10
|
+
zoomOut(): void;
|
|
11
|
+
}
|
|
12
|
+
export interface EditViewportProps {
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
camera: WorkspaceCamera;
|
|
15
|
+
onCameraChange(camera: WorkspaceCamera): void;
|
|
16
|
+
bounds: EditViewportBounds;
|
|
17
|
+
selectionBounds?: EditViewportBounds;
|
|
18
|
+
documentKey: string;
|
|
19
|
+
hand: boolean;
|
|
20
|
+
/** Captured once per document entry; false preserves a restored camera. */
|
|
21
|
+
initialFit?: boolean;
|
|
22
|
+
/** Wait for asynchronously projected geometry before the initial fit. */
|
|
23
|
+
ready?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare const EditViewport: import("react").ForwardRefExoticComponent<EditViewportProps & import("react").RefAttributes<EditViewportHandle>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
export type EditorTool = 'select' | 'hand' | 'frame' | 'text' | 'rectangle' | 'ellipse' | 'line' | 'polygon' | 'star' | 'arc' | 'pen' | 'marquee';
|
|
3
|
+
export interface EditorToolbarProps {
|
|
4
|
+
tool: EditorTool;
|
|
5
|
+
onToolChange(tool: EditorTool): void;
|
|
6
|
+
canUndo: boolean;
|
|
7
|
+
canRedo: boolean;
|
|
8
|
+
onUndo(): void;
|
|
9
|
+
onRedo(): void;
|
|
10
|
+
canGroup: boolean;
|
|
11
|
+
canDuplicate: boolean;
|
|
12
|
+
duplicateDisabledReason?: string;
|
|
13
|
+
onGroup(): void;
|
|
14
|
+
onDuplicate(): void;
|
|
15
|
+
canDelete?: boolean;
|
|
16
|
+
onDelete?(): void;
|
|
17
|
+
}
|
|
18
|
+
/** Tool selection and editor commands only; the canvas owns gestures and document transactions. */
|
|
19
|
+
export declare function EditorToolbar(props: EditorToolbarProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { WorkspaceCamera } from '../contracts.js';
|
|
2
|
+
export interface EditViewportBounds {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
export interface EditViewportSize {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function validEditCamera(camera: WorkspaceCamera): boolean;
|
|
13
|
+
/** A hidden viewport or invalid geometry must never replace a usable camera. */
|
|
14
|
+
export declare function fitEditViewport(bounds: EditViewportBounds, viewport: EditViewportSize): WorkspaceCamera | null;
|
|
15
|
+
/** Preserve the world point under a viewport-local pointer or viewport center. */
|
|
16
|
+
export declare function zoomEditViewport(camera: WorkspaceCamera, anchor: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
}, requestedZoom: number): WorkspaceCamera | null;
|
|
20
|
+
export declare function panEditViewport(camera: WorkspaceCamera, dx: number, dy: number): WorkspaceCamera | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { DataProjection } from '../../binding/preview.js';
|
|
2
|
+
import type { DesignDocument, DocumentNode } from '../../document/contracts.js';
|
|
3
|
+
import { type VectorShape } from '../../document/vector.js';
|
|
4
|
+
export interface CanvasBox {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
}
|
|
10
|
+
export interface CanvasEntry {
|
|
11
|
+
id: string;
|
|
12
|
+
box: CanvasBox;
|
|
13
|
+
topLevel: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type DrawingTool = 'frame' | 'text' | VectorShape;
|
|
16
|
+
export declare function canvasEntries(document: DesignDocument, projection: DataProjection | null, selected?: readonly string[]): CanvasEntry[];
|
|
17
|
+
export declare function canvasBounds(entries: readonly CanvasEntry[]): CanvasBox;
|
|
18
|
+
export declare function marqueeSelection(document: DesignDocument, entries: readonly CanvasEntry[], box: CanvasBox): readonly string[];
|
|
19
|
+
export declare function drawingBox(start: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
}, end: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
}, square?: boolean): CanvasBox;
|
|
26
|
+
/** New free layers are created in page space. Source components retain their owned geometry. */
|
|
27
|
+
export declare function drawnNode(tool: DrawingTool, id: string, box: CanvasBox, reverseLine?: boolean): DocumentNode;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export
|
|
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
|
|
451
|
-
|
|
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
|
|