Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9951679
feat: type-safe .riv schema system (POC)
mfazekas Jun 12, 2026
9add562
chore: fix lint (prettier) and exclude test-d.ts from jest
mfazekas Jun 12, 2026
c1ff0be
chore: prettier format scripts
mfazekas Jun 15, 2026
98ca778
feat: extract enum values into schema, type enumProperty() and useRiv…
mfazekas Jun 15, 2026
98cd17a
feat: enforce typed property paths via phantom brand on TypedViewMode…
mfazekas Jun 15, 2026
aff0862
feat: SchemaOf + TypedViewModelOf so typed params accept typeof impor…
mfazekas Jun 15, 2026
f5b2d96
chore: use structural __schema inference in useViewModelInstance type…
mfazekas Jun 15, 2026
4ccfd4f
chore: name the untyped overload brand as UntypedViewModelInstance
mfazekas Jun 15, 2026
54e7e77
chore: add type tests for useRiveNumber hook
mfazekas Jun 15, 2026
6cbfd72
chore: validate .riv schema files are up-to-date in CI
mfazekas Jun 15, 2026
5e05c0a
fix: restore number overload on fromSource to preserve backward compat
mfazekas Jun 15, 2026
448d960
fix: use spawnSync argv array instead of execSync shell string
mfazekas Jun 15, 2026
bcebc3e
fix: error on URL input without --out instead of producing an invalid…
mfazekas Jun 15, 2026
7bd30a7
chore: regenerate .riv.d.ts files with quoted property keys
mfazekas Jun 15, 2026
035a1ef
fix: exclude .riv.d.ts from lint, fix generator quoting to match pret…
mfazekas Jun 15, 2026
2390f25
chore: improve extractor error diagnostics
mfazekas Jun 15, 2026
bafe36a
fix: wrap long throw to satisfy prettier
mfazekas Jun 15, 2026
237c9fb
fix: handle null makeRenderImage on headless Linux, catch microtask e…
mfazekas Jun 15, 2026
1d5a587
fix: proxy stub for makeRenderImage when WebGL unavailable on headles…
mfazekas Jun 15, 2026
93c1f37
fix: use CustomFileAssetLoader to skip embedded assets, avoids WebGL …
mfazekas Jun 15, 2026
ba4798c
fix(scripts): handle embedded images on headless Linux in rive-extrac…
mfazekas Jun 15, 2026
32bf377
fix(scripts): run WASM inline in rive-gen-types, drop spawnSync subpr…
mfazekas Jun 15, 2026
c84f2f7
chore: fix prettier formatting in rive-gen-types.ts
mfazekas Jun 15, 2026
a5120ce
chore: remove unused __dirname from rive-gen-types.ts
mfazekas Jun 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actions/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ runs:
with:
node-version-file: .nvmrc

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Restore dependencies
id: yarn-cache
uses: actions/cache/restore@v4
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ jobs:
exit 1
fi

- name: Validate .riv schema files
run: |
yarn rive-gen-types --all example/assets/rive
if ! git diff --exit-code 'example/assets/rive/*.riv.d.ts'; then
echo "Error: .riv.d.ts files are out of date. Please run 'yarn rive-gen-types --all example/assets/rive' and commit the changes."
exit 1
fi

- name: Typecheck files
run: yarn typecheck

