@smoove/core 0.1.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.
Files changed (307) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/dist/animation/color.d.ts +9 -0
  4. package/dist/animation/color.d.ts.map +1 -0
  5. package/dist/animation/color.js +224 -0
  6. package/dist/animation/color.js.map +1 -0
  7. package/dist/animation/easing.d.ts +22 -0
  8. package/dist/animation/easing.d.ts.map +1 -0
  9. package/dist/animation/easing.js +59 -0
  10. package/dist/animation/easing.js.map +1 -0
  11. package/dist/animation/interpolate-colors.d.ts +7 -0
  12. package/dist/animation/interpolate-colors.d.ts.map +1 -0
  13. package/dist/animation/interpolate-colors.js +19 -0
  14. package/dist/animation/interpolate-colors.js.map +1 -0
  15. package/dist/animation/interpolate.d.ts +12 -0
  16. package/dist/animation/interpolate.d.ts.map +1 -0
  17. package/dist/animation/interpolate.js +65 -0
  18. package/dist/animation/interpolate.js.map +1 -0
  19. package/dist/audio/asset.d.ts +21 -0
  20. package/dist/audio/asset.d.ts.map +1 -0
  21. package/dist/audio/asset.js +2 -0
  22. package/dist/audio/asset.js.map +1 -0
  23. package/dist/audio/audio-driver.d.ts +34 -0
  24. package/dist/audio/audio-driver.d.ts.map +1 -0
  25. package/dist/audio/audio-driver.js +2 -0
  26. package/dist/audio/audio-driver.js.map +1 -0
  27. package/dist/audio/audio-for-preview.d.ts +12 -0
  28. package/dist/audio/audio-for-preview.d.ts.map +1 -0
  29. package/dist/audio/audio-for-preview.js +70 -0
  30. package/dist/audio/audio-for-preview.js.map +1 -0
  31. package/dist/audio/audio-for-rendering.d.ts +16 -0
  32. package/dist/audio/audio-for-rendering.d.ts.map +1 -0
  33. package/dist/audio/audio-for-rendering.js +32 -0
  34. package/dist/audio/audio-for-rendering.js.map +1 -0
  35. package/dist/audio/audio-source-browser.d.ts +30 -0
  36. package/dist/audio/audio-source-browser.d.ts.map +1 -0
  37. package/dist/audio/audio-source-browser.js +139 -0
  38. package/dist/audio/audio-source-browser.js.map +1 -0
  39. package/dist/audio/audio-source.d.ts +38 -0
  40. package/dist/audio/audio-source.d.ts.map +1 -0
  41. package/dist/audio/audio-source.js +2 -0
  42. package/dist/audio/audio-source.js.map +1 -0
  43. package/dist/audio/index.d.ts +45 -0
  44. package/dist/audio/index.d.ts.map +1 -0
  45. package/dist/audio/index.js +143 -0
  46. package/dist/audio/index.js.map +1 -0
  47. package/dist/audio/mixer.d.ts +43 -0
  48. package/dist/audio/mixer.d.ts.map +1 -0
  49. package/dist/audio/mixer.js +51 -0
  50. package/dist/audio/mixer.js.map +1 -0
  51. package/dist/audio/types.d.ts +31 -0
  52. package/dist/audio/types.d.ts.map +1 -0
  53. package/dist/audio/types.js +2 -0
  54. package/dist/audio/types.js.map +1 -0
  55. package/dist/block.d.ts +16 -0
  56. package/dist/block.d.ts.map +1 -0
  57. package/dist/block.js +173 -0
  58. package/dist/block.js.map +1 -0
  59. package/dist/composition.d.ts.map +1 -0
  60. package/dist/composition.js.map +1 -0
  61. package/dist/easing.d.ts +22 -0
  62. package/dist/easing.d.ts.map +1 -0
  63. package/dist/easing.js +59 -0
  64. package/dist/easing.js.map +1 -0
  65. package/dist/emitter.d.ts +7 -0
  66. package/dist/emitter.d.ts.map +1 -0
  67. package/dist/emitter.js +29 -0
  68. package/dist/emitter.js.map +1 -0
  69. package/dist/engine/composition.d.ts +182 -0
  70. package/dist/engine/composition.d.ts.map +1 -0
  71. package/dist/engine/composition.js +527 -0
  72. package/dist/engine/composition.js.map +1 -0
  73. package/dist/engine/emitter.d.ts +7 -0
  74. package/dist/engine/emitter.d.ts.map +1 -0
  75. package/dist/engine/emitter.js +29 -0
  76. package/dist/engine/emitter.js.map +1 -0
  77. package/dist/engine/environment.d.ts +30 -0
  78. package/dist/engine/environment.d.ts.map +1 -0
  79. package/dist/engine/environment.js +27 -0
  80. package/dist/engine/environment.js.map +1 -0
  81. package/dist/engine/offsets.d.ts +39 -0
  82. package/dist/engine/offsets.d.ts.map +1 -0
  83. package/dist/engine/offsets.js +54 -0
  84. package/dist/engine/offsets.js.map +1 -0
  85. package/dist/engine/runtime-defaults.d.ts +50 -0
  86. package/dist/engine/runtime-defaults.d.ts.map +1 -0
  87. package/dist/engine/runtime-defaults.js +77 -0
  88. package/dist/engine/runtime-defaults.js.map +1 -0
  89. package/dist/engine/sequence.d.ts +44 -0
  90. package/dist/engine/sequence.d.ts.map +1 -0
  91. package/dist/engine/sequence.js +101 -0
  92. package/dist/engine/sequence.js.map +1 -0
  93. package/dist/engine/series.d.ts +40 -0
  94. package/dist/engine/series.d.ts.map +1 -0
  95. package/dist/engine/series.js +58 -0
  96. package/dist/engine/series.js.map +1 -0
  97. package/dist/engine/signal.d.ts +10 -0
  98. package/dist/engine/signal.d.ts.map +1 -0
  99. package/dist/engine/signal.js +39 -0
  100. package/dist/engine/signal.js.map +1 -0
  101. package/dist/environment.d.ts.map +1 -0
  102. package/dist/environment.js.map +1 -0
  103. package/dist/flex-engine.d.ts +31 -0
  104. package/dist/flex-engine.d.ts.map +1 -0
  105. package/dist/flex-engine.js +186 -0
  106. package/dist/flex-engine.js.map +1 -0
  107. package/dist/flex-types.d.ts +165 -0
  108. package/dist/flex-types.d.ts.map +1 -0
  109. package/dist/flex-types.js +2 -0
  110. package/dist/flex-types.js.map +1 -0
  111. package/dist/flex.d.ts +26 -0
  112. package/dist/flex.d.ts.map +1 -0
  113. package/dist/flex.js +179 -0
  114. package/dist/flex.js.map +1 -0
  115. package/dist/image.d.ts +10 -0
  116. package/dist/image.d.ts.map +1 -0
  117. package/dist/image.js +156 -0
  118. package/dist/image.js.map +1 -0
  119. package/dist/index.d.ts +34 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +28 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/interpolate-colors.d.ts +7 -0
  124. package/dist/interpolate-colors.d.ts.map +1 -0
  125. package/dist/interpolate-colors.js +240 -0
  126. package/dist/interpolate-colors.js.map +1 -0
  127. package/dist/interpolate.d.ts +12 -0
  128. package/dist/interpolate.d.ts.map +1 -0
  129. package/dist/interpolate.js +65 -0
  130. package/dist/interpolate.js.map +1 -0
  131. package/dist/layout/block.d.ts +54 -0
  132. package/dist/layout/block.d.ts.map +1 -0
  133. package/dist/layout/block.js +186 -0
  134. package/dist/layout/block.js.map +1 -0
  135. package/dist/layout/contract.d.ts +41 -0
  136. package/dist/layout/contract.d.ts.map +1 -0
  137. package/dist/layout/contract.js +8 -0
  138. package/dist/layout/contract.js.map +1 -0
  139. package/dist/layout/flex/engine.d.ts +31 -0
  140. package/dist/layout/flex/engine.d.ts.map +1 -0
  141. package/dist/layout/flex/engine.js +186 -0
  142. package/dist/layout/flex/engine.js.map +1 -0
  143. package/dist/layout/flex/flex.d.ts +31 -0
  144. package/dist/layout/flex/flex.d.ts.map +1 -0
  145. package/dist/layout/flex/flex.js +175 -0
  146. package/dist/layout/flex/flex.js.map +1 -0
  147. package/dist/layout/flex/mixin.d.ts +52 -0
  148. package/dist/layout/flex/mixin.d.ts.map +1 -0
  149. package/dist/layout/flex/mixin.js +114 -0
  150. package/dist/layout/flex/mixin.js.map +1 -0
  151. package/dist/layout/flex/types.d.ts +31 -0
  152. package/dist/layout/flex/types.d.ts.map +1 -0
  153. package/dist/layout/flex/types.js +2 -0
  154. package/dist/layout/flex/types.js.map +1 -0
  155. package/dist/layout/image.d.ts +46 -0
  156. package/dist/layout/image.d.ts.map +1 -0
  157. package/dist/layout/image.js +198 -0
  158. package/dist/layout/image.js.map +1 -0
  159. package/dist/layout/shapes.d.ts +72 -0
  160. package/dist/layout/shapes.d.ts.map +1 -0
  161. package/dist/layout/shapes.js +29 -0
  162. package/dist/layout/shapes.js.map +1 -0
  163. package/dist/layout/text/font.d.ts +92 -0
  164. package/dist/layout/text/font.d.ts.map +1 -0
  165. package/dist/layout/text/font.js +166 -0
  166. package/dist/layout/text/font.js.map +1 -0
  167. package/dist/layout/text/geometry.d.ts +31 -0
  168. package/dist/layout/text/geometry.d.ts.map +1 -0
  169. package/dist/layout/text/geometry.js +81 -0
  170. package/dist/layout/text/geometry.js.map +1 -0
  171. package/dist/layout/text/text.d.ts +98 -0
  172. package/dist/layout/text/text.d.ts.map +1 -0
  173. package/dist/layout/text/text.js +676 -0
  174. package/dist/layout/text/text.js.map +1 -0
  175. package/dist/layout/text/types.d.ts +103 -0
  176. package/dist/layout/text/types.d.ts.map +1 -0
  177. package/dist/layout/text/types.js +2 -0
  178. package/dist/layout/text/types.js.map +1 -0
  179. package/dist/media/audio/asset.d.ts +21 -0
  180. package/dist/media/audio/asset.d.ts.map +1 -0
  181. package/dist/media/audio/asset.js +2 -0
  182. package/dist/media/audio/asset.js.map +1 -0
  183. package/dist/media/audio/audio-driver.d.ts +34 -0
  184. package/dist/media/audio/audio-driver.d.ts.map +1 -0
  185. package/dist/media/audio/audio-driver.js +2 -0
  186. package/dist/media/audio/audio-driver.js.map +1 -0
  187. package/dist/media/audio/audio-for-preview.d.ts +47 -0
  188. package/dist/media/audio/audio-for-preview.d.ts.map +1 -0
  189. package/dist/media/audio/audio-for-preview.js +232 -0
  190. package/dist/media/audio/audio-for-preview.js.map +1 -0
  191. package/dist/media/audio/audio-for-rendering.d.ts +16 -0
  192. package/dist/media/audio/audio-for-rendering.d.ts.map +1 -0
  193. package/dist/media/audio/audio-for-rendering.js +32 -0
  194. package/dist/media/audio/audio-for-rendering.js.map +1 -0
  195. package/dist/media/audio/audio-source-browser.d.ts +30 -0
  196. package/dist/media/audio/audio-source-browser.d.ts.map +1 -0
  197. package/dist/media/audio/audio-source-browser.js +139 -0
  198. package/dist/media/audio/audio-source-browser.js.map +1 -0
  199. package/dist/media/audio/audio-source-mediabunny.d.ts +45 -0
  200. package/dist/media/audio/audio-source-mediabunny.d.ts.map +1 -0
  201. package/dist/media/audio/audio-source-mediabunny.js +79 -0
  202. package/dist/media/audio/audio-source-mediabunny.js.map +1 -0
  203. package/dist/media/audio/audio-source.d.ts +38 -0
  204. package/dist/media/audio/audio-source.d.ts.map +1 -0
  205. package/dist/media/audio/audio-source.js +2 -0
  206. package/dist/media/audio/audio-source.js.map +1 -0
  207. package/dist/media/audio/index.d.ts +57 -0
  208. package/dist/media/audio/index.d.ts.map +1 -0
  209. package/dist/media/audio/index.js +170 -0
  210. package/dist/media/audio/index.js.map +1 -0
  211. package/dist/media/audio/mixer.d.ts +43 -0
  212. package/dist/media/audio/mixer.d.ts.map +1 -0
  213. package/dist/media/audio/mixer.js +51 -0
  214. package/dist/media/audio/mixer.js.map +1 -0
  215. package/dist/media/audio/shared-audio-context.d.ts +30 -0
  216. package/dist/media/audio/shared-audio-context.d.ts.map +1 -0
  217. package/dist/media/audio/shared-audio-context.js +68 -0
  218. package/dist/media/audio/shared-audio-context.js.map +1 -0
  219. package/dist/media/audio/types.d.ts +31 -0
  220. package/dist/media/audio/types.d.ts.map +1 -0
  221. package/dist/media/audio/types.js +2 -0
  222. package/dist/media/audio/types.js.map +1 -0
  223. package/dist/media/media-marker.d.ts +26 -0
  224. package/dist/media/media-marker.d.ts.map +1 -0
  225. package/dist/media/media-marker.js +26 -0
  226. package/dist/media/media-marker.js.map +1 -0
  227. package/dist/media/media-time.d.ts +17 -0
  228. package/dist/media/media-time.d.ts.map +1 -0
  229. package/dist/media/media-time.js +17 -0
  230. package/dist/media/media-time.js.map +1 -0
  231. package/dist/media/video/driver.d.ts +31 -0
  232. package/dist/media/video/driver.d.ts.map +1 -0
  233. package/dist/media/video/driver.js +3 -0
  234. package/dist/media/video/driver.js.map +1 -0
  235. package/dist/media/video/index.d.ts +66 -0
  236. package/dist/media/video/index.d.ts.map +1 -0
  237. package/dist/media/video/index.js +372 -0
  238. package/dist/media/video/index.js.map +1 -0
  239. package/dist/media/video/types.d.ts +36 -0
  240. package/dist/media/video/types.d.ts.map +1 -0
  241. package/dist/media/video/types.js +2 -0
  242. package/dist/media/video/types.js.map +1 -0
  243. package/dist/media/video/video-for-preview.d.ts +17 -0
  244. package/dist/media/video/video-for-preview.d.ts.map +1 -0
  245. package/dist/media/video/video-for-preview.js +30 -0
  246. package/dist/media/video/video-for-preview.js.map +1 -0
  247. package/dist/media/video/video-for-rendering.d.ts +17 -0
  248. package/dist/media/video/video-for-rendering.d.ts.map +1 -0
  249. package/dist/media/video/video-for-rendering.js +59 -0
  250. package/dist/media/video/video-for-rendering.js.map +1 -0
  251. package/dist/media/video/video-source-browser.d.ts +37 -0
  252. package/dist/media/video/video-source-browser.d.ts.map +1 -0
  253. package/dist/media/video/video-source-browser.js +171 -0
  254. package/dist/media/video/video-source-browser.js.map +1 -0
  255. package/dist/media/video/video-source-mediabunny.d.ts +69 -0
  256. package/dist/media/video/video-source-mediabunny.d.ts.map +1 -0
  257. package/dist/media/video/video-source-mediabunny.js +236 -0
  258. package/dist/media/video/video-source-mediabunny.js.map +1 -0
  259. package/dist/media/video/video-source.d.ts +48 -0
  260. package/dist/media/video/video-source.d.ts.map +1 -0
  261. package/dist/media/video/video-source.js +2 -0
  262. package/dist/media/video/video-source.js.map +1 -0
  263. package/dist/media-marker.d.ts +19 -0
  264. package/dist/media-marker.d.ts.map +1 -0
  265. package/dist/media-marker.js +19 -0
  266. package/dist/media-marker.js.map +1 -0
  267. package/dist/media-time.d.ts +17 -0
  268. package/dist/media-time.d.ts.map +1 -0
  269. package/dist/media-time.js +17 -0
  270. package/dist/media-time.js.map +1 -0
  271. package/dist/signal.d.ts +10 -0
  272. package/dist/signal.d.ts.map +1 -0
  273. package/dist/signal.js +39 -0
  274. package/dist/signal.js.map +1 -0
  275. package/dist/text.d.ts +91 -0
  276. package/dist/text.d.ts.map +1 -0
  277. package/dist/text.js +704 -0
  278. package/dist/text.js.map +1 -0
  279. package/dist/video/driver.d.ts +31 -0
  280. package/dist/video/driver.d.ts.map +1 -0
  281. package/dist/video/driver.js +3 -0
  282. package/dist/video/driver.js.map +1 -0
  283. package/dist/video/index.d.ts +45 -0
  284. package/dist/video/index.d.ts.map +1 -0
  285. package/dist/video/index.js +276 -0
  286. package/dist/video/index.js.map +1 -0
  287. package/dist/video/types.d.ts +35 -0
  288. package/dist/video/types.d.ts.map +1 -0
  289. package/dist/video/types.js +2 -0
  290. package/dist/video/types.js.map +1 -0
  291. package/dist/video/video-for-preview.d.ts +12 -0
  292. package/dist/video/video-for-preview.d.ts.map +1 -0
  293. package/dist/video/video-for-preview.js +73 -0
  294. package/dist/video/video-for-preview.js.map +1 -0
  295. package/dist/video/video-for-rendering.d.ts +16 -0
  296. package/dist/video/video-for-rendering.d.ts.map +1 -0
  297. package/dist/video/video-for-rendering.js +45 -0
  298. package/dist/video/video-for-rendering.js.map +1 -0
  299. package/dist/video/video-source-browser.d.ts +37 -0
  300. package/dist/video/video-source-browser.d.ts.map +1 -0
  301. package/dist/video/video-source-browser.js +171 -0
  302. package/dist/video/video-source-browser.js.map +1 -0
  303. package/dist/video/video-source.d.ts +48 -0
  304. package/dist/video/video-source.d.ts.map +1 -0
  305. package/dist/video/video-source.js +2 -0
  306. package/dist/video/video-source.js.map +1 -0
  307. package/package.json +42 -0
@@ -0,0 +1,527 @@
1
+ import Konva from "konva";
2
+ import { AudioMixer } from "../media/audio/mixer.js";
3
+ import { FONT_MARK, MEDIA_MARK } from "../media/media-marker.js";
4
+ import { createEmitter } from "./emitter.js";
5
+ import { detectEnvironment } from "./environment.js";
6
+ import { Sequence } from "./sequence.js";
7
+ import { createSignal, derived } from "./signal.js";
8
+ /** A SequenceProvider duck-types on a `sequences()` method (Konva layers lack one). */
9
+ function isSequenceProvider(x) {
10
+ return typeof x.sequences === "function";
11
+ }
12
+ const COMP_EVENTS = new Set(["play", "stop", "time"]);
13
+ const isCompositionEvent = (e) => COMP_EVENTS.has(e);
14
+ const raf = typeof globalThis.requestAnimationFrame === "function"
15
+ ? globalThis.requestAnimationFrame.bind(globalThis)
16
+ : null;
17
+ const caf = typeof globalThis.cancelAnimationFrame === "function"
18
+ ? globalThis.cancelAnimationFrame.bind(globalThis)
19
+ : null;
20
+ const wallNow = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
21
+ export function getComposition(stage) {
22
+ return stage.__SmooveComposition ?? null;
23
+ }
24
+ export class Composition extends Konva.Stage {
25
+ fps;
26
+ environment;
27
+ /** Composition-level audio bus — master volume/mute scaling every Video and Audio. */
28
+ mixer = new AudioMixer();
29
+ frame;
30
+ isPlaying;
31
+ durationInFrames;
32
+ isStopped;
33
+ isPaused;
34
+ loop;
35
+ /** Playback speed multiplier. 1 = realtime; negative plays in reverse. */
36
+ playbackRate;
37
+ /** Live props the scene reads. Pushed to with {@link setProps} by a player or
38
+ the studio form; updaters read it via `comp.props.get()`. */
39
+ props;
40
+ /** Asset-buffering state — `"idle"` | `"buffering"` | `"ready"`. See {@link registerAsset}. */
41
+ buffer;
42
+ /** Convenience: `buffer.get() === "buffering"`. */
43
+ isBuffering;
44
+ _frame;
45
+ _props;
46
+ _isPlaying;
47
+ _durationInFrames;
48
+ _loop;
49
+ _playbackRate;
50
+ _buffer;
51
+ _emitter;
52
+ _rafId = null;
53
+ _startWallMs = 0;
54
+ _startFrame = 0;
55
+ // Background work released by suspend() until resume() re-acquires it.
56
+ _suspended = false;
57
+ // Asset-buffering gate (the preview analogue of the delayRender render gate):
58
+ // outstanding asset loads that should be ready before playback advances.
59
+ _assets = new Set();
60
+ _readyWaiters = [];
61
+ // Set when play() is called while buffering — playback starts on buffer ready.
62
+ _resumeOnReady = false;
63
+ // delayRender/continueRender gate — outstanding async work that must complete
64
+ // before a rendered frame is captured (Remotion's delayRender model).
65
+ _renderHandles = new Set();
66
+ _nextHandle = 0;
67
+ _renderWaiters = [];
68
+ // Audio samples collected during offline rendering (one per Audio per frame),
69
+ // for an external audio-mux pass. Empty during preview.
70
+ _audioAssets = [];
71
+ // Reused scratch canvas for captureCanvas() — avoids a per-frame skia Canvas
72
+ // allocation (native memory V8's GC can't see) during long renders.
73
+ _captureCanvas = null;
74
+ constructor(opts) {
75
+ if (!opts.id)
76
+ throw new Error("Composition: id is required");
77
+ if (!Number.isFinite(opts.fps) || opts.fps <= 0) {
78
+ throw new Error("Composition: fps must be a positive number");
79
+ }
80
+ if (!Number.isInteger(opts.durationInFrames) || opts.durationInFrames <= 0) {
81
+ throw new Error("Composition: durationInFrames must be a positive integer");
82
+ }
83
+ const { fps, durationInFrames, loop = false, props, mode, ...stageOpts } = opts;
84
+ // Konva requires a container element. In the browser, fall back to a
85
+ // detached <div> when none is given, so a Composition can be constructed
86
+ // up-front and mounted later via `setContainer` (e.g. handed to a player).
87
+ // In non-browser runtimes (server rendering) there's no DOM, so leave it
88
+ // unset — frames are driven with `setFrame`/`renderFrame`, not a canvas.
89
+ if (stageOpts.container == null && typeof document !== "undefined") {
90
+ stageOpts.container = document.createElement("div");
91
+ }
92
+ super(stageOpts);
93
+ const marker = this;
94
+ if (marker.__SmooveComposition) {
95
+ throw new Error("A Composition is already attached to this Stage.");
96
+ }
97
+ marker.__SmooveComposition = this;
98
+ this.fps = fps;
99
+ this.environment = detectEnvironment(mode);
100
+ this._frame = createSignal(0);
101
+ this._isPlaying = createSignal(false);
102
+ this._durationInFrames = createSignal(durationInFrames);
103
+ this._loop = createSignal(loop);
104
+ this._playbackRate = createSignal(1);
105
+ this._props = createSignal(props ?? {});
106
+ this._buffer = createSignal("idle");
107
+ this.frame = this._frame;
108
+ this.isPlaying = this._isPlaying;
109
+ this.durationInFrames = this._durationInFrames;
110
+ this.loop = this._loop;
111
+ this.playbackRate = this._playbackRate;
112
+ this.props = this._props;
113
+ this.buffer = this._buffer;
114
+ this.isBuffering = derived([this._buffer], () => this._buffer.get() === "buffering");
115
+ this.isStopped = derived([this._isPlaying, this._frame], () => !this._isPlaying.get() && this._frame.get() === 0);
116
+ this.isPaused = derived([this._isPlaying, this._frame], () => !this._isPlaying.get() && this._frame.get() > 0);
117
+ this._emitter = createEmitter();
118
+ }
119
+ // biome-ignore lint/suspicious/noExplicitAny: bridges Konva's typed event API with our composition events.
120
+ on(evtStr, handler) {
121
+ if (typeof evtStr === "string" && isCompositionEvent(evtStr)) {
122
+ return this._emitter.on(evtStr, handler);
123
+ }
124
+ return super.on(evtStr, handler);
125
+ }
126
+ // biome-ignore lint/suspicious/noExplicitAny: see on() above.
127
+ off(evtStr, handler) {
128
+ if (typeof evtStr === "string" && isCompositionEvent(evtStr)) {
129
+ if (handler)
130
+ this._emitter.off(evtStr, handler);
131
+ return this;
132
+ }
133
+ return super.off(evtStr, handler);
134
+ }
135
+ add(first, ...rest) {
136
+ // Expand any SequenceProvider (Series / TransitionSeries) into its layers,
137
+ // so `comp.add(series)` works as well as `comp.add(layer)`.
138
+ const layers = [];
139
+ for (const item of [first, ...rest]) {
140
+ if (isSequenceProvider(item))
141
+ layers.push(...item.sequences());
142
+ else
143
+ layers.push(item);
144
+ }
145
+ if (layers.length === 0)
146
+ return this;
147
+ super.add(...layers);
148
+ const frame = this._frame.get();
149
+ // Pass 1 — register assets first (across ALL added layers) so a Font in any
150
+ // of them flips the buffer to "buffering" before we paint anything. Media is
151
+ // registered eagerly so mixer channels exist before playback (lazy fallback
152
+ // lives in each node's _ensureDriver / Font._kmTick).
153
+ for (const l of layers) {
154
+ if (l instanceof Sequence) {
155
+ for (const v of l.find((n) => n.getAttr(MEDIA_MARK) === true)) {
156
+ this.mixer.register(v);
157
+ }
158
+ for (const f of l.find((n) => n.getAttr(FONT_MARK) === true)) {
159
+ f._kmRegister?.(this);
160
+ }
161
+ }
162
+ }
163
+ // Pass 2 — paint the current frame, unless we're now buffering: leave the
164
+ // sequences hidden (transparent) until assets load. The buffer-drain in
165
+ // registerAsset paints the first frame once everything is ready.
166
+ if (this._buffer.get() !== "buffering") {
167
+ for (const l of layers) {
168
+ if (l instanceof Sequence)
169
+ l._apply(frame, true);
170
+ }
171
+ }
172
+ return this;
173
+ }
174
+ play() {
175
+ if (!raf || !caf) {
176
+ throw new Error("Composition.play() requires requestAnimationFrame. In non-browser environments, drive playback with setFrame() instead.");
177
+ }
178
+ if (this._isPlaying.get())
179
+ return;
180
+ // Buffer-aware: if assets are still loading, defer the clock and resume
181
+ // automatically once buffering completes (see registerAsset).
182
+ if (this._buffer.get() === "buffering") {
183
+ this._resumeOnReady = true;
184
+ return;
185
+ }
186
+ this._startClock();
187
+ }
188
+ _startClock() {
189
+ this._isPlaying.set(true);
190
+ this._startFrame = this._frame.get();
191
+ this._startWallMs = wallNow();
192
+ this._applyFrame(this._frame.get(), false);
193
+ this._emitter.emit("play", this._event());
194
+ this._scheduleTick();
195
+ }
196
+ destroy() {
197
+ this._cancelTick();
198
+ this._isPlaying.set(false);
199
+ return super.destroy();
200
+ }
201
+ pause() {
202
+ this._resumeOnReady = false;
203
+ if (!this._isPlaying.get())
204
+ return;
205
+ this._cancelTick();
206
+ this._isPlaying.set(false);
207
+ }
208
+ /** `true` between {@link suspend} and {@link resume}. */
209
+ get isSuspended() {
210
+ return this._suspended;
211
+ }
212
+ /**
213
+ * Release background work — halt the clock and tell every media node to drop
214
+ * its source, so a composition that isn't being shown (e.g. a `<smoove-player>`
215
+ * removed from the DOM) stops downloading/decoding video and audio. This does
216
+ * NOT tear the composition down: the scene graph stays intact and {@link resume}
217
+ * re-acquires the sources. No-op if already suspended.
218
+ */
219
+ suspend() {
220
+ if (this._suspended)
221
+ return;
222
+ this._suspended = true;
223
+ this._resumeOnReady = false;
224
+ this._cancelTick();
225
+ if (this._isPlaying.get())
226
+ this._isPlaying.set(false);
227
+ this._forEachMedia((n) => n._kmSuspend?.());
228
+ }
229
+ /**
230
+ * Undo {@link suspend}: re-acquire the media sources released while suspended
231
+ * (they re-download and redraw once ready) and repaint the current frame.
232
+ * No-op if not suspended.
233
+ */
234
+ resume() {
235
+ if (!this._suspended)
236
+ return;
237
+ this._suspended = false;
238
+ this._forEachMedia((n) => n._kmResume?.());
239
+ // force: sources were dropped, so the same frame must be re-applied.
240
+ this._applyFrame(this._frame.get(), false, true);
241
+ }
242
+ /** Walk every media node (Video/Audio) across all sequences. */
243
+ _forEachMedia(cb) {
244
+ for (const child of this.getChildren()) {
245
+ if (child instanceof Sequence) {
246
+ for (const n of child.find((x) => x.getAttr(MEDIA_MARK) === true)) {
247
+ cb(n);
248
+ }
249
+ }
250
+ }
251
+ }
252
+ stop() {
253
+ this._resumeOnReady = false;
254
+ this._cancelTick();
255
+ if (this._isPlaying.get())
256
+ this._isPlaying.set(false);
257
+ this._frame.set(0);
258
+ this._applyFrame(0, false);
259
+ this._emitter.emit("stop", this._event());
260
+ }
261
+ setLoop(value) {
262
+ this._loop.set(value);
263
+ }
264
+ /**
265
+ * Set the playback speed multiplier. `1` is realtime; `2` is double speed;
266
+ * negative values play in reverse. Clamped to `[-10, 10]`; `0` throws (it
267
+ * would freeze the clock). Changing the rate mid-playback resyncs the clock
268
+ * so the new speed takes effect from the current frame onward.
269
+ */
270
+ setPlaybackRate(rate) {
271
+ if (!Number.isFinite(rate) || rate === 0) {
272
+ throw new Error("Composition.setPlaybackRate(): rate must be a non-zero finite number");
273
+ }
274
+ const clamped = Math.max(-10, Math.min(10, rate));
275
+ if (clamped === this._playbackRate.get())
276
+ return;
277
+ this._playbackRate.set(clamped);
278
+ if (this._isPlaying.get()) {
279
+ this._startFrame = this._frame.get();
280
+ this._startWallMs = wallNow();
281
+ }
282
+ }
283
+ setFrame(target) {
284
+ const clamped = Math.max(0, Math.min(this._durationInFrames.get() - 1, Math.floor(target)));
285
+ if (clamped === this._frame.get())
286
+ return;
287
+ this._frame.set(clamped);
288
+ if (this._isPlaying.get()) {
289
+ this._startFrame = clamped;
290
+ this._startWallMs = wallNow();
291
+ }
292
+ this._applyFrame(clamped, true);
293
+ }
294
+ /**
295
+ * Re-apply the **current** frame to every sequence without advancing the
296
+ * playhead — the engine's "re-render" hook. Call this after mutating external
297
+ * state that updaters read (e.g. live-edited props) so the change shows
298
+ * immediately while paused. Updaters re-run, `Flex`/`Block` re-layout, and
299
+ * active sequences `batchDraw` — exactly like a normal tick at the same frame.
300
+ */
301
+ refresh() {
302
+ // force: props/external state may have changed at the same frame, so the
303
+ // sequence dedupe must not skip this re-apply.
304
+ this._applyFrame(this._frame.get(), false, true);
305
+ }
306
+ /**
307
+ * Replace the live props and re-render the current frame. Any holder — a bare
308
+ * `<smoove-player>` or the studio form — drives the scene by calling this; the
309
+ * `createSignal` `Object.is` guard skips a redundant refresh when nothing
310
+ * changed. Pass an updater to derive the next value from the previous one.
311
+ */
312
+ setProps(next) {
313
+ const value = typeof next === "function" ? next(this._props.get()) : next;
314
+ if (Object.is(value, this._props.get()))
315
+ return;
316
+ this._props.set(value);
317
+ this.refresh();
318
+ }
319
+ /**
320
+ * Register an outstanding asset load (e.g. a {@link Font}). While any asset is
321
+ * pending, {@link buffer} is `"buffering"`; once all settle it flips to
322
+ * `"ready"` and {@link whenReady} waiters resolve. A `play()` issued while
323
+ * buffering is deferred and starts automatically here. Errors are swallowed
324
+ * (the asset logs its own) so one bad asset can't wedge playback.
325
+ *
326
+ * This is the preview-side buffer; offline rendering uses the per-frame
327
+ * {@link delayRender}/{@link renderFrame} gate instead.
328
+ */
329
+ registerAsset(load, _label) {
330
+ this._assets.add(load);
331
+ if (this._buffer.get() !== "buffering") {
332
+ this._buffer.set("buffering");
333
+ // Hide everything so the stage is transparent while assets load — no frame
334
+ // is shown over not-yet-loaded fonts.
335
+ this._hideAllSequences();
336
+ }
337
+ const settle = () => {
338
+ if (!this._assets.delete(load))
339
+ return;
340
+ if (this._assets.size > 0)
341
+ return;
342
+ this._buffer.set("ready");
343
+ const waiters = this._readyWaiters;
344
+ this._readyWaiters = [];
345
+ for (const resolve of waiters)
346
+ resolve();
347
+ // Now that assets are loaded, paint. If a play() was deferred, resume the
348
+ // clock (which applies the frame); otherwise paint the current frame once.
349
+ if (this._resumeOnReady) {
350
+ this._resumeOnReady = false;
351
+ this._startClock();
352
+ }
353
+ else {
354
+ // force: first paint after assets settled, even though the frame is unchanged.
355
+ this._applyFrame(this._frame.get(), false, true);
356
+ }
357
+ };
358
+ load.then(settle, settle);
359
+ }
360
+ /** Resolves once no assets are pending — immediately if idle/ready. */
361
+ whenReady() {
362
+ if (this._assets.size === 0)
363
+ return Promise.resolve();
364
+ return new Promise((resolve) => {
365
+ this._readyWaiters.push(resolve);
366
+ });
367
+ }
368
+ /**
369
+ * Register an outstanding async task that must finish before the current
370
+ * frame is considered fully rendered — Remotion's `delayRender`. Returns a
371
+ * handle to clear with {@link continueRender}.
372
+ */
373
+ delayRender(_label) {
374
+ const handle = this._nextHandle++;
375
+ this._renderHandles.add(handle);
376
+ return handle;
377
+ }
378
+ /** Clear a {@link delayRender} handle; resolves `renderFrame()` once all clear. */
379
+ continueRender(handle) {
380
+ if (!this._renderHandles.delete(handle))
381
+ return;
382
+ if (this._renderHandles.size === 0) {
383
+ const waiters = this._renderWaiters;
384
+ this._renderWaiters = [];
385
+ for (const resolve of waiters)
386
+ resolve();
387
+ }
388
+ }
389
+ /**
390
+ * Apply a frame and wait until all {@link delayRender} handles registered
391
+ * during that application clear. This is the offline / server render
392
+ * entrypoint — e.g. `for (f) { await comp.renderFrame(f); capture(); }`.
393
+ */
394
+ async renderFrame(target) {
395
+ const clamped = Math.max(0, Math.min(this._durationInFrames.get() - 1, Math.floor(target)));
396
+ this._frame.set(clamped);
397
+ // force: offline render must apply every frame, even a re-rendered duplicate.
398
+ this._applyFrame(clamped, true, true);
399
+ if (this._renderHandles.size === 0)
400
+ return;
401
+ await new Promise((resolve) => {
402
+ this._renderWaiters.push(resolve);
403
+ });
404
+ }
405
+ /**
406
+ * Composite every visible sequence layer into a single canvas and return it.
407
+ * Works headlessly (no DOM container needed); under the server skia backend
408
+ * the result is a skia `Canvas`, on which a renderer can call
409
+ * `.toBufferSync("raw")` for RGBA pixels.
410
+ *
411
+ * Unlike `Stage.toCanvas()`, this **reuses one scratch canvas** across calls.
412
+ * Allocating a fresh skia `Canvas` per frame leaks native memory (invisible to
413
+ * V8's GC), which balloons RSS and collapses throughput over a long render.
414
+ */
415
+ captureCanvas() {
416
+ const w = this.width();
417
+ const h = this.height();
418
+ let scratch = this._captureCanvas;
419
+ if (!scratch) {
420
+ scratch = Konva.Util.createCanvasElement();
421
+ this._captureCanvas = scratch;
422
+ }
423
+ if (scratch.width !== w || scratch.height !== h) {
424
+ scratch.width = w;
425
+ scratch.height = h;
426
+ }
427
+ const ctx = scratch.getContext("2d");
428
+ if (!ctx)
429
+ return scratch;
430
+ ctx.clearRect(0, 0, w, h);
431
+ for (const child of this.getChildren()) {
432
+ if (child instanceof Konva.Layer && child.visible()) {
433
+ // Force a synchronous scene draw so the layer's own canvas is current
434
+ // (a `Sequence` may have only scheduled an async `batchDraw`).
435
+ child.drawScene();
436
+ ctx.drawImage(child.getNativeCanvasElement(), 0, 0, w, h);
437
+ }
438
+ }
439
+ return scratch;
440
+ }
441
+ /** @internal — {@link RenderingAudioDriver} records one sample per audio per frame. */
442
+ _collectAudioAsset(asset) {
443
+ this._audioAssets.push(asset);
444
+ }
445
+ /**
446
+ * Audio samples collected during offline rendering — one per {@link Audio}
447
+ * per rendered frame. Feed these to an external mux pass (e.g. ffmpeg) to
448
+ * assemble the audio track. Empty during preview.
449
+ */
450
+ getAudioAssets() {
451
+ return [...this._audioAssets];
452
+ }
453
+ /** Reset the collected audio samples — call before re-rendering a range. */
454
+ clearAudioAssets() {
455
+ this._audioAssets = [];
456
+ }
457
+ _event() {
458
+ return {
459
+ frame: this._frame.get(),
460
+ durationInFrames: this._durationInFrames.get(),
461
+ };
462
+ }
463
+ _applyFrame(frame, emit, force = false) {
464
+ // While buffering, draw nothing — the stage stays transparent until every
465
+ // registered asset (fonts, …) has loaded. Sequences are left hidden so no
466
+ // frame is painted over not-yet-loaded fonts. Offline rendering never
467
+ // buffers (fonts gate via delayRender), so this only affects preview.
468
+ if (this._buffer.get() === "buffering")
469
+ return;
470
+ for (const child of this.getChildren()) {
471
+ if (child instanceof Sequence)
472
+ child._apply(frame, force);
473
+ }
474
+ if (emit)
475
+ this._emitter.emit("time", this._event());
476
+ }
477
+ /** Hide every sequence (transparent stage) — used while buffering assets. */
478
+ _hideAllSequences() {
479
+ for (const child of this.getChildren()) {
480
+ if (child instanceof Sequence)
481
+ child._kmHide();
482
+ }
483
+ }
484
+ _scheduleTick() {
485
+ if (!raf)
486
+ return;
487
+ this._rafId = raf(this._tick);
488
+ }
489
+ _cancelTick() {
490
+ if (this._rafId !== null && caf) {
491
+ caf(this._rafId);
492
+ this._rafId = null;
493
+ }
494
+ }
495
+ _tick = (now) => {
496
+ if (!this._isPlaying.get())
497
+ return;
498
+ const rate = this._playbackRate.get();
499
+ const elapsedMs = now - this._startWallMs;
500
+ // round (not floor) so small negative advances still register frame-by-frame.
501
+ const advance = Math.round((elapsedMs / 1000) * this.fps * rate);
502
+ const lastFrame = this._durationInFrames.get() - 1;
503
+ const target = Math.max(0, Math.min(lastFrame, this._startFrame + advance));
504
+ if (target !== this._frame.get()) {
505
+ this._frame.set(target);
506
+ this._applyFrame(target, true);
507
+ }
508
+ const atEnd = rate > 0 && target >= lastFrame;
509
+ const atStart = rate < 0 && target <= 0;
510
+ if (atEnd || atStart) {
511
+ if (this._loop.get()) {
512
+ const wrap = atEnd ? 0 : lastFrame;
513
+ this._startFrame = wrap;
514
+ this._startWallMs = now;
515
+ this._frame.set(wrap);
516
+ this._applyFrame(wrap, true);
517
+ this._scheduleTick();
518
+ return;
519
+ }
520
+ this._cancelTick();
521
+ this._isPlaying.set(false);
522
+ return;
523
+ }
524
+ this._scheduleTick();
525
+ };
526
+ }
527
+ //# sourceMappingURL=composition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.js","sourceRoot":"","sources":["../../src/engine/composition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type Emitter<Events extends Record<string, unknown>> = {
2
+ on<K extends keyof Events>(event: K, listener: (payload: Events[K]) => void): () => void;
3
+ off<K extends keyof Events>(event: K, listener: (payload: Events[K]) => void): void;
4
+ emit<K extends keyof Events>(event: K, payload: Events[K]): void;
5
+ };
6
+ export declare function createEmitter<Events extends Record<string, unknown>>(): Emitter<Events>;
7
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/engine/emitter.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC5D,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACzF,GAAG,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACpF,IAAI,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CAClE,CAAC;AAEF,wBAAgB,aAAa,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CA2BvF"}
@@ -0,0 +1,29 @@
1
+ export function createEmitter() {
2
+ const listeners = new Map();
3
+ const getBucket = (event) => {
4
+ let bucket = listeners.get(event);
5
+ if (!bucket) {
6
+ bucket = new Set();
7
+ listeners.set(event, bucket);
8
+ }
9
+ return bucket;
10
+ };
11
+ return {
12
+ on(event, listener) {
13
+ const bucket = getBucket(event);
14
+ bucket.add(listener);
15
+ return () => bucket.delete(listener);
16
+ },
17
+ off(event, listener) {
18
+ listeners.get(event)?.delete(listener);
19
+ },
20
+ emit(event, payload) {
21
+ const bucket = listeners.get(event);
22
+ if (!bucket)
23
+ return;
24
+ for (const fn of bucket)
25
+ fn(payload);
26
+ },
27
+ };
28
+ }
29
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/engine/emitter.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,aAAa;IAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAC;IAE3E,MAAM,SAAS,GAAG,CAAyB,KAAQ,EAAE,EAAE;QACrD,IAAI,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;YACnB,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO;QACL,EAAE,CAAC,KAAK,EAAE,QAAQ;YAChB,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,CAAC,GAAG,CAAC,QAAsC,CAAC,CAAC;YACnD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAsC,CAAC,CAAC;QACrE,CAAC;QACD,GAAG,CAAC,KAAK,EAAE,QAAQ;YACjB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,QAAsC,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,OAAO;YACjB,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,KAAK,MAAM,EAAE,IAAI,MAAM;gBAAE,EAAE,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type Konva from "konva";
2
+ /**
3
+ * Runtime mode the engine is operating in — mirrors Remotion's
4
+ * `getRemotionEnvironment()`. `Video` (and any environment-aware node) branches
5
+ * its behavior on this: realtime playback in preview, deterministic frame-by-frame
6
+ * seeking when rendering.
7
+ */
8
+ export type Environment = {
9
+ /** Server / offline frame-by-frame rendering (e.g. Bun + Skia Canvas). */
10
+ isRendering: boolean;
11
+ /** Browser realtime playback / scrubbing. */
12
+ isPreview: boolean;
13
+ /** Reserved to mirror Remotion; always false for now. */
14
+ isClientSideRendering: boolean;
15
+ };
16
+ export type EnvironmentMode = "preview" | "rendering";
17
+ /**
18
+ * Resolve the environment. An explicit `override` (from `CompositionOptions.mode`)
19
+ * always wins; otherwise we detect from a global flag — Remotion reads
20
+ * `window.remotion_*`, we read `globalThis.__KONVA_MOTION_RENDERING__`, which a
21
+ * server renderer sets before constructing the composition.
22
+ */
23
+ export declare function detectEnvironment(override?: EnvironmentMode): Environment;
24
+ /**
25
+ * The environment of the Composition attached to `stage`, mirroring Remotion's
26
+ * `getRemotionEnvironment()`. Falls back to ambient detection if no Composition
27
+ * is attached.
28
+ */
29
+ export declare function getEnvironment(stage: Konva.Stage): Environment;
30
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/engine/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,0EAA0E;IAC1E,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,WAAW,CAAC;AAMtD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,eAAe,GAAG,WAAW,CAUzE;AAKD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,WAAW,CAG9D"}
@@ -0,0 +1,27 @@
1
+ const RENDERING_FLAG = "__KONVA_MOTION_RENDERING__";
2
+ /**
3
+ * Resolve the environment. An explicit `override` (from `CompositionOptions.mode`)
4
+ * always wins; otherwise we detect from a global flag — Remotion reads
5
+ * `window.remotion_*`, we read `globalThis.__KONVA_MOTION_RENDERING__`, which a
6
+ * server renderer sets before constructing the composition.
7
+ */
8
+ export function detectEnvironment(override) {
9
+ const isRendering = override !== undefined
10
+ ? override === "rendering"
11
+ : globalThis[RENDERING_FLAG] === true;
12
+ return {
13
+ isRendering,
14
+ isPreview: !isRendering,
15
+ isClientSideRendering: false,
16
+ };
17
+ }
18
+ /**
19
+ * The environment of the Composition attached to `stage`, mirroring Remotion's
20
+ * `getRemotionEnvironment()`. Falls back to ambient detection if no Composition
21
+ * is attached.
22
+ */
23
+ export function getEnvironment(stage) {
24
+ const comp = stage.__SmooveComposition;
25
+ return comp?.environment ?? detectEnvironment();
26
+ }
27
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/engine/environment.ts"],"names":[],"mappings":"AAmBA,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAIpD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAA0B;IAC1D,MAAM,WAAW,GACf,QAAQ,KAAK,SAAS;QACpB,CAAC,CAAC,QAAQ,KAAK,WAAW;QAC1B,CAAC,CAAE,UAA8B,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;IAC/D,OAAO;QACL,WAAW;QACX,SAAS,EAAE,CAAC,WAAW;QACvB,qBAAqB,EAAE,KAAK;KAC7B,CAAC;AACJ,CAAC;AAKD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,MAAM,IAAI,GAAI,KAA4D,CAAC,mBAAmB,CAAC;IAC/F,OAAO,IAAI,EAAE,WAAW,IAAI,iBAAiB,EAAE,CAAC;AAClD,CAAC"}