@pygmalionjs/pygmalion 0.15.0 → 0.16.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.
@@ -18944,6 +18944,7 @@ function e_(t, e) {
18944
18944
  data: n.data,
18945
18945
  source: n.source,
18946
18946
  duplicateMetadata: n.duplicateMetadata,
18947
+ textFontPreparation: n.textFontPreparation,
18947
18948
  loadDocument: n.loadDocument,
18948
18949
  saveDocument: n.saveDocument,
18949
18950
  renderComponent: n.renderComponent,
@@ -18951,7 +18952,7 @@ function e_(t, e) {
18951
18952
  });
18952
18953
  }
18953
18954
  function ro(t, e) {
18954
- return t === e || !!(t && e && t.data === e.data && t.source === e.source && t.duplicateMetadata === e.duplicateMetadata && t.loadDocument === e.loadDocument && t.saveDocument === e.saveDocument && t.renderComponent === e.renderComponent && t.onRequestData === e.onRequestData);
18955
+ return t === e || !!(t && e && t.data === e.data && t.source === e.source && t.duplicateMetadata === e.duplicateMetadata && t.textFontPreparation === e.textFontPreparation && t.loadDocument === e.loadDocument && t.saveDocument === e.saveDocument && t.renderComponent === e.renderComponent && t.onRequestData === e.onRequestData);
18955
18956
  }
