Skip to content

@aosengine/assets-aam ​

Classes ​

AamError ​

An AAM request that could not be completed.

The message names the path and the status but never the key — an error that reaches a log must not carry the credential.

Example ​

ts
import { AamError } from '@aosengine/assets-aam';

const err = new AamError('/api/characters/myra/ogs', 'not found', 404);
console.log(err.status, err.path); // 404 '/api/characters/myra/ogs'

Extends ​

  • Error

Constructors ​

Constructor ​
ts
new AamError(
   path, 
   message, 
   status?, 
   options?
): AamError;

Build an AAM error.

Parameters ​
ParameterTypeDescription
pathstringAAM path or URL involved.
messagestringWhat went wrong.
status?numberHTTP status, when there was one.
options?ErrorOptionsStandard Error options, used to keep the cause.
Returns ​

AamError

Overrides ​
ts
Error.constructor

Properties ​

path ​
ts
readonly path: string;

AAM path or URL the failure belongs to.

status? ​
ts
readonly optional status?: number;

HTTP status, when the failure came back as a response.

Interfaces ​

AamBundleFile ​

One file of a character's /ogs inference bundle.

Properties ​

name ​
ts
readonly name: string;

Bare filename, for example scene.json.

size? ​
ts
readonly optional size?: number;

Size in bytes, when the server reports one.

updatedAt? ​
ts
readonly optional updatedAt?: string;

Last-modified stamp, when the server reports one.

url ​
ts
readonly url: string;

Absolute URL the bytes are served from.


AamCharacterBundle ​

The listing of GET /api/characters/{slug}/ogs.

Properties ​

files ​
ts
readonly files: readonly AamBundleFile[];

Every file in the character's bundle, in server order.


AamCharacterEntries ​

What buildCharacterManifestEntries produces.

Properties ​

characterId ​
ts
readonly characterId: string;

Id of the character entry, for convenience.

entries ​
ts
readonly entries: readonly AssetEntry[];

The character entry plus one gltf entry per body clip.

faceClips ​
ts
readonly faceClips: readonly AamFaceClip[];

Face clips, which have no manifest type of their own.


AamClient ​

A typed AAM client bound to one deployment and one key.

Properties ​

baseUrl ​
ts
readonly baseUrl: string;

The normalised base URL, without a trailing slash.

Methods ​

fetchFile() ​
ts
fetchFile(url, options?): Promise<ArrayBuffer>;

Fetch one file's bytes, through the cache layer when it is enabled.

Parameters ​
ParameterTypeDescription
urlstringFile URL or AAM path.
options?AamFetchFileOptionsAbort signal and cache version token.
Returns ​

Promise<ArrayBuffer>

The bytes.

listAnimationAssets() ​
ts
listAnimationAssets(slug): Promise<AnimationAssetRow[]>;

List a character's animation clips.

Parameters ​
ParameterTypeDescription
slugstringCharacter slug.
Returns ​

Promise<AnimationAssetRow[]>

Every clip row, body and face.

listCharacterBundle() ​
ts
listCharacterBundle(slug): Promise<AamCharacterBundle>;

List a character's /ogs inference bundle.

Parameters ​
ParameterTypeDescription
slugstringCharacter slug.
Returns ​

Promise<AamCharacterBundle>

The bundle listing.

owns() ​
ts
owns(url): boolean;

Whether a URL belongs to this AAM deployment.

Parameters ​
ParameterTypeDescription
urlstringAbsolute URL, or a path when baseUrl is itself a path.
Returns ​

boolean

True when the key may be attached to it.

request() ​
ts
request(input, init?): Promise<Response>;

fetch with the key attached (same-origin only) and 5xx retried.

Parameters ​
ParameterTypeDescription
inputRequestInfo | URLURL, URL or Request to fetch.
init?RequestInitStandard fetch init; its headers are preserved.
Returns ​

Promise<Response>

The final Response, whatever its status.

