loopwind 0.12.3 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.video-preview/entry.tsx +35 -0
  2. package/.video-preview/index.html +55 -0
  3. package/dist/commands/preview.d.ts.map +1 -1
  4. package/dist/commands/preview.js +38 -5
  5. package/dist/commands/preview.js.map +1 -1
  6. package/dist/commands/render.d.ts.map +1 -1
  7. package/dist/commands/render.js +6 -1
  8. package/dist/commands/render.js.map +1 -1
  9. package/dist/lib/constants.d.ts.map +1 -1
  10. package/dist/lib/constants.js +9 -4
  11. package/dist/lib/constants.js.map +1 -1
  12. package/dist/lib/helpers.d.ts +2 -12
  13. package/dist/lib/helpers.d.ts.map +1 -1
  14. package/dist/lib/helpers.js +44 -116
  15. package/dist/lib/helpers.js.map +1 -1
  16. package/dist/lib/renderer.d.ts.map +1 -1
  17. package/dist/lib/renderer.js +71 -54
  18. package/dist/lib/renderer.js.map +1 -1
  19. package/dist/lib/tailwind-browser.d.ts +27 -0
  20. package/dist/lib/tailwind-browser.d.ts.map +1 -0
  21. package/dist/lib/tailwind-browser.js +656 -0
  22. package/dist/lib/tailwind-browser.js.map +1 -0
  23. package/dist/lib/tailwind.d.ts.map +1 -1
  24. package/dist/lib/tailwind.js +59 -0
  25. package/dist/lib/tailwind.js.map +1 -1
  26. package/dist/lib/utils.d.ts +4 -0
  27. package/dist/lib/utils.d.ts.map +1 -1
  28. package/dist/lib/utils.js +28 -1
  29. package/dist/lib/utils.js.map +1 -1
  30. package/dist/lib/video-player.d.ts +25 -0
  31. package/dist/lib/video-player.d.ts.map +1 -0
  32. package/dist/lib/video-player.js +265 -0
  33. package/dist/lib/video-player.js.map +1 -0
  34. package/dist/lib/video-preview.d.ts +15 -0
  35. package/dist/lib/video-preview.d.ts.map +1 -0
  36. package/dist/lib/video-preview.js +199 -0
  37. package/dist/lib/video-preview.js.map +1 -0
  38. package/package.json +5 -2
