egaki 0.6.0 → 0.7.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 (271) hide show
  1. package/CHANGELOG.md +140 -9
  2. package/dist/cli/cache-utils.d.ts +33 -0
  3. package/dist/cli/cache-utils.d.ts.map +1 -0
  4. package/dist/cli/cache-utils.js +157 -0
  5. package/dist/cli/cached-generate.d.ts +105 -0
  6. package/dist/cli/cached-generate.d.ts.map +1 -0
  7. package/dist/cli/cached-generate.js +208 -0
  8. package/dist/cli/cached-generate.test.d.ts +11 -0
  9. package/dist/cli/cached-generate.test.d.ts.map +1 -0
  10. package/dist/cli/cached-generate.test.js +431 -0
  11. package/dist/cli/cartesia-provider.d.ts +16 -0
  12. package/dist/cli/cartesia-provider.d.ts.map +1 -0
  13. package/dist/cli/cartesia-provider.js +184 -0
  14. package/dist/cli/chatgpt-auth.d.ts.map +1 -0
  15. package/dist/cli/cli.d.ts +4 -0
  16. package/dist/cli/cli.d.ts.map +1 -0
  17. package/dist/{cli.js → cli/cli.js} +626 -600
  18. package/dist/cli/clone-generate.d.ts +26 -0
  19. package/dist/cli/clone-generate.d.ts.map +1 -0
  20. package/dist/cli/clone-generate.js +148 -0
  21. package/dist/cli/credentials.d.ts.map +1 -0
  22. package/dist/{credentials.js → cli/credentials.js} +20 -0
  23. package/dist/cli/elevenlabs-speech-provider.d.ts +26 -0
  24. package/dist/cli/elevenlabs-speech-provider.d.ts.map +1 -0
  25. package/dist/cli/elevenlabs-speech-provider.js +199 -0
  26. package/dist/cli/generate.d.ts +140 -0
  27. package/dist/cli/generate.d.ts.map +1 -0
  28. package/dist/cli/generate.js +604 -0
  29. package/dist/cli/generate.test.d.ts +2 -0
  30. package/dist/cli/generate.test.d.ts.map +1 -0
  31. package/dist/cli/generate.test.js +131 -0
  32. package/dist/cli/login.d.ts.map +1 -0
  33. package/dist/cli/main.d.ts +3 -0
  34. package/dist/cli/main.d.ts.map +1 -0
  35. package/dist/cli/main.js +7 -0
  36. package/dist/{model-catalog.d.ts → cli/model-catalog.d.ts} +6 -0
  37. package/dist/cli/model-catalog.d.ts.map +1 -0
  38. package/dist/{model-catalog.js → cli/model-catalog.js} +714 -4
  39. package/dist/{models.d.ts → cli/models.d.ts} +12 -5
  40. package/dist/cli/models.d.ts.map +1 -0
  41. package/dist/{models.js → cli/models.js} +58 -57
  42. package/dist/cli/open-browser.d.ts.map +1 -0
  43. package/dist/cli/openai-speech-provider.d.ts +3 -0
  44. package/dist/cli/openai-speech-provider.d.ts.map +1 -0
  45. package/dist/cli/openai-speech-provider.js +28 -0
  46. package/dist/cli/separation-generate.d.ts +34 -0
  47. package/dist/cli/separation-generate.d.ts.map +1 -0
  48. package/dist/cli/separation-generate.js +117 -0
  49. package/dist/cli/speech-catalog.d.ts +35 -0
  50. package/dist/cli/speech-catalog.d.ts.map +1 -0
  51. package/dist/cli/speech-catalog.js +195 -0
  52. package/dist/cli/speech-generate.d.ts +86 -0
  53. package/dist/cli/speech-generate.d.ts.map +1 -0
  54. package/dist/cli/speech-generate.js +156 -0
  55. package/dist/cli/speech-models.d.ts +8 -0
  56. package/dist/cli/speech-models.d.ts.map +1 -0
  57. package/dist/cli/speech-models.js +109 -0
  58. package/dist/cli/speech-provider.test.d.ts +2 -0
  59. package/dist/cli/speech-provider.test.d.ts.map +1 -0
  60. package/dist/cli/speech-provider.test.js +197 -0
  61. package/dist/cli/subscription.d.ts.map +1 -0
  62. package/dist/cli/transcription-catalog.d.ts +35 -0
  63. package/dist/cli/transcription-catalog.d.ts.map +1 -0
  64. package/dist/cli/transcription-catalog.js +192 -0
  65. package/dist/cli/transcription-generate.d.ts +62 -0
  66. package/dist/cli/transcription-generate.d.ts.map +1 -0
  67. package/dist/cli/transcription-generate.js +144 -0
  68. package/dist/cli/transcription-models.d.ts +9 -0
  69. package/dist/cli/transcription-models.d.ts.map +1 -0
  70. package/dist/cli/transcription-models.js +100 -0
  71. package/dist/cli/transcription-providers.d.ts +22 -0
  72. package/dist/cli/transcription-providers.d.ts.map +1 -0
  73. package/dist/cli/transcription-providers.js +290 -0
  74. package/dist/cli/video-model-catalog.d.ts.map +1 -0
  75. package/dist/cli/xai-auth.d.ts.map +1 -0
  76. package/dist/{xai-auth.js → cli/xai-auth.js} +1 -1
  77. package/dist/vite/angled-screen.d.ts +57 -0
  78. package/dist/vite/angled-screen.d.ts.map +1 -0
  79. package/dist/vite/angled-screen.js +115 -0
  80. package/dist/vite/app.d.ts +51 -0
  81. package/dist/vite/app.d.ts.map +1 -0
  82. package/dist/vite/app.js +150 -0
  83. package/dist/vite/bands-shader.d.ts +47 -0
  84. package/dist/vite/bands-shader.d.ts.map +1 -0
  85. package/dist/vite/bands-shader.js +267 -0
  86. package/dist/vite/code-block.d.ts +107 -0
  87. package/dist/vite/code-block.d.ts.map +1 -0
  88. package/dist/vite/code-block.js +641 -0
  89. package/dist/vite/components.d.ts +36 -0
  90. package/dist/vite/components.d.ts.map +1 -0
  91. package/dist/vite/components.js +113 -0
  92. package/dist/vite/dispersion-rings-shader.d.ts +44 -0
  93. package/dist/vite/dispersion-rings-shader.d.ts.map +1 -0
  94. package/dist/vite/dispersion-rings-shader.js +282 -0
  95. package/dist/vite/easing-curves.d.ts +129 -0
  96. package/dist/vite/easing-curves.d.ts.map +1 -0
  97. package/dist/vite/easing-curves.js +584 -0
  98. package/dist/vite/easing-curves.test.d.ts +2 -0
  99. package/dist/vite/easing-curves.test.d.ts.map +1 -0
  100. package/dist/vite/easing-curves.test.js +200 -0
  101. package/dist/vite/generated-media-client.d.ts +35 -0
  102. package/dist/vite/generated-media-client.d.ts.map +1 -0
  103. package/dist/vite/generated-media-client.js +76 -0
  104. package/dist/vite/keyframes.d.ts +129 -0
  105. package/dist/vite/keyframes.d.ts.map +1 -0
  106. package/dist/vite/keyframes.js +194 -0
  107. package/dist/vite/layout-editor.d.ts +45 -0
  108. package/dist/vite/layout-editor.d.ts.map +1 -0
  109. package/dist/vite/layout-editor.js +587 -0
  110. package/dist/vite/layout-transition.d.ts +136 -0
  111. package/dist/vite/layout-transition.d.ts.map +1 -0
  112. package/dist/vite/layout-transition.js +581 -0
  113. package/dist/vite/liquid-gradient-shader.d.ts +62 -0
  114. package/dist/vite/liquid-gradient-shader.d.ts.map +1 -0
  115. package/dist/vite/liquid-gradient-shader.js +413 -0
  116. package/dist/vite/mdx-client.d.ts +15 -0
  117. package/dist/vite/mdx-client.d.ts.map +1 -0
  118. package/dist/vite/mdx-client.js +265 -0
  119. package/dist/vite/mdx-parse.d.ts +102 -0
  120. package/dist/vite/mdx-parse.d.ts.map +1 -0
  121. package/dist/vite/mdx-parse.js +251 -0
  122. package/dist/vite/mdx-provided-components.d.ts +18 -0
  123. package/dist/vite/mdx-provided-components.d.ts.map +1 -0
  124. package/dist/vite/mdx-provided-components.js +14 -0
  125. package/dist/vite/mdx-video.d.ts +327 -0
  126. package/dist/vite/mdx-video.d.ts.map +1 -0
  127. package/dist/vite/mdx-video.js +596 -0
  128. package/dist/vite/mdx-video.test.d.ts +9 -0
  129. package/dist/vite/mdx-video.test.d.ts.map +1 -0
  130. package/dist/vite/mdx-video.test.js +1945 -0
  131. package/dist/vite/media-components.d.ts +45 -0
  132. package/dist/vite/media-components.d.ts.map +1 -0
  133. package/dist/vite/media-components.js +355 -0
  134. package/dist/vite/media-duration-store.d.ts +66 -0
  135. package/dist/vite/media-duration-store.d.ts.map +1 -0
  136. package/dist/vite/media-duration-store.js +204 -0
  137. package/dist/vite/player-page.d.ts +35 -0
  138. package/dist/vite/player-page.d.ts.map +1 -0
  139. package/dist/vite/player-page.js +720 -0
  140. package/dist/vite/render-client.d.ts +18 -0
  141. package/dist/vite/render-client.d.ts.map +1 -0
  142. package/dist/vite/render-client.js +67 -0
  143. package/dist/vite/sdk.d.ts +221 -0
  144. package/dist/vite/sdk.d.ts.map +1 -0
  145. package/dist/vite/sdk.js +355 -0
  146. package/dist/vite/server-components.d.ts +55 -0
  147. package/dist/vite/server-components.d.ts.map +1 -0
  148. package/dist/vite/server-components.js +156 -0
  149. package/dist/vite/server-mdx.d.ts +74 -0
  150. package/dist/vite/server-mdx.d.ts.map +1 -0
  151. package/dist/vite/server-mdx.js +259 -0
  152. package/dist/vite/shader-renderer.d.ts +48 -0
  153. package/dist/vite/shader-renderer.d.ts.map +1 -0
  154. package/dist/vite/shader-renderer.js +411 -0
  155. package/dist/vite/store-hooks.d.ts +12 -0
  156. package/dist/vite/store-hooks.d.ts.map +1 -0
  157. package/dist/vite/store-hooks.js +93 -0
  158. package/dist/vite/store.d.ts +75 -0
  159. package/dist/vite/store.d.ts.map +1 -0
  160. package/dist/vite/store.js +52 -0
  161. package/dist/vite/store.test.d.ts +6 -0
  162. package/dist/vite/store.test.d.ts.map +1 -0
  163. package/dist/vite/store.test.js +172 -0
  164. package/dist/vite/tweakpane-hook.d.ts +94 -0
  165. package/dist/vite/tweakpane-hook.d.ts.map +1 -0
  166. package/dist/vite/tweakpane-hook.js +450 -0
  167. package/dist/vite/vite-plugin.d.ts +28 -0
  168. package/dist/vite/vite-plugin.d.ts.map +1 -0
  169. package/dist/vite/vite-plugin.js +538 -0
  170. package/dist/vite/wave-gradient-shader.d.ts +41 -0
  171. package/dist/vite/wave-gradient-shader.d.ts.map +1 -0
  172. package/dist/vite/wave-gradient-shader.js +207 -0
  173. package/package.json +101 -24
  174. package/skills/egaki/SKILL.md +162 -1
  175. package/src/cli/cache-utils.ts +169 -0
  176. package/src/cli/cached-generate.test.ts +531 -0
  177. package/src/cli/cached-generate.ts +348 -0
  178. package/src/cli/cartesia-provider.ts +249 -0
  179. package/src/{cli.ts → cli/cli.ts} +836 -884
  180. package/src/cli/clone-generate.ts +202 -0
  181. package/src/{credentials.ts → cli/credentials.ts} +20 -0
  182. package/src/cli/elevenlabs-speech-provider.ts +243 -0
  183. package/src/cli/generate.test.ts +166 -0
  184. package/src/cli/generate.ts +912 -0
  185. package/src/cli/main.ts +8 -0
  186. package/src/{model-catalog.ts → cli/model-catalog.ts} +787 -58
  187. package/src/{models.ts → cli/models.ts} +65 -86
  188. package/src/cli/openai-speech-provider.ts +34 -0
  189. package/src/cli/separation-generate.ts +187 -0
  190. package/src/cli/speech-catalog.ts +253 -0
  191. package/src/cli/speech-generate.ts +275 -0
  192. package/src/cli/speech-models.ts +146 -0
  193. package/src/cli/speech-provider.test.ts +226 -0
  194. package/src/cli/transcription-catalog.ts +250 -0
  195. package/src/cli/transcription-generate.ts +214 -0
  196. package/src/cli/transcription-models.ts +136 -0
  197. package/src/cli/transcription-providers.ts +427 -0
  198. package/src/{xai-auth.ts → cli/xai-auth.ts} +1 -1
  199. package/src/vite/angled-screen.tsx +214 -0
  200. package/src/vite/app.tsx +197 -0
  201. package/src/vite/bands-shader.tsx +319 -0
  202. package/src/vite/code-block.tsx +939 -0
  203. package/src/vite/components.tsx +278 -0
  204. package/src/vite/dispersion-rings-shader.tsx +331 -0
  205. package/src/vite/easing-curves.test.ts +232 -0
  206. package/src/vite/easing-curves.ts +743 -0
  207. package/src/vite/generated-media-client.tsx +121 -0
  208. package/src/vite/keyframes.tsx +347 -0
  209. package/src/vite/layout-editor.tsx +709 -0
  210. package/src/vite/layout-transition.tsx +706 -0
  211. package/src/vite/liquid-gradient-shader.tsx +474 -0
  212. package/src/vite/mdx-client.tsx +420 -0
  213. package/src/vite/mdx-parse.ts +343 -0
  214. package/src/vite/mdx-provided-components.ts +19 -0
  215. package/src/vite/mdx-video.test.tsx +2219 -0
  216. package/src/vite/mdx-video.tsx +976 -0
  217. package/src/vite/media-components.tsx +473 -0
  218. package/src/vite/media-duration-store.ts +225 -0
  219. package/src/vite/motion-timing.ts +194 -0
  220. package/src/vite/player-page.tsx +1107 -0
  221. package/src/vite/render-client.ts +84 -0
  222. package/src/vite/sdk.ts +598 -0
  223. package/src/vite/server-components.tsx +241 -0
  224. package/src/vite/server-mdx.ts +285 -0
  225. package/src/vite/shader-renderer.tsx +535 -0
  226. package/src/vite/store-hooks.ts +117 -0
  227. package/src/vite/store.test.ts +202 -0
  228. package/src/vite/store.ts +115 -0
  229. package/src/vite/styles.css +21 -0
  230. package/src/vite/tweakpane-hook.tsx +593 -0
  231. package/src/vite/virtual-modules.d.ts +30 -0
  232. package/src/vite/vite-plugin.ts +584 -0
  233. package/src/vite/wave-gradient-shader.tsx +253 -0
  234. package/README.md +0 -370
  235. package/dist/antigravity-auth.d.ts +0 -15
  236. package/dist/antigravity-auth.d.ts.map +0 -1
  237. package/dist/antigravity-auth.js +0 -544
  238. package/dist/antigravity-image.d.ts +0 -11
  239. package/dist/antigravity-image.d.ts.map +0 -1
  240. package/dist/antigravity-image.js +0 -285
  241. package/dist/chatgpt-auth.d.ts.map +0 -1
  242. package/dist/cli.d.ts +0 -3
  243. package/dist/cli.d.ts.map +0 -1
  244. package/dist/credentials.d.ts.map +0 -1
  245. package/dist/gateway-model-candidates.generated.d.ts +0 -11
  246. package/dist/gateway-model-candidates.generated.d.ts.map +0 -1
  247. package/dist/gateway-model-candidates.generated.js +0 -64
  248. package/dist/login.d.ts.map +0 -1
  249. package/dist/model-catalog.d.ts.map +0 -1
  250. package/dist/models.d.ts.map +0 -1
  251. package/dist/open-browser.d.ts.map +0 -1
  252. package/dist/subscription.d.ts.map +0 -1
  253. package/dist/video-model-catalog.d.ts.map +0 -1
  254. package/dist/xai-auth.d.ts.map +0 -1
  255. /package/dist/{chatgpt-auth.d.ts → cli/chatgpt-auth.d.ts} +0 -0
  256. /package/dist/{chatgpt-auth.js → cli/chatgpt-auth.js} +0 -0
  257. /package/dist/{credentials.d.ts → cli/credentials.d.ts} +0 -0
  258. /package/dist/{login.d.ts → cli/login.d.ts} +0 -0
  259. /package/dist/{login.js → cli/login.js} +0 -0
  260. /package/dist/{open-browser.d.ts → cli/open-browser.d.ts} +0 -0
  261. /package/dist/{open-browser.js → cli/open-browser.js} +0 -0
  262. /package/dist/{subscription.d.ts → cli/subscription.d.ts} +0 -0
  263. /package/dist/{subscription.js → cli/subscription.js} +0 -0
  264. /package/dist/{video-model-catalog.d.ts → cli/video-model-catalog.d.ts} +0 -0
  265. /package/dist/{video-model-catalog.js → cli/video-model-catalog.js} +0 -0
  266. /package/dist/{xai-auth.d.ts → cli/xai-auth.d.ts} +0 -0
  267. /package/src/{chatgpt-auth.ts → cli/chatgpt-auth.ts} +0 -0
  268. /package/src/{login.ts → cli/login.ts} +0 -0
  269. /package/src/{open-browser.ts → cli/open-browser.ts} +0 -0
  270. /package/src/{subscription.ts → cli/subscription.ts} +0 -0
  271. /package/src/{video-model-catalog.ts → cli/video-model-catalog.ts} +0 -0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Server components for AI media generation in MDX <Server> blocks.
