visualfries 0.1.10120 → 0.3.2

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 (133) hide show
  1. package/README.md +97 -0
  2. package/bin/visualfries.js +1570 -0
  3. package/dist/DIContainer.d.ts +2 -1
  4. package/dist/DIContainer.js +16 -5
  5. package/dist/SceneBuilder.svelte.d.ts +70 -1
  6. package/dist/SceneBuilder.svelte.js +96 -29
  7. package/dist/agent/audioMixer.d.ts +34 -0
  8. package/dist/agent/audioMixer.js +308 -0
  9. package/dist/agent/broll.d.ts +35 -0
  10. package/dist/agent/broll.js +226 -0
  11. package/dist/agent/capabilities.d.ts +34 -0
  12. package/dist/agent/capabilities.js +246 -0
  13. package/dist/agent/captionScene.d.ts +23 -0
  14. package/dist/agent/captionScene.js +204 -0
  15. package/dist/agent/catalog.d.ts +24 -0
  16. package/dist/agent/catalog.js +67 -0
  17. package/dist/agent/cueFiles.d.ts +54 -0
  18. package/dist/agent/cueFiles.js +219 -0
  19. package/dist/agent/cuePresets.d.ts +7 -0
  20. package/dist/agent/cuePresets.js +50 -0
  21. package/dist/agent/deterministicMedia.d.ts +61 -0
  22. package/dist/agent/deterministicMedia.js +303 -0
  23. package/dist/agent/index.d.ts +18 -0
  24. package/dist/agent/index.js +18 -0
  25. package/dist/agent/inspectScene.d.ts +36 -0
  26. package/dist/agent/inspectScene.js +139 -0
  27. package/dist/agent/localRender.d.ts +82 -0
  28. package/dist/agent/localRender.js +702 -0
  29. package/dist/agent/overlays.d.ts +40 -0
  30. package/dist/agent/overlays.js +325 -0
  31. package/dist/agent/productionPlan.d.ts +131 -0
  32. package/dist/agent/productionPlan.js +322 -0
  33. package/dist/agent/renderPlan.d.ts +27 -0
  34. package/dist/agent/renderPlan.js +68 -0
  35. package/dist/agent/renderRanges.d.ts +24 -0
  36. package/dist/agent/renderRanges.js +73 -0
  37. package/dist/agent/runtimeSupport.d.ts +19 -0
  38. package/dist/agent/runtimeSupport.js +192 -0
  39. package/dist/agent/streamingEncoder.d.ts +31 -0
  40. package/dist/agent/streamingEncoder.js +208 -0
  41. package/dist/agent/transcripts.d.ts +29 -0
  42. package/dist/agent/transcripts.js +146 -0
  43. package/dist/agent/transitions.d.ts +20 -0
  44. package/dist/agent/transitions.js +169 -0
  45. package/dist/animations/PixiAnimationTarget.d.ts +29 -0
  46. package/dist/animations/PixiAnimationTarget.js +63 -0
  47. package/dist/animations/builders/LineHighlighterAnimationBuilder.js +20 -3
  48. package/dist/animations/builders/WordHighlighterAnimationBuilder.js +15 -2
  49. package/dist/browser/browserExport.d.ts +73 -0
  50. package/dist/browser/browserExport.js +180 -0
  51. package/dist/browser/glTransitions.d.ts +37 -0
  52. package/dist/browser/glTransitions.js +261 -0
  53. package/dist/browser/index.d.ts +3 -0
  54. package/dist/browser/index.js +3 -0
  55. package/dist/browser/mediaDecode.d.ts +31 -0
  56. package/dist/browser/mediaDecode.js +152 -0
  57. package/dist/builders/PixiComponentBuilder.d.ts +6 -0
  58. package/dist/builders/PixiComponentBuilder.js +12 -0
  59. package/dist/builders/_ComponentState.svelte.d.ts +7 -5
  60. package/dist/builders/_ComponentState.svelte.js +29 -15
  61. package/dist/builders/html/StyleBuilder.js +9 -8
  62. package/dist/builders/html/TextComponentHtmlBuilder.js +4 -2
  63. package/dist/builders/html/processors/AppearanceStyleProcessor.js +1 -1
  64. package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +7 -0
  65. package/dist/builders/html/processors/TextEffectsStyleProcessor.js +32 -13
  66. package/dist/commands/ReplaceSourceOnTimeCommand.js +9 -1
  67. package/dist/commands/SeekCommand.js +19 -6
  68. package/dist/components/AnimatedGIF.d.ts +3 -0
  69. package/dist/components/AnimatedGIF.js +28 -1
  70. package/dist/components/Component.svelte.d.ts +5 -5
  71. package/dist/components/Component.svelte.js +29 -13
  72. package/dist/components/ComponentContext.svelte.js +68 -23
  73. package/dist/components/hooks/AnimationHook.js +1 -1
  74. package/dist/components/hooks/CanvasFillHook.d.ts +12 -0
  75. package/dist/components/hooks/CanvasFillHook.js +75 -0
  76. package/dist/components/hooks/DeterministicMediaFrameHook.js +3 -0
  77. package/dist/components/hooks/HtmlTextHook.js +11 -3
  78. package/dist/components/hooks/HtmlToCanvasHook.js +8 -25
  79. package/dist/components/hooks/MediaHook.js +172 -47
  80. package/dist/components/hooks/MediaSeekingHook.js +138 -88
  81. package/dist/components/hooks/PixiGifHook.js +4 -4
  82. package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +73 -6
  83. package/dist/components/hooks/PixiVideoTextureHook.js +10 -4
  84. package/dist/components/hooks/PixiVisualTransformHook.d.ts +16 -0
  85. package/dist/components/hooks/PixiVisualTransformHook.js +102 -0
  86. package/dist/components/hooks/SubtitlesHook.js +48 -24
  87. package/dist/components/hooks/VerifyMediaHook.js +2 -2
  88. package/dist/directors/ComponentDirector.d.ts +1 -0
  89. package/dist/directors/ComponentDirector.js +41 -8
  90. package/dist/fonts/fontDiscovery.js +12 -1
  91. package/dist/layers/Layer.svelte.d.ts +54 -0
  92. package/dist/layers/Layer.svelte.js +2 -25
  93. package/dist/managers/AppManager.svelte.js +8 -5
  94. package/dist/managers/ComponentsManager.svelte.d.ts +7 -7
  95. package/dist/managers/ComponentsManager.svelte.js +29 -15
  96. package/dist/managers/DeterministicMediaManager.js +38 -3
  97. package/dist/managers/EventManager.js +3 -1
  98. package/dist/managers/LayersManager.svelte.d.ts +54 -0
  99. package/dist/managers/RenderManager.d.ts +5 -0
  100. package/dist/managers/RenderManager.js +67 -21
  101. package/dist/managers/StateManager.svelte.d.ts +56 -0
  102. package/dist/managers/StateManager.svelte.js +60 -58
  103. package/dist/managers/SubtitlesManager.svelte.js +1 -3
  104. package/dist/managers/TimeManager.svelte.d.ts +4 -0
  105. package/dist/managers/TimeManager.svelte.js +23 -7
  106. package/dist/schemas/runtime/deterministic.js +5 -1
  107. package/dist/schemas/runtime/types.d.ts +36 -15
  108. package/dist/schemas/scene/components.d.ts +126 -0
  109. package/dist/schemas/scene/components.js +11 -0
  110. package/dist/schemas/scene/core.d.ts +109 -10
  111. package/dist/schemas/scene/core.js +1 -1
  112. package/dist/utils/mediaWindow.d.ts +13 -0
  113. package/dist/utils/mediaWindow.js +25 -0
  114. package/dist/utils/svgGenerator.js +1 -1
  115. package/dist/utils/timelineWindow.d.ts +2 -0
  116. package/dist/utils/timelineWindow.js +7 -0
  117. package/dist/utils/utils.js +2 -4
  118. package/docs/AGENT_PATTERNS.md +243 -0
  119. package/docs/AGENT_WORKFLOW.md +364 -0
  120. package/docs/AUTHORING_BEST_PRACTICES.md +188 -0
  121. package/docs/AUTHORING_SYSTEM_AUDIT.md +98 -0
  122. package/docs/BROWSER_EXPORT_SPIKE.md +55 -0
  123. package/docs/DETERMINISTIC_RENDERER.md +83 -0
  124. package/docs/NEXT_RELEASE.md +28 -0
  125. package/docs/PROPOSED_VISUALFRIES_SKILL.md +68 -0
  126. package/docs/examples/agent-cues.json +49 -0
  127. package/docs/examples/agent-transcript.json +23 -0
  128. package/docs/examples/agent-transcript.srt +7 -0
  129. package/docs/examples/agent-transcript.vtt +7 -0
  130. package/docs/examples/image-animation.json +87 -0
  131. package/docs/examples/native-text-metric-badge.json +109 -0
  132. package/package.json +133 -100
  133. package/skills/visualfries/SKILL.md +328 -0