resolveFileUrl() ​
ts
resolveFileUrl(path): string;

Join an AAM path onto baseUrl.

Parameters ​
ParameterTypeDescription
pathstringServer path such as /api/characters/myra/ogs, or a URL.
Returns ​

string

An absolute URL when baseUrl is absolute, else a prefixed path.


AamClientOptions ​

Options accepted by createAamClient.

Properties ​

apiKey ​
ts
readonly apiKey: string;

The X-API-Key value. Empty means "send no header" (cookie auth).

backoffMs? ​
ts
readonly optional backoffMs?: number;

First-retry delay in milliseconds; doubled on each further attempt.

baseUrl ​
ts
readonly baseUrl: string;

AAM origin or proxy prefix, for example https://aam.example or /aam.

cache? ​
ts
readonly optional cache?: AamCacheMode;

Where file bytes may be served from. Defaults to none.

fetch? ​
ts
readonly optional fetch?: (input, init?) => Promise<Response>;

fetch implementation. Defaults to the global one.

MDN Reference

Parameters ​
ParameterType
inputRequestInfo | URL
init?RequestInit
Returns ​

Promise<Response>

retries? ​
ts
readonly optional retries?: number;

Retries after the first attempt, on a network error or a 5xx.


AamEnvConfig ​

A usable AAM configuration read from the environment.

Properties ​

apiKey ​
ts
readonly apiKey: string;

Value of VITE_ASSET_MANAGER_API_KEY, or '' when it is unset.

Empty is legitimate: a deployment served from the same site authenticates with its session cookie, and the client then sends no X-API-Key header at all. The key is the localhost-development affordance, because a domain-scoped cookie cannot reach localhost.

baseUrl ​
ts
readonly baseUrl: string;

Value of VITE_ASSET_MANAGER_URL, with any trailing slash removed.


AamFaceClip ​

One face clip, as a JSON-serialisable record.

Face clips are ARKit weight tracks in JSON, not glTF, so they are not manifest entries — assets.json has no json type and inventing one would be a schema change. They come back as their own list instead, ready to be written into a game's own data file or handed to the animator directly.

Example ​

ts
import type { AamFaceClip } from '@aosengine/assets-aam';

const clip: AamFaceClip = {
  id: 'char.myra.smile',
  name: 'smile',
  url: 'https://aam.example/api/character-assets/7/smile.json',
  additive: false,
  additiveType: 'none',
  basePoseType: 'none',
  basePoseAssetId: null,
  refFrameIndex: 0,
  updatedAt: null,
};
console.log(clip.id); // 'char.myra.smile'

Properties ​

additive ​
ts
readonly additive: boolean;

Whether the clip plays as an additive layer.

additiveType ​
ts
readonly additiveType: AdditiveType;

Additive space.

basePoseAssetId ​
ts
readonly basePoseAssetId: string | null;

Row id of the clip supplying the base pose.

basePoseType ​
ts
readonly basePoseType: BasePoseType;

Which pose the additive bake subtracts.

id ​
ts
readonly id: string;

Manifest-style id, built from the same prefix as the body clips.

name ​
ts
readonly name: string;

The server's clip name.

refFrameIndex ​
ts
readonly refFrameIndex: number;

Frame index of the reference pose.

updatedAt ​
ts
readonly updatedAt: string | null;

Last-modified stamp, for cache versioning.

url ​
ts
readonly url: string;

Absolute URL the ARKit track is served from.


AamFetchFileOptions ​

Per-call options for AamClient.fetchFile.

Properties ​

signal? ​
ts
readonly optional signal?: AbortSignal;

Abort signal forwarded to fetch.

version? ​
ts
readonly optional version?: string | number | null;

Cache version token, normally the row's updatedAt or size. Changing it invalidates the Cache Storage entry, so a re-uploaded file is refetched instead of being replayed from the previous bytes.


AamResolver ​

A drop-in fetch bound to one AAM deployment.

Properties ​

