@sevenfold/setto-client 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/chrome.d.ts CHANGED
@@ -21,6 +21,27 @@ export interface SettoChromeHandshake {
21
21
  * where it cannot be forgotten.
22
22
  */
23
23
  mount: (Component: React.ComponentType) => void;
24
+ /**
25
+ * The same, for the page at `/setto`.
26
+ *
27
+ * A second slot because the dashboard is not an overlay: it belongs in the
28
+ * host's own route, where the customer navigated to it. Registering nothing
29
+ * leaves the bundled dashboard in place, which is what keeps a chrome that
30
+ * fails to load from taking the admin down with it.
31
+ */
32
+ mountAdmin: (Component: React.ComponentType) => void;
33
+ /**
34
+ * The host's own `useSetto`, callable from the chrome.
35
+ *
36
+ * This is what makes the whole arrangement cheap. The chrome renders inside
37
+ * the provider's tree, so it can simply use the context — supabase, api,
38
+ * session, sites, the i18n store — rather than having each field copied
39
+ * across a handshake that could never be extended without a re-pin.
40
+ *
41
+ * It is a hook: obey the rules of hooks, and only call it from a component
42
+ * this file rendered.
43
+ */
44
+ useSetto: () => unknown;
24
45
  config: {
25
46
  siteId: string;
26
47
  apiUrl: string;
@@ -48,4 +69,9 @@ declare global {
48
69
  __settoChromeLoaded__?: boolean;
49
70
  }
50
71
  }
72
+ /**
73
+ * What the host should render at `/setto`, or null while the chrome has not
74
+ * offered anything. Callers fall back to their bundled dashboard.
75
+ */
76
+ export declare function useSettoAdminChrome(): React.ComponentType | null;
51
77
  export declare function SettoChrome(): import("react/jsx-runtime").JSX.Element | null;
package/dist/index.d.ts CHANGED
@@ -22,6 +22,8 @@ export { SettoAnimation } from './SettoAnimation';
22
22
  export type { SettoAnimationProps } from './SettoAnimation';
23
23
  export { useSectionTheme } from './use-section-theme';
24
24
  export { SettoAdminApp } from './admin/App';
25
+ export { SettoContext } from './provider';
26
+ export type { SettoContextValue } from './provider';
25
27
  export { SETTO_BASE, adminViewUrl } from './lib/urls';
26
28
  export { AuthGate } from './edit-mode/auth-gate';
27
29
  export type { SettoConfig, BrandColor, DeploymentRow, SiteRow, ContentFile, PublishFile, PublishResult, } from './types';
@@ -5,7 +5,7 @@ import { I18nStore } from './lib/i18n-store';
5
5
  import { AssetStore } from './lib/asset-store';
6
6
  import { ThemeStore } from './lib/theme-store';
7
7
  import type { SettoConfig, SiteRow } from './types';
8
- interface SettoContextValue {
8
+ export interface SettoContextValue {
9
9
  config: SettoConfig;
10
10
  supabase: SupabaseClient;
11
11
  api: SettoApi;
@@ -26,6 +26,18 @@ interface SettoContextValue {
26
26
  themeStore: ThemeStore | null;
27
27
  assetStore: AssetStore | null;
28
28
  }
29
+ /**
30
+ * Exported for one caller: the chrome bundle.
31
+ *
32
+ * The dashboard is compiled into that bundle, so its `useSetto` reads *this*
33
+ * module's context — a different instance from the one the host provider
34
+ * fills, which would otherwise throw "must be used within SettoProvider" the
35
+ * moment it rendered. Handing it the host's value through this provider is
36
+ * what lets the same components run on either side of the boundary.
37
+ *
38
+ * Not part of the public API in any other sense. Use `useSetto`.
39
+ */
40
+ export declare const SettoContext: import("react").Context<SettoContextValue | null>;
29
41
  export interface SettoProviderProps {
30
42
  config: SettoConfig;
31
43
  children: ReactNode;
@@ -44,4 +56,3 @@ export interface SettoProviderProps {
44
56
  */
45
57
  export declare function SettoProvider({ config, children }: SettoProviderProps): import("react/jsx-runtime").JSX.Element;
46
58
  export declare function useSetto(): SettoContextValue;
47
- export {};
@@ -21376,6 +21376,30 @@ class ChromeBoundary extends React.Component {
21376
21376
  return this.state.dead ? null : this.props.children;
21377
21377
  }
21378
21378
  }
21379
+ const slots = {
21380
+ admin: null,
21381
+ listeners: /* @__PURE__ */ new Set()
21382
+ };
21383
+ function publishSlot(which, Component) {
21384
+ slots[which] = Component;
21385
+ for (const listener of slots.listeners) {
21386
+ try {
21387
+ listener();
21388
+ } catch {
21389
+ }
21390
+ }
21391
+ }
21392
+ function useSettoAdminChrome() {
21393
+ const [, force] = useState(0);
21394
+ useEffect(() => {
21395
+ const listener = () => force((n) => n + 1);
21396
+ slots.listeners.add(listener);
21397
+ return () => {
21398
+ slots.listeners.delete(listener);
21399
+ };
21400
+ }, []);
21401
+ return slots.admin;
21402
+ }
21379
21403
  function SettoChrome() {
21380
21404
  const setto = useSetto();
21381
21405
  const [Chrome, setChrome] = useState(null);
@@ -21428,10 +21452,12 @@ function SettoChrome() {
21428
21452
  },
21429
21453
  // `setChrome(() => C)`: a component is a function, and the updater form
21430
21454
  // is the only way to put one into state without React calling it.
21431
- mount: (Component) => setChrome(() => Component)
21455
+ mount: (Component) => setChrome(() => Component),
21456
+ mountAdmin: (Component) => publishSlot("admin", Component),
21457
+ useSetto
21432
21458
  };
21433
21459
  const script = document.createElement("script");
21434
- script.src = chromeUrl(setto.config.apiUrl);
21460
+ script.src = `${chromeUrl(setto.config.apiUrl)}?site=${encodeURIComponent(setto.config.siteId)}`;
21435
21461
  script.async = true;
21436
21462
  script.onerror = () => void 0;
21437
21463
  document.head.appendChild(script);
@@ -26559,6 +26585,8 @@ function depDotStyle(status) {
26559
26585
  };
26560
26586
  }
26561
26587
  function SettoAdminApp() {
26588
+ const Chrome = useSettoAdminChrome();
26589
+ if (Chrome) return /* @__PURE__ */ jsx(Chrome, {});
26562
26590
  return /* @__PURE__ */ jsx(AuthGate, { children: /* @__PURE__ */ jsx(SiteList, {}) });
26563
26591
  }
26564
26592
  const DEPLOYMENTS_VIEW = "deployments";
@@ -27161,6 +27189,7 @@ export {
27161
27189
  SettoBlock,
27162
27190
  SettoBlockTree,
27163
27191
  SettoChrome,
27192
+ SettoContext,
27164
27193
  SettoForm,
27165
27194
  SettoIcon,
27166
27195
  SettoImage,