Resource params should prefer URL-backed state
assertResourceParamsPreferQueryParams rejects query and asyncProcess params that depend on a local state. Filters, pagination and search values usually belong in queryParams, so a reload or a shared URL keeps the same view:
export function keepResourceParamsShareable(graph: ArchitectureGraph) {
assertResourceParamsPreferQueryParams(graph.graph, {
allow: [
{
name: 'locale',
file: 'src/app/examples/effect/effect-i18n.ts',
},
],
});
}What it prevents
This shape loses the active filters on reload:
const search = yield* state('search', '');
const page = yield* state('page', 1);
const params = craftComputed('usersParams', function* () {
return { search: yield* search(), page: yield* page() };
});
const users = yield* query('users', {
params,
loader: loadUsers,
});The architecture graph follows the complete params path, including computed values and dependencies declared in other files. It does not inspect state used only by a loader, insertion or unrelated UI code.
The URL-backed version
const filters = yield* queryParams('filters', {
state: {
search: { fallbackValue: '', codec: stringCodec },
page: { fallbackValue: 1, codec: numberCodec },
},
});
const users = yield* query('users', {
params: filters,
loader: loadUsers,
});Intentional exceptions
Some state values are not navigation state. For example, a process-wide locale may affect a query without belonging in the route. Whitelist that state with a name and, when necessary, a relative file path:
assertResourceParamsPreferQueryParams(graph.graph, {
allow: [
{
name: 'locale',
file: 'src/app/examples/effect/effect-i18n.ts',
},
],
});Keep the allowlist narrow and document the reason beside the architecture test.