kaafil-react-uikit 0.1.0-beta.1

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 (79) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +21 -0
  3. package/README.md +187 -0
  4. package/dist/OfflineFallbackScreen-B5dfaJBN.d.ts +37 -0
  5. package/dist/OfflineFallbackScreen-Ctm7nBa-.d.cts +37 -0
  6. package/dist/SessionExpiredScreen-CytQNuak.d.cts +50 -0
  7. package/dist/SessionExpiredScreen-D8GHyZc3.d.ts +50 -0
  8. package/dist/admin/index.cjs +23779 -0
  9. package/dist/admin/index.cjs.map +1 -0
  10. package/dist/admin/index.d.cts +1157 -0
  11. package/dist/admin/index.d.ts +1157 -0
  12. package/dist/admin/index.js +23724 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/chunk-6FPAGGFL.js +6028 -0
  15. package/dist/chunk-6FPAGGFL.js.map +1 -0
  16. package/dist/chunk-ACVU55PZ.cjs +294 -0
  17. package/dist/chunk-ACVU55PZ.cjs.map +1 -0
  18. package/dist/chunk-EM7JV3D7.cjs +6051 -0
  19. package/dist/chunk-EM7JV3D7.cjs.map +1 -0
  20. package/dist/chunk-IIPQ4JNC.js +287 -0
  21. package/dist/chunk-IIPQ4JNC.js.map +1 -0
  22. package/dist/chunk-LL243STJ.cjs +2195 -0
  23. package/dist/chunk-LL243STJ.cjs.map +1 -0
  24. package/dist/chunk-PJRZCOFF.cjs +958 -0
  25. package/dist/chunk-PJRZCOFF.cjs.map +1 -0
  26. package/dist/chunk-PTQ2CJKE.cjs +40 -0
  27. package/dist/chunk-PTQ2CJKE.cjs.map +1 -0
  28. package/dist/chunk-PZKXLQSU.js +10 -0
  29. package/dist/chunk-PZKXLQSU.js.map +1 -0
  30. package/dist/chunk-QHUDOVKW.cjs +111 -0
  31. package/dist/chunk-QHUDOVKW.cjs.map +1 -0
  32. package/dist/chunk-TOBZFADB.cjs +12 -0
  33. package/dist/chunk-TOBZFADB.cjs.map +1 -0
  34. package/dist/chunk-UUGMNP27.js +936 -0
  35. package/dist/chunk-UUGMNP27.js.map +1 -0
  36. package/dist/chunk-UYJ6LIWP.js +2154 -0
  37. package/dist/chunk-UYJ6LIWP.js.map +1 -0
  38. package/dist/chunk-VHTSTUCJ.cjs +346 -0
  39. package/dist/chunk-VHTSTUCJ.cjs.map +1 -0
  40. package/dist/chunk-WUAFL77X.js +340 -0
  41. package/dist/chunk-WUAFL77X.js.map +1 -0
  42. package/dist/chunk-XI7MK4Y7.js +38 -0
  43. package/dist/chunk-XI7MK4Y7.js.map +1 -0
  44. package/dist/chunk-YDGR7JSY.js +107 -0
  45. package/dist/chunk-YDGR7JSY.js.map +1 -0
  46. package/dist/core/index.cjs +1254 -0
  47. package/dist/core/index.cjs.map +1 -0
  48. package/dist/core/index.d.cts +1267 -0
  49. package/dist/core/index.d.ts +1267 -0
  50. package/dist/core/index.js +995 -0
  51. package/dist/core/index.js.map +1 -0
  52. package/dist/index.css +1 -0
  53. package/dist/manager/index.cjs +13562 -0
  54. package/dist/manager/index.cjs.map +1 -0
  55. package/dist/manager/index.d.cts +1054 -0
  56. package/dist/manager/index.d.ts +1054 -0
  57. package/dist/manager/index.js +13518 -0
  58. package/dist/manager/index.js.map +1 -0
  59. package/dist/testing/index.cjs +221 -0
  60. package/dist/testing/index.cjs.map +1 -0
  61. package/dist/testing/index.d.cts +269 -0
  62. package/dist/testing/index.d.ts +269 -0
  63. package/dist/testing/index.js +208 -0
  64. package/dist/testing/index.js.map +1 -0
  65. package/dist/tokenStyle-CToG5oOS.d.cts +3 -0
  66. package/dist/tokenStyle-CToG5oOS.d.ts +3 -0
  67. package/dist/traveller/index.cjs +1799 -0
  68. package/dist/traveller/index.cjs.map +1 -0
  69. package/dist/traveller/index.d.cts +58 -0
  70. package/dist/traveller/index.d.ts +58 -0
  71. package/dist/traveller/index.js +1789 -0
  72. package/dist/traveller/index.js.map +1 -0
  73. package/dist/useAgencyTrip-BUYSIaC2.d.cts +454 -0
  74. package/dist/useAgencyTrip-BzyJB1D9.d.ts +454 -0
  75. package/dist/useNotifications-BZW1Z_ur.d.cts +356 -0
  76. package/dist/useNotifications-D262i5BQ.d.ts +356 -0
  77. package/dist/useVendors-DXOuZWhZ.d.cts +784 -0
  78. package/dist/useVendors-DXOuZWhZ.d.ts +784 -0
  79. package/package.json +95 -0
