From f43b0362f4aaa30532c97abbc79c9af8ba79deb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Wed, 29 Jul 2026 21:13:36 +0200 Subject: [PATCH] feat: ship rive-gen-types as a bin in @rive-app/react-native MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Users can now run the schema generator directly from the installed library — npx rive-gen-types assets/rive — per the packaging discussion in #352. @rive-app/canvas (the ~5MB wasm introspection dependency) is an optional peer: it is only needed at codegen time, so users who generate types add it as a devDependency (the CLI prints exactly that instruction when it is missing) and everyone else never downloads it. Mechanics: the generator is compiled to plain CommonJS (esbuild, target node20) into lib/cli/ during prepare, launched by a committed shebang wrapper in cli/ — so the published tool has no Bun or TypeScript runtime requirement. @rive-app/canvas moves to a lazy dynamic import with a friendly error, and runCli() is exported for the launcher. Verified end to end: npm pack, install into a fresh project, npx rive-gen-types without canvas (clear install hint, exit 1) and with it (correct .riv.d.ts generated). The longer-term home (separate package / future Rive CLI integration) stays open; migrating later is a deprecation notice away. --- cli/rive-gen-types.js | 8 ++++++++ package.json | 16 ++++++++++++++-- scripts/rive-gen-types.ts | 28 +++++++++++++++++++++++----- yarn.lock | 9 ++++++++- 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100755 cli/rive-gen-types.js diff --git a/cli/rive-gen-types.js b/cli/rive-gen-types.js new file mode 100755 index 00000000..37c28866 --- /dev/null +++ b/cli/rive-gen-types.js @@ -0,0 +1,8 @@ +#!/usr/bin/env node +// Launcher for the compiled generator (built by `yarn build:cli`). +require('../lib/cli/rive-gen-types.cjs') + .runCli() + .catch((err) => { + process.stderr.write(`${err && err.message ? err.message : err}\n`); + process.exit(1); + }); diff --git a/package.json b/package.json index b461e08c..893402d5 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "./package.json": "./package.json" }, "files": [ + "cli", "src", "lib", "android", @@ -38,7 +39,7 @@ "typecheck": "tsc", "lint": "eslint \"**/*.{js,ts,tsx}\"", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib", - "prepare": "npx react-native-builder-bob@^0.40.0 build", + "prepare": "npx react-native-builder-bob@^0.40.0 build && yarn build:cli", "nitrogen": "nitrogen && npx tsx scripts/nitrogen-postprocess.ts", "rive-gen-types": "bun scripts/rive-gen-types.ts", "release": "release-it", @@ -50,7 +51,8 @@ "lint:fix:kotlin": "./scripts/lint-fix-kotlin.sh", "lint:native": "yarn lint:swift && yarn lint:kotlin", "typetest": "tsd --typings src/index.tsx", - "test:scripts": "cd scripts/__tests__ && bun test --no-parallel" + "test:scripts": "cd scripts/__tests__ && bun test --no-parallel", + "build:cli": "esbuild scripts/rive-gen-types.ts --outfile=lib/cli/rive-gen-types.cjs --format=cjs --platform=node --target=node20 --log-override:empty-import-meta=silent" }, "keywords": [ "react-native", @@ -92,6 +94,7 @@ "babel-plugin-react-compiler": "^1.0.0", "commitlint": "^19.6.1", "del-cli": "^5.1.0", + "esbuild": "^0.27.7", "eslint": "^9.22.0", "eslint-config-prettier": "^10.1.1", "eslint-plugin-jest": "^29.1.0", @@ -110,6 +113,7 @@ "typescript": "^5.2.2" }, "peerDependencies": { + "@rive-app/canvas": "^2.39.0", "react": "*", "react-native": "*", "react-native-nitro-modules": ">=0.35.10 <0.36" @@ -228,5 +232,13 @@ "browserslist": "^4.24.4", "@react-native-harness/runtime@1.4.0-rc.1": "patch:@react-native-harness/runtime@npm%3A1.4.0-rc.1#./.yarn/patches/@react-native-harness-runtime-npm-1.4.0-rc.1-5f3d78d6f0.patch", "@react-native-harness/bundler-metro@1.4.0-rc.1": "patch:@react-native-harness/bundler-metro@npm%3A1.4.0-rc.1#./.yarn/patches/@react-native-harness-bundler-metro-npm-1.4.0-rc.1-748c6eda8c.patch" + }, + "bin": { + "rive-gen-types": "cli/rive-gen-types.js" + }, + "peerDependenciesMeta": { + "@rive-app/canvas": { + "optional": true + } } } diff --git a/scripts/rive-gen-types.ts b/scripts/rive-gen-types.ts index 811ae22e..2de7510f 100644 --- a/scripts/rive-gen-types.ts +++ b/scripts/rive-gen-types.ts @@ -25,10 +25,6 @@ import { } from 'fs'; import { dirname, resolve, basename, extname } from 'path'; import { pathToFileURL } from 'url'; -// Default-import + destructure: @rive-app/canvas is CJS, and Node's ESM -// loader cannot statically see its named exports (bun's interop can). -import riveCanvas from '@rive-app/canvas'; -const { RuntimeLoader } = riveCanvas; // Called from main() so that importing this module (for unit-testing the // exported emit helpers) has no global side effects. @@ -57,7 +53,24 @@ let runtimeReady: Promise | null = null; async function getRuntime(): Promise { if (!runtimeReady) { - runtimeReady = RuntimeLoader.awaitInstance(); + runtimeReady = (async () => { + let riveCanvas: any; + try { + // Dynamic import: when shipped as a bin, @rive-app/canvas is an + // optional (dev-time only) peer — users who run codegen install it, + // everyone else never downloads the wasm. + riveCanvas = await import('@rive-app/canvas'); + } catch { + throw new Error( + "rive-gen-types needs '@rive-app/canvas' to inspect .riv files.\n" + + 'Install it as a devDependency:\n' + + ' yarn add -D @rive-app/canvas (or npm install -D @rive-app/canvas)' + ); + } + // CJS/ESM interop: named exports may only be visible on .default. + const mod = riveCanvas.default ?? riveCanvas; + return mod.RuntimeLoader.awaitInstance(); + })(); } return runtimeReady; } @@ -404,6 +417,11 @@ const isMain = (process.argv[1] != null && import.meta.url === pathToFileURL(process.argv[1]).href); +/** Entry point for the published `rive-gen-types` bin (see cli/). */ +export function runCli(): Promise { + return main(); +} + if (isMain) { main().catch((err: Error) => { process.stderr.write(err.message + '\n'); diff --git a/yarn.lock b/yarn.lock index 33e6e616..1242a5dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7032,6 +7032,7 @@ __metadata: babel-plugin-react-compiler: ^1.0.0 commitlint: ^19.6.1 del-cli: ^5.1.0 + esbuild: ^0.27.7 eslint: ^9.22.0 eslint-config-prettier: ^10.1.1 eslint-plugin-jest: ^29.1.0 @@ -7049,9 +7050,15 @@ __metadata: turbo: ^1.10.7 typescript: ^5.2.2 peerDependencies: + "@rive-app/canvas": ^2.39.0 react: "*" react-native: "*" react-native-nitro-modules: ">=0.35.10 <0.36" + peerDependenciesMeta: + "@rive-app/canvas": + optional: true + bin: + rive-gen-types: cli/rive-gen-types.js languageName: unknown linkType: soft @@ -11130,7 +11137,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.27.0": +"esbuild@npm:^0.27.0, esbuild@npm:^0.27.7": version: 0.27.7 resolution: "esbuild@npm:0.27.7" dependencies: