kaafil-react-uikit 0.10.2 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/admin/index.cjs +471 -363
  3. package/dist/admin/index.cjs.map +1 -1
  4. package/dist/admin/index.d.cts +4 -4
  5. package/dist/admin/index.d.ts +4 -4
  6. package/dist/admin/index.js +116 -8
  7. package/dist/admin/index.js.map +1 -1
  8. package/dist/{chunk-2OWH2KDY.cjs → chunk-2JNB5A6Z.cjs} +90 -84
  9. package/dist/chunk-2JNB5A6Z.cjs.map +1 -0
  10. package/dist/{chunk-S53XNHRU.cjs → chunk-4TTDAOOG.cjs} +18 -4
  11. package/dist/chunk-4TTDAOOG.cjs.map +1 -0
  12. package/dist/{chunk-AFWZFFEM.js → chunk-4WXIR6FD.js} +5 -5
  13. package/dist/{chunk-AFWZFFEM.js.map → chunk-4WXIR6FD.js.map} +1 -1
  14. package/dist/{chunk-NCHZLGEE.cjs → chunk-6MD4QTZZ.cjs} +9 -9
  15. package/dist/{chunk-NCHZLGEE.cjs.map → chunk-6MD4QTZZ.cjs.map} +1 -1
  16. package/dist/{chunk-7V2XJIXD.js → chunk-7CLYTDSC.js} +18 -4
  17. package/dist/chunk-7CLYTDSC.js.map +1 -0
  18. package/dist/{chunk-AJE2RNOR.cjs → chunk-DRUTYOTN.cjs} +4 -4
  19. package/dist/{chunk-AJE2RNOR.cjs.map → chunk-DRUTYOTN.cjs.map} +1 -1
  20. package/dist/{chunk-K5Z6N2FY.js → chunk-DTVRWYVN.js} +5 -5
  21. package/dist/{chunk-K5Z6N2FY.js.map → chunk-DTVRWYVN.js.map} +1 -1
  22. package/dist/{chunk-VCROLPO3.js → chunk-EGEVXI5K.js} +3 -3
  23. package/dist/{chunk-VCROLPO3.js.map → chunk-EGEVXI5K.js.map} +1 -1
  24. package/dist/{chunk-7752B4NM.js → chunk-F6SN6CEC.js} +3 -3
  25. package/dist/{chunk-7752B4NM.js.map → chunk-F6SN6CEC.js.map} +1 -1
  26. package/dist/{chunk-KV7ODN2X.js → chunk-HC4PLK4E.js} +3 -3
  27. package/dist/{chunk-KV7ODN2X.js.map → chunk-HC4PLK4E.js.map} +1 -1
  28. package/dist/{chunk-F4GGHUMX.cjs → chunk-KY752BBA.cjs} +55 -55
  29. package/dist/{chunk-F4GGHUMX.cjs.map → chunk-KY752BBA.cjs.map} +1 -1
  30. package/dist/chunk-PMXQQFQN.cjs +12 -0
  31. package/dist/{chunk-ZZK7USFC.cjs.map → chunk-PMXQQFQN.cjs.map} +1 -1
  32. package/dist/{chunk-TGP4GTIY.js → chunk-RK3CWJ56.js} +10 -4
  33. package/dist/chunk-RK3CWJ56.js.map +1 -0
  34. package/dist/{chunk-64R4ZJTA.cjs → chunk-UG4Z23IJ.cjs} +12 -12
  35. package/dist/{chunk-64R4ZJTA.cjs.map → chunk-UG4Z23IJ.cjs.map} +1 -1
  36. package/dist/{chunk-UUID3H4R.js → chunk-VWFNUQDH.js} +3 -3
  37. package/dist/{chunk-UUID3H4R.js.map → chunk-VWFNUQDH.js.map} +1 -1
  38. package/dist/{chunk-3AF2M2JD.cjs → chunk-W63ZEIC2.cjs} +17 -17
  39. package/dist/{chunk-3AF2M2JD.cjs.map → chunk-W63ZEIC2.cjs.map} +1 -1
  40. package/dist/core/index.cjs +107 -107
  41. package/dist/core/index.d.cts +5 -5
  42. package/dist/core/index.d.ts +5 -5
  43. package/dist/core/index.js +10 -10
  44. package/dist/index.css +1 -1
  45. package/dist/manager/index.cjs +256 -256
  46. package/dist/manager/index.d.cts +4 -4
  47. package/dist/manager/index.d.ts +4 -4
  48. package/dist/manager/index.js +6 -6
  49. package/dist/tokens.json +4 -1
  50. package/dist/traveller/index.cjs +35 -35
  51. package/dist/traveller/index.js +5 -5
  52. package/dist/{useAgencyTrip-gZB0NILH.d.ts → useAgencyTrip-BgQ4gkyy.d.ts} +1 -1
  53. package/dist/{useAgencyTrip-C1YmfuQq.d.cts → useAgencyTrip-CtUMpC-J.d.cts} +1 -1
  54. package/dist/{useNotifications-D262i5BQ.d.ts → useNotifications-B9t5jUQc.d.ts} +1 -1
  55. package/dist/{useNotifications-BZW1Z_ur.d.cts → useNotifications-xn08Oypa.d.cts} +1 -1
  56. package/dist/{useVendors-DXOuZWhZ.d.cts → useVendors-B827YIDs.d.cts} +20 -0
  57. package/dist/{useVendors-DXOuZWhZ.d.ts → useVendors-B827YIDs.d.ts} +20 -0
  58. package/package.json +2 -2
  59. package/dist/chunk-2OWH2KDY.cjs.map +0 -1
  60. package/dist/chunk-7V2XJIXD.js.map +0 -1
  61. package/dist/chunk-S53XNHRU.cjs.map +0 -1
  62. package/dist/chunk-TGP4GTIY.js.map +0 -1
  63. package/dist/chunk-ZZK7USFC.cjs +0 -12
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/hooks/useConflicts.ts","../src/core/hooks/useManagerMe.ts","../src/core/hooks/useNotifications.ts"],"names":["useContext","useState","useEffect"],"mappings":"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","file":"chunk-7752B4NM.js","sourcesContent":["'use client';\n\n// `08-core-hooks.md §2.7`. Every `409 CONFLICT_VERSION` op currently parked\n// and awaiting a human choice for this trip — entity-agnostic on purpose, so\n// the one shared `ConflictResolver` UI covers rooming/seating/checklist/\n// every versioned entity (`07-offline-and-sync.md §6`).\n//\n// VERIFIED SHAPE (`kaafil-js/src/offline/{outbox,reconcile}.ts`, this\n// session): a \"surface\" conflict reaches `Outbox.park()` with only\n// `{ status, code: 'CONFLICT_VERSION', userMessage }` — no row of either\n// side. The fresh server row, however, was already written into\n// `SnapshotStore` by `reconcileConflict()` before the park (its own \"why the\n// entity is re-pulled first\" header) whenever `op.entity` was set and the\n// re-read succeeded. `currentValue` below is read from there — the snapshot\n// — rather than invented on this hook's own read. `queuedValue` is the\n// parked op's own `body`, the intent that was never applied.\n\nimport type { OutboxOp } from 'kaafil-js/client';\nimport { useContext, useMemo, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport type { ConflictRecord } from '../types/offline.types';\nimport { useOfflineEvent } from './useOfflineEvent';\n\nexport interface ConflictsResult {\n readonly conflicts: readonly ConflictRecord[];\n readonly resolve: (opId: string, choice: 'keep-queued' | 'keep-current') => Promise<void>;\n}\n\nfunction isVersionConflict(op: OutboxOp): boolean {\n return op.status === 'parked' && op.parkReason?.code === 'CONFLICT_VERSION';\n}\n\nexport function useConflicts(tripRef: string): ConflictsResult {\n // NOT `useOfflineEngine()` (its throwing form) — called from inside a\n // domain hook's unconditional `build()` (`createDomainHook.ts`), including\n // the render(s) before `OfflineShell` has opened an engine. No engine yet\n // means no ops to have conflicted yet — `conflicts: []`, never a crash.\n const engine = useContext(OfflineEngineContext);\n // `tick` itself is never read below beyond being a `useMemo` dependency —\n // `engine.outbox.all()` is a plain synchronous read with no reactive\n // identity of its own, so bumping this on every `sync.error`/`sync.drained`\n // is what makes the memo below re-run on the events that can change what\n // it returns.\n const [tick, forceRefresh] = useState(0);\n\n useOfflineEvent('sync.error', () => forceRefresh((current) => current + 1));\n useOfflineEvent('sync.drained', () => forceRefresh((current) => current + 1));\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: tick is a deliberate side-channel dep, forcing a re-run against the outbox's own non-reactive state on every sync event (see its declaration above).\n const conflictOps = useMemo(\n () =>\n engine === null\n ? []\n : engine.outbox.all().filter((op) => op.tripRef === tripRef && isVersionConflict(op)),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- same reasoning, see the biome-ignore comment above.\n [engine, tripRef, tick],\n );\n\n const conflicts: readonly ConflictRecord[] =\n engine === null\n ? []\n : conflictOps.map((op) => {\n const currentValue =\n op.entity !== undefined\n ? engine.snapshot\n .list(op.tripRef, op.entity.listName)\n .find((row) => row.id === op.entity?.id)\n : undefined;\n return {\n opId: op.id,\n entity: op.entity?.listName ?? op.path,\n queuedValue: op.body,\n currentValue,\n };\n });\n\n async function resolve(opId: string, choice: 'keep-queued' | 'keep-current'): Promise<void> {\n if (engine === null) {\n return;\n }\n const op = engine.outbox.get(opId);\n if (op === undefined) {\n return;\n }\n if (choice === 'keep-current') {\n // `engine.discard()`, NOT `outbox.drop()`. The queue knows nothing about\n // the snapshot, so dropping a CREATE through it leaves the row the\n // manager just chose to discard on screen permanently: it is keyed on an\n // id only this device ever knew, so no pull, no delta and no tombstone\n // can ever remove it. `discard()` takes the optimistic row with the op.\n await engine.discard(opId);\n return;\n }\n // `keep-queued`: re-issue with the fresh version. The fresh row's own\n // `version` field is what `07-offline-and-sync.md §6` calls\n // `details.currentVersion`; reading it off the snapshot row this hook\n // already fetched above is the same value, sourced from the same\n // re-read `reconcileConflict()` already performed.\n const freshRow =\n op.entity !== undefined\n ? engine.snapshot\n .list(op.tripRef, op.entity.listName)\n .find((row) => row.id === op.entity?.id)\n : undefined;\n const freshVersion = freshRow?.version;\n await engine.outbox.reissue(opId, freshVersion !== undefined ? { ifMatch: freshVersion } : {});\n engine.drainer.kick();\n }\n\n return { conflicts, resolve };\n}\n","'use client';\n\n// `families/manager/01-surface.md`'s own \"trip-discovery gap\" note is now\n// stale — verified against the real engine: `GET /manager/me/trips`\n// (`client.managerMe.listTrips()`) resolves a manager's own live trip\n// assignments plus a sensible `defaultTripId`, and now also the manager's\n// own `fullName` (this build's own small engine addition —\n// `manager-me.dto.ts`'s `manager` field). This session's own product\n// decision overrides that spec note for `ManagerNowSection` and any future\n// manager composite that needs \"which trip(s) does THIS manager see\" —\n// never a host-supplied `assignedTrips` prop for those composites (that\n// prop still exists for `KaafilManagerApp`/`MyTripsScreen` themselves, per\n// spec, since a Surface's own trip-list PANE is a separate, larger\n// decision this hook does not revisit).\n//\n// Same deliberately minimal shape as `useManagerToday.ts`: a plain\n// `client.managerMe.listTrips()` call behind `useEffect`/`useState`, no\n// offline/outbox machinery (this is a live read with no mutation of its\n// own to queue), no capability gate (which trips a manager is assigned to\n// is an ingest fact, not a capability — `01-surface.md`'s own \"Gating\"\n// field, cited).\n\nimport type {\n KaafilClient,\n ManagerOwnTrip,\n ManagerOwnTripsResponse,\n OfflineEngine,\n} from 'kaafil-js/client';\nimport { useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useKaafilClient } from './useKaafilClient';\n\n// Re-exported so a composite (`ManagerTripSection.types.ts`, `TripHero.tsx`)\n// can name one trip row's shape without importing `kaafil-js/client`\n// directly — hard rule #1.\nexport type { ManagerOwnTrip };\n\nexport interface ManagerMeLoading {\n readonly status: 'loading';\n}\n\nexport interface ManagerMeError {\n readonly status: 'error';\n}\n\nexport interface ManagerMeReady extends ManagerOwnTripsResponse {\n readonly status: 'ready';\n /** The server timestamp this read landed with (`meta.serverTime`) — never\n * a local clock read (hard rule #6). */\n readonly syncedAt: string;\n}\n\nexport type ManagerMeResult = ManagerMeLoading | ManagerMeError | ManagerMeReady;\n\n/**\n * The last answer this read actually got, per open client — the same\n * module-level, instance-keyed `WeakMap` shape `../internal/ensureTripPulled.ts`\n * already uses, and for the same reason: five composites\n * (`KaafilManagerApp`, `ManagerNowSection`, `ManagerTripSection`,\n * `ManagerChecklistSection`, `ManagerMeSection`) call this hook, and the\n * field surface mounts and unmounts them as the manager moves between tabs.\n *\n * Without this, EVERY tab switch was a fresh network read that the field\n * persona is by definition not guaranteed to be able to make. On a manager's\n * phone with no signal the read rejected, the hook reported `'error'`, and\n * every one of those composites renders nothing at all for that status — so\n * losing the network and then touching a tab emptied the trip screen, with\n * no way back short of a page reload (`architecture/06-offline-first.md`:\n * the field half must serve what it last knew rather than blank).\n *\n * It is not a cache in front of `kaafil-js` (hard rule #3): nothing is\n * reconciled, no cursor is kept, no event is subscribed to, and a live read\n * still fires on every mount so \"re-mount to refresh\" keeps working. It only\n * stops a failed read from erasing an answer the session already has.\n *\n * It dies with the tab, which is the whole reason for the durable lane below.\n */\nconst lastKnown = new WeakMap<KaafilClient, ManagerMeReady>();\n\n/**\n * The key this hook's answer is cached under in the engine's durable read\n * cache (`kaafil-js`'s `engine.reads`, credential-scoped by the engine).\n *\n * The `WeakMap` above survives a tab switch; it does not survive a RELOAD, and\n * a reload is the field surface's normal case rather than an edge one — a\n * manager's phone discards a backgrounded tab on its own. So an offline\n * manager who reloaded got `'error'` from the very first read, and every\n * composite that reads this hook renders nothing for that status: a blank\n * trip list, with their queued writes sitting intact in IndexedDB behind a\n * screen with no way into them. Durable writes the manager could not reach\n * are indistinguishable, from where they are standing, from lost ones.\n *\n * This response cannot live in the snapshot store: its rows carry a\n * `tripRef`, a name and a status but no `id` and no `version`, so there is\n * nothing for a version-guarded merge to guard (`kaafil-js/src/offline/\n * reads.ts` explains the split at length). It is a whole answer or nothing,\n * which is exactly the promise `engine.reads` makes.\n */\nconst READ_CACHE_KEY = 'manager.me.trips';\n\n/** What is actually persisted — the response plus the `meta.serverTime` it\n * landed with. The store keeps `syncedAt` itself, so only the body goes in. */\ntype CachedManagerMe = ManagerOwnTripsResponse;\n\n/**\n * `client.managerMe.listTrips()` behind a plain fetch-on-mount effect —\n * this read takes no parameter (it resolves entirely off the authenticated\n * principal, `manager-me.routes.ts`'s own header, cited), so it never\n * re-fetches on a prop change the way `useManagerToday(tripRef)` does.\n * A caller wanting \"refresh now\" re-mounts this hook's owning component.\n */\nexport function useManagerMe(): ManagerMeResult {\n const client = useKaafilClient();\n // The raw context, not `useOfflineEngine()`'s throwing form: this hook is\n // read by desk composites too, and a desk mount has no `OfflineShell` and\n // therefore no engine. With none, everything below degrades to exactly the\n // in-memory behaviour this hook had before — which is right for a surface\n // that is online by definition.\n const engine = useContext(OfflineEngineContext);\n\n // Seeded from what is already known, in order: this session's own answer,\n // then the durable one from a previous session. Both beat a skeleton, and\n // the durable one is the only one that exists after a reload.\n const [result, setResult] = useState<ManagerMeResult>(\n () => lastKnown.get(client) ?? readCached(engine) ?? { status: 'loading' },\n );\n\n useEffect(() => {\n let cancelled = false;\n setResult(lastKnown.get(client) ?? readCached(engine) ?? { status: 'loading' });\n client.managerMe\n .listTrips()\n .then((response) => {\n const { meta, ...data } = response;\n const ready: ManagerMeReady = { status: 'ready', ...data, syncedAt: meta.serverTime };\n // Recorded before the cancellation check: a response that landed is\n // true regardless of whether THIS component is still mounted to\n // render it, and the next mount should not have to re-ask.\n lastKnown.set(client, ready);\n // Fire-and-forget, and deliberately not awaited before the state is\n // set: painting the fresh answer must not wait on a disk write, and a\n // failed write costs the NEXT reload's first paint rather than this\n // one's correctness. `meta.serverTime`, never a device clock — the\n // store has no setter that would accept one (hard rule #6).\n void engine?.reads?.set(READ_CACHE_KEY, data, meta.serverTime).catch(() => {\n // A full or unavailable store is not this read's problem to report.\n // The live answer above is already rendered and already correct.\n });\n if (!cancelled) {\n setResult(ready);\n }\n })\n .catch(() => {\n if (cancelled) {\n return;\n }\n // `'error'` ONLY when NOTHING is known — not this session, not the\n // last one. A read that failed after one succeeded means the device\n // is offline or the engine is unreachable, not that the manager\n // stopped being assigned to their trips; reporting `'error'` there is\n // what blanked the field surface, and after a reload it blanked it\n // from the very first read. `syncedAt` on the held value already\n // tells a caller how old the reading is.\n setResult(lastKnown.get(client) ?? readCached(engine) ?? { status: 'error' });\n });\n return () => {\n cancelled = true;\n };\n }, [client, engine]);\n\n return result;\n}\n\n/**\n * The last answer a PREVIOUS session got, if this surface has a durable store\n * at all. Returns `undefined` rather than an `'error'` so every call site can\n * fall through to the next-best source in one expression.\n */\nfunction readCached(engine: OfflineEngine | null): ManagerMeReady | undefined {\n const cached = engine?.reads?.get<CachedManagerMe>(READ_CACHE_KEY);\n if (cached === undefined) {\n return undefined;\n }\n return { status: 'ready', ...cached.value, syncedAt: cached.syncedAt };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useNotifications()`. Primary SDK surface\n// (verified, `kaafil-js/src/resources/notifications.ts`):\n// `notifications.list` (`managerAuth`-only), `notifications.markRead`\n// (likewise `managerAuth`-only). NOT trip-scoped — the only hook in this\n// table taking no `tripRef`. `managerAuth` is the ONLY scheme either\n// operation accepts, so this hook is structurally unreachable from the\n// `admin`/`traveller` families. `list` takes an optional `?since=` delta\n// cursor passed straight through, never a UIKit-invented filter language.\n//\n// Deliberately the same minimal shape as `useManagerToday.ts`/\n// `useManagerMe.ts`: a plain fetch-on-mount effect, no offline/outbox\n// machinery. `families/manager/11-offline-sync-and-notifications.md\n// §NotificationsFeed`'s own \"write: markRead enqueues through the outbox\n// with a fixed idempotency key\" contract is that COMPOSITE's job once it\n// is built — this hook exists now only so `ManagerNowSection`'s header\n// bell can show a real (honestly zero, until something writes a\n// notification) unread count, which needs `list()` alone. `markRead` is\n// still exposed as a direct SDK call (never mints its own idempotency key,\n// hard rule #4 — mark-read is naturally idempotent server-side per the\n// SDK's own doc comment, so no key is needed here at all) so an early\n// caller isn't blocked, but a future `NotificationsFeed` composite should\n// route its OWN write through the outbox instead of reusing this hook's\n// `markRead` as-is.\n//\n// The wire's `items` array is a discriminated union (a live row, or a\n// `{ _tombstone: true; id; version; deletedAt }` delete marker) — this hook\n// filters tombstones out of `notifications` (a plain unread-count/list\n// consumer has no use for a deleted row) rather than exposing the union to\n// every caller.\n\nimport type { NotificationsResource } from 'kaafil-js/client';\nimport { useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\n// `notifications.ts`'s resource module exports no named response type of its\n// own (unlike `manager-me.ts`'s `ManagerOwnTripsResponse`) — derived off the\n// resource's own method signature instead, `useFiles.ts`/`useExpenses.ts`'s\n// established precedent for this exact situation.\ntype NotificationListResponse = Awaited<ReturnType<NotificationsResource['list']>>;\ntype NotificationListItem = NotificationListResponse['items'][number];\n\n/** The live-row half of `NotificationListItem`'s union — a tombstone never\n * reaches a caller of this hook (see this file's own header). */\nexport type ManagerNotification = Exclude<NotificationListItem, { _tombstone: true }>;\n\nexport interface NotificationsLoading {\n readonly status: 'loading';\n}\n\nexport interface NotificationsError {\n readonly status: 'error';\n}\n\nexport interface NotificationsReady {\n readonly status: 'ready';\n readonly notifications: readonly ManagerNotification[];\n /** `notifications.filter((n) => n.readAt === null).length` — the wire\n * carries no numeric unread field of its own (verified against\n * `NotificationListResponse`), so this is a real derivation off real\n * rows, never a fabricated count. */\n readonly unreadCount: number;\n readonly markRead: (id: string) => Promise<void>;\n /** The server timestamp this read landed with (`meta.serverTime`) —\n * never a local clock read (hard rule #6). */\n readonly syncedAt: string;\n}\n\nexport type NotificationsResult = NotificationsLoading | NotificationsError | NotificationsReady;\n\nfunction isTombstone(\n item: NotificationListItem,\n): item is Extract<NotificationListItem, { _tombstone: true }> {\n return '_tombstone' in item && item._tombstone === true;\n}\n\nexport function useNotifications(): NotificationsResult {\n const client = useKaafilClient();\n const [result, setResult] = useState<NotificationsResult>({ status: 'loading' });\n\n useEffect(() => {\n let cancelled = false;\n setResult({ status: 'loading' });\n client.notifications\n .list()\n .then((response) => {\n if (cancelled) {\n return;\n }\n const notifications = response.items.filter(\n (item): item is ManagerNotification => !isTombstone(item),\n );\n setResult({\n status: 'ready',\n notifications,\n unreadCount: notifications.filter((n) => n.readAt === null).length,\n markRead: async (id: string) => {\n await client.notifications.markRead({ id });\n },\n syncedAt: response.meta.serverTime,\n });\n })\n .catch(() => {\n if (!cancelled) {\n setResult({ status: 'error' });\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n return result;\n}\n"]}
1
+ {"version":3,"sources":["../src/core/hooks/useConflicts.ts","../src/core/hooks/useManagerMe.ts","../src/core/hooks/useNotifications.ts"],"names":["useContext","useState","useEffect"],"mappings":"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","file":"chunk-F6SN6CEC.js","sourcesContent":["'use client';\n\n// `08-core-hooks.md §2.7`. Every `409 CONFLICT_VERSION` op currently parked\n// and awaiting a human choice for this trip — entity-agnostic on purpose, so\n// the one shared `ConflictResolver` UI covers rooming/seating/checklist/\n// every versioned entity (`07-offline-and-sync.md §6`).\n//\n// VERIFIED SHAPE (`kaafil-js/src/offline/{outbox,reconcile}.ts`, this\n// session): a \"surface\" conflict reaches `Outbox.park()` with only\n// `{ status, code: 'CONFLICT_VERSION', userMessage }` — no row of either\n// side. The fresh server row, however, was already written into\n// `SnapshotStore` by `reconcileConflict()` before the park (its own \"why the\n// entity is re-pulled first\" header) whenever `op.entity` was set and the\n// re-read succeeded. `currentValue` below is read from there — the snapshot\n// — rather than invented on this hook's own read. `queuedValue` is the\n// parked op's own `body`, the intent that was never applied.\n\nimport type { OutboxOp } from 'kaafil-js/client';\nimport { useContext, useMemo, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport type { ConflictRecord } from '../types/offline.types';\nimport { useOfflineEvent } from './useOfflineEvent';\n\nexport interface ConflictsResult {\n readonly conflicts: readonly ConflictRecord[];\n readonly resolve: (opId: string, choice: 'keep-queued' | 'keep-current') => Promise<void>;\n}\n\nfunction isVersionConflict(op: OutboxOp): boolean {\n return op.status === 'parked' && op.parkReason?.code === 'CONFLICT_VERSION';\n}\n\nexport function useConflicts(tripRef: string): ConflictsResult {\n // NOT `useOfflineEngine()` (its throwing form) — called from inside a\n // domain hook's unconditional `build()` (`createDomainHook.ts`), including\n // the render(s) before `OfflineShell` has opened an engine. No engine yet\n // means no ops to have conflicted yet — `conflicts: []`, never a crash.\n const engine = useContext(OfflineEngineContext);\n // `tick` itself is never read below beyond being a `useMemo` dependency —\n // `engine.outbox.all()` is a plain synchronous read with no reactive\n // identity of its own, so bumping this on every `sync.error`/`sync.drained`\n // is what makes the memo below re-run on the events that can change what\n // it returns.\n const [tick, forceRefresh] = useState(0);\n\n useOfflineEvent('sync.error', () => forceRefresh((current) => current + 1));\n useOfflineEvent('sync.drained', () => forceRefresh((current) => current + 1));\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: tick is a deliberate side-channel dep, forcing a re-run against the outbox's own non-reactive state on every sync event (see its declaration above).\n const conflictOps = useMemo(\n () =>\n engine === null\n ? []\n : engine.outbox.all().filter((op) => op.tripRef === tripRef && isVersionConflict(op)),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- same reasoning, see the biome-ignore comment above.\n [engine, tripRef, tick],\n );\n\n const conflicts: readonly ConflictRecord[] =\n engine === null\n ? []\n : conflictOps.map((op) => {\n const currentValue =\n op.entity !== undefined\n ? engine.snapshot\n .list(op.tripRef, op.entity.listName)\n .find((row) => row.id === op.entity?.id)\n : undefined;\n return {\n opId: op.id,\n entity: op.entity?.listName ?? op.path,\n queuedValue: op.body,\n currentValue,\n };\n });\n\n async function resolve(opId: string, choice: 'keep-queued' | 'keep-current'): Promise<void> {\n if (engine === null) {\n return;\n }\n const op = engine.outbox.get(opId);\n if (op === undefined) {\n return;\n }\n if (choice === 'keep-current') {\n // `engine.discard()`, NOT `outbox.drop()`. The queue knows nothing about\n // the snapshot, so dropping a CREATE through it leaves the row the\n // manager just chose to discard on screen permanently: it is keyed on an\n // id only this device ever knew, so no pull, no delta and no tombstone\n // can ever remove it. `discard()` takes the optimistic row with the op.\n await engine.discard(opId);\n return;\n }\n // `keep-queued`: re-issue with the fresh version. The fresh row's own\n // `version` field is what `07-offline-and-sync.md §6` calls\n // `details.currentVersion`; reading it off the snapshot row this hook\n // already fetched above is the same value, sourced from the same\n // re-read `reconcileConflict()` already performed.\n const freshRow =\n op.entity !== undefined\n ? engine.snapshot\n .list(op.tripRef, op.entity.listName)\n .find((row) => row.id === op.entity?.id)\n : undefined;\n const freshVersion = freshRow?.version;\n await engine.outbox.reissue(opId, freshVersion !== undefined ? { ifMatch: freshVersion } : {});\n engine.drainer.kick();\n }\n\n return { conflicts, resolve };\n}\n","'use client';\n\n// `families/manager/01-surface.md`'s own \"trip-discovery gap\" note is now\n// stale — verified against the real engine: `GET /manager/me/trips`\n// (`client.managerMe.listTrips()`) resolves a manager's own live trip\n// assignments plus a sensible `defaultTripId`, and now also the manager's\n// own `fullName` (this build's own small engine addition —\n// `manager-me.dto.ts`'s `manager` field). This session's own product\n// decision overrides that spec note for `ManagerNowSection` and any future\n// manager composite that needs \"which trip(s) does THIS manager see\" —\n// never a host-supplied `assignedTrips` prop for those composites (that\n// prop still exists for `KaafilManagerApp`/`MyTripsScreen` themselves, per\n// spec, since a Surface's own trip-list PANE is a separate, larger\n// decision this hook does not revisit).\n//\n// Same deliberately minimal shape as `useManagerToday.ts`: a plain\n// `client.managerMe.listTrips()` call behind `useEffect`/`useState`, no\n// offline/outbox machinery (this is a live read with no mutation of its\n// own to queue), no capability gate (which trips a manager is assigned to\n// is an ingest fact, not a capability — `01-surface.md`'s own \"Gating\"\n// field, cited).\n\nimport type {\n KaafilClient,\n ManagerOwnTrip,\n ManagerOwnTripsResponse,\n OfflineEngine,\n} from 'kaafil-js/client';\nimport { useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { useKaafilClient } from './useKaafilClient';\n\n// Re-exported so a composite (`ManagerTripSection.types.ts`, `TripHero.tsx`)\n// can name one trip row's shape without importing `kaafil-js/client`\n// directly — hard rule #1.\nexport type { ManagerOwnTrip };\n\nexport interface ManagerMeLoading {\n readonly status: 'loading';\n}\n\nexport interface ManagerMeError {\n readonly status: 'error';\n}\n\nexport interface ManagerMeReady extends ManagerOwnTripsResponse {\n readonly status: 'ready';\n /** The server timestamp this read landed with (`meta.serverTime`) — never\n * a local clock read (hard rule #6). */\n readonly syncedAt: string;\n}\n\nexport type ManagerMeResult = ManagerMeLoading | ManagerMeError | ManagerMeReady;\n\n/**\n * The last answer this read actually got, per open client — the same\n * module-level, instance-keyed `WeakMap` shape `../internal/ensureTripPulled.ts`\n * already uses, and for the same reason: five composites\n * (`KaafilManagerApp`, `ManagerNowSection`, `ManagerTripSection`,\n * `ManagerChecklistSection`, `ManagerMeSection`) call this hook, and the\n * field surface mounts and unmounts them as the manager moves between tabs.\n *\n * Without this, EVERY tab switch was a fresh network read that the field\n * persona is by definition not guaranteed to be able to make. On a manager's\n * phone with no signal the read rejected, the hook reported `'error'`, and\n * every one of those composites renders nothing at all for that status — so\n * losing the network and then touching a tab emptied the trip screen, with\n * no way back short of a page reload (`architecture/06-offline-first.md`:\n * the field half must serve what it last knew rather than blank).\n *\n * It is not a cache in front of `kaafil-js` (hard rule #3): nothing is\n * reconciled, no cursor is kept, no event is subscribed to, and a live read\n * still fires on every mount so \"re-mount to refresh\" keeps working. It only\n * stops a failed read from erasing an answer the session already has.\n *\n * It dies with the tab, which is the whole reason for the durable lane below.\n */\nconst lastKnown = new WeakMap<KaafilClient, ManagerMeReady>();\n\n/**\n * The key this hook's answer is cached under in the engine's durable read\n * cache (`kaafil-js`'s `engine.reads`, credential-scoped by the engine).\n *\n * The `WeakMap` above survives a tab switch; it does not survive a RELOAD, and\n * a reload is the field surface's normal case rather than an edge one — a\n * manager's phone discards a backgrounded tab on its own. So an offline\n * manager who reloaded got `'error'` from the very first read, and every\n * composite that reads this hook renders nothing for that status: a blank\n * trip list, with their queued writes sitting intact in IndexedDB behind a\n * screen with no way into them. Durable writes the manager could not reach\n * are indistinguishable, from where they are standing, from lost ones.\n *\n * This response cannot live in the snapshot store: its rows carry a\n * `tripRef`, a name and a status but no `id` and no `version`, so there is\n * nothing for a version-guarded merge to guard (`kaafil-js/src/offline/\n * reads.ts` explains the split at length). It is a whole answer or nothing,\n * which is exactly the promise `engine.reads` makes.\n */\nconst READ_CACHE_KEY = 'manager.me.trips';\n\n/** What is actually persisted — the response plus the `meta.serverTime` it\n * landed with. The store keeps `syncedAt` itself, so only the body goes in. */\ntype CachedManagerMe = ManagerOwnTripsResponse;\n\n/**\n * `client.managerMe.listTrips()` behind a plain fetch-on-mount effect —\n * this read takes no parameter (it resolves entirely off the authenticated\n * principal, `manager-me.routes.ts`'s own header, cited), so it never\n * re-fetches on a prop change the way `useManagerToday(tripRef)` does.\n * A caller wanting \"refresh now\" re-mounts this hook's owning component.\n */\nexport function useManagerMe(): ManagerMeResult {\n const client = useKaafilClient();\n // The raw context, not `useOfflineEngine()`'s throwing form: this hook is\n // read by desk composites too, and a desk mount has no `OfflineShell` and\n // therefore no engine. With none, everything below degrades to exactly the\n // in-memory behaviour this hook had before — which is right for a surface\n // that is online by definition.\n const engine = useContext(OfflineEngineContext);\n\n // Seeded from what is already known, in order: this session's own answer,\n // then the durable one from a previous session. Both beat a skeleton, and\n // the durable one is the only one that exists after a reload.\n const [result, setResult] = useState<ManagerMeResult>(\n () => lastKnown.get(client) ?? readCached(engine) ?? { status: 'loading' },\n );\n\n useEffect(() => {\n let cancelled = false;\n setResult(lastKnown.get(client) ?? readCached(engine) ?? { status: 'loading' });\n client.managerMe\n .listTrips()\n .then((response) => {\n const { meta, ...data } = response;\n const ready: ManagerMeReady = { status: 'ready', ...data, syncedAt: meta.serverTime };\n // Recorded before the cancellation check: a response that landed is\n // true regardless of whether THIS component is still mounted to\n // render it, and the next mount should not have to re-ask.\n lastKnown.set(client, ready);\n // Fire-and-forget, and deliberately not awaited before the state is\n // set: painting the fresh answer must not wait on a disk write, and a\n // failed write costs the NEXT reload's first paint rather than this\n // one's correctness. `meta.serverTime`, never a device clock — the\n // store has no setter that would accept one (hard rule #6).\n void engine?.reads?.set(READ_CACHE_KEY, data, meta.serverTime).catch(() => {\n // A full or unavailable store is not this read's problem to report.\n // The live answer above is already rendered and already correct.\n });\n if (!cancelled) {\n setResult(ready);\n }\n })\n .catch(() => {\n if (cancelled) {\n return;\n }\n // `'error'` ONLY when NOTHING is known — not this session, not the\n // last one. A read that failed after one succeeded means the device\n // is offline or the engine is unreachable, not that the manager\n // stopped being assigned to their trips; reporting `'error'` there is\n // what blanked the field surface, and after a reload it blanked it\n // from the very first read. `syncedAt` on the held value already\n // tells a caller how old the reading is.\n setResult(lastKnown.get(client) ?? readCached(engine) ?? { status: 'error' });\n });\n return () => {\n cancelled = true;\n };\n }, [client, engine]);\n\n return result;\n}\n\n/**\n * The last answer a PREVIOUS session got, if this surface has a durable store\n * at all. Returns `undefined` rather than an `'error'` so every call site can\n * fall through to the next-best source in one expression.\n */\nfunction readCached(engine: OfflineEngine | null): ManagerMeReady | undefined {\n const cached = engine?.reads?.get<CachedManagerMe>(READ_CACHE_KEY);\n if (cached === undefined) {\n return undefined;\n }\n return { status: 'ready', ...cached.value, syncedAt: cached.syncedAt };\n}\n","'use client';\n\n// `08-core-hooks.md §3` table, row `useNotifications()`. Primary SDK surface\n// (verified, `kaafil-js/src/resources/notifications.ts`):\n// `notifications.list` (`managerAuth`-only), `notifications.markRead`\n// (likewise `managerAuth`-only). NOT trip-scoped — the only hook in this\n// table taking no `tripRef`. `managerAuth` is the ONLY scheme either\n// operation accepts, so this hook is structurally unreachable from the\n// `admin`/`traveller` families. `list` takes an optional `?since=` delta\n// cursor passed straight through, never a UIKit-invented filter language.\n//\n// Deliberately the same minimal shape as `useManagerToday.ts`/\n// `useManagerMe.ts`: a plain fetch-on-mount effect, no offline/outbox\n// machinery. `families/manager/11-offline-sync-and-notifications.md\n// §NotificationsFeed`'s own \"write: markRead enqueues through the outbox\n// with a fixed idempotency key\" contract is that COMPOSITE's job once it\n// is built — this hook exists now only so `ManagerNowSection`'s header\n// bell can show a real (honestly zero, until something writes a\n// notification) unread count, which needs `list()` alone. `markRead` is\n// still exposed as a direct SDK call (never mints its own idempotency key,\n// hard rule #4 — mark-read is naturally idempotent server-side per the\n// SDK's own doc comment, so no key is needed here at all) so an early\n// caller isn't blocked, but a future `NotificationsFeed` composite should\n// route its OWN write through the outbox instead of reusing this hook's\n// `markRead` as-is.\n//\n// The wire's `items` array is a discriminated union (a live row, or a\n// `{ _tombstone: true; id; version; deletedAt }` delete marker) — this hook\n// filters tombstones out of `notifications` (a plain unread-count/list\n// consumer has no use for a deleted row) rather than exposing the union to\n// every caller.\n\nimport type { NotificationsResource } from 'kaafil-js/client';\nimport { useEffect, useState } from 'react';\nimport { useKaafilClient } from './useKaafilClient';\n\n// `notifications.ts`'s resource module exports no named response type of its\n// own (unlike `manager-me.ts`'s `ManagerOwnTripsResponse`) — derived off the\n// resource's own method signature instead, `useFiles.ts`/`useExpenses.ts`'s\n// established precedent for this exact situation.\ntype NotificationListResponse = Awaited<ReturnType<NotificationsResource['list']>>;\ntype NotificationListItem = NotificationListResponse['items'][number];\n\n/** The live-row half of `NotificationListItem`'s union — a tombstone never\n * reaches a caller of this hook (see this file's own header). */\nexport type ManagerNotification = Exclude<NotificationListItem, { _tombstone: true }>;\n\nexport interface NotificationsLoading {\n readonly status: 'loading';\n}\n\nexport interface NotificationsError {\n readonly status: 'error';\n}\n\nexport interface NotificationsReady {\n readonly status: 'ready';\n readonly notifications: readonly ManagerNotification[];\n /** `notifications.filter((n) => n.readAt === null).length` — the wire\n * carries no numeric unread field of its own (verified against\n * `NotificationListResponse`), so this is a real derivation off real\n * rows, never a fabricated count. */\n readonly unreadCount: number;\n readonly markRead: (id: string) => Promise<void>;\n /** The server timestamp this read landed with (`meta.serverTime`) —\n * never a local clock read (hard rule #6). */\n readonly syncedAt: string;\n}\n\nexport type NotificationsResult = NotificationsLoading | NotificationsError | NotificationsReady;\n\nfunction isTombstone(\n item: NotificationListItem,\n): item is Extract<NotificationListItem, { _tombstone: true }> {\n return '_tombstone' in item && item._tombstone === true;\n}\n\nexport function useNotifications(): NotificationsResult {\n const client = useKaafilClient();\n const [result, setResult] = useState<NotificationsResult>({ status: 'loading' });\n\n useEffect(() => {\n let cancelled = false;\n setResult({ status: 'loading' });\n client.notifications\n .list()\n .then((response) => {\n if (cancelled) {\n return;\n }\n const notifications = response.items.filter(\n (item): item is ManagerNotification => !isTombstone(item),\n );\n setResult({\n status: 'ready',\n notifications,\n unreadCount: notifications.filter((n) => n.readAt === null).length,\n markRead: async (id: string) => {\n await client.notifications.markRead({ id });\n },\n syncedAt: response.meta.serverTime,\n });\n })\n .catch(() => {\n if (!cancelled) {\n setResult({ status: 'error' });\n }\n });\n return () => {\n cancelled = true;\n };\n }, [client]);\n\n return result;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { OfflineEngineContext } from './chunk-7V2XJIXD.js';
1
+ import { OfflineEngineContext } from './chunk-7CLYTDSC.js';
2
2
  import { useContext, useState, useRef, useEffect } from 'react';
3
3
 
4
4
  var TICK_INTERVAL_MS = 1e3;
@@ -37,5 +37,5 @@ function useServerTime() {
37
37
  }
38
38
 
39
39
  export { useServerTime };
40
- //# sourceMappingURL=chunk-KV7ODN2X.js.map
41
- //# sourceMappingURL=chunk-KV7ODN2X.js.map
40
+ //# sourceMappingURL=chunk-HC4PLK4E.js.map
41
+ //# sourceMappingURL=chunk-HC4PLK4E.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/hooks/useServerTime.ts"],"names":[],"mappings":";;;AA8BA,IAAM,gBAAA,GAAmB,GAAA;AAElB,SAAS,aAAA,GAA+B;AAC7C,EAAA,MAAM,MAAA,GAAS,WAAW,oBAAoB,CAAA;AAC9C,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAA6B,MAAS,CAAA;AAClF,EAAA,MAAM,iBAAA,GAAoB,OAA2B,MAAS,CAAA;AAC9D,EAAA,MAAM,GAAG,SAAS,CAAA,GAAI,SAAS,CAAC,CAAA;AAEhC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,IAAA,EAAM;AACnB,MAAA;AAAA,IACF;AAKA,IAAA,MAAM,cAAc,MAAA,CAAO,MAAA,CAAO,EAAA,CAAG,kBAAA,EAAoB,CAAC,KAAA,KAAU;AASlE,MAAA,IAAI,KAAA,CAAM,eAAe,MAAA,EAAW;AAClC,QAAA;AAAA,MACF;AACA,MAAA,iBAAA,CAAkB,OAAA,GAAU,YAAY,GAAA,EAAI;AAC5C,MAAA,iBAAA,CAAkB,MAAM,UAAU,CAAA;AAAA,IACpC,CAAC,CAAA;AACD,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,YAAY,MAAM,SAAA,CAAU,CAAC,IAAA,KAAS,IAAA,GAAO,CAAC,CAAA,EAAG,gBAAgB,CAAA;AAC5E,IAAA,OAAO,MAAM,cAAc,EAAE,CAAA;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAS,GAAA,GAAc;AACrB,IAAA,IAAI,cAAA,KAAmB,MAAA,IAAa,iBAAA,CAAkB,OAAA,KAAY,MAAA,EAAW;AAY3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OAEF;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,EAAI,GAAI,iBAAA,CAAkB,OAAA;AACxD,IAAA,OAAO,IAAI,KAAK,IAAA,CAAK,KAAA,CAAM,cAAc,CAAA,GAAI,SAAS,EAAE,WAAA,EAAY;AAAA,EACtE;AAEA,EAAA,OAAO,EAAE,GAAA,EAAK,aAAA,EAAe,cAAA,EAAe;AAC9C","file":"chunk-KV7ODN2X.js","sourcesContent":["'use client';\n\n// `08-core-hooks.md §1.6`. The single place that turns the stream of\n// `meta.serverTime` stamps into a usable clock, so no composite reads\n// `meta.serverTime` off an individual response by hand.\n//\n// Hard rule #6 (\"Zero `Date.now()`/`new Date()` local getters in\n// `src/core`\") bans exactly the two calls that fabricate \"now\" from the\n// local wall clock: `Date.now()` and no-argument `new Date()`. This file\n// never calls either. Advancing a SERVER-supplied timestamp by an elapsed\n// delta necessarily needs SOME measure of \"how much local time passed\" —\n// this file measures that with `performance.now()`, a monotonic clock with\n// no relationship to wall-clock \"now\" (it cannot be read as a date, only as\n// a duration), and applies the delta with `new Date(<epoch-ms>)` /\n// `Date.parse(<iso-string>)` — both single-argument forms that operate on a\n// value already anchored to `meta.serverTime`, never on the local clock.\n\nimport { useContext, useEffect, useRef, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\n\nexport interface ServerTimeApi {\n now: () => string;\n sinceLastSync: string | undefined;\n}\n\n/** Re-renders any hook consumer often enough for a mounted countdown to look\n * live, without pretending the underlying value moved forward on its own\n * merits (`08-core-hooks.md §1.6`'s sandbox time-travel caveat: this timer\n * forces a re-render, it never advances the stamp past what the last real\n * response justified). */\nconst TICK_INTERVAL_MS = 1000;\n\nexport function useServerTime(): ServerTimeApi {\n const engine = useContext(OfflineEngineContext);\n const [lastServerTime, setLastServerTime] = useState<string | undefined>(undefined);\n const observedAtPerfRef = useRef<number | undefined>(undefined);\n const [, forceTick] = useState(0);\n\n useEffect(() => {\n if (engine === null) {\n return;\n }\n // `snapshot.updated` is the one event in `OfflineEventMap` that carries\n // `serverTime` (`kaafil-js/src/offline/events.ts`, verified this\n // session) — the engine's other five events do not, so this is the only\n // subscription this hook can build without inventing a stamp.\n const unsubscribe = engine.events.on('snapshot.updated', (event) => {\n // `serverTime` is ABSENT on a change that never involved the server —\n // an optimistic create painted while offline, or an op the host\n // discarded (`kaafil-js/src/offline/events.ts`). Those are real snapshot\n // changes and a list must repaint for them, but they carry no reading,\n // and taking `undefined` here would erase the last real one this\n // session had: `now()` would start throwing again mid-session, on a\n // device that HAS heard from the server, because the manager ticked\n // something off out of signal.\n if (event.serverTime === undefined) {\n return;\n }\n observedAtPerfRef.current = performance.now();\n setLastServerTime(event.serverTime);\n });\n return unsubscribe;\n }, [engine]);\n\n useEffect(() => {\n const id = setInterval(() => forceTick((tick) => tick + 1), TICK_INTERVAL_MS);\n return () => clearInterval(id);\n }, []);\n\n function now(): string {\n if (lastServerTime === undefined || observedAtPerfRef.current === undefined) {\n // No response has ever landed in this session yet. Fabricating a\n // value from the local wall clock is exactly what hard rule #6\n // forbids — this is the one case this hook cannot silently satisfy\n // its own non-optional return type, so it says so loudly instead.\n // CALLERS: this is a real, expected window — React runs an effect\n // (which is how this hook's own subscription above starts) strictly\n // AFTER the render that needs `now()`'s result has already committed,\n // so a component's very FIRST render can hit this throw even when\n // wired up correctly. Guard the call site, matching\n // `useStaleness.ts`'s own precedent, rather than reaching for a\n // device-clock fallback here (hard rule #6 forbids exactly that).\n throw new Error(\n 'useServerTime().now() was called before any response carrying meta.serverTime ' +\n 'had been observed — there is no server timestamp yet to advance from.',\n );\n }\n const elapsedMs = performance.now() - observedAtPerfRef.current;\n return new Date(Date.parse(lastServerTime) + elapsedMs).toISOString();\n }\n\n return { now, sinceLastSync: lastServerTime };\n}\n"]}
1
+ {"version":3,"sources":["../src/core/hooks/useServerTime.ts"],"names":[],"mappings":";;;AA8BA,IAAM,gBAAA,GAAmB,GAAA;AAElB,SAAS,aAAA,GAA+B;AAC7C,EAAA,MAAM,MAAA,GAAS,WAAW,oBAAoB,CAAA;AAC9C,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAI,SAA6B,MAAS,CAAA;AAClF,EAAA,MAAM,iBAAA,GAAoB,OAA2B,MAAS,CAAA;AAC9D,EAAA,MAAM,GAAG,SAAS,CAAA,GAAI,SAAS,CAAC,CAAA;AAEhC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,IAAA,EAAM;AACnB,MAAA;AAAA,IACF;AAKA,IAAA,MAAM,cAAc,MAAA,CAAO,MAAA,CAAO,EAAA,CAAG,kBAAA,EAAoB,CAAC,KAAA,KAAU;AASlE,MAAA,IAAI,KAAA,CAAM,eAAe,MAAA,EAAW;AAClC,QAAA;AAAA,MACF;AACA,MAAA,iBAAA,CAAkB,OAAA,GAAU,YAAY,GAAA,EAAI;AAC5C,MAAA,iBAAA,CAAkB,MAAM,UAAU,CAAA;AAAA,IACpC,CAAC,CAAA;AACD,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,YAAY,MAAM,SAAA,CAAU,CAAC,IAAA,KAAS,IAAA,GAAO,CAAC,CAAA,EAAG,gBAAgB,CAAA;AAC5E,IAAA,OAAO,MAAM,cAAc,EAAE,CAAA;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAS,GAAA,GAAc;AACrB,IAAA,IAAI,cAAA,KAAmB,MAAA,IAAa,iBAAA,CAAkB,OAAA,KAAY,MAAA,EAAW;AAY3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OAEF;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,EAAI,GAAI,iBAAA,CAAkB,OAAA;AACxD,IAAA,OAAO,IAAI,KAAK,IAAA,CAAK,KAAA,CAAM,cAAc,CAAA,GAAI,SAAS,EAAE,WAAA,EAAY;AAAA,EACtE;AAEA,EAAA,OAAO,EAAE,GAAA,EAAK,aAAA,EAAe,cAAA,EAAe;AAC9C","file":"chunk-HC4PLK4E.js","sourcesContent":["'use client';\n\n// `08-core-hooks.md §1.6`. The single place that turns the stream of\n// `meta.serverTime` stamps into a usable clock, so no composite reads\n// `meta.serverTime` off an individual response by hand.\n//\n// Hard rule #6 (\"Zero `Date.now()`/`new Date()` local getters in\n// `src/core`\") bans exactly the two calls that fabricate \"now\" from the\n// local wall clock: `Date.now()` and no-argument `new Date()`. This file\n// never calls either. Advancing a SERVER-supplied timestamp by an elapsed\n// delta necessarily needs SOME measure of \"how much local time passed\" —\n// this file measures that with `performance.now()`, a monotonic clock with\n// no relationship to wall-clock \"now\" (it cannot be read as a date, only as\n// a duration), and applies the delta with `new Date(<epoch-ms>)` /\n// `Date.parse(<iso-string>)` — both single-argument forms that operate on a\n// value already anchored to `meta.serverTime`, never on the local clock.\n\nimport { useContext, useEffect, useRef, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\n\nexport interface ServerTimeApi {\n now: () => string;\n sinceLastSync: string | undefined;\n}\n\n/** Re-renders any hook consumer often enough for a mounted countdown to look\n * live, without pretending the underlying value moved forward on its own\n * merits (`08-core-hooks.md §1.6`'s sandbox time-travel caveat: this timer\n * forces a re-render, it never advances the stamp past what the last real\n * response justified). */\nconst TICK_INTERVAL_MS = 1000;\n\nexport function useServerTime(): ServerTimeApi {\n const engine = useContext(OfflineEngineContext);\n const [lastServerTime, setLastServerTime] = useState<string | undefined>(undefined);\n const observedAtPerfRef = useRef<number | undefined>(undefined);\n const [, forceTick] = useState(0);\n\n useEffect(() => {\n if (engine === null) {\n return;\n }\n // `snapshot.updated` is the one event in `OfflineEventMap` that carries\n // `serverTime` (`kaafil-js/src/offline/events.ts`, verified this\n // session) — the engine's other five events do not, so this is the only\n // subscription this hook can build without inventing a stamp.\n const unsubscribe = engine.events.on('snapshot.updated', (event) => {\n // `serverTime` is ABSENT on a change that never involved the server —\n // an optimistic create painted while offline, or an op the host\n // discarded (`kaafil-js/src/offline/events.ts`). Those are real snapshot\n // changes and a list must repaint for them, but they carry no reading,\n // and taking `undefined` here would erase the last real one this\n // session had: `now()` would start throwing again mid-session, on a\n // device that HAS heard from the server, because the manager ticked\n // something off out of signal.\n if (event.serverTime === undefined) {\n return;\n }\n observedAtPerfRef.current = performance.now();\n setLastServerTime(event.serverTime);\n });\n return unsubscribe;\n }, [engine]);\n\n useEffect(() => {\n const id = setInterval(() => forceTick((tick) => tick + 1), TICK_INTERVAL_MS);\n return () => clearInterval(id);\n }, []);\n\n function now(): string {\n if (lastServerTime === undefined || observedAtPerfRef.current === undefined) {\n // No response has ever landed in this session yet. Fabricating a\n // value from the local wall clock is exactly what hard rule #6\n // forbids — this is the one case this hook cannot silently satisfy\n // its own non-optional return type, so it says so loudly instead.\n // CALLERS: this is a real, expected window — React runs an effect\n // (which is how this hook's own subscription above starts) strictly\n // AFTER the render that needs `now()`'s result has already committed,\n // so a component's very FIRST render can hit this throw even when\n // wired up correctly. Guard the call site, matching\n // `useStaleness.ts`'s own precedent, rather than reaching for a\n // device-clock fallback here (hard rule #6 forbids exactly that).\n throw new Error(\n 'useServerTime().now() was called before any response carrying meta.serverTime ' +\n 'had been observed — there is no server timestamp yet to advance from.',\n );\n }\n const elapsedMs = performance.now() - observedAtPerfRef.current;\n return new Date(Date.parse(lastServerTime) + elapsedMs).toISOString();\n }\n\n return { now, sinceLastSync: lastServerTime };\n}\n"]}
@@ -1,15 +1,15 @@
1
1
  'use strict';
2
2
 
3
- var chunk2OWH2KDY_cjs = require('./chunk-2OWH2KDY.cjs');
4
- var chunkAJE2RNOR_cjs = require('./chunk-AJE2RNOR.cjs');
5
- var chunkS53XNHRU_cjs = require('./chunk-S53XNHRU.cjs');
3
+ var chunk2JNB5A6Z_cjs = require('./chunk-2JNB5A6Z.cjs');
4
+ var chunkDRUTYOTN_cjs = require('./chunk-DRUTYOTN.cjs');
5
+ var chunk4TTDAOOG_cjs = require('./chunk-4TTDAOOG.cjs');
6
6
  var react = require('react');
7
7
  var client = require('kaafil-js/client');
8
8
  var reactDom = require('react-dom');
9
9
  var jsxRuntime = require('react/jsx-runtime');
10
10
 
11
11
  function useAgencyAdminMe() {
12
- const client = chunkS53XNHRU_cjs.useKaafilClient();
12
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
13
13
  const [result, setResult] = react.useState({ status: "loading" });
14
14
  react.useEffect(() => {
15
15
  let cancelled = false;
@@ -31,7 +31,7 @@ function useAgencyAdminMe() {
31
31
  return result;
32
32
  }
33
33
  function useAgencyChecklistTemplates() {
34
- const client = chunkS53XNHRU_cjs.useKaafilClient();
34
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
35
35
  const [templates, setTemplates] = react.useState([]);
36
36
  const [loaded, setLoaded] = react.useState(false);
37
37
  const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
@@ -91,7 +91,7 @@ function useAgencyChecklistTemplates() {
91
91
  };
92
92
  }
93
93
  function useAgencyForms() {
94
- const client = chunkS53XNHRU_cjs.useKaafilClient();
94
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
95
95
  const [forms, setForms] = react.useState([]);
96
96
  const [loaded, setLoaded] = react.useState(false);
97
97
  const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
@@ -247,7 +247,7 @@ function useAgencyForms() {
247
247
  };
248
248
  }
249
249
  function useAgencyJourneyTriggers() {
250
- const client = chunkS53XNHRU_cjs.useKaafilClient();
250
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
251
251
  const [triggers, setTriggers] = react.useState([]);
252
252
  const [loaded, setLoaded] = react.useState(false);
253
253
  const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
@@ -275,7 +275,7 @@ function useAgencyJourneyTriggers() {
275
275
  return { triggers, loaded, lastFetchFailed, refresh, patchTrigger };
276
276
  }
277
277
  function useAgencyManagerProfile(managerRef) {
278
- const client = chunkS53XNHRU_cjs.useKaafilClient();
278
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
279
279
  const [read, setRead] = react.useState(void 0);
280
280
  const [readFailed, setReadFailed] = react.useState(false);
281
281
  const refresh = react.useCallback(async () => {
@@ -293,7 +293,7 @@ function useAgencyManagerProfile(managerRef) {
293
293
  return { read, readFailed, refresh };
294
294
  }
295
295
  function useAgencySettings() {
296
- const client = chunkS53XNHRU_cjs.useKaafilClient();
296
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
297
297
  const [document2, setDocument] = react.useState(void 0);
298
298
  const [loaded, setLoaded] = react.useState(false);
299
299
  const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
@@ -321,7 +321,7 @@ function useAgencySettings() {
321
321
  return { document: document2, loaded, lastFetchFailed, refresh, patchSettings };
322
322
  }
323
323
  function useAgencyTrip(tripRef) {
324
- const client = chunkS53XNHRU_cjs.useKaafilClient();
324
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
325
325
  const [read, setRead] = react.useState(void 0);
326
326
  const [readFailed, setReadFailed] = react.useState(false);
327
327
  const refresh = react.useCallback(async () => {
@@ -341,7 +341,7 @@ function useAgencyTrip(tripRef) {
341
341
  var DEFAULT_PAGE_LIMIT = 20;
342
342
  var GROUPED_PAGE_LIMIT = 100;
343
343
  function useAgencyTripManifest(tripRef) {
344
- const client = chunkS53XNHRU_cjs.useKaafilClient();
344
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
345
345
  const [facets, setFacets] = react.useState(void 0);
346
346
  const mountedRef = react.useRef(true);
347
347
  react.useEffect(() => {
@@ -372,7 +372,7 @@ function useAgencyTripManifest(tripRef) {
372
372
  }
373
373
  var DEFAULT_PAGE_LIMIT2 = 20;
374
374
  function useAgencyTrips() {
375
- const client = chunkS53XNHRU_cjs.useKaafilClient();
375
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
376
376
  const [segmentCounts, setSegmentCounts] = react.useState(
377
377
  void 0
378
378
  );
@@ -402,18 +402,18 @@ function useAgencyTrips() {
402
402
  );
403
403
  return { makeTripsFetch, segmentCounts };
404
404
  }
405
- var useBookingsInternal = chunk2OWH2KDY_cjs.createDomainHook("bookings", (tripRef) => {
405
+ var useBookingsInternal = chunk2JNB5A6Z_cjs.createDomainHook("bookings", (tripRef) => {
406
406
  const {
407
407
  rows: bookings,
408
408
  syncedAt,
409
409
  refreshLive
410
- } = chunk2OWH2KDY_cjs.useSnapshotList(tripRef, "bookings", {
410
+ } = chunk2JNB5A6Z_cjs.useSnapshotList(tripRef, "bookings", {
411
411
  live: async (liveClient, ref) => {
412
412
  const response = await liveClient.bookings.list({ tripRef: ref });
413
413
  return { rows: [...response], syncedAt: response.meta.serverTime };
414
414
  }
415
415
  });
416
- const vouchersMutation = chunkS53XNHRU_cjs.useOfflineMutation({
416
+ const vouchersMutation = chunk4TTDAOOG_cjs.useOfflineMutation({
417
417
  tripRef,
418
418
  enqueue: (engine, input) => engine.enqueue({
419
419
  tripRef,
@@ -450,10 +450,10 @@ function useBookings(tripRef) {
450
450
  return useBookingsInternal(tripRef);
451
451
  }
452
452
  function useCapabilityStatuses(tripRef) {
453
- const { rows, loaded } = chunkS53XNHRU_cjs.useCapabilityRows(tripRef);
453
+ const { rows, loaded } = chunk4TTDAOOG_cjs.useCapabilityRows(tripRef);
454
454
  const statuses = react.useMemo(() => {
455
455
  const map = /* @__PURE__ */ new Map();
456
- for (const row of rows) map.set(row.capability, chunkS53XNHRU_cjs.deriveCapabilityTriple(row).status);
456
+ for (const row of rows) map.set(row.capability, chunk4TTDAOOG_cjs.deriveCapabilityTriple(row).status);
457
457
  return map;
458
458
  }, [rows]);
459
459
  return { statuses, loaded };
@@ -471,8 +471,8 @@ var DirectoriesWriteError = class _DirectoriesWriteError extends Error {
471
471
  }
472
472
  };
473
473
  function useDirectories(agencyRef) {
474
- const client = chunkS53XNHRU_cjs.useKaafilClient();
475
- chunkAJE2RNOR_cjs.useServerTime();
474
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
475
+ chunkDRUTYOTN_cjs.useServerTime();
476
476
  const makeManagersFetch = react.useCallback(
477
477
  (filters) => async (cursor) => {
478
478
  const page = await client.agencies.managers.listPage({
@@ -519,7 +519,7 @@ function useDirectories(agencyRef) {
519
519
  isLead: input.isLead
520
520
  });
521
521
  } catch (error) {
522
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
522
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
523
523
  }
524
524
  },
525
525
  [client]
@@ -534,7 +534,7 @@ function useDirectories(agencyRef) {
534
534
  ...input.isLead === void 0 ? {} : { isLead: input.isLead }
535
535
  });
536
536
  } catch (error) {
537
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
537
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
538
538
  }
539
539
  },
540
540
  [client]
@@ -547,7 +547,7 @@ function useDirectories(agencyRef) {
547
547
  managerRef: input.managerRef
548
548
  });
549
549
  } catch (error) {
550
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
550
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
551
551
  }
552
552
  },
553
553
  [client]
@@ -582,7 +582,7 @@ function useDirectories(agencyRef) {
582
582
  if (error instanceof DirectoriesWriteError) {
583
583
  throw error;
584
584
  }
585
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
585
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
586
586
  }
587
587
  },
588
588
  [client]
@@ -598,7 +598,7 @@ function useDirectories(agencyRef) {
598
598
  externalTravellerId: input.externalTravellerId
599
599
  });
600
600
  } catch (error) {
601
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
601
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
602
602
  }
603
603
  },
604
604
  [client]
@@ -611,7 +611,7 @@ function useDirectories(agencyRef) {
611
611
  travellerRef: input.travellerRef
612
612
  });
613
613
  } catch (error) {
614
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
614
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
615
615
  }
616
616
  },
617
617
  [client]
@@ -626,7 +626,7 @@ function useDirectories(agencyRef) {
626
626
  travellerRefs: [...input.travellerRefs]
627
627
  });
628
628
  } catch (error) {
629
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
629
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
630
630
  }
631
631
  },
632
632
  [client]
@@ -643,7 +643,7 @@ function useDirectories(agencyRef) {
643
643
  ...input.travellerRefs !== void 0 ? { travellerRefs: [...input.travellerRefs] } : {}
644
644
  });
645
645
  } catch (error) {
646
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
646
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
647
647
  }
648
648
  },
649
649
  [client]
@@ -653,7 +653,7 @@ function useDirectories(agencyRef) {
653
653
  try {
654
654
  await client.trips.parties.remove({ tripRef: input.tripRef, partyId: input.partyId });
655
655
  } catch (error) {
656
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
656
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
657
657
  }
658
658
  },
659
659
  [client]
@@ -667,7 +667,7 @@ function useDirectories(agencyRef) {
667
667
  body: input.body
668
668
  });
669
669
  } catch (error) {
670
- throw new DirectoriesWriteError(chunk2OWH2KDY_cjs.classifyError(error));
670
+ throw new DirectoriesWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
671
671
  }
672
672
  },
673
673
  [client]
@@ -714,7 +714,7 @@ function usePaginatedList(fetch, options) {
714
714
  setPageIndex(index);
715
715
  setError(void 0);
716
716
  } catch (caught) {
717
- setError(chunk2OWH2KDY_cjs.classifyError(caught));
717
+ setError(chunk2JNB5A6Z_cjs.classifyError(caught));
718
718
  setHasNext(false);
719
719
  } finally {
720
720
  setSettled(true);
@@ -773,7 +773,7 @@ var ShareLinkWriteError = class extends Error {
773
773
  }
774
774
  };
775
775
  function useShareLinks(tripRef, travellerRef) {
776
- const client = chunkS53XNHRU_cjs.useKaafilClient();
776
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
777
777
  const [links, setLinks] = react.useState(void 0);
778
778
  const [readFailed, setReadFailed] = react.useState(false);
779
779
  const refresh = react.useCallback(async () => {
@@ -804,7 +804,7 @@ function useShareLinks(tripRef, travellerRef) {
804
804
  await refresh();
805
805
  return minted;
806
806
  } catch (error) {
807
- throw new ShareLinkWriteError(chunk2OWH2KDY_cjs.classifyError(error));
807
+ throw new ShareLinkWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
808
808
  }
809
809
  },
810
810
  [client, tripRef, refresh]
@@ -815,7 +815,7 @@ function useShareLinks(tripRef, travellerRef) {
815
815
  await client.shareTokens.revoke({ id });
816
816
  await refresh();
817
817
  } catch (error) {
818
- throw new ShareLinkWriteError(chunk2OWH2KDY_cjs.classifyError(error));
818
+ throw new ShareLinkWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
819
819
  }
820
820
  },
821
821
  [client, refresh]
@@ -831,7 +831,7 @@ function useShareLinks(tripRef, travellerRef) {
831
831
  });
832
832
  await refresh();
833
833
  } catch (error) {
834
- throw new ShareLinkWriteError(chunk2OWH2KDY_cjs.classifyError(error));
834
+ throw new ShareLinkWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
835
835
  }
836
836
  },
837
837
  [client, refresh]
@@ -843,7 +843,7 @@ function useShareLinks(tripRef, travellerRef) {
843
843
  await refresh();
844
844
  return minted;
845
845
  } catch (error) {
846
- throw new ShareLinkWriteError(chunk2OWH2KDY_cjs.classifyError(error));
846
+ throw new ShareLinkWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
847
847
  }
848
848
  },
849
849
  [client, refresh]
@@ -854,7 +854,7 @@ function useShareLinks(tripRef, travellerRef) {
854
854
  const response = await client.shareTokens.reveal({ id });
855
855
  return response.token;
856
856
  } catch (error) {
857
- throw new ShareLinkWriteError(chunk2OWH2KDY_cjs.classifyError(error));
857
+ throw new ShareLinkWriteError(chunk2JNB5A6Z_cjs.classifyError(error));
858
858
  }
859
859
  },
860
860
  [client]
@@ -862,7 +862,7 @@ function useShareLinks(tripRef, travellerRef) {
862
862
  return { links, readFailed, refresh, mint, revoke, patch, regenerate, reveal };
863
863
  }
864
864
  function useTravellerFormResponses(tripRef, travellerRef) {
865
- const client = chunkS53XNHRU_cjs.useKaafilClient();
865
+ const client = chunk4TTDAOOG_cjs.useKaafilClient();
866
866
  const [responses, setResponses] = react.useState(
867
867
  void 0
868
868
  );
@@ -917,7 +917,7 @@ function ShadowIsolationBoundary({
917
917
  }
918
918
  function useDeskMinimumWidthWarning(rootRef, frame) {
919
919
  react.useEffect(() => {
920
- if (frame !== "desk" || !chunkS53XNHRU_cjs.isDevelopment() || typeof ResizeObserver === "undefined") {
920
+ if (frame !== "desk" || !chunk4TTDAOOG_cjs.isDevelopment() || typeof ResizeObserver === "undefined") {
921
921
  return;
922
922
  }
923
923
  const node = rootRef.current;
@@ -943,7 +943,7 @@ function useDeskMinimumWidthWarning(rootRef, frame) {
943
943
  }
944
944
  function useUnfilledConnectivitySlotWarning(frame, connectivitySlot) {
945
945
  react.useEffect(() => {
946
- if (frame === "field" && connectivitySlot === void 0 && chunkS53XNHRU_cjs.isDevelopment()) {
946
+ if (frame === "field" && connectivitySlot === void 0 && chunk4TTDAOOG_cjs.isDevelopment()) {
947
947
  console.warn(
948
948
  `kaafil-react-uikit: AppShell's "field" frame has no connectivitySlot filled \u2014 the permanently-visible connectivity/sync region this frame reserves is empty (01-app-shell.md, briefing \xA727.2).`
949
949
  );
@@ -992,7 +992,7 @@ function AppShell({
992
992
  className: "kf-root",
993
993
  "data-kf-isolation": "shadow",
994
994
  ...dataAttributes,
995
- style: chunkS53XNHRU_cjs.tokenStyle(style),
995
+ style: chunk4TTDAOOG_cjs.tokenStyle(style),
996
996
  children: /* @__PURE__ */ jsxRuntime.jsx(ShadowIsolationBoundary, { className: "kf-app-shell__shadow-host", children: content })
997
997
  }
998
998
  );
@@ -1004,7 +1004,7 @@ function AppShell({
1004
1004
  className: "kf-root",
1005
1005
  "data-kf-isolation": "scoped",
1006
1006
  ...dataAttributes,
1007
- style: chunkS53XNHRU_cjs.tokenStyle(style),
1007
+ style: chunk4TTDAOOG_cjs.tokenStyle(style),
1008
1008
  children: content
1009
1009
  }
1010
1010
  );
@@ -1023,10 +1023,10 @@ function ConfigShell({ seedConfig = {}, children }) {
1023
1023
  }),
1024
1024
  [seedConfig.agency, seedConfig.tenant]
1025
1025
  );
1026
- return /* @__PURE__ */ jsxRuntime.jsx(chunkS53XNHRU_cjs.ConfigContext.Provider, { value, children });
1026
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk4TTDAOOG_cjs.ConfigContext.Provider, { value, children });
1027
1027
  }
1028
1028
  function classifyForFallback(error) {
1029
- const classification = chunk2OWH2KDY_cjs.classifyError(error);
1029
+ const classification = chunk2JNB5A6Z_cjs.classifyError(error);
1030
1030
  if (classification.code === "RESOURCE_NOT_FOUND") {
1031
1031
  return { classification: "isolation", code: classification.code };
1032
1032
  }
@@ -1083,9 +1083,9 @@ function OfflineShell({
1083
1083
  scope,
1084
1084
  children
1085
1085
  }) {
1086
- const client = react.useContext(chunkS53XNHRU_cjs.KaafilClientContext);
1087
- const persona = chunkS53XNHRU_cjs.usePersona();
1088
- const session = chunkS53XNHRU_cjs.useSession();
1086
+ const client = react.useContext(chunk4TTDAOOG_cjs.KaafilClientContext);
1087
+ const persona = chunk4TTDAOOG_cjs.usePersona();
1088
+ const session = chunk4TTDAOOG_cjs.useSession();
1089
1089
  const reportExpired = react.useContext(SessionExpiryBridgeContext);
1090
1090
  const [engine, setEngine] = react.useState(null);
1091
1091
  const engineRef = react.useRef(null);
@@ -1135,7 +1135,7 @@ function OfflineShell({
1135
1135
  }
1136
1136
  };
1137
1137
  }, [client, derivedScope, session.status, persona, reportExpired]);
1138
- return /* @__PURE__ */ jsxRuntime.jsx(chunkS53XNHRU_cjs.OfflineEngineContext.Provider, { value: engine, children });
1138
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk4TTDAOOG_cjs.OfflineEngineContext.Provider, { value: engine, children });
1139
1139
  }
1140
1140
 
1141
1141
  // src/core/shells/internal/jwtKind.ts
@@ -1256,14 +1256,14 @@ function SessionShell(props) {
1256
1256
  if (state === null) {
1257
1257
  const openingPersona = shareTokenDep !== void 0 ? "share" : "manager";
1258
1258
  return /* @__PURE__ */ jsxRuntime.jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsxRuntime.jsx(
1259
- chunkS53XNHRU_cjs.SessionContext.Provider,
1259
+ chunk4TTDAOOG_cjs.SessionContext.Provider,
1260
1260
  {
1261
1261
  value: { status: "opening", persona: openingPersona, agencyRef: void 0, environment },
1262
1262
  children
1263
1263
  }
1264
1264
  ) });
1265
1265
  }
1266
- return /* @__PURE__ */ jsxRuntime.jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsxRuntime.jsx(chunkS53XNHRU_cjs.KaafilClientContext.Provider, { value: state.client, children: /* @__PURE__ */ jsxRuntime.jsx(chunkS53XNHRU_cjs.SessionContext.Provider, { value: state.session, children }) }) });
1266
+ return /* @__PURE__ */ jsxRuntime.jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsxRuntime.jsx(chunk4TTDAOOG_cjs.KaafilClientContext.Provider, { value: state.client, children: /* @__PURE__ */ jsxRuntime.jsx(chunk4TTDAOOG_cjs.SessionContext.Provider, { value: state.session, children }) }) });
1267
1267
  }
1268
1268
  function emit(onEvent, event) {
1269
1269
  if (onEvent === void 0) {
@@ -1275,8 +1275,8 @@ function emit(onEvent, event) {
1275
1275
  }
1276
1276
  }
1277
1277
  function TelemetryShell({ onEvent, children }) {
1278
- const session = chunkS53XNHRU_cjs.useSession();
1279
- const serverTime = chunkAJE2RNOR_cjs.useServerTime();
1278
+ const session = chunk4TTDAOOG_cjs.useSession();
1279
+ const serverTime = chunkDRUTYOTN_cjs.useServerTime();
1280
1280
  const previousStatusRef = react.useRef(void 0);
1281
1281
  react.useEffect(() => {
1282
1282
  const previousStatus = previousStatusRef.current;
@@ -1355,7 +1355,7 @@ function KaafilUIKitProvider(props) {
1355
1355
  ...credential
1356
1356
  } = props;
1357
1357
  const inner = /* @__PURE__ */ jsxRuntime.jsx(BuildShareUrlContext.Provider, { value: buildShareUrl ?? null, children: /* @__PURE__ */ jsxRuntime.jsx(DefaultCapabilityViewsContext.Provider, { value: defaultCapabilityViews ?? {}, children: /* @__PURE__ */ jsxRuntime.jsx(ConfigShell, { seedConfig, children: /* @__PURE__ */ jsxRuntime.jsx(
1358
- chunkS53XNHRU_cjs.BrandShell,
1358
+ chunk4TTDAOOG_cjs.BrandShell,
1359
1359
  {
1360
1360
  appName: brand?.appName,
1361
1361
  logo: brand?.logo,
@@ -1365,7 +1365,7 @@ function KaafilUIKitProvider(props) {
1365
1365
  children: /* @__PURE__ */ jsxRuntime.jsx(TelemetryShell, { onEvent, children })
1366
1366
  }
1367
1367
  ) }) }) });
1368
- return /* @__PURE__ */ jsxRuntime.jsx(ErrorShell, { children: /* @__PURE__ */ jsxRuntime.jsx(ThemeShell, { theme, density, children: /* @__PURE__ */ jsxRuntime.jsx(chunkS53XNHRU_cjs.I18nShell, { locale, children: /* @__PURE__ */ jsxRuntime.jsx(AppShell, { isolation, children: /* @__PURE__ */ jsxRuntime.jsx(
1368
+ return /* @__PURE__ */ jsxRuntime.jsx(ErrorShell, { children: /* @__PURE__ */ jsxRuntime.jsx(ThemeShell, { theme, density, children: /* @__PURE__ */ jsxRuntime.jsx(chunk4TTDAOOG_cjs.I18nShell, { locale, children: /* @__PURE__ */ jsxRuntime.jsx(AppShell, { isolation, children: /* @__PURE__ */ jsxRuntime.jsx(
1369
1369
  SessionShell,
1370
1370
  {
1371
1371
  ...credential,
@@ -1497,5 +1497,5 @@ exports.useDirectories = useDirectories;
1497
1497
  exports.usePaginatedList = usePaginatedList;
1498
1498
  exports.useShareLinks = useShareLinks;
1499
1499
  exports.useTravellerFormResponses = useTravellerFormResponses;
1500
- //# sourceMappingURL=chunk-F4GGHUMX.cjs.map
1501
- //# sourceMappingURL=chunk-F4GGHUMX.cjs.map
1500
+ //# sourceMappingURL=chunk-KY752BBA.cjs.map
1501
+ //# sourceMappingURL=chunk-KY752BBA.cjs.map