18956
18957
  function pi(t) {
18957
18958
  return Object.values(t.nodes).map((e) => {
@@ -20747,7 +20748,7 @@ function z_(t) {
20747
20748
  stamped: u ? i.isStampedFrozenPreview(u.root) : null
20748
20749
  },
20749
20750
  lodState: a.__debugFrameLodState(),
20750
- readFramesNow: (await import("./CameraLayer-CWrlA9D-.js")).__debugReadEditorFrames(t).find((h) => h.id === n)
20751
+ readFramesNow: (await import("./CameraLayer-BNw26sgR.js")).__debugReadEditorFrames(t).find((h) => h.id === n)
20751
20752
  };
20752
20753
  },
20753
20754
  /** Flow-session delivery states for headless diagnosis of the captureless supply. */
@@ -1,5 +1,5 @@
1
- import { b$ as l, T as u } from "./runtime-7no5RTHJ.js";
2
- import { bo as y, ch as b, ci as E, cj as P, bk as $, aw as T } from "./runtime-7no5RTHJ.js";
1
+ import { b$ as l, T as u } from "./runtime-Bo5tncK_.js";
2
+ import { bo as y, ch as b, ci as E, cj as P, bk as $, aw as T } from "./runtime-Bo5tncK_.js";
3
3
  const v = {
4
4
  mirror: ["status", "refresh", "refs"],
5
5
  session: ["open", "check", "previewVisual", "applyVisual", "revertVisual"],
@@ -183,3 +183,13 @@ export declare function fontFaceSetLoader(fonts: {
183
183
  } | undefined | null): TextFontLoader | null;
184
184
  /** A convenience for text nodes: the node's own font needs. */
185
185
  export declare function textNodeFontRequirements(node: DocumentNode): TextFontRequirement[];
186
+ /** An exact preparation request. A missing family remains unresolved; no default is guessed. */
187
+ export interface TextFontFaceRequest {
188
+ readonly family: string | null;
189
+ readonly weight: number;
190
+ readonly style: 'normal' | 'italic';
191
+ /** Written sample in UTF-16. Rendered case or connected substitutions require explicit resolution. */
192
+ readonly sample: string;
193
+ }
194
+ /** Preserves family expressions and sample bytes, keeping weight/style/sample combinations distinct. */
195
+ export declare function textFontFaceRequests(model: RichText, base?: TextNodeCharacterStyle): readonly TextFontFaceRequest[];
@@ -0,0 +1,36 @@
1
+ import type { TextFontFaceRequest } from './richText.js';
2
+ export type TextFontFaceResult = {
3
+ readonly status: 'ready';
4
+ readonly faceId: string;
5
+ readonly family: string;
6
+ readonly weight: number;
7
+ readonly style: 'normal' | 'italic';
8
+ readonly sample: string;
9
+ } | {
10
+ readonly status: 'unavailable';
11
+ readonly code: string;
12
+ readonly message: string;
13
+ } | {
14
+ readonly status: 'failed';
15
+ readonly code: string;
16
+ readonly message: string;
17
+ };
18
+ /** The provider explicitly attests to the exact face and sample coverage in this environment. */
19
+ export interface TextFontFaceResolver {
20
+ readonly environmentId: string;
21
+ resolve(request: TextFontFaceRequest, context: {
22
+ readonly signal: AbortSignal;
23
+ }): Promise<TextFontFaceResult>;
24
+ }
25
+ export interface PreparedTextFont {
26
+ readonly request: TextFontFaceRequest;
27
+ readonly result: TextFontFaceResult;
28
+ }
29
+ export interface TextFontPreparationReport {
30
+ readonly environmentId: string;
31
+ readonly status: 'ready' | 'unavailable' | 'failed';
32
+ readonly fonts: readonly PreparedTextFont[];
33
+ }
34
+ export declare function textFontRequestKey(request: TextFontFaceRequest): string;
35
+ /** Invalid provider attestations fail closed; a fallback or a different sample is not a ready face. */
36
+ export declare function validateTextFontFaceResult(request: TextFontFaceRequest, result: TextFontFaceResult): TextFontFaceResult;
@@ -55,8 +55,15 @@ export { planScopeTransfer, resolveScopeTransfer, applyScopeTransfer } from './w
55
55
  export type { ScopeTransferPlan, ScopeTransferDecisionPlan, ScopeTransferItem, ScopeTransferChoice, ScopeTransferDecision, ScopeTransferOptions, ResolvedScopeTransfer } from './workspace/edit/scopeTransfer.js';
56
56
  export { planDocumentLayerMove, applyDocumentLayerMove, normalizeDocumentLayerSelection } from './workspace/edit/layerMoves.js';
57
57
  export type { DocumentLayerMoveRequest, DocumentLayerMovePlan, DocumentLayerMoveOperation, ReadyDocumentLayerMove } from './workspace/edit/layerMoves.js';
58
- export { TEXT_CHARACTER_KEYS, TEXT_PARAGRAPH_KEYS, TEXT_RESIZE_MODES, RICH_TEXT_CASES, RICH_TEXT_LISTS, RICH_TEXT_ALIGNMENTS, TEXT_PARAGRAPH_PROPERTY, TEXT_NODE_PROPERTY_KEYS, isTextLink, isTextResizeMode, isRichTextCharacterValue, isRichTextParagraphValue, isRichTextCharacterStyle, isRichTextParagraphStyle, isRichTextRun, isRichTextParagraph, isRichText, richTextPlain, richTextLength, richTextFromPlain, normalizeRichText, applyRichTextCharacterStyle, clearRichTextCharacterStyle, setRichTextParagraphStyle, clearRichTextParagraphStyle, richTextInheritedStyle, insertRichText, deleteRichText, replaceRichText, splitRichTextParagraph, mergeRichTextParagraphs, applyPlainTextEdit, richTextCharacterStyleAt, richTextParagraphStyleAt, richTextVaryingKeys, textNodeStyle, textResizeMode, textNodePlain, textNodeModel, isRichTextTrivial, hoistRichTextStyle, richTextValue, normalizeTextProperties, plainTextProperties, textFontRequirements, documentFontRequirements, textNodeFontRequirements, loadTextFonts, loadDocumentFonts, fontFaceSetLoader, } from './document/richText.js';
58
+ export { TEXT_CHARACTER_KEYS, TEXT_PARAGRAPH_KEYS, TEXT_RESIZE_MODES, RICH_TEXT_CASES, RICH_TEXT_LISTS, RICH_TEXT_ALIGNMENTS, TEXT_PARAGRAPH_PROPERTY, TEXT_NODE_PROPERTY_KEYS, isTextLink, isTextResizeMode, isRichTextCharacterValue, isRichTextParagraphValue, isRichTextCharacterStyle, isRichTextParagraphStyle, isRichTextRun, isRichTextParagraph, isRichText, richTextPlain, richTextLength, richTextFromPlain, normalizeRichText, applyRichTextCharacterStyle, clearRichTextCharacterStyle, setRichTextParagraphStyle, clearRichTextParagraphStyle, richTextInheritedStyle, insertRichText, deleteRichText, replaceRichText, splitRichTextParagraph, mergeRichTextParagraphs, applyPlainTextEdit, richTextCharacterStyleAt, richTextParagraphStyleAt, richTextVaryingKeys, textNodeStyle, textResizeMode, textNodePlain, textNodeModel, isRichTextTrivial, hoistRichTextStyle, richTextValue, normalizeTextProperties, plainTextProperties, textFontRequirements, documentFontRequirements, textNodeFontRequirements, loadTextFonts, loadDocumentFonts, fontFaceSetLoader, textFontFaceRequests, } from './document/richText.js';
59
59
  export type * from './document/richText.js';
60
+ export * from './document/textFontPreparation.js';
61
+ export { createTextFontPreparationRuntime } from './workspace/edit/textFontRuntime.js';
62
+ export type { TextFontPreparationRuntime } from './workspace/edit/textFontRuntime.js';
63
+ export { collectTextFontOccurrences, textFontAddressKey } from './workspace/edit/textFontOccurrences.js';
64
+ export type { TextFontAddress, TextFontOccurrence, TextFontCollection, TextFontCollectionOptions } from './workspace/edit/textFontOccurrences.js';
65
+ export { useTextFontPreparation } from './workspace/edit/useTextFontPreparation.js';
66
+ export type { TextFontPreparationState } from './workspace/edit/useTextFontPreparation.js';
60
67
  export { VECTOR_SHAPES, VECTOR_BOOLEAN_OPERATIONS, VECTOR_FLATNESS, VECTOR_MERGE_DISTANCE, VECTOR_SIDE_SAMPLE, isVectorProperties, parseVector, serializeVector, vectorPathAnchors, vectorPathFromAnchors, vectorPathSegments, vectorBounds, transformVector, translateVector, vectorFitTransform, normalizeVectorOrigin, fitVectorNode, rectangleVector, ellipseVector, arcVector, lineVector, polygonVector, starVector, createShapeVector, roundVectorCorners, vectorPathData, vectorAnchorMode, moveVectorAnchor, moveVectorHandle, setVectorAnchorMode, insertVectorAnchor, deleteVectorAnchor, canSplitVectorPath, splitVectorPath, canJoinVectorPaths, joinVectorPaths, nearestVectorSegmentPoint, flattenVector, vectorContainsPoint, vectorArea, booleanRings, booleanVectors, booleanVectorPrecision, vectorRenderTransform, } from './document/vector.js';
61
68
  export type * from './document/vector.js';
62
69
  export { VectorEditor, VectorInspector, VectorNodeSurface, useVectorEditing } from './workspace/edit/VectorEditor.js';
@@ -4,11 +4,14 @@ import type { DesignDocument, DocumentNode, DocumentDuplicateMetadataRemapper }
4
4
  import type { WorkspaceSourceCapabilities } from './source/flowContracts.js';
5
5
  import type { WorkspaceTarget } from './contracts.js';
6
6
  import type { WorkspaceTokenLibraryCapabilities } from './tokens/contracts.js';
7
+ import type { TextFontPreparationRuntime } from './edit/textFontRuntime.js';
7
8
  /** One target's source, data, rendering, and persistence capabilities travel together. */
8
9
  export interface WorkspaceTargetConfiguration {
9
10
  data?: HostDataCapabilities;
10
11
  source?: WorkspaceSourceCapabilities;
11
12
  duplicateMetadata?: DocumentDuplicateMetadataRemapper;
13
+ /** Explicit font face and sample preparation; browser fallback rendering is not exact readiness. */
14
+ textFontPreparation?: TextFontPreparationRuntime;
12
15
  loadDocument?(target: WorkspaceTarget, options: {
13
16
  signal: AbortSignal;
14
17
  }): Promise<DesignDocument>;
@@ -1,5 +1,7 @@
1
1
  import type { DesignDocument, DocumentNode, DocumentTransaction } from '../../document/contracts.js';
2
2
  import { type TextFontLoader, type TextFontLoadReport } from '../../document/richText.js';
3
+ import type { TextFontPreparationRuntime } from './textFontRuntime.js';
4
+ import type { TextFontCollection } from './textFontOccurrences.js';
3
5
 
4
6
  type Act = (label: string, apply: (transaction: DocumentTransaction) => void) => boolean;
5
7
  /**
@@ -40,11 +42,15 @@ export interface TextEditorProps {
40
42
  connected?: boolean;
41
43
  /** Resolves required faces; the browser font set when omitted, no loading when null. */
42
44
  fontLoader?: TextFontLoader | null;
45
+ /** Optional exact face preparation; legacy loading stays separate. */
46
+ fontPreparation?: TextFontPreparationRuntime | null;
47
+ /** The selected resolved occurrence, including projected sample and overrides when relevant. */
48
+ fontCollection?: TextFontCollection;
43
49
  }
44
50
  /**
45
51
  * Inspector section for a text node. The written text is edited in a textarea whose selection decides
46
52
  * whether a style applies to a character range or to the whole layer. Every committed edit is one
47
53
  * document transaction; Escape discards the uncommitted draft.
48
54
  */
49
- export declare function TextEditor({ document, node, act, connected, fontLoader }: TextEditorProps): import("react").JSX.Element;
55
+ export declare function TextEditor({ document, node, act, connected, fontLoader, fontPreparation, fontCollection }: TextEditorProps): import("react").JSX.Element;
50
56
  export {};
@@ -0,0 +1,34 @@
1
+ import type { DesignDocument, DocumentResolveOptions } from '../../document/contracts.js';
2
+ import type { DataProjection } from '../../binding/preview.js';
3
+ import { type TextFontFaceRequest } from '../../document/richText.js';
4
+ import { type ProjectedDocumentNode } from './projection.js';
5
+ export interface TextFontAddress {
6
+ readonly sourceNodeId: string;
7
+ readonly instancePath: readonly string[];
8
+ readonly rowPath: ProjectedDocumentNode['rowPath'];
9
+ }
10
+ export interface TextFontOccurrence extends TextFontAddress {
11
+ readonly origin: 'authored' | 'source' | 'bound';
12
+ readonly requests: readonly TextFontFaceRequest[];
13
+ }
14
+ export interface TextFontCollection {
15
+ readonly occurrences: readonly TextFontOccurrence[];
16
+ readonly diagnostics: readonly {
17
+ readonly code: string;
18
+ readonly message: string;
19
+ readonly address?: TextFontAddress;
20
+ }[];
21
+ }
22
+ export interface TextFontCollectionOptions {
23
+ readonly projection?: DataProjection | null;
24
+ readonly resolveOptions?: DocumentResolveOptions;
25
+ /** Supply the same resolved scene the canvas uses, when it has custom resolution. */
26
+ readonly scene?: ProjectedDocumentNode;
27
+ readonly visibleRootIds?: readonly string[];
28
+ readonly subtree?: TextFontAddress;
29
+ /** Required for connected/source content or case-transformed samples. It must describe rendered text. */
30
+ readonly resolveText?: (item: ProjectedDocumentNode, address: TextFontAddress) => string | undefined;
31
+ }
32
+ export declare const textFontAddressKey: (address: TextFontAddress) => string;
33
+ /** Read-only effective occurrences; hidden pages/rows and unselected shared definitions do not preload. */
34
+ export declare function collectTextFontOccurrences(document: DesignDocument, options?: TextFontCollectionOptions): TextFontCollection;
@@ -0,0 +1,15 @@
1
+ import { type TextFontFaceResolver, type TextFontPreparationReport } from '../../document/textFontPreparation.js';
2
+ import type { TextFontFaceRequest } from '../../document/richText.js';
3
+ export interface TextFontPreparationRuntime {
4
+ readonly environmentId: string;
5
+ prepare(requests: readonly TextFontFaceRequest[], options?: {
6
+ signal?: AbortSignal;
7
+ retry?: boolean;
8
+ }): Promise<TextFontPreparationReport>;
9
+ clear(): void;
10
+ dispose(): void;
11
+ }
12
+ /** A bounded successful-result cache with shared in-flight work and independently cancellable readers. */
13
+ export declare function createTextFontPreparationRuntime(resolver: TextFontFaceResolver, options?: {
14
+ maxEntries?: number;
15
+ }): TextFontPreparationRuntime;
@@ -0,0 +1,12 @@
1
+ import type { DesignDocument, DocumentNode } from '../../document/contracts.js';
2
+ import type { TextFontPreparationReport } from '../../document/textFontPreparation.js';
3
+ import { type TextFontCollection } from './textFontOccurrences.js';
4
+ import type { TextFontPreparationRuntime } from './textFontRuntime.js';
5
+ export interface TextFontPreparationState {
6
+ readonly status: 'idle' | 'loading' | 'ready' | 'unavailable' | 'failed';
7
+ readonly messages: readonly string[];
8
+ readonly report?: TextFontPreparationReport;
9
+ retry(): void;
10
+ }
11
+ /** Exact readiness is opt-in; legacy font-set loading never becomes an identity attestation. */
12
+ export declare function useTextFontPreparation(document: DesignDocument, node: DocumentNode, runtime?: TextFontPreparationRuntime | null, supplied?: TextFontCollection): TextFontPreparationState;
@@ -30,8 +30,18 @@ export interface PrototypeInterruptedTiming {
30
30
  }
31
31
  /** One shared timing table per interrupted transition, never one solver per layer/channel. */
32
32
  export declare function createPrototypeInterruptedTiming(transition: PrototypeTransition, durationMs: number): PrototypeInterruptedTiming;
33
- /** Existing computed 2D/px/RGB tracks only. Unsupported values retain explicit diagnostics. */
34
- export declare function createPrototypeInterruptedFrames(captured: PrototypeMotionCapture, target: Partial<PrototypeMotionStyles>, timing: PrototypeInterruptedTiming): {
33
+ interface PrototypeInterruptedFrames {
35
34
  frames: Keyframe[];
36
35
  unsupported: PrototypeMotionProperty[];
37
- };
36
+ }
37
+ interface PrototypeInterruptedFramePlannerOptions {
38
+ maxTracks?: number;
39
+ maxBytes?: number;
40
+ }
41
+ /** A single preparation pass owns this cache; it retains no DOM, captures or animation records.
42
+ * Limits bound cached track count and UTF-16 string payload bytes, not total JavaScript heap size.
43
+ * Returned frames are detached even when their immutable property strings are reused. */
44
+ export declare function createPrototypeInterruptedFramePlanner(inputTiming: PrototypeInterruptedTiming, options?: PrototypeInterruptedFramePlannerOptions): (captured: PrototypeMotionCapture, target: Partial<PrototypeMotionStyles>) => PrototypeInterruptedFrames;
45
+ /** Existing computed 2D/px/RGB tracks only. Unsupported values retain explicit diagnostics. */
46
+ export declare function createPrototypeInterruptedFrames(captured: PrototypeMotionCapture, target: Partial<PrototypeMotionStyles>, timing: PrototypeInterruptedTiming): PrototypeInterruptedFrames;
47
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pygmalionjs/pygmalion",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "Code-backed DOM design sandbox and visual QA editor",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {