@smoove/studio 0.1.1

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 (276) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/components/brand/brand.d.ts +9 -0
  4. package/dist/components/brand/brand.d.ts.map +1 -0
  5. package/dist/components/brand/brand.js +11 -0
  6. package/dist/components/brand/brand.js.map +1 -0
  7. package/dist/components/button/button.d.ts +21 -0
  8. package/dist/components/button/button.d.ts.map +1 -0
  9. package/dist/components/button/button.js +20 -0
  10. package/dist/components/button/button.js.map +1 -0
  11. package/dist/components/button/icon-button.d.ts +27 -0
  12. package/dist/components/button/icon-button.d.ts.map +1 -0
  13. package/dist/components/button/icon-button.js +19 -0
  14. package/dist/components/button/icon-button.js.map +1 -0
  15. package/dist/components/header/header-title.d.ts +8 -0
  16. package/dist/components/header/header-title.d.ts.map +1 -0
  17. package/dist/components/header/header-title.js +7 -0
  18. package/dist/components/header/header-title.js.map +1 -0
  19. package/dist/components/header/header.d.ts +7 -0
  20. package/dist/components/header/header.d.ts.map +1 -0
  21. package/dist/components/header/header.js +7 -0
  22. package/dist/components/header/header.js.map +1 -0
  23. package/dist/components/header/zoom.d.ts +3 -0
  24. package/dist/components/header/zoom.d.ts.map +1 -0
  25. package/dist/components/header/zoom.js +16 -0
  26. package/dist/components/header/zoom.js.map +1 -0
  27. package/dist/components/icon/icon.d.ts +11 -0
  28. package/dist/components/icon/icon.d.ts.map +1 -0
  29. package/dist/components/icon/icon.js +7 -0
  30. package/dist/components/icon/icon.js.map +1 -0
  31. package/dist/components/icon/paths.d.ts +47 -0
  32. package/dist/components/icon/paths.d.ts.map +1 -0
  33. package/dist/components/icon/paths.js +54 -0
  34. package/dist/components/icon/paths.js.map +1 -0
  35. package/dist/components/left-panel/library.d.ts +8 -0
  36. package/dist/components/left-panel/library.d.ts.map +1 -0
  37. package/dist/components/left-panel/library.js +49 -0
  38. package/dist/components/left-panel/library.js.map +1 -0
  39. package/dist/components/left-panel/sidebar-group.d.ts +12 -0
  40. package/dist/components/left-panel/sidebar-group.d.ts.map +1 -0
  41. package/dist/components/left-panel/sidebar-group.js +11 -0
  42. package/dist/components/left-panel/sidebar-group.js.map +1 -0
  43. package/dist/components/left-panel/sidebar-item.d.ts +17 -0
  44. package/dist/components/left-panel/sidebar-item.d.ts.map +1 -0
  45. package/dist/components/left-panel/sidebar-item.js +12 -0
  46. package/dist/components/left-panel/sidebar-item.js.map +1 -0
  47. package/dist/components/left-panel/sidebar.d.ts +8 -0
  48. package/dist/components/left-panel/sidebar.d.ts.map +1 -0
  49. package/dist/components/left-panel/sidebar.js +8 -0
  50. package/dist/components/left-panel/sidebar.js.map +1 -0
  51. package/dist/components/primitives/dialog.d.ts +33 -0
  52. package/dist/components/primitives/dialog.d.ts.map +1 -0
  53. package/dist/components/primitives/dialog.js +30 -0
  54. package/dist/components/primitives/dialog.js.map +1 -0
  55. package/dist/components/primitives/menu.d.ts +25 -0
  56. package/dist/components/primitives/menu.d.ts.map +1 -0
  57. package/dist/components/primitives/menu.js +31 -0
  58. package/dist/components/primitives/menu.js.map +1 -0
  59. package/dist/components/primitives/number-field.d.ts +12 -0
  60. package/dist/components/primitives/number-field.d.ts.map +1 -0
  61. package/dist/components/primitives/number-field.js +7 -0
  62. package/dist/components/primitives/number-field.js.map +1 -0
  63. package/dist/components/primitives/portal-context.d.ts +9 -0
  64. package/dist/components/primitives/portal-context.d.ts.map +1 -0
  65. package/dist/components/primitives/portal-context.js +10 -0
  66. package/dist/components/primitives/portal-context.js.map +1 -0
  67. package/dist/components/primitives/select.d.ts +14 -0
  68. package/dist/components/primitives/select.d.ts.map +1 -0
  69. package/dist/components/primitives/select.js +11 -0
  70. package/dist/components/primitives/select.js.map +1 -0
  71. package/dist/components/primitives/slider.d.ts +10 -0
  72. package/dist/components/primitives/slider.d.ts.map +1 -0
  73. package/dist/components/primitives/slider.js +7 -0
  74. package/dist/components/primitives/slider.js.map +1 -0
  75. package/dist/components/primitives/switch.d.ts +5 -0
  76. package/dist/components/primitives/switch.d.ts.map +1 -0
  77. package/dist/components/primitives/switch.js +6 -0
  78. package/dist/components/primitives/switch.js.map +1 -0
  79. package/dist/components/primitives/tabs.d.ts +23 -0
  80. package/dist/components/primitives/tabs.d.ts.map +1 -0
  81. package/dist/components/primitives/tabs.js +17 -0
  82. package/dist/components/primitives/tabs.js.map +1 -0
  83. package/dist/components/primitives/tooltip.d.ts +9 -0
  84. package/dist/components/primitives/tooltip.d.ts.map +1 -0
  85. package/dist/components/primitives/tooltip.js +11 -0
  86. package/dist/components/primitives/tooltip.js.map +1 -0
  87. package/dist/components/render/export-frame-dialog.d.ts +8 -0
  88. package/dist/components/render/export-frame-dialog.d.ts.map +1 -0
  89. package/dist/components/render/export-frame-dialog.js +60 -0
  90. package/dist/components/render/export-frame-dialog.js.map +1 -0
  91. package/dist/components/render/render-dialog.d.ts +8 -0
  92. package/dist/components/render/render-dialog.d.ts.map +1 -0
  93. package/dist/components/render/render-dialog.js +95 -0
  94. package/dist/components/render/render-dialog.js.map +1 -0
  95. package/dist/components/render/render-queue.d.ts +5 -0
  96. package/dist/components/render/render-queue.d.ts.map +1 -0
  97. package/dist/components/render/render-queue.js +40 -0
  98. package/dist/components/render/render-queue.js.map +1 -0
  99. package/dist/components/right-panel/panel-handle.d.ts +3 -0
  100. package/dist/components/right-panel/panel-handle.d.ts.map +1 -0
  101. package/dist/components/right-panel/panel-handle.js +9 -0
  102. package/dist/components/right-panel/panel-handle.js.map +1 -0
  103. package/dist/components/right-panel/panel-tabs.d.ts +3 -0
  104. package/dist/components/right-panel/panel-tabs.d.ts.map +1 -0
  105. package/dist/components/right-panel/panel-tabs.js +26 -0
  106. package/dist/components/right-panel/panel-tabs.js.map +1 -0
  107. package/dist/components/right-panel/panel.d.ts +8 -0
  108. package/dist/components/right-panel/panel.d.ts.map +1 -0
  109. package/dist/components/right-panel/panel.js +16 -0
  110. package/dist/components/right-panel/panel.js.map +1 -0
  111. package/dist/components/schema-form/field.d.ts +9 -0
  112. package/dist/components/schema-form/field.d.ts.map +1 -0
  113. package/dist/components/schema-form/field.js +102 -0
  114. package/dist/components/schema-form/field.js.map +1 -0
  115. package/dist/components/schema-form/schema-form.d.ts +3 -0
  116. package/dist/components/schema-form/schema-form.d.ts.map +1 -0
  117. package/dist/components/schema-form/schema-form.js +18 -0
  118. package/dist/components/schema-form/schema-form.js.map +1 -0
  119. package/dist/components/stage/stage.d.ts +12 -0
  120. package/dist/components/stage/stage.d.ts.map +1 -0
  121. package/dist/components/stage/stage.js +103 -0
  122. package/dist/components/stage/stage.js.map +1 -0
  123. package/dist/components/studio/features.d.ts +4 -0
  124. package/dist/components/studio/features.d.ts.map +1 -0
  125. package/dist/components/studio/features.js +18 -0
  126. package/dist/components/studio/features.js.map +1 -0
  127. package/dist/components/studio/layout.d.ts +19 -0
  128. package/dist/components/studio/layout.d.ts.map +1 -0
  129. package/dist/components/studio/layout.js +17 -0
  130. package/dist/components/studio/layout.js.map +1 -0
  131. package/dist/components/studio/studio-context.d.ts +53 -0
  132. package/dist/components/studio/studio-context.d.ts.map +1 -0
  133. package/dist/components/studio/studio-context.js +3 -0
  134. package/dist/components/studio/studio-context.js.map +1 -0
  135. package/dist/components/studio/studio.d.ts +21 -0
  136. package/dist/components/studio/studio.d.ts.map +1 -0
  137. package/dist/components/studio/studio.js +38 -0
  138. package/dist/components/studio/studio.js.map +1 -0
  139. package/dist/components/timeline/layered-body.d.ts +8 -0
  140. package/dist/components/timeline/layered-body.d.ts.map +1 -0
  141. package/dist/components/timeline/layered-body.js +75 -0
  142. package/dist/components/timeline/layered-body.js.map +1 -0
  143. package/dist/components/timeline/region-handles.d.ts +8 -0
  144. package/dist/components/timeline/region-handles.d.ts.map +1 -0
  145. package/dist/components/timeline/region-handles.js +13 -0
  146. package/dist/components/timeline/region-handles.js.map +1 -0
  147. package/dist/components/timeline/ruler.d.ts +7 -0
  148. package/dist/components/timeline/ruler.d.ts.map +1 -0
  149. package/dist/components/timeline/ruler.js +19 -0
  150. package/dist/components/timeline/ruler.js.map +1 -0
  151. package/dist/components/timeline/scrubber.d.ts +6 -0
  152. package/dist/components/timeline/scrubber.d.ts.map +1 -0
  153. package/dist/components/timeline/scrubber.js +25 -0
  154. package/dist/components/timeline/scrubber.js.map +1 -0
  155. package/dist/components/timeline/timeline-header.d.ts +3 -0
  156. package/dist/components/timeline/timeline-header.d.ts.map +1 -0
  157. package/dist/components/timeline/timeline-header.js +36 -0
  158. package/dist/components/timeline/timeline-header.js.map +1 -0
  159. package/dist/components/timeline/timeline.d.ts +5 -0
  160. package/dist/components/timeline/timeline.d.ts.map +1 -0
  161. package/dist/components/timeline/timeline.js +16 -0
  162. package/dist/components/timeline/timeline.js.map +1 -0
  163. package/dist/components/timeline/transport.d.ts +5 -0
  164. package/dist/components/timeline/transport.d.ts.map +1 -0
  165. package/dist/components/timeline/transport.js +21 -0
  166. package/dist/components/timeline/transport.js.map +1 -0
  167. package/dist/components/timeline/use-scrub-surface.d.ts +20 -0
  168. package/dist/components/timeline/use-scrub-surface.d.ts.map +1 -0
  169. package/dist/components/timeline/use-scrub-surface.js +56 -0
  170. package/dist/components/timeline/use-scrub-surface.js.map +1 -0
  171. package/dist/components/toasts/toasts.d.ts +4 -0
  172. package/dist/components/toasts/toasts.d.ts.map +1 -0
  173. package/dist/components/toasts/toasts.js +22 -0
  174. package/dist/components/toasts/toasts.js.map +1 -0
  175. package/dist/hooks/use-composition.d.ts +10 -0
  176. package/dist/hooks/use-composition.d.ts.map +1 -0
  177. package/dist/hooks/use-composition.js +13 -0
  178. package/dist/hooks/use-composition.js.map +1 -0
  179. package/dist/hooks/use-layers.d.ts +9 -0
  180. package/dist/hooks/use-layers.d.ts.map +1 -0
  181. package/dist/hooks/use-layers.js +34 -0
  182. package/dist/hooks/use-layers.js.map +1 -0
  183. package/dist/hooks/use-playback.d.ts +15 -0
  184. package/dist/hooks/use-playback.d.ts.map +1 -0
  185. package/dist/hooks/use-playback.js +38 -0
  186. package/dist/hooks/use-playback.js.map +1 -0
  187. package/dist/hooks/use-props-form.d.ts +15 -0
  188. package/dist/hooks/use-props-form.d.ts.map +1 -0
  189. package/dist/hooks/use-props-form.js +22 -0
  190. package/dist/hooks/use-props-form.js.map +1 -0
  191. package/dist/hooks/use-real-fps.d.ts +3 -0
  192. package/dist/hooks/use-real-fps.d.ts.map +1 -0
  193. package/dist/hooks/use-real-fps.js +27 -0
  194. package/dist/hooks/use-real-fps.js.map +1 -0
  195. package/dist/hooks/use-shortcuts.d.ts +7 -0
  196. package/dist/hooks/use-shortcuts.d.ts.map +1 -0
  197. package/dist/hooks/use-shortcuts.js +53 -0
  198. package/dist/hooks/use-shortcuts.js.map +1 -0
  199. package/dist/hooks/use-studio.d.ts +4 -0
  200. package/dist/hooks/use-studio.d.ts.map +1 -0
  201. package/dist/hooks/use-studio.js +10 -0
  202. package/dist/hooks/use-studio.js.map +1 -0
  203. package/dist/index.d.ts +145 -0
  204. package/dist/index.d.ts.map +1 -0
  205. package/dist/index.js +117 -0
  206. package/dist/index.js.map +1 -0
  207. package/dist/lib/cn.d.ts +3 -0
  208. package/dist/lib/cn.d.ts.map +1 -0
  209. package/dist/lib/cn.js +8 -0
  210. package/dist/lib/cn.js.map +1 -0
  211. package/dist/lib/constants.d.ts +28 -0
  212. package/dist/lib/constants.d.ts.map +1 -0
  213. package/dist/lib/constants.js +38 -0
  214. package/dist/lib/constants.js.map +1 -0
  215. package/dist/lib/cva.d.ts +25 -0
  216. package/dist/lib/cva.d.ts.map +1 -0
  217. package/dist/lib/cva.js +23 -0
  218. package/dist/lib/cva.js.map +1 -0
  219. package/dist/lib/format.d.ts +13 -0
  220. package/dist/lib/format.d.ts.map +1 -0
  221. package/dist/lib/format.js +25 -0
  222. package/dist/lib/format.js.map +1 -0
  223. package/dist/lib/ids.d.ts +3 -0
  224. package/dist/lib/ids.d.ts.map +1 -0
  225. package/dist/lib/ids.js +6 -0
  226. package/dist/lib/ids.js.map +1 -0
  227. package/dist/registry/define-registry.d.ts +8 -0
  228. package/dist/registry/define-registry.d.ts.map +1 -0
  229. package/dist/registry/define-registry.js +71 -0
  230. package/dist/registry/define-registry.js.map +1 -0
  231. package/dist/registry/props-signal.d.ts +9 -0
  232. package/dist/registry/props-signal.d.ts.map +1 -0
  233. package/dist/registry/props-signal.js +25 -0
  234. package/dist/registry/props-signal.js.map +1 -0
  235. package/dist/schema/kf.d.ts +28 -0
  236. package/dist/schema/kf.d.ts.map +1 -0
  237. package/dist/schema/kf.js +82 -0
  238. package/dist/schema/kf.js.map +1 -0
  239. package/dist/schema/types.d.ts +69 -0
  240. package/dist/schema/types.d.ts.map +1 -0
  241. package/dist/schema/types.js +4 -0
  242. package/dist/schema/types.js.map +1 -0
  243. package/dist/server/index.d.ts +6 -0
  244. package/dist/server/index.d.ts.map +1 -0
  245. package/dist/server/index.js +7 -0
  246. package/dist/server/index.js.map +1 -0
  247. package/dist/server/map.d.ts +19 -0
  248. package/dist/server/map.d.ts.map +1 -0
  249. package/dist/server/map.js +63 -0
  250. package/dist/server/map.js.map +1 -0
  251. package/dist/server/render-queue.d.ts +46 -0
  252. package/dist/server/render-queue.d.ts.map +1 -0
  253. package/dist/server/render-queue.js +147 -0
  254. package/dist/server/render-queue.js.map +1 -0
  255. package/dist/server/temp-storage.d.ts +13 -0
  256. package/dist/server/temp-storage.d.ts.map +1 -0
  257. package/dist/server/temp-storage.js +55 -0
  258. package/dist/server/temp-storage.js.map +1 -0
  259. package/dist/server/types.d.ts +57 -0
  260. package/dist/server/types.d.ts.map +1 -0
  261. package/dist/server/types.js +2 -0
  262. package/dist/server/types.js.map +1 -0
  263. package/dist/signals/signal-bridge.d.ts +18 -0
  264. package/dist/signals/signal-bridge.d.ts.map +1 -0
  265. package/dist/signals/signal-bridge.js +39 -0
  266. package/dist/signals/signal-bridge.js.map +1 -0
  267. package/dist/store/store.d.ts +74 -0
  268. package/dist/store/store.d.ts.map +1 -0
  269. package/dist/store/store.js +276 -0
  270. package/dist/store/store.js.map +1 -0
  271. package/dist/styles/studio.css +2 -0
  272. package/dist/types.d.ts +112 -0
  273. package/dist/types.d.ts.map +1 -0
  274. package/dist/types.js +2 -0
  275. package/dist/types.js.map +1 -0
  276. package/package.json +66 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A minimal writable signal matching core's `ReadonlySignal` shape (get +
