createSession
createSession creates a headless store for one quote journey. Your view subscribes to it and renders; the session handles saving, resume, quoting and handoff.
const session = createSession({ client, vertical })Reference
Section titled “Reference”createSession(options)
Section titled “createSession(options)”import { createSession, sessionStorageAdapter } from '@partner-sdk/core/session';
const session = createSession({ client, vertical: 'cyber', storage: sessionStorageAdapter(),});Options
Section titled “Options”client: aClient.vertical: the product to quote, such as"cyber".storage(optional): where answers persist. DefaultmemoryStorage()(lost on reload). UsesessionStorageAdapter()in browsers. See storage.storageKey(optional): default`sb-quote:${vertical}`.initial(optional): aPromise<Questionnaire>already being created, for prefetching. Adopted bystart()when nothing is resumed.debounceMs(optional): quiet period before edits are sent as one PATCH. Default400.quoteTimeoutMs(optional): default120000.ttlMs(optional): stored sessions older than this are ignored. Default 24 hours.onEvent(optional):(event) => void. Events never carry answers.eventTarget(optional): whereonlineandpagehideare listened for. DefaultglobalThis; passnulloutside browsers.
Returns
Section titled “Returns”A Session.
Caveats
Section titled “Caveats”- Actions never reject. Failures land in state.
- After handoff or
dispose(), every action is a no-op.
Reading state
Section titled “Reading state”session.getSnapshot()
Section titled “session.getSnapshot()”Returns the current SessionState. A new object after every change.
session.subscribe(listener)
Section titled “session.subscribe(listener)”Calls listener after every change. Returns an unsubscribe function.
session.select(selector, listener, equals?)
Section titled “session.select(selector, listener, equals?)”Calls listener only when selector(state) changes, compared by equals (default Object.is). Returns an unsubscribe function.
session.select(toScreen, render, screenEquals);Actions
Section titled “Actions”session.start()
Section titled “session.start()”Resumes the stored questionnaire if it is still valid, else creates one. Idempotent.
- A 401, 403, 404 or 410 on resume clears storage and starts fresh.
- A network error keeps storage and sets
error: { action: "start" }; callstart()again to retry.
session.edit(name, value)
Section titled “session.edit(name, value)”Stores a value by question name, clears that question’s errors and schedules a sync. Synchronous.
If the journey is quoting, quoted or failed, an edit returns it to questioning and stops any poll.
session.flush()
Section titled “session.flush()”Sends pending answers now. Call it when a field commits (field.commit: blur or change).
Only one PATCH is in flight at a time; edits made meanwhile go in the next batch. A failed sync keeps the answers pending and retries on the next edit, flush or online event.
session.searchTrade(name, text)
Section titled “session.searchTrade(name, text)”Searches trades with the named question’s template. The latest call per name wins. Results land in state.search[name]. Debounce typing in your UI.
session.requestQuotes()
Section titled “session.requestQuotes()”Flushes, then polls for quotes if ready. Otherwise sets quotes: { status: "blocked", missing }. A second call joins the running one.
session.retryQuotes()
Section titled “session.retryQuotes()”After failed: follows the server’s retry, or polls again.
session.selectQuote(quoteId)
Section titled “session.selectQuote(quoteId)”After quoted: selects the quote, removes stored answers and moves to handoff with handoffUrl. A failure sets error: { action: "selectQuote" }.
session.handOff()
Section titled “session.handOff()”After quoted with no selectable quote: removes stored answers and moves to handoff with the comparison URL. Otherwise a no-op.
session.dispose()
Section titled “session.dispose()”Persists once, then stops every timer, request and listener.
Resume after a reload
Section titled “Resume after a reload”const session = createSession({ client, vertical: 'cyber', storage: sessionStorageAdapter() });await session.start(); // picks up where the customer left off, answers includedPrefetch the questionnaire
Section titled “Prefetch the questionnaire”Start creating it before your UI mounts:
const initial = client.start('cyber');// ...laterconst session = createSession({ client, vertical: 'cyber', initial });Send events to analytics
Section titled “Send events to analytics”createSession({ client, vertical: 'cyber', onEvent: (event) => analytics.track(`quote_${event.type}`, event),});Events are safe to send: counts, durations and error names only.
Test a view without the API
Section titled “Test a view without the API”import { createFakeSession } from '@partner-sdk/core/session/testing';
const fake = createFakeSession([{ phase: 'starting' }, { phase: 'questioning', questions }]);fake.next(); // move to the next statefake.calls; // actions your view calledTroubleshooting
Section titled “Troubleshooting”My answers aren’t being sent
Section titled “My answers aren’t being sent”Edits are debounced. Call session.flush() on blur or choice change, or wait for debounceMs. Check state.sync.status for "error".
Same value, no request
Section titled “Same value, no request”edit() with the value already stored is a no-op. That’s by design.