@nimblebrain/synapse
Advanced tools
| // src/ui/internal/inject-style.ts | ||
| function ensureStyle(id, css) { | ||
| if (typeof document === "undefined") return; | ||
| if (document.getElementById(id)) return; | ||
| const style = document.createElement("style"); | ||
| style.id = id; | ||
| style.textContent = css; | ||
| document.head.appendChild(style); | ||
| } | ||
| // src/ui/internal/base-reset.ts | ||
| var STYLE_ID = "nb-synapse-base"; | ||
| var RULES = "html, body, #root { height: 100%; } body { margin: 0; }"; | ||
| function injectBaseReset() { | ||
| ensureStyle(STYLE_ID, RULES); | ||
| } | ||
| export { ensureStyle, injectBaseReset }; | ||
| //# sourceMappingURL=chunk-3HQGHPNC.js.map | ||
| //# sourceMappingURL=chunk-3HQGHPNC.js.map |
| {"version":3,"sources":["../src/ui/internal/inject-style.ts","../src/ui/internal/base-reset.ts"],"names":[],"mappings":";AAKO,SAAS,WAAA,CAAY,IAAY,GAAA,EAAmB;AACzD,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAe,EAAE,CAAA,EAAG;AACjC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAK,EAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc,GAAA;AACpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;;;ACUA,IAAM,QAAA,GAAW,iBAAA;AACjB,IAAM,KAAA,GAAQ,yDAAA;AAOP,SAAS,eAAA,GAAwB;AACtC,EAAA,WAAA,CAAY,UAAU,KAAK,CAAA;AAC7B","file":"chunk-3HQGHPNC.js","sourcesContent":["/**\n * Inject a stylesheet into the document exactly once, keyed by `id`. Used for\n * the few things inline styles can't express — `@keyframes` and `:hover`/\n * `:focus` pseudo-states. SSR-safe (no-ops without `document`) and idempotent.\n */\nexport function ensureStyle(id: string, css: string): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(id)) return;\n const style = document.createElement(\"style\");\n style.id = id;\n style.textContent = css;\n document.head.appendChild(style);\n}\n","/**\n * The root-height chain every full-pane Synapse app needs, as a plain function\n * (no side effect on import — so a component can call it on render without the\n * mere act of importing injecting anything). The side-effect entry point is\n * `../base.ts` (`@nimblebrain/synapse/ui/base`).\n *\n * `AppFrame` sizes the app shell with `height: 100%`, which only resolves if its\n * ancestor chain (`#root` → `body` → `html`) has a definite height. Each app\n * iframe is its own bare document, so without this chain the shell collapses to\n * content height — full width, short height — inside the host pane.\n *\n * Percentages resolve against the actual pane box, which is correct whether the\n * app is sandboxed in an iframe or mounted into a host panel. A viewport unit\n * (`vh`/`dvh`) would instead assume the pane equals the viewport — wrong on\n * hosts that allocate a pane shorter than the viewport (it overflows with a\n * second scrollbar). The `#root` rule targets the conventional mount id and\n * harmlessly matches nothing if an app mounts elsewhere; `html, body` still\n * apply. `body { margin: 0 }` removes the UA default so the pane has no gap.\n */\n\nimport { ensureStyle } from \"./inject-style.js\";\n\nconst STYLE_ID = \"nb-synapse-base\";\nconst RULES = \"html, body, #root { height: 100%; } body { margin: 0; }\";\n\n/**\n * Inject the root-height + body-margin reset once. Idempotent (keyed by a\n * single style id) and SSR-safe (no-ops when `document` is unavailable, via\n * `ensureStyle`).\n */\nexport function injectBaseReset(): void {\n ensureStyle(STYLE_ID, RULES);\n}\n"]} |
| 'use strict'; | ||
| // src/ui/internal/inject-style.ts | ||
| function ensureStyle(id, css) { | ||
| if (typeof document === "undefined") return; | ||
| if (document.getElementById(id)) return; | ||
| const style = document.createElement("style"); | ||
| style.id = id; | ||
| style.textContent = css; | ||
| document.head.appendChild(style); | ||
| } | ||
| // src/ui/internal/base-reset.ts | ||
| var STYLE_ID = "nb-synapse-base"; | ||
| var RULES = "html, body, #root { height: 100%; } body { margin: 0; }"; | ||
| function injectBaseReset() { | ||
| ensureStyle(STYLE_ID, RULES); | ||
| } | ||
| exports.ensureStyle = ensureStyle; | ||
| exports.injectBaseReset = injectBaseReset; | ||
| //# sourceMappingURL=chunk-RX6XCLFF.cjs.map | ||
| //# sourceMappingURL=chunk-RX6XCLFF.cjs.map |
| {"version":3,"sources":["../src/ui/internal/inject-style.ts","../src/ui/internal/base-reset.ts"],"names":[],"mappings":";;;AAKO,SAAS,WAAA,CAAY,IAAY,GAAA,EAAmB;AACzD,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,IAAI,QAAA,CAAS,cAAA,CAAe,EAAE,CAAA,EAAG;AACjC,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,EAAA,KAAA,CAAM,EAAA,GAAK,EAAA;AACX,EAAA,KAAA,CAAM,WAAA,GAAc,GAAA;AACpB,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,KAAK,CAAA;AACjC;;;ACUA,IAAM,QAAA,GAAW,iBAAA;AACjB,IAAM,KAAA,GAAQ,yDAAA;AAOP,SAAS,eAAA,GAAwB;AACtC,EAAA,WAAA,CAAY,UAAU,KAAK,CAAA;AAC7B","file":"chunk-RX6XCLFF.cjs","sourcesContent":["/**\n * Inject a stylesheet into the document exactly once, keyed by `id`. Used for\n * the few things inline styles can't express — `@keyframes` and `:hover`/\n * `:focus` pseudo-states. SSR-safe (no-ops without `document`) and idempotent.\n */\nexport function ensureStyle(id: string, css: string): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(id)) return;\n const style = document.createElement(\"style\");\n style.id = id;\n style.textContent = css;\n document.head.appendChild(style);\n}\n","/**\n * The root-height chain every full-pane Synapse app needs, as a plain function\n * (no side effect on import — so a component can call it on render without the\n * mere act of importing injecting anything). The side-effect entry point is\n * `../base.ts` (`@nimblebrain/synapse/ui/base`).\n *\n * `AppFrame` sizes the app shell with `height: 100%`, which only resolves if its\n * ancestor chain (`#root` → `body` → `html`) has a definite height. Each app\n * iframe is its own bare document, so without this chain the shell collapses to\n * content height — full width, short height — inside the host pane.\n *\n * Percentages resolve against the actual pane box, which is correct whether the\n * app is sandboxed in an iframe or mounted into a host panel. A viewport unit\n * (`vh`/`dvh`) would instead assume the pane equals the viewport — wrong on\n * hosts that allocate a pane shorter than the viewport (it overflows with a\n * second scrollbar). The `#root` rule targets the conventional mount id and\n * harmlessly matches nothing if an app mounts elsewhere; `html, body` still\n * apply. `body { margin: 0 }` removes the UA default so the pane has no gap.\n */\n\nimport { ensureStyle } from \"./inject-style.js\";\n\nconst STYLE_ID = \"nb-synapse-base\";\nconst RULES = \"html, body, #root { height: 100%; } body { margin: 0; }\";\n\n/**\n * Inject the root-height + body-margin reset once. Idempotent (keyed by a\n * single style id) and SSR-safe (no-ops when `document` is unavailable, via\n * `ensureStyle`).\n */\nexport function injectBaseReset(): void {\n ensureStyle(STYLE_ID, RULES);\n}\n"]} |
| 'use strict'; | ||
| var chunkRX6XCLFF_cjs = require('../chunk-RX6XCLFF.cjs'); | ||
| // src/ui/base.ts | ||
| chunkRX6XCLFF_cjs.injectBaseReset(); | ||
| Object.defineProperty(exports, "injectBaseReset", { | ||
| enumerable: true, | ||
| get: function () { return chunkRX6XCLFF_cjs.injectBaseReset; } | ||
| }); | ||
| //# sourceMappingURL=base.cjs.map | ||
| //# sourceMappingURL=base.cjs.map |
| {"version":3,"sources":["../../src/ui/base.ts"],"names":["injectBaseReset"],"mappings":";;;;;AAqBAA,iCAAA,EAAgB","file":"base.cjs","sourcesContent":["/**\n * Establishes the root-height chain a full-pane Synapse app needs. Import for\n * the side effect:\n *\n * ```ts\n * import \"@nimblebrain/synapse/ui/base\";\n * ```\n *\n * This injects `html, body, #root { height: 100% }` (so a `height: 100%` app\n * shell resolves against the iframe's allocated pane) and `body { margin: 0 }`\n * (so the pane has no UA-margin gap). See `./internal/base-reset.ts` for why a\n * percentage chain — not a viewport unit — is the correct mechanism.\n *\n * `AppFrame` already calls `injectBaseReset()` on render, so apps built on it\n * get the chain automatically. Import this module explicitly to establish the\n * chain *before* React mounts — avoiding a first-paint layout jump — or for an\n * app that renders a full-pane root without `AppFrame`.\n */\n\nimport { injectBaseReset } from \"./internal/base-reset.js\";\n\ninjectBaseReset();\n\nexport { injectBaseReset };\n"]} |
| /** | ||
| * The root-height chain every full-pane Synapse app needs, as a plain function | ||
| * (no side effect on import — so a component can call it on render without the | ||
| * mere act of importing injecting anything). The side-effect entry point is | ||
| * `../base.ts` (`@nimblebrain/synapse/ui/base`). | ||
| * | ||
| * `AppFrame` sizes the app shell with `height: 100%`, which only resolves if its | ||
| * ancestor chain (`#root` → `body` → `html`) has a definite height. Each app | ||
| * iframe is its own bare document, so without this chain the shell collapses to | ||
| * content height — full width, short height — inside the host pane. | ||
| * | ||
| * Percentages resolve against the actual pane box, which is correct whether the | ||
| * app is sandboxed in an iframe or mounted into a host panel. A viewport unit | ||
| * (`vh`/`dvh`) would instead assume the pane equals the viewport — wrong on | ||
| * hosts that allocate a pane shorter than the viewport (it overflows with a | ||
| * second scrollbar). The `#root` rule targets the conventional mount id and | ||
| * harmlessly matches nothing if an app mounts elsewhere; `html, body` still | ||
| * apply. `body { margin: 0 }` removes the UA default so the pane has no gap. | ||
| */ | ||
| /** | ||
| * Inject the root-height + body-margin reset once. Idempotent (keyed by a | ||
| * single style id) and SSR-safe (no-ops when `document` is unavailable, via | ||
| * `ensureStyle`). | ||
| */ | ||
| declare function injectBaseReset(): void; | ||
| export { injectBaseReset }; |
| /** | ||
| * The root-height chain every full-pane Synapse app needs, as a plain function | ||
| * (no side effect on import — so a component can call it on render without the | ||
| * mere act of importing injecting anything). The side-effect entry point is | ||
| * `../base.ts` (`@nimblebrain/synapse/ui/base`). | ||
| * | ||
| * `AppFrame` sizes the app shell with `height: 100%`, which only resolves if its | ||
| * ancestor chain (`#root` → `body` → `html`) has a definite height. Each app | ||
| * iframe is its own bare document, so without this chain the shell collapses to | ||
| * content height — full width, short height — inside the host pane. | ||
| * | ||
| * Percentages resolve against the actual pane box, which is correct whether the | ||
| * app is sandboxed in an iframe or mounted into a host panel. A viewport unit | ||
| * (`vh`/`dvh`) would instead assume the pane equals the viewport — wrong on | ||
| * hosts that allocate a pane shorter than the viewport (it overflows with a | ||
| * second scrollbar). The `#root` rule targets the conventional mount id and | ||
| * harmlessly matches nothing if an app mounts elsewhere; `html, body` still | ||
| * apply. `body { margin: 0 }` removes the UA default so the pane has no gap. | ||
| */ | ||
| /** | ||
| * Inject the root-height + body-margin reset once. Idempotent (keyed by a | ||
| * single style id) and SSR-safe (no-ops when `document` is unavailable, via | ||
| * `ensureStyle`). | ||
| */ | ||
| declare function injectBaseReset(): void; | ||
| export { injectBaseReset }; |
| import { injectBaseReset } from '../chunk-3HQGHPNC.js'; | ||
| export { injectBaseReset } from '../chunk-3HQGHPNC.js'; | ||
| // src/ui/base.ts | ||
| injectBaseReset(); | ||
| //# sourceMappingURL=base.js.map | ||
| //# sourceMappingURL=base.js.map |
| {"version":3,"sources":["../../src/ui/base.ts"],"names":[],"mappings":";;;;AAqBA,eAAA,EAAgB","file":"base.js","sourcesContent":["/**\n * Establishes the root-height chain a full-pane Synapse app needs. Import for\n * the side effect:\n *\n * ```ts\n * import \"@nimblebrain/synapse/ui/base\";\n * ```\n *\n * This injects `html, body, #root { height: 100% }` (so a `height: 100%` app\n * shell resolves against the iframe's allocated pane) and `body { margin: 0 }`\n * (so the pane has no UA-margin gap). See `./internal/base-reset.ts` for why a\n * percentage chain — not a viewport unit — is the correct mechanism.\n *\n * `AppFrame` already calls `injectBaseReset()` on render, so apps built on it\n * get the chain automatically. Import this module explicitly to establish the\n * chain *before* React mounts — avoiding a first-paint layout jump — or for an\n * app that renders a full-pane root without `AppFrame`.\n */\n\nimport { injectBaseReset } from \"./internal/base-reset.js\";\n\ninjectBaseReset();\n\nexport { injectBaseReset };\n"]} |
| 'use strict'; | ||
| var chunk42N5BB5O_cjs = require('../chunk-42N5BB5O.cjs'); | ||
| var chunkHLT5UBJF_cjs = require('../chunk-HLT5UBJF.cjs'); | ||
| var chunk42N5BB5O_cjs = require('../chunk-42N5BB5O.cjs'); | ||
| Object.defineProperty(exports, "generateTypes", { | ||
| enumerable: true, | ||
| get: function () { return chunkHLT5UBJF_cjs.generateTypes; } | ||
| }); | ||
| Object.defineProperty(exports, "readFromManifest", { | ||
@@ -24,3 +20,7 @@ enumerable: true, | ||
| }); | ||
| Object.defineProperty(exports, "generateTypes", { | ||
| enumerable: true, | ||
| get: function () { return chunkHLT5UBJF_cjs.generateTypes; } | ||
| }); | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -0,4 +1,4 @@ | ||
| export { readFromManifest, readFromSchemaDir, readFromServer } from '../chunk-YWX3D24J.js'; | ||
| export { generateTypes } from '../chunk-JKHGWDZI.js'; | ||
| export { readFromManifest, readFromSchemaDir, readFromServer } from '../chunk-YWX3D24J.js'; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
+14
-24
| 'use strict'; | ||
| var chunkRX6XCLFF_cjs = require('../chunk-RX6XCLFF.cjs'); | ||
| var react = require('react'); | ||
| var jsxRuntime = require('react/jsx-runtime'); | ||
| // src/ui/components/Avatar.tsx | ||
| // src/ui/tokens.ts | ||
@@ -169,12 +168,2 @@ var tokens = { | ||
| } | ||
| // src/ui/internal/inject-style.ts | ||
| function ensureStyle(id, css) { | ||
| if (typeof document === "undefined") return; | ||
| if (document.getElementById(id)) return; | ||
| const style = document.createElement("style"); | ||
| style.id = id; | ||
| style.textContent = css; | ||
| document.head.appendChild(style); | ||
| } | ||
| var STYLE_ID = "nb-synapse-button"; | ||
@@ -227,3 +216,3 @@ var RULES = ` | ||
| }) { | ||
| ensureStyle(STYLE_ID, RULES); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID, RULES); | ||
| const vars = { | ||
@@ -258,3 +247,3 @@ "--nb-btn-radius": tokens.radiusSm, | ||
| function TextLink({ tone = "muted", style, className, children, ...rest }) { | ||
| ensureStyle(STYLE_ID, RULES); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID, RULES); | ||
| const resting = tone === "danger" ? tokens.danger : tone === "default" ? tokens.fg : tokens.fgMuted; | ||
@@ -301,3 +290,3 @@ const hover = tone === "danger" ? tokens.danger : tokens.accent; | ||
| }) { | ||
| if (interactive) ensureStyle(STYLE_ID2, RULES2); | ||
| if (interactive) chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID2, RULES2); | ||
| const cardStyle = { | ||
@@ -360,3 +349,3 @@ background: tokens.bgRaised, | ||
| }) { | ||
| ensureStyle(STYLE_ID3, RULES3); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID3, RULES3); | ||
| const dialogRef = react.useRef(null); | ||
@@ -680,3 +669,3 @@ const labelId = react.useId(); | ||
| }) { | ||
| ensureStyle(STYLE_ID4, RULES4); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID4, RULES4); | ||
| const rowStyle = { | ||
@@ -821,3 +810,3 @@ "--nb-listrow-hover": tokens.bgSubtle, | ||
| function Prose({ html, children, className, ...rest }) { | ||
| ensureStyle(STYLE_ID5, RULES5); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID5, RULES5); | ||
| const cls = `nb-prose ${className ?? ""}`.trim(); | ||
@@ -860,3 +849,3 @@ if (html !== void 0) { | ||
| }) { | ||
| ensureStyle(STYLE_ID6, RULES6); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID6, RULES6); | ||
| const fieldStyle = { | ||
@@ -920,3 +909,3 @@ "--nb-search-font": tokens.fontSans, | ||
| }) { | ||
| ensureStyle(STYLE_ID7, RULES7); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID7, RULES7); | ||
| const trackStyle = { | ||
@@ -957,3 +946,3 @@ "--nb-seg-radius": tokens.radiusSm, | ||
| function Spinner({ size = 16, color, style, className, ...rest }) { | ||
| ensureStyle(STYLE_ID8, RULES8); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID8, RULES8); | ||
| const spinnerStyle = { | ||
@@ -1009,3 +998,3 @@ display: "inline-block", | ||
| }) { | ||
| ensureStyle(STYLE_ID9, KEYFRAMES); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID9, KEYFRAMES); | ||
| const dotColor = color ?? COLOR[status]; | ||
@@ -1063,3 +1052,3 @@ const working = status === "working"; | ||
| }) { | ||
| ensureStyle(STYLE_ID10, RULES9); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID10, RULES9); | ||
| const vars = { | ||
@@ -1118,2 +1107,3 @@ "--nb-table-font": tokens.fontSans, | ||
| function AppFrameRoot({ contentWidth = "full", style, children, ...rest }) { | ||
| chunkRX6XCLFF_cjs.injectBaseReset(); | ||
| return /* @__PURE__ */ jsxRuntime.jsx(ContentWidthCtx.Provider, { value: contentWidth, children: /* @__PURE__ */ jsxRuntime.jsx( | ||
@@ -1313,3 +1303,3 @@ "div", | ||
| const { collapsed, mode, side, width, open, setOpen } = useSidebar(); | ||
| ensureStyle(STYLE_ID11, RULES10); | ||
| chunkRX6XCLFF_cjs.ensureStyle(STYLE_ID11, RULES10); | ||
| if (!collapsed) { | ||
@@ -1316,0 +1306,0 @@ const border = `${tokens.borderWidth} solid ${tokens.border}`; |
+2
-12
@@ -0,6 +1,5 @@ | ||
| import { ensureStyle, injectBaseReset } from '../chunk-3HQGHPNC.js'; | ||
| import { createContext, useRef, useId, useState, useEffect, useMemo, useContext, useLayoutEffect } from 'react'; | ||
| import { jsx, jsxs, Fragment } from 'react/jsx-runtime'; | ||
| // src/ui/components/Avatar.tsx | ||
| // src/ui/tokens.ts | ||
@@ -167,12 +166,2 @@ var tokens = { | ||
| } | ||
| // src/ui/internal/inject-style.ts | ||
| function ensureStyle(id, css) { | ||
| if (typeof document === "undefined") return; | ||
| if (document.getElementById(id)) return; | ||
| const style = document.createElement("style"); | ||
| style.id = id; | ||
| style.textContent = css; | ||
| document.head.appendChild(style); | ||
| } | ||
| var STYLE_ID = "nb-synapse-button"; | ||
@@ -1105,2 +1094,3 @@ var RULES = ` | ||
| function AppFrameRoot({ contentWidth = "full", style, children, ...rest }) { | ||
| injectBaseReset(); | ||
| return /* @__PURE__ */ jsx(ContentWidthCtx.Provider, { value: contentWidth, children: /* @__PURE__ */ jsx( | ||
@@ -1107,0 +1097,0 @@ "div", |
+6
-1
| { | ||
| "name": "@nimblebrain/synapse", | ||
| "version": "0.10.2", | ||
| "version": "0.11.0", | ||
| "description": "Agent-aware app SDK for the MCP ext-apps protocol", | ||
@@ -27,2 +27,7 @@ "type": "module", | ||
| }, | ||
| "./ui/base": { | ||
| "types": "./dist/ui/base.d.ts", | ||
| "import": "./dist/ui/base.js", | ||
| "require": "./dist/ui/base.cjs" | ||
| }, | ||
| "./vite": { | ||
@@ -29,0 +34,0 @@ "types": "./dist/vite/index.d.ts", |
+1
-0
@@ -48,2 +48,3 @@ # @nimblebrain/synapse | ||
| | `@nimblebrain/synapse/ui/fonts` | Side-effect import that loads the brand fonts into the iframe | | ||
| | `@nimblebrain/synapse/ui/base` | Side-effect import that establishes the root-height chain (`html, body, #root`) the app shell fills. `AppFrame` does this automatically on render; import it in your entry to apply it before first paint | | ||
| | `@nimblebrain/synapse/vite` | Vite plugin for dev mode | | ||
@@ -50,0 +51,0 @@ | `@nimblebrain/synapse/codegen` | CLI + programmatic code generation | |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
1757845
0.7%87
12.99%11342
0.53%477
0.21%