@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

ExportDescription
AssetClass: fromModule(input), fromModuleSync(input), downloadAsync()
resolveAssetSource(input)Resolve a TamerAssetInputTamerAsset
loadAssets(inputs)Load and download an array of assets
getManifest()Return the build-time asset manifest
lookupManifestEntry(uri)Look up a manifest entry by URI
nativeFetch(uri, hash?)Fetch asset to native cache, returns { localUri, width?, height? }
nativeProbe(uri)Probe native dimensions without caching
nativeClearCache()Clear native asset cache
useAsset(path)Hook: [Asset | undefined, Error | undefined]
useAssets(paths)Hook: [Asset[] | undefined, Error | undefined]

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;
};