create-rendiv 0.1.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.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { createInterface } from 'node:readline';
8
+ import { execSync } from 'node:child_process';
9
+ const thisDir = path.dirname(fileURLToPath(import.meta.url));
10
+ const templateDir = path.resolve(thisDir, 'template');
11
+ function detectPackageManager() {
12
+ const agent = process.env.npm_config_user_agent ?? '';
13
+ if (agent.startsWith('pnpm'))
14
+ return 'pnpm';
15
+ if (agent.startsWith('yarn'))
16
+ return 'yarn';
17
+ if (agent.startsWith('bun'))
18
+ return 'bun';
19
+ return 'npm';
20
+ }
21
+ function prompt(question) {
22
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
23
+ return new Promise((resolve) => {
24
+ rl.question(question, (answer) => {
25
+ rl.close();
26
+ resolve(answer.trim());
27
+ });
28
+ });
29
+ }
30
+ function copyDir(src, dest) {
31
+ fs.mkdirSync(dest, { recursive: true });
32
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
33
+ const srcPath = path.join(src, entry.name);
34
+ const destPath = path.join(dest, entry.name);
35
+ if (entry.isDirectory()) {
36
+ copyDir(srcPath, destPath);
37
+ }
38
+ else {
39
+ fs.copyFileSync(srcPath, destPath);
40
+ }
41
+ }
42
+ }
43
+ async function create(projectName) {
44
+ const targetDir = path.resolve(process.cwd(), projectName);
45
+ const dirName = path.basename(targetDir);
46
+ if (fs.existsSync(targetDir)) {
47
+ console.error(chalk.red(`Error: Directory "${dirName}" already exists.`));
48
+ process.exit(1);
49
+ }
50
+ console.log();
51
+ console.log(chalk.bold(`Creating a new Rendiv project in ${chalk.cyan(targetDir)}`));
52
+ console.log();
53
+ // Copy template files
54
+ copyDir(templateDir, targetDir);
55
+ // Process package.json template
56
+ const tmplPath = path.join(targetDir, 'package.json.tmpl');
57
+ const pkgContent = fs.readFileSync(tmplPath, 'utf-8').replace(/\{\{PROJECT_NAME\}\}/g, dirName);
58
+ fs.writeFileSync(path.join(targetDir, 'package.json'), pkgContent);
59
+ fs.unlinkSync(tmplPath);
60
+ // Install dependencies
61
+ const pm = detectPackageManager();
62
+ console.log(chalk.gray(`Installing dependencies with ${pm}...`));
63
+ console.log();
64
+ try {
65
+ execSync(`${pm} install`, { cwd: targetDir, stdio: 'inherit' });
66
+ }
67
+ catch {
68
+ console.log();
69
+ console.log(chalk.yellow('Could not install dependencies automatically.'));
70
+ console.log(chalk.yellow(`Run ${chalk.bold(`cd ${dirName} && ${pm} install`)} manually.`));
71
+ console.log();
72
+ }
73
+ // Success message
74
+ console.log();
75
+ console.log(chalk.green('Done!') + ' Your Rendiv project is ready.');
76
+ console.log();
77
+ console.log(' Next steps:');
78
+ console.log();
79
+ console.log(chalk.cyan(` cd ${dirName}`));
80
+ console.log(chalk.cyan(` ${pm === 'npm' ? 'npx' : pm} rendiv studio src/index.tsx`));
81
+ console.log();
82
+ console.log(' Other commands:');
83
+ console.log();
84
+ console.log(` ${chalk.gray(`${pm} run preview`)} Preview in browser`);
85
+ console.log(` ${chalk.gray(`${pm} run render`)} Render to MP4`);
86
+ console.log(` ${chalk.gray(`${pm} run still`)} Export a single frame`);
87
+ console.log();
88
+ }
89
+ const program = new Command();
90
+ program
91
+ .name('create-rendiv')
92
+ .description('Create a new Rendiv video project')
93
+ .version('0.1.0')
94
+ .argument('[project-name]', 'Name for the new project')
95
+ .action(async (name) => {
96
+ let projectName = name;
97
+ if (!projectName) {
98
+ projectName = await prompt('Project name: ');
99
+ }
100
+ if (!projectName) {
101
+ console.error(chalk.red('Error: Project name is required.'));
102
+ process.exit(1);
103
+ }
104
+ await create(projectName);
105
+ });
106
+ program.parse();
107
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAEtD,SAAS,oBAAoB;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC;IACtD,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5C,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,MAAM,CAAC,QAAgB;IAC9B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,EAAE,IAAY;IACxC,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,WAAmB;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAEzC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,OAAO,mBAAmB,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oCAAoC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,sBAAsB;IACtB,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAEhC,gCAAgC;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;IAChG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC;IACnE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAExB,uBAAuB;IACvB,MAAM,EAAE,GAAG,oBAAoB,EAAE,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,IAAI,CAAC;QACH,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC,CAAC;QAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,OAAO,OAAO,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;QAC3F,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,kBAAkB;IAClB,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,gCAAgC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,8BAA8B,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,0BAA0B,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,+BAA+B,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,mCAAmC,CAAC;KAChD,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,gBAAgB,EAAE,0BAA0B,CAAC;KACtD,MAAM,CAAC,KAAK,EAAE,IAAa,EAAE,EAAE;IAC9B,IAAI,WAAW,GAAG,IAAI,CAAC;IAEvB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "preview": "vite dev",
7
+ "studio": "rendiv studio src/index.tsx",
8
+ "render": "rendiv render src/index.tsx MyVideo out/my-video.mp4",
9
+ "still": "rendiv still src/index.tsx MyVideo out/still.png",
10
+ "compositions": "rendiv compositions src/index.tsx"
11
+ },
12
+ "dependencies": {
13
+ "@rendiv/core": "^0.1.0",
14
+ "@rendiv/player": "^0.1.0",
15
+ "@rendiv/cli": "^0.1.0",
16
+ "react": "^19.0.0",
17
+ "react-dom": "^19.0.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/react": "^19.0.0",
21
+ "@types/react-dom": "^19.0.0",
22
+ "@vitejs/plugin-react": "^4.3.0",
23
+ "vite": "^6.0.0",
24
+ "typescript": "^5.7.0"
25
+ }
26
+ }
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { useFrame, useCompositionConfig, Fill, interpolate, spring } from '@rendiv/core';
3
+
4
+ export const MyVideo: React.FC = () => {
5
+ const frame = useFrame();
6
+ const { fps, durationInFrames } = useCompositionConfig();
7
+
8
+ const opacity = interpolate(frame, [0, 30], [0, 1]);
9
+ const scale = spring({ frame, fps, config: { damping: 12 } });
10
+ const progress = frame / durationInFrames;
11
+
12
+ return (
13
+ <Fill
14
+ style={{
15
+ background: `linear-gradient(135deg, #0f0f0f ${(1 - progress) * 100}%, #1a1a2e 100%)`,
16
+ display: 'flex',
17
+ alignItems: 'center',
18
+ justifyContent: 'center',
19
+ }}
20
+ >
21
+ <h1
22
+ style={{
23
+ color: 'white',
24
+ fontSize: 80,
25
+ fontFamily: 'system-ui, sans-serif',
26
+ opacity,
27
+ transform: `scale(${scale})`,
28
+ }}
29
+ >
30
+ Hello, Rendiv!
31
+ </h1>
32
+ </Fill>
33
+ );
34
+ };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { setRootComponent, Composition } from '@rendiv/core';
3
+ import { MyVideo } from './MyVideo';
4
+
5
+ const Root: React.FC = () => (
6
+ <Composition
7
+ id="MyVideo"
8
+ component={MyVideo}
9
+ durationInFrames={150}
10
+ fps={30}
11
+ width={1920}
12
+ height={1080}
13
+ />
14
+ );
15
+
16
+ setRootComponent(Root);
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "private": true,
4
+ "type": "module",
5
+ "scripts": {
6
+ "preview": "vite dev",
7
+ "studio": "rendiv studio src/index.tsx",
8
+ "render": "rendiv render src/index.tsx MyVideo out/my-video.mp4",
9
+ "still": "rendiv still src/index.tsx MyVideo out/still.png",
10
+ "compositions": "rendiv compositions src/index.tsx"
11
+ },
12
+ "dependencies": {
13
+ "@rendiv/core": "^0.1.0",
14
+ "@rendiv/player": "^0.1.0",
15
+ "@rendiv/cli": "^0.1.0",
16
+ "react": "^19.0.0",
17
+ "react-dom": "^19.0.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/react": "^19.0.0",
21
+ "@types/react-dom": "^19.0.0",
22
+ "@vitejs/plugin-react": "^4.3.0",
23
+ "vite": "^6.0.0",
24
+ "typescript": "^5.7.0"
25
+ }
26
+ }
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { useFrame, useCompositionConfig, Fill, interpolate, spring } from '@rendiv/core';
3
+
4
+ export const MyVideo: React.FC = () => {
5
+ const frame = useFrame();
6
+ const { fps, durationInFrames } = useCompositionConfig();
7
+
8
+ const opacity = interpolate(frame, [0, 30], [0, 1]);
9
+ const scale = spring({ frame, fps, config: { damping: 12 } });
10
+ const progress = frame / durationInFrames;
11
+
12
+ return (
13
+ <Fill
14
+ style={{
15
+ background: `linear-gradient(135deg, #0f0f0f ${(1 - progress) * 100}%, #1a1a2e 100%)`,
16
+ display: 'flex',
17
+ alignItems: 'center',
18
+ justifyContent: 'center',
19
+ }}
20
+ >
21
+ <h1
22
+ style={{
23
+ color: 'white',
24
+ fontSize: 80,
25
+ fontFamily: 'system-ui, sans-serif',
26
+ opacity,
27
+ transform: `scale(${scale})`,
28
+ }}
29
+ >
30
+ Hello, Rendiv!
31
+ </h1>
32
+ </Fill>
33
+ );
34
+ };
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { setRootComponent, Composition } from '@rendiv/core';
3
+ import { MyVideo } from './MyVideo';
4
+
5
+ const Root: React.FC = () => (
6
+ <Composition
7
+ id="MyVideo"
8
+ component={MyVideo}
9
+ durationInFrames={150}
10
+ fps={30}
11
+ width={1920}
12
+ height={1080}
13
+ />
14
+ );
15
+
16
+ setRootComponent(Root);
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true
11
+ },
12
+ "include": ["src"]
13
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ });
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true
11
+ },
12
+ "include": ["src"]
13
+ }
@@ -0,0 +1,6 @@
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+
4
+ export default defineConfig({
5
+ plugins: [react()],
6
+ });
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "create-rendiv",
3
+ "version": "0.1.0",
4
+ "description": "Create a new Rendiv video project",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "create-rendiv": "./dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "template"
13
+ ],
14
+ "dependencies": {
15
+ "commander": "^12.1.0",
16
+ "chalk": "^5.3.0"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^22.0.0",
20
+ "@rendiv/tsconfig": "0.0.0"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc && cp -r src/template dist/template",
24
+ "typecheck": "tsc --noEmit",
25
+ "clean": "rm -rf dist"
26
+ }
27
+ }