fetch ​
ts
readonly fetch: (input, init?) => Promise<Response>;

fetch, with the key attached to AAM URLs only.

MDN Reference

Parameters ​
ParameterType
inputRequestInfo | URL
init?RequestInit
Returns ​

Promise<Response>


AnimationAssetRow ​

One row of GET /api/characters/{slug}/animation-assets.

The field names are the server's, not this package's: file_url is snake case and the additive settings are camel case, exactly as AAM sends them. Renaming them here would make the row un-greppable against the service.

Example ​

ts
import type { AnimationAssetRow } from '@aosengine/assets-aam';

const row: AnimationAssetRow = {
  id: '42',
  name: 'wave',
  kind: 'body',
  additive: true,
  file_url: '/api/character-assets/42/wave.glb',
  updatedAt: '2026-09-01T10:00:00Z',
  additiveType: 'local',
  basePoseType: 'local_frame',
  basePoseAssetId: null,
  refFrameIndex: 0,
};
console.log(row.kind); // 'body'

Properties ​

additive ​
ts
readonly additive: boolean;

Whether the clip is played as an additive layer.

additiveType ​
ts
readonly additiveType: AdditiveType;

Additive space. none when the clip is not additive.

basePoseAssetId ​
ts
readonly basePoseAssetId: string | null;

Row id of the clip supplying the base pose, for anim_frame.

basePoseType ​
ts
readonly basePoseType: BasePoseType;

Which pose the additive bake subtracts.

file_url ​
ts
readonly file_url: string;

Path or URL the bytes are served from.

id ​
ts
readonly id: string;

Server-assigned row id.

kind ​
ts
readonly kind: AnimationClipKind;

Body clip (a GLB) or face clip (an ARKit JSON track).

name ​
ts
readonly name: string;

Human-facing clip name; the manifest id is derived from it.

refFrameIndex ​
ts
readonly refFrameIndex: number;

Frame index of the reference pose inside the base clip.

updatedAt ​
ts
readonly updatedAt: string | null;

Last-modified stamp, used as the cache version. null when unknown.


BuildCharacterManifestOptions ​

Options accepted by buildCharacterManifestEntries.

Properties ​

idPrefix? ​
ts
readonly optional idPrefix?: string;

Id prefix for every entry. Defaults to char.<slug>.

rig? ​
ts
readonly optional rig?: AssetRig;

Rig for the character entry. Defaults to { backend: 'orl' }.

tags? ​
ts
readonly optional tags?: readonly string[];

Tags added to every generated entry. Defaults to ['aam', <slug>].

Type Aliases ​

AamCacheMode ​

ts
type AamCacheMode = "none" | "cache-storage";

Where AamClient.fetchFile may serve bytes from.


AdditiveType ​

ts
type AdditiveType = "none" | "local" | "mesh";

Which pose space an additive clip was baked in.


AnimationClipKind ​

ts
type AnimationClipKind = "body" | "face";

Whether a clip drives the body rig or the face.


BasePoseType ​

ts
type BasePoseType = "none" | "local_frame" | "anim_frame" | "ref_pose";

Which pose an additive clip subtracts to become a delta.

Variables ​

PACKAGE ​

ts
const PACKAGE: "@aosengine/assets-aam";

Package identity marker.

Example ​

ts
import { PACKAGE } from '@aosengine/assets-aam';

console.log(PACKAGE); // '@aosengine/assets-aam'

Functions ​

aamConfigFromEnv() ​

ts
function aamConfigFromEnv(env?): AamEnvConfig | null;

Read the AAM configuration from a Vite-style environment.

Parameters ​

ParameterTypeDescription
envRecord<string, string | undefined>Environment record. Defaults to import.meta.env.

Returns ​

AamEnvConfig | null

The configuration, or null when VITE_ASSET_MANAGER_URL is unset or blank — which means the adapter is simply not in use.

Example ​

