@json-render/remotion 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ZWW4MGY5.mjs → chunk-BVYWHWII.mjs} +16 -5
- package/dist/chunk-BVYWHWII.mjs.map +1 -0
- package/dist/index.js +15 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/server.d.mts +18 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.js +15 -4
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-ZWW4MGY5.mjs.map +0 -1
|
@@ -270,7 +270,8 @@ var standardComponentDefinitions = {
|
|
|
270
270
|
}),
|
|
271
271
|
type: "scene",
|
|
272
272
|
defaultDuration: 90,
|
|
273
|
-
description: "Full-screen title card with centered text. Use for intros, outros, and section breaks."
|
|
273
|
+
description: "Full-screen title card with centered text. Use for intros, outros, and section breaks.",
|
|
274
|
+
example: { title: "Welcome", subtitle: "An introduction" }
|
|
274
275
|
},
|
|
275
276
|
ImageSlide: {
|
|
276
277
|
props: z.object({
|
|
@@ -281,7 +282,12 @@ var standardComponentDefinitions = {
|
|
|
281
282
|
}),
|
|
282
283
|
type: "image",
|
|
283
284
|
defaultDuration: 150,
|
|
284
|
-
description: "Full-screen image display. Use for product shots, photos, and visual content."
|
|
285
|
+
description: "Full-screen image display. Use for product shots, photos, and visual content.",
|
|
286
|
+
example: {
|
|
287
|
+
src: "https://picsum.photos/1920/1080?random=1",
|
|
288
|
+
alt: "Hero image",
|
|
289
|
+
fit: "cover"
|
|
290
|
+
}
|
|
285
291
|
},
|
|
286
292
|
SplitScreen: {
|
|
287
293
|
props: z.object({
|
|
@@ -304,7 +310,11 @@ var standardComponentDefinitions = {
|
|
|
304
310
|
}),
|
|
305
311
|
type: "scene",
|
|
306
312
|
defaultDuration: 150,
|
|
307
|
-
description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images."
|
|
313
|
+
description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.",
|
|
314
|
+
example: {
|
|
315
|
+
quote: "The best way to predict the future is to invent it.",
|
|
316
|
+
author: "Alan Kay"
|
|
317
|
+
}
|
|
308
318
|
},
|
|
309
319
|
StatCard: {
|
|
310
320
|
props: z.object({
|
|
@@ -316,7 +326,8 @@ var standardComponentDefinitions = {
|
|
|
316
326
|
}),
|
|
317
327
|
type: "scene",
|
|
318
328
|
defaultDuration: 90,
|
|
319
|
-
description: "Large statistic display. Use for key metrics and numbers."
|
|
329
|
+
description: "Large statistic display. Use for key metrics and numbers.",
|
|
330
|
+
example: { value: "10M+", label: "Users worldwide", prefix: "" }
|
|
320
331
|
},
|
|
321
332
|
TypingText: {
|
|
322
333
|
props: z.object({
|
|
@@ -443,4 +454,4 @@ export {
|
|
|
443
454
|
standardTransitionDefinitions,
|
|
444
455
|
standardEffectDefinitions
|
|
445
456
|
};
|
|
446
|
-
//# sourceMappingURL=chunk-
|
|
457
|
+
//# sourceMappingURL=chunk-BVYWHWII.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/catalog.ts"],"sourcesContent":["import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"add\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"add\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"add\",\"path\":\"/clips\",\"value\":[]}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"add\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n 'First add /composition with {id, fps:30, width:1920, height:1080, durationInFrames}: {\"op\":\"add\",\"path\":\"/composition\",\"value\":{...}}',\n 'Then add /tracks array with video/overlay tracks: {\"op\":\"add\",\"path\":\"/tracks\",\"value\":[...]}',\n 'Then add each clip by appending to the array: {\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{...}}',\n 'Finally add /audio with {tracks:[]}: {\"op\":\"add\",\"path\":\"/audio\",\"value\":{...}}',\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n example: { title: \"Welcome\", subtitle: \"An introduction\" },\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n example: {\n src: \"https://picsum.photos/1920/1080?random=1\",\n alt: \"Hero image\",\n fit: \"cover\",\n },\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n example: {\n quote: \"The best way to predict the future is to invent it.\",\n author: \"Alan Kay\",\n },\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n example: { value: \"10M+\", label: \"Users worldwide\", prefix: \"\" },\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -996,7 +996,8 @@ var standardComponentDefinitions = {
|
|
|
996
996
|
}),
|
|
997
997
|
type: "scene",
|
|
998
998
|
defaultDuration: 90,
|
|
999
|
-
description: "Full-screen title card with centered text. Use for intros, outros, and section breaks."
|
|
999
|
+
description: "Full-screen title card with centered text. Use for intros, outros, and section breaks.",
|
|
1000
|
+
example: { title: "Welcome", subtitle: "An introduction" }
|
|
1000
1001
|
},
|
|
1001
1002
|
ImageSlide: {
|
|
1002
1003
|
props: import_zod.z.object({
|
|
@@ -1007,7 +1008,12 @@ var standardComponentDefinitions = {
|
|
|
1007
1008
|
}),
|
|
1008
1009
|
type: "image",
|
|
1009
1010
|
defaultDuration: 150,
|
|
1010
|
-
description: "Full-screen image display. Use for product shots, photos, and visual content."
|
|
1011
|
+
description: "Full-screen image display. Use for product shots, photos, and visual content.",
|
|
1012
|
+
example: {
|
|
1013
|
+
src: "https://picsum.photos/1920/1080?random=1",
|
|
1014
|
+
alt: "Hero image",
|
|
1015
|
+
fit: "cover"
|
|
1016
|
+
}
|
|
1011
1017
|
},
|
|
1012
1018
|
SplitScreen: {
|
|
1013
1019
|
props: import_zod.z.object({
|
|
@@ -1030,7 +1036,11 @@ var standardComponentDefinitions = {
|
|
|
1030
1036
|
}),
|
|
1031
1037
|
type: "scene",
|
|
1032
1038
|
defaultDuration: 150,
|
|
1033
|
-
description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images."
|
|
1039
|
+
description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.",
|
|
1040
|
+
example: {
|
|
1041
|
+
quote: "The best way to predict the future is to invent it.",
|
|
1042
|
+
author: "Alan Kay"
|
|
1043
|
+
}
|
|
1034
1044
|
},
|
|
1035
1045
|
StatCard: {
|
|
1036
1046
|
props: import_zod.z.object({
|
|
@@ -1042,7 +1052,8 @@ var standardComponentDefinitions = {
|
|
|
1042
1052
|
}),
|
|
1043
1053
|
type: "scene",
|
|
1044
1054
|
defaultDuration: 90,
|
|
1045
|
-
description: "Large statistic display. Use for key metrics and numbers."
|
|
1055
|
+
description: "Large statistic display. Use for key metrics and numbers.",
|
|
1056
|
+
example: { value: "10M+", label: "Users worldwide", prefix: "" }
|
|
1046
1057
|
},
|
|
1047
1058
|
TypingText: {
|
|
1048
1059
|
props: import_zod.z.object({
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/components/hooks.ts","../src/components/ClipWrapper.tsx","../src/components/standard.tsx","../src/components/Renderer.tsx","../src/catalog.ts"],"sourcesContent":["// Schema (Remotion's timeline-based spec format)\nexport { schema, type RemotionSchema, type RemotionSpec } from \"./schema\";\n\n// Catalog-aware types for Remotion\nexport type {\n FrameContext,\n VideoComponentContext,\n VideoComponentFn,\n VideoComponents,\n TransitionFn,\n BuiltInTransition,\n EffectFn,\n Effects,\n} from \"./catalog-types\";\n\n// Core types (re-exported for convenience)\nexport type { Spec } from \"@json-render/core\";\n\n// =============================================================================\n// Components - Pre-built Remotion components for rendering timelines\n// =============================================================================\n\n// Component types\nexport type {\n Clip,\n TimelineSpec,\n AudioTrack,\n TransitionStyles,\n MotionStyles,\n Motion,\n MotionState,\n MotionLoop,\n SpringConfig,\n ClipComponent,\n ComponentRegistry,\n} from \"./components\";\n\n// Hooks and utilities\nexport { useTransition, useMotion, ClipWrapper } from \"./components\";\n\n// Standard components\nexport {\n TitleCard,\n ImageSlide,\n SplitScreen,\n QuoteCard,\n StatCard,\n LowerThird,\n TextOverlay,\n TypingText,\n LogoBug,\n VideoClip,\n} from \"./components\";\n\n// Renderer and component registry\nexport { Renderer, standardComponents } from \"./components\";\n\n// =============================================================================\n// Catalog Definitions - Pre-built definitions for use in catalogs\n// =============================================================================\n\nexport {\n standardComponentDefinitions,\n standardTransitionDefinitions,\n standardEffectDefinitions,\n type ComponentDefinition,\n type TransitionDefinition,\n type EffectDefinition,\n} from \"./catalog\";\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"add\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"add\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"add\",\"path\":\"/clips\",\"value\":[]}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"add\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n 'First add /composition with {id, fps:30, width:1920, height:1080, durationInFrames}: {\"op\":\"add\",\"path\":\"/composition\",\"value\":{...}}',\n 'Then add /tracks array with video/overlay tracks: {\"op\":\"add\",\"path\":\"/tracks\",\"value\":[...]}',\n 'Then add each clip by appending to the array: {\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{...}}',\n 'Finally add /audio with {tracks:[]}: {\"op\":\"add\",\"path\":\"/audio\",\"value\":{...}}',\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","\"use client\";\n\nimport { useVideoConfig, spring, interpolate, Easing } from \"remotion\";\nimport type { Clip, TransitionStyles, MotionStyles } from \"./types\";\n\n/**\n * Calculate transition styles based on clip configuration\n *\n * Handles both transitionIn and transitionOut with support for:\n * - fade\n * - slideLeft / slideRight\n * - slideUp / slideDown\n * - zoom\n * - wipe\n */\nexport function useTransition(clip: Clip, frame: number): TransitionStyles {\n const { fps } = useVideoConfig();\n const relativeFrame = frame - clip.from;\n const clipEnd = clip.durationInFrames;\n\n let opacity = 1;\n let translateX = 0;\n let translateY = 0;\n let scale = 1;\n\n // Transition in\n if (clip.transitionIn && relativeFrame < clip.transitionIn.durationInFrames) {\n const progress = relativeFrame / clip.transitionIn.durationInFrames;\n const easedProgress = spring({\n frame: relativeFrame,\n fps,\n config: { damping: 200 },\n durationInFrames: clip.transitionIn.durationInFrames,\n });\n\n switch (clip.transitionIn.type) {\n case \"fade\":\n opacity = easedProgress;\n break;\n case \"slideLeft\":\n translateX = interpolate(easedProgress, [0, 1], [100, 0]);\n opacity = easedProgress;\n break;\n case \"slideRight\":\n translateX = interpolate(easedProgress, [0, 1], [-100, 0]);\n opacity = easedProgress;\n break;\n case \"slideUp\":\n translateY = interpolate(easedProgress, [0, 1], [100, 0]);\n opacity = easedProgress;\n break;\n case \"slideDown\":\n translateY = interpolate(easedProgress, [0, 1], [-100, 0]);\n opacity = easedProgress;\n break;\n case \"zoom\":\n scale = interpolate(easedProgress, [0, 1], [0.8, 1]);\n opacity = easedProgress;\n break;\n case \"wipe\":\n opacity = progress;\n break;\n }\n }\n\n // Transition out\n if (\n clip.transitionOut &&\n relativeFrame > clipEnd - clip.transitionOut.durationInFrames\n ) {\n const outStart = clipEnd - clip.transitionOut.durationInFrames;\n const outProgress =\n (relativeFrame - outStart) / clip.transitionOut.durationInFrames;\n const easedOutProgress = 1 - outProgress;\n\n switch (clip.transitionOut.type) {\n case \"fade\":\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideLeft\":\n translateX = interpolate(outProgress, [0, 1], [0, -100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideRight\":\n translateX = interpolate(outProgress, [0, 1], [0, 100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideUp\":\n translateY = interpolate(outProgress, [0, 1], [0, -100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideDown\":\n translateY = interpolate(outProgress, [0, 1], [0, 100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"zoom\":\n scale = interpolate(outProgress, [0, 1], [1, 1.2]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n }\n }\n\n return { opacity, translateX, translateY, scale };\n}\n\n/**\n * Calculate motion styles based on clip's motion configuration\n *\n * Handles declarative motion:\n * - enter: animate FROM values TO neutral\n * - exit: animate FROM neutral TO values\n * - loop: continuous animation during clip lifetime\n * - spring: physics-based easing\n */\nexport function useMotion(clip: Clip, frame: number): MotionStyles {\n const { fps } = useVideoConfig();\n const relativeFrame = frame - clip.from;\n const clipEnd = clip.durationInFrames;\n\n // Default neutral values\n let opacity = 1;\n let translateX = 0;\n let translateY = 0;\n let scale = 1;\n let rotate = 0;\n\n const motion = clip.motion;\n if (!motion) {\n return { opacity, translateX, translateY, scale, rotate };\n }\n\n // Spring config with defaults\n const springConfig = {\n damping: motion.spring?.damping ?? 20,\n stiffness: motion.spring?.stiffness ?? 100,\n mass: motion.spring?.mass ?? 1,\n };\n\n // Enter animation\n if (motion.enter) {\n const enterDuration = motion.enter.duration ?? 20;\n\n if (relativeFrame < enterDuration) {\n const progress = spring({\n frame: relativeFrame,\n fps,\n config: springConfig,\n durationInFrames: enterDuration,\n });\n\n // Interpolate FROM enter values TO neutral (1, 0, 0, 1, 0)\n if (motion.enter.opacity !== undefined) {\n opacity = interpolate(progress, [0, 1], [motion.enter.opacity, 1]);\n }\n if (motion.enter.scale !== undefined) {\n scale = interpolate(progress, [0, 1], [motion.enter.scale, 1]);\n }\n if (motion.enter.x !== undefined) {\n translateX = interpolate(progress, [0, 1], [motion.enter.x, 0]);\n }\n if (motion.enter.y !== undefined) {\n translateY = interpolate(progress, [0, 1], [motion.enter.y, 0]);\n }\n if (motion.enter.rotate !== undefined) {\n rotate = interpolate(progress, [0, 1], [motion.enter.rotate, 0]);\n }\n }\n }\n\n // Exit animation\n if (motion.exit) {\n const exitDuration = motion.exit.duration ?? 20;\n const exitStart = clipEnd - exitDuration;\n\n if (relativeFrame >= exitStart) {\n const exitFrame = relativeFrame - exitStart;\n const progress = spring({\n frame: exitFrame,\n fps,\n config: springConfig,\n durationInFrames: exitDuration,\n });\n\n // Interpolate FROM neutral TO exit values\n if (motion.exit.opacity !== undefined) {\n const exitOpacity = interpolate(\n progress,\n [0, 1],\n [1, motion.exit.opacity],\n );\n opacity = Math.min(opacity, exitOpacity);\n }\n if (motion.exit.scale !== undefined) {\n const exitScale = interpolate(progress, [0, 1], [1, motion.exit.scale]);\n // Multiply scales for composition\n scale = scale * exitScale;\n }\n if (motion.exit.x !== undefined) {\n const exitX = interpolate(progress, [0, 1], [0, motion.exit.x]);\n translateX = translateX + exitX;\n }\n if (motion.exit.y !== undefined) {\n const exitY = interpolate(progress, [0, 1], [0, motion.exit.y]);\n translateY = translateY + exitY;\n }\n if (motion.exit.rotate !== undefined) {\n const exitRotate = interpolate(\n progress,\n [0, 1],\n [0, motion.exit.rotate],\n );\n rotate = rotate + exitRotate;\n }\n }\n }\n\n // Loop animation (continuous during clip)\n if (motion.loop) {\n const { property, from, to, duration, easing = \"ease\" } = motion.loop;\n\n // Calculate loop progress (0-1 repeating)\n const loopFrame = relativeFrame % duration;\n let loopProgress: number;\n\n switch (easing) {\n case \"linear\":\n loopProgress = loopFrame / duration;\n break;\n case \"spring\":\n loopProgress = spring({\n frame: loopFrame,\n fps,\n config: springConfig,\n durationInFrames: duration,\n });\n break;\n case \"ease\":\n default:\n // Sine ease in-out for smooth looping\n loopProgress = interpolate(\n loopFrame,\n [0, duration / 2, duration],\n [0, 1, 0],\n { extrapolateRight: \"clamp\" },\n );\n break;\n }\n\n const loopValue = interpolate(loopProgress, [0, 1], [from, to]);\n\n switch (property) {\n case \"opacity\":\n opacity = opacity * loopValue;\n break;\n case \"scale\":\n scale = scale * loopValue;\n break;\n case \"x\":\n translateX = translateX + loopValue;\n break;\n case \"y\":\n translateY = translateY + loopValue;\n break;\n case \"rotate\":\n rotate = rotate + loopValue;\n break;\n }\n }\n\n return { opacity, translateX, translateY, scale, rotate };\n}\n","\"use client\";\n\nimport { AbsoluteFill, useCurrentFrame } from \"remotion\";\nimport { useTransition, useMotion } from \"./hooks\";\nimport type { Clip } from \"./types\";\n\ninterface ClipWrapperProps {\n clip: Clip;\n children: React.ReactNode;\n}\n\n/**\n * Wrapper component that applies transition and motion animations to clips\n *\n * Automatically handles:\n * - transitionIn/transitionOut: basic transition presets (fade, slide, zoom, etc.)\n * - motion: declarative enter/exit/loop animations with spring physics\n *\n * Transitions and motion compose together:\n * - Opacity: multiplied (both affect final opacity)\n * - Transforms: added (both contribute to final position/scale/rotation)\n */\nexport function ClipWrapper({ clip, children }: ClipWrapperProps) {\n const frame = useCurrentFrame();\n const absoluteFrame = frame + clip.from;\n\n // Get transition styles (from transitionIn/transitionOut)\n const transition = useTransition(clip, absoluteFrame);\n\n // Get motion styles (from motion.enter/exit/loop)\n const motion = useMotion(clip, absoluteFrame);\n\n // Compose styles: multiply opacity, add transforms\n const composedOpacity = transition.opacity * motion.opacity;\n const composedTranslateX = transition.translateX + motion.translateX;\n const composedTranslateY = transition.translateY + motion.translateY;\n const composedScale = transition.scale * motion.scale;\n const composedRotate = motion.rotate; // Only from motion (transitions don't rotate)\n\n return (\n <AbsoluteFill\n style={{\n opacity: composedOpacity,\n transform: `translateX(${composedTranslateX}%) translateY(${composedTranslateY}%) scale(${composedScale}) rotate(${composedRotate}deg)`,\n }}\n >\n {children}\n </AbsoluteFill>\n );\n}\n","\"use client\";\n\nimport {\n AbsoluteFill,\n useCurrentFrame,\n useVideoConfig,\n spring,\n} from \"remotion\";\nimport { ClipWrapper } from \"./ClipWrapper\";\nimport type { Clip } from \"./types\";\n\n// =============================================================================\n// TitleCard - Full-screen title with optional subtitle\n// =============================================================================\n\nexport function TitleCard({ clip }: { clip: Clip }) {\n const { title, subtitle, backgroundColor, textColor } = clip.props as {\n title: string;\n subtitle?: string;\n backgroundColor?: string;\n textColor?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#1a1a2e\",\n color: textColor || \"#ffffff\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 40,\n }}\n >\n <div\n style={{\n fontSize: 72,\n fontWeight: \"bold\",\n textAlign: \"center\",\n marginBottom: 16,\n }}\n >\n {title}\n </div>\n {subtitle && (\n <div\n style={{\n fontSize: 36,\n opacity: 0.7,\n textAlign: \"center\",\n }}\n >\n {subtitle}\n </div>\n )}\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// ImageSlide - Full-screen image display\n// =============================================================================\n\nexport function ImageSlide({ clip }: { clip: Clip }) {\n const { src, alt, fit, backgroundColor } = clip.props as {\n src: string;\n alt: string;\n fit?: \"cover\" | \"contain\";\n backgroundColor?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#0a0a0a\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {src ? (\n <img\n src={src}\n alt={alt}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: fit || \"cover\",\n }}\n />\n ) : (\n <div style={{ color: \"rgba(255,255,255,0.5)\", fontSize: 24 }}>\n [{alt}]\n </div>\n )}\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// SplitScreen - Two-panel comparison view\n// =============================================================================\n\nexport function SplitScreen({ clip }: { clip: Clip }) {\n const { leftTitle, rightTitle, leftColor, rightColor } = clip.props as {\n leftTitle: string;\n rightTitle: string;\n leftColor?: string;\n rightColor?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill style={{ display: \"flex\", flexDirection: \"row\" }}>\n <div\n style={{\n flex: 1,\n backgroundColor: leftColor || \"#1a1a2e\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n }}\n >\n <div style={{ fontSize: 48, fontWeight: \"bold\" }}>{leftTitle}</div>\n </div>\n <div\n style={{\n flex: 1,\n backgroundColor: rightColor || \"#2e1a1a\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n }}\n >\n <div style={{ fontSize: 48, fontWeight: \"bold\" }}>{rightTitle}</div>\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// QuoteCard - Quote with attribution\n// =============================================================================\n\nexport function QuoteCard({ clip }: { clip: Clip }) {\n const { quote, author, backgroundColor, textColor, transparent } =\n clip.props as {\n quote: string;\n author?: string;\n backgroundColor?: string;\n textColor?: string;\n transparent?: boolean;\n };\n\n // Use transparent background for overlays, or specified color, or default dark\n const bgColor = transparent ? \"transparent\" : backgroundColor || \"#1a1a2e\";\n\n const color = textColor || \"#ffffff\";\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: bgColor,\n color,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 80,\n }}\n >\n <div\n style={{\n fontSize: 48,\n fontStyle: \"italic\",\n textAlign: \"center\",\n marginBottom: 24,\n textShadow: transparent ? \"2px 2px 8px rgba(0,0,0,0.8)\" : \"none\",\n }}\n >\n “{quote}”\n </div>\n {author && (\n <div\n style={{\n fontSize: 28,\n opacity: 0.9,\n textShadow: transparent ? \"1px 1px 4px rgba(0,0,0,0.8)\" : \"none\",\n }}\n >\n - {author}\n </div>\n )}\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// StatCard - Large statistic display with animation\n// =============================================================================\n\nexport function StatCard({ clip }: { clip: Clip }) {\n const { value, label, prefix, suffix, backgroundColor } = clip.props as {\n value: string | number;\n label: string;\n prefix?: string;\n suffix?: string;\n backgroundColor?: string;\n };\n\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n // Animate the number counting up\n const animationProgress = spring({\n frame,\n fps,\n config: { damping: 100 },\n durationInFrames: 30,\n });\n\n const numValue = typeof value === \"number\" ? value : parseFloat(value) || 0;\n const displayValue = Math.round(numValue * animationProgress);\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#1a1a2e\",\n color: \"#ffffff\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ fontSize: 96, fontWeight: \"bold\", marginBottom: 16 }}>\n {prefix || \"\"}\n {typeof value === \"number\" ? displayValue : value}\n {suffix || \"\"}\n </div>\n <div style={{ fontSize: 32, opacity: 0.7 }}>{label}</div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// LowerThird - Name/title overlay\n// =============================================================================\n\nexport function LowerThird({ clip }: { clip: Clip }) {\n const { name, title } = clip.props as {\n name: string;\n title?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill>\n <div\n style={{\n position: \"absolute\",\n bottom: 100,\n left: 40,\n backgroundColor: \"rgba(0,0,0,0.8)\",\n color: \"#ffffff\",\n padding: \"16px 24px\",\n borderRadius: 8,\n }}\n >\n <div style={{ fontSize: 28, fontWeight: \"bold\" }}>{name}</div>\n {title && <div style={{ fontSize: 20, opacity: 0.7 }}>{title}</div>}\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// TextOverlay - Simple text overlay\n// =============================================================================\n\nexport function TextOverlay({ clip }: { clip: Clip }) {\n const { text, position, fontSize } = clip.props as {\n text: string;\n position?: \"top\" | \"center\" | \"bottom\";\n fontSize?: \"small\" | \"medium\" | \"large\";\n };\n\n const positionStyles: Record<string, React.CSSProperties> = {\n top: { top: 100, left: 0, right: 0 },\n center: { top: \"50%\", left: 0, right: 0, transform: \"translateY(-50%)\" },\n bottom: { bottom: 100, left: 0, right: 0 },\n };\n\n const fontSizes: Record<string, number> = {\n small: 24,\n medium: 36,\n large: 56,\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill>\n <div\n style={{\n position: \"absolute\",\n ...positionStyles[position || \"center\"],\n textAlign: \"center\",\n color: \"#ffffff\",\n fontSize: fontSizes[fontSize || \"medium\"],\n padding: 20,\n textShadow: \"2px 2px 4px rgba(0,0,0,0.5)\",\n }}\n >\n {text}\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// TypingText - Terminal-style typing animation\n// =============================================================================\n\nexport function TypingText({ clip }: { clip: Clip }) {\n const {\n text,\n backgroundColor,\n textColor,\n fontSize,\n fontFamily,\n showCursor = true,\n cursorChar = \"|\",\n charsPerSecond = 15,\n } = clip.props as {\n text: string;\n backgroundColor?: string;\n textColor?: string;\n fontSize?: number;\n fontFamily?: \"monospace\" | \"sans-serif\" | \"serif\";\n showCursor?: boolean;\n cursorChar?: string;\n charsPerSecond?: number;\n };\n\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n // Calculate how many characters to show based on current frame\n const framesPerChar = fps / charsPerSecond;\n const charsToShow = Math.min(Math.floor(frame / framesPerChar), text.length);\n const displayedText = text.slice(0, charsToShow);\n const isTypingComplete = charsToShow >= text.length;\n\n // Blinking cursor (blinks every 0.5 seconds)\n const cursorVisible =\n showCursor &&\n (Math.floor(frame / (fps / 2)) % 2 === 0 || !isTypingComplete);\n\n const fontFamilyMap: Record<string, string> = {\n monospace: \"'Courier New', Consolas, monospace\",\n \"sans-serif\": \"system-ui, -apple-system, sans-serif\",\n serif: \"Georgia, 'Times New Roman', serif\",\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#1e1e1e\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 60,\n }}\n >\n <div\n style={{\n color: textColor || \"#00ff00\",\n fontSize: fontSize || 48,\n fontFamily: fontFamilyMap[fontFamily || \"monospace\"],\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n maxWidth: \"90%\",\n textAlign: \"left\",\n }}\n >\n {displayedText}\n {cursorVisible && (\n <span\n style={{\n opacity: isTypingComplete\n ? Math.floor(frame / (fps / 2)) % 2 === 0\n ? 1\n : 0\n : 1,\n }}\n >\n {cursorChar}\n </span>\n )}\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// LogoBug - Corner watermark/logo\n// =============================================================================\n\nexport function LogoBug({ clip }: { clip: Clip }) {\n const { position, opacity: propOpacity } = clip.props as {\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n opacity?: number;\n };\n\n const positionStyles: Record<string, React.CSSProperties> = {\n \"top-left\": { top: 20, left: 20 },\n \"top-right\": { top: 20, right: 20 },\n \"bottom-left\": { bottom: 20, left: 20 },\n \"bottom-right\": { bottom: 20, right: 20 },\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill>\n <div\n style={{\n position: \"absolute\",\n ...positionStyles[position || \"bottom-right\"],\n opacity: propOpacity ?? 0.5,\n color: \"#ffffff\",\n fontSize: 14,\n fontWeight: \"bold\",\n textShadow: \"1px 1px 2px rgba(0,0,0,0.5)\",\n }}\n >\n LOGO\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// VideoClip - Video file playback (placeholder)\n// =============================================================================\n\nexport function VideoClip({ clip }: { clip: Clip }) {\n const { src } = clip.props as {\n src: string;\n startFrom?: number;\n volume?: number;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: \"#000000\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"rgba(255,255,255,0.5)\",\n }}\n >\n <div>[Video: {src}]</div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n","\"use client\";\n\nimport React, { type ErrorInfo, type ReactNode } from \"react\";\nimport { AbsoluteFill, Sequence } from \"remotion\";\nimport type { TimelineSpec, ComponentRegistry, Clip } from \"./types\";\n\n// Import standard components\nimport {\n TitleCard,\n ImageSlide,\n SplitScreen,\n QuoteCard,\n StatCard,\n LowerThird,\n TextOverlay,\n TypingText,\n LogoBug,\n VideoClip,\n} from \"./standard\";\n\n/**\n * Standard components provided by @json-render/remotion\n */\nexport const standardComponents: ComponentRegistry = {\n TitleCard,\n ImageSlide,\n SplitScreen,\n QuoteCard,\n StatCard,\n LowerThird,\n TextOverlay,\n TypingText,\n LogoBug,\n VideoClip,\n};\n\n// ---------------------------------------------------------------------------\n// ClipErrorBoundary – catches rendering errors in individual clips so\n// a single bad clip never crashes the entire composition.\n// ---------------------------------------------------------------------------\n\ninterface ClipErrorBoundaryProps {\n clipId: string;\n component: string;\n children: ReactNode;\n}\n\ninterface ClipErrorBoundaryState {\n hasError: boolean;\n}\n\nclass ClipErrorBoundary extends React.Component<\n ClipErrorBoundaryProps,\n ClipErrorBoundaryState\n> {\n constructor(props: ClipErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ClipErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n console.error(\n `[json-render/remotion] Rendering error in clip \"${this.props.clipId}\" (<${this.props.component}>):`,\n error,\n info.componentStack,\n );\n }\n\n render() {\n if (this.state.hasError) {\n return null;\n }\n return this.props.children;\n }\n}\n\ninterface RendererProps {\n /** The timeline spec to render */\n spec: TimelineSpec;\n /**\n * Custom component registry to merge with standard components.\n * Custom components override standard ones with the same name.\n */\n components?: ComponentRegistry;\n}\n\n/**\n * Renders a timeline spec into Remotion components\n *\n * @example\n * // Use with standard components only\n * <Renderer spec={mySpec} />\n *\n * @example\n * // Add custom components\n * <Renderer\n * spec={mySpec}\n * components={{\n * CustomScene: MyCustomSceneComponent,\n * }}\n * />\n */\nexport function Renderer({\n spec,\n components: customComponents,\n}: RendererProps) {\n // Merge standard + custom components (custom overrides standard)\n const components: ComponentRegistry = {\n ...standardComponents,\n ...customComponents,\n };\n\n if (!spec.clips || spec.clips.length === 0) {\n return (\n <AbsoluteFill\n style={{\n backgroundColor: \"#1a1a2e\",\n color: \"#ffffff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ fontSize: 24, opacity: 0.5 }}>No clips</div>\n </AbsoluteFill>\n );\n }\n\n // Separate main track clips from overlay clips\n const mainClips = spec.clips.filter((c) => c.trackId === \"main\");\n const overlayClips = spec.clips.filter((c) => c.trackId === \"overlay\");\n\n const renderClip = (clip: Clip) => {\n const Component = components[clip.component];\n if (!Component) {\n console.warn(`Unknown component: ${clip.component}`);\n return null;\n }\n\n return (\n <Sequence\n key={clip.id}\n from={clip.from}\n durationInFrames={clip.durationInFrames}\n >\n <ClipErrorBoundary clipId={clip.id} component={clip.component}>\n <Component clip={clip} />\n </ClipErrorBoundary>\n </Sequence>\n );\n };\n\n return (\n <AbsoluteFill style={{ backgroundColor: \"#000000\" }}>\n {/* Main track clips */}\n {mainClips.map(renderClip)}\n\n {/* Overlay clips */}\n {overlayClips.map(renderClip)}\n </AbsoluteFill>\n );\n}\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":["import_remotion","import_remotion","import_jsx_runtime","import_remotion","import_jsx_runtime","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/components/hooks.ts","../src/components/ClipWrapper.tsx","../src/components/standard.tsx","../src/components/Renderer.tsx","../src/catalog.ts"],"sourcesContent":["// Schema (Remotion's timeline-based spec format)\nexport { schema, type RemotionSchema, type RemotionSpec } from \"./schema\";\n\n// Catalog-aware types for Remotion\nexport type {\n FrameContext,\n VideoComponentContext,\n VideoComponentFn,\n VideoComponents,\n TransitionFn,\n BuiltInTransition,\n EffectFn,\n Effects,\n} from \"./catalog-types\";\n\n// Core types (re-exported for convenience)\nexport type { Spec } from \"@json-render/core\";\n\n// =============================================================================\n// Components - Pre-built Remotion components for rendering timelines\n// =============================================================================\n\n// Component types\nexport type {\n Clip,\n TimelineSpec,\n AudioTrack,\n TransitionStyles,\n MotionStyles,\n Motion,\n MotionState,\n MotionLoop,\n SpringConfig,\n ClipComponent,\n ComponentRegistry,\n} from \"./components\";\n\n// Hooks and utilities\nexport { useTransition, useMotion, ClipWrapper } from \"./components\";\n\n// Standard components\nexport {\n TitleCard,\n ImageSlide,\n SplitScreen,\n QuoteCard,\n StatCard,\n LowerThird,\n TextOverlay,\n TypingText,\n LogoBug,\n VideoClip,\n} from \"./components\";\n\n// Renderer and component registry\nexport { Renderer, standardComponents } from \"./components\";\n\n// =============================================================================\n// Catalog Definitions - Pre-built definitions for use in catalogs\n// =============================================================================\n\nexport {\n standardComponentDefinitions,\n standardTransitionDefinitions,\n standardEffectDefinitions,\n type ComponentDefinition,\n type TransitionDefinition,\n type EffectDefinition,\n} from \"./catalog\";\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"add\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"add\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"add\",\"path\":\"/clips\",\"value\":[]}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"add\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n 'First add /composition with {id, fps:30, width:1920, height:1080, durationInFrames}: {\"op\":\"add\",\"path\":\"/composition\",\"value\":{...}}',\n 'Then add /tracks array with video/overlay tracks: {\"op\":\"add\",\"path\":\"/tracks\",\"value\":[...]}',\n 'Then add each clip by appending to the array: {\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{...}}',\n 'Finally add /audio with {tracks:[]}: {\"op\":\"add\",\"path\":\"/audio\",\"value\":{...}}',\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","\"use client\";\n\nimport { useVideoConfig, spring, interpolate, Easing } from \"remotion\";\nimport type { Clip, TransitionStyles, MotionStyles } from \"./types\";\n\n/**\n * Calculate transition styles based on clip configuration\n *\n * Handles both transitionIn and transitionOut with support for:\n * - fade\n * - slideLeft / slideRight\n * - slideUp / slideDown\n * - zoom\n * - wipe\n */\nexport function useTransition(clip: Clip, frame: number): TransitionStyles {\n const { fps } = useVideoConfig();\n const relativeFrame = frame - clip.from;\n const clipEnd = clip.durationInFrames;\n\n let opacity = 1;\n let translateX = 0;\n let translateY = 0;\n let scale = 1;\n\n // Transition in\n if (clip.transitionIn && relativeFrame < clip.transitionIn.durationInFrames) {\n const progress = relativeFrame / clip.transitionIn.durationInFrames;\n const easedProgress = spring({\n frame: relativeFrame,\n fps,\n config: { damping: 200 },\n durationInFrames: clip.transitionIn.durationInFrames,\n });\n\n switch (clip.transitionIn.type) {\n case \"fade\":\n opacity = easedProgress;\n break;\n case \"slideLeft\":\n translateX = interpolate(easedProgress, [0, 1], [100, 0]);\n opacity = easedProgress;\n break;\n case \"slideRight\":\n translateX = interpolate(easedProgress, [0, 1], [-100, 0]);\n opacity = easedProgress;\n break;\n case \"slideUp\":\n translateY = interpolate(easedProgress, [0, 1], [100, 0]);\n opacity = easedProgress;\n break;\n case \"slideDown\":\n translateY = interpolate(easedProgress, [0, 1], [-100, 0]);\n opacity = easedProgress;\n break;\n case \"zoom\":\n scale = interpolate(easedProgress, [0, 1], [0.8, 1]);\n opacity = easedProgress;\n break;\n case \"wipe\":\n opacity = progress;\n break;\n }\n }\n\n // Transition out\n if (\n clip.transitionOut &&\n relativeFrame > clipEnd - clip.transitionOut.durationInFrames\n ) {\n const outStart = clipEnd - clip.transitionOut.durationInFrames;\n const outProgress =\n (relativeFrame - outStart) / clip.transitionOut.durationInFrames;\n const easedOutProgress = 1 - outProgress;\n\n switch (clip.transitionOut.type) {\n case \"fade\":\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideLeft\":\n translateX = interpolate(outProgress, [0, 1], [0, -100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideRight\":\n translateX = interpolate(outProgress, [0, 1], [0, 100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideUp\":\n translateY = interpolate(outProgress, [0, 1], [0, -100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"slideDown\":\n translateY = interpolate(outProgress, [0, 1], [0, 100]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n case \"zoom\":\n scale = interpolate(outProgress, [0, 1], [1, 1.2]);\n opacity = Math.min(opacity, easedOutProgress);\n break;\n }\n }\n\n return { opacity, translateX, translateY, scale };\n}\n\n/**\n * Calculate motion styles based on clip's motion configuration\n *\n * Handles declarative motion:\n * - enter: animate FROM values TO neutral\n * - exit: animate FROM neutral TO values\n * - loop: continuous animation during clip lifetime\n * - spring: physics-based easing\n */\nexport function useMotion(clip: Clip, frame: number): MotionStyles {\n const { fps } = useVideoConfig();\n const relativeFrame = frame - clip.from;\n const clipEnd = clip.durationInFrames;\n\n // Default neutral values\n let opacity = 1;\n let translateX = 0;\n let translateY = 0;\n let scale = 1;\n let rotate = 0;\n\n const motion = clip.motion;\n if (!motion) {\n return { opacity, translateX, translateY, scale, rotate };\n }\n\n // Spring config with defaults\n const springConfig = {\n damping: motion.spring?.damping ?? 20,\n stiffness: motion.spring?.stiffness ?? 100,\n mass: motion.spring?.mass ?? 1,\n };\n\n // Enter animation\n if (motion.enter) {\n const enterDuration = motion.enter.duration ?? 20;\n\n if (relativeFrame < enterDuration) {\n const progress = spring({\n frame: relativeFrame,\n fps,\n config: springConfig,\n durationInFrames: enterDuration,\n });\n\n // Interpolate FROM enter values TO neutral (1, 0, 0, 1, 0)\n if (motion.enter.opacity !== undefined) {\n opacity = interpolate(progress, [0, 1], [motion.enter.opacity, 1]);\n }\n if (motion.enter.scale !== undefined) {\n scale = interpolate(progress, [0, 1], [motion.enter.scale, 1]);\n }\n if (motion.enter.x !== undefined) {\n translateX = interpolate(progress, [0, 1], [motion.enter.x, 0]);\n }\n if (motion.enter.y !== undefined) {\n translateY = interpolate(progress, [0, 1], [motion.enter.y, 0]);\n }\n if (motion.enter.rotate !== undefined) {\n rotate = interpolate(progress, [0, 1], [motion.enter.rotate, 0]);\n }\n }\n }\n\n // Exit animation\n if (motion.exit) {\n const exitDuration = motion.exit.duration ?? 20;\n const exitStart = clipEnd - exitDuration;\n\n if (relativeFrame >= exitStart) {\n const exitFrame = relativeFrame - exitStart;\n const progress = spring({\n frame: exitFrame,\n fps,\n config: springConfig,\n durationInFrames: exitDuration,\n });\n\n // Interpolate FROM neutral TO exit values\n if (motion.exit.opacity !== undefined) {\n const exitOpacity = interpolate(\n progress,\n [0, 1],\n [1, motion.exit.opacity],\n );\n opacity = Math.min(opacity, exitOpacity);\n }\n if (motion.exit.scale !== undefined) {\n const exitScale = interpolate(progress, [0, 1], [1, motion.exit.scale]);\n // Multiply scales for composition\n scale = scale * exitScale;\n }\n if (motion.exit.x !== undefined) {\n const exitX = interpolate(progress, [0, 1], [0, motion.exit.x]);\n translateX = translateX + exitX;\n }\n if (motion.exit.y !== undefined) {\n const exitY = interpolate(progress, [0, 1], [0, motion.exit.y]);\n translateY = translateY + exitY;\n }\n if (motion.exit.rotate !== undefined) {\n const exitRotate = interpolate(\n progress,\n [0, 1],\n [0, motion.exit.rotate],\n );\n rotate = rotate + exitRotate;\n }\n }\n }\n\n // Loop animation (continuous during clip)\n if (motion.loop) {\n const { property, from, to, duration, easing = \"ease\" } = motion.loop;\n\n // Calculate loop progress (0-1 repeating)\n const loopFrame = relativeFrame % duration;\n let loopProgress: number;\n\n switch (easing) {\n case \"linear\":\n loopProgress = loopFrame / duration;\n break;\n case \"spring\":\n loopProgress = spring({\n frame: loopFrame,\n fps,\n config: springConfig,\n durationInFrames: duration,\n });\n break;\n case \"ease\":\n default:\n // Sine ease in-out for smooth looping\n loopProgress = interpolate(\n loopFrame,\n [0, duration / 2, duration],\n [0, 1, 0],\n { extrapolateRight: \"clamp\" },\n );\n break;\n }\n\n const loopValue = interpolate(loopProgress, [0, 1], [from, to]);\n\n switch (property) {\n case \"opacity\":\n opacity = opacity * loopValue;\n break;\n case \"scale\":\n scale = scale * loopValue;\n break;\n case \"x\":\n translateX = translateX + loopValue;\n break;\n case \"y\":\n translateY = translateY + loopValue;\n break;\n case \"rotate\":\n rotate = rotate + loopValue;\n break;\n }\n }\n\n return { opacity, translateX, translateY, scale, rotate };\n}\n","\"use client\";\n\nimport { AbsoluteFill, useCurrentFrame } from \"remotion\";\nimport { useTransition, useMotion } from \"./hooks\";\nimport type { Clip } from \"./types\";\n\ninterface ClipWrapperProps {\n clip: Clip;\n children: React.ReactNode;\n}\n\n/**\n * Wrapper component that applies transition and motion animations to clips\n *\n * Automatically handles:\n * - transitionIn/transitionOut: basic transition presets (fade, slide, zoom, etc.)\n * - motion: declarative enter/exit/loop animations with spring physics\n *\n * Transitions and motion compose together:\n * - Opacity: multiplied (both affect final opacity)\n * - Transforms: added (both contribute to final position/scale/rotation)\n */\nexport function ClipWrapper({ clip, children }: ClipWrapperProps) {\n const frame = useCurrentFrame();\n const absoluteFrame = frame + clip.from;\n\n // Get transition styles (from transitionIn/transitionOut)\n const transition = useTransition(clip, absoluteFrame);\n\n // Get motion styles (from motion.enter/exit/loop)\n const motion = useMotion(clip, absoluteFrame);\n\n // Compose styles: multiply opacity, add transforms\n const composedOpacity = transition.opacity * motion.opacity;\n const composedTranslateX = transition.translateX + motion.translateX;\n const composedTranslateY = transition.translateY + motion.translateY;\n const composedScale = transition.scale * motion.scale;\n const composedRotate = motion.rotate; // Only from motion (transitions don't rotate)\n\n return (\n <AbsoluteFill\n style={{\n opacity: composedOpacity,\n transform: `translateX(${composedTranslateX}%) translateY(${composedTranslateY}%) scale(${composedScale}) rotate(${composedRotate}deg)`,\n }}\n >\n {children}\n </AbsoluteFill>\n );\n}\n","\"use client\";\n\nimport {\n AbsoluteFill,\n useCurrentFrame,\n useVideoConfig,\n spring,\n} from \"remotion\";\nimport { ClipWrapper } from \"./ClipWrapper\";\nimport type { Clip } from \"./types\";\n\n// =============================================================================\n// TitleCard - Full-screen title with optional subtitle\n// =============================================================================\n\nexport function TitleCard({ clip }: { clip: Clip }) {\n const { title, subtitle, backgroundColor, textColor } = clip.props as {\n title: string;\n subtitle?: string;\n backgroundColor?: string;\n textColor?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#1a1a2e\",\n color: textColor || \"#ffffff\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 40,\n }}\n >\n <div\n style={{\n fontSize: 72,\n fontWeight: \"bold\",\n textAlign: \"center\",\n marginBottom: 16,\n }}\n >\n {title}\n </div>\n {subtitle && (\n <div\n style={{\n fontSize: 36,\n opacity: 0.7,\n textAlign: \"center\",\n }}\n >\n {subtitle}\n </div>\n )}\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// ImageSlide - Full-screen image display\n// =============================================================================\n\nexport function ImageSlide({ clip }: { clip: Clip }) {\n const { src, alt, fit, backgroundColor } = clip.props as {\n src: string;\n alt: string;\n fit?: \"cover\" | \"contain\";\n backgroundColor?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#0a0a0a\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {src ? (\n <img\n src={src}\n alt={alt}\n style={{\n width: \"100%\",\n height: \"100%\",\n objectFit: fit || \"cover\",\n }}\n />\n ) : (\n <div style={{ color: \"rgba(255,255,255,0.5)\", fontSize: 24 }}>\n [{alt}]\n </div>\n )}\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// SplitScreen - Two-panel comparison view\n// =============================================================================\n\nexport function SplitScreen({ clip }: { clip: Clip }) {\n const { leftTitle, rightTitle, leftColor, rightColor } = clip.props as {\n leftTitle: string;\n rightTitle: string;\n leftColor?: string;\n rightColor?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill style={{ display: \"flex\", flexDirection: \"row\" }}>\n <div\n style={{\n flex: 1,\n backgroundColor: leftColor || \"#1a1a2e\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n }}\n >\n <div style={{ fontSize: 48, fontWeight: \"bold\" }}>{leftTitle}</div>\n </div>\n <div\n style={{\n flex: 1,\n backgroundColor: rightColor || \"#2e1a1a\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"#ffffff\",\n }}\n >\n <div style={{ fontSize: 48, fontWeight: \"bold\" }}>{rightTitle}</div>\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// QuoteCard - Quote with attribution\n// =============================================================================\n\nexport function QuoteCard({ clip }: { clip: Clip }) {\n const { quote, author, backgroundColor, textColor, transparent } =\n clip.props as {\n quote: string;\n author?: string;\n backgroundColor?: string;\n textColor?: string;\n transparent?: boolean;\n };\n\n // Use transparent background for overlays, or specified color, or default dark\n const bgColor = transparent ? \"transparent\" : backgroundColor || \"#1a1a2e\";\n\n const color = textColor || \"#ffffff\";\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: bgColor,\n color,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 80,\n }}\n >\n <div\n style={{\n fontSize: 48,\n fontStyle: \"italic\",\n textAlign: \"center\",\n marginBottom: 24,\n textShadow: transparent ? \"2px 2px 8px rgba(0,0,0,0.8)\" : \"none\",\n }}\n >\n “{quote}”\n </div>\n {author && (\n <div\n style={{\n fontSize: 28,\n opacity: 0.9,\n textShadow: transparent ? \"1px 1px 4px rgba(0,0,0,0.8)\" : \"none\",\n }}\n >\n - {author}\n </div>\n )}\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// StatCard - Large statistic display with animation\n// =============================================================================\n\nexport function StatCard({ clip }: { clip: Clip }) {\n const { value, label, prefix, suffix, backgroundColor } = clip.props as {\n value: string | number;\n label: string;\n prefix?: string;\n suffix?: string;\n backgroundColor?: string;\n };\n\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n // Animate the number counting up\n const animationProgress = spring({\n frame,\n fps,\n config: { damping: 100 },\n durationInFrames: 30,\n });\n\n const numValue = typeof value === \"number\" ? value : parseFloat(value) || 0;\n const displayValue = Math.round(numValue * animationProgress);\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#1a1a2e\",\n color: \"#ffffff\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ fontSize: 96, fontWeight: \"bold\", marginBottom: 16 }}>\n {prefix || \"\"}\n {typeof value === \"number\" ? displayValue : value}\n {suffix || \"\"}\n </div>\n <div style={{ fontSize: 32, opacity: 0.7 }}>{label}</div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// LowerThird - Name/title overlay\n// =============================================================================\n\nexport function LowerThird({ clip }: { clip: Clip }) {\n const { name, title } = clip.props as {\n name: string;\n title?: string;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill>\n <div\n style={{\n position: \"absolute\",\n bottom: 100,\n left: 40,\n backgroundColor: \"rgba(0,0,0,0.8)\",\n color: \"#ffffff\",\n padding: \"16px 24px\",\n borderRadius: 8,\n }}\n >\n <div style={{ fontSize: 28, fontWeight: \"bold\" }}>{name}</div>\n {title && <div style={{ fontSize: 20, opacity: 0.7 }}>{title}</div>}\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// TextOverlay - Simple text overlay\n// =============================================================================\n\nexport function TextOverlay({ clip }: { clip: Clip }) {\n const { text, position, fontSize } = clip.props as {\n text: string;\n position?: \"top\" | \"center\" | \"bottom\";\n fontSize?: \"small\" | \"medium\" | \"large\";\n };\n\n const positionStyles: Record<string, React.CSSProperties> = {\n top: { top: 100, left: 0, right: 0 },\n center: { top: \"50%\", left: 0, right: 0, transform: \"translateY(-50%)\" },\n bottom: { bottom: 100, left: 0, right: 0 },\n };\n\n const fontSizes: Record<string, number> = {\n small: 24,\n medium: 36,\n large: 56,\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill>\n <div\n style={{\n position: \"absolute\",\n ...positionStyles[position || \"center\"],\n textAlign: \"center\",\n color: \"#ffffff\",\n fontSize: fontSizes[fontSize || \"medium\"],\n padding: 20,\n textShadow: \"2px 2px 4px rgba(0,0,0,0.5)\",\n }}\n >\n {text}\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// TypingText - Terminal-style typing animation\n// =============================================================================\n\nexport function TypingText({ clip }: { clip: Clip }) {\n const {\n text,\n backgroundColor,\n textColor,\n fontSize,\n fontFamily,\n showCursor = true,\n cursorChar = \"|\",\n charsPerSecond = 15,\n } = clip.props as {\n text: string;\n backgroundColor?: string;\n textColor?: string;\n fontSize?: number;\n fontFamily?: \"monospace\" | \"sans-serif\" | \"serif\";\n showCursor?: boolean;\n cursorChar?: string;\n charsPerSecond?: number;\n };\n\n const frame = useCurrentFrame();\n const { fps } = useVideoConfig();\n\n // Calculate how many characters to show based on current frame\n const framesPerChar = fps / charsPerSecond;\n const charsToShow = Math.min(Math.floor(frame / framesPerChar), text.length);\n const displayedText = text.slice(0, charsToShow);\n const isTypingComplete = charsToShow >= text.length;\n\n // Blinking cursor (blinks every 0.5 seconds)\n const cursorVisible =\n showCursor &&\n (Math.floor(frame / (fps / 2)) % 2 === 0 || !isTypingComplete);\n\n const fontFamilyMap: Record<string, string> = {\n monospace: \"'Courier New', Consolas, monospace\",\n \"sans-serif\": \"system-ui, -apple-system, sans-serif\",\n serif: \"Georgia, 'Times New Roman', serif\",\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: backgroundColor || \"#1e1e1e\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 60,\n }}\n >\n <div\n style={{\n color: textColor || \"#00ff00\",\n fontSize: fontSize || 48,\n fontFamily: fontFamilyMap[fontFamily || \"monospace\"],\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n maxWidth: \"90%\",\n textAlign: \"left\",\n }}\n >\n {displayedText}\n {cursorVisible && (\n <span\n style={{\n opacity: isTypingComplete\n ? Math.floor(frame / (fps / 2)) % 2 === 0\n ? 1\n : 0\n : 1,\n }}\n >\n {cursorChar}\n </span>\n )}\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// LogoBug - Corner watermark/logo\n// =============================================================================\n\nexport function LogoBug({ clip }: { clip: Clip }) {\n const { position, opacity: propOpacity } = clip.props as {\n position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n opacity?: number;\n };\n\n const positionStyles: Record<string, React.CSSProperties> = {\n \"top-left\": { top: 20, left: 20 },\n \"top-right\": { top: 20, right: 20 },\n \"bottom-left\": { bottom: 20, left: 20 },\n \"bottom-right\": { bottom: 20, right: 20 },\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill>\n <div\n style={{\n position: \"absolute\",\n ...positionStyles[position || \"bottom-right\"],\n opacity: propOpacity ?? 0.5,\n color: \"#ffffff\",\n fontSize: 14,\n fontWeight: \"bold\",\n textShadow: \"1px 1px 2px rgba(0,0,0,0.5)\",\n }}\n >\n LOGO\n </div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n\n// =============================================================================\n// VideoClip - Video file playback (placeholder)\n// =============================================================================\n\nexport function VideoClip({ clip }: { clip: Clip }) {\n const { src } = clip.props as {\n src: string;\n startFrom?: number;\n volume?: number;\n };\n\n return (\n <ClipWrapper clip={clip}>\n <AbsoluteFill\n style={{\n backgroundColor: \"#000000\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n color: \"rgba(255,255,255,0.5)\",\n }}\n >\n <div>[Video: {src}]</div>\n </AbsoluteFill>\n </ClipWrapper>\n );\n}\n","\"use client\";\n\nimport React, { type ErrorInfo, type ReactNode } from \"react\";\nimport { AbsoluteFill, Sequence } from \"remotion\";\nimport type { TimelineSpec, ComponentRegistry, Clip } from \"./types\";\n\n// Import standard components\nimport {\n TitleCard,\n ImageSlide,\n SplitScreen,\n QuoteCard,\n StatCard,\n LowerThird,\n TextOverlay,\n TypingText,\n LogoBug,\n VideoClip,\n} from \"./standard\";\n\n/**\n * Standard components provided by @json-render/remotion\n */\nexport const standardComponents: ComponentRegistry = {\n TitleCard,\n ImageSlide,\n SplitScreen,\n QuoteCard,\n StatCard,\n LowerThird,\n TextOverlay,\n TypingText,\n LogoBug,\n VideoClip,\n};\n\n// ---------------------------------------------------------------------------\n// ClipErrorBoundary – catches rendering errors in individual clips so\n// a single bad clip never crashes the entire composition.\n// ---------------------------------------------------------------------------\n\ninterface ClipErrorBoundaryProps {\n clipId: string;\n component: string;\n children: ReactNode;\n}\n\ninterface ClipErrorBoundaryState {\n hasError: boolean;\n}\n\nclass ClipErrorBoundary extends React.Component<\n ClipErrorBoundaryProps,\n ClipErrorBoundaryState\n> {\n constructor(props: ClipErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false };\n }\n\n static getDerivedStateFromError(): ClipErrorBoundaryState {\n return { hasError: true };\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n console.error(\n `[json-render/remotion] Rendering error in clip \"${this.props.clipId}\" (<${this.props.component}>):`,\n error,\n info.componentStack,\n );\n }\n\n render() {\n if (this.state.hasError) {\n return null;\n }\n return this.props.children;\n }\n}\n\ninterface RendererProps {\n /** The timeline spec to render */\n spec: TimelineSpec;\n /**\n * Custom component registry to merge with standard components.\n * Custom components override standard ones with the same name.\n */\n components?: ComponentRegistry;\n}\n\n/**\n * Renders a timeline spec into Remotion components\n *\n * @example\n * // Use with standard components only\n * <Renderer spec={mySpec} />\n *\n * @example\n * // Add custom components\n * <Renderer\n * spec={mySpec}\n * components={{\n * CustomScene: MyCustomSceneComponent,\n * }}\n * />\n */\nexport function Renderer({\n spec,\n components: customComponents,\n}: RendererProps) {\n // Merge standard + custom components (custom overrides standard)\n const components: ComponentRegistry = {\n ...standardComponents,\n ...customComponents,\n };\n\n if (!spec.clips || spec.clips.length === 0) {\n return (\n <AbsoluteFill\n style={{\n backgroundColor: \"#1a1a2e\",\n color: \"#ffffff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <div style={{ fontSize: 24, opacity: 0.5 }}>No clips</div>\n </AbsoluteFill>\n );\n }\n\n // Separate main track clips from overlay clips\n const mainClips = spec.clips.filter((c) => c.trackId === \"main\");\n const overlayClips = spec.clips.filter((c) => c.trackId === \"overlay\");\n\n const renderClip = (clip: Clip) => {\n const Component = components[clip.component];\n if (!Component) {\n console.warn(`Unknown component: ${clip.component}`);\n return null;\n }\n\n return (\n <Sequence\n key={clip.id}\n from={clip.from}\n durationInFrames={clip.durationInFrames}\n >\n <ClipErrorBoundary clipId={clip.id} component={clip.component}>\n <Component clip={clip} />\n </ClipErrorBoundary>\n </Sequence>\n );\n };\n\n return (\n <AbsoluteFill style={{ backgroundColor: \"#000000\" }}>\n {/* Main track clips */}\n {mainClips.map(renderClip)}\n\n {/* Overlay clips */}\n {overlayClips.map(renderClip)}\n </AbsoluteFill>\n );\n}\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n example: { title: \"Welcome\", subtitle: \"An introduction\" },\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n example: {\n src: \"https://picsum.photos/1920/1080?random=1\",\n alt: \"Hero image\",\n fit: \"cover\",\n },\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n example: {\n quote: \"The best way to predict the future is to invent it.\",\n author: \"Alan Kay\",\n },\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n example: { value: \"10M+\", label: \"Users worldwide\", prefix: \"\" },\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":["import_remotion","import_remotion","import_jsx_runtime","import_remotion","import_jsx_runtime","React"]}
|
package/dist/index.mjs
CHANGED
package/dist/server.d.mts
CHANGED
|
@@ -271,6 +271,10 @@ declare const standardComponentDefinitions: {
|
|
|
271
271
|
type: string;
|
|
272
272
|
defaultDuration: number;
|
|
273
273
|
description: string;
|
|
274
|
+
example: {
|
|
275
|
+
title: string;
|
|
276
|
+
subtitle: string;
|
|
277
|
+
};
|
|
274
278
|
};
|
|
275
279
|
ImageSlide: {
|
|
276
280
|
props: z.ZodObject<{
|
|
@@ -285,6 +289,11 @@ declare const standardComponentDefinitions: {
|
|
|
285
289
|
type: string;
|
|
286
290
|
defaultDuration: number;
|
|
287
291
|
description: string;
|
|
292
|
+
example: {
|
|
293
|
+
src: string;
|
|
294
|
+
alt: string;
|
|
295
|
+
fit: string;
|
|
296
|
+
};
|
|
288
297
|
};
|
|
289
298
|
SplitScreen: {
|
|
290
299
|
props: z.ZodObject<{
|
|
@@ -308,6 +317,10 @@ declare const standardComponentDefinitions: {
|
|
|
308
317
|
type: string;
|
|
309
318
|
defaultDuration: number;
|
|
310
319
|
description: string;
|
|
320
|
+
example: {
|
|
321
|
+
quote: string;
|
|
322
|
+
author: string;
|
|
323
|
+
};
|
|
311
324
|
};
|
|
312
325
|
StatCard: {
|
|
313
326
|
props: z.ZodObject<{
|
|
@@ -320,6 +333,11 @@ declare const standardComponentDefinitions: {
|
|
|
320
333
|
type: string;
|
|
321
334
|
defaultDuration: number;
|
|
322
335
|
description: string;
|
|
336
|
+
example: {
|
|
337
|
+
value: string;
|
|
338
|
+
label: string;
|
|
339
|
+
prefix: string;
|
|
340
|
+
};
|
|
323
341
|
};
|
|
324
342
|
TypingText: {
|
|
325
343
|
props: z.ZodObject<{
|
package/dist/server.d.ts
CHANGED
|
@@ -271,6 +271,10 @@ declare const standardComponentDefinitions: {
|
|
|
271
271
|
type: string;
|
|
272
272
|
defaultDuration: number;
|
|
273
273
|
description: string;
|
|
274
|
+
example: {
|
|
275
|
+
title: string;
|
|
276
|
+
subtitle: string;
|
|
277
|
+
};
|
|
274
278
|
};
|
|
275
279
|
ImageSlide: {
|
|
276
280
|
props: z.ZodObject<{
|
|
@@ -285,6 +289,11 @@ declare const standardComponentDefinitions: {
|
|
|
285
289
|
type: string;
|
|
286
290
|
defaultDuration: number;
|
|
287
291
|
description: string;
|
|
292
|
+
example: {
|
|
293
|
+
src: string;
|
|
294
|
+
alt: string;
|
|
295
|
+
fit: string;
|
|
296
|
+
};
|
|
288
297
|
};
|
|
289
298
|
SplitScreen: {
|
|
290
299
|
props: z.ZodObject<{
|
|
@@ -308,6 +317,10 @@ declare const standardComponentDefinitions: {
|
|
|
308
317
|
type: string;
|
|
309
318
|
defaultDuration: number;
|
|
310
319
|
description: string;
|
|
320
|
+
example: {
|
|
321
|
+
quote: string;
|
|
322
|
+
author: string;
|
|
323
|
+
};
|
|
311
324
|
};
|
|
312
325
|
StatCard: {
|
|
313
326
|
props: z.ZodObject<{
|
|
@@ -320,6 +333,11 @@ declare const standardComponentDefinitions: {
|
|
|
320
333
|
type: string;
|
|
321
334
|
defaultDuration: number;
|
|
322
335
|
description: string;
|
|
336
|
+
example: {
|
|
337
|
+
value: string;
|
|
338
|
+
label: string;
|
|
339
|
+
prefix: string;
|
|
340
|
+
};
|
|
323
341
|
};
|
|
324
342
|
TypingText: {
|
|
325
343
|
props: z.ZodObject<{
|
package/dist/server.js
CHANGED
|
@@ -299,7 +299,8 @@ var standardComponentDefinitions = {
|
|
|
299
299
|
}),
|
|
300
300
|
type: "scene",
|
|
301
301
|
defaultDuration: 90,
|
|
302
|
-
description: "Full-screen title card with centered text. Use for intros, outros, and section breaks."
|
|
302
|
+
description: "Full-screen title card with centered text. Use for intros, outros, and section breaks.",
|
|
303
|
+
example: { title: "Welcome", subtitle: "An introduction" }
|
|
303
304
|
},
|
|
304
305
|
ImageSlide: {
|
|
305
306
|
props: import_zod.z.object({
|
|
@@ -310,7 +311,12 @@ var standardComponentDefinitions = {
|
|
|
310
311
|
}),
|
|
311
312
|
type: "image",
|
|
312
313
|
defaultDuration: 150,
|
|
313
|
-
description: "Full-screen image display. Use for product shots, photos, and visual content."
|
|
314
|
+
description: "Full-screen image display. Use for product shots, photos, and visual content.",
|
|
315
|
+
example: {
|
|
316
|
+
src: "https://picsum.photos/1920/1080?random=1",
|
|
317
|
+
alt: "Hero image",
|
|
318
|
+
fit: "cover"
|
|
319
|
+
}
|
|
314
320
|
},
|
|
315
321
|
SplitScreen: {
|
|
316
322
|
props: import_zod.z.object({
|
|
@@ -333,7 +339,11 @@ var standardComponentDefinitions = {
|
|
|
333
339
|
}),
|
|
334
340
|
type: "scene",
|
|
335
341
|
defaultDuration: 150,
|
|
336
|
-
description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images."
|
|
342
|
+
description: "Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.",
|
|
343
|
+
example: {
|
|
344
|
+
quote: "The best way to predict the future is to invent it.",
|
|
345
|
+
author: "Alan Kay"
|
|
346
|
+
}
|
|
337
347
|
},
|
|
338
348
|
StatCard: {
|
|
339
349
|
props: import_zod.z.object({
|
|
@@ -345,7 +355,8 @@ var standardComponentDefinitions = {
|
|
|
345
355
|
}),
|
|
346
356
|
type: "scene",
|
|
347
357
|
defaultDuration: 90,
|
|
348
|
-
description: "Large statistic display. Use for key metrics and numbers."
|
|
358
|
+
description: "Large statistic display. Use for key metrics and numbers.",
|
|
359
|
+
example: { value: "10M+", label: "Users worldwide", prefix: "" }
|
|
349
360
|
},
|
|
350
361
|
TypingText: {
|
|
351
362
|
props: import_zod.z.object({
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/schema.ts","../src/catalog.ts"],"sourcesContent":["/**\n * Server-safe exports for @json-render/remotion\n *\n * This entry point only exports schema and catalog definitions,\n * without any React or Remotion runtime dependencies.\n * Use this in server components, API routes, and build scripts.\n *\n * @example\n * ```ts\n * // In an API route or server component\n * import { schema, standardComponentDefinitions } from \"@json-render/remotion/server\";\n * ```\n */\n\n// Schema (no React dependencies)\nexport { schema, type RemotionSchema, type RemotionSpec } from \"./schema\";\n\n// Catalog definitions (no React dependencies)\nexport {\n standardComponentDefinitions,\n standardTransitionDefinitions,\n standardEffectDefinitions,\n type ComponentDefinition,\n type TransitionDefinition,\n type EffectDefinition,\n} from \"./catalog\";\n\n// Catalog types (type-only exports)\nexport type {\n FrameContext,\n VideoComponentContext,\n VideoComponentFn,\n VideoComponents,\n TransitionFn,\n BuiltInTransition,\n EffectFn,\n Effects,\n} from \"./catalog-types\";\n\n// Core types (re-exported for convenience)\nexport type { Spec } from \"@json-render/core\";\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"add\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"add\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"add\",\"path\":\"/clips\",\"value\":[]}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"add\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n 'First add /composition with {id, fps:30, width:1920, height:1080, durationInFrames}: {\"op\":\"add\",\"path\":\"/composition\",\"value\":{...}}',\n 'Then add /tracks array with video/overlay tracks: {\"op\":\"add\",\"path\":\"/tracks\",\"value\":[...]}',\n 'Then add each clip by appending to the array: {\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{...}}',\n 'Finally add /audio with {tracks:[]}: {\"op\":\"add\",\"path\":\"/audio\",\"value\":{...}}',\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/schema.ts","../src/catalog.ts"],"sourcesContent":["/**\n * Server-safe exports for @json-render/remotion\n *\n * This entry point only exports schema and catalog definitions,\n * without any React or Remotion runtime dependencies.\n * Use this in server components, API routes, and build scripts.\n *\n * @example\n * ```ts\n * // In an API route or server component\n * import { schema, standardComponentDefinitions } from \"@json-render/remotion/server\";\n * ```\n */\n\n// Schema (no React dependencies)\nexport { schema, type RemotionSchema, type RemotionSpec } from \"./schema\";\n\n// Catalog definitions (no React dependencies)\nexport {\n standardComponentDefinitions,\n standardTransitionDefinitions,\n standardEffectDefinitions,\n type ComponentDefinition,\n type TransitionDefinition,\n type EffectDefinition,\n} from \"./catalog\";\n\n// Catalog types (type-only exports)\nexport type {\n FrameContext,\n VideoComponentContext,\n VideoComponentFn,\n VideoComponents,\n TransitionFn,\n BuiltInTransition,\n EffectFn,\n Effects,\n} from \"./catalog-types\";\n\n// Core types (re-exported for convenience)\nexport type { Spec } from \"@json-render/core\";\n","import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"add\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"add\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"add\",\"path\":\"/clips\",\"value\":[]}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"add\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n 'First add /composition with {id, fps:30, width:1920, height:1080, durationInFrames}: {\"op\":\"add\",\"path\":\"/composition\",\"value\":{...}}',\n 'Then add /tracks array with video/overlay tracks: {\"op\":\"add\",\"path\":\"/tracks\",\"value\":[...]}',\n 'Then add each clip by appending to the array: {\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{...}}',\n 'Finally add /audio with {tracks:[]}: {\"op\":\"add\",\"path\":\"/audio\",\"value\":{...}}',\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n example: { title: \"Welcome\", subtitle: \"An introduction\" },\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n example: {\n src: \"https://picsum.photos/1920/1080?random=1\",\n alt: \"Hero image\",\n fit: \"cover\",\n },\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n example: {\n quote: \"The best way to predict the future is to invent it.\",\n author: \"Alan Kay\",\n },\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n example: { value: \"10M+\", label: \"Users worldwide\", prefix: \"\" },\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":[]}
|
package/dist/server.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-render/remotion",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Remotion renderer for @json-render/core. JSON becomes video compositions.",
|
|
6
6
|
"keywords": [
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dist"
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@json-render/core": "0.5.
|
|
48
|
+
"@json-render/core": "0.5.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/react": "19.2.3",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema.ts","../src/catalog.ts"],"sourcesContent":["import { defineSchema, type PromptContext } from \"@json-render/core\";\n\n/**\n * Prompt template for Remotion timeline generation\n *\n * Uses JSONL patch format (same as React) but builds up a timeline spec structure.\n */\nfunction remotionPromptTemplate(context: PromptContext): string {\n const { catalog, options } = context;\n const { system = \"You are a video timeline generator.\", customRules = [] } =\n options;\n\n const lines: string[] = [];\n lines.push(system);\n lines.push(\"\");\n\n // Output format - JSONL patches\n lines.push(\"OUTPUT FORMAT:\");\n lines.push(\n \"Output JSONL (one JSON object per line) with patches to build a timeline spec.\",\n );\n lines.push(\n \"Each line is a JSON patch operation. Build the timeline incrementally.\",\n );\n lines.push(\"\");\n lines.push(\"Example output (each line is a separate JSON object):\");\n lines.push(\"\");\n lines.push(`{\"op\":\"add\",\"path\":\"/composition\",\"value\":{\"id\":\"intro\",\"fps\":30,\"width\":1920,\"height\":1080,\"durationInFrames\":300}}\n{\"op\":\"add\",\"path\":\"/tracks\",\"value\":[{\"id\":\"main\",\"name\":\"Main\",\"type\":\"video\",\"enabled\":true},{\"id\":\"overlay\",\"name\":\"Overlay\",\"type\":\"overlay\",\"enabled\":true}]}\n{\"op\":\"add\",\"path\":\"/clips\",\"value\":[]}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-1\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Welcome\",\"subtitle\":\"Getting Started\"},\"from\":0,\"durationInFrames\":90,\"transitionIn\":{\"type\":\"fade\",\"durationInFrames\":15},\"transitionOut\":{\"type\":\"fade\",\"durationInFrames\":15},\"motion\":{\"enter\":{\"opacity\":0,\"y\":50,\"scale\":0.9,\"duration\":25},\"spring\":{\"damping\":15}}}}\n{\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{\"id\":\"clip-2\",\"trackId\":\"main\",\"component\":\"TitleCard\",\"props\":{\"title\":\"Features\"},\"from\":90,\"durationInFrames\":90,\"motion\":{\"enter\":{\"opacity\":0,\"x\":-100,\"duration\":20},\"exit\":{\"opacity\":0,\"x\":100,\"duration\":15}}}}\n{\"op\":\"add\",\"path\":\"/audio\",\"value\":{\"tracks\":[]}}`);\n lines.push(\"\");\n\n // Components\n const catalogData = catalog as {\n components?: Record<\n string,\n { description?: string; defaultDuration?: number }\n >;\n transitions?: Record<string, { description?: string }>;\n effects?: Record<string, { description?: string }>;\n };\n\n if (catalogData.components) {\n lines.push(\n `AVAILABLE COMPONENTS (${Object.keys(catalogData.components).length}):`,\n );\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.components)) {\n const duration = def.defaultDuration\n ? ` [default: ${def.defaultDuration} frames]`\n : \"\";\n lines.push(\n `- ${name}: ${def.description || \"No description\"}${duration}`,\n );\n }\n lines.push(\"\");\n }\n\n // Transitions\n if (\n catalogData.transitions &&\n Object.keys(catalogData.transitions).length > 0\n ) {\n lines.push(\"AVAILABLE TRANSITIONS:\");\n lines.push(\"\");\n for (const [name, def] of Object.entries(catalogData.transitions)) {\n lines.push(`- ${name}: ${def.description || \"No description\"}`);\n }\n lines.push(\"\");\n }\n\n // Motion system documentation\n lines.push(\"MOTION SYSTEM:\");\n lines.push(\n \"Clips can have a 'motion' field for declarative animations (optional, use for dynamic/engaging videos):\",\n );\n lines.push(\"\");\n lines.push(\n \"- enter: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM these values TO normal when clip starts\",\n );\n lines.push(\n \"- exit: {opacity?, scale?, x?, y?, rotate?, duration?} - animate FROM normal TO these values when clip ends\",\n );\n lines.push(\n \"- spring: {damping?, stiffness?, mass?} - physics config (lower damping = more bounce)\",\n );\n lines.push(\n '- loop: {property, from, to, duration, easing?} - continuous animation (property: \"scale\"|\"rotate\"|\"x\"|\"y\"|\"opacity\")',\n );\n lines.push(\"\");\n lines.push(\"Example motion configs:\");\n lines.push(' Fade up: {\"enter\":{\"opacity\":0,\"y\":30,\"duration\":20}}');\n lines.push(\n ' Scale pop: {\"enter\":{\"scale\":0.5,\"opacity\":0,\"duration\":15},\"spring\":{\"damping\":10}}',\n );\n lines.push(\n ' Slide in/out: {\"enter\":{\"x\":-100,\"duration\":20},\"exit\":{\"x\":100,\"duration\":15}}',\n );\n lines.push(\n ' Gentle pulse: {\"loop\":{\"property\":\"scale\",\"from\":1,\"to\":1.05,\"duration\":60,\"easing\":\"ease\"}}',\n );\n lines.push(\"\");\n\n // Rules\n lines.push(\"RULES:\");\n const baseRules = [\n \"Output ONLY JSONL patches - one JSON object per line, no markdown, no code fences\",\n 'First add /composition with {id, fps:30, width:1920, height:1080, durationInFrames}: {\"op\":\"add\",\"path\":\"/composition\",\"value\":{...}}',\n 'Then add /tracks array with video/overlay tracks: {\"op\":\"add\",\"path\":\"/tracks\",\"value\":[...]}',\n 'Then add each clip by appending to the array: {\"op\":\"add\",\"path\":\"/clips/-\",\"value\":{...}}',\n 'Finally add /audio with {tracks:[]}: {\"op\":\"add\",\"path\":\"/audio\",\"value\":{...}}',\n \"ONLY use components listed above\",\n \"fps is always 30 (1 second = 30 frames, 10 seconds = 300 frames)\",\n 'Clips on \"main\" track flow sequentially (from = previous clip\\'s from + durationInFrames)',\n 'Overlay clips (LowerThird, TextOverlay) go on \"overlay\" track',\n \"Use motion.enter for engaging clip entrances, motion.exit for smooth departures\",\n \"Spring damping: 20=smooth, 10=bouncy, 5=very bouncy\",\n ];\n const allRules = [...baseRules, ...customRules];\n allRules.forEach((rule, i) => {\n lines.push(`${i + 1}. ${rule}`);\n });\n\n return lines.join(\"\\n\");\n}\n\n/**\n * The schema for @json-render/remotion\n *\n * This schema is fundamentally different from the React element tree schema.\n * It's timeline-based, designed for video composition:\n *\n * - Spec: A composition with tracks containing timed clips\n * - Catalog: Video components (scenes, overlays, etc.) and effects\n *\n * This demonstrates that json-render is truly agnostic - different renderers\n * can have completely different spec formats.\n */\nexport const schema = defineSchema(\n (s) => ({\n // What the AI-generated SPEC looks like (timeline-based)\n spec: s.object({\n /** Composition settings */\n composition: s.object({\n /** Unique composition ID */\n id: s.string(),\n /** Frames per second */\n fps: s.number(),\n /** Width in pixels */\n width: s.number(),\n /** Height in pixels */\n height: s.number(),\n /** Total duration in frames */\n durationInFrames: s.number(),\n }),\n\n /** Timeline tracks (like layers in video editing) */\n tracks: s.array(\n s.object({\n /** Unique track ID */\n id: s.string(),\n /** Track name for organization */\n name: s.string(),\n /** Track type: \"video\" | \"audio\" | \"overlay\" | \"text\" */\n type: s.string(),\n /** Whether track is muted/hidden */\n enabled: s.boolean(),\n }),\n ),\n\n /** Clips placed on the timeline */\n clips: s.array(\n s.object({\n /** Unique clip ID */\n id: s.string(),\n /** Which track this clip belongs to */\n trackId: s.string(),\n /** Component type from catalog */\n component: s.ref(\"catalog.components\"),\n /** Component props */\n props: s.propsOf(\"catalog.components\"),\n /** Start frame (when clip begins) */\n from: s.number(),\n /** Duration in frames */\n durationInFrames: s.number(),\n /** Transition in effect */\n transitionIn: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Transition out effect */\n transitionOut: s.object({\n type: s.ref(\"catalog.transitions\"),\n durationInFrames: s.number(),\n }),\n /** Declarative motion configuration for custom animations */\n motion: s.object({\n /** Enter animation - animates FROM these values TO neutral */\n enter: s.object({\n /** Starting opacity (0-1), animates to 1 */\n opacity: s.number(),\n /** Starting scale (e.g., 0.8 = 80%), animates to 1 */\n scale: s.number(),\n /** Starting X offset in pixels, animates to 0 */\n x: s.number(),\n /** Starting Y offset in pixels, animates to 0 */\n y: s.number(),\n /** Starting rotation in degrees, animates to 0 */\n rotate: s.number(),\n /** Duration of enter animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Exit animation - animates FROM neutral TO these values */\n exit: s.object({\n /** Ending opacity (0-1), animates from 1 */\n opacity: s.number(),\n /** Ending scale, animates from 1 */\n scale: s.number(),\n /** Ending X offset in pixels, animates from 0 */\n x: s.number(),\n /** Ending Y offset in pixels, animates from 0 */\n y: s.number(),\n /** Ending rotation in degrees, animates from 0 */\n rotate: s.number(),\n /** Duration of exit animation in frames (default: 20) */\n duration: s.number(),\n }),\n /** Spring physics configuration */\n spring: s.object({\n /** Damping coefficient (default: 20) */\n damping: s.number(),\n /** Stiffness (default: 100) */\n stiffness: s.number(),\n /** Mass (default: 1) */\n mass: s.number(),\n }),\n /** Continuous looping animation */\n loop: s.object({\n /** Property to animate: \"scale\" | \"rotate\" | \"x\" | \"y\" | \"opacity\" */\n property: s.string(),\n /** Starting value */\n from: s.number(),\n /** Ending value */\n to: s.number(),\n /** Duration of one cycle in frames */\n duration: s.number(),\n /** Easing type: \"linear\" | \"ease\" | \"spring\" (default: \"ease\") */\n easing: s.string(),\n }),\n }),\n }),\n ),\n\n /** Audio configuration */\n audio: s.object({\n /** Background music/audio clips */\n tracks: s.array(\n s.object({\n id: s.string(),\n src: s.string(),\n from: s.number(),\n durationInFrames: s.number(),\n volume: s.number(),\n }),\n ),\n }),\n }),\n\n // What the CATALOG must provide\n catalog: s.object({\n /** Video component definitions (scenes, overlays, etc.) */\n components: s.map({\n /** Zod schema for component props */\n props: s.zod(),\n /** Component type: \"scene\" | \"overlay\" | \"text\" | \"image\" | \"video\" */\n type: s.string(),\n /** Default duration in frames (can be overridden per clip) */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Transition effect definitions */\n transitions: s.map({\n /** Default duration in frames */\n defaultDuration: s.number(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n /** Effect definitions (filters, animations, etc.) */\n effects: s.map({\n /** Zod schema for effect params */\n params: s.zod(),\n /** Description for AI generation hints */\n description: s.string(),\n }),\n }),\n }),\n {\n promptTemplate: remotionPromptTemplate,\n },\n);\n\n/**\n * Type for the Remotion schema\n */\nexport type RemotionSchema = typeof schema;\n\n/**\n * Infer the spec type from a catalog\n */\nexport type RemotionSpec<TCatalog> = typeof schema extends {\n createCatalog: (catalog: TCatalog) => { _specType: infer S };\n}\n ? S\n : never;\n","import { z } from \"zod\";\n\n/**\n * Standard component definitions for Remotion catalogs\n *\n * These can be used directly or extended with custom components.\n */\nexport const standardComponentDefinitions = {\n // ==========================================================================\n // Scene Components (full-screen)\n // ==========================================================================\n\n TitleCard: {\n props: z.object({\n title: z.string(),\n subtitle: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description:\n \"Full-screen title card with centered text. Use for intros, outros, and section breaks.\",\n },\n\n ImageSlide: {\n props: z.object({\n src: z.string(),\n alt: z.string(),\n fit: z.enum([\"cover\", \"contain\"]).nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"image\",\n defaultDuration: 150,\n description:\n \"Full-screen image display. Use for product shots, photos, and visual content.\",\n },\n\n SplitScreen: {\n props: z.object({\n leftTitle: z.string(),\n rightTitle: z.string(),\n leftColor: z.string().nullable(),\n rightColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 120,\n description:\n \"Split screen with two sides. Use for comparisons or before/after.\",\n },\n\n QuoteCard: {\n props: z.object({\n quote: z.string(),\n author: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n transparent: z.boolean().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 150,\n description:\n \"Quote display with author. Props: quote, author, textColor, backgroundColor. Set transparent:true when using as overlay on images.\",\n },\n\n StatCard: {\n props: z.object({\n value: z.string(),\n label: z.string(),\n prefix: z.string().nullable(),\n suffix: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 90,\n description: \"Large statistic display. Use for key metrics and numbers.\",\n },\n\n TypingText: {\n props: z.object({\n text: z.string(),\n backgroundColor: z.string().nullable(),\n textColor: z.string().nullable(),\n fontSize: z.number().nullable(),\n fontFamily: z.enum([\"monospace\", \"sans-serif\", \"serif\"]).nullable(),\n showCursor: z.boolean().nullable(),\n cursorChar: z.string().nullable(),\n charsPerSecond: z.number().nullable(),\n }),\n type: \"scene\",\n defaultDuration: 180,\n description:\n \"Terminal-style typing animation that reveals text character by character. Perfect for code demos, CLI commands, and dramatic text reveals.\",\n },\n\n // ==========================================================================\n // Overlay Components\n // ==========================================================================\n\n LowerThird: {\n props: z.object({\n name: z.string(),\n title: z.string().nullable(),\n backgroundColor: z.string().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 120,\n description:\n \"Name/title overlay in lower third of screen. Use to identify speakers.\",\n },\n\n TextOverlay: {\n props: z.object({\n text: z.string(),\n position: z.enum([\"top\", \"center\", \"bottom\"]).nullable(),\n fontSize: z.enum([\"small\", \"medium\", \"large\"]).nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 90,\n description: \"Simple text overlay. Use for captions and annotations.\",\n },\n\n LogoBug: {\n props: z.object({\n position: z\n .enum([\"top-left\", \"top-right\", \"bottom-left\", \"bottom-right\"])\n .nullable(),\n opacity: z.number().nullable(),\n }),\n type: \"overlay\",\n defaultDuration: 300,\n description: \"Corner logo watermark. Use for branding throughout video.\",\n },\n\n // ==========================================================================\n // Video Components\n // ==========================================================================\n\n VideoClip: {\n props: z.object({\n src: z.string(),\n startFrom: z.number().nullable(),\n volume: z.number().nullable(),\n }),\n type: \"video\",\n defaultDuration: 150,\n description: \"Video file playback. Use for B-roll and footage.\",\n },\n};\n\n/**\n * Standard transition definitions for Remotion catalogs\n */\nexport const standardTransitionDefinitions = {\n fade: {\n defaultDuration: 15,\n description: \"Smooth fade in/out. Use for gentle transitions.\",\n },\n slideLeft: {\n defaultDuration: 20,\n description: \"Slide from right to left. Use for forward progression.\",\n },\n slideRight: {\n defaultDuration: 20,\n description: \"Slide from left to right. Use for backward progression.\",\n },\n slideUp: {\n defaultDuration: 15,\n description: \"Slide from bottom to top. Use for overlays appearing.\",\n },\n slideDown: {\n defaultDuration: 15,\n description: \"Slide from top to bottom. Use for overlays disappearing.\",\n },\n zoom: {\n defaultDuration: 20,\n description: \"Zoom in/out effect. Use for emphasis.\",\n },\n wipe: {\n defaultDuration: 15,\n description: \"Horizontal wipe. Use for scene changes.\",\n },\n none: {\n defaultDuration: 0,\n description: \"No transition (hard cut).\",\n },\n};\n\n/**\n * Standard effect definitions for Remotion catalogs\n */\nexport const standardEffectDefinitions = {\n kenBurns: {\n params: z.object({\n startScale: z.number(),\n endScale: z.number(),\n panX: z.number().nullable(),\n panY: z.number().nullable(),\n }),\n description: \"Ken Burns pan and zoom effect for images.\",\n },\n pulse: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Subtle pulsing scale effect for emphasis.\",\n },\n shake: {\n params: z.object({\n intensity: z.number(),\n }),\n description: \"Camera shake effect for energy.\",\n },\n};\n\n/**\n * Type for component definition\n */\nexport type ComponentDefinition = {\n props: z.ZodType;\n type: string;\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for transition definition\n */\nexport type TransitionDefinition = {\n defaultDuration: number;\n description: string;\n};\n\n/**\n * Type for effect definition\n */\nexport type EffectDefinition = {\n params: z.ZodType;\n description: string;\n};\n"],"mappings":"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","names":[]}
|