3
+ * subscribe) plus `set`. React-free and Node-safe. An entry's `load` receives
4
+ * the readable side and reads `props.get()` in updaters / subscribes to re-apply
5
+ * the current frame; the studio holds the writable side and pushes form edits.
6
+ */
7
+ export function createPropsSignal(initial) {
8
+ let value = initial;
9
+ const listeners = new Set();
10
+ return {
11
+ get: () => value,
12
+ set(next) {
13
+ value = next;
14
+ for (const fn of listeners)
15
+ fn(value);
16
+ },
17
+ subscribe(listener) {
18
+ listeners.add(listener);
19
+ return () => {
20
+ listeners.delete(listener);
21
+ };
22
+ },
23
+ };
24
+ }
25
+ //# sourceMappingURL=props-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"props-signal.js","sourceRoot":"","sources":["../../src/registry/props-signal.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAI,OAAU;IAC7C,IAAI,KAAK,GAAG,OAAO,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;QAChB,GAAG,CAAC,IAAO;YACT,KAAK,GAAG,IAAI,CAAC;YACb,KAAK,MAAM,EAAE,IAAI,SAAS;gBAAE,EAAE,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;QACD,SAAS,CAAC,QAAwB;YAChC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { ArrayField, BooleanField, ColorField, DividerField, MultilineField, MultiselectField, NumberField, ObjectField, SelectField, SmooveField, SmooveSchema, TextField } from "./types.js";
2
+ /**
3
+ * `kf` — the studio's field-descriptor builder. Each call returns a plain
4
+ * descriptor object; `kf.object({...})` is the top-level schema you attach to a
5
+ * registry entry's `propsSchema`. The form renders these and writes values back
6
+ * into the composition's props signal.
7
+ */
8
+ export declare const kf: {
9
+ text: (o?: Omit<TextField, "type">) => TextField;
10
+ multiline: (o?: Omit<MultilineField, "type">) => MultilineField;
11
+ color: (o?: Omit<ColorField, "type">) => ColorField;
12
+ boolean: (o?: Omit<BooleanField, "type">) => BooleanField;
13
+ number: (o?: Omit<NumberField, "type">) => NumberField;
14
+ select: (o: Omit<SelectField, "type">) => SelectField;
15
+ multiselect: (o: Omit<MultiselectField, "type">) => MultiselectField;
16
+ divider: (o?: Omit<DividerField, "type">) => DividerField;
17
+ object: (o: Omit<ObjectField, "type">) => ObjectField;
18
+ array: (o: Omit<ArrayField, "type">) => ArrayField;
19
+ };
20
+ /** Fields with a value (everything but dividers) — used by the form + defaults. */
21
+ export declare function isValueField(f: SmooveField): f is Exclude<SmooveField, DividerField>;
22
+ /** Derive a default value for a single field. */
23
+ export declare function defaultForField(field: SmooveField): unknown;
24
+ /** Build the default value record for an object schema (skips dividers). */
25
+ export declare function defaultsFor(schema: ObjectField): Record<string, unknown>;
26
+ /** Defaults for a schema, deep-merged with caller-supplied overrides. */
27
+ export declare function resolveDefaults(schema: SmooveSchema | undefined, overrides?: Record<string, unknown>): Record<string, unknown>;
28
+ //# sourceMappingURL=kf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kf.d.ts","sourceRoot":"","sources":["../../src/schema/kf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACV,MAAM,YAAY,CAAC;AAEpB;;;;;GAKG;AACH,eAAO,MAAM,EAAE;eACH,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,KAAQ,SAAS;oBACnC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,KAAQ,cAAc;gBAItD,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,KAAQ,UAAU;kBACxC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,KAAQ,YAAY;iBAC/C,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,KAAQ,WAAW;gBAC5C,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,KAAG,WAAW;qBAClC,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,KAAG,gBAAgB;kBAIrD,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,KAAQ,YAAY;gBAC/C,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,KAAG,WAAW;eACxC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,KAAG,UAAU;CACjD,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAEpF;AAED,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAsB3D;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOxE;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAC7B,MAAM,EAAE,YAAY,GAAG,SAAS,EAChC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * `kf` — the studio's field-descriptor builder. Each call returns a plain
3
+ * descriptor object; `kf.object({...})` is the top-level schema you attach to a
4
+ * registry entry's `propsSchema`. The form renders these and writes values back
5
+ * into the composition's props signal.
6
+ */
7
+ export const kf = {
8
+ text: (o = {}) => ({ type: "text", ...o }),
9
+ multiline: (o = {}) => ({
10
+ type: "multiline",
11
+ ...o,
12
+ }),
13
+ color: (o = {}) => ({ type: "color", ...o }),
14
+ boolean: (o = {}) => ({ type: "boolean", ...o }),
15
+ number: (o = {}) => ({ type: "number", ...o }),
16
+ select: (o) => ({ type: "select", ...o }),
17
+ multiselect: (o) => ({
18
+ type: "multiselect",
19
+ ...o,
20
+ }),
21
+ divider: (o = {}) => ({ type: "divider", ...o }),
22
+ object: (o) => ({ type: "object", ...o }),
23
+ array: (o) => ({ type: "array", ...o }),
24
+ };
25
+ /** Fields with a value (everything but dividers) — used by the form + defaults. */
26
+ export function isValueField(f) {
27
+ return f.type !== "divider";
28
+ }
29
+ /** Derive a default value for a single field. */
30
+ export function defaultForField(field) {
31
+ switch (field.type) {
32
+ case "divider":
33
+ return undefined;
34
+ case "text":
35
+ case "multiline":
36
+ return field.default ?? "";
37
+ case "color":
38
+ return field.default ?? "#ffffff";
39
+ case "boolean":
40
+ return field.default ?? false;
41
+ case "number":
42
+ return field.default ?? field.min ?? 0;
43
+ case "select":
44
+ return field.default ?? field.options[0]?.value ?? "";
45
+ case "multiselect":
46
+ return field.default ?? [];
47
+ case "object":
48
+ return defaultsFor(field);
49
+ case "array":
50
+ return field.default ? [...field.default] : [];
51
+ }
52
+ }
53
+ /** Build the default value record for an object schema (skips dividers). */
54
+ export function defaultsFor(schema) {
55
+ const out = {};
56
+ for (const [key, field] of Object.entries(schema.fields)) {
57
+ if (!isValueField(field))
58
+ continue;
59
+ out[key] = defaultForField(field);
60
+ }
61
+ return out;
62
+ }
63
+ /** Defaults for a schema, deep-merged with caller-supplied overrides. */
64
+ export function resolveDefaults(schema, overrides) {
65
+ const base = schema ? defaultsFor(schema) : {};
66
+ return overrides ? deepMerge(base, overrides) : base;
67
+ }
68
+ function deepMerge(base, over) {
69
+ const out = { ...base };
70
+ for (const [k, v] of Object.entries(over)) {
71
+ const prev = out[k];
72
+ if (isPlainObject(prev) && isPlainObject(v))
73
+ out[k] = deepMerge(prev, v);
74
+ else
75
+ out[k] = v; // arrays + primitives replace
76
+ }
77
+ return out;
78
+ }
79
+ function isPlainObject(x) {
80
+ return typeof x === "object" && x !== null && !Array.isArray(x);
81
+ }
82
+ //# sourceMappingURL=kf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kf.js","sourceRoot":"","sources":["../../src/schema/kf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /** Field descriptors that drive the schema-driven props form. Authored fresh
2
+ for the studio (a lightweight, typed descriptor DSL — see `kf`). */
3
+ export type FieldBase = {
4
+ label?: string;
5
+ description?: string;
6
+ };
7
+ export type TextField = FieldBase & {
8
+ type: "text";
9
+ default?: string;
10
+ placeholder?: string;
11
+ };
12
+ export type MultilineField = FieldBase & {
13
+ type: "multiline";
14
+ default?: string;
15
+ placeholder?: string;
16
+ rows?: number;
17
+ };
18
+ export type ColorField = FieldBase & {
19
+ type: "color";
20
+ default?: string;
21
+ /** Preset swatches shown alongside the hex input. */
22
+ swatches?: string[];
23
+ };
24
+ export type BooleanField = FieldBase & {
25
+ type: "boolean";
26
+ default?: boolean;
27
+ };
28
+ export type NumberField = FieldBase & {
29
+ type: "number";
30
+ default?: number;
31
+ min?: number;
32
+ max?: number;
33
+ step?: number;
34
+ unit?: string;
35
+ };
36
+ export type SelectOption = {
37
+ value: string;
38
+ label: string;
39
+ };
40
+ export type SelectField = FieldBase & {
41
+ type: "select";
42
+ default?: string;
43
+ options: SelectOption[];
44
+ };
45
+ export type MultiselectField = FieldBase & {
46
+ type: "multiselect";
47
+ default?: string[];
48
+ options: SelectOption[];
49
+ };
50
+ export type DividerField = {
51
+ type: "divider";
52
+ label?: string;
53
+ };
54
+ export type ObjectField = FieldBase & {
55
+ type: "object";
56
+ fields: Record<string, SmooveField>;
57
+ };
58
+ export type ArrayField = FieldBase & {
59
+ type: "array";
60
+ of: SmooveField;
61
+ default?: unknown[];
62
+ min?: number;
63
+ max?: number;
64
+ itemLabel?: string;
65
+ };
66
+ export type SmooveField = TextField | MultilineField | ColorField | BooleanField | NumberField | SelectField | MultiselectField | DividerField | ObjectField | ArrayField;
67
+ /** The top-level schema is always an object of fields. */
68
+ export type SmooveSchema = ObjectField;
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA;uEACuE;AAEvE,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG;IACvC,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG;IACrC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG;IACzC,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,WAAW,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,cAAc,GACd,UAAU,GACV,YAAY,GACZ,WAAW,GACX,WAAW,GACX,gBAAgB,GAChB,YAAY,GACZ,WAAW,GACX,UAAU,CAAC;AAEf,0DAA0D;AAC1D,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** Field descriptors that drive the schema-driven props form. Authored fresh
2
+ for the studio (a lightweight, typed descriptor DSL — see `kf`). */
3
+ export {};
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA;uEACuE"}
@@ -0,0 +1,6 @@
1
+ export { qualityPreset, stillMeta, toRenderOptions, toStillOptions, videoMeta, } from "./map.js";
2
+ export type { CreateRenderQueueOptions, RenderQueue } from "./render-queue.js";
3
+ export { createRenderQueue } from "./render-queue.js";
4
+ export { createTempStorage } from "./temp-storage.js";
5
+ export type { RenderQueueJob, RenderStorage, StoredArtifact } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EACb,SAAS,EACT,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ // Server-side render kit for @smoove/studio. Node-only (imports
2
+ // @smoove/renderer + node:*). Contracts + mappers + an in-memory queue —
3
+ // NO HTTP. A host wires the transport (see the demo's resource routes).
4
+ export { qualityPreset, stillMeta, toRenderOptions, toStillOptions, videoMeta, } from "./map.js";
5
+ export { createRenderQueue } from "./render-queue.js";
6
+ export { createTempStorage } from "./temp-storage.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,yEAAyE;AACzE,wEAAwE;AAExE,OAAO,EACL,aAAa,EACb,SAAS,EACT,eAAe,EACf,cAAc,EACd,SAAS,GACV,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { QualityPreset, RenderOptions, StillOptions } from "@smoove/renderer";
2
+ import type { RenderRequest } from "../types.js";
3
+ export declare function qualityPreset(quality: string): QualityPreset;
4
+ /** Container metadata for a video format request. */
5
+ export declare function videoMeta(format: string): {
6
+ ext: string;
7
+ contentType: string;
8
+ };
9
+ /** Image metadata for a still format request. */
10
+ export declare function stillMeta(format: string): {
11
+ ext: string;
12
+ contentType: string;
13
+ type: "png" | "jpeg";
14
+ };
15
+ /** A video {@link RenderRequest} → `renderComposition` options writing to `output`. */
16
+ export declare function toRenderOptions(req: RenderRequest, output: string): RenderOptions;
17
+ /** A still {@link RenderRequest} → `renderStill` options writing to `output`. */
18
+ export declare function toStillOptions(req: RenderRequest, output: string): StillOptions;
19
+ //# sourceMappingURL=map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../../src/server/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgBjD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAE5D;AAED,qDAAqD;AACrD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAS9E;AAED,iDAAiD;AACjD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;CACtB,CASA;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAajF;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAO/E"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Pure mappers from the studio-side {@link RenderRequest} to the renderer's
3
+ * option shapes. No I/O, no HTTP — just translation, so a host (or another
4
+ * runtime) can reuse them without pulling in any transport assumptions.
5
+ */
6
+ /** Studio quality string → renderer encode preset. */
7
+ const QUALITY_BY_NAME = {
8
+ draft: "low",
9
+ standard: "medium",
10
+ high: "high",
11
+ lossless: "max",
12
+ };
13
+ export function qualityPreset(quality) {
14
+ return QUALITY_BY_NAME[quality] ?? "medium";
15
+ }
16
+ /** Container metadata for a video format request. */
17
+ export function videoMeta(format) {
18
+ switch (format) {
19
+ case "webm":
20
+ return { ext: "webm", contentType: "video/webm" };
21
+ case "mov":
22
+ return { ext: "mov", contentType: "video/quicktime" };
23
+ default:
24
+ return { ext: "mp4", contentType: "video/mp4" };
25
+ }
26
+ }
27
+ /** Image metadata for a still format request. */
28
+ export function stillMeta(format) {
29
+ switch (format) {
30
+ case "jpeg":
31
+ case "jpg":
32
+ return { ext: "jpg", contentType: "image/jpeg", type: "jpeg" };
33
+ default:
34
+ // The renderer rasterizes png/jpeg only; anything else falls back to PNG.
35
+ return { ext: "png", contentType: "image/png", type: "png" };
36
+ }
37
+ }
38
+ /** A video {@link RenderRequest} → `renderComposition` options writing to `output`. */
39
+ export function toRenderOptions(req, output) {
40
+ const opts = {
41
+ output,
42
+ resolution: { width: req.w, height: req.h },
43
+ fps: req.fps,
44
+ quality: qualityPreset(req.quality),
45
+ // The renderer encodes mp4 (H.264/AAC) or webm (VP9/Opus); other containers
46
+ // (e.g. mov) fall back to mp4.
47
+ format: videoMeta(req.format).ext === "webm" ? "webm" : "mp4",
48
+ };
49
+ // `to` is inclusive in both the studio region and the renderer's FrameRange.
50
+ if (req.from != null && req.to != null)
51
+ opts.range = { from: req.from, to: req.to };
52
+ return opts;
53
+ }
54
+ /** A still {@link RenderRequest} → `renderStill` options writing to `output`. */
55
+ export function toStillOptions(req, output) {
56
+ return {
57
+ frame: req.frameNo ?? 0,
58
+ output,
59
+ resolution: { width: req.w, height: req.h },
60
+ type: stillMeta(req.format).type,
61
+ };
62
+ }
63
+ //# sourceMappingURL=map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.js","sourceRoot":"","sources":["../../src/server/map.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,sDAAsD;AACtD,MAAM,eAAe,GAAkC;IACrD,KAAK,EAAE,KAAK;IACZ,QAAQ,EAAE,QAAQ;IAClB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,KAAK;CAChB,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO,eAAe,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC;AAC9C,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;QACpD,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,CAAC;QACxD;YACE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;IACpD,CAAC;AACH,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,SAAS,CAAC,MAAc;IAKtC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM,CAAC;QACZ,KAAK,KAAK;YACR,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACjE;YACE,0EAA0E;YAC1E,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACjE,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,GAAkB,EAAE,MAAc;IAChE,MAAM,IAAI,GAAkB;QAC1B,MAAM;QACN,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE;QAC3C,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC;QACnC,4EAA4E;QAC5E,+BAA+B;QAC/B,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;KAC9D,CAAC;IACF,6EAA6E;IAC7E,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI;QAAE,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC;IACpF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,GAAkB,EAAE,MAAc;IAC/D,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,OAAO,IAAI,CAAC;QACvB,MAAM;QACN,UAAU,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE;QAC3C,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI;KACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { Composition } from "@smoove/core";
2
+ import { type SetupOptions } from "@smoove/renderer";
3
+ import type { RenderRequest } from "../types.js";
4
+ import type { RenderQueueJob, RenderStorage, StoredArtifact } from "./types.js";
5
+ export interface CreateRenderQueueOptions {
6
+ /**
7
+ * Turn a request into a rendering-mode {@link Composition} with its props
8
+ * applied. MUST resolve a composition built AFTER `setupServerRendering()` ran
9
+ * (the queue calls it before `resolve`), so the engine is in rendering mode.
10
+ */
11
+ resolve: (req: RenderRequest) => Promise<Composition>;
12
+ /** Where artifacts are written. Default: {@link createTempStorage}. */
13
+ storage?: RenderStorage;
14
+ /** Forwarded to `setupServerRendering` once on first render (fonts, etc.). */
15
+ setup?: SetupOptions;
16
+ /**
17
+ * Max renders running at once. Default 1 — safe when `resolve` returns a
18
+ * cached/module-singleton composition, since a render mutates frame state.
19
+ */
20
+ concurrency?: number;
21
+ }
22
+ export interface RenderQueue {
23
+ /** Create a job and kick off its render. Returns the queued job immediately. */
24
+ enqueue(req: RenderRequest): RenderQueueJob;
25
+ get(jobId: string): RenderQueueJob | undefined;
26
+ list(): RenderQueueJob[];
27
+ /** Abort an in-flight (or not-yet-started) job. */
28
+ cancel(jobId: string): void;
29
+ /** Forget a job and drop its artifact. */
30
+ remove(jobId: string): Promise<void>;
31
+ /**
32
+ * Listen for changes to one job. The current state is delivered synchronously
33
+ * on subscribe, then again on every update. Returns an unsubscribe function.
34
+ */
35
+ subscribe(jobId: string, fn: (job: RenderQueueJob) => void): () => void;
36
+ /** The finished artifact for a job, or null. */
37
+ download(jobId: string): Promise<StoredArtifact | null>;
38
+ }
39
+ /**
40
+ * An in-memory render queue — the only implementation the package ships. It
41
+ * owns nothing HTTP: it runs renders via `@smoove/renderer`, tracks job
42
+ * state, and pushes progress to subscribers. A host wraps it in whatever
43
+ * transport it likes (the demo: React Router resource routes + SSE).
44
+ */
45
+ export declare function createRenderQueue(opts: CreateRenderQueueOptions): RenderQueue;
46
+ //# sourceMappingURL=render-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-queue.d.ts","sourceRoot":"","sources":["../../src/server/render-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAGL,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEhF,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,uEAAuE;IACvE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,OAAO,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAAC;IAC5C,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAC/C,IAAI,IAAI,cAAc,EAAE,CAAC;IACzB,mDAAmD;IACnD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0CAA0C;IAC1C,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACxE,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACzD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,WAAW,CA2I7E"}
@@ -0,0 +1,147 @@
1
+ import { renderComposition, renderStill, setupServerRendering, } from "@smoove/renderer";
2
+ import { makeJobId } from "../lib/ids.js";
3
+ import { stillMeta, toRenderOptions, toStillOptions, videoMeta } from "./map.js";
4
+ import { createTempStorage } from "./temp-storage.js";
5
+ /**
6
+ * An in-memory render queue — the only implementation the package ships. It
7
+ * owns nothing HTTP: it runs renders via `@smoove/renderer`, tracks job
8
+ * state, and pushes progress to subscribers. A host wraps it in whatever
9
+ * transport it likes (the demo: React Router resource routes + SSE).
10
+ */
11
+ export function createRenderQueue(opts) {
12
+ const storage = opts.storage ?? createTempStorage();
13
+ const concurrency = Math.max(1, opts.concurrency ?? 1);
14
+ const jobs = new Map();
15
+ const listeners = new Map();
16
+ const aborts = new Map();
17
+ // ---- concurrency gate ----------------------------------------------------
18
+ let active = 0;
19
+ const waiting = [];
20
+ const pump = () => {
21
+ while (active < concurrency && waiting.length > 0) {
22
+ active++;
23
+ const run = waiting.shift();
24
+ run?.();
25
+ }
26
+ };
27
+ const release = () => {
28
+ active--;
29
+ pump();
30
+ };
31
+ // ---- setup (once) --------------------------------------------------------
32
+ let didSetup = false;
33
+ const ensureSetup = () => {
34
+ if (didSetup)
35
+ return;
36
+ setupServerRendering(opts.setup);
37
+ didSetup = true;
38
+ };
39
+ // ---- state notify --------------------------------------------------------
40
+ const emit = (jobId) => {
41
+ const job = jobs.get(jobId);
42
+ if (!job)
43
+ return;
44
+ const set = listeners.get(jobId);
45
+ if (!set)
46
+ return;
47
+ for (const fn of set)
48
+ fn(job);
49
+ };
50
+ const update = (jobId, patch) => {
51
+ const job = jobs.get(jobId);
52
+ if (!job)
53
+ return;
54
+ jobs.set(jobId, { ...job, ...patch });
55
+ emit(jobId);
56
+ };
57
+ // ---- the render --------------------------------------------------------
58
+ const run = async (jobId) => {
59
+ const job = jobs.get(jobId);
60
+ if (!job || job.status === "canceled")
61
+ return;
62
+ const ac = new AbortController();
63
+ aborts.set(jobId, ac);
64
+ update(jobId, { status: "rendering" });
65
+ try {
66
+ const comp = await opts.resolve(job.request);
67
+ if (ac.signal.aborted)
68
+ return;
69
+ const meta = job.request.kind === "still"
70
+ ? stillMeta(job.request.format)
71
+ : videoMeta(job.request.format);
72
+ const { path, finalize } = await storage.put(jobId, {
73
+ ext: meta.ext,
74
+ contentType: meta.contentType,
75
+ filename: `${job.request.id}.${meta.ext}`,
76
+ });
77
+ if (job.request.kind === "still") {
78
+ await renderStill(comp, toStillOptions(job.request, path));
79
+ }
80
+ else {
81
+ await renderComposition(comp, {
82
+ ...toRenderOptions(job.request, path),
83
+ signal: ac.signal,
84
+ onProgress: (p) => update(jobId, { progress: p.total ? p.frame / p.total : 0 }),
85
+ });
86
+ }
87
+ await finalize();
88
+ update(jobId, { status: "done", progress: 1, result: jobId });
89
+ }
90
+ catch (err) {
91
+ if (jobs.get(jobId)?.status === "canceled")
92
+ return;
93
+ update(jobId, { status: "error", error: err instanceof Error ? err.message : String(err) });
94
+ }
95
+ finally {
96
+ aborts.delete(jobId);
97
+ }
98
+ };
99
+ return {
100
+ enqueue(req) {
101
+ ensureSetup();
102
+ const job = {
103
+ jobId: makeJobId(),
104
+ status: "queued",
105
+ progress: 0,
106
+ request: req,
107
+ createdAt: Date.now(),
108
+ };
109
+ jobs.set(job.jobId, job);
110
+ waiting.push(() => {
111
+ void run(job.jobId).finally(release);
112
+ });
113
+ pump();
114
+ return job;
115
+ },
116
+ get: (jobId) => jobs.get(jobId),
117
+ list: () => [...jobs.values()],
118
+ cancel(jobId) {
119
+ const job = jobs.get(jobId);
120
+ if (!job || job.status === "done" || job.status === "error")
121
+ return;
122
+ aborts.get(jobId)?.abort();
123
+ update(jobId, { status: "canceled" });
124
+ },
125
+ async remove(jobId) {
126
+ jobs.delete(jobId);
127
+ listeners.delete(jobId);
128
+ await storage.remove(jobId);
129
+ },
130
+ subscribe(jobId, fn) {
131
+ let set = listeners.get(jobId);
132
+ if (!set) {
133
+ set = new Set();
134
+ listeners.set(jobId, set);
135
+ }
136
+ set.add(fn);
137
+ const current = jobs.get(jobId);
138
+ if (current)
139
+ fn(current);
140
+ return () => {
141
+ set?.delete(fn);
142
+ };
143
+ },
144
+ download: (jobId) => storage.get(jobId),
145
+ };
146
+ }
147
+ //# sourceMappingURL=render-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-queue.js","sourceRoot":"","sources":["../../src/server/render-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { RenderStorage } from "./types.js";
2
+ /**
3
+ * The default {@link RenderStorage}: artifacts live as files under a directory
4
+ * in the server's temp space (`os.tmpdir()/smoove-renders` by default).
5
+ *
6
+ * The renderer writes directly to the file path returned by `put()`, so this is
7
+ * a thin shim over the filesystem — no copy on the hot path. A host that needs
8
+ * durable/remote storage implements the `RenderStorage` contract instead.
9
+ */
10
+ export declare function createTempStorage(opts?: {
11
+ dir?: string;
12
+ }): RenderStorage;
13
+ //# sourceMappingURL=temp-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temp-storage.d.ts","sourceRoot":"","sources":["../../src/server/temp-storage.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,YAAY,CAAC;AAEhE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,aAAa,CAyC5E"}
@@ -0,0 +1,55 @@
1
+ import { createReadStream } from "node:fs";
2
+ import { mkdir, rm, stat } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ /**
6
+ * The default {@link RenderStorage}: artifacts live as files under a directory
7
+ * in the server's temp space (`os.tmpdir()/smoove-renders` by default).
8
+ *
9
+ * The renderer writes directly to the file path returned by `put()`, so this is
10
+ * a thin shim over the filesystem — no copy on the hot path. A host that needs
11
+ * durable/remote storage implements the `RenderStorage` contract instead.
12
+ */
13
+ export function createTempStorage(opts = {}) {
14
+ const root = opts.dir ?? join(tmpdir(), "smoove-renders");
15
+ /** jobId → { path, contentType, filename } for finished artifacts. */
16
+ const index = new Map();
17
+ return {
18
+ async put(jobId, o) {
19
+ await mkdir(root, { recursive: true });
20
+ const path = join(root, `${jobId}.${o.ext}`);
21
+ return {
22
+ path,
23
+ finalize: async () => {
24
+ index.set(jobId, { path, contentType: o.contentType, filename: o.filename });
25
+ },
26
+ };
27
+ },
28
+ async get(jobId) {
29
+ const rec = index.get(jobId);
30
+ if (!rec)
31
+ return null;
32
+ let size;
33
+ try {
34
+ size = (await stat(rec.path)).size;
35
+ }
36
+ catch {
37
+ return null; // written record but the file vanished
38
+ }
39
+ return {
40
+ read: () => createReadStream(rec.path),
41
+ contentType: rec.contentType,
42
+ filename: rec.filename,
43
+ size,
44
+ };
45
+ },
46
+ async remove(jobId) {
47
+ const rec = index.get(jobId);
48
+ if (!rec)
49
+ return;
50
+ index.delete(jobId);
51
+ await rm(rec.path, { force: true });
52
+ },
53
+ };
54
+ }
55
+ //# sourceMappingURL=temp-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temp-storage.js","sourceRoot":"","sources":["../../src/server/temp-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAyB,EAAE;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC1D,sEAAsE;IACtE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmE,CAAC;IAEzF,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YAC7C,OAAO;gBACL,IAAI;gBACJ,QAAQ,EAAE,KAAK,IAAI,EAAE;oBACnB,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/E,CAAC;aACF,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,KAAK;YACb,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,CAAC,GAAG;gBAAE,OAAO,IAAI,CAAC;YACtB,IAAI,IAAwB,CAAC;YAC7B,IAAI,CAAC;gBACH,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC,CAAC,uCAAuC;YACtD,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC;gBACtC,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,IAAI;aACL,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,KAAK;YAChB,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,CAAC,GAAG;gBAAE,OAAO;YACjB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;KACF,CAAC;AACJ,CAAC"}