Expand Down
2 changes: 2 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export default defineConfig([
'node_modules/',
'lib/',
'**/.expo/',
'**/*.test-d.ts',
'**/*.riv.d.ts',
],
},
]);
Binary file added example/assets/rive/GradientBorder.riv
Binary file not shown.
17 changes: 17 additions & 0 deletions example/assets/rive/GradientBorder.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: GradientBorder.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Layout';
defaultArtboard: 'Layout';
stateMachines: {
Layout: 'State';
};
viewModels: {
ViewModel: {
isFocused: 'boolean';
};
};
}>;
export default asset;
21 changes: 21 additions & 0 deletions example/assets/rive/artboard_db_test.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: artboard_db_test.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Main' | 'ArtboardGreen' | 'ArtboardBlue' | 'ArtboardRed';
defaultArtboard: 'Main';
stateMachines: {
Main: 'State Machine 1';
ArtboardGreen: 'State Machine 1';
ArtboardBlue: 'State Machine 1';
ArtboardRed: 'State Machine 1';
};
viewModels: {
MainViewModel: {
artboard_1: 'artboard';
artboard_2: 'artboard';
};
};
}>;
export default asset;
97 changes: 97 additions & 0 deletions example/assets/rive/blinko.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: blinko.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Main' | 'StoreItem' | 'Token' | 'Indicator' | 'Puck' | 'StoreIcon' | 'Peg' | 'scoreBox';
defaultArtboard: 'Main';
stateMachines: {
Main: 'State Machine 1';
StoreItem: 'State Machine 1';
Token: 'State Machine 1';
Indicator: 'State Machine 1';
Puck: 'State Machine 1';
StoreIcon: 'State Machine 1';
Peg: 'State Machine 1';
scoreBox: 'State Machine 1';
};
viewModels: {
IndicatorVM: {
purchased: 'boolean';
};
StoreItemVM: {
tokenCount: 'number';
height: 'number';
itemHover: 'boolean';
cost: 'number';
description: 'string';
id: 'string';
itemType: 'string';
maxPurchases: 'number';
name: 'string';
purchase: 'trigger';
purchaseCount: 'number';
};
storeIconVM: {
storeiconClick: 'trigger';
iconHovered: 'boolean';
};
storeVM: {
'xbuttonClick': 'trigger';
'xbuttonHover': 'boolean';
'items': 'list';
'storeOpen': 'boolean';
'property of pegVM': 'viewModel:pegVM';
'multiplierValue': 'number';
'extraTokenSlotActive': 'boolean';
'extraTokenSlotCost': 'number';
'extraTokenSlotCount': 'number';
'purchaseExtraTokenSlot': 'trigger';
'purchaseSuperMultiplier': 'trigger';
'superMultiplierActive': 'boolean';
'superMultiplierCost': 'number';
'superMultiplierCount': 'number';
};
TokenVM: {
spinToken: 'boolean';
};
pegVM: {
blink: 'trigger';
multiplierValue: 'number';
pegType: 'enum:normal|multiplier';
pegBounced: 'trigger';
};
gameLogicVM: {
turnTokens: 'number';
turnScore: 'number';
buttonLabel: 'string';
message: 'string';
startTurn: 'trigger';
turnEnded: 'trigger';
gameEnded: 'boolean';
tokenCount: 'number';
scoreTotal: 'number';
};
scoreBox: {
Token: 'viewModel:TokenVM';
slotType: 'enum:addToken|normal';
landed: 'trigger';
scoreValue: 'number';
};
PuckVM: {
puckBounce: 'trigger';
puckRotation: 'number';
};
main: {
'PuckVM': 'viewModel:PuckVM';
'storeItemVM': 'viewModel:StoreItemVM';
'storeIconVM': 'viewModel:storeIconVM';
'pegVM': 'viewModel:pegVM';
'storeVM': 'viewModel:storeVM';
'buttonHover': 'boolean';
'tokenVM': 'viewModel:TokenVM';
'property of gameLogicVM': 'viewModel:gameLogicVM';
};
};
}>;
export default asset;
17 changes: 17 additions & 0 deletions example/assets/rive/bouncing_ball.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: bouncing_ball.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
vm: {
ypos: 'number';
};
};
}>;
export default asset;
17 changes: 17 additions & 0 deletions example/assets/rive/counter.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: counter.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
ViewModel1: {
cnt: 'number';
};
};
}>;
export default asset;
28 changes: 28 additions & 0 deletions example/assets/rive/databinding.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: databinding.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
Person: {
pet: 'viewModel:Pet';
jump: 'trigger';
likes_popcorn: 'boolean';
favourite_pet: 'enum:chipmunk|rat|frog|owl|cat|dog';
favourite_color: 'color';
age: 'number';
website: 'string';
name: 'string';
};
Pet: {
type: 'enum:chipmunk|rat|frog|owl|cat|dog';
name: 'string';
};
};
}>;
export default asset;
17 changes: 17 additions & 0 deletions example/assets/rive/databinding_images.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: databinding_images.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
MyViewModel: {
bound_image: 'image';
};
};
}>;
export default asset;
20 changes: 20 additions & 0 deletions example/assets/rive/databinding_lists.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: databinding_lists.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
Person: {
name: 'string';
};
DevRel: {
team: 'list';
};
};
}>;
export default asset;
12 changes: 12 additions & 0 deletions example/assets/rive/fallback_fonts.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: fallback_fonts.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
}>;
export default asset;
17 changes: 17 additions & 0 deletions example/assets/rive/font_fallback.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: font_fallback.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
ViewModel: {
text: 'string';
};
};
}>;
export default asset;
12 changes: 12 additions & 0 deletions example/assets/rive/hello_world_text.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: hello_world_text.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'New Artboard';
defaultArtboard: 'New Artboard';
stateMachines: {
'New Artboard': 'State Machine 1';
};
}>;
export default asset;
Binary file added example/assets/rive/inputglow.riv
Binary file not shown.
17 changes: 17 additions & 0 deletions example/assets/rive/inputglow.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: inputglow.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Layout';
defaultArtboard: 'Layout';
stateMachines: {
Layout: 'State';
};
viewModels: {
ViewModel: {
isFocused: 'boolean';
};
};
}>;
export default asset;
12 changes: 12 additions & 0 deletions example/assets/rive/ios_android_layouts_demo_v01.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: ios_android_layouts_demo_v01.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'iOS_Android_Layouts_demo_v01';
defaultArtboard: 'iOS_Android_Layouts_demo_v01';
stateMachines: {
iOS_Android_Layouts_demo_v01: 'State Machine 1';
};
}>;
export default asset;
Binary file added example/assets/rive/layout_test.riv
Binary file not shown.
17 changes: 17 additions & 0 deletions example/assets/rive/layout_test.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: layout_test.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'Artboard';
defaultArtboard: 'Artboard';
stateMachines: {
Artboard: 'State Machine 1';
};
viewModels: {
ViewModel1: {

};
};
}>;
export default asset;
12 changes: 12 additions & 0 deletions example/assets/rive/layouts_demo.riv.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Generated by rive-gen-types — do not edit manually. @generated
// eslint-disable
// Source: layouts_demo.riv
import type { RiveAsset } from '@rive-app/react-native';
declare const asset: RiveAsset<{
artboards: 'iOS_Android_Layouts_demo_v01';
defaultArtboard: 'iOS_Android_Layouts_demo_v01';
stateMachines: {
iOS_Android_Layouts_demo_v01: 'State Machine 1';
};
}>;
export default asset;
Loading
Loading