@immediately-run/sdk 0.58.0 → 0.59.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/index.d.cts CHANGED
@@ -13,7 +13,7 @@ export { ObjectUrlState, useAllMetadata, useFileMetadata, useMetadataQuery, useO
13
13
  export { MetadataSource, MetadataSourceMode, MetadataSourceProps, useMetadataStore } from './metadataSource.cjs';
14
14
  export { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler.cjs';
15
15
  export { AuthState, AuthStatus, SandboxUser, getAuthState, onAuthChange, useAuth } from './auth.cjs';
16
- export { HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme } from './theme.cjs';
16
+ export { HostTheme, HostThemeSelection, SetHostThemeSelectionParams, ThemeBundleLocation, ThemeCatalog, ThemeCatalogEntry, addThemeSource, getHostTheme, getHostThemeSelection, getThemeCatalog, onHostThemeChange, onHostThemeSelectionChange, onThemeCatalogChange, removeThemeSource, setHostTheme, setHostThemeSelection, useHostTheme, useHostThemeSelection, useThemeCatalog } from './theme.cjs';
17
17
  export { EditorContext, getEditorContext, onEditorContextChange, useEditorContext } from './editorContext.cjs';
18
18
  export { EditTarget, EditorOpenError, EditorOpenOptions, EditorSelection, EditorSessionError, EditorWriteError, RequestEditError, closeFile, createFile, createFolder, deleteEntry, openInEditor, renameEntry, requestEdit, setActiveFile, uploadFile } from './editor.cjs';
19
19
  export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorChange, useFormFactor } from './formFactor.cjs';
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { ObjectUrlState, useAllMetadata, useFileMetadata, useMetadataQuery, useO
13
13
  export { MetadataSource, MetadataSourceMode, MetadataSourceProps, useMetadataStore } from './metadataSource.js';
14
14
  export { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler.js';
15
15
  export { AuthState, AuthStatus, SandboxUser, getAuthState, onAuthChange, useAuth } from './auth.js';
16
- export { HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme } from './theme.js';
16
+ export { HostTheme, HostThemeSelection, SetHostThemeSelectionParams, ThemeBundleLocation, ThemeCatalog, ThemeCatalogEntry, addThemeSource, getHostTheme, getHostThemeSelection, getThemeCatalog, onHostThemeChange, onHostThemeSelectionChange, onThemeCatalogChange, removeThemeSource, setHostTheme, setHostThemeSelection, useHostTheme, useHostThemeSelection, useThemeCatalog } from './theme.js';
17
17
  export { EditorContext, getEditorContext, onEditorContextChange, useEditorContext } from './editorContext.js';
18
18
  export { EditTarget, EditorOpenError, EditorOpenOptions, EditorSelection, EditorSessionError, EditorWriteError, RequestEditError, closeFile, createFile, createFolder, deleteEntry, openInEditor, renameEntry, requestEdit, setActiveFile, uploadFile } from './editor.js';
19
19
  export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorChange, useFormFactor } from './formFactor.js';
package/dist/theme.cjs CHANGED
@@ -18,38 +18,122 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var theme_exports = {};
20
20
  __export(theme_exports, {
21
+ addThemeSource: () => addThemeSource,
21
22
  getHostTheme: () => getHostTheme,
23
+ getHostThemeSelection: () => getHostThemeSelection,
24
+ getThemeCatalog: () => getThemeCatalog,
22
25
  onHostThemeChange: () => onHostThemeChange,
26
+ onHostThemeSelectionChange: () => onHostThemeSelectionChange,
27
+ onThemeCatalogChange: () => onThemeCatalogChange,
28
+ removeThemeSource: () => removeThemeSource,
23
29
  setHostTheme: () => setHostTheme,
24
- useHostTheme: () => useHostTheme
30
+ setHostThemeSelection: () => setHostThemeSelection,
31
+ useHostTheme: () => useHostTheme,
32
+ useHostThemeSelection: () => useHostThemeSelection,
33
+ useThemeCatalog: () => useThemeCatalog
25
34
  });
26
35
  module.exports = __toCommonJS(theme_exports);
27
36
  var import_pushChannel = require("./pushChannel");
28
37
  var import_sandboxUtils = require("./sandboxUtils");
29
38
  var import_protocol = require("./generated/protocol");
30
39
  var import_protocolSchemes = require("./protocolSchemes");
40
+ const DEFAULT_SELECTION = {
41
+ theme: "dark",
42
+ themeKey: "immediately-run-default",
43
+ modeId: "dark"
44
+ };
31
45
  const channel = (0, import_pushChannel.createPushChannel)({
32
46
  pushType: import_protocol.THEME,
33
47
  requestType: import_protocol.REQUEST_THEME,
34
- initial: "dark",
35
- parse: (msg) => msg.theme === "light" || msg.theme === "dark" ? msg.theme : void 0
48
+ initial: DEFAULT_SELECTION,
49
+ parse: (msg) => {
50
+ if (msg.theme !== "light" && msg.theme !== "dark") return void 0;
51
+ if (typeof msg.themeKey !== "string" || typeof msg.modeId !== "string") return void 0;
52
+ return { theme: msg.theme, themeKey: msg.themeKey, modeId: msg.modeId };
53
+ }
36
54
  });
37
- const getHostTheme = () => channel.get();
38
- const onHostThemeChange = (listener) => channel.onChange(listener);
39
- const useHostTheme = () => channel.use();
40
- const setHostTheme = async (theme) => {
41
- const res = await (0, import_sandboxUtils.protocolRequest)(import_protocolSchemes.SCHEMES[import_protocol.PROTOCOL_THEME], "set", [{ theme }]);
55
+ const getHostTheme = () => channel.get().theme;
56
+ const onHostThemeChange = (listener) => channel.onChange((sel) => listener(sel.theme));
57
+ const useHostTheme = () => channel.use().theme;
58
+ const getHostThemeSelection = () => channel.get();
59
+ const onHostThemeSelectionChange = (listener) => channel.onChange(listener);
60
+ const useHostThemeSelection = () => channel.use();
61
+ const DEFAULT_CATALOG = { themes: [] };
62
+ const catalogChannel = (0, import_pushChannel.createPushChannel)({
63
+ pushType: import_protocol.THEME_CATALOG,
64
+ requestType: import_protocol.REQUEST_THEME_CATALOG,
65
+ initial: DEFAULT_CATALOG,
66
+ parse: (msg) => {
67
+ const themes = msg.themes;
68
+ if (!Array.isArray(themes)) return void 0;
69
+ const out = [];
70
+ for (const t of themes) {
71
+ if (!t || typeof t !== "object") return void 0;
72
+ const entry = t;
73
+ if (typeof entry.themeKey !== "string" || typeof entry.label !== "string" || !Array.isArray(entry.modes)) {
74
+ return void 0;
75
+ }
76
+ const modes = [];
77
+ for (const m of entry.modes) {
78
+ if (!m || typeof m !== "object") return void 0;
79
+ const mode = m;
80
+ if (typeof mode.id !== "string" || mode.polarity !== "light" && mode.polarity !== "dark") {
81
+ return void 0;
82
+ }
83
+ modes.push({ id: mode.id, polarity: mode.polarity });
84
+ }
85
+ out.push({ themeKey: entry.themeKey, label: entry.label, modes });
86
+ }
87
+ return { themes: out };
88
+ }
89
+ });
90
+ const getThemeCatalog = () => catalogChannel.get();
91
+ const onThemeCatalogChange = (listener) => catalogChannel.onChange(listener);
92
+ const useThemeCatalog = () => catalogChannel.use();
93
+ const setTheme = async (params) => {
94
+ const res = await (0, import_sandboxUtils.protocolRequest)(import_protocolSchemes.SCHEMES[import_protocol.PROTOCOL_THEME], "set", [params]);
42
95
  if (!res || res.ok !== true) {
43
96
  const err = new Error(res?.message ?? "setHostTheme failed");
44
97
  err.code = (res && "code" in res ? res.code : void 0) ?? "unknown";
45
98
  throw err;
46
99
  }
47
100
  };
101
+ const setHostThemeSelection = async (selection) => {
102
+ await setTheme(selection);
103
+ };
104
+ const setHostTheme = async (theme) => {
105
+ await setTheme({ theme });
106
+ };
107
+ const addThemeSource = async (location) => {
108
+ const res = await (0, import_sandboxUtils.protocolRequest)(import_protocolSchemes.SCHEMES[import_protocol.PROTOCOL_THEME], "add-source", [{ location }]);
109
+ if (!res || res.ok !== true) {
110
+ const err = new Error(res?.message ?? "addThemeSource failed");
111
+ err.code = (res && "code" in res ? res.code : void 0) ?? "unknown";
112
+ throw err;
113
+ }
114
+ };
115
+ const removeThemeSource = async (themeKey) => {
116
+ const res = await (0, import_sandboxUtils.protocolRequest)(import_protocolSchemes.SCHEMES[import_protocol.PROTOCOL_THEME], "remove-source", [{ themeKey }]);
117
+ if (!res || res.ok !== true) {
118
+ const err = new Error(res?.message ?? "removeThemeSource failed");
119
+ err.code = (res && "code" in res ? res.code : void 0) ?? "unknown";
120
+ throw err;
121
+ }
122
+ };
48
123
  // Annotate the CommonJS export names for ESM import in node:
49
124
  0 && (module.exports = {
125
+ addThemeSource,
50
126
  getHostTheme,
127
+ getHostThemeSelection,
128
+ getThemeCatalog,
51
129
  onHostThemeChange,
130
+ onHostThemeSelectionChange,
131
+ onThemeCatalogChange,
132
+ removeThemeSource,
52
133
  setHostTheme,
53
- useHostTheme
134
+ setHostThemeSelection,
135
+ useHostTheme,
136
+ useHostThemeSelection,
137
+ useThemeCatalog
54
138
  });
55
139
  //# sourceMappingURL=theme.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { protocolRequest } from './sandboxUtils';\nimport { PROTOCOL_THEME, REQUEST_THEME, THEME } from './generated/protocol';\nimport { SCHEMES } from './protocolSchemes';\n\n/**\n * The host UI theme, mirrored from the immediately.run host window into the\n * sandbox. Your app can read this to render in step with the host chrome\n * (light / dark).\n *\n * This is the baseline `theme:read` capability — every app may read it. Changing\n * the host theme is a separate, elevated action (`theme:set`), available only to\n * the theme-toggle system app.\n */\nexport type HostTheme = 'light' | 'dark';\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `theme` and\n// answers `request-theme` (wire format: site-main channelBridge.ts). The host's\n// default before it reports is `dark` (sandbox themeState.DEFAULT_THEME).\nconst channel = createPushChannel<HostTheme>({\n pushType: THEME,\n requestType: REQUEST_THEME,\n initial: 'dark',\n parse: (msg) => (msg.theme === 'light' || msg.theme === 'dark' ? msg.theme : undefined),\n});\n\n/**\n * Returns the current host theme. Poll this for a one-off read; use\n * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.\n */\nexport const getHostTheme = (): HostTheme => channel.get();\n\n/**\n * Subscribe to host theme changes. The listener is invoked immediately with the\n * current theme, then again on every change. Returns an unsubscribe fn.\n */\nexport const onHostThemeChange = (listener: (theme: HostTheme) => void): (() => void) => channel.onChange(listener);\n\n/**\n * React hook returning the current host theme, re-rendering when it changes.\n * The recommended way to implement an app's own `useTheme`: follow the host,\n * allow a local override.\n */\nexport const useHostTheme = (): HostTheme => channel.use();\n\n/**\n * Set the host UI theme — the ELEVATED `theme:set` action (§8.5). The host\n * applies it and re-pushes the new value to every `theme:read` iframe, so your\n * own {@link useHostTheme} confirms the change (the loop closes with no special\n * case). Only a grant holding `theme:set` (e.g. the theme-toggle system app) may\n * call this; any other app is rejected host-side with a `forbidden`\n * {@link Error} (carrying `.code`), regardless of what the app claims. Update\n * optimistically and let the re-push confirm.\n */\nexport const setHostTheme = async (theme: HostTheme): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [{ theme }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'setHostTheme failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAkC;AAClC,0BAAgC;AAChC,sBAAqD;AACrD,6BAAwB;AAgBxB,MAAM,cAAU,sCAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO,CAAC,QAAS,IAAI,UAAU,WAAW,IAAI,UAAU,SAAS,IAAI,QAAQ;AAC/E,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,oBAAoB,CAAC,aAAuD,QAAQ,SAAS,QAAQ;AAO3G,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAWlD,MAAM,eAAe,OAAO,UAAoC;AACrE,QAAM,MAAO,UAAM,qCAAgB,+BAAQ,8BAAc,GAAG,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AAI9E,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,qBAAqB;AAG3D,QAAI,QAAQ,OAAO,UAAU,MAAM,IAAI,OAAO,WAAc;AAC5D,UAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { protocolRequest } from './sandboxUtils';\nimport { PROTOCOL_THEME, REQUEST_THEME, REQUEST_THEME_CATALOG, THEME, THEME_CATALOG } from './generated/protocol';\nimport { SCHEMES } from './protocolSchemes';\n\n/**\n * The host UI theme polarity, mirrored from the immediately.run host window into\n * the sandbox. Your app can read this to render in step with the host chrome\n * (light / dark).\n *\n * This is the baseline `theme:read` capability — every app may read it. Changing\n * the host theme is a separate, elevated action (`theme:set`), available only to\n * the theme-toggle system app.\n *\n * `HostTheme` is the RESOLVED POLARITY only. The full selection — which theme is\n * active and which of its modes — is {@link HostThemeSelection}.\n */\nexport type HostTheme = 'light' | 'dark';\n\n/**\n * The full host theme selection (HOST_THEMING_SPEC §2/§9.1): the resolved polarity\n * plus the active theme's registry key and resolved mode. Carried on the widened\n * `theme` push. `modeId` is always the RESOLVED mode (never the literal `system` —\n * an app wants to know what is on screen).\n */\nexport interface HostThemeSelection {\n /** Resolved polarity — the same value the legacy `theme` field carried. */\n theme: HostTheme;\n /** The host-minted registry key of the active theme. */\n themeKey: string;\n /** The resolved active mode id of the active theme. */\n modeId: string;\n}\n\n/**\n * The selection assumed before the host reports. The platform default theme is\n * `immediately-run-default` (dark polarity first-paint, matching the shipped\n * provider default — HOST_THEMING_SPEC §3 build-time correction).\n */\nconst DEFAULT_SELECTION: HostThemeSelection = {\n theme: 'dark',\n themeKey: 'immediately-run-default',\n modeId: 'dark',\n};\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `theme` and\n// answers `request-theme` (wire format: site-main channelBridge.ts). The parse\n// reads ALL THREE fields so the full selection survives the transport; the\n// polarity-only surface derives from it.\nconst channel = createPushChannel<HostThemeSelection>({\n pushType: THEME,\n requestType: REQUEST_THEME,\n initial: DEFAULT_SELECTION,\n parse: (msg) => {\n if (msg.theme !== 'light' && msg.theme !== 'dark') return undefined;\n if (typeof msg.themeKey !== 'string' || typeof msg.modeId !== 'string') return undefined;\n return { theme: msg.theme, themeKey: msg.themeKey, modeId: msg.modeId };\n },\n});\n\n/**\n * Returns the current host theme polarity. Poll this for a one-off read; use\n * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.\n */\nexport const getHostTheme = (): HostTheme => channel.get().theme;\n\n/**\n * Subscribe to host theme polarity changes. The listener is invoked immediately\n * with the current polarity, then again on every change. Returns an unsubscribe fn.\n */\nexport const onHostThemeChange = (listener: (theme: HostTheme) => void): (() => void) =>\n channel.onChange((sel) => listener(sel.theme));\n\n/**\n * React hook returning the current host theme polarity, re-rendering when it\n * changes. The recommended way to implement an app's own `useTheme`: follow the\n * host, allow a local override.\n */\nexport const useHostTheme = (): HostTheme => channel.use().theme;\n\n/**\n * Returns the current full host theme selection — polarity, active theme key, and\n * resolved mode. Use {@link useHostThemeSelection} to react to changes.\n */\nexport const getHostThemeSelection = (): HostThemeSelection => channel.get();\n\n/**\n * Subscribe to full host theme selection changes. The listener is invoked\n * immediately with the current selection, then again on every change. Returns an\n * unsubscribe fn.\n */\nexport const onHostThemeSelectionChange = (listener: (selection: HostThemeSelection) => void): (() => void) =>\n channel.onChange(listener);\n\n/** React hook returning the current full host theme selection. */\nexport const useHostThemeSelection = (): HostThemeSelection => channel.use();\n\n/**\n * One entry of the theme catalogue: a selectable theme and its modes. The\n * catalogue is projected per grant — the baseline `theme:read` projection carries\n * NO source identities (no repo coordinates, no spaceIds), and labels are bounded.\n */\nexport interface ThemeCatalogEntry {\n themeKey: string;\n label: string;\n modes: { id: string; polarity: 'light' | 'dark' }[];\n}\n\n/**\n * The loaded-theme catalogue (HOST_THEMING_SPEC §9.2): every selectable theme, so\n * a theme-aware app can render a picker and match chrome. Pushed on\n * `theme-catalog` / polled with `request-theme-catalog`.\n */\nexport interface ThemeCatalog {\n themes: ThemeCatalogEntry[];\n}\n\nconst DEFAULT_CATALOG: ThemeCatalog = { themes: [] };\n\nconst catalogChannel = createPushChannel<ThemeCatalog>({\n pushType: THEME_CATALOG,\n requestType: REQUEST_THEME_CATALOG,\n initial: DEFAULT_CATALOG,\n parse: (msg) => {\n const themes = msg.themes;\n if (!Array.isArray(themes)) return undefined;\n const out: ThemeCatalogEntry[] = [];\n for (const t of themes as unknown[]) {\n if (!t || typeof t !== 'object') return undefined;\n const entry = t as { themeKey?: unknown; label?: unknown; modes?: unknown };\n if (typeof entry.themeKey !== 'string' || typeof entry.label !== 'string' || !Array.isArray(entry.modes)) {\n return undefined;\n }\n const modes: ThemeCatalogEntry['modes'] = [];\n for (const m of entry.modes) {\n if (!m || typeof m !== 'object') return undefined;\n const mode = m as { id?: unknown; polarity?: unknown };\n if (typeof mode.id !== 'string' || (mode.polarity !== 'light' && mode.polarity !== 'dark')) {\n return undefined;\n }\n modes.push({ id: mode.id, polarity: mode.polarity });\n }\n out.push({ themeKey: entry.themeKey, label: entry.label, modes });\n }\n return { themes: out };\n },\n});\n\n/**\n * Returns the current theme catalogue (themes + their modes). Use\n * {@link useThemeCatalog} to react to changes.\n */\nexport const getThemeCatalog = (): ThemeCatalog => catalogChannel.get();\n\n/**\n * Subscribe to theme catalogue changes. The listener is invoked immediately with\n * the current catalogue, then again on every change. Returns an unsubscribe fn.\n */\nexport const onThemeCatalogChange = (listener: (catalog: ThemeCatalog) => void): (() => void) =>\n catalogChannel.onChange(listener);\n\n/** React hook returning the current theme catalogue. */\nexport const useThemeCatalog = (): ThemeCatalog => catalogChannel.use();\n\n/**\n * A location the open-bundle picker returned — a repo or a space, with a\n * confined in-bundle path (OPEN_BUNDLE_SPEC §2). Carried to the host's\n * `theme:sources` `add-source` verb.\n */\nexport type ThemeBundleLocation =\n | { kind: 'repo'; repo: string; ref?: string; path: string }\n | { kind: 'space'; spaceId: string; path: string };\n\n/**\n * The canonical `theme:set` params (HOST_THEMING_SPEC §9.3). `theme` is the\n * registry key of the theme to select (or the legacy `'light' | 'dark'` polarity —\n * the host disambiguates by the reserved-id rule: legacy iff the value is\n * light/dark AND `mode` is absent). `mode` is one of that theme's modes or\n * `'system'`.\n */\nexport interface SetHostThemeSelectionParams {\n theme: string;\n mode?: string;\n}\n\n/** The one `set` call site, so the wire shape is fingerprint-stable. */\nconst setTheme = async (params: SetHostThemeSelectionParams): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [params])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'setHostTheme failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n\n/**\n * Set the host theme selection — the ELEVATED `theme:set` action\n * (HOST_THEMING_SPEC §9.3). `theme` is the registry key of the theme to select,\n * `mode` is one of that theme's modes or `'system'`. The host applies it and\n * re-pushes the new selection to every `theme:read` iframe, so your own\n * {@link useHostThemeSelection} confirms the change (the loop closes with no\n * special case). Only a grant holding `theme:set` (e.g. the theme-toggle system\n * app) may call this; any other app is rejected host-side with a `forbidden`\n * {@link Error} (carrying `.code`), regardless of what the app claims.\n */\nexport const setHostThemeSelection = async (selection: { theme: string; mode: string }): Promise<void> => {\n await setTheme(selection);\n};\n\n/**\n * Set the host UI theme polarity — the LEGACY form of `theme:set` (§9.3). The host\n * applies that polarity to the CURRENT theme (never resets to the default), then\n * re-pushes. Keep this alias for old-SDK callers; new code should prefer\n * {@link setHostThemeSelection}.\n */\nexport const setHostTheme = async (theme: HostTheme): Promise<void> => {\n await setTheme({ theme });\n};\n\n/**\n * Add a theme source — the ELEVATED `theme:sources` `add-source` verb\n * (HOST_THEMING_SPEC §9.3). `location` must be a location the host journal saw a\n * RECENT open-bundle invocation OF THIS APP return (the picker-provenance rule —\n * \"the pick is the consent\", machine-checked); anything else is rejected with a\n * readable reason. The host fetches, gates, and registers the theme before\n * returning, so a rejected pick surfaces inline in the switcher. Only a grant\n * holding `theme:sources` (the theme switcher) may call this.\n */\nexport const addThemeSource = async (location: ThemeBundleLocation): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'add-source', [{ location }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'addThemeSource failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n\n/**\n * Remove a theme source — the `theme:sources` `remove-source` verb (§9.3). If the\n * removed theme is the current selection, the host falls back to the default theme\n * (keeping the mode selection where it exists). The default theme is never\n * removable. Only a grant holding `theme:sources` may call this.\n */\nexport const removeThemeSource = async (themeKey: string): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'remove-source', [{ themeKey }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'removeThemeSource failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n"],"mappings":"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","names":[]}
package/dist/theme.d.cts CHANGED
@@ -1,38 +1,155 @@
1
1
  /**
2
- * The host UI theme, mirrored from the immediately.run host window into the
3
- * sandbox. Your app can read this to render in step with the host chrome
2
+ * The host UI theme polarity, mirrored from the immediately.run host window into
3
+ * the sandbox. Your app can read this to render in step with the host chrome
4
4
  * (light / dark).
5
5
  *
6
6
  * This is the baseline `theme:read` capability — every app may read it. Changing
7
7
  * the host theme is a separate, elevated action (`theme:set`), available only to
8
8
  * the theme-toggle system app.
9
+ *
10
+ * `HostTheme` is the RESOLVED POLARITY only. The full selection — which theme is
11
+ * active and which of its modes — is {@link HostThemeSelection}.
9
12
  */
10
13
  type HostTheme = 'light' | 'dark';
11
14
  /**
12
- * Returns the current host theme. Poll this for a one-off read; use
15
+ * The full host theme selection (HOST_THEMING_SPEC §2/§9.1): the resolved polarity
16
+ * plus the active theme's registry key and resolved mode. Carried on the widened
17
+ * `theme` push. `modeId` is always the RESOLVED mode (never the literal `system` —
18
+ * an app wants to know what is on screen).
19
+ */
20
+ interface HostThemeSelection {
21
+ /** Resolved polarity — the same value the legacy `theme` field carried. */
22
+ theme: HostTheme;
23
+ /** The host-minted registry key of the active theme. */
24
+ themeKey: string;
25
+ /** The resolved active mode id of the active theme. */
26
+ modeId: string;
27
+ }
28
+ /**
29
+ * Returns the current host theme polarity. Poll this for a one-off read; use
13
30
  * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.
14
31
  */
15
32
  declare const getHostTheme: () => HostTheme;
16
33
  /**
17
- * Subscribe to host theme changes. The listener is invoked immediately with the
18
- * current theme, then again on every change. Returns an unsubscribe fn.
34
+ * Subscribe to host theme polarity changes. The listener is invoked immediately
35
+ * with the current polarity, then again on every change. Returns an unsubscribe fn.
19
36
  */
20
37
  declare const onHostThemeChange: (listener: (theme: HostTheme) => void) => (() => void);
21
38
  /**
22
- * React hook returning the current host theme, re-rendering when it changes.
23
- * The recommended way to implement an app's own `useTheme`: follow the host,
24
- * allow a local override.
39
+ * React hook returning the current host theme polarity, re-rendering when it
40
+ * changes. The recommended way to implement an app's own `useTheme`: follow the
41
+ * host, allow a local override.
25
42
  */
26
43
  declare const useHostTheme: () => HostTheme;
27
44
  /**
28
- * Set the host UI theme — the ELEVATED `theme:set` action (§8.5). The host
29
- * applies it and re-pushes the new value to every `theme:read` iframe, so your
30
- * own {@link useHostTheme} confirms the change (the loop closes with no special
31
- * case). Only a grant holding `theme:set` (e.g. the theme-toggle system app) may
32
- * call this; any other app is rejected host-side with a `forbidden`
33
- * {@link Error} (carrying `.code`), regardless of what the app claims. Update
34
- * optimistically and let the re-push confirm.
45
+ * Returns the current full host theme selection — polarity, active theme key, and
46
+ * resolved mode. Use {@link useHostThemeSelection} to react to changes.
47
+ */
48
+ declare const getHostThemeSelection: () => HostThemeSelection;
49
+ /**
50
+ * Subscribe to full host theme selection changes. The listener is invoked
51
+ * immediately with the current selection, then again on every change. Returns an
52
+ * unsubscribe fn.
53
+ */
54
+ declare const onHostThemeSelectionChange: (listener: (selection: HostThemeSelection) => void) => (() => void);
55
+ /** React hook returning the current full host theme selection. */
56
+ declare const useHostThemeSelection: () => HostThemeSelection;
57
+ /**
58
+ * One entry of the theme catalogue: a selectable theme and its modes. The
59
+ * catalogue is projected per grant — the baseline `theme:read` projection carries
60
+ * NO source identities (no repo coordinates, no spaceIds), and labels are bounded.
61
+ */
62
+ interface ThemeCatalogEntry {
63
+ themeKey: string;
64
+ label: string;
65
+ modes: {
66
+ id: string;
67
+ polarity: 'light' | 'dark';
68
+ }[];
69
+ }
70
+ /**
71
+ * The loaded-theme catalogue (HOST_THEMING_SPEC §9.2): every selectable theme, so
72
+ * a theme-aware app can render a picker and match chrome. Pushed on
73
+ * `theme-catalog` / polled with `request-theme-catalog`.
74
+ */
75
+ interface ThemeCatalog {
76
+ themes: ThemeCatalogEntry[];
77
+ }
78
+ /**
79
+ * Returns the current theme catalogue (themes + their modes). Use
80
+ * {@link useThemeCatalog} to react to changes.
81
+ */
82
+ declare const getThemeCatalog: () => ThemeCatalog;
83
+ /**
84
+ * Subscribe to theme catalogue changes. The listener is invoked immediately with
85
+ * the current catalogue, then again on every change. Returns an unsubscribe fn.
86
+ */
87
+ declare const onThemeCatalogChange: (listener: (catalog: ThemeCatalog) => void) => (() => void);
88
+ /** React hook returning the current theme catalogue. */
89
+ declare const useThemeCatalog: () => ThemeCatalog;
90
+ /**
91
+ * A location the open-bundle picker returned — a repo or a space, with a
92
+ * confined in-bundle path (OPEN_BUNDLE_SPEC §2). Carried to the host's
93
+ * `theme:sources` `add-source` verb.
94
+ */
95
+ type ThemeBundleLocation = {
96
+ kind: 'repo';
97
+ repo: string;
98
+ ref?: string;
99
+ path: string;
100
+ } | {
101
+ kind: 'space';
102
+ spaceId: string;
103
+ path: string;
104
+ };
105
+ /**
106
+ * The canonical `theme:set` params (HOST_THEMING_SPEC §9.3). `theme` is the
107
+ * registry key of the theme to select (or the legacy `'light' | 'dark'` polarity —
108
+ * the host disambiguates by the reserved-id rule: legacy iff the value is
109
+ * light/dark AND `mode` is absent). `mode` is one of that theme's modes or
110
+ * `'system'`.
111
+ */
112
+ interface SetHostThemeSelectionParams {
113
+ theme: string;
114
+ mode?: string;
115
+ }
116
+ /**
117
+ * Set the host theme selection — the ELEVATED `theme:set` action
118
+ * (HOST_THEMING_SPEC §9.3). `theme` is the registry key of the theme to select,
119
+ * `mode` is one of that theme's modes or `'system'`. The host applies it and
120
+ * re-pushes the new selection to every `theme:read` iframe, so your own
121
+ * {@link useHostThemeSelection} confirms the change (the loop closes with no
122
+ * special case). Only a grant holding `theme:set` (e.g. the theme-toggle system
123
+ * app) may call this; any other app is rejected host-side with a `forbidden`
124
+ * {@link Error} (carrying `.code`), regardless of what the app claims.
125
+ */
126
+ declare const setHostThemeSelection: (selection: {
127
+ theme: string;
128
+ mode: string;
129
+ }) => Promise<void>;
130
+ /**
131
+ * Set the host UI theme polarity — the LEGACY form of `theme:set` (§9.3). The host
132
+ * applies that polarity to the CURRENT theme (never resets to the default), then
133
+ * re-pushes. Keep this alias for old-SDK callers; new code should prefer
134
+ * {@link setHostThemeSelection}.
35
135
  */
36
136
  declare const setHostTheme: (theme: HostTheme) => Promise<void>;
137
+ /**
138
+ * Add a theme source — the ELEVATED `theme:sources` `add-source` verb
139
+ * (HOST_THEMING_SPEC §9.3). `location` must be a location the host journal saw a
140
+ * RECENT open-bundle invocation OF THIS APP return (the picker-provenance rule —
141
+ * "the pick is the consent", machine-checked); anything else is rejected with a
142
+ * readable reason. The host fetches, gates, and registers the theme before
143
+ * returning, so a rejected pick surfaces inline in the switcher. Only a grant
144
+ * holding `theme:sources` (the theme switcher) may call this.
145
+ */
146
+ declare const addThemeSource: (location: ThemeBundleLocation) => Promise<void>;
147
+ /**
148
+ * Remove a theme source — the `theme:sources` `remove-source` verb (§9.3). If the
149
+ * removed theme is the current selection, the host falls back to the default theme
150
+ * (keeping the mode selection where it exists). The default theme is never
151
+ * removable. Only a grant holding `theme:sources` may call this.
152
+ */
153
+ declare const removeThemeSource: (themeKey: string) => Promise<void>;
37
154
 
38
- export { type HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme };
155
+ export { type HostTheme, type HostThemeSelection, type SetHostThemeSelectionParams, type ThemeBundleLocation, type ThemeCatalog, type ThemeCatalogEntry, addThemeSource, getHostTheme, getHostThemeSelection, getThemeCatalog, onHostThemeChange, onHostThemeSelectionChange, onThemeCatalogChange, removeThemeSource, setHostTheme, setHostThemeSelection, useHostTheme, useHostThemeSelection, useThemeCatalog };
package/dist/theme.d.ts CHANGED
@@ -1,38 +1,155 @@
1
1
  /**
2
- * The host UI theme, mirrored from the immediately.run host window into the
3
- * sandbox. Your app can read this to render in step with the host chrome
2
+ * The host UI theme polarity, mirrored from the immediately.run host window into
3
+ * the sandbox. Your app can read this to render in step with the host chrome
4
4
  * (light / dark).
5
5
  *
6
6
  * This is the baseline `theme:read` capability — every app may read it. Changing
7
7
  * the host theme is a separate, elevated action (`theme:set`), available only to
8
8
  * the theme-toggle system app.
9
+ *
10
+ * `HostTheme` is the RESOLVED POLARITY only. The full selection — which theme is
11
+ * active and which of its modes — is {@link HostThemeSelection}.
9
12
  */
10
13
  type HostTheme = 'light' | 'dark';
11
14
  /**
12
- * Returns the current host theme. Poll this for a one-off read; use
15
+ * The full host theme selection (HOST_THEMING_SPEC §2/§9.1): the resolved polarity
16
+ * plus the active theme's registry key and resolved mode. Carried on the widened
17
+ * `theme` push. `modeId` is always the RESOLVED mode (never the literal `system` —
18
+ * an app wants to know what is on screen).
19
+ */
20
+ interface HostThemeSelection {
21
+ /** Resolved polarity — the same value the legacy `theme` field carried. */
22
+ theme: HostTheme;
23
+ /** The host-minted registry key of the active theme. */
24
+ themeKey: string;
25
+ /** The resolved active mode id of the active theme. */
26
+ modeId: string;
27
+ }
28
+ /**
29
+ * Returns the current host theme polarity. Poll this for a one-off read; use
13
30
  * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.
14
31
  */
15
32
  declare const getHostTheme: () => HostTheme;
16
33
  /**
17
- * Subscribe to host theme changes. The listener is invoked immediately with the
18
- * current theme, then again on every change. Returns an unsubscribe fn.
34
+ * Subscribe to host theme polarity changes. The listener is invoked immediately
35
+ * with the current polarity, then again on every change. Returns an unsubscribe fn.
19
36
  */
20
37
  declare const onHostThemeChange: (listener: (theme: HostTheme) => void) => (() => void);
21
38
  /**
22
- * React hook returning the current host theme, re-rendering when it changes.
23
- * The recommended way to implement an app's own `useTheme`: follow the host,
24
- * allow a local override.
39
+ * React hook returning the current host theme polarity, re-rendering when it
40
+ * changes. The recommended way to implement an app's own `useTheme`: follow the
41
+ * host, allow a local override.
25
42
  */
26
43
  declare const useHostTheme: () => HostTheme;
27
44
  /**
28
- * Set the host UI theme — the ELEVATED `theme:set` action (§8.5). The host
29
- * applies it and re-pushes the new value to every `theme:read` iframe, so your
30
- * own {@link useHostTheme} confirms the change (the loop closes with no special
31
- * case). Only a grant holding `theme:set` (e.g. the theme-toggle system app) may
32
- * call this; any other app is rejected host-side with a `forbidden`
33
- * {@link Error} (carrying `.code`), regardless of what the app claims. Update
34
- * optimistically and let the re-push confirm.
45
+ * Returns the current full host theme selection — polarity, active theme key, and
46
+ * resolved mode. Use {@link useHostThemeSelection} to react to changes.
47
+ */
48
+ declare const getHostThemeSelection: () => HostThemeSelection;
49
+ /**
50
+ * Subscribe to full host theme selection changes. The listener is invoked
51
+ * immediately with the current selection, then again on every change. Returns an
52
+ * unsubscribe fn.
53
+ */
54
+ declare const onHostThemeSelectionChange: (listener: (selection: HostThemeSelection) => void) => (() => void);
55
+ /** React hook returning the current full host theme selection. */
56
+ declare const useHostThemeSelection: () => HostThemeSelection;
57
+ /**
58
+ * One entry of the theme catalogue: a selectable theme and its modes. The
59
+ * catalogue is projected per grant — the baseline `theme:read` projection carries
60
+ * NO source identities (no repo coordinates, no spaceIds), and labels are bounded.
61
+ */
62
+ interface ThemeCatalogEntry {
63
+ themeKey: string;
64
+ label: string;
65
+ modes: {
66
+ id: string;
67
+ polarity: 'light' | 'dark';
68
+ }[];
69
+ }
70
+ /**
71
+ * The loaded-theme catalogue (HOST_THEMING_SPEC §9.2): every selectable theme, so
72
+ * a theme-aware app can render a picker and match chrome. Pushed on
73
+ * `theme-catalog` / polled with `request-theme-catalog`.
74
+ */
75
+ interface ThemeCatalog {
76
+ themes: ThemeCatalogEntry[];
77
+ }
78
+ /**
79
+ * Returns the current theme catalogue (themes + their modes). Use
80
+ * {@link useThemeCatalog} to react to changes.
81
+ */
82
+ declare const getThemeCatalog: () => ThemeCatalog;
83
+ /**
84
+ * Subscribe to theme catalogue changes. The listener is invoked immediately with
85
+ * the current catalogue, then again on every change. Returns an unsubscribe fn.
86
+ */
87
+ declare const onThemeCatalogChange: (listener: (catalog: ThemeCatalog) => void) => (() => void);
88
+ /** React hook returning the current theme catalogue. */
89
+ declare const useThemeCatalog: () => ThemeCatalog;
90
+ /**
91
+ * A location the open-bundle picker returned — a repo or a space, with a
92
+ * confined in-bundle path (OPEN_BUNDLE_SPEC §2). Carried to the host's
93
+ * `theme:sources` `add-source` verb.
94
+ */
95
+ type ThemeBundleLocation = {
96
+ kind: 'repo';
97
+ repo: string;
98
+ ref?: string;
99
+ path: string;
100
+ } | {
101
+ kind: 'space';
102
+ spaceId: string;
103
+ path: string;
104
+ };
105
+ /**
106
+ * The canonical `theme:set` params (HOST_THEMING_SPEC §9.3). `theme` is the
107
+ * registry key of the theme to select (or the legacy `'light' | 'dark'` polarity —
108
+ * the host disambiguates by the reserved-id rule: legacy iff the value is
109
+ * light/dark AND `mode` is absent). `mode` is one of that theme's modes or
110
+ * `'system'`.
111
+ */
112
+ interface SetHostThemeSelectionParams {
113
+ theme: string;
114
+ mode?: string;
115
+ }
116
+ /**
117
+ * Set the host theme selection — the ELEVATED `theme:set` action
118
+ * (HOST_THEMING_SPEC §9.3). `theme` is the registry key of the theme to select,
119
+ * `mode` is one of that theme's modes or `'system'`. The host applies it and
120
+ * re-pushes the new selection to every `theme:read` iframe, so your own
121
+ * {@link useHostThemeSelection} confirms the change (the loop closes with no
122
+ * special case). Only a grant holding `theme:set` (e.g. the theme-toggle system
123
+ * app) may call this; any other app is rejected host-side with a `forbidden`
124
+ * {@link Error} (carrying `.code`), regardless of what the app claims.
125
+ */
126
+ declare const setHostThemeSelection: (selection: {
127
+ theme: string;
128
+ mode: string;
129
+ }) => Promise<void>;
130
+ /**
131
+ * Set the host UI theme polarity — the LEGACY form of `theme:set` (§9.3). The host
132
+ * applies that polarity to the CURRENT theme (never resets to the default), then
133
+ * re-pushes. Keep this alias for old-SDK callers; new code should prefer
134
+ * {@link setHostThemeSelection}.
35
135
  */
36
136
  declare const setHostTheme: (theme: HostTheme) => Promise<void>;
137
+ /**
138
+ * Add a theme source — the ELEVATED `theme:sources` `add-source` verb
139
+ * (HOST_THEMING_SPEC §9.3). `location` must be a location the host journal saw a
140
+ * RECENT open-bundle invocation OF THIS APP return (the picker-provenance rule —
141
+ * "the pick is the consent", machine-checked); anything else is rejected with a
142
+ * readable reason. The host fetches, gates, and registers the theme before
143
+ * returning, so a rejected pick surfaces inline in the switcher. Only a grant
144
+ * holding `theme:sources` (the theme switcher) may call this.
145
+ */
146
+ declare const addThemeSource: (location: ThemeBundleLocation) => Promise<void>;
147
+ /**
148
+ * Remove a theme source — the `theme:sources` `remove-source` verb (§9.3). If the
149
+ * removed theme is the current selection, the host falls back to the default theme
150
+ * (keeping the mode selection where it exists). The default theme is never
151
+ * removable. Only a grant holding `theme:sources` may call this.
152
+ */
153
+ declare const removeThemeSource: (themeKey: string) => Promise<void>;
37
154
 
38
- export { type HostTheme, getHostTheme, onHostThemeChange, setHostTheme, useHostTheme };
155
+ export { type HostTheme, type HostThemeSelection, type SetHostThemeSelectionParams, type ThemeBundleLocation, type ThemeCatalog, type ThemeCatalogEntry, addThemeSource, getHostTheme, getHostThemeSelection, getThemeCatalog, onHostThemeChange, onHostThemeSelectionChange, onThemeCatalogChange, removeThemeSource, setHostTheme, setHostThemeSelection, useHostTheme, useHostThemeSelection, useThemeCatalog };
package/dist/theme.js CHANGED
@@ -1,29 +1,104 @@
1
1
  import "./chunk-VHAA22YE.js";
2
2
  import { createPushChannel } from "./pushChannel";
3
3
  import { protocolRequest } from "./sandboxUtils";
4
- import { PROTOCOL_THEME, REQUEST_THEME, THEME } from "./generated/protocol";
4
+ import { PROTOCOL_THEME, REQUEST_THEME, REQUEST_THEME_CATALOG, THEME, THEME_CATALOG } from "./generated/protocol";
5
5
  import { SCHEMES } from "./protocolSchemes";
6
+ const DEFAULT_SELECTION = {
7
+ theme: "dark",
8
+ themeKey: "immediately-run-default",
9
+ modeId: "dark"
10
+ };
6
11
  const channel = createPushChannel({
7
12
  pushType: THEME,
8
13
  requestType: REQUEST_THEME,
9
- initial: "dark",
10
- parse: (msg) => msg.theme === "light" || msg.theme === "dark" ? msg.theme : void 0
14
+ initial: DEFAULT_SELECTION,
15
+ parse: (msg) => {
16
+ if (msg.theme !== "light" && msg.theme !== "dark") return void 0;
17
+ if (typeof msg.themeKey !== "string" || typeof msg.modeId !== "string") return void 0;
18
+ return { theme: msg.theme, themeKey: msg.themeKey, modeId: msg.modeId };
19
+ }
11
20
  });
12
- const getHostTheme = () => channel.get();
13
- const onHostThemeChange = (listener) => channel.onChange(listener);
14
- const useHostTheme = () => channel.use();
15
- const setHostTheme = async (theme) => {
16
- const res = await protocolRequest(SCHEMES[PROTOCOL_THEME], "set", [{ theme }]);
21
+ const getHostTheme = () => channel.get().theme;
22
+ const onHostThemeChange = (listener) => channel.onChange((sel) => listener(sel.theme));
23
+ const useHostTheme = () => channel.use().theme;
24
+ const getHostThemeSelection = () => channel.get();
25
+ const onHostThemeSelectionChange = (listener) => channel.onChange(listener);
26
+ const useHostThemeSelection = () => channel.use();
27
+ const DEFAULT_CATALOG = { themes: [] };
28
+ const catalogChannel = createPushChannel({
29
+ pushType: THEME_CATALOG,
30
+ requestType: REQUEST_THEME_CATALOG,
31
+ initial: DEFAULT_CATALOG,
32
+ parse: (msg) => {
33
+ const themes = msg.themes;
34
+ if (!Array.isArray(themes)) return void 0;
35
+ const out = [];
36
+ for (const t of themes) {
37
+ if (!t || typeof t !== "object") return void 0;
38
+ const entry = t;
39
+ if (typeof entry.themeKey !== "string" || typeof entry.label !== "string" || !Array.isArray(entry.modes)) {
40
+ return void 0;
41
+ }
42
+ const modes = [];
43
+ for (const m of entry.modes) {
44
+ if (!m || typeof m !== "object") return void 0;
45
+ const mode = m;
46
+ if (typeof mode.id !== "string" || mode.polarity !== "light" && mode.polarity !== "dark") {
47
+ return void 0;
48
+ }
49
+ modes.push({ id: mode.id, polarity: mode.polarity });
50
+ }
51
+ out.push({ themeKey: entry.themeKey, label: entry.label, modes });
52
+ }
53
+ return { themes: out };
54
+ }
55
+ });
56
+ const getThemeCatalog = () => catalogChannel.get();
57
+ const onThemeCatalogChange = (listener) => catalogChannel.onChange(listener);
58
+ const useThemeCatalog = () => catalogChannel.use();
59
+ const setTheme = async (params) => {
60
+ const res = await protocolRequest(SCHEMES[PROTOCOL_THEME], "set", [params]);
17
61
  if (!res || res.ok !== true) {
18
62
  const err = new Error(res?.message ?? "setHostTheme failed");
19
63
  err.code = (res && "code" in res ? res.code : void 0) ?? "unknown";
20
64
  throw err;
21
65
  }
22
66
  };
67
+ const setHostThemeSelection = async (selection) => {
68
+ await setTheme(selection);
69
+ };
70
+ const setHostTheme = async (theme) => {
71
+ await setTheme({ theme });
72
+ };
73
+ const addThemeSource = async (location) => {
74
+ const res = await protocolRequest(SCHEMES[PROTOCOL_THEME], "add-source", [{ location }]);
75
+ if (!res || res.ok !== true) {
76
+ const err = new Error(res?.message ?? "addThemeSource failed");
77
+ err.code = (res && "code" in res ? res.code : void 0) ?? "unknown";
78
+ throw err;
79
+ }
80
+ };
81
+ const removeThemeSource = async (themeKey) => {
82
+ const res = await protocolRequest(SCHEMES[PROTOCOL_THEME], "remove-source", [{ themeKey }]);
83
+ if (!res || res.ok !== true) {
84
+ const err = new Error(res?.message ?? "removeThemeSource failed");
85
+ err.code = (res && "code" in res ? res.code : void 0) ?? "unknown";
86
+ throw err;
87
+ }
88
+ };
23
89
  export {
90
+ addThemeSource,
24
91
  getHostTheme,
92
+ getHostThemeSelection,
93
+ getThemeCatalog,
25
94
  onHostThemeChange,
95
+ onHostThemeSelectionChange,
96
+ onThemeCatalogChange,
97
+ removeThemeSource,
26
98
  setHostTheme,
27
- useHostTheme
99
+ setHostThemeSelection,
100
+ useHostTheme,
101
+ useHostThemeSelection,
102
+ useThemeCatalog
28
103
  };
29
104
  //# sourceMappingURL=theme.js.map
package/dist/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { protocolRequest } from './sandboxUtils';\nimport { PROTOCOL_THEME, REQUEST_THEME, THEME } from './generated/protocol';\nimport { SCHEMES } from './protocolSchemes';\n\n/**\n * The host UI theme, mirrored from the immediately.run host window into the\n * sandbox. Your app can read this to render in step with the host chrome\n * (light / dark).\n *\n * This is the baseline `theme:read` capability — every app may read it. Changing\n * the host theme is a separate, elevated action (`theme:set`), available only to\n * the theme-toggle system app.\n */\nexport type HostTheme = 'light' | 'dark';\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `theme` and\n// answers `request-theme` (wire format: site-main channelBridge.ts). The host's\n// default before it reports is `dark` (sandbox themeState.DEFAULT_THEME).\nconst channel = createPushChannel<HostTheme>({\n pushType: THEME,\n requestType: REQUEST_THEME,\n initial: 'dark',\n parse: (msg) => (msg.theme === 'light' || msg.theme === 'dark' ? msg.theme : undefined),\n});\n\n/**\n * Returns the current host theme. Poll this for a one-off read; use\n * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.\n */\nexport const getHostTheme = (): HostTheme => channel.get();\n\n/**\n * Subscribe to host theme changes. The listener is invoked immediately with the\n * current theme, then again on every change. Returns an unsubscribe fn.\n */\nexport const onHostThemeChange = (listener: (theme: HostTheme) => void): (() => void) => channel.onChange(listener);\n\n/**\n * React hook returning the current host theme, re-rendering when it changes.\n * The recommended way to implement an app's own `useTheme`: follow the host,\n * allow a local override.\n */\nexport const useHostTheme = (): HostTheme => channel.use();\n\n/**\n * Set the host UI theme — the ELEVATED `theme:set` action (§8.5). The host\n * applies it and re-pushes the new value to every `theme:read` iframe, so your\n * own {@link useHostTheme} confirms the change (the loop closes with no special\n * case). Only a grant holding `theme:set` (e.g. the theme-toggle system app) may\n * call this; any other app is rejected host-side with a `forbidden`\n * {@link Error} (carrying `.code`), regardless of what the app claims. Update\n * optimistically and let the re-push confirm.\n */\nexport const setHostTheme = async (theme: HostTheme): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [{ theme }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'setHostTheme failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n"],"mappings":";AAAA,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,gBAAgB,eAAe,aAAa;AACrD,SAAS,eAAe;AAgBxB,MAAM,UAAU,kBAA6B;AAAA,EAC3C,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO,CAAC,QAAS,IAAI,UAAU,WAAW,IAAI,UAAU,SAAS,IAAI,QAAQ;AAC/E,CAAC;AAMM,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAMlD,MAAM,oBAAoB,CAAC,aAAuD,QAAQ,SAAS,QAAQ;AAO3G,MAAM,eAAe,MAAiB,QAAQ,IAAI;AAWlD,MAAM,eAAe,OAAO,UAAoC;AACrE,QAAM,MAAO,MAAM,gBAAgB,QAAQ,cAAc,GAAG,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;AAI9E,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,qBAAqB;AAG3D,QAAI,QAAQ,OAAO,UAAU,MAAM,IAAI,OAAO,WAAc;AAC5D,UAAM;AAAA,EACR;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/theme.ts"],"sourcesContent":["import { createPushChannel } from './pushChannel';\nimport { protocolRequest } from './sandboxUtils';\nimport { PROTOCOL_THEME, REQUEST_THEME, REQUEST_THEME_CATALOG, THEME, THEME_CATALOG } from './generated/protocol';\nimport { SCHEMES } from './protocolSchemes';\n\n/**\n * The host UI theme polarity, mirrored from the immediately.run host window into\n * the sandbox. Your app can read this to render in step with the host chrome\n * (light / dark).\n *\n * This is the baseline `theme:read` capability — every app may read it. Changing\n * the host theme is a separate, elevated action (`theme:set`), available only to\n * the theme-toggle system app.\n *\n * `HostTheme` is the RESOLVED POLARITY only. The full selection — which theme is\n * active and which of its modes — is {@link HostThemeSelection}.\n */\nexport type HostTheme = 'light' | 'dark';\n\n/**\n * The full host theme selection (HOST_THEMING_SPEC §2/§9.1): the resolved polarity\n * plus the active theme's registry key and resolved mode. Carried on the widened\n * `theme` push. `modeId` is always the RESOLVED mode (never the literal `system` —\n * an app wants to know what is on screen).\n */\nexport interface HostThemeSelection {\n /** Resolved polarity — the same value the legacy `theme` field carried. */\n theme: HostTheme;\n /** The host-minted registry key of the active theme. */\n themeKey: string;\n /** The resolved active mode id of the active theme. */\n modeId: string;\n}\n\n/**\n * The selection assumed before the host reports. The platform default theme is\n * `immediately-run-default` (dark polarity first-paint, matching the shipped\n * provider default — HOST_THEMING_SPEC §3 build-time correction).\n */\nconst DEFAULT_SELECTION: HostThemeSelection = {\n theme: 'dark',\n themeKey: 'immediately-run-default',\n modeId: 'dark',\n};\n\n// Read over the transport (SDK_PACKAGING_SPEC §4): the host pushes `theme` and\n// answers `request-theme` (wire format: site-main channelBridge.ts). The parse\n// reads ALL THREE fields so the full selection survives the transport; the\n// polarity-only surface derives from it.\nconst channel = createPushChannel<HostThemeSelection>({\n pushType: THEME,\n requestType: REQUEST_THEME,\n initial: DEFAULT_SELECTION,\n parse: (msg) => {\n if (msg.theme !== 'light' && msg.theme !== 'dark') return undefined;\n if (typeof msg.themeKey !== 'string' || typeof msg.modeId !== 'string') return undefined;\n return { theme: msg.theme, themeKey: msg.themeKey, modeId: msg.modeId };\n },\n});\n\n/**\n * Returns the current host theme polarity. Poll this for a one-off read; use\n * {@link onHostThemeChange} or {@link useHostTheme} to react to changes.\n */\nexport const getHostTheme = (): HostTheme => channel.get().theme;\n\n/**\n * Subscribe to host theme polarity changes. The listener is invoked immediately\n * with the current polarity, then again on every change. Returns an unsubscribe fn.\n */\nexport const onHostThemeChange = (listener: (theme: HostTheme) => void): (() => void) =>\n channel.onChange((sel) => listener(sel.theme));\n\n/**\n * React hook returning the current host theme polarity, re-rendering when it\n * changes. The recommended way to implement an app's own `useTheme`: follow the\n * host, allow a local override.\n */\nexport const useHostTheme = (): HostTheme => channel.use().theme;\n\n/**\n * Returns the current full host theme selection — polarity, active theme key, and\n * resolved mode. Use {@link useHostThemeSelection} to react to changes.\n */\nexport const getHostThemeSelection = (): HostThemeSelection => channel.get();\n\n/**\n * Subscribe to full host theme selection changes. The listener is invoked\n * immediately with the current selection, then again on every change. Returns an\n * unsubscribe fn.\n */\nexport const onHostThemeSelectionChange = (listener: (selection: HostThemeSelection) => void): (() => void) =>\n channel.onChange(listener);\n\n/** React hook returning the current full host theme selection. */\nexport const useHostThemeSelection = (): HostThemeSelection => channel.use();\n\n/**\n * One entry of the theme catalogue: a selectable theme and its modes. The\n * catalogue is projected per grant — the baseline `theme:read` projection carries\n * NO source identities (no repo coordinates, no spaceIds), and labels are bounded.\n */\nexport interface ThemeCatalogEntry {\n themeKey: string;\n label: string;\n modes: { id: string; polarity: 'light' | 'dark' }[];\n}\n\n/**\n * The loaded-theme catalogue (HOST_THEMING_SPEC §9.2): every selectable theme, so\n * a theme-aware app can render a picker and match chrome. Pushed on\n * `theme-catalog` / polled with `request-theme-catalog`.\n */\nexport interface ThemeCatalog {\n themes: ThemeCatalogEntry[];\n}\n\nconst DEFAULT_CATALOG: ThemeCatalog = { themes: [] };\n\nconst catalogChannel = createPushChannel<ThemeCatalog>({\n pushType: THEME_CATALOG,\n requestType: REQUEST_THEME_CATALOG,\n initial: DEFAULT_CATALOG,\n parse: (msg) => {\n const themes = msg.themes;\n if (!Array.isArray(themes)) return undefined;\n const out: ThemeCatalogEntry[] = [];\n for (const t of themes as unknown[]) {\n if (!t || typeof t !== 'object') return undefined;\n const entry = t as { themeKey?: unknown; label?: unknown; modes?: unknown };\n if (typeof entry.themeKey !== 'string' || typeof entry.label !== 'string' || !Array.isArray(entry.modes)) {\n return undefined;\n }\n const modes: ThemeCatalogEntry['modes'] = [];\n for (const m of entry.modes) {\n if (!m || typeof m !== 'object') return undefined;\n const mode = m as { id?: unknown; polarity?: unknown };\n if (typeof mode.id !== 'string' || (mode.polarity !== 'light' && mode.polarity !== 'dark')) {\n return undefined;\n }\n modes.push({ id: mode.id, polarity: mode.polarity });\n }\n out.push({ themeKey: entry.themeKey, label: entry.label, modes });\n }\n return { themes: out };\n },\n});\n\n/**\n * Returns the current theme catalogue (themes + their modes). Use\n * {@link useThemeCatalog} to react to changes.\n */\nexport const getThemeCatalog = (): ThemeCatalog => catalogChannel.get();\n\n/**\n * Subscribe to theme catalogue changes. The listener is invoked immediately with\n * the current catalogue, then again on every change. Returns an unsubscribe fn.\n */\nexport const onThemeCatalogChange = (listener: (catalog: ThemeCatalog) => void): (() => void) =>\n catalogChannel.onChange(listener);\n\n/** React hook returning the current theme catalogue. */\nexport const useThemeCatalog = (): ThemeCatalog => catalogChannel.use();\n\n/**\n * A location the open-bundle picker returned — a repo or a space, with a\n * confined in-bundle path (OPEN_BUNDLE_SPEC §2). Carried to the host's\n * `theme:sources` `add-source` verb.\n */\nexport type ThemeBundleLocation =\n | { kind: 'repo'; repo: string; ref?: string; path: string }\n | { kind: 'space'; spaceId: string; path: string };\n\n/**\n * The canonical `theme:set` params (HOST_THEMING_SPEC §9.3). `theme` is the\n * registry key of the theme to select (or the legacy `'light' | 'dark'` polarity —\n * the host disambiguates by the reserved-id rule: legacy iff the value is\n * light/dark AND `mode` is absent). `mode` is one of that theme's modes or\n * `'system'`.\n */\nexport interface SetHostThemeSelectionParams {\n theme: string;\n mode?: string;\n}\n\n/** The one `set` call site, so the wire shape is fingerprint-stable. */\nconst setTheme = async (params: SetHostThemeSelectionParams): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [params])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'setHostTheme failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n\n/**\n * Set the host theme selection — the ELEVATED `theme:set` action\n * (HOST_THEMING_SPEC §9.3). `theme` is the registry key of the theme to select,\n * `mode` is one of that theme's modes or `'system'`. The host applies it and\n * re-pushes the new selection to every `theme:read` iframe, so your own\n * {@link useHostThemeSelection} confirms the change (the loop closes with no\n * special case). Only a grant holding `theme:set` (e.g. the theme-toggle system\n * app) may call this; any other app is rejected host-side with a `forbidden`\n * {@link Error} (carrying `.code`), regardless of what the app claims.\n */\nexport const setHostThemeSelection = async (selection: { theme: string; mode: string }): Promise<void> => {\n await setTheme(selection);\n};\n\n/**\n * Set the host UI theme polarity — the LEGACY form of `theme:set` (§9.3). The host\n * applies that polarity to the CURRENT theme (never resets to the default), then\n * re-pushes. Keep this alias for old-SDK callers; new code should prefer\n * {@link setHostThemeSelection}.\n */\nexport const setHostTheme = async (theme: HostTheme): Promise<void> => {\n await setTheme({ theme });\n};\n\n/**\n * Add a theme source — the ELEVATED `theme:sources` `add-source` verb\n * (HOST_THEMING_SPEC §9.3). `location` must be a location the host journal saw a\n * RECENT open-bundle invocation OF THIS APP return (the picker-provenance rule —\n * \"the pick is the consent\", machine-checked); anything else is rejected with a\n * readable reason. The host fetches, gates, and registers the theme before\n * returning, so a rejected pick surfaces inline in the switcher. Only a grant\n * holding `theme:sources` (the theme switcher) may call this.\n */\nexport const addThemeSource = async (location: ThemeBundleLocation): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'add-source', [{ location }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'addThemeSource failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n\n/**\n * Remove a theme source — the `theme:sources` `remove-source` verb (§9.3). If the\n * removed theme is the current selection, the host falls back to the default theme\n * (keeping the mode selection where it exists). The default theme is never\n * removable. Only a grant holding `theme:sources` may call this.\n */\nexport const removeThemeSource = async (themeKey: string): Promise<void> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_THEME], 'remove-source', [{ themeKey }])) as\n | { ok: true; data?: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'removeThemeSource failed') as Error & {\n code?: string;\n };\n err.code = (res && 'code' in res ? res.code : undefined) ?? 'unknown';\n throw err;\n }\n};\n"],"mappings":"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","names":[]}
package/dist/version.cjs CHANGED
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  SDK_VERSION: () => SDK_VERSION
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const SDK_VERSION = "0.58.0";
24
+ const SDK_VERSION = "0.59.0";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  SDK_VERSION
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.58.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.59.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
@@ -1,4 +1,4 @@
1
1
  /** This SDK's package version, baked from package.json at build (SP2-6). */
2
- declare const SDK_VERSION = "0.58.0";
2
+ declare const SDK_VERSION = "0.59.0";
3
3
 
4
4
  export { SDK_VERSION };
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  /** This SDK's package version, baked from package.json at build (SP2-6). */
2
- declare const SDK_VERSION = "0.58.0";
2
+ declare const SDK_VERSION = "0.59.0";
3
3
 
4
4
  export { SDK_VERSION };
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "./chunk-VHAA22YE.js";
2
- const SDK_VERSION = "0.58.0";
2
+ const SDK_VERSION = "0.59.0";
3
3
  export {
4
4
  SDK_VERSION
5
5
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.58.0';\n"],"mappings":";AAIO,MAAM,cAAc;","names":[]}
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.59.0';\n"],"mappings":";AAIO,MAAM,cAAc;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immediately-run/sdk",
3
- "version": "0.58.0",
3
+ "version": "0.59.0",
4
4
  "description": "Runtime SDK for code executing inside an immediately.run sandbox.",
5
5
  "license": "MIT",
6
6
  "repository": "github:immediately-run/immediately-run-sdk",
@@ -64,7 +64,7 @@
64
64
  "@immediately-run/mdx-plugins": "0.5.0",
65
65
  "@immediately-run/platform-constants": "0.2.0",
66
66
  "@immediately-run/safe-content": "0.1.0",
67
- "@immediately-run/sandbox-protocol": "0.7.7",
67
+ "@immediately-run/sandbox-protocol": "0.8.2",
68
68
  "react-error-boundary": "^6.0.0"
69
69
  },
70
70
  "devDependencies": {