kaafil-react-uikit 0.4.0 → 0.4.2

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 (57) hide show
  1. package/CHANGELOG.md +33 -2
  2. package/dist/admin/index.cjs +355 -353
  3. package/dist/admin/index.cjs.map +1 -1
  4. package/dist/admin/index.js +16 -14
  5. package/dist/admin/index.js.map +1 -1
  6. package/dist/{chunk-WPQB7JWS.js → chunk-3E2FN5JJ.js} +3 -3
  7. package/dist/{chunk-WPQB7JWS.js.map → chunk-3E2FN5JJ.js.map} +1 -1
  8. package/dist/{chunk-2XW5EIMS.cjs → chunk-3RZDHDEY.cjs} +17 -17
  9. package/dist/{chunk-2XW5EIMS.cjs.map → chunk-3RZDHDEY.cjs.map} +1 -1
  10. package/dist/chunk-62HCQWZL.cjs +12 -0
  11. package/dist/chunk-62HCQWZL.cjs.map +1 -0
  12. package/dist/{chunk-7G6IENKN.js → chunk-6FUVFVYY.js} +99 -6
  13. package/dist/chunk-6FUVFVYY.js.map +1 -0
  14. package/dist/{chunk-E6ER25BG.js → chunk-762SWUEG.js} +3 -3
  15. package/dist/{chunk-E6ER25BG.js.map → chunk-762SWUEG.js.map} +1 -1
  16. package/dist/{chunk-3N2EQ2KC.cjs → chunk-CK3L6Y43.cjs} +100 -4
  17. package/dist/chunk-CK3L6Y43.cjs.map +1 -0
  18. package/dist/{chunk-A7C74SJT.cjs → chunk-DI77H7ED.cjs} +83 -83
  19. package/dist/{chunk-A7C74SJT.cjs.map → chunk-DI77H7ED.cjs.map} +1 -1
  20. package/dist/{chunk-3BEQYIFU.js → chunk-EDLIJSMR.js} +5 -5
  21. package/dist/{chunk-3BEQYIFU.js.map → chunk-EDLIJSMR.js.map} +1 -1
  22. package/dist/{chunk-RBIEMGHT.js → chunk-ITGVRN2S.js} +3 -3
  23. package/dist/{chunk-RBIEMGHT.js.map → chunk-ITGVRN2S.js.map} +1 -1
  24. package/dist/{chunk-6BY2NPBZ.cjs → chunk-LO3GQFQ6.cjs} +4 -4
  25. package/dist/{chunk-6BY2NPBZ.cjs.map → chunk-LO3GQFQ6.cjs.map} +1 -1
  26. package/dist/{chunk-7356B6YS.cjs → chunk-QD4Z5DRT.cjs} +12 -12
  27. package/dist/{chunk-7356B6YS.cjs.map → chunk-QD4Z5DRT.cjs.map} +1 -1
  28. package/dist/{chunk-2LMFSKZU.js → chunk-QMUIZHJO.js} +510 -16
  29. package/dist/chunk-QMUIZHJO.js.map +1 -0
  30. package/dist/{chunk-KTEXDGAA.js → chunk-RW6TJMRK.js} +3 -3
  31. package/dist/{chunk-KTEXDGAA.js.map → chunk-RW6TJMRK.js.map} +1 -1
  32. package/dist/{chunk-XBLAVNP3.cjs → chunk-V6UQ6GIM.cjs} +551 -48
  33. package/dist/chunk-V6UQ6GIM.cjs.map +1 -0
  34. package/dist/chunk-XU7GP53M.js +10 -0
  35. package/dist/chunk-XU7GP53M.js.map +1 -0
  36. package/dist/{chunk-KETEED2T.cjs → chunk-XYIOM75D.cjs} +9 -9
  37. package/dist/{chunk-KETEED2T.cjs.map → chunk-XYIOM75D.cjs.map} +1 -1
  38. package/dist/core/index.cjs +153 -613
  39. package/dist/core/index.cjs.map +1 -1
  40. package/dist/core/index.d.cts +36 -1
  41. package/dist/core/index.d.ts +36 -1
  42. package/dist/core/index.js +21 -511
  43. package/dist/core/index.js.map +1 -1
  44. package/dist/index.css +1 -1
  45. package/dist/manager/index.cjs +239 -239
  46. package/dist/manager/index.js +6 -6
  47. package/dist/traveller/index.cjs +35 -35
  48. package/dist/traveller/index.js +5 -5
  49. package/package.json +1 -1
  50. package/dist/chunk-2LMFSKZU.js.map +0 -1
  51. package/dist/chunk-3N2EQ2KC.cjs.map +0 -1
  52. package/dist/chunk-4QYI7TOF.cjs +0 -110
  53. package/dist/chunk-4QYI7TOF.cjs.map +0 -1
  54. package/dist/chunk-7G6IENKN.js.map +0 -1
  55. package/dist/chunk-CLHAJBJS.js +0 -105
  56. package/dist/chunk-CLHAJBJS.js.map +0 -1
  57. package/dist/chunk-XBLAVNP3.cjs.map +0 -1