@@ -0,0 +1,995 @@
1
+ export { useConflicts, useManagerMe, useNotifications } from '../chunk-YDGR7JSY.js';
2
+ export { CLOSEOUT_ACTION_TAB, fromSearchParams, isTripTabKey, resolveBlockerDeepLink, toSearchParams, useAgencyAdminMe, useAgencyChecklistTemplates, useAgencyForms, useAgencyJourneyTriggers, useAgencyManagerProfile, useAgencySettings, useAgencyTrip, useAgencyTripManifest, useAgencyTrips, useBookings, useCapabilityStatuses, useDirectories, usePaginatedList, useShareLinks, useTravellerFormResponses } from '../chunk-UUGMNP27.js';
3
+ import { createDomainHook, useSnapshotList, classifyError } from '../chunk-UYJ6LIWP.js';
4
+ export { ERROR_HANDLING_PATH, classifyError, useChecklists, useCloseout, useCollections, useExpenses, useFiles, useFloat, useForms, useItinerary, useManagerToday, useManagers, useParties, usePickups, useRooming, useSeating, useSnapshotList, useTravellerProfile, useVendors } from '../chunk-UYJ6LIWP.js';
5
+ import { BrandShell } from '../chunk-WUAFL77X.js';
6
+ export { BrandShell, useKaafilBrand, useKaafilShareMeta, useShareForms, useShareSnapshot } from '../chunk-WUAFL77X.js';
7
+ export { useOfflineEngine } from '../chunk-PZKXLQSU.js';
8
+ import { useServerTime } from '../chunk-XI7MK4Y7.js';
9
+ export { useServerTime } from '../chunk-XI7MK4Y7.js';
10
+ import { useKaafilClient, useOfflineMutation, OfflineEngineContext, useOfflineEvent, usePersona, useCapabilityRows, isDevelopment, deriveCapabilityTriple, useRequiredContext, ConfigContext, tokenStyle, KaafilClientContext, useSession, SessionContext, I18nShell, useKaafilChrome } from '../chunk-6FPAGGFL.js';
11
+ export { I18nShell, createRegistry, useCapabilities, useCapability, useKaafilChrome, useKaafilClient, useOfflineEvent, useOfflineMutation, useOutboxStatus, usePersona, useSession } from '../chunk-6FPAGGFL.js';
12
+ import { SyncOpMethod, KaafilClient } from 'kaafil-js/client';
13
+ export { UnsatisfiableSchemeError } from 'kaafil-js/client';
14
+ import { useState, useCallback, useEffect, createContext, useContext, useRef, useMemo, Component, Fragment } from 'react';
15
+ import { createPortal } from 'react-dom';
16
+ import { jsx, Fragment as Fragment$1, jsxs } from 'react/jsx-runtime';
17
+
18
+ var NotImplementedError = class _NotImplementedError extends Error {
19
+ hookName;
20
+ specSection;
21
+ constructor(hookName, specSection) {
22
+ super(
23
+ `${hookName}() has no implementation in this build yet \u2014 see 08-core-hooks.md ${specSection} for its full signature and SDK binding.`
24
+ );
25
+ this.name = "NotImplementedError";
26
+ Object.setPrototypeOf(this, _NotImplementedError.prototype);
27
+ this.hookName = hookName;
28
+ this.specSection = specSection;
29
+ }
30
+ };
31
+ function useBlobStatus(blobId) {
32
+ const engine = useContext(OfflineEngineContext);
33
+ const [, forceRefresh] = useState(0);
34
+ useOfflineEvent("sync.drained", () => forceRefresh((tick) => tick + 1));
35
+ useOfflineEvent("sync.error", () => forceRefresh((tick) => tick + 1));
36
+ const record = engine?.blobs?.all().find((candidate) => candidate.id === blobId);
37
+ if (record === void 0) {
38
+ return { status: "pending", progress: void 0 };
39
+ }
40
+ const status = record.status === "confirmed" ? "ready" : record.status === "parked" ? "orphaned" : record.attemptCount > 0 ? "uploading" : "pending";
41
+ return { status, progress: void 0 };
42
+ }
43
+ function useFeedbackNps(scope) {
44
+ const client = useKaafilClient();
45
+ const [summary, setSummary] = useState(void 0);
46
+ const [definitions, setDefinitions] = useState([]);
47
+ const [loaded, setLoaded] = useState(false);
48
+ const [lastFetchFailed, setLastFetchFailed] = useState(false);
49
+ const [syncedAt, setSyncedAt] = useState(void 0);
50
+ const formIdRef = useRef(void 0);
51
+ const refresh = useCallback(async () => {
52
+ try {
53
+ if (scope.kind === "trip") {
54
+ const response = await client.feedbackNps.trip({ tripRef: scope.tripRef });
55
+ setSummary(response.data);
56
+ formIdRef.current = response.data.configured ? response.data.formId : void 0;
57
+ setLoaded(true);
58
+ setLastFetchFailed(false);
59
+ setSyncedAt(response.meta.serverTime);
60
+ } else {
61
+ const response = await client.feedbackNps.agency({});
62
+ setDefinitions(response.data.definitions);
63
+ setLoaded(true);
64
+ setLastFetchFailed(false);
65
+ setSyncedAt(response.meta.serverTime);
66
+ }
67
+ } catch {
68
+ setLastFetchFailed(true);
69
+ }
70
+ }, [client, scope.kind, scope.kind === "trip" ? scope.tripRef : scope.agencyRef]);
71
+ useEffect(() => {
72
+ void refresh();
73
+ }, [refresh]);
74
+ const dispatchMutation = useOfflineMutation({
75
+ tripRef: scope.kind === "trip" ? scope.tripRef : "",
76
+ enqueue: (engine, input) => {
77
+ const formId = formIdRef.current;
78
+ if (formId === void 0 || scope.kind !== "trip") {
79
+ throw new Error("useFeedbackNps: cannot dispatch before a feedback form is resolved");
80
+ }
81
+ return engine.enqueue({
82
+ tripRef: scope.tripRef,
83
+ method: SyncOpMethod.Post,
84
+ path: `/api/v1/trips/${scope.tripRef}/forms/${formId}/dispatch`,
85
+ // Hardcoded literal, not imported: `OperationId` is not exported
86
+ // from `kaafil-js/client`'s public surface — same convention as
87
+ // `useRooming.ts`'s own `'assignRoomingBed' as never`. Verified
88
+ // against `kaafil-js/src/generated/security.ts`
89
+ // (`OPERATION_SECURITY.dispatchForm`) this session.
90
+ operationId: "dispatchForm",
91
+ body: input ?? {}
92
+ });
93
+ }
94
+ });
95
+ const dispatchMutate = dispatchMutation.mutate;
96
+ const dispatch = useCallback(
97
+ async (input) => {
98
+ const op = await dispatchMutate(input ?? {});
99
+ void refresh();
100
+ return op;
101
+ },
102
+ [dispatchMutate, refresh]
103
+ );
104
+ return {
105
+ kind: scope.kind,
106
+ summary,
107
+ definitions,
108
+ loaded,
109
+ lastFetchFailed,
110
+ syncedAt,
111
+ refresh,
112
+ dispatch,
113
+ dispatchStatus: dispatchMutation.status,
114
+ dispatchOp: dispatchMutation.op
115
+ };
116
+ }
117
+ function useJourney(tripRef) {
118
+ const client = useKaafilClient();
119
+ const persona = usePersona();
120
+ const { rows } = useCapabilityRows(tripRef);
121
+ const [read, setRead] = useState(void 0);
122
+ const [liveRows, setLiveRows] = useState(void 0);
123
+ useEffect(() => {
124
+ if (persona === "share") {
125
+ if (isDevelopment()) {
126
+ throw new Error(
127
+ "useJourney() was called from a share session \u2014 it is manager/agencyAdmin only (08-core-hooks.md \xA73.2)."
128
+ );
129
+ }
130
+ return;
131
+ }
132
+ let cancelled = false;
133
+ void client.journey.get({ tripRef }).then((response) => {
134
+ if (!cancelled) {
135
+ setRead(response);
136
+ }
137
+ });
138
+ return () => {
139
+ cancelled = true;
140
+ };
141
+ }, [client, persona, tripRef]);
142
+ const refreshCapabilities = useCallback(async () => {
143
+ const response = await client.journey.capabilities({ tripRef, live: true });
144
+ setLiveRows(response);
145
+ }, [client, tripRef]);
146
+ const effectiveRows = liveRows ?? rows;
147
+ const capabilities = /* @__PURE__ */ new Map();
148
+ for (const row of effectiveRows) {
149
+ capabilities.set(row.capability, deriveCapabilityTriple(row));
150
+ }
151
+ return {
152
+ read,
153
+ capabilities,
154
+ refreshCapabilities,
155
+ triggers: {
156
+ list: (options) => client.journey.triggers.list(options),
157
+ patch: (options) => client.journey.triggers.patch(options)
158
+ }
159
+ };
160
+ }
161
+
162
+ // src/core/hooks/useResolvedSetting.ts
163
+ function useResolvedSetting(key) {
164
+ const config = useRequiredContext(ConfigContext, "useResolvedSetting", "ConfigShell");
165
+ return config.resolveSetting(key);
166
+ }
167
+ function useSnapshotEntity(tripRef, listName, id) {
168
+ const engine = useContext(OfflineEngineContext);
169
+ const { rows } = useSnapshotList(tripRef, listName);
170
+ const row = rows.find((candidate) => candidate.id === id);
171
+ const syncedAt = engine === null ? void 0 : engine.snapshot.syncedAt(tripRef, listName, id);
172
+ return { row, syncedAt };
173
+ }
174
+
175
+ // src/core/hooks/useStaleness.ts
176
+ function useStaleness(tripRef, listName) {
177
+ const { syncedAt } = useSnapshotList(tripRef, listName);
178
+ const { now } = useServerTime();
179
+ const thresholdSeconds = useResolvedSetting("stale.thresholdSeconds.default");
180
+ if (syncedAt === void 0) {
181
+ return { syncedAt: void 0, ageSeconds: void 0, isStale: false };
182
+ }
183
+ let ageSeconds;
184
+ try {
185
+ ageSeconds = (Date.parse(now()) - Date.parse(syncedAt)) / 1e3;
186
+ } catch {
187
+ ageSeconds = void 0;
188
+ }
189
+ const isStale = ageSeconds !== void 0 && thresholdSeconds !== void 0 && ageSeconds > thresholdSeconds;
190
+ return { syncedAt, ageSeconds, isStale };
191
+ }
192
+ var WALK_INS_PAGE_SIZE = 25;
193
+ var useTreksInternal = createDomainHook("treks", (tripRef) => {
194
+ const client = useKaafilClient();
195
+ const [boardData, setBoardData] = useState(void 0);
196
+ const [boardLoaded, setBoardLoaded] = useState(false);
197
+ const [boardFetchFailed, setBoardFetchFailed] = useState(false);
198
+ const [boardFetchedAt, setBoardFetchedAt] = useState(void 0);
199
+ const refreshBoard = useCallback(async () => {
200
+ try {
201
+ const response = await client.treks.board({ trekRef: tripRef });
202
+ setBoardData(response);
203
+ setBoardLoaded(true);
204
+ setBoardFetchFailed(false);
205
+ setBoardFetchedAt(response.meta.serverTime);
206
+ } catch {
207
+ setBoardFetchFailed(true);
208
+ }
209
+ }, [client, tripRef]);
210
+ useEffect(() => {
211
+ void refreshBoard();
212
+ }, [refreshBoard]);
213
+ const [walkInRows, setWalkInRows] = useState([]);
214
+ const [walkInsLoaded, setWalkInsLoaded] = useState(false);
215
+ const [walkInsFetchFailed, setWalkInsFetchFailed] = useState(false);
216
+ const [walkInsFetchedAt, setWalkInsFetchedAt] = useState(void 0);
217
+ const [walkInsCursor, setWalkInsCursor] = useState(void 0);
218
+ const [walkInsHasNext, setWalkInsHasNext] = useState(false);
219
+ const refreshWalkIns = useCallback(async () => {
220
+ try {
221
+ const page = await client.treks.walkIns.listPage({
222
+ trekRef: tripRef,
223
+ limit: WALK_INS_PAGE_SIZE
224
+ });
225
+ setWalkInRows(page);
226
+ setWalkInsLoaded(true);
227
+ setWalkInsFetchFailed(false);
228
+ setWalkInsFetchedAt(page.meta.serverTime);
229
+ setWalkInsCursor(page.meta.page.cursor ?? void 0);
230
+ setWalkInsHasNext(page.meta.page.hasNext);
231
+ } catch {
232
+ setWalkInsFetchFailed(true);
233
+ }
234
+ }, [client, tripRef]);
235
+ const loadMoreWalkIns = useCallback(async () => {
236
+ if (walkInsCursor === void 0 || !walkInsHasNext) {
237
+ return;
238
+ }
239
+ try {
240
+ const page = await client.treks.walkIns.listPage({
241
+ trekRef: tripRef,
242
+ cursor: walkInsCursor,
243
+ limit: WALK_INS_PAGE_SIZE
244
+ });
245
+ setWalkInRows((existing) => [...existing, ...page]);
246
+ setWalkInsFetchedAt(page.meta.serverTime);
247
+ setWalkInsCursor(page.meta.page.cursor ?? void 0);
248
+ setWalkInsHasNext(page.meta.page.hasNext);
249
+ } catch {
250
+ setWalkInsFetchFailed(true);
251
+ }
252
+ }, [client, tripRef, walkInsCursor, walkInsHasNext]);
253
+ useEffect(() => {
254
+ void refreshWalkIns();
255
+ }, [refreshWalkIns]);
256
+ const [metaData, setMetaData] = useState(void 0);
257
+ const [metaLoaded, setMetaLoaded] = useState(false);
258
+ const [metaFetchFailed, setMetaFetchFailed] = useState(false);
259
+ const refreshMeta = useCallback(async () => {
260
+ try {
261
+ const response = await client.treks.walkIns.meta({ trekRef: tripRef });
262
+ setMetaData(response);
263
+ setMetaLoaded(true);
264
+ setMetaFetchFailed(false);
265
+ } catch {
266
+ setMetaFetchFailed(true);
267
+ }
268
+ }, [client, tripRef]);
269
+ useEffect(() => {
270
+ void refreshMeta();
271
+ }, [refreshMeta]);
272
+ const createWalkInMutation = useOfflineMutation({
273
+ tripRef,
274
+ enqueue: (engine, input) => engine.enqueue({
275
+ tripRef,
276
+ method: SyncOpMethod.Post,
277
+ path: `/api/v1/treks/${tripRef}/walk-ins`,
278
+ // `OperationId` is not exported from `kaafil-js/client`'s public
279
+ // surface — same documented gap `useFloat.ts`/`useRooming.ts` cast
280
+ // around for their own literal `operationId`s.
281
+ operationId: "createTrekWalkIn",
282
+ body: input
283
+ })
284
+ });
285
+ const postponeMutation = useOfflineMutation({
286
+ tripRef,
287
+ enqueue: (engine, input) => engine.enqueue({
288
+ tripRef,
289
+ method: SyncOpMethod.Post,
290
+ path: `/api/v1/treks/${tripRef}/postpone`,
291
+ operationId: "postponeTrek",
292
+ body: input
293
+ })
294
+ });
295
+ const reconcileMutation = useOfflineMutation({
296
+ tripRef,
297
+ enqueue: (engine, { walkInId, input }) => engine.enqueue({
298
+ tripRef,
299
+ method: SyncOpMethod.Post,
300
+ path: `/api/v1/treks/${tripRef}/walk-ins/${walkInId}/reconcile`,
301
+ operationId: "reconcileTrekWalkIn",
302
+ body: input
303
+ })
304
+ });
305
+ const createWalkInMutate = createWalkInMutation.mutate;
306
+ const createWalkIn = useCallback(
307
+ async (input) => {
308
+ const op = await createWalkInMutate(input);
309
+ void refreshBoard();
310
+ void refreshWalkIns();
311
+ return op;
312
+ },
313
+ [createWalkInMutate, refreshBoard, refreshWalkIns]
314
+ );
315
+ const postponeMutate = postponeMutation.mutate;
316
+ const postpone = useCallback(
317
+ async (input) => {
318
+ const op = await postponeMutate(input);
319
+ void refreshBoard();
320
+ return op;
321
+ },
322
+ [postponeMutate, refreshBoard]
323
+ );
324
+ const reconcileMutate = reconcileMutation.mutate;
325
+ const reconcileWalkIn = useCallback(
326
+ async (walkInId, input) => {
327
+ const op = await reconcileMutate({ walkInId, input });
328
+ void refreshWalkIns();
329
+ return op;
330
+ },
331
+ [reconcileMutate, refreshWalkIns]
332
+ );
333
+ return {
334
+ board: {
335
+ data: boardData,
336
+ loaded: boardLoaded,
337
+ lastFetchFailed: boardFetchFailed,
338
+ fetchedAt: boardFetchedAt,
339
+ refresh: refreshBoard
340
+ },
341
+ walkIns: {
342
+ rows: walkInRows,
343
+ loaded: walkInsLoaded,
344
+ lastFetchFailed: walkInsFetchFailed,
345
+ fetchedAt: walkInsFetchedAt,
346
+ hasMore: walkInsHasNext,
347
+ refresh: refreshWalkIns,
348
+ loadMore: loadMoreWalkIns
349
+ },
350
+ walkInMeta: {
351
+ data: metaData,
352
+ loaded: metaLoaded,
353
+ lastFetchFailed: metaFetchFailed,
354
+ refresh: refreshMeta
355
+ },
356
+ createWalkIn,
357
+ postpone,
358
+ reconcileWalkIn
359
+ };
360
+ });
361
+ function useTreks(tripRef) {
362
+ return useTreksInternal(tripRef);
363
+ }
364
+ var ThemeAttributesContext = createContext(null);
365
+ var FAMILY_DEFAULT_FRAME = {
366
+ admin: "desk",
367
+ manager: "field",
368
+ traveller: "document"
369
+ };
370
+ var DESK_MINIMUM_CONTAINER_WIDTH_PX = 640;
371
+ function ShadowIsolationBoundary({
372
+ className,
373
+ children
374
+ }) {
375
+ const hostRef = useRef(null);
376
+ const [shadowContainer, setShadowContainer] = useState(null);
377
+ useEffect(() => {
378
+ const host = hostRef.current;
379
+ if (host === null) {
380
+ return;
381
+ }
382
+ const shadow = host.shadowRoot ?? host.attachShadow({ mode: "open" });
383
+ let container = shadow.querySelector("div[data-kf-shadow-content]");
384
+ if (container === null) {
385
+ container = document.createElement("div");
386
+ container.setAttribute("data-kf-shadow-content", "");
387
+ shadow.appendChild(container);
388
+ }
389
+ setShadowContainer(container);
390
+ }, []);
391
+ return /* @__PURE__ */ jsx("div", { ref: hostRef, className, "data-kf-isolation": "shadow", children: shadowContainer !== null ? createPortal(children, shadowContainer) : null });
392
+ }
393
+ function useDeskMinimumWidthWarning(rootRef, frame) {
394
+ useEffect(() => {
395
+ if (frame !== "desk" || !isDevelopment() || typeof ResizeObserver === "undefined") {
396
+ return;
397
+ }
398
+ const node = rootRef.current;
399
+ if (node === null) {
400
+ return;
401
+ }
402
+ let warned = false;
403
+ const observer = new ResizeObserver((entries) => {
404
+ const entry = entries[0];
405
+ if (entry === void 0 || warned) {
406
+ return;
407
+ }
408
+ if (entry.contentRect.width < DESK_MINIMUM_CONTAINER_WIDTH_PX) {
409
+ warned = true;
410
+ console.warn(
411
+ `kaafil-react-uikit: the 'desk' frame's .kf-root is narrower than the stated minimum container width (05-theming-and-branding.md \xA74.4). AppShell never auto-swaps frames \u2014 mount the manager family, or pass frame="field" explicitly, for this container.`
412
+ );
413
+ }
414
+ });
415
+ observer.observe(node);
416
+ return () => observer.disconnect();
417
+ }, [rootRef, frame]);
418
+ }
419
+ function useUnfilledConnectivitySlotWarning(frame, connectivitySlot) {
420
+ useEffect(() => {
421
+ if (frame === "field" && connectivitySlot === void 0 && isDevelopment()) {
422
+ console.warn(
423
+ `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).`
424
+ );
425
+ }
426
+ }, [frame, connectivitySlot]);
427
+ }
428
+ function AppShell({
429
+ frame,
430
+ family,
431
+ isolation = "scoped",
432
+ navSlot,
433
+ actionBarSlot,
434
+ connectivitySlot,
435
+ children,
436
+ style
437
+ }) {
438
+ const themeAttributes = useContext(ThemeAttributesContext);
439
+ const rootRef = useRef(null);
440
+ const resolvedFrame = frame ?? (family !== void 0 ? FAMILY_DEFAULT_FRAME[family] : "document");
441
+ useDeskMinimumWidthWarning(rootRef, resolvedFrame);
442
+ useUnfilledConnectivitySlotWarning(resolvedFrame, connectivitySlot);
443
+ const dataAttributes = {
444
+ "data-kf-frame": resolvedFrame
445
+ };
446
+ if (family !== void 0) {
447
+ dataAttributes["data-kf-family"] = family;
448
+ }
449
+ if (themeAttributes !== null) {
450
+ dataAttributes["data-kf-theme"] = themeAttributes.theme;
451
+ if (themeAttributes.density !== void 0) {
452
+ dataAttributes["data-kf-density"] = themeAttributes.density;
453
+ }
454
+ }
455
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
456
+ resolvedFrame === "desk" && navSlot !== void 0 ? /* @__PURE__ */ jsx("div", { className: "kf-app-shell__nav", children: navSlot }) : null,
457
+ /* @__PURE__ */ jsx("div", { className: "kf-app-shell__content", children }),
458
+ resolvedFrame === "field" && actionBarSlot !== void 0 ? /* @__PURE__ */ jsx("div", { className: "kf-app-shell__action-bar", children: actionBarSlot }) : null,
459
+ resolvedFrame === "field" && connectivitySlot !== void 0 ? /* @__PURE__ */ jsx("div", { className: "kf-app-shell__connectivity", children: connectivitySlot }) : null,
460
+ /* @__PURE__ */ jsx("div", { className: "kf-app-shell__live-region", role: "status", "aria-live": "polite" })
461
+ ] });
462
+ if (isolation === "shadow") {
463
+ return /* @__PURE__ */ jsx(
464
+ "div",
465
+ {
466
+ ref: rootRef,
467
+ className: "kf-root",
468
+ "data-kf-isolation": "shadow",
469
+ ...dataAttributes,
470
+ style: tokenStyle(style),
471
+ children: /* @__PURE__ */ jsx(ShadowIsolationBoundary, { className: "kf-app-shell__shadow-host", children: content })
472
+ }
473
+ );
474
+ }
475
+ return /* @__PURE__ */ jsx(
476
+ "div",
477
+ {
478
+ ref: rootRef,
479
+ className: "kf-root",
480
+ "data-kf-isolation": "scoped",
481
+ ...dataAttributes,
482
+ style: tokenStyle(style),
483
+ children: content
484
+ }
485
+ );
486
+ }
487
+ function ConfigShell({ seedConfig = {}, children }) {
488
+ const value = useMemo(
489
+ () => ({
490
+ resolveSetting(key) {
491
+ const agencyValue = seedConfig.agency?.[key];
492
+ if (agencyValue !== void 0) {
493
+ return agencyValue;
494
+ }
495
+ const tenantValue = seedConfig.tenant?.[key];
496
+ return tenantValue === void 0 ? void 0 : tenantValue;
497
+ }
498
+ }),
499
+ [seedConfig.agency, seedConfig.tenant]
500
+ );
501
+ return /* @__PURE__ */ jsx(ConfigContext.Provider, { value, children });
502
+ }
503
+ function classifyForFallback(error) {
504
+ const classification = classifyError(error);
505
+ if (classification.code === "RESOURCE_NOT_FOUND") {
506
+ return { classification: "isolation", code: classification.code };
507
+ }
508
+ if (classification.path === "parked" || classification.unsatisfiableScheme) {
509
+ return { classification: "parked", code: classification.code };
510
+ }
511
+ return { classification: "retryable", code: classification.code };
512
+ }
513
+ var FALLBACK_STYLE = {
514
+ fontFamily: "system-ui, sans-serif",
515
+ padding: "1.5rem",
516
+ border: "1px solid #999",
517
+ borderRadius: "4px",
518
+ color: "#1a1a1a",
519
+ background: "#fff"
520
+ };
521
+ function DefaultFallback({
522
+ ctx,
523
+ onRetry
524
+ }) {
525
+ const role = ctx.classification === "retryable" ? "status" : "alert";
526
+ const ariaLive = ctx.classification === "retryable" ? "polite" : "assertive";
527
+ const message = ctx.classification === "isolation" ? "Not found." : ctx.classification === "parked" ? "This action can't be completed right now." : "Something went wrong.";
528
+ return /* @__PURE__ */ jsxs("div", { style: FALLBACK_STYLE, role, "aria-live": ariaLive, children: [
529
+ /* @__PURE__ */ jsx("p", { style: { margin: 0 }, children: message }),
530
+ ctx.classification === "retryable" ? /* @__PURE__ */ jsx("button", { type: "button", onClick: onRetry, style: { marginTop: "0.75rem" }, children: "Try again" }) : null
531
+ ] });
532
+ }
533
+ var ErrorShell = class extends Component {
534
+ state = { caught: null, retryKey: 0 };
535
+ static getDerivedStateFromError(error) {
536
+ return { caught: { error } };
537
+ }
538
+ handleRetry = () => {
539
+ this.setState((current) => ({ caught: null, retryKey: current.retryKey + 1 }));
540
+ };
541
+ render() {
542
+ if (this.state.caught !== null) {
543
+ const ctx = classifyForFallback(this.state.caught.error);
544
+ if (this.props.fallbackSlot !== void 0) {
545
+ return this.props.fallbackSlot(ctx);
546
+ }
547
+ return /* @__PURE__ */ jsx(DefaultFallback, { ctx, onRetry: this.handleRetry });
548
+ }
549
+ return /* @__PURE__ */ jsx(Fragment, { children: this.props.children }, this.state.retryKey);
550
+ }
551
+ };
552
+ var SessionExpiryBridgeContext = createContext(void 0);
553
+ function OfflineShell({
554
+ storage,
555
+ blob,
556
+ conflictResolver,
557
+ readEntity,
558
+ scope,
559
+ children
560
+ }) {
561
+ const client = useContext(KaafilClientContext);
562
+ const persona = usePersona();
563
+ const session = useSession();
564
+ const reportExpired = useContext(SessionExpiryBridgeContext);
565
+ const [engine, setEngine] = useState(null);
566
+ const engineRef = useRef(null);
567
+ const derivedScope = scope ?? `${persona}:${session.agencyRef ?? "share"}`;
568
+ useEffect(() => {
569
+ if (session.status !== "authenticated" || client === null) {
570
+ return;
571
+ }
572
+ const newEngine = client.openOffline({
573
+ storage,
574
+ scope: derivedScope,
575
+ ...readEntity !== void 0 ? { readEntity } : {},
576
+ ...conflictResolver !== void 0 ? { conflictResolver } : {},
577
+ ...blob !== void 0 ? { blob } : {}
578
+ // GAP flagged in this phase's report: a share session's local
579
+ // `expiresAt` enforcement (`OpenOfflineOptions.share`,
580
+ // `07-offline-and-sync.md §8`) needs an `expiresAt` this shell has no
581
+ // source for yet — it is not on `useSession()`'s derived shape and no
582
+ // prop carries it. Omitted here rather than guessed; a share engine
583
+ // opens without the local expiry/grace/purge enforcement until that
584
+ // value has a wire source.
585
+ });
586
+ engineRef.current = newEngine;
587
+ setEngine(newEngine);
588
+ const unsubscribeSessionExpired = persona !== "share" ? newEngine.events.on("session.expired", () => reportExpired?.("session")) : void 0;
589
+ const unsubscribeShareExpired = persona === "share" ? newEngine.events.on("share.expired", () => reportExpired?.("share")) : void 0;
590
+ const unsubscribeShareRevoked = persona === "share" ? newEngine.events.on("share.revoked", () => reportExpired?.("share")) : void 0;
591
+ return () => {
592
+ unsubscribeSessionExpired?.();
593
+ unsubscribeShareExpired?.();
594
+ unsubscribeShareRevoked?.();
595
+ newEngine.close();
596
+ if (engineRef.current === newEngine) {
597
+ engineRef.current = null;
598
+ }
599
+ };
600
+ }, [client, derivedScope, session.status, persona, reportExpired]);
601
+ return /* @__PURE__ */ jsx(OfflineEngineContext.Provider, { value: engine, children });
602
+ }
603
+
604
+ // src/core/shells/internal/jwtKind.ts
605
+ function base64UrlDecode(segment) {
606
+ const padded = segment.replace(/-/g, "+").replace(/_/g, "/");
607
+ const withPadding = padded + "=".repeat((4 - padded.length % 4) % 4);
608
+ return atob(withPadding);
609
+ }
610
+ function decodeManagerOrAgencyAdminKind(accessToken) {
611
+ const segments = accessToken.split(".");
612
+ const payloadSegment = segments[1];
613
+ if (segments.length !== 3 || payloadSegment === void 0) {
614
+ throw new Error(
615
+ 'SessionShell could not parse "accessToken" as a JWT \u2014 it does not have the three dot-separated segments every manager/agencyAdmin session token has.'
616
+ );
617
+ }
618
+ let claim;
619
+ try {
620
+ claim = JSON.parse(base64UrlDecode(payloadSegment));
621
+ } catch {
622
+ throw new Error(
623
+ `SessionShell could not decode "accessToken"'s payload segment as JSON \u2014 the value handed to <KaafilUIKitProvider accessToken> is not a well-formed JWT.`
624
+ );
625
+ }
626
+ const kind = claim.kind;
627
+ if (kind === "agencyAdmin") {
628
+ return "agencyAdmin";
629
+ }
630
+ if (kind === "managerSession" || kind === "manager") {
631
+ return "managerSession";
632
+ }
633
+ throw new Error(
634
+ `SessionShell read an unrecognised "kind" claim ("${String(kind)}") off "accessToken" \u2014 expected the manager or agencyAdmin session JWT shape (00-decisions.md U-003).`
635
+ );
636
+ }
637
+ async function resolveCredential(props) {
638
+ if (props.credentialResolver !== void 0) {
639
+ const resolved = await props.credentialResolver();
640
+ if ("shareToken" in resolved) {
641
+ return { kind: "share", shareToken: resolved.shareToken };
642
+ }
643
+ const kind2 = decodeManagerOrAgencyAdminKind(resolved.accessToken) === "agencyAdmin" ? "agencyAdmin" : "manager";
644
+ return { kind: kind2, ...resolved };
645
+ }
646
+ if (props.shareToken !== void 0) {
647
+ return { kind: "share", shareToken: props.shareToken };
648
+ }
649
+ const kind = decodeManagerOrAgencyAdminKind(props.accessToken) === "agencyAdmin" ? "agencyAdmin" : "manager";
650
+ return {
651
+ kind,
652
+ accessToken: props.accessToken,
653
+ refreshToken: props.refreshToken,
654
+ agencyRef: props.agencyRef
655
+ };
656
+ }
657
+ function SessionShell(props) {
658
+ const { environment = "live", onRefresh, onSessionExpired, children } = props;
659
+ const [state, setState] = useState(null);
660
+ const expiredCallbackFiredRef = useRef(false);
661
+ const currentPersonaRef = useRef("manager");
662
+ const reportExpired = useCallback(() => {
663
+ if (expiredCallbackFiredRef.current) {
664
+ return;
665
+ }
666
+ expiredCallbackFiredRef.current = true;
667
+ onSessionExpired?.(currentPersonaRef.current);
668
+ setState(
669
+ (current) => current === null ? current : { ...current, session: { ...current.session, status: "expired" } }
670
+ );
671
+ }, [onSessionExpired]);
672
+ const accessTokenDep = "accessToken" in props ? props.accessToken : void 0;
673
+ const refreshTokenDep = "refreshToken" in props ? props.refreshToken : void 0;
674
+ const agencyRefDep = "agencyRef" in props ? props.agencyRef : void 0;
675
+ const shareTokenDep = "shareToken" in props ? props.shareToken : void 0;
676
+ useEffect(() => {
677
+ let cancelled = false;
678
+ const client = new KaafilClient({ environment });
679
+ expiredCallbackFiredRef.current = false;
680
+ async function open() {
681
+ const credential = await resolveCredential(props);
682
+ if (cancelled) {
683
+ return;
684
+ }
685
+ currentPersonaRef.current = credential.kind;
686
+ if (credential.kind === "share") {
687
+ client.share.open({ token: credential.shareToken });
688
+ } else if (credential.kind === "agencyAdmin") {
689
+ client.admin.open({
690
+ accessToken: credential.accessToken,
691
+ refreshToken: credential.refreshToken,
692
+ agencyRef: credential.agencyRef,
693
+ ...onRefresh !== void 0 ? { onRefresh } : {}
694
+ });
695
+ } else {
696
+ client.session.open({
697
+ accessToken: credential.accessToken,
698
+ refreshToken: credential.refreshToken,
699
+ agencyRef: credential.agencyRef,
700
+ ...onRefresh !== void 0 ? { onRefresh } : {}
701
+ });
702
+ }
703
+ setState({
704
+ client,
705
+ session: {
706
+ status: "authenticated",
707
+ persona: credential.kind,
708
+ agencyRef: credential.agencyRef,
709
+ environment
710
+ }
711
+ });
712
+ }
713
+ void open();
714
+ return () => {
715
+ cancelled = true;
716
+ client.close();
717
+ };
718
+ }, [environment, accessTokenDep, refreshTokenDep, agencyRefDep, shareTokenDep]);
719
+ if (state === null) {
720
+ return /* @__PURE__ */ jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsx(
721
+ SessionContext.Provider,
722
+ {
723
+ value: { status: "opening", persona: "manager", agencyRef: void 0, environment },
724
+ children
725
+ }
726
+ ) });
727
+ }
728
+ return /* @__PURE__ */ jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsx(KaafilClientContext.Provider, { value: state.client, children: /* @__PURE__ */ jsx(SessionContext.Provider, { value: state.session, children }) }) });
729
+ }
730
+ function emit(onEvent, event) {
731
+ if (onEvent === void 0) {
732
+ return;
733
+ }
734
+ try {
735
+ onEvent(event);
736
+ } catch {
737
+ }
738
+ }
739
+ function TelemetryShell({ onEvent, children }) {
740
+ const session = useSession();
741
+ const serverTime = useServerTime();
742
+ const previousStatusRef = useRef(void 0);
743
+ useEffect(() => {
744
+ const previousStatus = previousStatusRef.current;
745
+ if (serverTime.sinceLastSync !== void 0) {
746
+ if (session.status === "authenticated" && previousStatus !== "authenticated") {
747
+ emit(onEvent, {
748
+ type: "session.opened",
749
+ timestamp: serverTime.now(),
750
+ persona: session.persona
751
+ });
752
+ }
753
+ if (session.status === "expired" && previousStatus !== "expired") {
754
+ emit(onEvent, {
755
+ type: "session.expired",
756
+ timestamp: serverTime.now(),
757
+ persona: session.persona
758
+ });
759
+ }
760
+ }
761
+ previousStatusRef.current = session.status;
762
+ }, [session.status, serverTime.sinceLastSync]);
763
+ return /* @__PURE__ */ jsx(Fragment$1, { children });
764
+ }
765
+ function resolveSystemTheme() {
766
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
767
+ return "light";
768
+ }
769
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
770
+ }
771
+ function ThemeShell({ theme = "system", density, children }) {
772
+ const [systemTheme, setSystemTheme] = useState(
773
+ () => theme === "system" ? resolveSystemTheme() : theme
774
+ );
775
+ useEffect(() => {
776
+ if (theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
777
+ return;
778
+ }
779
+ const query = window.matchMedia("(prefers-color-scheme: dark)");
780
+ const listener = (event) => {
781
+ setSystemTheme(event.matches ? "dark" : "light");
782
+ };
783
+ query.addEventListener("change", listener);
784
+ return () => query.removeEventListener("change", listener);
785
+ }, [theme]);
786
+ const resolvedTheme = theme === "system" ? systemTheme : theme;
787
+ const value = useMemo(() => ({ theme: resolvedTheme, density }), [resolvedTheme, density]);
788
+ return /* @__PURE__ */ jsx(ThemeAttributesContext.Provider, { value, children });
789
+ }
790
+ var DefaultCapabilityViewsContext = createContext({});
791
+ function useDefaultCapabilityViews() {
792
+ return useContext(DefaultCapabilityViewsContext);
793
+ }
794
+ function KaafilUIKitProvider(props) {
795
+ const {
796
+ environment,
797
+ onSessionExpired,
798
+ density,
799
+ theme,
800
+ brand,
801
+ locale,
802
+ isolation,
803
+ onEvent,
804
+ storage,
805
+ blob,
806
+ conflictResolver,
807
+ readEntity,
808
+ offlineScope,
809
+ seedConfig,
810
+ defaultCapabilityViews,
811
+ children,
812
+ ...credential
813
+ } = props;
814
+ const inner = /* @__PURE__ */ jsx(DefaultCapabilityViewsContext.Provider, { value: defaultCapabilityViews ?? {}, children: /* @__PURE__ */ jsx(ConfigShell, { seedConfig, children: /* @__PURE__ */ jsx(
815
+ BrandShell,
816
+ {
817
+ appName: brand?.appName,
818
+ logo: brand?.logo,
819
+ logoMark: brand?.logoMark,
820
+ favicon: brand?.favicon,
821
+ headStrategy: brand?.headStrategy,
822
+ children: /* @__PURE__ */ jsx(TelemetryShell, { onEvent, children })
823
+ }
824
+ ) }) });
825
+ return /* @__PURE__ */ jsx(ErrorShell, { children: /* @__PURE__ */ jsx(ThemeShell, { theme, density, children: /* @__PURE__ */ jsx(I18nShell, { locale, children: /* @__PURE__ */ jsx(AppShell, { isolation, children: /* @__PURE__ */ jsx(
826
+ SessionShell,
827
+ {
828
+ ...credential,
829
+ environment,
830
+ onSessionExpired,
831
+ children: storage !== void 0 ? /* @__PURE__ */ jsx(
832
+ OfflineShell,
833
+ {
834
+ storage,
835
+ blob,
836
+ conflictResolver,
837
+ readEntity,
838
+ scope: offlineScope,
839
+ children: inner
840
+ }
841
+ ) : inner
842
+ }
843
+ ) }) }) }) });
844
+ }
845
+ var HAZARD_LABELS = {
846
+ "global-box-sizing-reset": "A global box-sizing reset escapes this widget's scope.",
847
+ "global-button-input-unset": "A global button/input unset rule is active.",
848
+ "tailwind-preflight-after-ours": "A Tailwind preflight is loaded after this widget's CSS.",
849
+ "global-margin-padding-reset": "A global margin/padding reset is active.",
850
+ "conflicting-layer-order": "A conflicting @layer declaration order was detected.",
851
+ "global-img-max-width": "A global img max-width rule fights this widget's media components.",
852
+ "host-css-reset-library": "A host-level CSS reset library (e.g. normalize.css) loads after this widget's CSS.",
853
+ "global-focus-outline-removed": "A global :focus outline removal defeats this widget's focus-visible ring."
854
+ };
855
+ function detectHazards() {
856
+ if (typeof document === "undefined") {
857
+ return [];
858
+ }
859
+ const probe = document.createElement("div");
860
+ probe.setAttribute("data-kf-host-css-probe", "");
861
+ probe.style.position = "absolute";
862
+ probe.style.visibility = "hidden";
863
+ probe.style.pointerEvents = "none";
864
+ document.body.appendChild(probe);
865
+ const button = document.createElement("button");
866
+ probe.appendChild(button);
867
+ const img = document.createElement("img");
868
+ probe.appendChild(img);
869
+ const buttonStyle = getComputedStyle(button);
870
+ const imgStyle = getComputedStyle(img);
871
+ const probeStyle = getComputedStyle(probe);
872
+ const hazards = [];
873
+ if (probeStyle.boxSizing !== "border-box" && probeStyle.boxSizing !== "content-box") {
874
+ hazards.push("global-box-sizing-reset");
875
+ }
876
+ if (buttonStyle.appearance === "none" && buttonStyle.border === "0px none") {
877
+ hazards.push("global-button-input-unset");
878
+ }
879
+ if (probeStyle.margin !== "" && probeStyle.margin === "0px" && probeStyle.padding === "0px") {
880
+ hazards.push("global-margin-padding-reset");
881
+ }
882
+ if (imgStyle.maxWidth === "100%") {
883
+ hazards.push("global-img-max-width");
884
+ }
885
+ if (buttonStyle.outlineStyle === "none") {
886
+ hazards.push("global-focus-outline-removed");
887
+ }
888
+ document.body.removeChild(probe);
889
+ return hazards;
890
+ }
891
+ function HostCssCompatibilityProbe({
892
+ style
893
+ } = {}) {
894
+ const chrome = useKaafilChrome();
895
+ const [hazards, setHazards] = useState(null);
896
+ useEffect(() => {
897
+ if (isDevelopment()) {
898
+ setHazards(detectHazards());
899
+ }
900
+ }, []);
901
+ if (!isDevelopment() || hazards === null) {
902
+ return null;
903
+ }
904
+ return /* @__PURE__ */ jsxs(
905
+ "div",
906
+ {
907
+ style: tokenStyle(style, {
908
+ border: "1px solid #999",
909
+ padding: "0.75rem",
910
+ borderRadius: "4px"
911
+ }),
912
+ children: [
913
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontWeight: 600 }, children: chrome.t("probe.hostCss.title") }),
914
+ hazards.length === 0 ? /* @__PURE__ */ jsx("p", { style: { margin: "0.5rem 0 0" }, children: chrome.t("probe.hostCss.clean") }) : /* @__PURE__ */ jsx("ul", { style: { margin: "0.5rem 0 0" }, children: hazards.map((hazard) => /* @__PURE__ */ jsx("li", { children: HAZARD_LABELS[hazard] }, hazard)) }),
915
+ hazards.length > 0 ? /* @__PURE__ */ jsxs("p", { style: { margin: "0.5rem 0 0" }, children: [
916
+ "Recommended: pass ",
917
+ /* @__PURE__ */ jsx("code", { children: 'isolation="shadow"' }),
918
+ " to <KaafilUIKitProvider> (05-theming-and-branding.md \xA77, rung 2)."
919
+ ] }) : null
920
+ ]
921
+ }
922
+ );
923
+ }
924
+ function KaafilSessionProbe({
925
+ expectedEnvironment,
926
+ style
927
+ }) {
928
+ const session = useSession();
929
+ const chrome = useKaafilChrome();
930
+ if (session.status === "expired") {
931
+ return /* @__PURE__ */ jsx(
932
+ "div",
933
+ {
934
+ role: "status",
935
+ style: tokenStyle(style, {
936
+ border: "1px solid #c00",
937
+ padding: "0.75rem",
938
+ borderRadius: "4px"
939
+ }),
940
+ children: "Tokens invalid or already expired at mount \u2014 the values handed to <KaafilUIKitProvider> were rejected before a successful open (00-decisions.md U-014)."
941
+ }
942
+ );
943
+ }
944
+ if (expectedEnvironment !== void 0 && session.status === "authenticated" && session.environment !== expectedEnvironment) {
945
+ return /* @__PURE__ */ jsxs(
946
+ "div",
947
+ {
948
+ role: "status",
949
+ style: tokenStyle(style, {
950
+ border: "1px solid #c00",
951
+ padding: "0.75rem",
952
+ borderRadius: "4px"
953
+ }),
954
+ children: [
955
+ 'Wrong environment \u2014 expected "',
956
+ expectedEnvironment,
957
+ '" but the opened credential is "',
958
+ session.environment,
959
+ '"',
960
+ session.environment === "test" && expectedEnvironment === "live" ? " (test key on live)." : "."
961
+ ]
962
+ }
963
+ );
964
+ }
965
+ if (session.status === "opening") {
966
+ return /* @__PURE__ */ jsx("div", { role: "status", style: tokenStyle(style), children: chrome.t("chrome.loading") });
967
+ }
968
+ return /* @__PURE__ */ jsxs(
969
+ "div",
970
+ {
971
+ style: tokenStyle(style, {
972
+ border: "1px solid #0a0",
973
+ padding: "0.75rem",
974
+ borderRadius: "4px"
975
+ }),
976
+ children: [
977
+ /* @__PURE__ */ jsx("p", { style: { margin: 0 }, children: chrome.t("probe.session.ok") }),
978
+ /* @__PURE__ */ jsxs("dl", { style: { margin: "0.5rem 0 0" }, children: [
979
+ /* @__PURE__ */ jsx("dt", { children: chrome.t("probe.session.credentialKind") }),
980
+ /* @__PURE__ */ jsx("dd", { children: session.persona }),
981
+ /* @__PURE__ */ jsx("dt", { children: chrome.t("probe.session.environment") }),
982
+ /* @__PURE__ */ jsx("dd", { children: session.environment }),
983
+ session.agencyRef !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
984
+ /* @__PURE__ */ jsx("dt", { children: chrome.t("probe.session.agency") }),
985
+ /* @__PURE__ */ jsx("dd", { children: session.agencyRef })
986
+ ] }) : null
987
+ ] })
988
+ ]
989
+ }
990
+ );
991
+ }
992
+
993
+ export { AppShell, ConfigShell, ErrorShell, HostCssCompatibilityProbe, KaafilSessionProbe, KaafilUIKitProvider, NotImplementedError, OfflineShell, SessionShell, TelemetryShell, ThemeShell, useBlobStatus, useDefaultCapabilityViews, useFeedbackNps, useJourney, useResolvedSetting, useSnapshotEntity, useStaleness, useTreks };
994
+ //# sourceMappingURL=index.js.map
995
+ //# sourceMappingURL=index.js.map