mockpit 0.0.0-stage → 1.0.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.
Files changed (82) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +232 -2
  3. package/bin/demoData.js +132 -0
  4. package/bin/initDesign.js +846 -0
  5. package/bin/mockpit.js +1830 -0
  6. package/bin/serveUrl.d.ts +1 -0
  7. package/bin/serveUrl.js +7 -0
  8. package/dist/mcp/server.d.ts +2 -0
  9. package/dist/mcp/server.js +230 -0
  10. package/dist/server/apiViews.d.ts +329 -0
  11. package/dist/server/apiViews.js +135 -0
  12. package/dist/server/app.d.ts +53 -0
  13. package/dist/server/app.js +3112 -0
  14. package/dist/server/base64.d.ts +1 -0
  15. package/dist/server/base64.js +16 -0
  16. package/dist/server/cdn.d.ts +6 -0
  17. package/dist/server/cdn.js +33 -0
  18. package/dist/server/codeRunner.d.ts +5 -0
  19. package/dist/server/codeRunner.js +89 -0
  20. package/dist/server/codeWorker.d.ts +1 -0
  21. package/dist/server/codeWorker.js +196 -0
  22. package/dist/server/designGuide.d.ts +16 -0
  23. package/dist/server/designGuide.js +311 -0
  24. package/dist/server/events.d.ts +53 -0
  25. package/dist/server/events.js +14 -0
  26. package/dist/server/feedbackBatch.d.ts +43 -0
  27. package/dist/server/feedbackBatch.js +98 -0
  28. package/dist/server/icons.d.ts +50 -0
  29. package/dist/server/icons.js +225 -0
  30. package/dist/server/index.d.ts +1 -0
  31. package/dist/server/index.js +64 -0
  32. package/dist/server/kits.d.ts +36 -0
  33. package/dist/server/kits.js +279 -0
  34. package/dist/server/knobs.d.ts +15 -0
  35. package/dist/server/knobs.js +333 -0
  36. package/dist/server/mcpHttp.d.ts +53 -0
  37. package/dist/server/mcpHttp.js +143 -0
  38. package/dist/server/mcpSpec.d.ts +191 -0
  39. package/dist/server/mcpSpec.js +402 -0
  40. package/dist/server/parts.d.ts +31 -0
  41. package/dist/server/parts.js +338 -0
  42. package/dist/server/postMarkdown.d.ts +10 -0
  43. package/dist/server/postMarkdown.js +271 -0
  44. package/dist/server/postSurfaces.d.ts +40 -0
  45. package/dist/server/postSurfaces.js +407 -0
  46. package/dist/server/public.d.ts +5 -0
  47. package/dist/server/public.js +5 -0
  48. package/dist/server/push.d.ts +45 -0
  49. package/dist/server/push.js +234 -0
  50. package/dist/server/richRender.d.ts +15 -0
  51. package/dist/server/richRender.js +392 -0
  52. package/dist/server/run.d.ts +82 -0
  53. package/dist/server/run.js +290 -0
  54. package/dist/server/runApi.d.ts +6 -0
  55. package/dist/server/runApi.js +82 -0
  56. package/dist/server/slots.d.ts +14 -0
  57. package/dist/server/slots.js +71 -0
  58. package/dist/server/sqlStore.d.ts +119 -0
  59. package/dist/server/sqlStore.js +954 -0
  60. package/dist/server/sqliteStorage.d.ts +2 -0
  61. package/dist/server/sqliteStorage.js +90 -0
  62. package/dist/server/surfacePage.d.ts +48 -0
  63. package/dist/server/surfacePage.js +1099 -0
  64. package/dist/server/themes.d.ts +48 -0
  65. package/dist/server/themes.js +305 -0
  66. package/dist/server/types.d.ts +599 -0
  67. package/dist/server/types.js +299 -0
  68. package/dist/workers/public.d.ts +1 -0
  69. package/dist/workers/public.js +3 -0
  70. package/extensions/mockpit.js +703 -0
  71. package/guide/AGENT_SETUP.md +23 -0
  72. package/guide/topics/asks.md +87 -0
  73. package/guide/topics/feedback.md +127 -0
  74. package/guide/topics/html.md +175 -0
  75. package/guide/topics/http.md +76 -0
  76. package/guide/topics/knobs.md +72 -0
  77. package/guide/topics/scripts.md +129 -0
  78. package/guide/topics/surfaces.md +100 -0
  79. package/package.json +165 -4
  80. package/skills/launch-video/SKILL.md +159 -0
  81. package/skills/mockpit/SKILL.md +40 -0
  82. package/viewer/dist/index.html +1922 -0
@@ -0,0 +1,2 @@
1
+ import type { SqlStorage } from "./types.ts";
2
+ export declare function createSqliteStorage(path?: string): SqlStorage;
@@ -0,0 +1,90 @@
1
+ import { mkdirSync } from "node:fs";
2
+ import { dirname } from "node:path";
3
+ // node:sqlite emits a one-time ExperimentalWarning when the builtin loads. It's
4
+ // stable enough for us (the store-contract suite runs SqlStore against it), so
5
+ // drop just that line while loading it, then restore the default handler. The
6
+ // import is dynamic so the patch is in place first — a static `import` is
7
+ // instantiated before any module body runs, too early to intercept. Every other
8
+ // warning is untouched.
9
+ const defaultEmitWarning = process.emitWarning;
10
+ process.emitWarning = function patched(warning, ...rest) {
11
+ const message = typeof warning === "string" ? warning : warning.message;
12
+ if (/\bSQLite is an experimental feature\b/.test(message))
13
+ return;
14
+ defaultEmitWarning(warning, ...rest);
15
+ };
16
+ // finally so the original handler is restored even if the import rejects (e.g.
17
+ // a Node build without node:sqlite) — otherwise the patch would leak and
18
+ // silently swallow later SQLite warnings from elsewhere.
19
+ let DatabaseSync;
20
+ try {
21
+ ({ DatabaseSync } = await import("node:sqlite"));
22
+ }
23
+ finally {
24
+ process.emitWarning = defaultEmitWarning;
25
+ }
26
+ function makeCursor(rows) {
27
+ return {
28
+ toArray: () => rows,
29
+ one: () => {
30
+ if (rows.length !== 1)
31
+ throw new Error(`Expected exactly one row, got ${rows.length}`);
32
+ return rows[0];
33
+ },
34
+ };
35
+ }
36
+ // A `SqlStorage` (the slice of a Durable Object's SQL API that SqlStore uses)
37
+ // backed by Node's built-in node:sqlite. Lets the SAME SqlStore run locally
38
+ // that runs on the Worker DO, so the two deploys exercise one storage code
39
+ // path. `:memory:` (the default) backs the store-contract suite; a file path is
40
+ // the real local store.
41
+ export function createSqliteStorage(path = ":memory:") {
42
+ if (path !== ":memory:") {
43
+ // node:sqlite won't create missing parent directories — it just fails with
44
+ // "unable to open database file", so a first run would always crash.
45
+ mkdirSync(dirname(path), { recursive: true });
46
+ }
47
+ const db = new DatabaseSync(path);
48
+ if (path !== ":memory:") {
49
+ // WAL + NORMAL: durable across a crash, far fewer fsyncs than the default
50
+ // — the right tradeoff for a single-process local server.
51
+ db.exec("PRAGMA journal_mode = WAL");
52
+ db.exec("PRAGMA synchronous = NORMAL");
53
+ }
54
+ return {
55
+ exec(query, ...bindings) {
56
+ // Schema DDL (multi-statement) and transaction control can't be run as a
57
+ // bound prepared statement — hand them to db.exec() directly. Everything
58
+ // else is a single prepared statement, matching the DO's exec(). The
59
+ // `bindings.length === 0` guard relies on SqlStore never issuing a
60
+ // zero-binding query that contains a literal `;` (it inlines no values —
61
+ // every dynamic value is a bound `?`), so a semicolon only ever means DDL.
62
+ const control = bindings.length === 0 &&
63
+ (/;\s*\S/.test(query) || /^\s*(BEGIN|COMMIT|ROLLBACK)\b/i.test(query));
64
+ if (control) {
65
+ db.exec(query);
66
+ return makeCursor([]);
67
+ }
68
+ // node:sqlite binds blobs as Uint8Array; the SqlStorage contract passes
69
+ // them as ArrayBuffer — adapt so BLOB columns round-trip.
70
+ const params = bindings.map((b) => (b instanceof ArrayBuffer ? new Uint8Array(b) : b));
71
+ const rows = db.prepare(query).all(...params);
72
+ return makeCursor(rows);
73
+ },
74
+ transactionSync(fn) {
75
+ // Already inside one (a store method composing another): join it.
76
+ if (db.isTransaction)
77
+ return fn();
78
+ db.exec("BEGIN");
79
+ try {
80
+ const result = fn();
81
+ db.exec("COMMIT");
82
+ return result;
83
+ }
84
+ catch (err) {
85
+ db.exec("ROLLBACK");
86
+ throw err;
87
+ }
88
+ },
89
+ };
90
+ }
@@ -0,0 +1,48 @@
1
+ import { type IconResolver } from "./icons.ts";
2
+ import type { DesignSettings } from "./types.ts";
3
+ import { type Mode, type Theme } from "./themes.ts";
4
+ export declare const BRIDGE_JS = "\nwindow.sendPrompt = function (text) {\n parent.postMessage({ __mockpit: true, type: 'send-prompt', text: String(text) }, '*');\n};\nwindow.openLink = function (url) {\n parent.postMessage({ __mockpit: true, type: 'open-link', url: String(url) }, '*');\n};\nwindow.copyToClipboard = function (text) {\n parent.postMessage({ __mockpit: true, type: 'copy', text: String(text) }, '*');\n};\ndocument.addEventListener('click', function (e) {\n var a = e.target && e.target.closest ? e.target.closest('a[href]') : null;\n if (a && /^https?:/.test(a.href)) { e.preventDefault(); window.openLink(a.href); }\n});\n// Cmd+Option+Up/Down switches sessions in the sidebar, but keydowns fire in\n// whichever document holds focus \u2014 once the user clicks into a surface, this\n// sandboxed iframe swallows them. Forward just that combo to the host.\ndocument.addEventListener('keydown', function (e) {\n if (!e.metaKey || !e.altKey || e.ctrlKey || e.shiftKey) return;\n if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return;\n e.preventDefault();\n parent.postMessage({ __mockpit: true, type: 'switch-session', key: e.key }, '*');\n});\n// Report content height to the parent so it can size this iframe, while\n// breaking a feedback loop that can peg a CPU core.\n//\n// The loop: the parent sets the iframe's height to whatever we report, but some\n// content's height *inverts* with the frame's height \u2014 a scrollbar that appears\n// at height A reflows the content to height B, then disappears at B and reflows\n// back to A (or any 100vh / percentage-derived layout). The ResizeObserver then\n// fires on every flip, so reported heights alternate A, B, A, B... forever. With\n// a cheap surface that's a brief blip; with a heavy one (a big syntax-highlighted\n// diff/markdown surface) each relayout is expensive and the tab sits at 100% CPU\n// until the surface unmounts.\n//\n// A plain h !== __lastH guard can't stop this: in a 2-cycle every value differs\n// from the one immediately before it. So we remember the previous height too and\n// defer a return to it *if it recurs faster than a human could* (< 250ms) \u2014 that's\n// the runaway. The deferred pass keeps one trailing re-measure and reports the\n// taller height in the pair, so an ordinary font/image reflow can't leave the\n// frame permanently clipped.\nvar __lastH = 0;\nvar __prevH = 0;\nvar __lastT = 0;\nvar __seenH = 0;\nvar __trailTimer = 0;\nvar __trailH = 0;\nvar __FLIP_MS = 250;\nvar __TRAIL_MS = 350;\nfunction __now() {\n return typeof performance !== 'undefined' && performance.now ? performance.now() : Date.now();\n}\nfunction __measureHeight() {\n return document.body\n ? document.body.scrollHeight\n : document.documentElement.scrollHeight;\n}\nfunction __postHeight(h, t) {\n __prevH = __lastH;\n __lastH = h;\n __lastT = t;\n parent.postMessage({ __mockpit: true, type: 'resize', height: h }, '*');\n}\nfunction __clearTrailing() {\n if (__trailTimer && typeof clearTimeout !== 'undefined') clearTimeout(__trailTimer);\n __trailTimer = 0;\n __trailH = 0;\n}\nfunction __flushTrailing() {\n __trailTimer = 0;\n var measured = __measureHeight();\n if (measured > 0) __seenH = measured;\n var target = Math.max(__trailH || 0, measured || 0);\n __trailH = 0;\n if (target <= 0 || target === __lastH) return;\n __postHeight(target, __now());\n}\nfunction __scheduleTrailing(h, reset) {\n __trailH = Math.max(__trailH || 0, h || 0, __lastH || 0);\n if (__trailTimer) {\n if (!reset) return;\n if (typeof clearTimeout !== 'undefined') clearTimeout(__trailTimer);\n }\n __trailTimer = setTimeout(__flushTrailing, __TRAIL_MS);\n}\nfunction __report() {\n var h = __measureHeight();\n if (h <= 0) return; // no content yet\n var changed = h !== __seenH;\n __seenH = h;\n if (h === __lastH) return; // unchanged\n var t = __now();\n if (h === __prevH && (__trailTimer || t - __lastT < __FLIP_MS)) {\n __scheduleTrailing(h, true); // rapid A<->B flip: defer one settled report\n return;\n }\n __clearTrailing();\n __postHeight(h, t);\n}\nif (document.readyState === 'complete') __report();\nelse window.addEventListener('load', function () { requestAnimationFrame(__report); });\nsetTimeout(__report, 60);\nsetTimeout(__report, 350);\nsetTimeout(__report, 1500);\nsetTimeout(__report, 3000);\nsetTimeout(__report, 6000);\nsetTimeout(__report, 10000);\nif (document.fonts && document.fonts.ready && document.fonts.ready.then) {\n document.fonts.ready.then(function () { __report(); });\n}\nif (window.ResizeObserver) {\n window.__ssRO = new ResizeObserver(__report);\n window.__ssRO.observe(document.documentElement);\n if (document.body) window.__ssRO.observe(document.body);\n}\n";
5
+ export declare const HIT_TEST_JS = "\n(function () {\n var MAX_DEPTH = 6;\n var MAX_TEXT = 60;\n function docBox() {\n var w = document.documentElement.clientWidth || 1;\n var h = (document.body && document.body.scrollHeight) || document.documentElement.scrollHeight || 1;\n return { w: w, h: h };\n }\n function ident(v) { return typeof v === 'string' && /^[A-Za-z][\\w-]*$/.test(v); }\n function cssPath(el) {\n var parts = [];\n while (el && el.nodeType === 1 && el !== document.body && el !== document.documentElement) {\n var tag = el.tagName.toLowerCase();\n if (ident(el.id)) { parts.unshift(tag + '#' + el.id); break; }\n var sel = tag;\n var cls = (el.getAttribute('class') || '').split(/\\s+/).filter(ident).slice(0, 2);\n if (cls.length) sel += '.' + cls.join('.');\n var p = el.parentElement;\n if (p) {\n var sibs = [];\n for (var i = 0; i < p.children.length; i++) {\n if (p.children[i].tagName === el.tagName) sibs.push(p.children[i]);\n }\n if (sibs.length > 1) sel += ':nth-of-type(' + (sibs.indexOf(el) + 1) + ')';\n }\n parts.unshift(sel);\n if (parts.length >= MAX_DEPTH) break;\n el = p;\n }\n return parts.join(' > ');\n }\n function firstLine(el) {\n var t = (el.innerText || el.textContent || '').replace(/\\s+/g, ' ').trim();\n var line = t.split('\\n')[0].trim();\n return line.length > MAX_TEXT ? line.slice(0, MAX_TEXT - 1) + '\\u2026' : line;\n }\n window.addEventListener('message', function (e) {\n if (e.source !== parent || parent === window) return;\n var d = e.data;\n if (!d || d.__mockpit !== true || d.type !== 'hit-test') return;\n var box = docBox();\n var px = Math.max(0, Math.min(1, Number(d.x) || 0)) * box.w;\n var py = Math.max(0, Math.min(1, Number(d.y) || 0)) * box.h;\n var el = document.elementFromPoint(px - (window.scrollX || 0), py - (window.scrollY || 0));\n var reply = { __mockpit: true, type: 'hit-test-result', ref: d.ref, path: '', text: '', rect: [0, 0, 0, 0] };\n if (el && el.nodeType === 1) {\n var r = el.getBoundingClientRect();\n reply.path = cssPath(el);\n reply.text = firstLine(el);\n reply.rect = [\n (r.left + (window.scrollX || 0)) / box.w,\n (r.top + (window.scrollY || 0)) / box.h,\n r.width / box.w,\n r.height / box.h,\n ];\n }\n parent.postMessage(reply, '*');\n });\n})();\n";
6
+ export declare const PARTS_JS = "\n(function () {\n if (window.parent === window) return;\n var HL = 'mockpit-part-hl';\n var MAX_PARTS = 200;\n var MAX_TEXT = 200;\n var doc = window.__mockpitDoc || {};\n var version = typeof doc.version === 'number' ? doc.version : null;\n function text(v) { return v == null ? null : String(v).slice(0, MAX_TEXT); }\n function isFixed(el) {\n for (var n = el; n && n.nodeType === 1; n = n.parentElement) {\n if (getComputedStyle(n).position === 'fixed') return true;\n }\n return false;\n }\n function collect() {\n var sx = window.scrollX || 0, sy = window.scrollY || 0;\n var els = document.querySelectorAll('[data-part]');\n var parts = [];\n for (var i = 0; i < els.length && parts.length < MAX_PARTS; i++) {\n var el = els[i];\n var name = text(el.getAttribute('data-part'));\n if (!name) continue;\n var r = el.getBoundingClientRect();\n var depth = 0;\n for (var p = el.parentElement; p; p = p.parentElement) if (p.hasAttribute('data-part')) depth++;\n var outer = el.parentElement && el.parentElement.closest('[data-part]');\n parts.push({\n name: name,\n label: text(el.getAttribute('data-part-label')) || name,\n key: text(el.getAttribute('data-part-key')),\n box: { x: r.left + sx, y: r.top + sy, w: r.width, h: r.height },\n visible: (r.width > 0 || r.height > 0) && getComputedStyle(el).visibility !== 'hidden',\n fixed: isFixed(el),\n depth: depth,\n parent: outer ? text(outer.getAttribute('data-part')) : null,\n order: i,\n });\n }\n return {\n version: version,\n parts: parts,\n height: document.body ? document.body.scrollHeight : document.documentElement.scrollHeight,\n scroll: { x: sx, y: sy },\n viewport: { w: innerWidth, h: innerHeight },\n };\n }\n var last = '';\n var timer = 0;\n // setTimeout, not rAF: a hidden cross-origin frame may have rendering (and\n // with it rAF and ResizeObserver) throttled, but timers still run.\n function schedule() {\n if (timer) return;\n timer = setTimeout(function () {\n timer = 0;\n var m = collect();\n var key = JSON.stringify(m);\n if (key === last) return;\n last = key;\n m.__mockpit = true;\n m.type = 'parts';\n parent.postMessage(m, '*');\n }, 0);\n }\n\n var ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(schedule) : null;\n var observed = typeof WeakSet !== 'undefined' ? new WeakSet() : null;\n function observeAll() {\n if (!ro || !observed) return;\n // html/body too: a non-part sibling growing moves parts without resizing them.\n var els = [document.documentElement, document.body].concat([].slice.call(document.querySelectorAll('[data-part]')));\n for (var i = 0; i < els.length; i++) {\n var el = els[i];\n if (el && !observed.has(el)) { observed.add(el); ro.observe(el); }\n }\n }\n var moTimer = 0;\n var mo = new MutationObserver(function () {\n clearTimeout(moTimer);\n moTimer = setTimeout(function () { observeAll(); schedule(); }, 40);\n });\n mo.observe(document.documentElement, { subtree: true, childList: true, attributes: true, characterData: true });\n\n // Transforms and transitions move boxes without resizing or mutating anything.\n document.addEventListener('animationend', schedule, true);\n document.addEventListener('transitionend', schedule, true);\n window.addEventListener('scroll', schedule, { passive: true });\n window.addEventListener('resize', schedule);\n if (document.fonts && document.fonts.ready) document.fonts.ready.then(schedule);\n observeAll();\n schedule();\n // WebKit: RO's initial callback may never fire in a sandboxed frame.\n function settle() {\n schedule();\n [50, 150, 400, 1000].forEach(function (ms) { setTimeout(schedule, ms); });\n }\n if (document.readyState === 'complete') settle();\n else window.addEventListener('load', settle);\n\n function setHighlight(names) {\n var on = document.querySelectorAll('.' + HL);\n for (var i = 0; i < on.length; i++) on[i].classList.remove(HL);\n if (names && names.length) {\n var want = {};\n for (var k = 0; k < names.length && k < MAX_PARTS; k++) want[String(names[k])] = true;\n var els = document.querySelectorAll('[data-part]');\n for (var j = 0; j < els.length; j++) {\n if (want[els[j].getAttribute('data-part')] === true) els[j].classList.add(HL);\n }\n }\n // Our own class flip must not look like the agent's page changing.\n mo.takeRecords();\n }\n\n window.addEventListener('message', function (e) {\n if (e.source !== parent) return;\n var d = e.data;\n if (!d || d.__mockpit !== true) return;\n if (d.type === 'highlight') setHighlight(Array.isArray(d.parts) ? d.parts : []);\n else if (d.type === 'clear') setHighlight(null);\n else if (d.type === 'scroll') window.scrollBy(Number(d.dx) || 0, Number(d.dy) || 0);\n else if (d.type === 'hit') {\n var el = document.elementFromPoint(\n (Number(d.x) || 0) - (window.scrollX || 0),\n (Number(d.y) || 0) - (window.scrollY || 0)\n );\n var part = el && el.closest ? el.closest('[data-part]') : null;\n parent.postMessage({\n __mockpit: true,\n type: 'hit',\n ref: d.ref,\n part: part ? text(part.getAttribute('data-part')) : null,\n key: part ? text(part.getAttribute('data-part-key')) : null,\n }, '*');\n }\n });\n})();\n";
7
+ export declare const KNOBS_JS = "\n(function () {\n\nvar __kPathRe = /^[A-Za-z_][\\w-]{0,63}(\\.[A-Za-z_][\\w-]{0,63}){0,3}$/;\nvar __kTokenRe = /^[#\\w(),.%/+-][#\\w\\s(),.%/+-]*$/;\nfunction __kName(path) { return path.replace(/\\./g, '-'); }\nfunction __kCssString(s) {\n return '\"' + s.replace(/[\\\\\"]/g, function (c) { return '\\\\' + c; })\n .replace(/[\\u0000-\\u001f\\u007f]/g, function (c) { return '\\\\' + c.charCodeAt(0).toString(16) + ' '; }) + '\"';\n}\nfunction __kCss(v) {\n if (typeof v === 'number') return isFinite(v) ? String(v) : null;\n if (typeof v === 'boolean') return v ? '1' : '0';\n if (typeof v === 'string') return __kTokenRe.test(v) ? v : __kCssString(v);\n return null;\n}\nfunction __kVars(path, v) {\n var name = __kName(path);\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n var out = [];\n for (var f in v) {\n if (!Object.prototype.hasOwnProperty.call(v, f) || !/^[A-Za-z_][\\w-]{0,63}$/.test(f)) continue;\n var c = __kCss(v[f]);\n if (c !== null) out.push([name + '-' + f, c]);\n }\n return out;\n }\n var css = __kCss(v);\n return css === null ? [] : [[name, css]];\n}\nfunction __kAttr(v) {\n if (typeof v === 'number') return isFinite(v) ? String(v) : null;\n if (typeof v === 'boolean') return v ? 'true' : 'false';\n if (typeof v === 'string') return v;\n return null;\n}\n\n var doc = window.__mockpitDoc || {};\n var current = {};\n function own(o, k) { return Object.prototype.hasOwnProperty.call(o, k); }\n function bind(path, v) {\n var els = document.querySelectorAll('[data-k-bind]');\n for (var i = 0; i < els.length; i++) {\n if (els[i].getAttribute('data-k-bind') !== path) continue;\n els[i].textContent = v && typeof v === 'object' ? JSON.stringify(v) : String(v);\n }\n }\n function apply(values, live) {\n var root = document.documentElement;\n for (var path in values) {\n if (!own(values, path) || !__kPathRe.test(path)) continue;\n var v = values[path];\n if (v === null || v === undefined) continue;\n current[path] = v;\n if (live) {\n var vars = __kVars(path, v);\n if (!vars.length) root.style.removeProperty('--k-' + __kName(path));\n for (var i = 0; i < vars.length; i++) root.style.setProperty('--k-' + vars[i][0], vars[i][1]);\n var attr = __kAttr(v);\n if (attr === null) root.removeAttribute('data-k-' + __kName(path));\n else root.setAttribute('data-k-' + __kName(path), attr);\n }\n bind(path, v);\n }\n window.dispatchEvent(new CustomEvent('mockpit:knobs', {\n detail: { values: JSON.parse(JSON.stringify(current)) },\n }));\n }\n function initial() { apply(doc.knobs && typeof doc.knobs === 'object' ? doc.knobs : {}, false); }\n if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', initial);\n else initial();\n window.addEventListener('message', function (e) {\n if (e.source !== parent || parent === window) return;\n var d = e.data;\n if (!d || d.__mockpit !== true || d.type !== 'knobs') return;\n if (d.values && typeof d.values === 'object' && !Array.isArray(d.values)) apply(d.values, true);\n });\n})();\n";
8
+ export declare function knobCss(v: unknown): string | null;
9
+ export declare function knobVars(path: string, v: unknown): [string, string][];
10
+ export declare function knobAttr(v: unknown): string | null;
11
+ export declare const KNOB_VALUE_SOURCE = "\nvar __kPathRe = /^[A-Za-z_][\\w-]{0,63}(\\.[A-Za-z_][\\w-]{0,63}){0,3}$/;\nvar __kTokenRe = /^[#\\w(),.%/+-][#\\w\\s(),.%/+-]*$/;\nfunction __kName(path) { return path.replace(/\\./g, '-'); }\nfunction __kCssString(s) {\n return '\"' + s.replace(/[\\\\\"]/g, function (c) { return '\\\\' + c; })\n .replace(/[\\u0000-\\u001f\\u007f]/g, function (c) { return '\\\\' + c.charCodeAt(0).toString(16) + ' '; }) + '\"';\n}\nfunction __kCss(v) {\n if (typeof v === 'number') return isFinite(v) ? String(v) : null;\n if (typeof v === 'boolean') return v ? '1' : '0';\n if (typeof v === 'string') return __kTokenRe.test(v) ? v : __kCssString(v);\n return null;\n}\nfunction __kVars(path, v) {\n var name = __kName(path);\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n var out = [];\n for (var f in v) {\n if (!Object.prototype.hasOwnProperty.call(v, f) || !/^[A-Za-z_][\\w-]{0,63}$/.test(f)) continue;\n var c = __kCss(v[f]);\n if (c !== null) out.push([name + '-' + f, c]);\n }\n return out;\n }\n var css = __kCss(v);\n return css === null ? [] : [[name, css]];\n}\nfunction __kAttr(v) {\n if (typeof v === 'number') return isFinite(v) ? String(v) : null;\n if (typeof v === 'boolean') return v ? 'true' : 'false';\n if (typeof v === 'string') return v;\n return null;\n}\n";
12
+ export declare function knobPreamble(version: number | undefined, knobs: Record<string, unknown> | undefined): {
13
+ htmlTag: string;
14
+ headScript: string;
15
+ };
16
+ export interface StaticAsset {
17
+ path: string;
18
+ contentType: string;
19
+ body: string;
20
+ }
21
+ export declare const STATIC_ASSET_PREFIX = "/asset/";
22
+ export declare const staticAsset: (path: string) => StaticAsset | null;
23
+ export declare const escapeHtml: (s: string) => string;
24
+ export declare function renderSandboxedPart(doc: {
25
+ body: string;
26
+ css: string;
27
+ origin: string;
28
+ theme?: Theme | string;
29
+ mode?: Mode;
30
+ }): string;
31
+ export declare function renderMermaidPage(doc: {
32
+ mermaid: string;
33
+ origin: string;
34
+ theme?: Theme | string;
35
+ mode?: Mode;
36
+ }): string;
37
+ export declare function renderHtmlPage(doc: {
38
+ title: string;
39
+ html: string;
40
+ origin: string;
41
+ theme?: Theme | string;
42
+ mode?: Mode;
43
+ kits?: string[];
44
+ design?: DesignSettings | null;
45
+ version?: number;
46
+ knobs?: Record<string, unknown>;
47
+ resolveIcon?: IconResolver;
48
+ }): string;