@@ -1,20 +1,17 @@
1
- export { useConflicts, useManagerMe, useNotifications } from '../chunk-KTEXDGAA.js';
2
- import { useResolvedSetting } from '../chunk-2LMFSKZU.js';
3
- export { CLOSEOUT_ACTION_TAB, fromSearchParams, isTripTabKey, resolveBlockerDeepLink, toSearchParams, useAgencyAdminMe, useAgencyChecklistTemplates, useAgencyForms, useAgencyJourneyTriggers, useAgencyManagerProfile, useAgencySettings, useAgencyTrip, useAgencyTripManifest, useAgencyTrips, useBookings, useCapabilityStatuses, useDirectories, usePaginatedList, useResolvedSetting, useShareLinks, useTravellerFormResponses } from '../chunk-2LMFSKZU.js';
4
- import { createDomainHook, useSnapshotList, classifyError } from '../chunk-WPQB7JWS.js';
5
- export { ERROR_HANDLING_PATH, classifyError, useChecklists, useCloseout, useCollections, useExpenses, useFiles, useFloat, useForms, useItinerary, useManagerToday, useManagers, useParties, usePickups, useRooming, useSeating, useSnapshotList, useTravellerProfile, useVendors } from '../chunk-WPQB7JWS.js';
6
- export { useShareForms, useShareSnapshot } from '../chunk-3BEQYIFU.js';
7
- import { BrandShell } from '../chunk-CLHAJBJS.js';
8
- export { BrandShell, useKaafilBrand, useKaafilShareMeta, useOfflineEngine } from '../chunk-CLHAJBJS.js';
9
- import { useServerTime } from '../chunk-RBIEMGHT.js';
10
- export { useServerTime } from '../chunk-RBIEMGHT.js';
11
- import { useKaafilClient, useOfflineMutation, OfflineEngineContext, useOfflineEvent, usePersona, useCapabilityRows, isDevelopment, deriveCapabilityTriple, tokenStyle, ConfigContext, KaafilClientContext, useSession, SessionContext, I18nShell, useKaafilChrome } from '../chunk-7G6IENKN.js';
12
- export { I18nShell, createRegistry, useCapabilities, useCapability, useKaafilChrome, useKaafilClient, useOfflineEvent, useOfflineMutation, useOutboxStatus, usePersona, useSession } from '../chunk-7G6IENKN.js';
13
- import { SyncOpMethod, KaafilClient } from 'kaafil-js/client';
1
+ export { useConflicts, useManagerMe, useNotifications } from '../chunk-RW6TJMRK.js';
2
+ export { AppShell, CLOSEOUT_ACTION_TAB, ConfigShell, ErrorShell, KaafilUIKitProvider, OfflineShell, SessionShell, TelemetryShell, ThemeShell, fromSearchParams, isTripTabKey, resolveBlockerDeepLink, toSearchParams, useAgencyAdminMe, useAgencyChecklistTemplates, useAgencyForms, useAgencyJourneyTriggers, useAgencyManagerProfile, useAgencySettings, useAgencyTrip, useAgencyTripManifest, useAgencyTrips, useBookings, useBuildShareUrl, useCapabilityStatuses, useDefaultCapabilityViews, useDirectories, usePaginatedList, useShareLinks, useTravellerFormResponses } from '../chunk-QMUIZHJO.js';
3
+ import { createDomainHook, useSnapshotList } from '../chunk-3E2FN5JJ.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-3E2FN5JJ.js';
5
+ export { useShareForms, useShareSnapshot } from '../chunk-EDLIJSMR.js';
6
+ export { useOfflineEngine } from '../chunk-XU7GP53M.js';
7
+ import { useServerTime } from '../chunk-ITGVRN2S.js';
8
+ export { useServerTime } from '../chunk-ITGVRN2S.js';
9
+ import { useKaafilClient, useOfflineMutation, OfflineEngineContext, useOfflineEvent, usePersona, useCapabilityRows, isDevelopment, deriveCapabilityTriple, useRequiredContext, ConfigContext, useKaafilChrome, tokenStyle, useSession } from '../chunk-6FUVFVYY.js';
10
+ export { BrandShell, I18nShell, createRegistry, useCapabilities, useCapability, useKaafilBrand, useKaafilChrome, useKaafilClient, useKaafilShareMeta, useOfflineEvent, useOfflineMutation, useOutboxStatus, usePersona, useSession } from '../chunk-6FUVFVYY.js';
11
+ import { SyncOpMethod } from 'kaafil-js/client';
14
12
  export { UnsatisfiableSchemeError } from 'kaafil-js/client';
