ui/role_grant_offers_state.svelte.ts

Reactive state for the consentful-role-grants offer flow.

Maintains one offer cache keyed by id, seeded by the RPC list/history actions and kept live by the six role-grant-offer WebSocket notifications. incoming (recipient-side pending) and outgoing (grantor-side pending) are derived views; history is the full cache ordered newest-first for the grantor/admin history view.

Wiring is transport-agnostic: the ctor accepts a narrow RPC interface the consumer adapts from their typed client, plus an account_id / actor_id getter pair (typically bound to auth_state). Notification delivery is pull-only via subscribe() — the consumer plumbs their FrontendWebsocketClient / ActionPeer receiver to apply_notification.

Holds six AsyncSlots — one per RPC verb. The cache #offers lives on the class (multiple ops write into it via #merge_offers / #remove_offer); the create slot is typed AsyncSlot<RoleGrantOfferJson> so submit_create can return the new offer via the slot's supersession-safe data path, but the other slots' data is unused (no single op owns the cache). Method names use the submit_* prefix to avoid slot-name collisions; the history view stayed natural by naming the fetch slot list_history.

Declarations
#

6 declarations

view source

role_grant_offers_state_context
#

ui/role_grant_offers_state.svelte.ts view source

{ get: (error_message?: string | undefined) => RoleGrantOffersState; get_maybe: () => RoleGrantOffersState | undefined; set: (value: RoleGrantOffersState) => RoleGrantOffersState; }

Svelte context for RoleGrantOffersState. Use role_grant_offers_state_context.set(state) in the provider and role_grant_offers_state_context.get() to access.

RoleGrantOfferNotification
#

RoleGrantOffersRpc
#

ui/role_grant_offers_state.svelte.ts view source

RoleGrantOffersRpc

Narrow RPC surface consumed by RoleGrantOffersState. Consumers adapt their typed client (e.g. a create_rpc_client Proxy) to this shape — the state class stays decoupled from the client's Result return type so tests can inject plain-function stubs.

list

type () => Promise<{offers: Array<RoleGrantOfferJson>}>

history

type (options?: { limit?: number; offset?: number; }) => Promise<{offers: Array<RoleGrantOfferJson>}>

create

type (params: { to_account_id: string; to_actor_id?: string | null; role: string; scope_id?: string | null; message?: string | null; }) => Promise<{offer: RoleGrantOfferJson}>

accept

type (offer_id: string) => Promise<{ role_grant_id: string; offer: RoleGrantOfferJson; superseded_offer_ids: Array<string>; }>

decline

type (offer_id: string, reason?: string | null) => Promise<{ok: true}>

retract

type (offer_id: string) => Promise<{ok: true}>

RoleGrantOffersState
#

ui/role_grant_offers_state.svelte.ts view source

list

readonly

list_history

readonly

create

readonly

accept

readonly

decline

readonly

retract

readonly

incoming

Pending offers for the current account, soonest-expiring first.

type Array<RoleGrantOfferJson>

readonly

outgoing

Pending offers from the current actor, newest-created first.

type Array<RoleGrantOfferJson>

readonly

history

Every offer known to this state, newest-created first. Feeds the history view.

type Array<RoleGrantOfferJson>

readonly

incoming_count

type number

readonly

constructor

type new (options: RoleGrantOffersStateOptions): RoleGrantOffersState

options

fetch

Seed the cache with the recipient-side pending inbox.

type (): Promise<void>

returns Promise<void>

fetch_history

Seed both-directions history (includes terminal rows).

type (options?: { limit?: number | undefined; offset?: number | undefined; } | undefined): Promise<void>

options?
type { limit?: number | undefined; offset?: number | undefined; } | undefined
optional
returns Promise<void>

submit_create

Issue a new offer; merges the returned offer into the cache on success.

to_actor_id (optional) narrows the offer to a specific actor on to_account_id; omit / null for the account-grain default (any actor on the recipient account may accept).

type (params: { to_account_id: string; to_actor_id?: string | null | undefined; role: string; scope_id?: string | null | undefined; message?: string | null | undefined; }): Promise<{ id: string & $brand<...>; ... 14 more ...; resulting_role_grant_id: (string & $brand<...>) | null; } | undefined>

params
type { to_account_id: string; to_actor_id?: string | null | undefined; role: string; scope_id?: string | null | undefined; message?: string | null | undefined; }
returns Promise<{ id: string & $brand<"Uuid">; from_actor_id: string & $brand<"Uuid">; to_account_id: string & $brand<"Uuid">; to_actor_id: (string & $brand<"Uuid">) | null; ... 11 more ...; resulting_role_grant_id: (string & $brand<...>) | null; } | undefined>

submit_accept

Accept an offer; stamps it terminal in the cache and drops any siblings the server superseded.

type (offer_id: string): Promise<void>

offer_id
type string
returns Promise<void>

submit_decline

type (offer_id: string, reason?: string | null | undefined): Promise<void>

offer_id
type string
reason?
type string | null | undefined
optional
returns Promise<void>

submit_retract

type (offer_id: string): Promise<void>

offer_id
type string
returns Promise<void>

subscribe

Wire a notification subscription. The handler dispatches each matching notification into apply_notification; the returned disposer unwires.

type (subscribe_fn: RoleGrantOfferSubscribe): () => void

subscribe_fn
returns () => void

apply_notification

Reduce a single WS notification into the cache. Exposed so consumers wiring their WS receiver directly (without subscribe) and tests can drive the reducer without allocating a subscription.

type (notification: RoleGrantOfferNotification): void

notification
returns void

reset

Clear the cache and reset every slot.

type (): void

returns void

RoleGrantOffersStateOptions
#

ui/role_grant_offers_state.svelte.ts view source

RoleGrantOffersStateOptions

rpc

account_id

Reactive accessor for the current account id; returns null when logged out.

type () => string | null

actor_id

Reactive accessor for the current actor id — required to classify offers as outgoing. Returns null when unknown.

type () => string | null

RoleGrantOfferSubscribe
#

Depends on
#

Imported by
#