57 lines
1.8 KiB
Markdown
57 lines
1.8 KiB
Markdown
|
|
# Inventory + catalog — `client.inventory`, `client.catalog`
|
||
|
|
|
||
|
|
## Inventory
|
||
|
|
|
||
|
|
`InventoryDomain` (source: `src/domains/InventoryDomain.ts`) — owned items
|
||
|
|
merged with their catalog entries. Synced under revision key `inventory`;
|
||
|
|
also refreshed whenever the catalog changes.
|
||
|
|
|
||
|
|
```ts
|
||
|
|
client.inventory.data // InventoryItem[] | undefined
|
||
|
|
client.inventory.onChange(cb);
|
||
|
|
await client.inventory.load() / .reload();
|
||
|
|
```
|
||
|
|
|
||
|
|
### `InventoryItem` (merged view, source: `src/state/inventory.ts`)
|
||
|
|
|
||
|
|
```ts
|
||
|
|
interface InventoryItem {
|
||
|
|
slug: string; // '' when the wire item has no slug
|
||
|
|
amount: number; // 0 when absent on the wire
|
||
|
|
name: string; // nameOverride || catalog name || slug
|
||
|
|
properties: Record<string, unknown>; // catalog properties + propertiesOverride (override wins)
|
||
|
|
tags: string[]; // from the catalog entry
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
The raw wire shape is `PlayerInventoryItem`
|
||
|
|
(`slug?, amount?, nameOverride?, propertiesOverride?, updatedAt?`) — you rarely
|
||
|
|
need it; the domain hands out the merged `InventoryItem`.
|
||
|
|
|
||
|
|
## Catalog
|
||
|
|
|
||
|
|
`CatalogDomain` (source: `src/domains/CatalogDomain.ts`) — the item catalog
|
||
|
|
keyed by slug. Synced under revision key `catalog`.
|
||
|
|
|
||
|
|
```ts
|
||
|
|
client.catalog.data // Map<string, CatalogItem> | undefined
|
||
|
|
|
||
|
|
interface CatalogItem {
|
||
|
|
name?: string;
|
||
|
|
properties?: { [key: string]: unknown };
|
||
|
|
slug?: string;
|
||
|
|
tags?: string[];
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Items without a `slug` are skipped when the map is built.
|
||
|
|
|
||
|
|
## Behavior notes
|
||
|
|
|
||
|
|
- The catalog is warmed at login; inventory loads on first use, waits on the
|
||
|
|
catalog load, and merges, so `client.inventory.data` always has catalog
|
||
|
|
fields filled in.
|
||
|
|
- Invalidated after store purchases and scenario callbacks.
|
||
|
|
- Inventory has no client-side mutations — items change via purchases, quest /
|
||
|
|
battle pass rewards, and scenario nodes (all server-side).
|