15
- import { useState, useCallback, useEffect, createContext, useContext, useRef, useMemo, Component, Fragment } from 'react';
16
- import { createPortal } from 'react-dom';
17
- import { jsx, Fragment as Fragment$1, jsxs } from 'react/jsx-runtime';
13
+ import { useState, useCallback, useEffect, useContext, useRef } from 'react';
14
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
18
15
 
19
16
  var NotImplementedError = class _NotImplementedError extends Error {
20
17
  hookName;
@@ -159,6 +156,12 @@ function useJourney(tripRef) {
159
156
  }
160
157
  };
161
158
  }
159
+
160
+ // src/core/hooks/useResolvedSetting.ts
161
+ function useResolvedSetting(key) {
162
+ const config = useRequiredContext(ConfigContext, "useResolvedSetting", "ConfigShell");
163
+ return config.resolveSetting(key);
164
+ }
162
165
  function useSnapshotEntity(tripRef, listName, id) {
163
166
  const engine = useContext(OfflineEngineContext);
164
167
  const { rows } = useSnapshotList(tripRef, listName);
@@ -356,499 +359,6 @@ var useTreksInternal = createDomainHook("treks", (tripRef) => {
356
359
  function useTreks(tripRef) {
357
360
  return useTreksInternal(tripRef);
358
361
  }
359
- var ThemeAttributesContext = createContext(null);
360
- var FAMILY_DEFAULT_FRAME = {
361
- admin: "desk",
362
- manager: "field",
363
- traveller: "document"
364
- };
365
- var DESK_MINIMUM_CONTAINER_WIDTH_PX = 640;
366
- function ShadowIsolationBoundary({
367
- className,
368
- children
369
- }) {
370
- const hostRef = useRef(null);
371
- const [shadowContainer, setShadowContainer] = useState(null);
372
- useEffect(() => {
373
- const host = hostRef.current;
374
- if (host === null) {
375
- return;
376
- }
377
- const shadow = host.shadowRoot ?? host.attachShadow({ mode: "open" });
378
- let container = shadow.querySelector("div[data-kf-shadow-content]");
379
- if (container === null) {
380
- container = document.createElement("div");
381
- container.setAttribute("data-kf-shadow-content", "");
382
- shadow.appendChild(container);
383
- }
384
- setShadowContainer(container);
385
- }, []);
386
- return /* @__PURE__ */ jsx("div", { ref: hostRef, className, "data-kf-isolation": "shadow", children: shadowContainer !== null ? createPortal(children, shadowContainer) : null });
387
- }
388
- function useDeskMinimumWidthWarning(rootRef, frame) {
389
- useEffect(() => {
390
- if (frame !== "desk" || !isDevelopment() || typeof ResizeObserver === "undefined") {
391
- return;
392
- }
393
- const node = rootRef.current;
394
- if (node === null) {
395
- return;
396
- }
397
- let warned = false;
398
- const observer = new ResizeObserver((entries) => {
399
- const entry = entries[0];
400
- if (entry === void 0 || warned) {
401
- return;
402
- }
403
- if (entry.contentRect.width < DESK_MINIMUM_CONTAINER_WIDTH_PX) {
404
- warned = true;
405
- console.warn(
406
- `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.`
407
- );
408
- }
409
- });
410
- observer.observe(node);
411
- return () => observer.disconnect();
412
- }, [rootRef, frame]);
413
- }
414
- function useUnfilledConnectivitySlotWarning(frame, connectivitySlot) {
415
- useEffect(() => {
416
- if (frame === "field" && connectivitySlot === void 0 && isDevelopment()) {
417
- console.warn(
418
- `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).`
419
- );
420
- }
421
- }, [frame, connectivitySlot]);
422
- }
423
- function AppShell({
424
- frame,
425
- family,
426
- isolation = "scoped",
427
- navSlot,
428
- actionBarSlot,
429
- connectivitySlot,
430
- children,
431
- style
432
- }) {
433
- const themeAttributes = useContext(ThemeAttributesContext);
434
- const rootRef = useRef(null);
435
- const resolvedFrame = frame ?? (family !== void 0 ? FAMILY_DEFAULT_FRAME[family] : "document");
436
- useDeskMinimumWidthWarning(rootRef, resolvedFrame);
437
- useUnfilledConnectivitySlotWarning(resolvedFrame, connectivitySlot);
438
- const dataAttributes = {
439
- "data-kf-frame": resolvedFrame
440
- };
441
- if (family !== void 0) {
442
- dataAttributes["data-kf-family"] = family;
443
- }
444
- if (themeAttributes !== null) {
445
- dataAttributes["data-kf-theme"] = themeAttributes.theme;
446
- if (themeAttributes.density !== void 0) {
447
- dataAttributes["data-kf-density"] = themeAttributes.density;
448
- }
449
- }
450
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
451
- resolvedFrame === "desk" && navSlot !== void 0 ? /* @__PURE__ */ jsx("div", { className: "kf-app-shell__nav", children: navSlot }) : null,
452
- /* @__PURE__ */ jsx("div", { className: "kf-app-shell__content", children }),
453
- resolvedFrame === "field" && actionBarSlot !== void 0 ? /* @__PURE__ */ jsx("div", { className: "kf-app-shell__action-bar", children: actionBarSlot }) : null,
454
- resolvedFrame === "field" && connectivitySlot !== void 0 ? /* @__PURE__ */ jsx("div", { className: "kf-app-shell__connectivity", children: connectivitySlot }) : null,
455
- /* @__PURE__ */ jsx("div", { className: "kf-app-shell__live-region", role: "status", "aria-live": "polite" })
456
- ] });
457
- if (isolation === "shadow") {
458
- return /* @__PURE__ */ jsx(
459
- "div",
460
- {
461
- ref: rootRef,
462
- className: "kf-root",
463
- "data-kf-isolation": "shadow",
464
- ...dataAttributes,
465
- style: tokenStyle(style),
466
- children: /* @__PURE__ */ jsx(ShadowIsolationBoundary, { className: "kf-app-shell__shadow-host", children: content })
467
- }
468
- );
469
- }
470
- return /* @__PURE__ */ jsx(
471
- "div",
472
- {
473
- ref: rootRef,
474
- className: "kf-root",
475
- "data-kf-isolation": "scoped",
476
- ...dataAttributes,
477
- style: tokenStyle(style),
478
- children: content
479
- }
480
- );
481
- }
482
- function ConfigShell({ seedConfig = {}, children }) {
483
- const value = useMemo(
484
- () => ({
485
- resolveSetting(key) {
486
- const agencyValue = seedConfig.agency?.[key];
487
- if (agencyValue !== void 0) {
488
- return agencyValue;
489
- }
490
- const tenantValue = seedConfig.tenant?.[key];
491
- return tenantValue === void 0 ? void 0 : tenantValue;
492
- }
493
- }),
494
- [seedConfig.agency, seedConfig.tenant]
495
- );
496
- return /* @__PURE__ */ jsx(ConfigContext.Provider, { value, children });
497
- }
498
- function classifyForFallback(error) {
499
- const classification = classifyError(error);
500
- if (classification.code === "RESOURCE_NOT_FOUND") {
501
- return { classification: "isolation", code: classification.code };
502
- }
503
- if (classification.path === "parked" || classification.unsatisfiableScheme) {
504
- return { classification: "parked", code: classification.code };
505
- }
506
- return { classification: "retryable", code: classification.code };
507
- }
508
- var FALLBACK_STYLE = {
509
- fontFamily: "system-ui, sans-serif",
510
- padding: "1.5rem",
511
- border: "1px solid #999",
512
- borderRadius: "4px",
513
- color: "#1a1a1a",
514
- background: "#fff"
515
- };
516
- function DefaultFallback({
517
- ctx,
518
- onRetry
519
- }) {
520
- const role = ctx.classification === "retryable" ? "status" : "alert";
521
- const ariaLive = ctx.classification === "retryable" ? "polite" : "assertive";
522
- const message = ctx.classification === "isolation" ? "Not found." : ctx.classification === "parked" ? "This action can't be completed right now." : "Something went wrong.";
523
- return /* @__PURE__ */ jsxs("div", { style: FALLBACK_STYLE, role, "aria-live": ariaLive, children: [
524
- /* @__PURE__ */ jsx("p", { style: { margin: 0 }, children: message }),
525
- ctx.classification === "retryable" ? /* @__PURE__ */ jsx("button", { type: "button", onClick: onRetry, style: { marginTop: "0.75rem" }, children: "Try again" }) : null
526
- ] });
527
- }
528
- var ErrorShell = class extends Component {
529
- state = { caught: null, retryKey: 0 };
530
- static getDerivedStateFromError(error) {
531
- return { caught: { error } };
532
- }
533
- handleRetry = () => {
534
- this.setState((current) => ({ caught: null, retryKey: current.retryKey + 1 }));
535
- };
536
- render() {
537
- if (this.state.caught !== null) {
538
- const ctx = classifyForFallback(this.state.caught.error);
539
- if (this.props.fallbackSlot !== void 0) {
540
- return this.props.fallbackSlot(ctx);
541
- }
542
- return /* @__PURE__ */ jsx(DefaultFallback, { ctx, onRetry: this.handleRetry });
543
- }
544
- return /* @__PURE__ */ jsx(Fragment, { children: this.props.children }, this.state.retryKey);
545
- }
546
- };
547
- var SessionExpiryBridgeContext = createContext(void 0);
548
- function OfflineShell({
549
- storage,
550
- blob,
551
- conflictResolver,
552
- readEntity,
553
- scope,
554
- children
555
- }) {
556
- const client = useContext(KaafilClientContext);
557
- const persona = usePersona();
558
- const session = useSession();
559
- const reportExpired = useContext(SessionExpiryBridgeContext);
560
- const [engine, setEngine] = useState(null);
561
- const engineRef = useRef(null);
562
- const derivedScope = scope ?? `${persona}:${session.agencyRef ?? "share"}`;
563
- useEffect(() => {
564
- if (session.status !== "authenticated" || client === null) {
565
- return;
566
- }
567
- const newEngine = client.openOffline({
568
- storage,
569
- scope: derivedScope,
570
- ...readEntity !== void 0 ? { readEntity } : {},
571
- ...conflictResolver !== void 0 ? { conflictResolver } : {},
572
- ...blob !== void 0 ? { blob } : {}
573
- // GAP flagged in this phase's report: a share session's local
574
- // `expiresAt` enforcement (`OpenOfflineOptions.share`,
575
- // `07-offline-and-sync.md §8`) needs an `expiresAt` this shell has no
576
- // source for yet — it is not on `useSession()`'s derived shape and no
577
- // prop carries it. Omitted here rather than guessed; a share engine
578
- // opens without the local expiry/grace/purge enforcement until that
579
- // value has a wire source.
580
- });
581
- engineRef.current = newEngine;
582
- let opened = false;
583
- let disposed = false;
584
- void newEngine.open().then(() => {
585
- opened = true;
586
- if (disposed) {
587
- newEngine.close();
588
- return;
589
- }
590
- if (engineRef.current === newEngine) setEngine(newEngine);
591
- }).catch(() => {
592
- if (!disposed && engineRef.current === newEngine) setEngine(null);
593
- });
594
- const unsubscribeSessionExpired = persona !== "share" ? newEngine.events.on("session.expired", () => reportExpired?.("session")) : void 0;
595
- const unsubscribeShareExpired = persona === "share" ? newEngine.events.on("share.expired", () => reportExpired?.("share")) : void 0;
596
- const unsubscribeShareRevoked = persona === "share" ? newEngine.events.on("share.revoked", () => reportExpired?.("share")) : void 0;
597
- return () => {
598
- unsubscribeSessionExpired?.();
599
- unsubscribeShareExpired?.();
600
- unsubscribeShareRevoked?.();
601
- disposed = true;
602
- if (opened) newEngine.close();
603
- if (engineRef.current === newEngine) {
604
- engineRef.current = null;
605
- }
606
- };
607
- }, [client, derivedScope, session.status, persona, reportExpired]);
608
- return /* @__PURE__ */ jsx(OfflineEngineContext.Provider, { value: engine, children });
609
- }
610
-
611
- // src/core/shells/internal/jwtKind.ts
612
- function base64UrlDecode(segment) {
613
- const padded = segment.replace(/-/g, "+").replace(/_/g, "/");
614
- const withPadding = padded + "=".repeat((4 - padded.length % 4) % 4);
615
- return atob(withPadding);
616
- }
617
- function decodeManagerOrAgencyAdminKind(accessToken) {
618
- const segments = accessToken.split(".");
619
- const payloadSegment = segments[1];
620
- if (segments.length !== 3 || payloadSegment === void 0) {
621
- throw new Error(
622
- 'SessionShell could not parse "accessToken" as a JWT \u2014 it does not have the three dot-separated segments every manager/agencyAdmin session token has.'
623
- );
624
- }
625
- let claim;
626
- try {
627
- claim = JSON.parse(base64UrlDecode(payloadSegment));
628
- } catch {
629
- throw new Error(
630
- `SessionShell could not decode "accessToken"'s payload segment as JSON \u2014 the value handed to <KaafilUIKitProvider accessToken> is not a well-formed JWT.`
631
- );
632
- }
633
- const kind = claim.kind;
634
- if (kind === "agencyAdmin") {
635
- return "agencyAdmin";
636
- }
637
- if (kind === "managerSession" || kind === "manager") {
638
- return "managerSession";
639
- }
640
- throw new Error(
641
- `SessionShell read an unrecognised "kind" claim ("${String(kind)}") off "accessToken" \u2014 expected the manager or agencyAdmin session JWT shape (00-decisions.md U-003).`
642
- );
643
- }
644
- async function resolveCredential(props) {
645
- if (props.credentialResolver !== void 0) {
646
- const resolved = await props.credentialResolver();
647
- if ("shareToken" in resolved) {
648
- return { kind: "share", shareToken: resolved.shareToken };
649
- }
650
- const kind2 = decodeManagerOrAgencyAdminKind(resolved.accessToken) === "agencyAdmin" ? "agencyAdmin" : "manager";
651
- return { kind: kind2, ...resolved };
652
- }
653
- if (props.shareToken !== void 0) {
654
- return { kind: "share", shareToken: props.shareToken };
655
- }
656
- const kind = decodeManagerOrAgencyAdminKind(props.accessToken) === "agencyAdmin" ? "agencyAdmin" : "manager";
657
- return {
658
- kind,
659
- accessToken: props.accessToken,
660
- refreshToken: props.refreshToken,
661
- agencyRef: props.agencyRef
662
- };
663
- }
664
- function SessionShell(props) {
665
- const { environment = "live", onRefresh, onSessionExpired, children } = props;
666
- const [state, setState] = useState(null);
667
- const expiredCallbackFiredRef = useRef(false);
668
- const currentPersonaRef = useRef("manager");
669
- const reportExpired = useCallback(() => {
670
- if (expiredCallbackFiredRef.current) {
671
- return;
672
- }
673
- expiredCallbackFiredRef.current = true;
674
- onSessionExpired?.(currentPersonaRef.current);
675
- setState(
676
- (current) => current === null ? current : { ...current, session: { ...current.session, status: "expired" } }
677
- );
678
- }, [onSessionExpired]);
679
- const accessTokenDep = "accessToken" in props ? props.accessToken : void 0;
680
- const refreshTokenDep = "refreshToken" in props ? props.refreshToken : void 0;
681
- const agencyRefDep = "agencyRef" in props ? props.agencyRef : void 0;
682
- const shareTokenDep = "shareToken" in props ? props.shareToken : void 0;
683
- useEffect(() => {
684
- let cancelled = false;
685
- const client = new KaafilClient({ environment });
686
- expiredCallbackFiredRef.current = false;
687
- async function open() {
688
- const credential = await resolveCredential(props);
689
- if (cancelled) {
690
- return;
691
- }
692
- currentPersonaRef.current = credential.kind;
693
- if (credential.kind === "share") {
694
- client.share.open({ token: credential.shareToken });
695
- } else if (credential.kind === "agencyAdmin") {
696
- client.admin.open({
697
- accessToken: credential.accessToken,
698
- refreshToken: credential.refreshToken,
699
- agencyRef: credential.agencyRef,
700
- ...onRefresh !== void 0 ? { onRefresh } : {}
701
- });
702
- } else {
703
- client.session.open({
704
- accessToken: credential.accessToken,
705
- refreshToken: credential.refreshToken,
706
- agencyRef: credential.agencyRef,
707
- ...onRefresh !== void 0 ? { onRefresh } : {}
708
- });
709
- }
710
- setState({
711
- client,
712
- session: {
713
- status: "authenticated",
714
- persona: credential.kind,
715
- agencyRef: credential.agencyRef,
716
- environment
717
- }
718
- });
719
- }
720
- void open();
721
- return () => {
722
- cancelled = true;
723
- client.close();
724
- };
725
- }, [environment, accessTokenDep, refreshTokenDep, agencyRefDep, shareTokenDep]);
726
- if (state === null) {
727
- return /* @__PURE__ */ jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsx(
728
- SessionContext.Provider,
729
- {
730
- value: { status: "opening", persona: "manager", agencyRef: void 0, environment },
731
- children
732
- }
733
- ) });
734
- }
735
- return /* @__PURE__ */ jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsx(KaafilClientContext.Provider, { value: state.client, children: /* @__PURE__ */ jsx(SessionContext.Provider, { value: state.session, children }) }) });
736
- }
737
- function emit(onEvent, event) {
738
- if (onEvent === void 0) {
739
- return;
740
- }
741
- try {
742
- onEvent(event);
743
- } catch {
744
- }
745
- }
746
- function TelemetryShell({ onEvent, children }) {
747
- const session = useSession();
748
- const serverTime = useServerTime();
749
- const previousStatusRef = useRef(void 0);
750
- useEffect(() => {
751
- const previousStatus = previousStatusRef.current;
752
- if (serverTime.sinceLastSync !== void 0) {
753
- if (session.status === "authenticated" && previousStatus !== "authenticated") {
754
- emit(onEvent, {
755
- type: "session.opened",
756
- timestamp: serverTime.now(),
757
- persona: session.persona
758
- });
759
- }
760
- if (session.status === "expired" && previousStatus !== "expired") {
761
- emit(onEvent, {
762
- type: "session.expired",
763
- timestamp: serverTime.now(),
764
- persona: session.persona
765
- });
766
- }
767
- }
768
- previousStatusRef.current = session.status;
769
- }, [session.status, serverTime.sinceLastSync]);
770
- return /* @__PURE__ */ jsx(Fragment$1, { children });
771
- }
772
- function resolveSystemTheme() {
773
- if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
774
- return "light";
775
- }
776
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
777
- }
778
- function ThemeShell({ theme = "system", density, children }) {
779
- const [systemTheme, setSystemTheme] = useState(
780
- () => theme === "system" ? resolveSystemTheme() : theme
781
- );
782
- useEffect(() => {
783
- if (theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
784
- return;
785
- }
786
- const query = window.matchMedia("(prefers-color-scheme: dark)");
787
- const listener = (event) => {
788
- setSystemTheme(event.matches ? "dark" : "light");
789
- };
790
- query.addEventListener("change", listener);
791
- return () => query.removeEventListener("change", listener);
792
- }, [theme]);
793
- const resolvedTheme = theme === "system" ? systemTheme : theme;
794
- const value = useMemo(() => ({ theme: resolvedTheme, density }), [resolvedTheme, density]);
795
- return /* @__PURE__ */ jsx(ThemeAttributesContext.Provider, { value, children });
796
- }
797
- var DefaultCapabilityViewsContext = createContext({});
798
- function useDefaultCapabilityViews() {
799
- return useContext(DefaultCapabilityViewsContext);
800
- }
801
- function KaafilUIKitProvider(props) {
802
- const {
803
- environment,
804
- onSessionExpired,
805
- density,
806
- theme,
807
- brand,
808
- locale,
809
- isolation,
810
- onEvent,
811
- storage,
812
- blob,
813
- conflictResolver,
814
- readEntity,
815
- offlineScope,
816
- seedConfig,
817
- defaultCapabilityViews,
818
- children,
819
- ...credential
820
- } = props;
821
- const inner = /* @__PURE__ */ jsx(DefaultCapabilityViewsContext.Provider, { value: defaultCapabilityViews ?? {}, children: /* @__PURE__ */ jsx(ConfigShell, { seedConfig, children: /* @__PURE__ */ jsx(
822
- BrandShell,
823
- {
824
- appName: brand?.appName,
825
- logo: brand?.logo,
826
- logoMark: brand?.logoMark,
827
- favicon: brand?.favicon,
828
- headStrategy: brand?.headStrategy,
829
- children: /* @__PURE__ */ jsx(TelemetryShell, { onEvent, children })
830
- }
831
- ) }) });
832
- return /* @__PURE__ */ jsx(ErrorShell, { children: /* @__PURE__ */ jsx(ThemeShell, { theme, density, children: /* @__PURE__ */ jsx(I18nShell, { locale, children: /* @__PURE__ */ jsx(AppShell, { isolation, children: /* @__PURE__ */ jsx(
833
- SessionShell,
834
- {
835
- ...credential,
836
- environment,
837
- onSessionExpired,
838
- children: storage !== void 0 ? /* @__PURE__ */ jsx(
839
- OfflineShell,
840
- {
841
- storage,
842
- blob,
843
- conflictResolver,
844
- readEntity,
845
- scope: offlineScope,
846
- children: inner
847
- }
848
- ) : inner
849
- }
850
- ) }) }) }) });
851
- }
852
362
  var HAZARD_LABELS = {
853
363
  "global-box-sizing-reset": "A global box-sizing reset escapes this widget's scope.",
854
364
  "global-button-input-unset": "A global button/input unset rule is active.",
@@ -987,7 +497,7 @@ function KaafilSessionProbe({
987
497
  /* @__PURE__ */ jsx("dd", { children: session.persona }),
988
498
  /* @__PURE__ */ jsx("dt", { children: chrome.t("probe.session.environment") }),
989
499
  /* @__PURE__ */ jsx("dd", { children: session.environment }),
990
- session.agencyRef !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
500
+ session.agencyRef !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
991
501
  /* @__PURE__ */ jsx("dt", { children: chrome.t("probe.session.agency") }),
992
502
  /* @__PURE__ */ jsx("dd", { children: session.agencyRef })
993
503
  ] }) : null
@@ -997,6 +507,6 @@ function KaafilSessionProbe({
997
507
  );
998
508
  }
999
509
 
1000
- export { AppShell, ConfigShell, ErrorShell, HostCssCompatibilityProbe, KaafilSessionProbe, KaafilUIKitProvider, NotImplementedError, OfflineShell, SessionShell, TelemetryShell, ThemeShell, useBlobStatus, useDefaultCapabilityViews, useFeedbackNps, useJourney, useSnapshotEntity, useStaleness, useTreks };
510
+ export { HostCssCompatibilityProbe, KaafilSessionProbe, NotImplementedError, useBlobStatus, useFeedbackNps, useJourney, useResolvedSetting, useSnapshotEntity, useStaleness, useTreks };
1001
511
  //# sourceMappingURL=index.js.map
1002
512
  //# sourceMappingURL=index.js.map