@marinoscar/platform-web 0.1.0-next.6 → 0.1.0-next.8

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 (72) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/ai/ui/index.d.ts +9 -0
  3. package/dist/ai/ui/index.d.ts.map +1 -1
  4. package/dist/ai/ui/index.js +7 -0
  5. package/dist/ai/ui/index.js.map +1 -1
  6. package/dist/ai/ui/user/AccountSignInProviderCard.d.ts +128 -0
  7. package/dist/ai/ui/user/AccountSignInProviderCard.d.ts.map +1 -0
  8. package/dist/ai/ui/user/AccountSignInProviderCard.js +87 -0
  9. package/dist/ai/ui/user/AccountSignInProviderCard.js.map +1 -0
  10. package/dist/ai/ui/user/DefaultAiModelPicker.d.ts +13 -0
  11. package/dist/ai/ui/user/DefaultAiModelPicker.d.ts.map +1 -1
  12. package/dist/ai/ui/user/DefaultAiModelPicker.js +5 -0
  13. package/dist/ai/ui/user/DefaultAiModelPicker.js.map +1 -1
  14. package/dist/ai/ui/user/KeylessProviderCard.d.ts +18 -1
  15. package/dist/ai/ui/user/KeylessProviderCard.d.ts.map +1 -1
  16. package/dist/ai/ui/user/KeylessProviderCard.js +10 -1
  17. package/dist/ai/ui/user/KeylessProviderCard.js.map +1 -1
  18. package/dist/ai/ui/user/UserAiKeyCard.d.ts +22 -0
  19. package/dist/ai/ui/user/UserAiKeyCard.d.ts.map +1 -1
  20. package/dist/ai/ui/user/UserAiKeyCard.js +5 -0
  21. package/dist/ai/ui/user/UserAiKeyCard.js.map +1 -1
  22. package/dist/ai/ui/user/aiErrorText.d.ts +10 -2
  23. package/dist/ai/ui/user/aiErrorText.d.ts.map +1 -1
  24. package/dist/ai/ui/user/aiErrorText.js +10 -2
  25. package/dist/ai/ui/user/aiErrorText.js.map +1 -1
  26. package/dist/identity/headless/index.d.ts +2 -0
  27. package/dist/identity/headless/index.d.ts.map +1 -1
  28. package/dist/identity/headless/index.js +1 -0
  29. package/dist/identity/headless/index.js.map +1 -1
  30. package/dist/identity/headless/local-identity.d.ts +63 -0
  31. package/dist/identity/headless/local-identity.d.ts.map +1 -0
  32. package/dist/identity/headless/local-identity.js +84 -0
  33. package/dist/identity/headless/local-identity.js.map +1 -0
  34. package/dist/identity/headless/types.d.ts +7 -0
  35. package/dist/identity/headless/types.d.ts.map +1 -1
  36. package/dist/identity/headless/use-permissions.d.ts +6 -1
  37. package/dist/identity/headless/use-permissions.d.ts.map +1 -1
  38. package/dist/identity/headless/use-permissions.js +24 -9
  39. package/dist/identity/headless/use-permissions.js.map +1 -1
  40. package/dist/identity/index.d.ts +1 -1
  41. package/dist/identity/index.d.ts.map +1 -1
  42. package/dist/identity/index.js +1 -1
  43. package/dist/identity/index.js.map +1 -1
  44. package/dist/shell/headless/index.d.ts +2 -0
  45. package/dist/shell/headless/index.d.ts.map +1 -1
  46. package/dist/shell/headless/index.js +1 -0
  47. package/dist/shell/headless/index.js.map +1 -1
  48. package/dist/shell/headless/preferences.d.ts +72 -0
  49. package/dist/shell/headless/preferences.d.ts.map +1 -0
  50. package/dist/shell/headless/preferences.js +83 -0
  51. package/dist/shell/headless/preferences.js.map +1 -0
  52. package/dist/shell/headless/rail-preference.d.ts.map +1 -1
  53. package/dist/shell/headless/rail-preference.js +44 -1
  54. package/dist/shell/headless/rail-preference.js.map +1 -1
  55. package/dist/shell/testing/index.d.ts +2 -0
  56. package/dist/shell/testing/index.d.ts.map +1 -0
  57. package/dist/shell/testing/index.js +6 -0
  58. package/dist/shell/testing/index.js.map +1 -0
  59. package/dist/shell/testing/shell-local-host.suite.d.ts +11 -0
  60. package/dist/shell/testing/shell-local-host.suite.d.ts.map +1 -0
  61. package/dist/shell/testing/shell-local-host.suite.js +152 -0
  62. package/dist/shell/testing/shell-local-host.suite.js.map +1 -0
  63. package/dist/shell/ui/ShellBottomNav.d.ts.map +1 -1
  64. package/dist/shell/ui/ShellBottomNav.js +14 -1
  65. package/dist/shell/ui/ShellBottomNav.js.map +1 -1
  66. package/dist/shell/ui/ShellUserMenu.d.ts +33 -1
  67. package/dist/shell/ui/ShellUserMenu.d.ts.map +1 -1
  68. package/dist/shell/ui/ShellUserMenu.js +12 -5
  69. package/dist/shell/ui/ShellUserMenu.js.map +1 -1
  70. package/dist/shell/ui/index.d.ts +1 -1
  71. package/dist/shell/ui/index.d.ts.map +1 -1
  72. package/package.json +6 -2
@@ -1,4 +1,6 @@
1
1
  export { AuthContext, AuthProvider, useAuth, useOptionalAuth } from './auth-context.js';
2
+ export { LocalIdentityProvider, createLocalAuthContextValue } from './local-identity.js';
3
+ export type { LocalIdentityInput, LocalIdentityProviderProps } from './local-identity.js';
2
4
  export { useCurrentUserExtension, userExtension } from './user-extensions.js';
3
5
  export type { AuthProviderProps } from './auth-context.js';
4
6
  export type { AuthContextValue, AuthProviderInfo, AuthRole, AuthSessionClient, AuthUser, LoginOptions, OrgMembershipSummary, OrgSummary, } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/index.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@
4
4
  // registry and the device-activation credential logic. Documented in
5
5
  // ../README.md. Explicit named exports only.
6
6
  export { AuthContext, AuthProvider, useAuth, useOptionalAuth } from './auth-context.js';
7
+ export { LocalIdentityProvider, createLocalAuthContextValue } from './local-identity.js';
7
8
  export { useCurrentUserExtension, userExtension } from './user-extensions.js';
8
9
  export { usePermissions } from './use-permissions.js';
9
10
  export { RequireAuth, RequireMultiOrg, RequirePermission, useOrgsFeature } from './guards.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/identity/headless/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,qEAAqE;AACrE,6CAA6C;AAE7C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAY9E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9F,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACjG,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AA+BxD,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAcpG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAE9F,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/identity/headless/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,qEAAqE;AACrE,6CAA6C;AAE7C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAY9E,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9F,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACjG,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AA+BxD,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAcpG,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAE9F,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,63 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ import type { AuthContextValue } from './types.js';
3
+ /**
4
+ * The one local user a {@link LocalIdentityProvider} presents.
5
+ *
6
+ * @stability experimental
7
+ */
8
+ export interface LocalIdentityInput {
9
+ /** The local user's id. */
10
+ userId: string;
11
+ /**
12
+ * The name the user menu shows.
13
+ *
14
+ * @defaultValue `'You'`
15
+ */
16
+ displayName?: string;
17
+ /** The email, or `null`/absent for none (shown as an empty string). */
18
+ email?: string | null;
19
+ /** The permissions the local user holds (the exact strings a destination or card names). */
20
+ permissions: readonly string[];
21
+ /** The role names the local user holds. */
22
+ roles?: readonly string[];
23
+ }
24
+ /**
25
+ * Builds the {@link AuthContextValue} of a local, always-signed-in user:
26
+ * `isAuthenticated` is `true`, there are no sign-in providers, `mode` is
27
+ * `'local'`, and `login`, `logout`, `refreshUser`, `switchOrg` and
28
+ * `setAccessToken` do nothing.
29
+ *
30
+ * @param input - see {@link LocalIdentityInput}.
31
+ * @returns the context value; give it a stable identity (memoize) when passing it to `AuthContext.Provider`.
32
+ *
33
+ * @stability experimental
34
+ */
35
+ export declare function createLocalAuthContextValue(input: LocalIdentityInput): AuthContextValue;
36
+ /**
37
+ * Props of {@link LocalIdentityProvider}: a {@link LocalIdentityInput} and the tree.
38
+ *
39
+ * @stability experimental
40
+ */
41
+ export type LocalIdentityProviderProps = LocalIdentityInput & {
42
+ /** The tree. */
43
+ children: ReactNode;
44
+ };
45
+ /**
46
+ * Provides a local, always-signed-in user as the auth context. For a host with
47
+ * no API session; mount it where an `AuthProvider` would go.
48
+ *
49
+ * @param props - see {@link LocalIdentityProviderProps}.
50
+ * @returns the provider element.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * <LocalIdentityProvider userId="local" permissions={['notes:read', 'notes:write']}>
55
+ * <ShellLayout navigation={navigation} />
56
+ * </LocalIdentityProvider>
57
+ * ```
58
+ *
59
+ * @extensionPoint component
60
+ * @stability experimental
61
+ */
62
+ export declare function LocalIdentityProvider({ children, userId, displayName, email, permissions, roles, }: LocalIdentityProviderProps): ReactElement;
63
+ //# sourceMappingURL=local-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-identity.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/local-identity.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGrD,OAAO,KAAK,EAAE,gBAAgB,EAAY,MAAM,YAAY,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,4FAA4F;IAC5F,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,2CAA2C;IAC3C,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,kBAAkB,GAAG,gBAAgB,CA0BvF;AAED;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,GAAG,kBAAkB,GAAG;IAC5D,gBAAgB;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,MAAM,EACN,WAAW,EACX,KAAK,EACL,WAAW,EACX,KAAK,GACN,EAAE,0BAA0B,GAAG,YAAY,CAgB3C"}
@@ -0,0 +1,84 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // =============================================================================
3
+ // Local identity (a host with no API session, e.g. a desktop shell)
4
+ // =============================================================================
5
+ //
6
+ // A local host has one user, known at start-up, with a fixed permission set.
7
+ // `LocalIdentityProvider` provides an `AuthContext` value for it
8
+ // (`mode: 'local'`) so the shell's chrome (`usePermissions`, the user menu) works
9
+ // unchanged. Nothing here calls the network; every session verb is a no-op.
10
+ // =============================================================================
11
+ import { useMemo } from 'react';
12
+ import { AuthContext } from './auth-context.js';
13
+ const noop = () => undefined;
14
+ const resolved = () => Promise.resolve();
15
+ /**
16
+ * Builds the {@link AuthContextValue} of a local, always-signed-in user:
17
+ * `isAuthenticated` is `true`, there are no sign-in providers, `mode` is
18
+ * `'local'`, and `login`, `logout`, `refreshUser`, `switchOrg` and
19
+ * `setAccessToken` do nothing.
20
+ *
21
+ * @param input - see {@link LocalIdentityInput}.
22
+ * @returns the context value; give it a stable identity (memoize) when passing it to `AuthContext.Provider`.
23
+ *
24
+ * @stability experimental
25
+ */
26
+ export function createLocalAuthContextValue(input) {
27
+ const user = {
28
+ id: input.userId,
29
+ email: input.email ?? '',
30
+ displayName: input.displayName ?? 'You',
31
+ profileImageUrl: null,
32
+ roles: (input.roles ?? []).map((name) => ({ name })),
33
+ permissions: [...input.permissions],
34
+ isActive: true,
35
+ createdAt: new Date(0).toISOString(),
36
+ };
37
+ return {
38
+ user,
39
+ isLoading: false,
40
+ isAuthenticated: true,
41
+ providers: [],
42
+ sessionExpired: false,
43
+ login: noop,
44
+ logout: resolved,
45
+ refreshUser: resolved,
46
+ setAccessToken: noop,
47
+ activeOrg: null,
48
+ memberships: [],
49
+ switchOrg: resolved,
50
+ mode: 'local',
51
+ };
52
+ }
53
+ /**
54
+ * Provides a local, always-signed-in user as the auth context. For a host with
55
+ * no API session; mount it where an `AuthProvider` would go.
56
+ *
57
+ * @param props - see {@link LocalIdentityProviderProps}.
58
+ * @returns the provider element.
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * <LocalIdentityProvider userId="local" permissions={['notes:read', 'notes:write']}>
63
+ * <ShellLayout navigation={navigation} />
64
+ * </LocalIdentityProvider>
65
+ * ```
66
+ *
67
+ * @extensionPoint component
68
+ * @stability experimental
69
+ */
70
+ export function LocalIdentityProvider({ children, userId, displayName, email, permissions, roles, }) {
71
+ const permissionKey = permissions.join('\u0000');
72
+ const roleKey = (roles ?? []).join('\u0000');
73
+ const value = useMemo(() => createLocalAuthContextValue({
74
+ userId,
75
+ ...(displayName === undefined ? {} : { displayName }),
76
+ ...(email === undefined ? {} : { email }),
77
+ permissions,
78
+ ...(roles === undefined ? {} : { roles }),
79
+ }),
80
+ // The arrays are compared by content so an inline literal does not rebuild the value every render.
81
+ [userId, displayName, email, permissionKey, roleKey]);
82
+ return _jsx(AuthContext.Provider, { value: value, children: children });
83
+ }
84
+ //# sourceMappingURL=local-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-identity.js","sourceRoot":"","sources":["../../../src/identity/headless/local-identity.tsx"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oEAAoE;AACpE,gFAAgF;AAChF,EAAE;AACF,6EAA6E;AAC7E,iEAAiE;AACjE,kFAAkF;AAClF,4EAA4E;AAC5E,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAGhC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAyBhD,MAAM,IAAI,GAAG,GAAS,EAAE,CAAC,SAAS,CAAC;AACnC,MAAM,QAAQ,GAAG,GAAkB,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAAyB;IACnE,MAAM,IAAI,GAAa;QACrB,EAAE,EAAE,KAAK,CAAC,MAAM;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,KAAK;QACvC,eAAe,EAAE,IAAI;QACrB,KAAK,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;QACnC,QAAQ,EAAE,IAAI;QACd,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;KACrC,CAAC;IACF,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,KAAK;QAChB,eAAe,EAAE,IAAI;QACrB,SAAS,EAAE,EAAE;QACb,cAAc,EAAE,KAAK;QACrB,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,QAAQ;QAChB,WAAW,EAAE,QAAQ;QACrB,cAAc,EAAE,IAAI;QACpB,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,EAAE;QACf,SAAS,EAAE,QAAQ;QACnB,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,qBAAqB,CAAC,EACpC,QAAQ,EACR,MAAM,EACN,WAAW,EACX,KAAK,EACL,WAAW,EACX,KAAK,GACsB;IAC3B,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CACH,2BAA2B,CAAC;QAC1B,MAAM;QACN,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;QACrD,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACzC,WAAW;QACX,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;KAC1C,CAAC;IACJ,mGAAmG;IACnG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,CACrD,CAAC;IACF,OAAO,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAwB,CAAC;AAC/E,CAAC"}
@@ -161,6 +161,13 @@ export interface AuthContextValue {
161
161
  * Rejects when the API refuses; the current session is then unchanged.
162
162
  */
163
163
  switchOrg: (orgId: string) => Promise<void>;
164
+ /**
165
+ * Where the identity comes from. Absent or `'server'`: an {@link AuthProvider}
166
+ * session against the API. `'local'`: a {@link LocalIdentityProvider}, a
167
+ * single local user with no API (a desktop host); the shell hides sign-out and
168
+ * the organization switcher by default and nothing here reaches the network.
169
+ */
170
+ mode?: 'server' | 'local';
164
171
  }
165
172
  /**
166
173
  * What {@link AuthProvider} drives sessions through: the access-token holder
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAE/F;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,yEAAyE;IACzE,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,sDAAsD;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,4CAA4C;IAC5C,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1D,sFAAsF;IACtF,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC;;;OAGG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,kEAAkE;IAClE,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,0FAA0F;IAC1F,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,8CAA8C;IAC9C,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,qCAAqC;IACrC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3C,iFAAiF;IACjF,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,iFAAiF;IACjF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CACpD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAE/F;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB,qBAAqB;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,6EAA6E;IAC7E,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,yEAAyE;IACzE,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,4EAA4E;IAC5E,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,4DAA4D;IAC5D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B,wDAAwD;IACxD,SAAS,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,sDAAsD;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,eAAe,EAAE,OAAO,CAAC;IACzB,4CAA4C;IAC5C,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,cAAc,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1D,sFAAsF;IACtF,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,4DAA4D;IAC5D,WAAW,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC;;;OAGG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,kEAAkE;IAClE,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IAC7B,0FAA0F;IAC1F,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC;;;;;OAKG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C;;;;;OAKG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACnE,8CAA8C;IAC9C,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD,qCAAqC;IACrC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAC3C,iFAAiF;IACjF,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,iFAAiF;IACjF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CACpD"}
@@ -26,8 +26,13 @@ export interface UsePermissionsReturn {
26
26
  /**
27
27
  * The signed-in user's permissions and roles, as predicates.
28
28
  *
29
+ * The source, in order: the {@link AuthContext} (an `AuthProvider`, or the
30
+ * `LocalIdentityProvider` of a local host); else the `PlatformHostProvider`'s
31
+ * viewer (`hasPermission` only: the viewer port cannot list permissions or
32
+ * roles, so `permissions` and `roles` are empty and `isAdmin` is `false`).
33
+ *
29
34
  * @returns see {@link UsePermissionsReturn}.
30
- * @throws Error outside an `AuthProvider`.
35
+ * @throws Error when neither an `AuthProvider`/`LocalIdentityProvider` nor a `PlatformHostProvider` is mounted.
31
36
  *
32
37
  * @example
33
38
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"use-permissions.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/use-permissions.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,uDAAuD;IACvD,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,+CAA+C;IAC/C,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,+EAA+E;IAC/E,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/C,sDAAsD;IACtD,gBAAgB,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAClD,mDAAmD;IACnD,iBAAiB,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IACnD,4CAA4C;IAC5C,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,uDAAuD;IACvD,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAC/C,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CA4DrD"}
1
+ {"version":3,"file":"use-permissions.d.ts","sourceRoot":"","sources":["../../../src/identity/headless/use-permissions.ts"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,uDAAuD;IACvD,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,+CAA+C;IAC/C,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,+EAA+E;IAC/E,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/C,sDAAsD;IACtD,gBAAgB,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAClD,mDAAmD;IACnD,iBAAiB,EAAE,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IACnD,4CAA4C;IAC5C,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,uDAAuD;IACvD,UAAU,EAAE,CAAC,GAAG,QAAQ,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC;IAC/C,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAyErD"}
@@ -2,12 +2,18 @@
2
2
  // reference app's `hooks/usePermissions.ts`. These only decide what the UI
3
3
  // shows; the API enforces every permission.
4
4
  import { useCallback, useMemo } from 'react';
5
- import { useAuth } from './auth-context.js';
5
+ import { useOptionalPlatformHost } from '../../core/index.js';
6
+ import { useOptionalAuth } from './auth-context.js';
6
7
  /**
7
8
  * The signed-in user's permissions and roles, as predicates.
8
9
  *
10
+ * The source, in order: the {@link AuthContext} (an `AuthProvider`, or the
11
+ * `LocalIdentityProvider` of a local host); else the `PlatformHostProvider`'s
12
+ * viewer (`hasPermission` only: the viewer port cannot list permissions or
13
+ * roles, so `permissions` and `roles` are empty and `isAdmin` is `false`).
14
+ *
9
15
  * @returns see {@link UsePermissionsReturn}.
10
- * @throws Error outside an `AuthProvider`.
16
+ * @throws Error when neither an `AuthProvider`/`LocalIdentityProvider` nor a `PlatformHostProvider` is mounted.
11
17
  *
12
18
  * @example
13
19
  * ```tsx
@@ -19,22 +25,26 @@ import { useAuth } from './auth-context.js';
19
25
  * @stability stable
20
26
  */
21
27
  export function usePermissions() {
22
- const { user } = useAuth();
28
+ const auth = useOptionalAuth();
29
+ const viewer = useOptionalPlatformHost()?.viewer ?? null;
30
+ const user = auth?.user;
23
31
  const permissions = useMemo(() => {
24
32
  return new Set(user?.permissions || []);
25
33
  }, [user?.permissions]);
26
34
  const roles = useMemo(() => {
27
35
  return new Set(user?.roles?.map((r) => r.name) || []);
28
36
  }, [user?.roles]);
37
+ // The viewer port answers one permission at a time; used only without an AuthContext.
38
+ const viewerCheck = auth === null ? viewer : null;
29
39
  const hasPermission = useCallback((permission) => {
30
- return permissions.has(permission);
31
- }, [permissions]);
40
+ return viewerCheck ? viewerCheck.hasPermission(permission) : permissions.has(permission);
41
+ }, [permissions, viewerCheck]);
32
42
  const hasAnyPermission = useCallback((...perms) => {
33
- return perms.some((p) => permissions.has(p));
34
- }, [permissions]);
43
+ return perms.some((p) => hasPermission(p));
44
+ }, [hasPermission]);
35
45
  const hasAllPermissions = useCallback((...perms) => {
36
- return perms.every((p) => permissions.has(p));
37
- }, [permissions]);
46
+ return perms.every((p) => hasPermission(p));
47
+ }, [hasPermission]);
38
48
  const hasRole = useCallback((role) => {
39
49
  return roles.has(role);
40
50
  }, [roles]);
