@tamer4lynx/tamer-asset
Expo-style asset loading for Tamer/Lynx — JS runtime, React hooks, Rsbuild plugin, and native cache layer.
Install
t4l add tamer-asset
t4l link
How it works
At build time, the Rsbuild plugin (./tamer.config) scans source files for useAsset/useAssets calls with literal string paths, resolves each file, generates an asset manifest (tamer-asset-manifest.json), and registers an inline asset loader. At runtime, Asset.downloadAsync() fetches assets to a native FS cache (using ETags in dev, app bundle in prod).
Path arguments must be static string literals — dynamic strings cannot be resolved at build time and will fail.
Setup
Add the plugin via tamer.config.ts (auto-discovered by pluginTamer):
// tamer.config.ts
import pluginTamerAsset from '@tamer4lynx/tamer-asset/tamer.config';
export default {
plugins: [pluginTamerAsset],
};
Or wire the Rsbuild plugin manually:
import { createTamerAssetManifestPlugin, appendInlineAssetRule } from '@tamer4lynx/tamer-asset/plugin';
React hooks
import { useAsset, useAssets } from '@tamer4lynx/tamer-asset';
// single asset — path must be a static string literal
const [asset, error] = useAsset('./logo.png');
// multiple assets
const [assets, error] = useAssets(['./logo.png', './hero.png']);
Both hooks return [asset(s) | undefined, Error | undefined] and trigger a re-render when the download completes.
Asset class
import { Asset } from '@tamer4lynx/tamer-asset';
// sync — width/height may be undefined until downloadAsync()
const asset = Asset.fromModule({ uri: 'https://cdn.example.com/img.png', name: 'img', type: 'image/png', embedded: false });
await asset.downloadAsync(); // fetches to native cache, populates localUri / width / height
console.log(asset.localUri, asset.width, asset.height);
downloadAsync() is idempotent — calling it again on an already-downloaded asset returns immediately.
API
Types
type TamerAssetInput =
| string
| { uri?: string; localUri?: string; name?: string; type?: string;
hash?: string; width?: number; height?: number; embedded?: boolean };
type TamerAsset = {
uri: string; localUri: string; name: string; type: string;
hash?: string; width?: number; height?: number; embedded: boolean;
};