Frontend SDK notification implementation
The SDK provides TypeScript types, runtime selectors, event merge behavior, application notification polling, display ownership classification, and action execution helpers.
Maintainer entry points:
src/types/notifications.tssrc/types/applicationNotifications.tssrc/notifications/src/plugins/displayPresentation.tssrc/plugins/actionDisplayPolicy.tssrc/plugins/actionRunner.tssrc/plugins/uiEffects.tssrc/plugins/applicationActionsInvalidation.tssrc/plugins/pluginsRegistry.tssrc/events/pollingEventSource.ts
Session selectors validate metadata and skip malformed records. Application notification controllers can hydrate an authoritative owner snapshot before polling from a cursor captured before that snapshot. Revision-aware merge prevents stale events from replacing newer snapshot records. Display envelopes classify connection and session ownership independently from presentation.
RestAgentBackend exposes application/session list and dismiss operations.
Mobile enables snapshot hydration and uses
NotificationDismissalCache over a host-provided KeyValueStore. The cache
stores connection/scope/session/notification identity plus the exact dismissed
revision, but no notification content.
Application notification controllers hide a cached exact revision, retry its unchanged dismissal during hydration or observation, and remove the cache after server convergence. A newer authoritative revision invalidates the older cache entry and is presented; the controller never rewrites the cached expected revision. Dismissal events remain in the event contract but are not forced onto another already-open presentation.
The SDK exposes the versioned retention type and a TTL deadline helper. Application notification controllers remember TTL lifecycle identities accepted before their deadline for the controller's lifetime. A reconstructed controller filters an elapsed record during snapshot hydration; no timer or TTL lifecycle event removes an already accepted record.
Direct action-display close remains transient and does not enter the notification dismissal cache. The cache is synchronization state, not the authoritative notification record.
NotificationUiEffectObserver deduplicates notification effects by scope,
notification identity, and revision and ignores terminal revisions.
uiEffects.ts stores backend-keyed pending session and session-list
invalidations. Matching mobile and desktop consumers claim one invalidation,
reload authoritative data, and acknowledge only after success. A failed or
deferred reload releases the claim while retaining the invalidation for a
later subscription.
Claims live in backend-scoped SDK state rather than component-local state. This prevents React rerender or resubscription from starting duplicate reloads while the first reload is still in flight. Revision comparison prevents a late completion from clearing a newer invalidation.
Application-action definition invalidation uses a parallel backend-keyed
pending revision. PluginsRegistry invalidates its cache, refreshes actions
and application UI schema, and acknowledges after successful refresh.
These runtime invalidations are not persisted independently. A reconstructed frontend can recreate notification invalidation by observing the latest persisted pending notification revision.
Tests should distinguish portable contract coverage from TypeScript-specific details such as backend-keyed subscriptions and controller ownership.