Skip to content

Commit cd995f4

Browse files
mfazekasclaude
andcommitted
feat: add explicit type field to ResolvedReferencedAsset for asset loading
Adds an optional `type` field ('image' | 'font' | 'audio') to ResolvedReferencedAsset so callers can declare asset types explicitly, avoiding the deprecated extension/magic-byte inference fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 3f0a5da commit cd995f4

8 files changed

Lines changed: 93 additions & 19 deletions

File tree

ios/new/ExperimentalAssetLoader.swift

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ enum AssetType {
66
case font
77
case audio
88

9+
/// Initialise from an explicit caller-provided string ("image" | "font" | "audio").
10+
/// This is the preferred path — always use this when the value is available.
11+
init?(fromExplicit string: String) {
12+
switch string.lowercased() {
13+
case "image": self = .image
14+
case "font": self = .font
15+
case "audio": self = .audio
16+
default: return nil
17+
}
18+
}
19+
20+
/// Initialise by guessing from a file-name suffix.
21+
/// Deprecated: provide `type` explicitly instead.
922
init?(fromName name: String) {
1023
let lowercased = name.lowercased()
1124
if lowercased.hasSuffix(".png") || lowercased.hasSuffix(".jpg") || lowercased.hasSuffix(".jpeg") || lowercased.hasSuffix(".webp") {
@@ -47,13 +60,23 @@ final class ExperimentalAssetLoader {
4760
let data = try await loadAssetData(asset)
4861
guard !data.isEmpty else { return }
4962

50-
let assetType = AssetType(fromName: name) ?? inferAssetType(from: asset, data: data)
51-
guard let assetType = assetType else {
52-
RCTLogWarn("Could not determine asset type for: \(name)")
63+
// Prefer an explicit type provided by the caller.
64+
let resolvedType: AssetType?
65+
if let explicit = asset.type, let explicitType = AssetType(fromExplicit: explicit) {
66+
resolvedType = explicitType
67+
} else {
68+
// No explicit type — fall back to extension / magic-byte inference.
69+
// Deprecated: set type on the asset entry to silence this warning.
70+
RCTLogWarn("[Rive] No type provided for '\(name)'. Falling back to extension/magic-byte inference — " +
71+
"set type: 'image' | 'font' | 'audio' on the asset to silence this warning.")
72+
resolvedType = AssetType(fromName: name) ?? inferAssetType(from: asset, data: data)
73+
}
74+
guard let resolvedType else {
75+
RCTLogWarn("[Rive] Could not determine asset type for: \(name)")
5376
return
5477
}
5578

56-
try await registerAsset(data: data, name: name, type: assetType, worker: worker)
79+
try await registerAsset(data: data, name: name, type: resolvedType, worker: worker)
5780
} catch {
5881
RCTLogError("Failed to load asset '\(name)': \(error)")
5982
}

nitrogen/generated/android/c++/JResolvedReferencedAsset.hpp

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nitrogen/generated/android/kotlin/com/margelo/nitro/rive/ResolvedReferencedAsset.kt

Lines changed: 6 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nitrogen/generated/ios/swift/ResolvedReferencedAsset.swift

Lines changed: 19 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nitrogen/generated/shared/c++/ResolvedReferencedAsset.hpp

Lines changed: 6 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/core/ReferencedAssets.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
import type { ResolvedReferencedAsset } from '../specs/RiveFile.nitro';
1+
import type { ResolvedReferencedAsset, RiveAssetType } from '../specs/RiveFile.nitro';
22
import type { RiveImage } from '../specs/RiveImage.nitro';
33

4-
export type ReferencedAssetSource = { source: number | { uri: string } };
4+
export type ReferencedAssetSource = {
5+
source: number | { uri: string };
6+
/**
7+
* Explicitly declares the type of this asset.
8+
* **Recommended** — the new Rive runtime does not expose asset type at load
9+
* time, so omitting this will trigger a deprecation warning and fall back to
10+
* extension / magic-byte inference.
11+
*/
12+
type?: RiveAssetType;
13+
};
514

615
export type ReferencedAsset = ReferencedAssetSource | RiveImage;
716

src/hooks/useRiveFile.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,27 +40,27 @@ function parsePossibleSources(asset: ReferencedAsset): ResolvedReferencedAsset {
4040
return { image: asset };
4141
}
4242

43-
const source = asset.source;
43+
const { source, type } = asset;
4444

4545
if (typeof source === 'number') {
4646
const resolvedAsset = Image.resolveAssetSource(source);
4747
if (resolvedAsset && resolvedAsset.uri) {
48-
return { sourceAssetId: resolvedAsset.uri };
48+
return { sourceAssetId: resolvedAsset.uri, type };
4949
} else {
5050
throw new Error('Invalid asset source provided.');
5151
}
5252
}
5353

5454
const uri = (source as any).uri;
5555
if (typeof source === 'object' && uri) {
56-
return { sourceUrl: uri };
56+
return { sourceUrl: uri, type };
5757
}
5858

5959
const fileName = (source as any).fileName;
6060
const path = (source as any).path;
6161

6262
if (typeof source === 'object' && fileName) {
63-
const result: ResolvedReferencedAsset = { sourceAsset: fileName };
63+
const result: ResolvedReferencedAsset = { sourceAsset: fileName, type };
6464

6565
if (path) {
6666
result.path = path;

src/specs/RiveFile.nitro.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,26 @@ export interface RiveEnumDefinition {
1515
readonly values: string[];
1616
}
1717

18+
/**
19+
* Explicitly declares the type of a referenced asset.
20+
* Providing this is **recommended** — the new Rive runtime no longer exposes
21+
* the asset type at load time, so falling back to extension/magic-byte
22+
* inference is deprecated and may be removed in a future release.
23+
*/
24+
export type RiveAssetType = 'image' | 'font' | 'audio';
25+
1826
export type ResolvedReferencedAsset = {
1927
sourceUrl?: string;
2028
sourceAsset?: string;
2129
/** URL on iOS, URL or resource name on Android (from Image.resolveAssetSource) */
2230
sourceAssetId?: string;
2331
path?: string;
2432
image?: RiveImage;
33+
/**
34+
* Explicitly declares the type of this asset.
35+
* Recommended — provide this instead of relying on extension/magic-byte inference.
36+
*/
37+
type?: RiveAssetType;
2538
};
2639

2740
export type ReferencedAssetsType = {

0 commit comments

Comments
 (0)