@@ -1,4 +1,5 @@
1
1
  import { type AwilixContainer } from 'awilix/browser';
2
2
  import type { Scene as SceneData } from './';
3
3
  export declare const registerNewContainer: (data: SceneData, instances: [string, unknown][]) => AwilixContainer;
4
- export declare const removeContainer: (sceneId: string) => void;
4
+ export declare const evictContainer: (sceneId: string) => AwilixContainer | undefined;
5
+ export declare const removeContainer: (sceneId: string, expectedContainer?: AwilixContainer) => Promise<void>;
@@ -42,6 +42,8 @@ import { LayersManager } from './managers/LayersManager.svelte.js';
42
42
  import { MediaSeekingHook } from './components/hooks/MediaSeekingHook.js';
43
43
  import { VerifyGifHook } from './components/hooks/VerifyGifHook.js';
44
44
  import { DeterministicMediaFrameHook } from './components/hooks/DeterministicMediaFrameHook.js';
45
+ import { PixiVisualTransformHook } from './components/hooks/PixiVisualTransformHook.js';
46
+ import { CanvasFillHook } from './components/hooks/CanvasFillHook.js';
45
47
  import { ComponentAnimationTransformer } from './animations/transformers/AnimationReferenceTransformer.js';
46
48
  import { AnimationPresetsRegister } from './animations/AnimationPresetsRegister.js';
