loopwind 0.25.9 → 0.25.10
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/cli.js +36 -28
- package/dist/cli.js.map +1 -1
- package/dist/sdk/edge-gif.d.ts +38 -0
- package/dist/sdk/edge-gif.d.ts.map +1 -0
- package/dist/sdk/edge-gif.js +107 -0
- package/dist/sdk/edge-gif.js.map +1 -0
- package/package.json +2 -1
- package/platform/container/Dockerfile +22 -0
- package/platform/container/package-lock.json +2319 -0
- package/platform/container/package.json +22 -0
- package/platform/package-lock.json +30 -0
- package/platform/package.json +2 -0
- package/platform/wrangler.toml +16 -0
package/dist/cli.js
CHANGED
|
@@ -6,12 +6,13 @@ import { renderCommand } from './commands/render.js';
|
|
|
6
6
|
import { validateCommand } from './commands/validate.js';
|
|
7
7
|
import { initCommand } from './commands/init.js';
|
|
8
8
|
import { defaultCommand } from './commands/default.js';
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
9
|
+
// Platform commands (commented out for now)
|
|
10
|
+
// import { loginCommand } from './commands/login.js';
|
|
11
|
+
// import { logoutCommand } from './commands/logout.js';
|
|
12
|
+
// import { whoamiCommand } from './commands/whoami.js';
|
|
13
|
+
// import { publishCommand } from './commands/publish.js';
|
|
14
|
+
// import { templatesCommand } from './commands/templates.js';
|
|
15
|
+
// import { unpublishCommand } from './commands/unpublish.js';
|
|
15
16
|
import { readFileSync } from 'fs';
|
|
16
17
|
import { fileURLToPath } from 'url';
|
|
17
18
|
import { dirname, join } from 'path';
|
|
@@ -72,29 +73,33 @@ program
|
|
|
72
73
|
.command('init')
|
|
73
74
|
.description('Initialize a loopwind.json config file')
|
|
74
75
|
.action(initCommand);
|
|
75
|
-
// Platform commands
|
|
76
|
+
// Platform commands (commented out for now)
|
|
77
|
+
/*
|
|
76
78
|
// loopwind login
|
|
77
79
|
program
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
.command('login')
|
|
81
|
+
.description('Authenticate with Loopwind Platform')
|
|
82
|
+
.action(loginCommand);
|
|
83
|
+
|
|
81
84
|
// loopwind logout
|
|
82
85
|
program
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
+
.command('logout')
|
|
87
|
+
.description('Log out from Loopwind Platform')
|
|
88
|
+
.action(logoutCommand);
|
|
89
|
+
|
|
86
90
|
// loopwind whoami
|
|
87
91
|
program
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
.command('whoami')
|
|
93
|
+
.description('Show current user and organization')
|
|
94
|
+
.action(whoamiCommand);
|
|
95
|
+
|
|
91
96
|
// loopwind publish [template]
|
|
92
97
|
program
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
.command('publish [template]')
|
|
99
|
+
.description('Publish a template to Loopwind Platform')
|
|
100
|
+
.option('-n, --name <name>', 'Override template name')
|
|
101
|
+
.option('-o, --org <org>', 'Organization to publish to (slug or name)')
|
|
102
|
+
.addHelpText('after', `
|
|
98
103
|
Examples:
|
|
99
104
|
Publish current directory:
|
|
100
105
|
$ loopwind publish
|
|
@@ -109,16 +114,19 @@ Examples:
|
|
|
109
114
|
Publish to a specific organization:
|
|
110
115
|
$ loopwind publish banner-hero --org my-company
|
|
111
116
|
`)
|
|
112
|
-
|
|
117
|
+
.action(publishCommand);
|
|
118
|
+
|
|
113
119
|
// loopwind templates
|
|
114
120
|
program
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
.command('templates')
|
|
122
|
+
.description('List published templates')
|
|
123
|
+
.action(templatesCommand);
|
|
124
|
+
|
|
118
125
|
// loopwind unpublish <name>
|
|
119
126
|
program
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
.command('unpublish <name>')
|
|
128
|
+
.description('Remove a template from Loopwind Platform')
|
|
129
|
+
.action(unpublishCommand);
|
|
130
|
+
*/
|
|
123
131
|
program.parse();
|
|
124
132
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,4CAA4C;AAC5C,sDAAsD;AACtD,wDAAwD;AACxD,wDAAwD;AACxD,0DAA0D;AAC1D,8DAA8D;AAC9D,8DAA8D;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAErC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1F,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,wFAAwF,CAAC;KACrG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC;KAC5B,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,wBAAwB;AACxB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,sBAAsB,EAAE,qBAAqB,EAAE,wBAAwB,CAAC;KAC/E,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,cAAc;AACd,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,mCAAmC;AACnC,OAAO;KACJ,OAAO,CAAC,2BAA2B,CAAC;KACpC,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,oBAAoB,EAAE,iEAAiE,CAAC;KAC/F,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;KAC9C,MAAM,CAAC,mBAAmB,EAAE,2CAA2C,EAAE,KAAK,CAAC;KAC/E,MAAM,CAAC,eAAe,EAAE,wCAAwC,CAAC;KACjE,MAAM,CAAC,gBAAgB,EAAE,8CAA8C,EAAE,IAAI,CAAC;KAC9E,MAAM,CAAC,UAAU,EAAE,4DAA4D,CAAC;KAChF,MAAM,CAAC,SAAS,EAAE,yDAAyD,CAAC;KAC5E,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;CAcvB,CAAC;KACC,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,kBAAkB;AAClB,OAAO;KACJ,OAAO,CAAC,qBAAqB,CAAC;KAC9B,WAAW,CAAC,4BAA4B,CAAC;KACzC,MAAM,CAAC,eAAe,CAAC,CAAC;AAE3B,cAAc;AACd,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,4CAA4C;AAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDE;AAEF,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Experimental GIF support for edge runtimes
|
|
3
|
+
*
|
|
4
|
+
* WARNING: This is experimental and may hit CPU/memory limits on free tier.
|
|
5
|
+
* Recommended for short animations (< 2 seconds, < 10 frames)
|
|
6
|
+
*/
|
|
7
|
+
import { GIFEncoder, quantize, applyPalette } from 'gifenc';
|
|
8
|
+
export interface GifOptions {
|
|
9
|
+
/** Frame HTML strings to render */
|
|
10
|
+
frames: string[];
|
|
11
|
+
/** Width in pixels */
|
|
12
|
+
width?: number;
|
|
13
|
+
/** Height in pixels */
|
|
14
|
+
height?: number;
|
|
15
|
+
/** Delay between frames in ms */
|
|
16
|
+
delay?: number;
|
|
17
|
+
/** Number of loops (0 = infinite) */
|
|
18
|
+
repeat?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Render frames to GIF
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const gif = await renderGif({
|
|
26
|
+
* frames: [
|
|
27
|
+
* '<div style="background: red;">Frame 1</div>',
|
|
28
|
+
* '<div style="background: blue;">Frame 2</div>',
|
|
29
|
+
* ],
|
|
30
|
+
* width: 400,
|
|
31
|
+
* height: 300,
|
|
32
|
+
* delay: 500, // 500ms between frames
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function renderGif(options: GifOptions): Promise<Uint8Array>;
|
|
37
|
+
export { GIFEncoder, quantize, applyPalette };
|
|
38
|
+
//# sourceMappingURL=edge-gif.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-gif.d.ts","sourceRoot":"","sources":["../../src/sdk/edge-gif.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAG5D,MAAM,WAAW,UAAU;IACzB,mCAAmC;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CA6CxE;AAgDD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Experimental GIF support for edge runtimes
|
|
3
|
+
*
|
|
4
|
+
* WARNING: This is experimental and may hit CPU/memory limits on free tier.
|
|
5
|
+
* Recommended for short animations (< 2 seconds, < 10 frames)
|
|
6
|
+
*/
|
|
7
|
+
import { ImageResponse } from 'workers-og';
|
|
8
|
+
import { GIFEncoder, quantize, applyPalette } from 'gifenc';
|
|
9
|
+
import { decode as decodePng } from 'fast-png';
|
|
10
|
+
/**
|
|
11
|
+
* Render frames to GIF
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const gif = await renderGif({
|
|
16
|
+
* frames: [
|
|
17
|
+
* '<div style="background: red;">Frame 1</div>',
|
|
18
|
+
* '<div style="background: blue;">Frame 2</div>',
|
|
19
|
+
* ],
|
|
20
|
+
* width: 400,
|
|
21
|
+
* height: 300,
|
|
22
|
+
* delay: 500, // 500ms between frames
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export async function renderGif(options) {
|
|
27
|
+
const { frames, width = 400, height = 300, delay = 100, repeat = 0, } = options;
|
|
28
|
+
if (frames.length === 0) {
|
|
29
|
+
throw new Error('At least one frame is required');
|
|
30
|
+
}
|
|
31
|
+
if (frames.length > 30) {
|
|
32
|
+
console.warn('Warning: Many frames may exceed Workers CPU/memory limits');
|
|
33
|
+
}
|
|
34
|
+
const gif = GIFEncoder();
|
|
35
|
+
for (let i = 0; i < frames.length; i++) {
|
|
36
|
+
// Render frame to PNG using workers-og
|
|
37
|
+
const response = new ImageResponse(frames[i], { width, height });
|
|
38
|
+
const pngBuffer = await response.arrayBuffer();
|
|
39
|
+
// Convert PNG to RGBA using pure JS decoder
|
|
40
|
+
const rgba = pngToRgba(new Uint8Array(pngBuffer));
|
|
41
|
+
// Quantize to 256 colors
|
|
42
|
+
const palette = quantize(rgba, 256, { format: 'rgb565' });
|
|
43
|
+
const indexed = applyPalette(rgba, palette, 'rgb565');
|
|
44
|
+
// Write frame
|
|
45
|
+
const frameOptions = {
|
|
46
|
+
palette,
|
|
47
|
+
delay: delay,
|
|
48
|
+
};
|
|
49
|
+
if (i === 0) {
|
|
50
|
+
gif.writeFrame(indexed, width, height, { ...frameOptions, first: true });
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
gif.writeFrame(indexed, width, height, frameOptions);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
gif.finish();
|
|
57
|
+
return gif.bytes();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Decode PNG to RGBA using fast-png (pure JS, no Canvas needed)
|
|
61
|
+
*/
|
|
62
|
+
function pngToRgba(png) {
|
|
63
|
+
const decoded = decodePng(png);
|
|
64
|
+
// fast-png returns data in the format matching the PNG
|
|
65
|
+
// We need RGBA, so handle different cases
|
|
66
|
+
if (decoded.channels === 4) {
|
|
67
|
+
// Already RGBA
|
|
68
|
+
return new Uint8Array(decoded.data);
|
|
69
|
+
}
|
|
70
|
+
else if (decoded.channels === 3) {
|
|
71
|
+
// RGB - add alpha channel
|
|
72
|
+
const rgba = new Uint8Array(decoded.width * decoded.height * 4);
|
|
73
|
+
for (let i = 0, j = 0; i < decoded.data.length; i += 3, j += 4) {
|
|
74
|
+
rgba[j] = decoded.data[i];
|
|
75
|
+
rgba[j + 1] = decoded.data[i + 1];
|
|
76
|
+
rgba[j + 2] = decoded.data[i + 2];
|
|
77
|
+
rgba[j + 3] = 255;
|
|
78
|
+
}
|
|
79
|
+
return rgba;
|
|
80
|
+
}
|
|
81
|
+
else if (decoded.channels === 2) {
|
|
82
|
+
// Grayscale + alpha
|
|
83
|
+
const rgba = new Uint8Array(decoded.width * decoded.height * 4);
|
|
84
|
+
for (let i = 0, j = 0; i < decoded.data.length; i += 2, j += 4) {
|
|
85
|
+
const gray = decoded.data[i];
|
|
86
|
+
rgba[j] = gray;
|
|
87
|
+
rgba[j + 1] = gray;
|
|
88
|
+
rgba[j + 2] = gray;
|
|
89
|
+
rgba[j + 3] = decoded.data[i + 1];
|
|
90
|
+
}
|
|
91
|
+
return rgba;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
// Grayscale
|
|
95
|
+
const rgba = new Uint8Array(decoded.width * decoded.height * 4);
|
|
96
|
+
for (let i = 0, j = 0; i < decoded.data.length; i++, j += 4) {
|
|
97
|
+
const gray = decoded.data[i];
|
|
98
|
+
rgba[j] = gray;
|
|
99
|
+
rgba[j + 1] = gray;
|
|
100
|
+
rgba[j + 2] = gray;
|
|
101
|
+
rgba[j + 3] = 255;
|
|
102
|
+
}
|
|
103
|
+
return rgba;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export { GIFEncoder, quantize, applyPalette };
|
|
107
|
+
//# sourceMappingURL=edge-gif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-gif.js","sourceRoot":"","sources":["../../src/sdk/edge-gif.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loopwind",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.10",
|
|
4
4
|
"description": "A CLI and SDK for generating images and videos from JSX templates using Tailwind CSS.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"chalk": "^5.3.0",
|
|
66
66
|
"commander": "^12.0.0",
|
|
67
67
|
"esbuild": "^0.27.0",
|
|
68
|
+
"fast-png": "^8.0.0",
|
|
68
69
|
"gifenc": "^1.0.3",
|
|
69
70
|
"gradient-string": "^3.0.0",
|
|
70
71
|
"h264-mp4-encoder": "^1.0.12",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Video rendering container for Loopwind
|
|
2
|
+
FROM node:20-slim
|
|
3
|
+
|
|
4
|
+
WORKDIR /app
|
|
5
|
+
|
|
6
|
+
# Copy package files
|
|
7
|
+
COPY package*.json ./
|
|
8
|
+
|
|
9
|
+
# Install dependencies
|
|
10
|
+
RUN npm ci
|
|
11
|
+
|
|
12
|
+
# Copy source
|
|
13
|
+
COPY . .
|
|
14
|
+
|
|
15
|
+
# Build TypeScript
|
|
16
|
+
RUN npm run build
|
|
17
|
+
|
|
18
|
+
# Expose port
|
|
19
|
+
EXPOSE 8080
|
|
20
|
+
|
|
21
|
+
# Start server
|
|
22
|
+
CMD ["node", "dist/server.js"]
|