3
+ *
4
+ * No 'use client' directive: these execute in the RSC environment (async,
5
+ * filesystem access, API calls). They are auto-wrapped in <Server> by
6
+ * wrapGenerateNodes() in server-mdx.ts, so users write them bare in MDX.
7
+ *
8
+ * Each component delegates to the cached generate functions from egaki/generate
9
+ * (which handle caching, deduplication, stale management, and progress tracking
10
+ * via cachedGenerate) and passes the resolved URL to the client wrapper component.
11
+ *
12
+ * The server components add a thin layer on top for:
13
+ * - Composition-aware defaults (aspect ratio from dimensions)
14
+ * - Asset path resolution (string paths → Uint8Array)
15
+ * - Fallback lookup for RSC streaming (show stale while generating)
16
+ * - RSC flight streaming (pass promise to client wrapper)
17
+ */
18
+ import type { ComponentProps } from 'react';
19
+ import type { GenerateImageOptions } from '../cli/generate.js';
20
+ import type { GenerateVideoOptions } from '../cli/generate.js';
21
+ import type { GenerateSpeechOptions } from '../cli/speech-generate.js';
22
+ import type { Img, Audio, Video } from './mdx-video.tsx';
23
+ export { getGenerationProgress, onProgressChange, type GenerationProgressEvent, type GenerationProgressSummary, type GenerationProgressEntry, type GenerationError, type GenerationEntry, } from '../cli/cached-generate.js';
24
+ export { stableJsonKey, hashKey, promptPrefix, findCachedFile, findFallbackFile } from '../cli/cache-utils.js';
25
+ /** Resolve a path prop to an absolute filesystem path.
26
+ * `/photo.png` → `{projectRoot}/public/photo.png` if the file exists.
27
+ * Relative paths resolve against projectRoot.
28
+ * Absolute paths and URLs pass through unchanged. */
29
+ export declare function resolveAssetPath(p: string): Promise<string>;
30
+ /** Resolve a path and read it as bytes. */
31
+ export declare function readAssetBytes(p: string): Promise<Uint8Array>;
32
+ type GeneratedImageGenProps = Omit<GenerateImageOptions, 'count' | 'inputImages' | 'maskImage'> & {
33
+ inputImages?: string[];
34
+ maskImage?: string;
35
+ };
36
+ export type GeneratedImageProps = GeneratedImageGenProps & Omit<ComponentProps<typeof Img>, 'src'>;
37
+ export declare function GeneratedImage({ inputImages: inputImagePaths, maskImage: maskImagePath, ...props }: GeneratedImageProps): Promise<import("react").JSX.Element>;
38
+ type GeneratedVideoGenProps = Omit<GenerateVideoOptions, 'count' | 'inputImage'> & {
39
+ inputImage?: string;
40
+ };
41
+ export type GeneratedVideoProps = GeneratedVideoGenProps & Omit<ComponentProps<typeof Video>, 'src'>;
42
+ export declare function GeneratedVideo({ inputImage: inputImagePath, ...props }: GeneratedVideoProps): Promise<import("react").JSX.Element>;
43
+ type GeneratedSpeechGenProps = GenerateSpeechOptions & {
44
+ seed?: number;
45
+ };
46
+ export type GeneratedSpeechProps = GeneratedSpeechGenProps & Omit<ComponentProps<typeof Audio>, 'src'>;
47
+ export declare function GeneratedSpeech(props: GeneratedSpeechProps): Promise<import("react").JSX.Element>;
48
+ interface TextToSpeechProps {
49
+ /** Text to synthesize. */
50
+ text: string;
51
+ /** Voice preset. */
52
+ voice?: string;
53
+ }
54
+ export declare function TextToSpeech({ text, voice }: TextToSpeechProps): Promise<import("react").JSX.Element>;
55
+ //# sourceMappingURL=server-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-components.d.ts","sourceRoot":"","sources":["../../src/vite/server-components.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;AAStE,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAIxD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,2BAA2B,CAAA;AAGlC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAoC9G;;;sDAGsD;AACtD,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcjE;AAED,2CAA2C;AAC3C,wBAAsB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAQnE;AAMD,KAAK,sBAAsB,GAAG,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,aAAa,GAAG,WAAW,CAAC,GAAG;IAChG,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;AAElG,wBAAsB,cAAc,CAAC,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,wCA6B7H;AAMD,KAAK,sBAAsB,GAAG,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,YAAY,CAAC,GAAG;IACjF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,sBAAsB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;AAEpG,wBAAsB,cAAc,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,wCA0BjG;AAMD,KAAK,uBAAuB,GAAG,qBAAqB,GAAG;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,uBAAuB,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;AAEtG,wBAAsB,eAAe,CAAC,KAAK,EAAE,oBAAoB,wCAmBhE;AAMD,UAAU,iBAAiB;IACzB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,YAAY,CAAC,EAAE,IAAI,EAAE,KAAe,EAAE,EAAE,iBAAiB,wCAE9E"}
@@ -0,0 +1,156 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Server components for AI media generation in MDX <Server> blocks.
4
+ *
5
+ * No 'use client' directive: these execute in the RSC environment (async,
6
+ * filesystem access, API calls). They are auto-wrapped in <Server> by
7
+ * wrapGenerateNodes() in server-mdx.ts, so users write them bare in MDX.
8
+ *
9
+ * Each component delegates to the cached generate functions from egaki/generate
10
+ * (which handle caching, deduplication, stale management, and progress tracking
11
+ * via cachedGenerate) and passes the resolved URL to the client wrapper component.
12
+ *
13
+ * The server components add a thin layer on top for:
14
+ * - Composition-aware defaults (aspect ratio from dimensions)
15
+ * - Asset path resolution (string paths → Uint8Array)
16
+ * - Fallback lookup for RSC streaming (show stale while generating)
17
+ * - RSC flight streaming (pass promise to client wrapper)
18
+ */
19
+ import fs from 'node:fs';
20
+ import path from 'node:path';
21
+ import { CATALOG, VIDEO_CATALOG } from '../cli/model-catalog.js';
22
+ import { DEFAULT_MODEL, DEFAULT_VIDEO_MODEL } from '../cli/models.js';
23
+ import { aspectRatioFromDimensions } from "./mdx-parse.js";
24
+ import { GeneratedImageClient, GeneratedVideoClient, GeneratedSpeechClient, } from "./generated-media-client.js";
25
+ import { setProjectRoot } from '../cli/cache-utils.js';
26
+ // Re-export progress tracking from the centralized module
27
+ export { getGenerationProgress, onProgressChange, } from '../cli/cached-generate.js';
28
+ // Re-export caching utilities so existing imports from 'egaki/generate-media' still work
29
+ export { stableJsonKey, hashKey, promptPrefix, findCachedFile, findFallbackFile } from '../cli/cache-utils.js';
30
+ // ---------------------------------------------------------------------------
31
+ // Project root and composition dimensions from Vite virtual module.
32
+ // setProjectRoot() is called here so the cached generate functions
33
+ // in egaki/generate know where public/generated/ is.
34
+ // ---------------------------------------------------------------------------
35
+ let _initialized = false;
36
+ async function ensureInit() {
37
+ if (_initialized)
38
+ return;
39
+ const mod = await import('virtual:egaki-mdx');
40
+ setProjectRoot(mod.projectRoot);
41
+ _initialized = true;
42
+ }
43
+ async function getCompositionDimensions() {
44
+ const mod = await import('virtual:egaki-mdx');
45
+ return { width: mod.compositionWidth, height: mod.compositionHeight };
46
+ }
47
+ /** Look up a model's supported aspect ratios from the catalog. */
48
+ function getModelAspectRatios(modelId, type) {
49
+ if (type === 'image') {
50
+ const entry = CATALOG.find((m) => m.id === modelId);
51
+ return entry?.features.aspectRatios;
52
+ }
53
+ const entry = VIDEO_CATALOG.find((m) => m.id === modelId);
54
+ return entry?.features.aspectRatios ?? undefined;
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // Asset path resolution — paths starting with `/` resolve to the project's
58
+ // public/ folder (Vite convention), then fall back to absolute/relative paths.
59
+ // ---------------------------------------------------------------------------
60
+ /** Resolve a path prop to an absolute filesystem path.
61
+ * `/photo.png` → `{projectRoot}/public/photo.png` if the file exists.
62
+ * Relative paths resolve against projectRoot.
63
+ * Absolute paths and URLs pass through unchanged. */
64
+ export async function resolveAssetPath(p) {
65
+ await ensureInit();
66
+ const { getProjectRoot } = await import('../cli/cache-utils.js');
67
+ const root = getProjectRoot();
68
+ if (p.startsWith('http://') || p.startsWith('https://'))
69
+ return p;
70
+ if (p.startsWith('/')) {
71
+ const publicDir = path.join(root, 'public');
72
+ const publicPath = path.resolve(publicDir, '.' + p);
73
+ if (publicPath.startsWith(publicDir + path.sep) && fs.existsSync(publicPath)) {
74
+ return publicPath;
75
+ }
76
+ }
77
+ if (path.isAbsolute(p))
78
+ return p;
79
+ return path.resolve(root, p);
80
+ }
81
+ /** Resolve a path and read it as bytes. */
82
+ export async function readAssetBytes(p) {
83
+ const resolved = await resolveAssetPath(p);
84
+ if (resolved.startsWith('http://') || resolved.startsWith('https://')) {
85
+ const res = await fetch(resolved);
86
+ if (!res.ok)
87
+ throw new Error(`Failed to fetch ${resolved}: ${res.status}`);
88
+ return new Uint8Array(await res.arrayBuffer());
89
+ }
90
+ return new Uint8Array(fs.readFileSync(resolved));
91
+ }
92
+ export async function GeneratedImage({ inputImages: inputImagePaths, maskImage: maskImagePath, ...props }) {
93
+ await ensureInit();
94
+ const { prompt, model, seed, aspectRatio: aspectRatioProp, quality, resolution, outputFormat, negativePrompt, allowPeople, imageSize, ...passthrough } = props;
95
+ const { width, height } = await getCompositionDimensions();
96
+ const allowedRatios = getModelAspectRatios(model ?? DEFAULT_MODEL, 'image');
97
+ const aspectRatio = aspectRatioProp ?? (allowedRatios?.length ? aspectRatioFromDimensions(width, height, allowedRatios) : undefined);
98
+ const inputImages = inputImagePaths ? await Promise.all(inputImagePaths.map(readAssetBytes)) : undefined;
99
+ const maskImage = maskImagePath ? await readAssetBytes(maskImagePath) : undefined;
100
+ const genParams = { prompt, model, seed, aspectRatio, quality, resolution, outputFormat, negativePrompt, allowPeople, imageSize, inputImages, maskImage };
101
+ // Sync cache check + fallback lookup for RSC streaming.
102
+ // Uses the wrapper's getCacheInfo() so the same cacheKey config is applied.
103
+ const { generateImage } = await import('../cli/generate.js');
104
+ const cacheInfo = generateImage.getCacheInfo(genParams);
105
+ if (cacheInfo.cached) {
106
+ return _jsx(GeneratedImageClient, { srcPromise: Promise.resolve(`/generated/image/${cacheInfo.cached}`), ...passthrough });
107
+ }
108
+ const srcPromise = generateImage(genParams)
109
+ .then((result) => {
110
+ if (result instanceof Error)
111
+ throw result;
112
+ return result.src;
113
+ });
114
+ return _jsx(GeneratedImageClient, { srcPromise: srcPromise, fallbackSrc: cacheInfo.fallbackSrc, ...passthrough });
115
+ }
116
+ export async function GeneratedVideo({ inputImage: inputImagePath, ...props }) {
117
+ await ensureInit();
118
+ const { prompt, model, seed, aspectRatio: aspectRatioProp, resolution, duration, fps, negativePrompt, mode, videoUrl, referenceImages, ...passthrough } = props;
119
+ const inputImage = inputImagePath ? await readAssetBytes(inputImagePath) : undefined;
120
+ const { width, height } = await getCompositionDimensions();
121
+ const allowedRatios = getModelAspectRatios(model ?? DEFAULT_VIDEO_MODEL, 'video');
122
+ const aspectRatio = aspectRatioProp ?? (allowedRatios?.length ? aspectRatioFromDimensions(width, height, allowedRatios) : undefined);
123
+ const genParams = { prompt, model, seed, aspectRatio, resolution, duration, fps, negativePrompt, inputImage, mode, videoUrl, referenceImages };
124
+ const { generateVideo } = await import('../cli/generate.js');
125
+ const cacheInfo = generateVideo.getCacheInfo(genParams);
126
+ if (cacheInfo.cached) {
127
+ return _jsx(GeneratedVideoClient, { srcPromise: Promise.resolve(`/generated/video/${cacheInfo.cached}`), ...passthrough });
128
+ }
129
+ const srcPromise = generateVideo(genParams)
130
+ .then((result) => {
131
+ if (result instanceof Error)
132
+ throw result;
133
+ return result.src;
134
+ });
135
+ return _jsx(GeneratedVideoClient, { srcPromise: srcPromise, fallbackSrc: cacheInfo.fallbackSrc, ...passthrough });
136
+ }
137
+ export async function GeneratedSpeech(props) {
138
+ await ensureInit();
139
+ const { text, model, voice, outputFormat, instructions, speed, language, seed, ...passthrough } = props;
140
+ const genParams = { text, model, voice, outputFormat, instructions, speed, language, seed };
141
+ const { generateSpeech } = await import('../cli/speech-generate.js');
142
+ const cacheInfo = generateSpeech.getCacheInfo(genParams);
143
+ if (cacheInfo.cached) {
144
+ return _jsx(GeneratedSpeechClient, { srcPromise: Promise.resolve(`/generated/audio/${cacheInfo.cached}`), ...passthrough });
145
+ }
146
+ const srcPromise = generateSpeech(genParams)
147
+ .then((result) => {
148
+ if (result instanceof Error)
149
+ throw result;
150
+ return result.src;
151
+ });
152
+ return _jsx(GeneratedSpeechClient, { srcPromise: srcPromise, fallbackSrc: cacheInfo.fallbackSrc, ...passthrough });
153
+ }
154
+ export async function TextToSpeech({ text, voice = 'alloy' }) {
155
+ return GeneratedSpeech({ text, voice });
156
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * <Server> MDX parsing utilities.
3
+ *
4
+ * <Server> is a reserved MDX element marking a subtree as React Server
5
+ * Components. This module contains the pure parsing logic shared by the
6
+ * server (app.tsx), the client (mdx-client.tsx), and the vite plugin:
7
+ *
8
+ * - findServerNodes: locate <Server> elements, keyed by start line
9
+ * - blankServerContents: strip server content from the client-facing MDX
10
+ * string while preserving line positions
11
+ * - collectServerImportSources: detect which MDX imports <Server> blocks
12
+ * need (app.tsx dynamically imports them at request time)
13
+ * - filterImportNodesToModules: per-statement import filtering against an
14
+ * environment's modules map
15
+ *
16
+ * Environment-neutral: no remotion, react, or node-only imports.
17
+ */
18
+ type RootContent = any;
19
+ export interface ServerNode {
20
+ /** Slot key: the node's start LINE as a string. Stable across server
21
+ * and client because both parse the same source string
22
+ * (blankServerContents preserves all line positions). Line-only (no
23
+ * column) because the client matches slots via the data-markdown-line
24
+ * prop that safe-mdx injects, which only carries the line. Two <Server>
25
+ * elements on the same line collide — app.tsx warns about duplicates. */
26
+ key: string;
27
+ node: RootContent;
28
+ }
29
+ /** Recursively find <Server> elements in the mdast. Server nodes nested
30
+ * inside another <Server> are skipped — the outer slot covers them. */
31
+ export declare function findServerNodes(mdast: {
32
+ children?: RootContent[];
33
+ }): ServerNode[];
34
+ /** Replace each <Server> element's source range with a self-closing
35
+ * `<Server />` marker, padded with newlines so the result has the EXACT
36
+ * same line count and all subsequent positions stay valid. This keeps
37
+ * slot keys, data-markdown-line attributes, and sourcemaps aligned with
38
+ * the original file, and prevents the client from parsing (and trying to
39
+ * resolve imports for) server-only content. */
40
+ export declare function blankServerContents(source: string, serverNodes: ServerNode[]): string;
41
+ /** Collect MDX import sources whose names are used inside <Server>
42
+ * subtrees. Includes bare specifiers (e.g. 'egaki/text-to-speech') —
43
+ * app.tsx imports them through vite's resolver, and the resolved file's
44
+ * 'use client' directive (or lack of it) decides whether the exports are
45
+ * client refs or server components. */
46
+ export declare function collectServerImportSources(mdast: {
47
+ children?: RootContent[];
48
+ }): string[];
49
+ /** Component names that should be auto-wrapped in <Server>. */
50
+ export declare const GENERATED_COMPONENT_NAMES: Set<string>;
51
+ /** Collect local names imported from *.server.* sources in the MDX.
52
+ * These components should be auto-wrapped in <Server> because the
53
+ * .server postfix signals they run in the RSC environment. */
54
+ export declare function collectServerFileImportNames(mdast: {
55
+ children?: RootContent[];
56
+ }): Set<string>;
57
+ /** Walk the mdast and wrap bare server components in <Server>.
58
+ * Targets two categories:
59
+ * 1. Built-in generated media components (GeneratedImage, etc.)
60
+ * 2. Components imported from *.server.* files
61
+ * Mutates the tree in place. Wrapping reuses the original node's position
62
+ * so slot keys and line numbers are unchanged. */
63
+ export declare function wrapGenerateNodes(mdast: {
64
+ children?: RootContent[];
65
+ }): void;
66
+ /** Filter mdxjsEsm import nodes to statements whose source is resolvable
67
+ * in the given modules map. Each environment's map only contains the
68
+ * modules that belong there, so this keeps exactly the imports that
69
+ * environment can satisfy — no naming rules. Filtering is per-STATEMENT:
70
+ * contiguous import lines parse as a single mdxjsEsm node, so dropping
71
+ * whole nodes would remove unrelated imports. */
72
+ export declare function filterImportNodesToModules(importNodes: RootContent[], moduleKeys: string[]): RootContent[];
73
+ export {};
74
+ //# sourceMappingURL=server-mdx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-mdx.d.ts","sourceRoot":"","sources":["../../src/vite/server-mdx.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,KAAK,WAAW,GAAG,GAAG,CAAA;AAYtB,MAAM,WAAW,UAAU;IACzB;;;;;8EAK0E;IAC1E,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,WAAW,CAAA;CAClB;AAMD;wEACwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;CAAE,GAAG,UAAU,EAAE,CAcjF;AAED;;;;;gDAKgD;AAChD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAgBrF;AAsDD;;;;wCAIwC;AACxC,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;CAAE,GAAG,MAAM,EAAE,CA+BxF;AAYD,+DAA+D;AAC/D,eAAO,MAAM,yBAAyB,aAIpC,CAAA;AAEF;;+DAE+D;AAC/D,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;CAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAe7F;AAED;;;;;mDAKmD;AACnD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAA;CAAE,GAAG,IAAI,CAqC3E;AAED;;;;;kDAKkD;AAClD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,WAAW,EAAE,EAC1B,UAAU,EAAE,MAAM,EAAE,GACnB,WAAW,EAAE,CAaf"}
@@ -0,0 +1,259 @@
1
+ /**
2
+ * <Server> MDX parsing utilities.
3
+ *
4
+ * <Server> is a reserved MDX element marking a subtree as React Server
5
+ * Components. This module contains the pure parsing logic shared by the
6
+ * server (app.tsx), the client (mdx-client.tsx), and the vite plugin:
7
+ *
8
+ * - findServerNodes: locate <Server> elements, keyed by start line
9
+ * - blankServerContents: strip server content from the client-facing MDX
10
+ * string while preserving line positions
11
+ * - collectServerImportSources: detect which MDX imports <Server> blocks
12
+ * need (app.tsx dynamically imports them at request time)
13
+ * - filterImportNodesToModules: per-statement import filtering against an
14
+ * environment's modules map
15
+ *
16
+ * Environment-neutral: no remotion, react, or node-only imports.
17
+ */
18
+ import { resolveModulePath } from 'safe-mdx/parse';
19
+ function serverNodeKey(node) {
20
+ return String(node.position?.start?.line);
21
+ }
22
+ /** Recursively find <Server> elements in the mdast. Server nodes nested
23
+ * inside another <Server> are skipped — the outer slot covers them. */
24
+ export function findServerNodes(mdast) {
25
+ const found = [];
26
+ const visit = (node) => {
27
+ const isServer = (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement')
28
+ && node.name === 'Server';
29
+ if (isServer) {
30
+ found.push({ key: serverNodeKey(node), node });
31
+ return; // don't descend — nested Server is part of the outer slot
32
+ }
33
+ for (const child of node.children || [])
34
+ visit(child);
35
+ };
36
+ for (const child of mdast.children || [])
37
+ visit(child);
38
+ return found;
39
+ }
40
+ /** Replace each <Server> element's source range with a self-closing
41
+ * `<Server />` marker, padded with newlines so the result has the EXACT
42
+ * same line count and all subsequent positions stay valid. This keeps
43
+ * slot keys, data-markdown-line attributes, and sourcemaps aligned with
44
+ * the original file, and prevents the client from parsing (and trying to
45
+ * resolve imports for) server-only content. */
46
+ export function blankServerContents(source, serverNodes) {
47
+ // Process back-to-front so earlier offsets stay valid after each splice.
48
+ const sorted = [...serverNodes].sort((a, b) => (b.node.position?.start?.offset ?? 0) - (a.node.position?.start?.offset ?? 0));
49
+ let result = source;
50
+ for (const { node } of sorted) {
51
+ const start = node.position?.start?.offset;
52
+ const end = node.position?.end?.offset;
53
+ if (typeof start !== 'number' || typeof end !== 'number')
54
+ continue;
55
+ const span = result.slice(start, end);
56
+ const newlines = span.split('\n').length - 1;
57
+ const replacement = '<Server />' + '\n'.repeat(newlines);
58
+ result = result.slice(0, start) + replacement + result.slice(end);
59
+ }
60
+ return result;
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // Server import detection
64
+ //
65
+ // Detects which MDX imports are needed by <Server> slot rendering by
66
+ // scanning identifier usage inside <Server> subtrees. app.tsx dynamically
67
+ // imports exactly these sources at request time — no filename convention
68
+ // required (though *.server.* remains supported as a hard "never bundle
69
+ // to the browser" override in the vite plugin).
70
+ //
71
+ // Detection is name-based and intentionally COARSE: it collects JSX
72
+ // element names (root identifier of <ns.Comp/>) plus every estree
73
+ // Identifier in expressions and attribute values. Over-collection just
74
+ // imports an extra file server-side; under-collection would break slot
75
+ // rendering, so coarse is the safe direction.
76
+ // ---------------------------------------------------------------------------
77
+ /** Collect every estree Identifier name reachable from a value. */
78
+ function collectEstreeIdentifiers(value, out) {
79
+ if (!value || typeof value !== 'object')
80
+ return;
81
+ if (Array.isArray(value)) {
82
+ for (const item of value)
83
+ collectEstreeIdentifiers(item, out);
84
+ return;
85
+ }
86
+ if (value.type === 'Identifier' && typeof value.name === 'string') {
87
+ out.add(value.name);
88
+ }
89
+ for (const key of Object.keys(value)) {
90
+ if (key === 'position' || key === 'loc' || key === 'range' || key === 'start' || key === 'end')
91
+ continue;
92
+ collectEstreeIdentifiers(value[key], out);
93
+ }
94
+ }
95
+ /** Collect identifier usage from a single mdast node into a bucket:
96
+ * JSX element names plus identifiers in expressions/attribute values. */
97
+ function collectNodeIdentifiers(node, out) {
98
+ if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
99
+ if (typeof node.name === 'string' && node.name) {
100
+ out.add(node.name.split('.')[0]);
101
+ }
102
+ for (const attr of node.attributes || []) {
103
+ if (attr.type === 'mdxJsxExpressionAttribute') {
104
+ collectEstreeIdentifiers(attr.data?.estree, out);
105
+ }
106
+ else if (attr.value && typeof attr.value === 'object') {
107
+ collectEstreeIdentifiers(attr.value.data?.estree, out);
108
+ }
109
+ }
110
+ }
111
+ if (node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression') {
112
+ collectEstreeIdentifiers(node.data?.estree, out);
113
+ }
114
+ }
115
+ /** Collect MDX import sources whose names are used inside <Server>
116
+ * subtrees. Includes bare specifiers (e.g. 'egaki/text-to-speech') —
117
+ * app.tsx imports them through vite's resolver, and the resolved file's
118
+ * 'use client' directive (or lack of it) decides whether the exports are
119
+ * client refs or server components. */
120
+ export function collectServerImportSources(mdast) {
121
+ const insideNames = new Set();
122
+ const visit = (node, insideServer) => {
123
+ const isServer = (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement')
124
+ && node.name === 'Server';
125
+ const nowInside = insideServer || isServer;
126
+ if (nowInside && !isServer) {
127
+ // The <Server> element itself contributes no identifiers.
128
+ collectNodeIdentifiers(node, insideNames);
129
+ }
130
+ for (const child of node.children || [])
131
+ visit(child, nowInside);
132
+ };
133
+ for (const child of mdast.children || [])
134
+ visit(child, false);
135
+ const sources = new Set();
136
+ for (const node of mdast.children || []) {
137
+ if (node.type !== 'mdxjsEsm')
138
+ continue;
139
+ const body = node.data?.estree?.body || [];
140
+ for (const stmt of body) {
141
+ if (stmt.type !== 'ImportDeclaration')
142
+ continue;
143
+ const source = stmt.source?.value;
144
+ if (typeof source !== 'string')
145
+ continue;
146
+ const locals = (stmt.specifiers || [])
147
+ .map((s) => s.local?.name)
148
+ .filter(Boolean);
149
+ if (locals.some((name) => insideNames.has(name)))
150
+ sources.add(source);
151
+ }
152
+ }
153
+ return [...sources].sort();
154
+ }
155
+ // ---------------------------------------------------------------------------
156
+ // Auto-wrap generated media components in <Server>
157
+ //
158
+ // <GeneratedImage>, <GeneratedVideo>, <GeneratedSpeech> are server components
159
+ // that call egaki's generation APIs. When found bare in the mdast (not inside
160
+ // a <Server> block), this transform wraps them in a synthetic <Server> node
161
+ // so findServerNodes() picks them up. The wrapper reuses the original node's
162
+ // position so line numbers stay stable and no sourcemap fixup is needed.
163
+ // ---------------------------------------------------------------------------
164
+ /** Component names that should be auto-wrapped in <Server>. */
165
+ export const GENERATED_COMPONENT_NAMES = new Set([
166
+ 'GeneratedImage',
167
+ 'GeneratedVideo',
168
+ 'GeneratedSpeech',
169
+ ]);
170
+ /** Collect local names imported from *.server.* sources in the MDX.
171
+ * These components should be auto-wrapped in <Server> because the
172
+ * .server postfix signals they run in the RSC environment. */
173
+ export function collectServerFileImportNames(mdast) {
174
+ const names = new Set();
175
+ for (const node of mdast.children || []) {
176
+ if (node.type !== 'mdxjsEsm')
177
+ continue;
178
+ for (const stmt of node.data?.estree?.body || []) {
179
+ if (stmt.type !== 'ImportDeclaration')
180
+ continue;
181
+ const source = stmt.source?.value;
182
+ if (typeof source !== 'string')
183
+ continue;
184
+ if (!/\.server(\.[jt]sx?)?$/.test(source))
185
+ continue;
186
+ for (const spec of stmt.specifiers || []) {
187
+ if (spec.local?.name)
188
+ names.add(spec.local.name);
189
+ }
190
+ }
191
+ }
192
+ return names;
193
+ }
194
+ /** Walk the mdast and wrap bare server components in <Server>.
195
+ * Targets two categories:
196
+ * 1. Built-in generated media components (GeneratedImage, etc.)
197
+ * 2. Components imported from *.server.* files
198
+ * Mutates the tree in place. Wrapping reuses the original node's position
199
+ * so slot keys and line numbers are unchanged. */
200
+ export function wrapGenerateNodes(mdast) {
201
+ const serverImportNames = collectServerFileImportNames(mdast);
202
+ const shouldWrap = (name) => GENERATED_COMPONENT_NAMES.has(name) || serverImportNames.has(name);
203
+ const wrapInParent = (parent) => {
204
+ if (!parent.children)
205
+ return;
206
+ for (let i = 0; i < parent.children.length; i++) {
207
+ const node = parent.children[i];
208
+ // Use root identifier for dotted names like <Scenes.Hero /> → "Scenes"
209
+ const jsxRootName = typeof node.name === 'string' ? node.name.split('.')[0] : '';
210
+ if ((node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement')
211
+ && shouldWrap(jsxRootName)) {
212
+ // Wrap in a synthetic <Server> with the same position so slot
213
+ // keying (by start line) stays identical and blankServerContents
214
+ // replaces the right source span.
215
+ parent.children[i] = {
216
+ type: node.type,
217
+ name: 'Server',
218
+ attributes: [],
219
+ children: [node],
220
+ position: node.position ? { ...node.position } : undefined,
221
+ };
222
+ continue;
223
+ }
224
+ // Don't descend into <Server> — already server-side
225
+ const isServer = (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement')
226
+ && node.name === 'Server';
227
+ if (isServer)
228
+ continue;
229
+ // Recurse into other elements
230
+ if (node.children)
231
+ wrapInParent(node);
232
+ }
233
+ };
234
+ wrapInParent(mdast);
235
+ }
236
+ /** Filter mdxjsEsm import nodes to statements whose source is resolvable
237
+ * in the given modules map. Each environment's map only contains the
238
+ * modules that belong there, so this keeps exactly the imports that
239
+ * environment can satisfy — no naming rules. Filtering is per-STATEMENT:
240
+ * contiguous import lines parse as a single mdxjsEsm node, so dropping
241
+ * whole nodes would remove unrelated imports. */
242
+ export function filterImportNodesToModules(importNodes, moduleKeys) {
243
+ return importNodes.map((node) => {
244
+ const estree = node.data?.estree;
245
+ if (!estree?.body)
246
+ return node;
247
+ const body = estree.body.filter((stmt) => {
248
+ if (stmt.type !== 'ImportDeclaration')
249
+ return true;
250
+ const source = stmt.source?.value;
251
+ if (typeof source !== 'string')
252
+ return true;
253
+ return resolveModulePath(source, './', moduleKeys) !== undefined;
254
+ });
255
+ if (body.length === estree.body.length)
256
+ return node;
257
+ return { ...node, data: { ...node.data, estree: { ...estree, body } } };
258
+ });
259
+ }
@@ -0,0 +1,48 @@
1
+ import { type CSSProperties } from 'react';
2
+ export interface NumberControl {
3
+ type: 'number';
4
+ defaultValue: number;
5
+ min: number;
6
+ max: number;
7
+ step: number;
8
+ /** Hidden controls are not shown in the tweakpane UI but still set as uniforms. */
9
+ hidden?: boolean;
10
+ }
11
+ export interface ColorArrayControl {
12
+ type: 'array';
13
+ control: {
14
+ type: 'color';
15
+ };
16
+ /** Maximum number of colors. Determines the GLSL array size. */
17
+ maxCount: number;
18
+ /** Max color slots shown in tweakpane UI. Defaults to maxCount. */
19
+ maxVisible?: number;
20
+ defaultValue: string[];
21
+ }
22
+ export type PropertyControl = NumberControl | ColorArrayControl;
23
+ export interface ShaderConfig {
24
+ /** Display name shown in tweakpane and used as React displayName. */
25
+ title: string;
26
+ /** Fragment shader body (everything after the auto-generated header). */
27
+ fragment: string;
28
+ /** Property controls that become uniforms and tweakpane sliders. */
29
+ propertyControls: Record<string, PropertyControl>;
30
+ }
31
+ /**
32
+ * Create a React component that renders a WebGL2 fragment shader full-screen.
33
+ *
34
+ * The returned component accepts all property control keys as optional props
35
+ * plus a `style` prop. Number controls are exposed in tweakpane as sliders
36
+ * (unless `hidden: true`). Color array items are exposed as individual
37
+ * tweakpane color pickers with swatch UI.
38
+ *
39
+ * Time and resolution are derived from Remotion's hooks, making the shader
40
+ * fully deterministic and seekable.
41
+ */
42
+ export declare function defineShader(config: ShaderConfig): {
43
+ (props: Record<string, any> & {
44
+ style?: CSSProperties;
45
+ }): import("react").JSX.Element;
46
+ displayName: string;
47
+ };
48
+ //# sourceMappingURL=shader-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shader-renderer.d.ts","sourceRoot":"","sources":["../../src/vite/shader-renderer.tsx"],"names":[],"mappings":"AA8BA,OAAO,EAA2B,KAAK,aAAa,EAAE,MAAM,OAAO,CAAA;AAOnE,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAA;IACd,YAAY,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAA;IAC1B,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAE/D,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAA;IAChB,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAClD;AAoLD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY;YAsEtC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;QAAE,KAAK,CAAC,EAAE,aAAa,CAAA;KAAE;;EA+MzD"}