Minor Changes
- 8619a4e: Per-entity punchline: new optional
descriptiononEntityManager— a one-liner explaining what the entity is, rendered as a muted subtitle under the list page title.useListPagepicks it up automatically; override per page with thesubtitleoption (nullsuppresses it). - dd100d7: Declare which entities your backend writes out of session, and qdadm routes its events to the right cache (#1888 lot C, reported in #1887).
sse: { entities: ['runs', 'jobs'] }— ortrue/'*'for all — makes the stream'sentity:{created,updated,deleted}frames (data: {"entity": "runs", "id": 42}) invalidate that entity's cache; the frame names are registered for you. Undeclared entities are ignored, since a stream carries more than entity mutations, with a one-off dev warning per entity so a dropped frame is never silent. The routing runs inside the front's security scope: an event for an entity the current user cannot read is dropped rather than refetched.LiveEntityRouteris transport-agnostic — itsnotify(entity, action, id)entry point takes a plain fact, so a WebSocket or aBroadcastChannelbetween two tabs attaches the same way SSE does. - a22f012: A screen showing a live entity now follows changes made outside the session (#1888 lot D, reported in #1887). Invalidating marks a cache stale but repaints nothing, so a list already on screen kept its rows until the user navigated away and back — precisely the case a pushing backend exists for.
useListPageanduseEntityItemShowPagenow reload themselves, with no page-level opt-in to forget: the gate is upstream, since only an entity declared insse.entitiesever produces a remote event. Each entity carries its own policy, pre-wired and overridable —live: { refresh: 'mounted' | false, coalesceMs: 300 }on theEntityManager, so a heavylogslist can drop its stale cache without refetching whilerunsrefreshes on sight. A burst of events collapses into one reload; a detail page only reacts to its own record; and a list refreshing under someone mid-bulk-action keeps their selection, re-matched by key. - 534512e: Remote changes now invalidate the list cache (#1888 lot B, reported in #1887).
entity:data-invalidatecarries asourcemarker, and anEntityManagerreceivingsource: 'remote'for its own entity drops its list cache. Until now no subscriber cleared it: the parent-entity handler only fires for an entity's parents, and the own-entity handler is gated on asymmetric mode and only touched the detail cache — so an ordinary entity received nothing, and an app emitting the canonical signal kept serving a stale list while believing it had invalidated everything. Local mutations emitsource: 'local'and are ignored by that handler, since the manager that mutated has already repaired its own cache: writes cost no extra refetch. - e910984: SSE: the auth token may now be fetched asynchronously, and the kernel
sseconfig can supply it (#1888 lot A, BookShepherd report #1887).EventSourceaccepts no headers, so the token rides in the query string and lands in access logs — apps that refuse to leak a durable credential there can now serve a short-lived, single-use ticket instead:getTokenaccepts() => string | null | Promise<string | null>, awaited before each connect.SSEConfiggainsgetToken(an explicitnullsends no token at all), plusconnectOnSignal/disconnectOnSignalpassthrough — without them the async token was unreachable for anyone using the kernel'ssseconfig rather than building anSSEBridgeby hand. Purely additive: synchronousgetTokenimplementations keep working unchanged. A connect that awaited its token now checks it has not been superseded before opening the connection, so adisconnect()or a secondconnect()during the fetch no longer resurrects a torn-down stream. - 4a04f4d: Vendor
pluralizeas an internal ESM module and drop it from dependencies (#1454). qdadm no longer has any CJS transitive, soqdadmVitePluginstops emittingoptimizeDeps.includeentirely — this fixes the unresolvablepluralizeoptimizer error forfile:-linked consumers (npminstall-links=false), where qdadm's deps are never installed at the consumer root. Consumers that addedpluralizeas a direct-dependency workaround can remove it.
Patch Changes
- a87ee80: Declare which parts of the API are stable and which are still moving (#1029). New
docs/API_STABILITY.mddefines three tiers operationally — stable is what the CI-enforced consumer-smoke fixture and the tutorial exercise, supported is documented and demo-exercised, experimental is marked in the source — and says what breaking each one costs. Five module entry points now carry@experimentalJSDoc, visible in editor tooltips:chain/,deferred/,query/(the executor classes only — the query object syntax is stable),kernel/SSEBridge, andgen/vite-plugin. Annotations and docs only; no API change. - 2fbdaab: Fix: a live event naming an entity with no registered manager is dropped instead of throwing (#1888).
Orchestrator.get()raises on an unknown name by design — to catch developer typos loudly — so the live router now checkshas()first. A typo insse.entities, or an entity whose module is lazily loaded, would otherwise have raised inside the signal bus on every frame the backend sent. - c2946e6: Declare
sass-embeddedas an optional peerDependency and add it to every quick-start install line (#1514, aihoku feedback). qdadm ships raw.scssstyles, so Vite consumers need a sass compiler — the requirement is now visible in metadata and docs instead of surfacing as aPreprocessor dependency "sass-embedded" not foundoverlay on first boot. - Updated dependencies [e910984]
- @quazardous/qdcore@1.1.0