Recipes
Building route metadata for a custom decorator
This is the pattern @quik/http's route decorators use internally (packages/http/src/router/decorators/Metadata.ts):
import { MetadataStore } from '@quik/metadata';
type RouteMeta = {
name: string;
flags: string[];
};
function getRouteMetadata(context: ClassDecoratorContext): RouteMeta {
const metadata = MetadataStore.get<RouteMeta>(context.metadata);
if (context.name && !metadata.name) {
metadata.name = context.name.toString();
}
if (!metadata.flags) {
metadata.flags = [];
}
return metadata;
}
Because MetadataStore.get lazily creates an empty object on first access, decorator implementations can call it
repeatedly across multiple decorators applied to the same class/method and accumulate fields on the same record.
Inspecting all registered metadata
import { MetadataStore } from '@quik/metadata';
const entries = MetadataStore.snapshot(); // Array<Record<string, unknown>>
snapshot() is memoized between writes — it only recomputes the array after register/get adds a new key or
clear() runs, so repeated calls are cheap.
Clearing metadata on bootstrap reset
@quik/metadata's onReset() hook calls MetadataStore.clear() automatically during a full bootstrap restart.
clear() empties the snapshot()-backing cache (and invalidates the memoized snapshot array) — it does not, and
cannot, remove entries from the underlying WeakMap, since WeakMap has no way to enumerate or bulk-clear its
keys. Existing get(metadata) lookups for a DecoratorMetadata key already seen will still return the same
object after clear().