Fetcher View Engine
Read references/api.md before composing or changing public APIs. Verify exports against packages/view-engine/src/index.ts and src/react.ts and reuse the package's examples and Storybook scenarios.
Choose the composition boundary
- For a complete workbench with saved-view navigation and management, use
ViewPage. It owns the engine lifecycle; keepscopeKeystable for the same user/tenant/access scope and recreate it when that identity changes. - For a caller-owned
ViewEngine, useRecordViewfor the record workbench orViewPageContentfor the navigation/management shell. The caller disposes its engine. - For a controlled table with externally owned data, use
RecordTable. For an isolated buffered filter editor, useFilterPanel; its caller handlesonApplyand any requests or saving. UseFieldFilterfor a fixed field andFilterSelectfor controlled labels/values. - Import headless contracts,
ViewEngineandMemoryViewHostfrom the core entry, React components from/react, and compiled styles from/styles.css.
Connect a record workbench
- Describe the actual response with
ViewDefinition: source ID, own-propertyrowKey/field navigation paths, field metadata and allowed operators. Store columns and their renderer references inViewInstance.config.presentation.table.columns, alongside the instance’s filter, sort and pagination configuration. Response property names exclude dots; dots in configured paths only navigate objects/arrays. Definitions and savedViewInstanceconfigurations are JSON; runtime functions belong in extensions. - Implement the applicable
ViewHostservices:definition,instance,preference,permission, plusresolveSourcefor business queries. The host provides metadata, persistence, current-user authorization and request identity/CAS guarantees. Reuse Fetcher/Wow query clients and existing storage APIs. - Let the engine coordinate selection, filter drafts/applied/saved state, paged/cursor navigation, queries, summaries, saving and recovery. Complete workbenches use engine commands for these operations. Instance lists supply
defaultInstanceId: nullor a returned ID. Saved operators must satisfy both definition-wide and field-level restrictions. - Persist
config.filterscomponent properties and references. The registered component owns pure compilation to a Wow filter; Query/Enter applies the draft. Preserve unset controls and opaque custom props. In React, register each component and compiler together throughextensions.filters; directly owned headless engines usefilterCompilers. - Use
extensions.globalActions,toolbarActions,rowActions,filtersandcellsfor the five extension points. Table actions handle current-page batch selection. Reuse built-in filters and cell renderers before adding custom components; report invalid editor buffers throughonValidityChange. - Respect the current capability/permission snapshot and system-view name/delete restrictions. Keep drafts after failures. Use
retryQueryfor record failures,refreshSummaryfor aggregate failures, andreloadInstancefor instance/write reconciliation. Unknown creations keep their original request ID/body; source-less recovery contexts remain inpendingCreates. These are local recovery entries, not ordinary queryable or saveable views. See the reference for conflict and idempotent-replay contracts.
Verify delivery
- Use
IndexedDBViewHostfor real browser persistence; useMemoryViewHostand the existing development HTTP fixtures for Node/in-process state to verify saved JSON through a fresh host/engine back into components, including extension props, permissions and uncertain-write recovery. Business records stay outside view storage. - Reuse the shadcn components in
src/components/ui. Preserve Base UI behavior,fve:utilities,--fve-*tokens, scoped portal themes and accessibility. - Run affected package tests/builds; include Storybook interaction checks for UI changes and the existing package/host acceptance commands for delivery-contract changes. Repository commits require the full
pnpm test:unitcheck. Read exact commands from package scripts and the API reference.