loopwind 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +9 -2
  2. package/dist/cli.js +5 -3
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/render.d.ts +1 -0
  5. package/dist/commands/render.d.ts.map +1 -1
  6. package/dist/commands/render.js +1 -0
  7. package/dist/commands/render.js.map +1 -1
  8. package/dist/lib/encode-worker.d.ts +2 -0
  9. package/dist/lib/encode-worker.d.ts.map +1 -0
  10. package/dist/lib/encode-worker.js +29 -0
  11. package/dist/lib/encode-worker.js.map +1 -0
  12. package/dist/lib/mjpeg-muxer.d.ts +46 -0
  13. package/dist/lib/mjpeg-muxer.d.ts.map +1 -0
  14. package/dist/lib/mjpeg-muxer.js +513 -0
  15. package/dist/lib/mjpeg-muxer.js.map +1 -0
  16. package/dist/lib/render-core.d.ts +63 -0
  17. package/dist/lib/render-core.d.ts.map +1 -0
  18. package/dist/lib/render-core.js +65 -0
  19. package/dist/lib/render-core.js.map +1 -0
  20. package/dist/lib/renderer.d.ts.map +1 -1
  21. package/dist/lib/renderer.js +10 -7
  22. package/dist/lib/renderer.js.map +1 -1
  23. package/dist/lib/resvg-init.d.ts +15 -0
  24. package/dist/lib/resvg-init.d.ts.map +1 -0
  25. package/dist/lib/resvg-init.js +55 -0
  26. package/dist/lib/resvg-init.js.map +1 -0
  27. package/dist/lib/tailwind/colors.d.ts +8 -0
  28. package/dist/lib/tailwind/colors.d.ts.map +1 -0
  29. package/dist/lib/tailwind/colors.js +102 -0
  30. package/dist/lib/tailwind/colors.js.map +1 -0
  31. package/dist/lib/tailwind/index.d.ts +10 -0
  32. package/dist/lib/tailwind/index.d.ts.map +1 -0
  33. package/dist/lib/tailwind/index.js +9 -0
  34. package/dist/lib/tailwind/index.js.map +1 -0
  35. package/dist/lib/tailwind/resolvers.d.ts +28 -0
  36. package/dist/lib/tailwind/resolvers.d.ts.map +1 -0
  37. package/dist/lib/tailwind/resolvers.js +94 -0
  38. package/dist/lib/tailwind/resolvers.js.map +1 -0
  39. package/dist/lib/tailwind/types.d.ts +29 -0
  40. package/dist/lib/tailwind/types.d.ts.map +1 -0
  41. package/dist/lib/tailwind/types.js +8 -0
  42. package/dist/lib/tailwind/types.js.map +1 -0
  43. package/dist/lib/tailwind-config-loader.d.ts +8 -45
  44. package/dist/lib/tailwind-config-loader.d.ts.map +1 -1
  45. package/dist/lib/tailwind-config-loader.js +6 -429
  46. package/dist/lib/tailwind-config-loader.js.map +1 -1
  47. package/dist/lib/tailwind.d.ts +1 -1
  48. package/dist/lib/tailwind.d.ts.map +1 -1
  49. package/dist/lib/tailwind.js +1 -1
  50. package/dist/lib/tailwind.js.map +1 -1
  51. package/dist/lib/video-preview.d.ts.map +1 -1
  52. package/dist/lib/video-preview.js +28 -16
  53. package/dist/lib/video-preview.js.map +1 -1
  54. package/dist/lib/video-renderer.d.ts +19 -1
  55. package/dist/lib/video-renderer.d.ts.map +1 -1
  56. package/dist/lib/video-renderer.js +194 -70
  57. package/dist/lib/video-renderer.js.map +1 -1
  58. package/dist/sdk/edge/index.d.ts +91 -0
  59. package/dist/sdk/edge/index.d.ts.map +1 -0
  60. package/dist/sdk/edge/index.js +187 -0
  61. package/dist/sdk/edge/index.js.map +1 -0
  62. package/dist/sdk/workers/index.d.ts +135 -0
  63. package/dist/sdk/workers/index.d.ts.map +1 -0
  64. package/dist/sdk/workers/index.js +271 -0
  65. package/dist/sdk/workers/index.js.map +1 -0
  66. package/dist/sdk/workers/tailwind-config.d.ts +48 -0
  67. package/dist/sdk/workers/tailwind-config.d.ts.map +1 -0
  68. package/dist/sdk/workers/tailwind-config.js +187 -0
  69. package/dist/sdk/workers/tailwind-config.js.map +1 -0
  70. package/dist/sdk/workers/tailwind.d.ts +9 -0
  71. package/dist/sdk/workers/tailwind.d.ts.map +1 -0
  72. package/dist/sdk/workers/tailwind.js +8 -0
  73. package/dist/sdk/workers/tailwind.js.map +1 -0
  74. package/package.json +6 -2
  75. package/test-cloudflare-worker/README.md +64 -0
  76. package/test-cloudflare-worker/dist/README.md +1 -0
  77. package/test-cloudflare-worker/dist/index.js +23743 -0
  78. package/test-cloudflare-worker/dist/index.js.map +8 -0
  79. package/test-cloudflare-worker/package-lock.json +1773 -0
  80. package/test-cloudflare-worker/package.json +25 -0
  81. package/test-cloudflare-worker/test-sdk.mjs +75 -0
  82. package/test-cloudflare-worker/wrangler.toml +14 -0
  83. package/test-video-720p.mjs +96 -0
  84. package/test-video-breakdown.mjs +98 -0
  85. package/test-video-perf-1080.mjs +67 -0
  86. package/test-video-perf.mjs +56 -0
  87. package/test-worker-1080p.mjs +103 -0
  88. package/test-worker-viability.mjs +140 -0
  89. package/website/astro.config.mjs +4 -9
  90. package/website/dist/_astro/PlaygroundEditor.DzFavsm8.js +26 -0
  91. package/website/dist/_astro/VideoPreviewClient.BrajhYmh.js +1 -0
  92. package/website/dist/_astro/agents.CZXv4DCM.css +1 -0
  93. package/website/dist/_astro/client.BHSq4mdQ.js +33 -0
  94. package/website/dist/_astro/index.CTbGshLK.js +9 -0
  95. package/website/dist/_astro/jsx-runtime.BjG_zV1W.js +9 -0
  96. package/website/dist/_routes.json +1 -0
  97. package/website/dist/_worker.js/_@astrojs-ssr-adapter.mjs +4 -4
  98. package/website/dist/_worker.js/_astro-internal_middleware.mjs +2 -2
  99. package/website/dist/_worker.js/chunks/Logo_Cud5QvBJ.mjs +22 -0
  100. package/website/dist/_worker.js/chunks/_@astro-renderers_-YVK7NHa.mjs +15015 -0
  101. package/website/dist/_worker.js/chunks/astro/{server_Y5_QHO8v.mjs → server_CsUrSZgd.mjs} +113 -2
  102. package/website/dist/_worker.js/chunks/{astro-designed-error-pages_BNTLO-TA.mjs → astro-designed-error-pages_1ELXm5Tt.mjs} +1 -1
  103. package/website/dist/_worker.js/chunks/{index_C1UTDwYg.mjs → index_BDWR1Q-q.mjs} +2 -2
  104. package/website/dist/_worker.js/chunks/{noop-middleware_DlWGj5t5.mjs → noop-middleware_B8fH5jha.mjs} +1 -1
  105. package/website/dist/_worker.js/index.js +38 -30
  106. package/website/dist/_worker.js/manifest_Bk6136-u.mjs +98 -0
  107. package/website/dist/_worker.js/pages/_image.astro.mjs +1 -1
  108. package/website/dist/_worker.js/pages/api/playground/render.astro.mjs +25562 -0
  109. package/website/dist/_worker.js/pages/api/playground/templates.astro.mjs +92 -0
  110. package/website/dist/_worker.js/pages/api/raw-markdown/_---path_.astro.mjs +1 -1
  111. package/website/dist/_worker.js/pages/playground/_example_.astro.mjs +95 -0
  112. package/website/dist/_worker.js/pages/playground.astro.mjs +1 -0
  113. package/website/dist/_worker.js/renderers.mjs +1 -56
  114. package/website/dist/agents/index.html +4 -2
  115. package/website/dist/animation/index.html +629 -3
  116. package/website/dist/config/index.html +4 -2
  117. package/website/dist/fonts/index.html +4 -2
  118. package/website/dist/getting-started/index.html +4 -2
  119. package/website/dist/helpers/index.html +196 -10
  120. package/website/dist/images/index.html +4 -2
  121. package/website/dist/index.html +4 -3
  122. package/website/dist/llm.txt +870 -20
  123. package/website/dist/playground/index.html +6 -0
  124. package/website/dist/preview/index.html +4 -2
  125. package/website/dist/sdk/index.html +639 -127
  126. package/website/dist/sitemap.xml +12 -12
  127. package/website/dist/styling/index.html +4 -2
  128. package/website/dist/templates/index.html +4 -2
  129. package/website/dist/video/index.html +47 -12
  130. package/website/package-lock.json +11 -1
  131. package/website/package.json +3 -1
  132. package/website/wrangler.toml +9 -0
  133. package/_dsgn/templates/dashed-stroke-test/template.tsx +0 -73
  134. package/_dsgn/templates/path-follow-test/template.tsx +0 -176
  135. package/_dsgn/templates/path-simple-test/template.tsx +0 -98
  136. package/_dsgn/templates/stroke-dash-test/meta.json +0 -12
  137. package/_dsgn/templates/stroke-dash-test/template.tsx +0 -53
  138. package/website/dist/_astro/agents.Yx-L_igG.css +0 -1
  139. package/website/dist/_worker.js/manifest_CT_D-YDe.mjs +0 -98
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Loopwind SDK for Edge Runtimes (Cloudflare Workers, Vercel Edge, etc.)
3
+ *
4
+ * This module provides image rendering without Node.js dependencies.
5
+ * Uses @resvg/resvg-wasm instead of @resvg/resvg-js.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { renderImage, defineTemplate } from 'loopwind/sdk/edge';
10
+ *
11
+ * const template = defineTemplate({
12
+ * name: 'og-image',
13
+ * size: { width: 1200, height: 630 },
14
+ * render: ({ tw, title }) => <div style={tw('flex')}>{title}</div>
15
+ * });
16
+ *
17
+ * const png = await renderImage(template, { title: 'Hello' });
18
+ * ```
19
+ */
20
+ import satori from 'satori';
21
+ import { Resvg, initWasm } from '@resvg/resvg-wasm';
22
+ // @ts-ignore - WASM import handled by bundler
23
+ import resvgWasm from '@resvg/resvg-wasm/index_bg.wasm?init';
24
+ import { tw as createTwHelper } from '../../lib/tailwind.js';
25
+ // Re-export template definition helpers (these don't use Node.js APIs)
26
+ export { defineTemplate, defineTemplateFromSchema } from '../template.js';
27
+ let wasmInitialized = false;
28
+ let wasmInitPromise = null;
29
+ /**
30
+ * Initialize WASM module (called automatically on first render)
31
+ */
32
+ export async function initResvgWasm() {
33
+ if (wasmInitialized)
34
+ return;
35
+ if (wasmInitPromise) {
36
+ await wasmInitPromise;
37
+ return;
38
+ }
39
+ wasmInitPromise = (async () => {
40
+ try {
41
+ // Try to initialize with the bundled WASM
42
+ if (typeof resvgWasm === 'function') {
43
+ const wasmModule = await resvgWasm();
44
+ await initWasm(wasmModule);
45
+ }
46
+ else {
47
+ await initWasm(resvgWasm);
48
+ }
49
+ wasmInitialized = true;
50
+ }
51
+ catch (error) {
52
+ // If already initialized, ignore
53
+ if (String(error).includes('already been initialized')) {
54
+ wasmInitialized = true;
55
+ }
56
+ else {
57
+ throw error;
58
+ }
59
+ }
60
+ })();
61
+ await wasmInitPromise;
62
+ }
63
+ // Font cache
64
+ let fontCache = null;
65
+ /**
66
+ * Load default Inter font from CDN
67
+ */
68
+ async function loadDefaultFonts() {
69
+ if (fontCache)
70
+ return fontCache;
71
+ const fonts = [];
72
+ try {
73
+ // Load Inter Regular
74
+ const regularResponse = await fetch('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.18/files/inter-latin-400-normal.woff2');
75
+ if (regularResponse.ok) {
76
+ fonts.push({
77
+ name: 'Inter',
78
+ data: await regularResponse.arrayBuffer(),
79
+ weight: 400,
80
+ style: 'normal',
81
+ });
82
+ }
83
+ // Load Inter Bold
84
+ const boldResponse = await fetch('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.18/files/inter-latin-700-normal.woff2');
85
+ if (boldResponse.ok) {
86
+ fonts.push({
87
+ name: 'Inter',
88
+ data: await boldResponse.arrayBuffer(),
89
+ weight: 700,
90
+ style: 'normal',
91
+ });
92
+ }
93
+ }
94
+ catch (error) {
95
+ console.warn('Failed to load default fonts:', error);
96
+ }
97
+ fontCache = fonts;
98
+ return fonts;
99
+ }
100
+ /**
101
+ * Render an image from a template definition (Edge-compatible)
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const template = {
106
+ * name: 'og-image',
107
+ * size: { width: 1200, height: 630 },
108
+ * render: ({ tw, title }) => (
109
+ * <div style={tw('flex items-center justify-center w-full h-full bg-black')}>
110
+ * <h1 style={tw('text-6xl font-bold text-white')}>{title}</h1>
111
+ * </div>
112
+ * )
113
+ * };
114
+ *
115
+ * const png = await renderImage(template, { title: 'Hello World' });
116
+ * ```
117
+ */
118
+ export async function renderImage(template, props, options = {}) {
119
+ const { format = 'png', scale = 2, fonts: customFonts, config } = options;
120
+ // Merge configs
121
+ const mergedConfig = {
122
+ ...template.config,
123
+ ...config,
124
+ colors: { ...template.config?.colors, ...config?.colors },
125
+ fonts: { ...template.config?.fonts, ...config?.fonts },
126
+ };
127
+ // Create tw helper
128
+ const tw = (classes) => createTwHelper(classes, undefined, mergedConfig);
129
+ // Load fonts
130
+ const fonts = customFonts || await loadDefaultFonts();
131
+ // Render to SVG with satori
132
+ const svg = await satori(template.render({ ...props, tw, config: mergedConfig }), {
133
+ width: template.size.width,
134
+ height: template.size.height,
135
+ fonts: fonts.map(f => ({
136
+ name: f.name,
137
+ data: f.data,
138
+ weight: f.weight || 400,
139
+ style: f.style || 'normal',
140
+ })),
141
+ });
142
+ if (format === 'svg') {
143
+ return new TextEncoder().encode(svg).buffer;
144
+ }
145
+ // Initialize WASM if needed
146
+ await initResvgWasm();
147
+ // Convert to PNG using resvg-wasm
148
+ const resvg = new Resvg(svg, {
149
+ fitTo: {
150
+ mode: 'width',
151
+ value: Math.round(template.size.width * scale),
152
+ },
153
+ });
154
+ const pngData = resvg.render();
155
+ const pngBuffer = pngData.asPng();
156
+ return pngBuffer.buffer;
157
+ }
158
+ /**
159
+ * Render to SVG only (no WASM needed)
160
+ */
161
+ export async function renderSVG(template, props, options = {}) {
162
+ const { fonts: customFonts, config } = options;
163
+ // Merge configs
164
+ const mergedConfig = {
165
+ ...template.config,
166
+ ...config,
167
+ colors: { ...template.config?.colors, ...config?.colors },
168
+ fonts: { ...template.config?.fonts, ...config?.fonts },
169
+ };
170
+ // Create tw helper
171
+ const tw = (classes) => createTwHelper(classes, undefined, mergedConfig);
172
+ // Load fonts
173
+ const fonts = customFonts || await loadDefaultFonts();
174
+ // Render to SVG with satori
175
+ const svg = await satori(template.render({ ...props, tw, config: mergedConfig }), {
176
+ width: template.size.width,
177
+ height: template.size.height,
178
+ fonts: fonts.map(f => ({
179
+ name: f.name,
180
+ data: f.data,
181
+ weight: f.weight || 400,
182
+ style: f.style || 'normal',
183
+ })),
184
+ });
185
+ return svg;
186
+ }
187
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sdk/edge/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Cloudflare Workers SDK for loopwind
3
+ *
4
+ * Pure JavaScript/WASM implementation for edge runtimes.
5
+ * - @resvg/resvg-wasm for SVG-to-PNG conversion
6
+ * - h264-mp4-encoder for video encoding
7
+ *
8
+ * All rendering (image and video) works in Cloudflare Workers!
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { renderImage, renderSVG, renderVideo, defineTemplate, initWasm } from 'loopwind/sdk/workers';
13
+ * import React from 'react';
14
+ *
15
+ * // Image template
16
+ * const imageTemplate = defineTemplate({
17
+ * name: 'og-image',
18
+ * size: { width: 1200, height: 630 },
19
+ * render: ({ tw, title }) => React.createElement(
20
+ * 'div',
21
+ * { style: tw('flex items-center justify-center w-full h-full bg-blue-500') },
22
+ * React.createElement('h1', { style: tw('text-6xl font-bold text-white') }, title)
23
+ * )
24
+ * });
25
+ *
26
+ * // SVG (no WASM needed)
27
+ * const svg = await renderSVG(imageTemplate, { title: 'Hello World' });
28
+ *
29
+ * // PNG (requires WASM)
30
+ * await initWasm();
31
+ * const png = await renderImage(imageTemplate, { title: 'Hello World' });
32
+ *
33
+ * // Video template
34
+ * const videoTemplate = defineTemplate({
35
+ * name: 'intro',
36
+ * type: 'video',
37
+ * size: { width: 1920, height: 1080 },
38
+ * video: { fps: 30, duration: 2 },
39
+ * render: ({ tw, progress }) => React.createElement(
40
+ * 'div',
41
+ * { style: tw('flex items-center justify-center w-full h-full bg-gradient-to-r from-blue-500 to-purple-500') },
42
+ * React.createElement('div', { style: { opacity: progress } }, 'Fade In')
43
+ * )
44
+ * });
45
+ *
46
+ * // MP4 (requires WASM)
47
+ * const mp4 = await renderVideo(videoTemplate, {});
48
+ * ```
49
+ */
50
+ import { type TemplateConfig, type FontConfig, type StyleConfig } from '../../lib/render-core.js';
51
+ export { defineTemplate } from '../../lib/render-core.js';
52
+ export type { TemplateConfig, FontConfig, StyleConfig };
53
+ export { defineTemplateFromSchema, defineTemplateFromSource } from '../template.js';
54
+ export type { TemplateDefinition } from '../template.js';
55
+ /**
56
+ * Render options for workers
57
+ */
58
+ export interface WorkerRenderOptions {
59
+ format?: 'png' | 'svg';
60
+ fonts?: FontConfig[];
61
+ config?: StyleConfig;
62
+ scale?: number;
63
+ }
64
+ /**
65
+ * Initialize WASM (required for PNG rendering)
66
+ */
67
+ export declare function initWasm(resvgWasm?: ArrayBuffer): Promise<void>;
68
+ /**
69
+ * Check if WASM is initialized
70
+ */
71
+ export declare function isWasmInitialized(): boolean;
72
+ /**
73
+ * Render to SVG string
74
+ */
75
+ export declare function renderSVG<TProps = any>(template: TemplateConfig<TProps>, props: TProps, options?: WorkerRenderOptions): Promise<string>;
76
+ /**
77
+ * Render to PNG (requires initWasm() first)
78
+ */
79
+ export declare function renderImage<TProps = any>(template: TemplateConfig<TProps>, props: TProps, options?: WorkerRenderOptions): Promise<Uint8Array>;
80
+ /**
81
+ * Load a font from URL (helper for custom fonts)
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const fonts = await Promise.all([
86
+ * loadFont('https://example.com/my-font-400.woff', 'MyFont', 400),
87
+ * loadFont('https://example.com/my-font-700.woff', 'MyFont', 700),
88
+ * ]);
89
+ *
90
+ * const png = await renderImage(template, props, { fonts });
91
+ * ```
92
+ */
93
+ export declare function loadFont(url: string, name: string, weight?: number, style?: 'normal' | 'italic'): Promise<FontConfig>;
94
+ /**
95
+ * Fetch an image and convert to data URI
96
+ */
97
+ export declare function fetchImage(url: string): Promise<string>;
98
+ /**
99
+ * Video render options for workers
100
+ */
101
+ export interface VideoRenderOptions {
102
+ fonts?: FontConfig[];
103
+ config?: StyleConfig;
104
+ quality?: number;
105
+ onProgress?: (frame: number, total: number) => void;
106
+ }
107
+ /**
108
+ * Render a video template to MP4 (requires initWasm() first)
109
+ *
110
+ * Uses h264-mp4-encoder (WASM) for encoding - works in Cloudflare Workers.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * await initWasm();
115
+ *
116
+ * const template = defineTemplate({
117
+ * name: 'video',
118
+ * type: 'video',
119
+ * size: { width: 1920, height: 1080 },
120
+ * video: { fps: 30, duration: 2 },
121
+ * render: ({ tw, progress }) => React.createElement(
122
+ * 'div',
123
+ * { style: tw('flex items-center justify-center w-full h-full bg-blue-500') },
124
+ * React.createElement('div', {
125
+ * style: { opacity: progress, ...tw('text-6xl font-bold text-white') }
126
+ * }, 'Fade In')
127
+ * )
128
+ * });
129
+ *
130
+ * const mp4 = await renderVideo(template, {});
131
+ * return new Response(mp4, { headers: { 'Content-Type': 'video/mp4' } });
132
+ * ```
133
+ */
134
+ export declare function renderVideo<TProps = any>(template: TemplateConfig<TProps>, props: TProps, options?: VideoRenderOptions): Promise<Uint8Array>;
135
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sdk/workers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAIH,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AAGxD,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACpF,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,SAAS,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAarE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAyCD;;GAEG;AACH,wBAAsB,SAAS,CAAC,MAAM,GAAG,GAAG,EAC1C,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,GAAG,GAAG,EAC5C,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,UAAU,CAAC,CAyBrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,MAAY,EACpB,KAAK,GAAE,QAAQ,GAAG,QAAmB,GACpC,OAAO,CAAC,UAAU,CAAC,CAWrB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAc7D;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,WAAW,CAAC,MAAM,GAAG,GAAG,EAC5C,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAgErB"}
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Cloudflare Workers SDK for loopwind
3
+ *
4
+ * Pure JavaScript/WASM implementation for edge runtimes.
5
+ * - @resvg/resvg-wasm for SVG-to-PNG conversion
6
+ * - h264-mp4-encoder for video encoding
7
+ *
8
+ * All rendering (image and video) works in Cloudflare Workers!
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { renderImage, renderSVG, renderVideo, defineTemplate, initWasm } from 'loopwind/sdk/workers';
13
+ * import React from 'react';
14
+ *
15
+ * // Image template
16
+ * const imageTemplate = defineTemplate({
17
+ * name: 'og-image',
18
+ * size: { width: 1200, height: 630 },
19
+ * render: ({ tw, title }) => React.createElement(
20
+ * 'div',
21
+ * { style: tw('flex items-center justify-center w-full h-full bg-blue-500') },
22
+ * React.createElement('h1', { style: tw('text-6xl font-bold text-white') }, title)
23
+ * )
24
+ * });
25
+ *
26
+ * // SVG (no WASM needed)
27
+ * const svg = await renderSVG(imageTemplate, { title: 'Hello World' });
28
+ *
29
+ * // PNG (requires WASM)
30
+ * await initWasm();
31
+ * const png = await renderImage(imageTemplate, { title: 'Hello World' });
32
+ *
33
+ * // Video template
34
+ * const videoTemplate = defineTemplate({
35
+ * name: 'intro',
36
+ * type: 'video',
37
+ * size: { width: 1920, height: 1080 },
38
+ * video: { fps: 30, duration: 2 },
39
+ * render: ({ tw, progress }) => React.createElement(
40
+ * 'div',
41
+ * { style: tw('flex items-center justify-center w-full h-full bg-gradient-to-r from-blue-500 to-purple-500') },
42
+ * React.createElement('div', { style: { opacity: progress } }, 'Fade In')
43
+ * )
44
+ * });
45
+ *
46
+ * // MP4 (requires WASM)
47
+ * const mp4 = await renderVideo(videoTemplate, {});
48
+ * ```
49
+ */
50
+ import { Resvg, initWasm as initResvgWasm } from '@resvg/resvg-wasm';
51
+ import HME from 'h264-mp4-encoder';
52
+ import { renderTemplateToSVG, } from '../../lib/render-core.js';
53
+ // Re-export core types and functions
54
+ export { defineTemplate } from '../../lib/render-core.js';
55
+ // Re-export from template module for backwards compatibility
56
+ export { defineTemplateFromSchema, defineTemplateFromSource } from '../template.js';
57
+ // WASM state
58
+ let wasmInitialized = false;
59
+ /**
60
+ * Initialize WASM (required for PNG rendering)
61
+ */
62
+ export async function initWasm(resvgWasm) {
63
+ if (wasmInitialized)
64
+ return;
65
+ if (resvgWasm) {
66
+ await initResvgWasm(resvgWasm);
67
+ }
68
+ else {
69
+ const wasmUrl = 'https://unpkg.com/@resvg/resvg-wasm@2.6.2/index_bg.wasm';
70
+ const response = await fetch(wasmUrl);
71
+ const wasm = await response.arrayBuffer();
72
+ await initResvgWasm(wasm);
73
+ }
74
+ wasmInitialized = true;
75
+ }
76
+ /**
77
+ * Check if WASM is initialized
78
+ */
79
+ export function isWasmInitialized() {
80
+ return wasmInitialized;
81
+ }
82
+ // Font cache
83
+ let defaultFontsCache = null;
84
+ async function getDefaultFonts() {
85
+ if (defaultFontsCache)
86
+ return defaultFontsCache;
87
+ const fonts = [];
88
+ try {
89
+ const [regularRes, boldRes] = await Promise.all([
90
+ fetch('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.18/files/inter-latin-400-normal.woff'),
91
+ fetch('https://cdn.jsdelivr.net/npm/@fontsource/inter@5.0.18/files/inter-latin-700-normal.woff'),
92
+ ]);
93
+ if (regularRes.ok) {
94
+ fonts.push({
95
+ name: 'Inter',
96
+ data: await regularRes.arrayBuffer(),
97
+ weight: 400,
98
+ style: 'normal',
99
+ });
100
+ }
101
+ if (boldRes.ok) {
102
+ fonts.push({
103
+ name: 'Inter',
104
+ data: await boldRes.arrayBuffer(),
105
+ weight: 700,
106
+ style: 'normal',
107
+ });
108
+ }
109
+ }
110
+ catch (e) {
111
+ console.warn('Failed to load default fonts:', e);
112
+ }
113
+ defaultFontsCache = fonts;
114
+ return fonts;
115
+ }
116
+ /**
117
+ * Render to SVG string
118
+ */
119
+ export async function renderSVG(template, props, options = {}) {
120
+ const fonts = options.fonts || await getDefaultFonts();
121
+ return renderTemplateToSVG(template, props, {
122
+ fonts,
123
+ config: options.config,
124
+ });
125
+ }
126
+ /**
127
+ * Render to PNG (requires initWasm() first)
128
+ */
129
+ export async function renderImage(template, props, options = {}) {
130
+ const { format = 'png', scale = 2 } = options;
131
+ if (!wasmInitialized) {
132
+ throw new Error('WASM not initialized. Call initWasm() before rendering.');
133
+ }
134
+ if (template.type === 'video') {
135
+ throw new Error('Cannot render video template as image.');
136
+ }
137
+ const svg = await renderSVG(template, props, options);
138
+ if (format === 'svg') {
139
+ return new TextEncoder().encode(svg);
140
+ }
141
+ const resvg = new Resvg(svg, {
142
+ fitTo: {
143
+ mode: 'width',
144
+ value: Math.round(template.size.width * scale),
145
+ },
146
+ });
147
+ return resvg.render().asPng();
148
+ }
149
+ /**
150
+ * Load a font from URL (helper for custom fonts)
151
+ *
152
+ * @example
153
+ * ```typescript
154
+ * const fonts = await Promise.all([
155
+ * loadFont('https://example.com/my-font-400.woff', 'MyFont', 400),
156
+ * loadFont('https://example.com/my-font-700.woff', 'MyFont', 700),
157
+ * ]);
158
+ *
159
+ * const png = await renderImage(template, props, { fonts });
160
+ * ```
161
+ */
162
+ export async function loadFont(url, name, weight = 400, style = 'normal') {
163
+ const response = await fetch(url);
164
+ if (!response.ok) {
165
+ throw new Error(`Failed to load font from ${url}: ${response.statusText}`);
166
+ }
167
+ return {
168
+ name,
169
+ data: await response.arrayBuffer(),
170
+ weight,
171
+ style,
172
+ };
173
+ }
174
+ /**
175
+ * Fetch an image and convert to data URI
176
+ */
177
+ export async function fetchImage(url) {
178
+ try {
179
+ const response = await fetch(url);
180
+ if (!response.ok)
181
+ throw new Error(`Failed to fetch: ${response.statusText}`);
182
+ const arrayBuffer = await response.arrayBuffer();
183
+ const base64 = btoa(String.fromCharCode(...new Uint8Array(arrayBuffer)));
184
+ const contentType = response.headers.get('content-type') || 'image/png';
185
+ return `data:${contentType.split(';')[0]};base64,${base64}`;
186
+ }
187
+ catch (error) {
188
+ console.error('Image loading failed:', error);
189
+ return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
190
+ }
191
+ }
192
+ /**
193
+ * Render a video template to MP4 (requires initWasm() first)
194
+ *
195
+ * Uses h264-mp4-encoder (WASM) for encoding - works in Cloudflare Workers.
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * await initWasm();
200
+ *
201
+ * const template = defineTemplate({
202
+ * name: 'video',
203
+ * type: 'video',
204
+ * size: { width: 1920, height: 1080 },
205
+ * video: { fps: 30, duration: 2 },
206
+ * render: ({ tw, progress }) => React.createElement(
207
+ * 'div',
208
+ * { style: tw('flex items-center justify-center w-full h-full bg-blue-500') },
209
+ * React.createElement('div', {
210
+ * style: { opacity: progress, ...tw('text-6xl font-bold text-white') }
211
+ * }, 'Fade In')
212
+ * )
213
+ * });
214
+ *
215
+ * const mp4 = await renderVideo(template, {});
216
+ * return new Response(mp4, { headers: { 'Content-Type': 'video/mp4' } });
217
+ * ```
218
+ */
219
+ export async function renderVideo(template, props, options = {}) {
220
+ if (!wasmInitialized) {
221
+ throw new Error('WASM not initialized. Call initWasm() before rendering video.');
222
+ }
223
+ if (template.type !== 'video') {
224
+ throw new Error('Template must have type: "video" to render as video.');
225
+ }
226
+ if (!template.video) {
227
+ throw new Error('Template must have video config (fps, duration).');
228
+ }
229
+ const { fps, duration } = template.video;
230
+ const { width, height } = template.size;
231
+ const { quality = 23, onProgress } = options;
232
+ const totalFrames = Math.floor(fps * duration);
233
+ const fonts = options.fonts || await getDefaultFonts();
234
+ // Generate all frames as RGBA
235
+ const rgbaFrames = new Array(totalFrames);
236
+ for (let frame = 0; frame < totalFrames; frame++) {
237
+ const progress = frame / (totalFrames - 1);
238
+ const frameProps = { ...props, frame, progress };
239
+ // Render SVG
240
+ const svg = await renderTemplateToSVG(template, frameProps, {
241
+ fonts,
242
+ config: options.config,
243
+ });
244
+ // Convert SVG to RGBA using resvg
245
+ const resvg = new Resvg(svg, {
246
+ fitTo: { mode: 'width', value: width },
247
+ });
248
+ const rendered = resvg.render();
249
+ rgbaFrames[frame] = rendered.pixels;
250
+ if (onProgress) {
251
+ onProgress(frame + 1, totalFrames);
252
+ }
253
+ }
254
+ // Encode to H.264 MP4
255
+ const encoder = await HME.createH264MP4Encoder();
256
+ encoder.width = width;
257
+ encoder.height = height;
258
+ encoder.frameRate = fps;
259
+ encoder.quantizationParameter = quality;
260
+ encoder.speed = 10;
261
+ encoder.groupOfPictures = fps;
262
+ encoder.initialize();
263
+ for (let i = 0; i < rgbaFrames.length; i++) {
264
+ encoder.addFrameRgba(rgbaFrames[i]);
265
+ }
266
+ encoder.finalize();
267
+ const output = encoder.FS.readFile(encoder.outputFilename);
268
+ encoder.delete();
269
+ return output;
270
+ }
271
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sdk/workers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Tailwind config utilities for Cloudflare Workers
3
+ * Pure JavaScript - no Node.js dependencies
4
+ */
5
+ /**
6
+ * Tailwind config interface (simplified)
7
+ */
8
+ export interface TailwindConfig {
9
+ theme?: {
10
+ extend?: {
11
+ colors?: Record<string, any>;
12
+ spacing?: Record<string, string>;
13
+ fontSize?: Record<string, any>;
14
+ fontFamily?: Record<string, string[]>;
15
+ borderRadius?: Record<string, string>;
16
+ [key: string]: any;
17
+ };
18
+ colors?: Record<string, any>;
19
+ spacing?: Record<string, string>;
20
+ fontSize?: Record<string, any>;
21
+ fontFamily?: Record<string, string[]>;
22
+ borderRadius?: Record<string, string>;
23
+ [key: string]: any;
24
+ };
25
+ [key: string]: any;
26
+ }
27
+ export declare const DEFAULT_COLORS: Record<string, any>;
28
+ /**
29
+ * Resolve a color from Tailwind config
30
+ * Supports: primary, blue-500, slate-200, etc.
31
+ */
32
+ export declare function resolveColor(colorName: string, tailwindConfig: TailwindConfig | null): string | null;
33
+ /**
34
+ * Resolve spacing value from Tailwind config
35
+ */
36
+ export declare function resolveSpacing(value: string, tailwindConfig: TailwindConfig | null): string | null;
37
+ /**
38
+ * Resolve font size from Tailwind config
39
+ */
40
+ export declare function resolveFontSize(size: string, tailwindConfig: TailwindConfig | null): {
41
+ fontSize: string;
42
+ lineHeight?: string;
43
+ } | null;
44
+ /**
45
+ * Resolve border radius from Tailwind config
46
+ */
47
+ export declare function resolveBorderRadius(value: string, tailwindConfig: TailwindConfig | null): string | null;
48
+ //# sourceMappingURL=tailwind-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailwind-config.d.ts","sourceRoot":"","sources":["../../../src/sdk/workers/tailwind-config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE;YACP,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACtC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;SACpB,CAAC;QACF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAGD,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CA8F9C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,cAAc,GAAG,IAAI,GACpC,MAAM,GAAG,IAAI,CA+Bf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,cAAc,GAAG,IAAI,GACpC,MAAM,GAAG,IAAI,CAWf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,cAAc,GAAG,IAAI,GACpC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA6BlD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,cAAc,GAAG,IAAI,GACpC,MAAM,GAAG,IAAI,CAWf"}