@@ -0,0 +1,265 @@
1
+ import React, { useState, useEffect, useCallback, useRef } from 'react';
2
+ import { tw as twBase } from './tailwind-browser.js';
3
+ export function VideoPlayer({ Template, meta, props, tailwindConfig = null, loopwindConfig = null }) {
4
+ const [frame, setFrame] = useState(0);
5
+ const [isPlaying, setIsPlaying] = useState(true);
6
+ const [isLooping, setIsLooping] = useState(true);
7
+ const [scale, setScale] = useState(1);
8
+ const animationRef = useRef(null);
9
+ const lastTimeRef = useRef(0);
10
+ const containerRef = useRef(null);
11
+ const { fps, duration } = meta.video;
12
+ const totalFrames = Math.floor(fps * duration);
13
+ const durationMs = duration * 1000;
14
+ // Create tw function bound to current animation context
15
+ const boundTw = useCallback((classes) => {
16
+ const context = {
17
+ frame: Math.floor(frame),
18
+ totalFrames,
19
+ durationMs,
20
+ progress: frame / totalFrames
21
+ };
22
+ return twBase(classes, tailwindConfig, loopwindConfig, context);
23
+ }, [frame, totalFrames, durationMs, tailwindConfig, loopwindConfig]);
24
+ // Image helper - returns the image URL from props
25
+ const image = useCallback((key) => {
26
+ return props[key] || '';
27
+ }, [props]);
28
+ // Playback loop
29
+ useEffect(() => {
30
+ if (!isPlaying) {
31
+ if (animationRef.current) {
32
+ cancelAnimationFrame(animationRef.current);
33
+ animationRef.current = null;
34
+ }
35
+ return;
36
+ }
37
+ lastTimeRef.current = performance.now();
38
+ const animate = (time) => {
39
+ const delta = time - lastTimeRef.current;
40
+ lastTimeRef.current = time;
41
+ setFrame(prev => {
42
+ const increment = (delta / 1000) * fps;
43
+ const next = prev + increment;
44
+ if (next >= totalFrames) {
45
+ if (isLooping) {
46
+ return next % totalFrames;
47
+ }
48
+ else {
49
+ setIsPlaying(false);
50
+ return totalFrames - 1;
51
+ }
52
+ }
53
+ return next;
54
+ });
55
+ animationRef.current = requestAnimationFrame(animate);
56
+ };
57
+ animationRef.current = requestAnimationFrame(animate);
58
+ return () => {
59
+ if (animationRef.current) {
60
+ cancelAnimationFrame(animationRef.current);
61
+ }
62
+ };
63
+ }, [isPlaying, fps, totalFrames, isLooping]);
64
+ // Calculate scale to fit video in container
65
+ useEffect(() => {
66
+ const calculateScale = () => {
67
+ if (!containerRef.current)
68
+ return;
69
+ const container = containerRef.current;
70
+ const padding = 64; // 2rem on each side
71
+ const availableWidth = container.clientWidth - padding;
72
+ const availableHeight = container.clientHeight - padding;
73
+ const scaleX = availableWidth / meta.size.width;
74
+ const scaleY = availableHeight / meta.size.height;
75
+ // Use the smaller scale to fit both dimensions, but cap at 1 (don't scale up)
76
+ const newScale = Math.min(scaleX, scaleY, 1);
77
+ setScale(newScale);
78
+ };
79
+ calculateScale();
80
+ window.addEventListener('resize', calculateScale);
81
+ return () => window.removeEventListener('resize', calculateScale);
82
+ }, [meta.size.width, meta.size.height]);
83
+ // Format time as milliseconds (matches animation class format)
84
+ const formatTime = (ms) => {
85
+ return `${Math.floor(ms)}ms`;
86
+ };
87
+ const currentMs = (frame / totalFrames) * durationMs;
88
+ const progress = (frame / totalFrames) * 100;
89
+ const handleScrub = (e) => {
90
+ const value = parseFloat(e.target.value);
91
+ setFrame((value / 100) * totalFrames);
92
+ };
93
+ const handlePlayPause = () => {
94
+ if (!isPlaying && frame >= totalFrames - 1) {
95
+ setFrame(0);
96
+ }
97
+ setIsPlaying(!isPlaying);
98
+ };
99
+ const handleRestart = () => {
100
+ setFrame(0);
101
+ setIsPlaying(true);
102
+ };
103
+ const handleStepBackward = () => {
104
+ setIsPlaying(false);
105
+ setFrame(prev => Math.max(0, prev - 1));
106
+ };
107
+ const handleStepForward = () => {
108
+ setIsPlaying(false);
109
+ setFrame(prev => Math.min(totalFrames - 1, prev + 1));
110
+ };
111
+ return (React.createElement("div", { style: {
112
+ display: 'flex',
113
+ flexDirection: 'column',
114
+ height: '100vh',
115
+ background: '#0a0a0a',
116
+ color: '#ffffff',
117
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
118
+ } },
119
+ React.createElement("div", { style: {
120
+ background: '#18181b',
121
+ borderBottom: '1px solid #27272a',
122
+ padding: '1rem 2rem',
123
+ display: 'flex',
124
+ justifyContent: 'space-between',
125
+ alignItems: 'center'
126
+ } },
127
+ React.createElement("h1", { style: { fontSize: '1.25rem', fontWeight: 600, margin: 0 } },
128
+ "loopwind preview: ",
129
+ meta.name),
130
+ React.createElement("div", { style: { display: 'flex', gap: '0.5rem', alignItems: 'center' } },
131
+ React.createElement("span", { style: {
132
+ background: '#7c3aed',
133
+ color: 'white',
134
+ padding: '0.25rem 0.75rem',
135
+ borderRadius: '0.375rem',
136
+ fontSize: '0.875rem',
137
+ fontWeight: 500
138
+ } }, "VIDEO"),
139
+ React.createElement("span", { style: {
140
+ background: '#27272a',
141
+ color: '#a1a1aa',
142
+ padding: '0.25rem 0.75rem',
143
+ borderRadius: '0.375rem',
144
+ fontSize: '0.75rem',
145
+ fontFamily: 'monospace'
146
+ } },
147
+ meta.size.width,
148
+ "\u00D7",
149
+ meta.size.height,
150
+ " @ ",
151
+ fps,
152
+ "fps"))),
153
+ React.createElement("div", { ref: containerRef, style: {
154
+ flex: 1,
155
+ display: 'flex',
156
+ alignItems: 'center',
157
+ justifyContent: 'center',
158
+ padding: '2rem',
159
+ overflow: 'hidden'
160
+ } },
161
+ React.createElement("div", { style: {
162
+ width: meta.size.width,
163
+ height: meta.size.height,
164
+ boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.5)',
165
+ borderRadius: '0.5rem',
166
+ overflow: 'hidden',
167
+ flexShrink: 0,
168
+ border: '1px solid #3f3f46',
169
+ transform: `scale(${scale})`,
170
+ transformOrigin: 'center center'
171
+ } },
172
+ React.createElement(Template, { tw: boundTw, image: image, __currentTimeMs: currentMs, __isPlaying: isPlaying, ...props }))),
173
+ React.createElement("div", { style: {
174
+ background: '#18181b',
175
+ borderTop: '1px solid #27272a',
176
+ padding: '1rem 2rem'
177
+ } },
178
+ React.createElement("div", { style: { marginBottom: '0.75rem' } },
179
+ React.createElement("input", { type: "range", min: "0", max: "100", step: "0.1", value: progress, onChange: handleScrub, style: {
180
+ width: '100%',
181
+ height: '6px',
182
+ background: `linear-gradient(to right, #7c3aed ${progress}%, #3f3f46 ${progress}%)`,
183
+ borderRadius: '3px',
184
+ cursor: 'pointer',
185
+ WebkitAppearance: 'none',
186
+ appearance: 'none'
187
+ } })),
188
+ React.createElement("div", { style: {
189
+ display: 'flex',
190
+ alignItems: 'center',
191
+ justifyContent: 'space-between'
192
+ } },
193
+ React.createElement("div", { style: { display: 'flex', alignItems: 'center', gap: '0.5rem' } },
194
+ React.createElement("button", { onClick: handleRestart, style: {
195
+ background: 'transparent',
196
+ border: 'none',
197
+ color: '#a1a1aa',
198
+ cursor: 'pointer',
199
+ padding: '0.5rem',
200
+ fontSize: '1rem',
201
+ display: 'flex',
202
+ alignItems: 'center',
203
+ justifyContent: 'center'
204
+ }, title: "Restart" }, "\u23EE"),
205
+ React.createElement("button", { onClick: handleStepBackward, style: {
206
+ background: 'transparent',
207
+ border: 'none',
208
+ color: '#a1a1aa',
209
+ cursor: 'pointer',
210
+ padding: '0.5rem',
211
+ fontSize: '1rem',
212
+ display: 'flex',
213
+ alignItems: 'center',
214
+ justifyContent: 'center'
215
+ }, title: "Previous frame" }, "\u23EA"),
216
+ React.createElement("button", { onClick: handlePlayPause, style: {
217
+ background: '#7c3aed',
218
+ border: 'none',
219
+ color: 'white',
220
+ cursor: 'pointer',
221
+ padding: '0.75rem 1rem',
222
+ borderRadius: '0.375rem',
223
+ fontSize: '1rem',
224
+ display: 'flex',
225
+ alignItems: 'center',
226
+ justifyContent: 'center',
227
+ minWidth: '3rem'
228
+ } }, isPlaying ? '⏸' : '▶'),
229
+ React.createElement("button", { onClick: handleStepForward, style: {
230
+ background: 'transparent',
231
+ border: 'none',
232
+ color: '#a1a1aa',
233
+ cursor: 'pointer',
234
+ padding: '0.5rem',
235
+ fontSize: '1rem',
236
+ display: 'flex',
237
+ alignItems: 'center',
238
+ justifyContent: 'center'
239
+ }, title: "Next frame" }, "\u23E9"),
240
+ React.createElement("button", { onClick: () => setIsLooping(!isLooping), style: {
241
+ background: isLooping ? '#3f3f46' : 'transparent',
242
+ border: '1px solid #3f3f46',
243
+ color: isLooping ? '#ffffff' : '#71717a',
244
+ cursor: 'pointer',
245
+ padding: '0.5rem 0.75rem',
246
+ borderRadius: '0.375rem',
247
+ fontSize: '0.75rem',
248
+ marginLeft: '0.5rem'
249
+ }, title: isLooping ? 'Loop enabled' : 'Loop disabled' }, "\uD83D\uDD01")),
250
+ React.createElement("div", { style: {
251
+ fontFamily: 'monospace',
252
+ fontSize: '0.875rem',
253
+ color: '#a1a1aa'
254
+ } },
255
+ React.createElement("span", { style: { color: '#ffffff' } }, formatTime(currentMs)),
256
+ ' / ',
257
+ formatTime(durationMs),
258
+ React.createElement("span", { style: { marginLeft: '1rem', color: '#71717a' } },
259
+ "Frame ",
260
+ Math.floor(frame),
261
+ " / ",
262
+ totalFrames))))));
263
+ }
264
+ export default VideoPlayer;
265
+ //# sourceMappingURL=video-player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-player.js","sourceRoot":"","sources":["../../src/lib/video-player.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ interface VideoPreviewOptions {
2
+ templateName: string;
3
+ templatePath: string;
4
+ props: Record<string, any>;
5
+ meta: any;
6
+ port: number;
7
+ open: boolean;
8
+ }
9
+ export declare function startVideoPreview(options: VideoPreviewOptions): Promise<{
10
+ server: import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
11
+ vite: import("vite").ViteDevServer;
12
+ cleanup: () => Promise<void>;
13
+ }>;
14
+ export {};
15
+ //# sourceMappingURL=video-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-preview.d.ts","sourceRoot":"","sources":["../../src/lib/video-preview.ts"],"names":[],"mappings":"AASA,UAAU,mBAAmB;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3B,IAAI,EAAE,GAAG,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB;;;;GA2MnE"}
@@ -0,0 +1,199 @@
1
+ import express from 'express';
2
+ import { createServer as createViteServer } from 'vite';
3
+ import path from 'path';
4
+ import fs from 'fs/promises';
5
+ import { fileURLToPath } from 'url';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ export async function startVideoPreview(options) {
9
+ const { templateName, templatePath, props, meta, port, open } = options;
10
+ const app = express();
11
+ // Try to load loopwind.json from project (_loopwind/loopwind.json)
12
+ let loopwindConfig = null;
13
+ const projectRoot = path.join(__dirname, '../..');
14
+ const loopwindJsonPath = path.join(projectRoot, '_loopwind', 'loopwind.json');
15
+ try {
16
+ const loopwindContent = await fs.readFile(loopwindJsonPath, 'utf-8');
17
+ loopwindConfig = JSON.parse(loopwindContent);
18
+ }
19
+ catch {
20
+ // loopwind.json doesn't exist or couldn't be read - that's fine
21
+ }
22
+ // Create temporary directory for generated files
23
+ const tempDir = path.join(__dirname, '../../.video-preview');
24
+ await fs.mkdir(tempDir, { recursive: true });
25
+ // Get the source directory for imports
26
+ // __dirname at runtime is dist/lib, we need src/lib for Vite to bundle TSX
27
+ const srcLibDir = path.join(projectRoot, 'src/lib');
28
+ // Generate the entry file
29
+ const entryContent = `
30
+ import React from 'react';
31
+ import { createRoot } from 'react-dom/client';
32
+ import { VideoPlayer } from '${srcLibDir}/video-player.tsx';
33
+ import { tw } from '${srcLibDir}/tailwind-browser.ts';
34
+ import Template, { meta } from '${templatePath}';
35
+
36
+ const props = ${JSON.stringify(props)};
37
+
38
+ // Tailwind config not loaded in browser (would need dynamic import of user's config)
39
+ const tailwindConfig = null;
40
+
41
+ // loopwind.json config (loaded server-side and embedded)
42
+ const loopwindConfig = ${JSON.stringify(loopwindConfig)};
43
+
44
+ function App() {
45
+ return (
46
+ <VideoPlayer
47
+ Template={Template}
48
+ meta={meta}
49
+ props={props}
50
+ tailwindConfig={tailwindConfig}
51
+ loopwindConfig={loopwindConfig}
52
+ />
53
+ );
54
+ }
55
+
56
+ const container = document.getElementById('root');
57
+ const root = createRoot(container);
58
+ root.render(<App />);
59
+
60
+ // Hot module replacement
61
+ if (import.meta.hot) {
62
+ import.meta.hot.accept();
63
+ }
64
+ `;
65
+ const entryPath = path.join(tempDir, 'entry.tsx');
66
+ await fs.writeFile(entryPath, entryContent);
67
+ // Generate index.html
68
+ const htmlContent = `
69
+ <!DOCTYPE html>
70
+ <html lang="en">
71
+ <head>
72
+ <meta charset="UTF-8">
73
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
74
+ <title>Video Preview: ${templateName}</title>
75
+ <style>
76
+ * {
77
+ margin: 0;
78
+ padding: 0;
79
+ box-sizing: border-box;
80
+ }
81
+ body {
82
+ overflow: hidden;
83
+ }
84
+ /* Custom range slider styling */
85
+ input[type="range"] {
86
+ -webkit-appearance: none;
87
+ appearance: none;
88
+ outline: none;
89
+ }
90
+ input[type="range"]::-webkit-slider-thumb {
91
+ -webkit-appearance: none;
92
+ appearance: none;
93
+ width: 14px;
94
+ height: 14px;
95
+ border-radius: 50%;
96
+ background: #7c3aed;
97
+ cursor: pointer;
98
+ margin-top: -4px;
99
+ }
100
+ input[type="range"]::-moz-range-thumb {
101
+ width: 14px;
102
+ height: 14px;
103
+ border-radius: 50%;
104
+ background: #7c3aed;
105
+ cursor: pointer;
106
+ border: none;
107
+ }
108
+ input[type="range"]::-webkit-slider-runnable-track {
109
+ height: 6px;
110
+ border-radius: 3px;
111
+ }
112
+ input[type="range"]::-moz-range-track {
113
+ height: 6px;
114
+ border-radius: 3px;
115
+ }
116
+ </style>
117
+ </head>
118
+ <body>
119
+ <div id="root"></div>
120
+ <script type="module" src="/entry.tsx"></script>
121
+ </body>
122
+ </html>
123
+ `;
124
+ const htmlPath = path.join(tempDir, 'index.html');
125
+ await fs.writeFile(htmlPath, htmlContent);
126
+ // Dynamically import the React plugin
127
+ // @ts-expect-error - moduleResolution incompatibility with @vitejs/plugin-react types
128
+ const { default: react } = await import('@vitejs/plugin-react');
129
+ // Create Vite server
130
+ const vite = await createViteServer({
131
+ root: tempDir,
132
+ server: {
133
+ middlewareMode: true,
134
+ hmr: true,
135
+ },
136
+ plugins: [react()],
137
+ define: {
138
+ 'process.env.NODE_ENV': JSON.stringify('development'),
139
+ 'process.env': JSON.stringify({}),
140
+ },
141
+ resolve: {
142
+ alias: {
143
+ // Ensure proper resolution of our library files
144
+ }
145
+ },
146
+ optimizeDeps: {
147
+ include: ['react', 'react-dom'],
148
+ // Don't pre-bundle our local files
149
+ exclude: ['video-player']
150
+ },
151
+ build: {
152
+ rollupOptions: {
153
+ input: entryPath
154
+ }
155
+ }
156
+ });
157
+ // Serve template directory for local assets (videos, images)
158
+ const templateDir = path.dirname(templatePath);
159
+ app.use('/template', express.static(templateDir));
160
+ // Use Vite's connect instance as middleware
161
+ app.use(vite.middlewares);
162
+ // Serve index.html for root
163
+ app.get('/', async (req, res) => {
164
+ try {
165
+ let html = await fs.readFile(htmlPath, 'utf-8');
166
+ html = await vite.transformIndexHtml(req.url, html);
167
+ res.status(200).set({ 'Content-Type': 'text/html' }).end(html);
168
+ }
169
+ catch (e) {
170
+ vite.ssrFixStacktrace(e);
171
+ res.status(500).end(e.message);
172
+ }
173
+ });
174
+ // Start server
175
+ const server = app.listen(port, () => {
176
+ // Open browser if requested
177
+ if (open) {
178
+ import('open').then(({ default: openBrowser }) => {
179
+ openBrowser(`http://localhost:${port}`);
180
+ }).catch(() => {
181
+ // Silently fail
182
+ });
183
+ }
184
+ });
185
+ // Cleanup function
186
+ const cleanup = async () => {
187
+ await vite.close();
188
+ server.close();
189
+ // Clean up temp files
190
+ try {
191
+ await fs.rm(tempDir, { recursive: true });
192
+ }
193
+ catch {
194
+ // Ignore cleanup errors
195
+ }
196
+ };
197
+ return { server, vite, cleanup };
198
+ }
199
+ //# sourceMappingURL=video-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-preview.js","sourceRoot":"","sources":["../../src/lib/video-preview.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loopwind",
3
- "version": "0.12.3",
3
+ "version": "0.13.1",
4
4
  "description": "A CLI tool for AI code agents and developers for generating images and videos.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -47,6 +47,7 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@resvg/resvg-js": "^2.6.0",
50
+ "@vitejs/plugin-react": "^5.1.1",
50
51
  "boxen": "^7.1.1",
51
52
  "chalk": "^5.3.0",
52
53
  "chalk-animation": "^2.0.3",
@@ -61,14 +62,16 @@
61
62
  "mediabunny": "^1.25.0",
62
63
  "open": "^11.0.0",
63
64
  "ora": "^8.0.1",
65
+ "patch-package": "^8.0.1",
64
66
  "pngjs": "^7.0.0",
65
67
  "qrcode": "^1.5.4",
66
68
  "react": "^18.2.0",
69
+ "react-dom": "^18.3.1",
67
70
  "satori": "^0.18.3",
68
71
  "sharp": "^0.34.5",
69
72
  "tailwind-merge": "^3.4.0",
70
73
  "tailwindcss": "^3.4.1",
71
- "patch-package": "^8.0.1"
74
+ "vite": "^7.2.2"
72
75
  },
73
76
  "devDependencies": {
74
77
  "@types/chalk-animation": "^1.6.3",