47
49
  import { SplitTextCache } from './animations/SplitTextCache.js';
@@ -95,6 +97,8 @@ export const registerNewContainer = function (data, instances) {
95
97
  deterministicMediaFrameHook: asClass(DeterministicMediaFrameHook, {
96
98
  lifetime: Lifetime.TRANSIENT
97
99
  }),
100
+ pixiVisualTransformHook: asClass(PixiVisualTransformHook, { lifetime: Lifetime.TRANSIENT }),
101
+ canvasFillHook: asClass(CanvasFillHook, { lifetime: Lifetime.TRANSIENT }),
98
102
  videoTextureHook: asClass(PixiVideoTextureHook, { lifetime: Lifetime.TRANSIENT }),
99
103
  splitScreenHook: asClass(PixiSplitScreenDisplayObjectHook, { lifetime: Lifetime.TRANSIENT }),
100
104
  htmlTextHook: asClass(HtmlTextHook, { lifetime: Lifetime.TRANSIENT }),
@@ -144,10 +148,17 @@ export const registerNewContainer = function (data, instances) {
144
148
  containers.set(data.id, childContainer);
145
149
  return childContainer;
146
150
  };
147
- export const removeContainer = function (sceneId) {
148
- if (containers.has(sceneId)) {
149
- const container = containers.get(sceneId);
150
- container.dispose();
151
+ export const evictContainer = function (sceneId) {
152
+ const container = containers.get(sceneId);
153
+ if (container)
151
154
  containers.delete(sceneId);
152
- }
155
+ return container;
156
+ };
157
+ export const removeContainer = async function (sceneId, expectedContainer) {
158
+ const current = containers.get(sceneId);
159
+ if (expectedContainer && current !== expectedContainer)
160
+ return;
161
+ const container = evictContainer(sceneId);
162
+ if (container)
163
+ await container.dispose();
153
164
  };
@@ -64,6 +64,21 @@ export declare class SceneBuilder implements ISceneBuilder {
64
64
  start: number;
65
65
  end: number;
66
66
  }[];
67
+ explainComponentState(componentId: string): {
68
+ componentId: string;
69
+ type: "VIDEO" | "GIF" | "IMAGE" | "TEXT" | "SHAPE" | "AUDIO" | "COLOR" | "GRADIENT" | "SUBTITLES";
70
+ time: number;
71
+ active: boolean;
72
+ relativeTime: number;
73
+ targetKind: "none" | "html" | "pixi";
74
+ targetOwner: "wrapper" | "element" | "none" | "pixi";
75
+ computed: Record<string, string | number>;
76
+ animations: {
77
+ id: string;
78
+ enabled: boolean;
79
+ startAt: number;
80
+ }[];
81
+ } | null;
67
82
  addExcludedTimestamp(start: number, end: number): void;
68
83
  removeExcludedTimestampsBetween(start: number, end: number): void;
69
84
  syncChanges(): void;
@@ -538,6 +553,12 @@ export declare class SceneBuilder implements ISceneBuilder {
538
553
  unit: "px" | "em" | "rem" | "%";
539
554
  } | null | undefined;
540
555
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
556
+ padding?: number | {
557
+ top: number;
558
+ right: number;
559
+ bottom: number;
560
+ left: number;
561
+ } | undefined;
541
562
  shadow?: {
542
563
  enabled?: boolean | undefined;
543
564
  preset?: string | undefined;
@@ -1157,6 +1178,12 @@ export declare class SceneBuilder implements ISceneBuilder {
1157
1178
  unit: "px" | "em" | "rem" | "%";
1158
1179
  } | null | undefined;
1159
1180
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
1181
+ padding?: number | {
1182
+ top: number;
1183
+ right: number;
1184
+ bottom: number;
1185
+ left: number;
1186
+ } | undefined;
1160
1187
  shadow?: {
1161
1188
  enabled?: boolean | undefined;
1162
1189
  preset?: string | undefined;
@@ -1750,6 +1777,12 @@ export declare class SceneBuilder implements ISceneBuilder {
1750
1777
  unit: "px" | "em" | "rem" | "%";
1751
1778
  } | null | undefined;
1752
1779
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
1780
+ padding?: number | {
1781
+ top: number;
1782
+ right: number;
1783
+ bottom: number;
1784
+ left: number;
1785
+ } | undefined;
1753
1786
  shadow?: {
1754
1787
  enabled?: boolean | undefined;
1755
1788
  preset?: string | undefined;
@@ -2341,6 +2374,12 @@ export declare class SceneBuilder implements ISceneBuilder {
2341
2374
  unit: "px" | "em" | "rem" | "%";
2342
2375
  } | null | undefined;
2343
2376
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
2377
+ padding?: number | {
2378
+ top: number;
2379
+ right: number;
2380
+ bottom: number;
2381
+ left: number;
2382
+ } | undefined;
2344
2383
  shadow?: {
2345
2384
  enabled?: boolean | undefined;
2346
2385
  preset?: string | undefined;
@@ -2966,6 +3005,12 @@ export declare class SceneBuilder implements ISceneBuilder {
2966
3005
  unit: "px" | "em" | "rem" | "%";
2967
3006
  } | null | undefined;
2968
3007
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
3008
+ padding?: number | {
3009
+ top: number;
3010
+ right: number;
3011
+ bottom: number;
3012
+ left: number;
3013
+ } | undefined;
2969
3014
  shadow?: {
2970
3015
  enabled?: boolean | undefined;
2971
3016
  preset?: string | undefined;
@@ -3561,6 +3606,12 @@ export declare class SceneBuilder implements ISceneBuilder {
3561
3606
  unit: "px" | "em" | "rem" | "%";
3562
3607
  } | null | undefined;
3563
3608
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
3609
+ padding?: number | {
3610
+ top: number;
3611
+ right: number;
3612
+ bottom: number;
3613
+ left: number;
3614
+ } | undefined;
3564
3615
  shadow?: {
3565
3616
  enabled?: boolean | undefined;
3566
3617
  preset?: string | undefined;
@@ -4107,6 +4158,12 @@ export declare class SceneBuilder implements ISceneBuilder {
4107
4158
  unit: "px" | "em" | "rem" | "%";
4108
4159
  } | null | undefined;
4109
4160
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
4161
+ padding?: number | {
4162
+ top: number;
4163
+ right: number;
4164
+ bottom: number;
4165
+ left: number;
4166
+ } | undefined;
4110
4167
  shadow?: {
4111
4168
  enabled?: boolean | undefined;
4112
4169
  preset?: string | undefined;
@@ -4658,6 +4715,12 @@ export declare class SceneBuilder implements ISceneBuilder {
4658
4715
  unit: "px" | "em" | "rem" | "%";
4659
4716
  } | null | undefined;
4660
4717
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
4718
+ padding?: number | {
4719
+ top: number;
4720
+ right: number;
4721
+ bottom: number;
4722
+ left: number;
4723
+ } | undefined;
4661
4724
  shadow?: {
4662
4725
  enabled?: boolean | undefined;
4663
4726
  preset?: string | undefined;
@@ -5202,6 +5265,12 @@ export declare class SceneBuilder implements ISceneBuilder {
5202
5265
  unit: "px" | "em" | "rem" | "%";
5203
5266
  } | null | undefined;
5204
5267
  textTransform?: "none" | "uppercase" | "lowercase" | "capitalize" | undefined;
5268
+ padding?: number | {
5269
+ top: number;
5270
+ right: number;
5271
+ bottom: number;
5272
+ left: number;
5273
+ } | undefined;
5205
5274
  shadow?: {
5206
5275
  enabled?: boolean | undefined;
5207
5276
  preset?: string | undefined;
@@ -5412,5 +5481,5 @@ export declare class SceneBuilder implements ISceneBuilder {
5412
5481
  removeLoadingComponent(componentId: string): void;
5413
5482
  buildCharactersList(): void;
5414
5483
  render(): void;
5415
- destroy(): void;
5484
+ destroy(): Promise<void>;
5416
5485
  }
@@ -17,7 +17,7 @@ import { MediaManager } from './managers/MediaManager.js';
17
17
  import { DeterministicMediaManager } from './managers/DeterministicMediaManager.js';
18
18
  import { LayersManager } from './managers/LayersManager.svelte.js';
19
19
  import { SubtitlesManager } from './managers/SubtitlesManager.svelte.js';
20
- import { removeContainer } from './DIContainer.js';
20
+ import { evictContainer, removeContainer } from './DIContainer.js';
21
21
  export class SceneBuilder {
22
22
  initialized = false;
23
23
  renderTicker;
@@ -106,6 +106,50 @@ export class SceneBuilder {
106
106
  get disabledTimeZones() {
107
107
  return this.stateManager.disabledTimeZones;
108
108
  }
109
+ explainComponentState(componentId) {
110
+ const component = this.componentsManager.get(componentId);
111
+ if (!component)
112
+ return null;
113
+ const data = component.props.getData();
114
+ const target = component.context.getResource('animationTarget');
115
+ const isHtml = typeof HTMLElement !== 'undefined' && target instanceof HTMLElement;
116
+ const wrapper = component.context.getResource('wrapperHtmlEl');
117
+ const element = component.context.getResource('htmlEl');
118
+ let targetKind = 'none';
119
+ let targetOwner = 'none';
120
+ const computed = {};
121
+ if (isHtml) {
122
+ targetKind = 'html';
123
+ targetOwner = target === wrapper ? 'wrapper' : target === element ? 'element' : 'element';
124
+ const style = getComputedStyle(target);
125
+ computed.opacity = Number.parseFloat(style.opacity || '1');
126
+ computed.transform = style.transform || 'none';
127
+ }
128
+ else if (target) {
129
+ targetKind = 'pixi';
130
+ targetOwner = 'pixi';
131
+ for (const key of ['x', 'y', 'opacity', 'rotation', 'scale', 'scaleX', 'scaleY']) {
132
+ const value = target[key];
133
+ if (typeof value === 'number')
134
+ computed[key] = value;
135
+ }
136
+ }
137
+ return {
138
+ componentId,
139
+ type: data.type,
140
+ time: this.currentTime,
141
+ active: component.context.isActive,
142
+ relativeTime: this.currentTime - data.timeline.startAt,
143
+ targetKind,
144
+ targetOwner,
145
+ computed,
146
+ animations: (data.animations?.list ?? []).map((entry) => ({
147
+ id: entry.id,
148
+ enabled: data.animations?.enabled !== false && entry.enabled !== false,
149
+ startAt: entry.startAt ?? 0
150
+ }))
151
+ };
152
+ }
109
153
  addExcludedTimestamp(start, end) {
110
154
  this.stateManager.data.settings.trimZones = this.stateManager.data.settings?.trimZones || [];
111
155
  this.stateManager.data.settings.trimZones.push({
@@ -181,21 +225,27 @@ export class SceneBuilder {
181
225
  return;
182
226
  }
183
227
  this.initialized = true;
184
- gsap.ticker.fps(this.fps);
185
- this.renderTicker = () => {
186
- this.render();
187
- };
188
- await this.loadFonts(this.fonts);
189
- this.layersManager.setAppManager(this.appManager);
190
- await this.appManager.initialize();
191
- if (this.stateManager.scale !== 1) {
192
- this.scale(this.stateManager.scale);
228
+ try {
229
+ gsap.ticker.fps(this.fps);
230
+ this.renderTicker = () => {
231
+ this.render();
232
+ };
233
+ await this.loadFonts(this.fonts);
234
+ this.layersManager.setAppManager(this.appManager);
235
+ await this.appManager.initialize();
236
+ if (this.stateManager.scale !== 1) {
237
+ this.scale(this.stateManager.scale);
238
+ }
239
+ await this.buildSceneTree();
240
+ await this.seek(0);
241
+ this.eventManager.isReady = true;
242
+ this.domManager.removeLoader();
243
+ }
244
+ catch (error) {
245
+ this.initialized = false;
246
+ this.eventManager.isReady = false;
247
+ throw error;
193
248
  }
194
- await this.buildSceneTree();
195
- this.seek(0);
196
- this.render();
197
- this.eventManager.isReady = true;
198
- this.domManager.removeLoader();
199
249
  }
200
250
  async buildSceneTree() {
201
251
  // Sort layers by order
@@ -423,6 +473,7 @@ export class SceneBuilder {
423
473
  if (!isDuplicate) {
424
474
  previousMimeType = mimeType;
425
475
  }
476
+ // Current frame payloads are strings, ArrayBuffers, or Blobs, so release() is a no-op today.
426
477
  let released = false;
427
478
  const release = () => {
428
479
  if (released) {
@@ -491,20 +542,36 @@ export class SceneBuilder {
491
542
  gsap.ticker.remove(this.renderTicker);
492
543
  }
493
544
  }
494
- destroy() {
495
- // Stop the timeline and remove the render ticker
496
- gsap.ticker.remove(this.renderTicker);
497
- // Clear the components map
545
+ async destroy() {
498
546
  this.initialized = false;
499
- this.appManager.destroy();
500
- this.domManager.destroy();
501
- this.stateManager.destroy();
502
- this.timelineManager.destroy();
503
- this.componentsManager.destroy();
504
- // media manages should be destroyed last
505
- this.mediaManager.destroy();
506
- void this.deterministicMediaManager.destroy();
507
- // Remove the container from the DI container cache
508
- removeContainer(this.sceneData.id);
547
+ this.eventManager.isReady = false;
548
+ const container = evictContainer(this.sceneData.id);
549
+ const errors = [];
550
+ const cleanup = async (operation) => {
551
+ try {
552
+ await operation();
553
+ }
554
+ catch (error) {
555
+ errors.push(error);
556
+ }
557
+ };
558
+ try {
559
+ await cleanup(() => gsap.ticker.remove(this.renderTicker));
560
+ await cleanup(() => this.componentsManager.destroy());
561
+ await cleanup(() => this.mediaManager.destroy());
562
+ await cleanup(() => this.deterministicMediaManager.destroy());
563
+ await cleanup(() => this.timelineManager.destroy());
564
+ await cleanup(() => this.appManager.destroy());
565
+ await cleanup(() => this.domManager.destroy());
566
+ await cleanup(() => this.stateManager.destroy());
567
+ }
568
+ finally {
569
+ await cleanup(() => container?.dispose());
570
+ if (container)
571
+ await cleanup(() => removeContainer(this.sceneData.id, container));
572
+ }
573
+ if (errors.length > 0) {
574
+ throw new AggregateError(errors, `SceneBuilder teardown failed for ${this.sceneData.id}.`);
575
+ }
509
576
  }
510
577
  }
@@ -0,0 +1,34 @@
1
+ export type AudioMixRange = {
2
+ start: number;
3
+ end: number;
4
+ };
5
+ export type AudioSourcePlan = {
6
+ id: string;
7
+ kind: 'component' | 'track' | 'scene';
8
+ url: string;
9
+ startInChunkSec: number;
10
+ durationSec: number;
11
+ sourceOffsetSec: number;
12
+ volume: number;
13
+ };
14
+ export type BuildLocalMixedAudioResult = {
15
+ audioPath: string | null;
16
+ selectedSources: number;
17
+ skippedSources: number;
18
+ plannedSources: AudioSourcePlan[];
19
+ };
20
+ export declare function resolveAudioMixRanges(sceneInput: unknown, chunkStartSec: number, chunkEndSec: number): AudioMixRange[];
21
+ export declare function collectAudioSourcesForRanges(sceneInput: unknown, ranges: AudioMixRange[]): AudioSourcePlan[];
22
+ export declare function sourceHasAudio(url: string): Promise<boolean>;
23
+ export declare function createPrepareSourceAudioArgs(source: AudioSourcePlan, outputPath: string): string[];
24
+ export declare function createMixAudioArgs(inputs: Array<{
25
+ plan: AudioSourcePlan;
26
+ path: string;
27
+ }>, outputPath: string, chunkDurationSec: number): string[];
28
+ export declare function buildLocalMixedAudioTrack(input: {
29
+ scene: unknown;
30
+ ranges: AudioMixRange[];
31
+ workDir: string;
32
+ renderId?: string;
33
+ debug?: boolean;
34
+ }): Promise<BuildLocalMixedAudioResult>;