@@ -44,6 +54,11 @@ export function usePermissions() {
44
54
  const isAdmin = useMemo(() => {
45
55
  return roles.has('admin');
46
56
  }, [roles]);
57
+ if (auth === null && viewer === null) {
58
+ throw new Error('usePermissions: no permission source. Mount an AuthProvider (or a LocalIdentityProvider for a local host) ' +
59
+ "from '@marinoscar/platform-web/identity/headless', or a PlatformHostProvider from '@marinoscar/platform-web/core' " +
60
+ '(its viewer answers hasPermission).');
61
+ }
47
62
  return {
48
63
  permissions,
49
64
  roles,
@@ -1 +1 @@
1
- {"version":3,"file":"use-permissions.js","sourceRoot":"","sources":["../../../src/identity/headless/use-permissions.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,4CAA4C;AAE5C,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AA4B5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;IAE3B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IAExB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE;QACzB,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAElB,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,UAAkB,EAAW,EAAE;QAC9B,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC,EACD,CAAC,WAAW,CAAC,CACd,CAAC;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,GAAG,KAAe,EAAW,EAAE;QAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC,EACD,CAAC,WAAW,CAAC,CACd,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,GAAG,KAAe,EAAW,EAAE;QAC9B,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,EACD,CAAC,WAAW,CAAC,CACd,CAAC;IAEF,MAAM,OAAO,GAAG,WAAW,CACzB,CAAC,IAAY,EAAW,EAAE;QACxB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAC;IAEF,MAAM,UAAU,GAAG,WAAW,CAC5B,CAAC,GAAG,QAAkB,EAAW,EAAE;QACjC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,CAAC,EACD,CAAC,KAAK,CAAC,CACR,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC5B,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO;QACL,WAAW;QACX,KAAK;QACL,aAAa;QACb,gBAAgB;QAChB,iBAAiB;QACjB,OAAO;QACP,UAAU;QACV,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"use-permissions.js","sourceRoot":"","sources":["../../../src/identity/headless/use-permissions.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export { useAuth, usePermissions } from './headless/index.js';
1
+ export { useAuth, usePermissions, LocalIdentityProvider } from './headless/index.js';
2
2
  export type { IdentityDataTableProps, IdentityTableColumn, IdentityTableFilter, IdentityTableRowAction, } from './headless/index.js';
3
3
  export { IdentityTable } from './ui/table.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC9D,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACrF,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -4,7 +4,7 @@
4
4
  // dependency (notifications -> identity). Not a package subpath: apps import
5
5
  // `@marinoscar/platform-web/identity/headless` and `/identity/ui`. Narrow on
6
6
  // purpose: only what a sibling uses.
7
- export { useAuth, usePermissions } from './headless/index.js';
7
+ export { useAuth, usePermissions, LocalIdentityProvider } from './headless/index.js';
8
8
  // The table seam: the app's DataTable from the identity adapters, else the
9
9
  // plain MUI fallback.
10
10
  export { IdentityTable } from './ui/table.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,qCAAqC;AAErC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAO9D,2EAA2E;AAC3E,sBAAsB;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/identity/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,qCAAqC;AAErC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAOrF,2EAA2E;AAC3E,sBAAsB;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -1,5 +1,7 @@
1
1
  export { groupDestinationRuns, isDestinationVisible, isExternalUrl, owns, resolveActiveDestination, shellDestinationRoutes, } from './navigation.js';
2
2
  export type { ShellConsole, ShellConsoleBack, ShellDestination, ShellDestinationRun, ShellIcon, ShellIconProps, ShellNavigation, ShellRailPreference, ShellSettingsSurface, } from './navigation.js';
3
+ export { ShellPreferencesProvider, createLocalStorageShellPreferencesPort, useOptionalShellPreferencesPort, } from './preferences.js';
4
+ export type { ShellPreferences, ShellPreferencesPort, ShellPreferencesProviderProps } from './preferences.js';
3
5
  export { useShellRailPreference } from './rail-preference.js';
4
6
  export type { ShellRailPreferenceOptions, UseShellRailPreferenceResult } from './rail-preference.js';
5
7
  export { BUILTIN_SHELL_THEME_MODES, createShellTheme, isBuiltinThemeMode, listThemeModes, registerThemeMode, shellComponentOverrides, shellPalette, useOptionalShellTheme, useShellTheme, } from './theme.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shell/headless/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,IAAI,EACJ,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shell/headless/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,IAAI,EACJ,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,wBAAwB,EACxB,sCAAsC,EACtC,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAC9G,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AACrG,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,sBAAsB,EACtB,cAAc,EACd,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -2,6 +2,7 @@
2
2
  // theme and providers composition, with no component (issue #868). Documented
3
3
  // in ../README.md.
4
4
  export { groupDestinationRuns, isDestinationVisible, isExternalUrl, owns, resolveActiveDestination, shellDestinationRoutes, } from './navigation.js';
5
+ export { ShellPreferencesProvider, createLocalStorageShellPreferencesPort, useOptionalShellPreferencesPort, } from './preferences.js';
5
6
  export { useShellRailPreference } from './rail-preference.js';
6
7
  export { BUILTIN_SHELL_THEME_MODES, createShellTheme, isBuiltinThemeMode, listThemeModes, registerThemeMode, shellComponentOverrides, shellPalette, useOptionalShellTheme, useShellTheme, } from './theme.js';
7
8
  export { ShellProviders } from './providers.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shell/headless/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,mBAAmB;AAEnB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,IAAI,EACJ,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,YAAY,CAAC;AAQpB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shell/headless/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,mBAAmB;AAEnB,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,IAAI,EACJ,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAYzB,OAAO,EACL,wBAAwB,EACxB,sCAAsC,EACtC,+BAA+B,GAChC,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EACL,yBAAyB,EACzB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,YAAY,CAAC;AAQpB,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,72 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+ /**
3
+ * The preferences the shell stores per viewer. Absent means the default.
4
+ *
5
+ * @stability experimental
6
+ */
7
+ export interface ShellPreferences {
8
+ /** The desktop rail is collapsed. Absent: expanded. */
9
+ railCollapsed?: boolean;
10
+ }
11
+ /**
12
+ * Where a host keeps {@link ShellPreferences}.
13
+ *
14
+ * @extensionPoint option
15
+ * @stability experimental
16
+ */
17
+ export interface ShellPreferencesPort {
18
+ /** Reads the stored preferences (an empty object when none). */
19
+ read(): ShellPreferences | Promise<ShellPreferences>;
20
+ /** Stores the fields of `patch`; fields it omits are left as they are. */
21
+ write(patch: Partial<ShellPreferences>): void | Promise<void>;
22
+ }
23
+ /**
24
+ * Props of {@link ShellPreferencesProvider}.
25
+ *
26
+ * @stability experimental
27
+ */
28
+ export interface ShellPreferencesProviderProps {
29
+ /** The port; keep its identity stable. */
30
+ port: ShellPreferencesPort;
31
+ /** The tree. */
32
+ children: ReactNode;
33
+ }
34
+ /**
35
+ * Stores the shell's preferences through `port` instead of `/user-settings`.
36
+ * Mount it for the whole life of the shell: `useShellRailPreference` picks its
37
+ * source from whether a provider is mounted.
38
+ *
39
+ * @param props - see {@link ShellPreferencesProviderProps}.
40
+ * @returns the provider element.
41
+ *
42
+ * @extensionPoint component
43
+ * @stability experimental
44
+ */
45
+ export declare function ShellPreferencesProvider({ port, children }: ShellPreferencesProviderProps): ReactElement;
46
+ /**
47
+ * The preferences port in context, or `null` when no
48
+ * {@link ShellPreferencesProvider} is mounted.
49
+ *
50
+ * @returns the port, or `null`.
51
+ *
52
+ * @stability experimental
53
+ */
54
+ export declare function useOptionalShellPreferencesPort(): ShellPreferencesPort | null;
55
+ /**
56
+ * A port over `window.localStorage`: one JSON object under `key`. Every storage
57
+ * access is guarded, so a blocked or full store reads as "no preferences" and
58
+ * a failed write is dropped; the shell then keeps the choice for the session.
59
+ *
60
+ * @param key - the storage key. Default `'shell-preferences'`.
61
+ * @returns the port.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * const port = createLocalStorageShellPreferencesPort('myapp.shell');
66
+ * <ShellPreferencesProvider port={port}>...</ShellPreferencesProvider>
67
+ * ```
68
+ *
69
+ * @stability experimental
70
+ */
71
+ export declare function createLocalStorageShellPreferencesPort(key?: string): ShellPreferencesPort;
72
+ //# sourceMappingURL=preferences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/shell/headless/preferences.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,IAAI,IAAI,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrD,0EAA0E;IAC1E,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAKD;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,0CAA0C;IAC1C,IAAI,EAAE,oBAAoB,CAAC;IAC3B,gBAAgB;IAChB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,6BAA6B,GAAG,YAAY,CAExG;AAED;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,IAAI,oBAAoB,GAAG,IAAI,CAE7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sCAAsC,CAAC,GAAG,SAAsB,GAAG,oBAAoB,CAuBtG"}
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // =============================================================================
3
+ // The shell preferences port (a host with no `/user-settings`)
4
+ // =============================================================================
5
+ //
6
+ // The rail's collapse preference lives in the viewer's `navigation`
7
+ // user-settings namespace by default (`useShellRailPreference`). A host with no
8
+ // API (a desktop shell) mounts `ShellPreferencesProvider` with a port that reads
9
+ // and writes the same values locally, and the rail then never touches the API.
10
+ // =============================================================================
11
+ import { createContext, useContext } from 'react';
12
+ const ShellPreferencesContext = createContext(null);
13
+ ShellPreferencesContext.displayName = 'ShellPreferencesContext';
14
+ /**
15
+ * Stores the shell's preferences through `port` instead of `/user-settings`.
16
+ * Mount it for the whole life of the shell: `useShellRailPreference` picks its
17
+ * source from whether a provider is mounted.
18
+ *
19
+ * @param props - see {@link ShellPreferencesProviderProps}.
20
+ * @returns the provider element.
21
+ *
22
+ * @extensionPoint component
23
+ * @stability experimental
24
+ */
25
+ export function ShellPreferencesProvider({ port, children }) {
26
+ return _jsx(ShellPreferencesContext.Provider, { value: port, children: children });
27
+ }
28
+ /**
29
+ * The preferences port in context, or `null` when no
30
+ * {@link ShellPreferencesProvider} is mounted.
31
+ *
32
+ * @returns the port, or `null`.
33
+ *
34
+ * @stability experimental
35
+ */
36
+ export function useOptionalShellPreferencesPort() {
37
+ return useContext(ShellPreferencesContext);
38
+ }
39
+ /**
40
+ * A port over `window.localStorage`: one JSON object under `key`. Every storage
41
+ * access is guarded, so a blocked or full store reads as "no preferences" and
42
+ * a failed write is dropped; the shell then keeps the choice for the session.
43
+ *
44
+ * @param key - the storage key. Default `'shell-preferences'`.
45
+ * @returns the port.
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * const port = createLocalStorageShellPreferencesPort('myapp.shell');
50
+ * <ShellPreferencesProvider port={port}>...</ShellPreferencesProvider>
51
+ * ```
52
+ *
53
+ * @stability experimental
54
+ */
55
+ export function createLocalStorageShellPreferencesPort(key = 'shell-preferences') {
56
+ const readAll = () => {
57
+ try {
58
+ const raw = window.localStorage.getItem(key);
59
+ if (raw === null)
60
+ return {};
61
+ const parsed = JSON.parse(raw);
62
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
63
+ return {};
64
+ const railCollapsed = parsed.railCollapsed;
65
+ return typeof railCollapsed === 'boolean' ? { railCollapsed } : {};
66
+ }
67
+ catch {
68
+ return {};
69
+ }
70
+ };
71
+ return {
72
+ read: readAll,
73
+ write(patch) {
74
+ try {
75
+ window.localStorage.setItem(key, JSON.stringify({ ...readAll(), ...patch }));
76
+ }
77
+ catch {
78
+ // Storage unavailable: the preference lasts for the session only.
79
+ }
80
+ },
81
+ };
82
+ }
83
+ //# sourceMappingURL=preferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preferences.js","sourceRoot":"","sources":["../../../src/shell/headless/preferences.tsx"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+DAA+D;AAC/D,gFAAgF;AAChF,EAAE;AACF,oEAAoE;AACpE,gFAAgF;AAChF,iFAAiF;AACjF,+EAA+E;AAC/E,gFAAgF;AAEhF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AA0BlD,MAAM,uBAAuB,GAAG,aAAa,CAA8B,IAAI,CAAC,CAAC;AACjF,uBAAuB,CAAC,WAAW,GAAG,yBAAyB,CAAC;AAchE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAiC;IACxF,OAAO,KAAC,uBAAuB,CAAC,QAAQ,IAAC,KAAK,EAAE,IAAI,YAAG,QAAQ,GAAoC,CAAC;AACtG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,+BAA+B;IAC7C,OAAO,UAAU,CAAC,uBAAuB,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,sCAAsC,CAAC,GAAG,GAAG,mBAAmB;IAC9E,MAAM,OAAO,GAAG,GAAqB,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAO,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,OAAO,EAAE,CAAC;YACtF,MAAM,aAAa,GAAI,MAAsC,CAAC,aAAa,CAAC;YAC5E,OAAO,OAAO,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IACF,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK,CAAC,KAAK;YACT,IAAI,CAAC;gBACH,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC;YAC/E,CAAC;YAAC,MAAM,CAAC;gBACP,kEAAkE;YACpE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rail-preference.d.ts","sourceRoot":"","sources":["../../../src/shell/headless/rail-preference.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAI7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAU3D;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,4EAA4E;IAC5E,GAAG,CAAC,EAAE,iBAAiB,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IACvE,2FAA2F;IAC3F,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,0BAA+B,GAAG,4BAA4B,CAmC7G"}
1
+ {"version":3,"file":"rail-preference.d.ts","sourceRoot":"","sources":["../../../src/shell/headless/rail-preference.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAI7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAY3D;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,4EAA4E;IAC5E,GAAG,CAAC,EAAE,iBAAiB,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA6B,SAAQ,mBAAmB;IACvE,2FAA2F;IAC3F,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,0BAA+B,GAAG,4BAA4B,CAK7G"}
@@ -17,9 +17,10 @@
17
17
  // at which point the stored value either carries the new value (success) or
18
18
  // the old one (failure): the revert is the same path as the commit.
19
19
  // =============================================================================
20
- import { useCallback, useMemo, useRef, useState } from 'react';
20
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
21
21
  import { useUserSettings } from '../../settings/index.js';
22
22
  import { useIsMounted } from '../internal/use-is-mounted.js';
23
+ import { useOptionalShellPreferencesPort } from './preferences.js';
23
24
  /**
24
25
  * The desktop rail's collapse preference, stored in the viewer's `navigation`
25
26
  * user-settings namespace (`railCollapsed`). Optimistic toggle; a default is
@@ -33,6 +34,48 @@ import { useIsMounted } from '../internal/use-is-mounted.js';
33
34
  * @stability experimental
34
35
  */
35
36
  export function useShellRailPreference(options = {}) {
37
+ // The source is fixed for the life of the shell (a provider is mounted or it
38
+ // is not), so choosing between the two hooks here keeps the hook order stable.
39
+ const port = useOptionalShellPreferencesPort();
40
+ return port ? usePortRailPreference(port) : useServerRailPreference(options);
41
+ }
42
+ /** The preference over a host's {@link ShellPreferencesPort}; never touches the API. */
43
+ function usePortRailPreference(port) {
44
+ const [railCollapsed, setRailCollapsed] = useState(false);
45
+ const [isLoading, setIsLoading] = useState(true);
46
+ // A write made before the first read resolves wins over the stale read.
47
+ const touched = useRef(false);
48
+ useEffect(() => {
49
+ let cancelled = false;
50
+ void Promise.resolve()
51
+ .then(() => port.read())
52
+ .then((stored) => {
53
+ if (cancelled || touched.current)
54
+ return;
55
+ setRailCollapsed(stored.railCollapsed === true);
56
+ })
57
+ .catch(() => undefined)
58
+ .finally(() => {
59
+ if (!cancelled)
60
+ setIsLoading(false);
61
+ });
62
+ return () => {
63
+ cancelled = true;
64
+ };
65
+ }, [port]);
66
+ const toggleRailCollapsed = useCallback(() => {
67
+ touched.current = true;
68
+ const next = !railCollapsed;
69
+ setRailCollapsed(next);
70
+ void Promise.resolve()
71
+ .then(() => port.write({ railCollapsed: next }))
72
+ // The choice stays for this session when the port cannot keep it.
73
+ .catch(() => undefined);
74
+ }, [port, railCollapsed]);
75
+ return { railCollapsed, toggleRailCollapsed, isLoading };
76
+ }
77
+ /** The preference over `/user-settings` (the default). */
78
+ function useServerRailPreference(options) {
36
79
  const { settings, isLoading, updateSettings } = useUserSettings({
37
80
  syncTheme: false,
38
81
  ...(options.api === undefined ? {} : { api: options.api }),