ts
import { aamConfigFromEnv, createAamClient } from '@aosengine/assets-aam';

const config = aamConfigFromEnv({ VITE_ASSET_MANAGER_URL: 'https://aam.example' });
const client = config === null ? null : createAamClient(config);
console.log(config?.baseUrl); // 'https://aam.example'

buildCharacterManifestEntries() ​

ts
function buildCharacterManifestEntries(
   client, 
   slug, 
   options?
): Promise<AamCharacterEntries>;

Read a character's listings and turn them into manifest entries.

The character entry's src is a virtual directory URL — <baseUrl>/api/characters/<slug>/ogs/ — not a single file. The character loader appends a filename to it (scene.json, mesh.json, the decoders) and fetches each one, exactly as it would from a static directory; the only difference is that the directory is served by AAM and needs the key, which is what createAamResolver supplies.

The bundle listing is fetched as well as the directory being named, so an empty or missing bundle fails here, with the character's slug in the message, rather than deep inside the loader on a 404 for scene.json.

Parameters ​

ParameterTypeDescription
clientAamClientClient for the deployment the character lives in.
slugstringCharacter slug.
optionsBuildCharacterManifestOptionsId prefix, rig and tags.

Returns ​

Promise<AamCharacterEntries>

The character entry, the body-clip entries and the face clips.

Example ​

ts
import { buildCharacterManifestEntries, createAamClient } from '@aosengine/assets-aam';

const client = createAamClient({ baseUrl: 'https://aam.example', apiKey: key });
const built = await buildCharacterManifestEntries(client, 'myra');
console.log(built.characterId); // 'char.myra'

createAamClient() ​

ts
function createAamClient(options): AamClient;

Build a client for one AAM deployment.

Parameters ​

ParameterTypeDescription
optionsAamClientOptionsBase URL, key, and the injectable fetch, retry and cache policy.

Returns ​

AamClient

The client.

Example ​

ts
import { createAamClient } from '@aosengine/assets-aam';

const client = createAamClient({ baseUrl: 'https://aam.example', apiKey: key });
console.log(client.resolveFileUrl('/api/characters/myra/ogs'));
// 'https://aam.example/api/characters/myra/ogs'

createAamResolver() ​

ts
function createAamResolver(client): AamResolver;

Build the fetch option for loadManifest and loadCharacterBundle.

Parameters ​

ParameterTypeDescription
clientAamClientClient for the deployment that holds the key.

Returns ​

AamResolver

An object with a single fetch, assignable anywhere the engine accepts a fetch override.

Example ​

ts
import { loadManifest } from '@aosengine/assets';
import { createAamClient, createAamResolver } from '@aosengine/assets-aam';

const client = createAamClient({ baseUrl: 'https://aam.example', apiKey: key });
const resolver = createAamResolver(client);
const manifest = await loadManifest('/assets/assets.json', { fetch: resolver.fetch });
console.log(manifest.assets.length);

mergeManifests() ​

ts
function mergeManifests(base, extra): AssetManifest;

Merge generated entries into a game's manifest.

Entries built by buildCharacterManifestEntries carry absolute URLs, so the base manifest's baseUrl does not apply to them and is preserved untouched for everything that was already there. A duplicate id throws: an id is the guest/host contract, and silently letting one definition win would change what a running game loads without changing a line of its code.

Parameters ​

ParameterTypeDescription
baseAssetManifestThe game's manifest.
extra| AssetManifest | readonly AssetEntry[]Entries to add, or another manifest to take entries from.

Returns ​

AssetManifest

A new frozen manifest.

Example ​

ts
import { parseManifest } from '@aosengine/assets';
import { mergeManifests } from '@aosengine/assets-aam';

const base = parseManifest({ version: 1, baseUrl: '/assets/', assets: [] });
const merged = mergeManifests(base, [
  { id: 'char.myra.wave', type: 'gltf', src: 'https://aam.example/f/wave.glb' },
]);
console.log(merged.assets.length); // 1