useDocyrusInventory
Shared app-utils inventory cache for Docyrus metadata (apps, data sources with fields/enums/views/forms, users, brands, preferences) plus a post-sign-in load() warm-up hook that drives an application loading dialog.
Installation
pnpm dlx @docyrus/cli add @docyrus/hooks-use-docyrus-inventorypnpm add @docyrus/app-utils @docyrus/api-clientThis module ships two named exports:
getSharedDocyrusInventory(client)— returns the process-wide sharedInventoryClientfor a givenRestApiClient, creating it on first use (memoized in aWeakMapkeyed by client). Pass the result intocreateDataSourceClient/createDataViewClient/createDataFormClient({ inventory }) so every client shares one in-memory cache.nullin →nullout.useDocyrusInventoryLoader(options)— headless React hook that runsinventory.load()once per client (StrictMode-safe) right after sign-in, exposing determinate progress + status so a host app can render a loading dialog before routing to the home page.
Why this exists
The @docyrus/app-utils inventory (createInventoryClient) caches everything a Docyrus app needs at startup — apps, data sources (with embedded views / forms / fields, and enums on select-type fields), users, brands, and tenant preferences — in one GET /v1/apps/data-sources?expand=views,forms,fields request (plus a request each for users / brands / preferences). Because the cache lives in the returned client's closure, a single shared instance is what lets:
- a post-sign-in
load()warm-up populate it behind a progress bar, and - every inventory-backed hook (
useDocyrusFormView,useDocyrusDataGrid,useDocyrusDataViewSelect, …) read tenant metadata from that same warm cache instead of re-fetching per mount.
getSharedDocyrusInventory is the single source of that instance; the Docyrus hooks call it internally, so warming the cache once makes their schema / enum / view / form / relation reads cache hits.
getSharedDocyrusInventory(client)
import { getSharedDocyrusInventory } from '@docyrus/ui/library/hooks/use-docyrus-inventory';
import { createDataSourceClient } from '@docyrus/app-utils';
const inventory = getSharedDocyrusInventory(apiClient);
const dataSources = createDataSourceClient(apiClient, { inventory });
// No `expand` → served from the shared cache (fields incl. enums, views, forms embedded)
const contacts = await dataSources.getBySlug('crm', 'contacts');| Parameter | Type | Description |
|---|---|---|
client | RestApiClient | null | undefined | The authenticated API client. |
Returns: InventoryClient (or null when client is nullish).
useDocyrusInventoryLoader(options)
Runs inventory.load() once, as soon as it is enabled and a client exists, and re-runs automatically when the client identity changes (e.g. a tenant switch that rebuilds the client). Failures do not throw — status becomes 'error' and reload() retries; the app can still run (inventory-backed reads fall back to the API).
import { useDocyrusAuth } from '@docyrus/signin';
import { useDocyrusInventoryLoader } from '@docyrus/ui/library/hooks/use-docyrus-inventory';
function InventoryGate({ children }) {
const { client, status } = useDocyrusAuth();
const { status: loadStatus, progress, error, reload } = useDocyrusInventoryLoader({
client,
enabled: status === 'authenticated'
});
if (loadStatus === 'ready') return children;
return (
<LoadingDialog
message={progress?.message}
percent={Math.round((progress?.ratio ?? 0) * 100)}
error={error}
onRetry={reload} />
);
}Options
| Option | Type | Default | Description |
|---|---|---|---|
client | RestApiClient | null | undefined | — | The authenticated API client. The loader waits until this is set. |
enabled | boolean | true | Gate the warm-up (e.g. only once authenticated). Still requires a non-null client. |
include | InventoryLoadStepId[] | ['apps','data-sources','users','brands','preferences'] | Which tenant-wide steps to warm. Drop 'users' when the signed-in user may lack the Users.Read.All scope. |
configAppIds | string[] | VITE_APP_ID (if set) | App ids whose config + user-config to warm. Pass [] to skip. |
force | boolean | true | Invalidate caches before loading so the warm-up issues fresh network calls. |
Result
| Field | Type | Description |
|---|---|---|
inventory | InventoryClient | null | The shared inventory for the current client. |
status | 'idle' | 'loading' | 'ready' | 'error' | Warm-up lifecycle. |
progress | InventoryLoadProgress | null | Latest progress event — drive a determinate bar with progress.ratio. |
error | unknown | Present when status === 'error'. |
result | InventoryLoadResult | null | The loaded payload once ready. |
isLoading | boolean | true while warming. |
isReady | boolean | true once warmed successfully. |
reload | () => void | Re-run the warm-up (Retry button, or after a tenant switch). |
useDocyrusInstantMessageComposer
useDocyrusInstantMessageComposer hook.
useDocyrusKanban
One-call wiring of a Docyrus data source to a fully configured Kanban board with select/status/radio-group, user, and date columns, drag-to-update persistence, final-zone integration, and a standard Docyrus card layout.