@ulearning/ai-generative-frame 0.0.0-stage → 1.0.0-next.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 (323) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -2
  3. package/dist/assistant-ui/entry.d.ts +34 -0
  4. package/dist/assistant-ui/entry.d.ts.map +1 -0
  5. package/dist/assistant-ui/entry.js +50 -0
  6. package/dist/assistant-ui/entry.js.map +1 -0
  7. package/dist/assistant-ui/extension.d.ts +18 -0
  8. package/dist/assistant-ui/extension.d.ts.map +1 -0
  9. package/dist/assistant-ui/extension.js +0 -0
  10. package/dist/assistant-ui/history.d.ts +15 -0
  11. package/dist/assistant-ui/history.d.ts.map +1 -0
  12. package/dist/assistant-ui/history.js +39 -0
  13. package/dist/assistant-ui/history.js.map +1 -0
  14. package/dist/assistant-ui/modelContext.d.ts +45 -0
  15. package/dist/assistant-ui/modelContext.d.ts.map +1 -0
  16. package/dist/assistant-ui/modelContext.js +88 -0
  17. package/dist/assistant-ui/modelContext.js.map +1 -0
  18. package/dist/assistant-ui/snapshotSaver.d.ts +11 -0
  19. package/dist/assistant-ui/snapshotSaver.d.ts.map +1 -0
  20. package/dist/assistant-ui/snapshotSaver.js +83 -0
  21. package/dist/assistant-ui/snapshotSaver.js.map +1 -0
  22. package/dist/assistant-ui/tool-calls.d.ts +21 -0
  23. package/dist/assistant-ui/tool-calls.d.ts.map +1 -0
  24. package/dist/assistant-ui/tool-calls.js +65 -0
  25. package/dist/assistant-ui/tool-calls.js.map +1 -0
  26. package/dist/assistant-ui/toolkit.d.ts +96 -0
  27. package/dist/assistant-ui/toolkit.d.ts.map +1 -0
  28. package/dist/assistant-ui/toolkit.js +456 -0
  29. package/dist/assistant-ui/toolkit.js.map +1 -0
  30. package/dist/assistant-ui/useSharedContext.d.ts +14 -0
  31. package/dist/assistant-ui/useSharedContext.d.ts.map +1 -0
  32. package/dist/assistant-ui/useSharedContext.js +27 -0
  33. package/dist/assistant-ui/useSharedContext.js.map +1 -0
  34. package/dist/assistant-ui.d.ts +3 -0
  35. package/dist/assistant-ui.d.ts.map +1 -0
  36. package/dist/assistant-ui.js +1 -0
  37. package/dist/bootstrap.d.ts +23 -0
  38. package/dist/bootstrap.d.ts.map +1 -0
  39. package/dist/bootstrap.js +78 -0
  40. package/dist/bootstrap.js.map +1 -0
  41. package/dist/csp.d.ts +25 -0
  42. package/dist/csp.d.ts.map +1 -0
  43. package/dist/csp.js +78 -0
  44. package/dist/csp.js.map +1 -0
  45. package/dist/index.d.ts +6 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +5 -0
  48. package/dist/json-schema.d.ts +70 -0
  49. package/dist/json-schema.d.ts.map +1 -0
  50. package/dist/json-schema.js +163 -0
  51. package/dist/json-schema.js.map +1 -0
  52. package/dist/preview.d.ts +30 -0
  53. package/dist/preview.d.ts.map +1 -0
  54. package/dist/preview.js +60 -0
  55. package/dist/preview.js.map +1 -0
  56. package/dist/prompts/guidance.d.ts +41 -0
  57. package/dist/prompts/guidance.d.ts.map +1 -0
  58. package/dist/prompts/guidance.js +268 -0
  59. package/dist/prompts/guidance.js.map +1 -0
  60. package/dist/prompts.d.ts +2 -0
  61. package/dist/prompts.d.ts.map +1 -0
  62. package/dist/prompts.js +1 -0
  63. package/dist/protocol.d.ts +114 -0
  64. package/dist/protocol.d.ts.map +1 -0
  65. package/dist/protocol.js +49 -0
  66. package/dist/protocol.js.map +1 -0
  67. package/dist/repair/repair.d.ts +72 -0
  68. package/dist/repair/repair.d.ts.map +1 -0
  69. package/dist/repair/repair.js +103 -0
  70. package/dist/repair/repair.js.map +1 -0
  71. package/dist/repair.d.ts +2 -0
  72. package/dist/repair.d.ts.map +1 -0
  73. package/dist/repair.js +1 -0
  74. package/dist/rpc.d.ts +60 -0
  75. package/dist/rpc.d.ts.map +1 -0
  76. package/dist/rpc.js +127 -0
  77. package/dist/rpc.js.map +1 -0
  78. package/dist/runtime/diagnostics.d.ts +17 -0
  79. package/dist/runtime/diagnostics.d.ts.map +1 -0
  80. package/dist/runtime/diagnostics.js +128 -0
  81. package/dist/runtime/diagnostics.js.map +1 -0
  82. package/dist/runtime/generated.d.ts +2 -0
  83. package/dist/runtime/generated.d.ts.map +1 -0
  84. package/dist/runtime/generated.js +5 -0
  85. package/dist/runtime/generated.js.map +1 -0
  86. package/dist/runtime/index.d.ts +7 -0
  87. package/dist/runtime/index.d.ts.map +1 -0
  88. package/dist/runtime/index.js +264 -0
  89. package/dist/runtime/index.js.map +1 -0
  90. package/dist/runtime/morph.d.ts +51 -0
  91. package/dist/runtime/morph.d.ts.map +1 -0
  92. package/dist/runtime/morph.js +251 -0
  93. package/dist/runtime/morph.js.map +1 -0
  94. package/dist/runtime/screenshot.d.ts +23 -0
  95. package/dist/runtime/screenshot.d.ts.map +1 -0
  96. package/dist/runtime/screenshot.js +188 -0
  97. package/dist/runtime/screenshot.js.map +1 -0
  98. package/dist/runtime/size.d.ts +10 -0
  99. package/dist/runtime/size.d.ts.map +1 -0
  100. package/dist/runtime/size.js +21 -0
  101. package/dist/runtime/size.js.map +1 -0
  102. package/dist/runtime/storage.d.ts +4 -0
  103. package/dist/runtime/storage.d.ts.map +1 -0
  104. package/dist/runtime/storage.js +38 -0
  105. package/dist/runtime/storage.js.map +1 -0
  106. package/dist/spec/actions.d.ts +40 -0
  107. package/dist/spec/actions.d.ts.map +1 -0
  108. package/dist/spec/actions.js +53 -0
  109. package/dist/spec/actions.js.map +1 -0
  110. package/dist/spec/assistant-ui/thread.d.ts +66 -0
  111. package/dist/spec/assistant-ui/thread.d.ts.map +1 -0
  112. package/dist/spec/assistant-ui/thread.js +252 -0
  113. package/dist/spec/assistant-ui/thread.js.map +1 -0
  114. package/dist/spec/assistant-ui/toolkit.d.ts +33 -0
  115. package/dist/spec/assistant-ui/toolkit.d.ts.map +1 -0
  116. package/dist/spec/assistant-ui/toolkit.js +142 -0
  117. package/dist/spec/assistant-ui/toolkit.js.map +1 -0
  118. package/dist/spec/assistant-ui/web.d.ts +6 -0
  119. package/dist/spec/assistant-ui/web.d.ts.map +1 -0
  120. package/dist/spec/assistant-ui/web.js +48 -0
  121. package/dist/spec/assistant-ui/web.js.map +1 -0
  122. package/dist/spec/assistant-ui.d.ts +3 -0
  123. package/dist/spec/assistant-ui.d.ts.map +1 -0
  124. package/dist/spec/assistant-ui.js +1 -0
  125. package/dist/spec/calc.d.ts +8 -0
  126. package/dist/spec/calc.d.ts.map +1 -0
  127. package/dist/spec/calc.js +498 -0
  128. package/dist/spec/calc.js.map +1 -0
  129. package/dist/spec/catalog.d.ts +52 -0
  130. package/dist/spec/catalog.d.ts.map +1 -0
  131. package/dist/spec/catalog.js +104 -0
  132. package/dist/spec/catalog.js.map +1 -0
  133. package/dist/spec/expressions.d.ts +45 -0
  134. package/dist/spec/expressions.d.ts.map +1 -0
  135. package/dist/spec/expressions.js +199 -0
  136. package/dist/spec/expressions.js.map +1 -0
  137. package/dist/spec/patch.d.ts +20 -0
  138. package/dist/spec/patch.d.ts.map +1 -0
  139. package/dist/spec/patch.js +77 -0
  140. package/dist/spec/patch.js.map +1 -0
  141. package/dist/spec/pending.d.ts +15 -0
  142. package/dist/spec/pending.d.ts.map +1 -0
  143. package/dist/spec/pending.js +33 -0
  144. package/dist/spec/pending.js.map +1 -0
  145. package/dist/spec/pointer.d.ts +17 -0
  146. package/dist/spec/pointer.d.ts.map +1 -0
  147. package/dist/spec/pointer.js +88 -0
  148. package/dist/spec/pointer.js.map +1 -0
  149. package/dist/spec/prompt.d.ts +29 -0
  150. package/dist/spec/prompt.d.ts.map +1 -0
  151. package/dist/spec/prompt.js +145 -0
  152. package/dist/spec/prompt.js.map +1 -0
  153. package/dist/spec/render-spec.d.ts +50 -0
  154. package/dist/spec/render-spec.d.ts.map +1 -0
  155. package/dist/spec/render-spec.js +104 -0
  156. package/dist/spec/render-spec.js.map +1 -0
  157. package/dist/spec/resolve.d.ts +39 -0
  158. package/dist/spec/resolve.d.ts.map +1 -0
  159. package/dist/spec/resolve.js +51 -0
  160. package/dist/spec/resolve.js.map +1 -0
  161. package/dist/spec/resolved.d.ts +3 -0
  162. package/dist/spec/resolved.d.ts.map +1 -0
  163. package/dist/spec/resolved.js +36 -0
  164. package/dist/spec/resolved.js.map +1 -0
  165. package/dist/spec/state.d.ts +34 -0
  166. package/dist/spec/state.d.ts.map +1 -0
  167. package/dist/spec/state.js +111 -0
  168. package/dist/spec/state.js.map +1 -0
  169. package/dist/spec/stream.d.ts +50 -0
  170. package/dist/spec/stream.d.ts.map +1 -0
  171. package/dist/spec/stream.js +168 -0
  172. package/dist/spec/stream.js.map +1 -0
  173. package/dist/spec/tools.d.ts +3 -0
  174. package/dist/spec/tools.d.ts.map +1 -0
  175. package/dist/spec/tools.js +3 -0
  176. package/dist/spec/tree.d.ts +21 -0
  177. package/dist/spec/tree.d.ts.map +1 -0
  178. package/dist/spec/tree.js +27 -0
  179. package/dist/spec/tree.js.map +1 -0
  180. package/dist/spec/types.d.ts +66 -0
  181. package/dist/spec/types.d.ts.map +1 -0
  182. package/dist/spec/types.js +9 -0
  183. package/dist/spec/types.js.map +1 -0
  184. package/dist/spec/validate.d.ts +32 -0
  185. package/dist/spec/validate.d.ts.map +1 -0
  186. package/dist/spec/validate.js +264 -0
  187. package/dist/spec/validate.js.map +1 -0
  188. package/dist/spec/vue/SpecRenderer.d.ts +43 -0
  189. package/dist/spec/vue/SpecRenderer.d.ts.map +1 -0
  190. package/dist/spec/vue/SpecRenderer.js +357 -0
  191. package/dist/spec/vue/SpecRenderer.js.map +1 -0
  192. package/dist/spec/vue/useSpecStream.d.ts +19 -0
  193. package/dist/spec/vue/useSpecStream.d.ts.map +1 -0
  194. package/dist/spec/vue/useSpecStream.js +115 -0
  195. package/dist/spec/vue/useSpecStream.js.map +1 -0
  196. package/dist/spec/vue.d.ts +3 -0
  197. package/dist/spec/vue.d.ts.map +1 -0
  198. package/dist/spec/vue.js +3 -0
  199. package/dist/spec.d.ts +12 -0
  200. package/dist/spec.d.ts.map +1 -0
  201. package/dist/spec.js +8 -0
  202. package/dist/theme.d.ts +38 -0
  203. package/dist/theme.d.ts.map +1 -0
  204. package/dist/theme.js +370 -0
  205. package/dist/theme.js.map +1 -0
  206. package/dist/tools/define.d.ts +43 -0
  207. package/dist/tools/define.d.ts.map +1 -0
  208. package/dist/tools/define.js +31 -0
  209. package/dist/tools/define.js.map +1 -0
  210. package/dist/tools/edits.d.ts +19 -0
  211. package/dist/tools/edits.d.ts.map +1 -0
  212. package/dist/tools/edits.js +55 -0
  213. package/dist/tools/edits.js.map +1 -0
  214. package/dist/tools/registry.d.ts +19 -0
  215. package/dist/tools/registry.d.ts.map +1 -0
  216. package/dist/tools/registry.js +33 -0
  217. package/dist/tools/registry.js.map +1 -0
  218. package/dist/tools/tools.d.ts +88 -0
  219. package/dist/tools/tools.d.ts.map +1 -0
  220. package/dist/tools/tools.js +235 -0
  221. package/dist/tools/tools.js.map +1 -0
  222. package/dist/tools.d.ts +5 -0
  223. package/dist/tools.d.ts.map +1 -0
  224. package/dist/tools.js +5 -0
  225. package/dist/version.d.ts +2 -0
  226. package/dist/version.d.ts.map +1 -0
  227. package/dist/version.js +5 -0
  228. package/dist/version.js.map +1 -0
  229. package/dist/vue/Widget.d.ts +16 -0
  230. package/dist/vue/Widget.d.ts.map +1 -0
  231. package/dist/vue/Widget.js +58 -0
  232. package/dist/vue/Widget.js.map +1 -0
  233. package/dist/vue/sync.d.ts +19 -0
  234. package/dist/vue/sync.d.ts.map +1 -0
  235. package/dist/vue/sync.js +31 -0
  236. package/dist/vue/sync.js.map +1 -0
  237. package/dist/vue/themeStore.d.ts +23 -0
  238. package/dist/vue/themeStore.d.ts.map +1 -0
  239. package/dist/vue/themeStore.js +115 -0
  240. package/dist/vue/themeStore.js.map +1 -0
  241. package/dist/vue/useThemeTokens.d.ts +6 -0
  242. package/dist/vue/useThemeTokens.d.ts.map +1 -0
  243. package/dist/vue/useThemeTokens.js +49 -0
  244. package/dist/vue/useThemeTokens.js.map +1 -0
  245. package/dist/vue/useWidget.d.ts +10 -0
  246. package/dist/vue/useWidget.d.ts.map +1 -0
  247. package/dist/vue/useWidget.js +81 -0
  248. package/dist/vue/useWidget.js.map +1 -0
  249. package/dist/vue.d.ts +5 -0
  250. package/dist/vue.d.ts.map +1 -0
  251. package/dist/vue.js +4 -0
  252. package/dist/widget.d.ts +129 -0
  253. package/dist/widget.d.ts.map +1 -0
  254. package/dist/widget.js +655 -0
  255. package/dist/widget.js.map +1 -0
  256. package/package.json +125 -3
  257. package/src/assistant-ui/entry.ts +124 -0
  258. package/src/assistant-ui/extension.ts +19 -0
  259. package/src/assistant-ui/history.ts +63 -0
  260. package/src/assistant-ui/modelContext.ts +162 -0
  261. package/src/assistant-ui/snapshotSaver.ts +116 -0
  262. package/src/assistant-ui/tool-calls.ts +115 -0
  263. package/src/assistant-ui/toolkit.tsx +747 -0
  264. package/src/assistant-ui/useSharedContext.ts +40 -0
  265. package/src/assistant-ui.ts +14 -0
  266. package/src/bootstrap.ts +112 -0
  267. package/src/csp.ts +96 -0
  268. package/src/index.ts +44 -0
  269. package/src/json-schema.ts +353 -0
  270. package/src/preview.ts +120 -0
  271. package/src/prompts/guidance.ts +369 -0
  272. package/src/prompts.ts +8 -0
  273. package/src/protocol.ts +141 -0
  274. package/src/repair/repair.ts +202 -0
  275. package/src/repair.ts +11 -0
  276. package/src/rpc.ts +228 -0
  277. package/src/runtime/diagnostics.ts +165 -0
  278. package/src/runtime/generated.ts +2 -0
  279. package/src/runtime/index.ts +343 -0
  280. package/src/runtime/morph.ts +352 -0
  281. package/src/runtime/screenshot.ts +288 -0
  282. package/src/runtime/size.ts +17 -0
  283. package/src/runtime/storage.ts +49 -0
  284. package/src/spec/actions.ts +111 -0
  285. package/src/spec/assistant-ui/thread.ts +381 -0
  286. package/src/spec/assistant-ui/toolkit.tsx +295 -0
  287. package/src/spec/assistant-ui/web.tsx +63 -0
  288. package/src/spec/assistant-ui.ts +2 -0
  289. package/src/spec/calc.ts +598 -0
  290. package/src/spec/catalog.ts +196 -0
  291. package/src/spec/expressions.ts +301 -0
  292. package/src/spec/patch.ts +112 -0
  293. package/src/spec/pending.ts +36 -0
  294. package/src/spec/pointer.ts +170 -0
  295. package/src/spec/prompt.ts +243 -0
  296. package/src/spec/render-spec.ts +144 -0
  297. package/src/spec/resolve.ts +123 -0
  298. package/src/spec/resolved.ts +53 -0
  299. package/src/spec/state.ts +193 -0
  300. package/src/spec/stream.ts +230 -0
  301. package/src/spec/tools.ts +17 -0
  302. package/src/spec/tree.ts +37 -0
  303. package/src/spec/types.ts +51 -0
  304. package/src/spec/validate.ts +429 -0
  305. package/src/spec/vue/SpecRenderer.tsx +544 -0
  306. package/src/spec/vue/__tests__/harness.ts +50 -0
  307. package/src/spec/vue/useSpecStream.ts +162 -0
  308. package/src/spec/vue.ts +13 -0
  309. package/src/spec.ts +55 -0
  310. package/src/theme.ts +423 -0
  311. package/src/tools/define.ts +65 -0
  312. package/src/tools/edits.ts +73 -0
  313. package/src/tools/registry.ts +44 -0
  314. package/src/tools/tools.ts +361 -0
  315. package/src/tools.ts +32 -0
  316. package/src/version.ts +4 -0
  317. package/src/vue/Widget.tsx +74 -0
  318. package/src/vue/sync.ts +36 -0
  319. package/src/vue/themeStore.ts +157 -0
  320. package/src/vue/useThemeTokens.ts +71 -0
  321. package/src/vue/useWidget.ts +117 -0
  322. package/src/vue.ts +8 -0
  323. package/src/widget.ts +1080 -0
@@ -0,0 +1,32 @@
1
+ import type { Catalog } from "./catalog.js";
2
+ import type { Spec } from "./types.js";
3
+ export type SpecIssueCode = "missing-root" | "unknown-root" | "invalid-element" | "unknown-type" | "invalid-props" | "missing-child" | "children-not-allowed" | "unknown-slot" | "cycle" | "unknown-event" | "unknown-action" | "invalid-params" | "invalid-formula" | "unfilled-placeholder" | "invalid-repeat" | "unreachable" | "invalid-patch" | "invalid-state" | "missing-tool-result";
4
+ export type SpecIssue = {
5
+ code: SpecIssueCode;
6
+ severity: "error" | "warning";
7
+ message: string;
8
+ /** JSON Pointer into the spec where the issue is. */
9
+ path: string;
10
+ elementId?: string;
11
+ };
12
+ export type SpecValidation = {
13
+ ok: boolean;
14
+ issues: SpecIssue[];
15
+ };
16
+ export type ValidateSpecOptions = {
17
+ /**
18
+ * The spec is still streaming: children that are not added yet are not
19
+ * errors, and unreachable elements are not reported.
20
+ */
21
+ partial?: boolean;
22
+ };
23
+ /**
24
+ * Checks a spec against a catalog: the root exists, every element has a
25
+ * known type and valid props, children resolve and form no cycle, slots and
26
+ * events are declared, and actions are known with valid params. Issues carry
27
+ * JSON Pointers so a repair prompt can point at the exact place.
28
+ */
29
+ export declare function validateSpec(spec: Spec, catalog: Catalog, options?: ValidateSpecOptions): SpecValidation;
30
+ /** Formats issues as model-readable repair feedback. */
31
+ export declare function formatSpecIssues(issues: readonly SpecIssue[]): string;
32
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAW;AAGxC,OAAO,KAAK,EAAiB,IAAI,EAAe,MAAM,YAAS;AAE/D,MAAM,MAAM,aAAa,GACrB,cAAc,GACd,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,eAAe,GACf,eAAe,GACf,sBAAsB,GACtB,cAAc,GACd,OAAO,GACP,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,iBAAiB,GACjB,sBAAsB,GACtB,gBAAgB,GAChB,aAAa,GACb,eAAe,GACf,eAAe,GACf,qBAAqB;AAEzB,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,aAAa;IACnB,QAAQ,EAAE,OAAO,GAAG,SAAS;IAC7B,OAAO,EAAE,MAAM;IACf;IACA,IAAI,EAAE,MAAM;IACZ,SAAS,CAAC,EAAE,MAAM;CACnB;AAED,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,OAAO;IAAE,MAAM,EAAE,SAAS,EAAE;CAAE;AAEjE,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;IAIA,OAAO,CAAC,EAAE,OAAO;CAClB;AAWD;;;;;;AAMA,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,mBAAwB,GAChC,cAAc;AAuVjB;AACA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM","names":[],"ignoreList":[],"sources":["../../src/spec/validate.ts"],"sourcesContent":[null]}
@@ -0,0 +1,264 @@
1
+ import { escapePointerToken } from "./pointer.js";
2
+ import { formulaIssue } from "./calc.js";
3
+ import { isExpressionKey } from "./expressions.js";
4
+ // src/spec/validate.ts
5
+ const elementPath = (id) => `/elements/${escapePointerToken(id)}`;
6
+ const PLACEHOLDER = /\$\{\s*(?:\/|\$item\b|\$index\b)[^}]*\}/;
7
+ const bindingsOf = (value) => value === void 0 ? [] : Array.isArray(value) ? value : [value];
8
+ /**
9
+ * Checks a spec against a catalog: the root exists, every element has a
10
+ * known type and valid props, children resolve and form no cycle, slots and
11
+ * events are declared, and actions are known with valid params. Issues carry
12
+ * JSON Pointers so a repair prompt can point at the exact place.
13
+ */
14
+ function validateSpec(spec, catalog, options = {}) {
15
+ const issues = [];
16
+ const error = (issue) => issues.push({
17
+ severity: "error",
18
+ ...issue
19
+ });
20
+ const elements = spec && typeof spec.elements === "object" && spec.elements ? spec.elements : {};
21
+ if (!spec?.root) error({
22
+ code: "missing-root",
23
+ message: "The spec has no root element id.",
24
+ path: "/root"
25
+ });
26
+ else if (!Object.hasOwn(elements, spec.root) && !options.partial) error({
27
+ code: "unknown-root",
28
+ message: `The root "${spec.root}" is not an element.`,
29
+ path: "/root"
30
+ });
31
+ const specState = spec?.state;
32
+ if (specState !== void 0 && (typeof specState !== "object" || specState === null || Array.isArray(specState))) error({
33
+ code: "invalid-state",
34
+ message: "The spec's state is not an object.",
35
+ path: "/state"
36
+ });
37
+ const childLists = (id, element) => {
38
+ const lists = [];
39
+ if (element.children !== void 0) lists.push({
40
+ slot: "default",
41
+ path: `${elementPath(id)}/children`,
42
+ ids: element.children
43
+ });
44
+ for (const [slot, ids] of Object.entries(element.slots ?? {})) lists.push({
45
+ slot,
46
+ path: `${elementPath(id)}/slots/${escapePointerToken(slot)}`,
47
+ ids
48
+ });
49
+ return lists;
50
+ };
51
+ const checkBindings = (id, path, bindings) => {
52
+ bindings.forEach((binding, index) => {
53
+ const at = bindings.length > 1 ? `${path}/${index}` : path;
54
+ if (!binding || typeof binding.action !== "string") {
55
+ error({
56
+ code: "unknown-action",
57
+ elementId: id,
58
+ path: at,
59
+ message: "An action binding needs an `action` name."
60
+ });
61
+ return;
62
+ }
63
+ if (!catalog.action(binding.action)) {
64
+ error({
65
+ code: "unknown-action",
66
+ elementId: id,
67
+ path: `${at}/action`,
68
+ message: `Unknown action "${binding.action}". Known: ${[
69
+ "setState",
70
+ "sendMessage",
71
+ "updateModelContext",
72
+ "copyText",
73
+ ...Object.keys(catalog.actions)
74
+ ].join(", ")}.`
75
+ });
76
+ return;
77
+ }
78
+ for (const issue of catalog.validateParams(binding.action, binding.params)) error({
79
+ code: "invalid-params",
80
+ elementId: id,
81
+ path: `${at}/params${issue.path === "/" ? "" : issue.path}`,
82
+ message: `${binding.action} params ${issue.path === "/" ? "" : `${issue.path} `}${issue.message}`
83
+ });
84
+ });
85
+ };
86
+ const checkExpressions = (id, path, value) => {
87
+ const seen = /* @__PURE__ */ new Set();
88
+ const pending = [[path, value]];
89
+ for (let next = pending.pop(); next; next = pending.pop()) {
90
+ const [at, current] = next;
91
+ if (typeof current !== "object" || current === null) continue;
92
+ if (seen.has(current)) continue;
93
+ seen.add(current);
94
+ const children = [];
95
+ for (const [key, child] of Object.entries(current)) {
96
+ const childPath = `${at}/${escapePointerToken(key)}`;
97
+ if (key !== "$calc" || Array.isArray(current)) {
98
+ const plain = typeof child === "string" && (key !== "$template" || Array.isArray(current)) ? child : void 0;
99
+ const placeholder = plain === void 0 ? void 0 : PLACEHOLDER.exec(plain.slice(0, plain.lastIndexOf("}") + 1))?.[0];
100
+ if (placeholder) error({
101
+ code: "unfilled-placeholder",
102
+ elementId: id,
103
+ path: childPath,
104
+ message: `"${id}" shows \`${placeholder}\` as written, since only \`$template\` and \`$calc\` fill placeholders. Write the string as \`{ "$template": "…" }\`, or compute the value with \`$calc\`.`
105
+ });
106
+ if (plain !== void 0 && isExpressionKey(plain)) {
107
+ const name = plain.trim();
108
+ error({
109
+ code: "unfilled-placeholder",
110
+ elementId: id,
111
+ path: childPath,
112
+ message: `"${id}" shows \`"${name}"\` as written, since an expression is an object, not a string. Write it as \`{ "${name}": … }\`.`
113
+ });
114
+ }
115
+ children.push([childPath, child]);
116
+ continue;
117
+ }
118
+ const issue = typeof child === "string" ? formulaIssue(child) : "`$calc` needs a formula string";
119
+ if (issue) error({
120
+ code: "invalid-formula",
121
+ elementId: id,
122
+ path: childPath,
123
+ message: `Formula in "${id}": ${issue}.`
124
+ });
125
+ }
126
+ for (let i = children.length - 1; i >= 0; i--) pending.push(children[i]);
127
+ }
128
+ };
129
+ for (const [id, element] of Object.entries(elements)) {
130
+ const path = elementPath(id);
131
+ if (!element || typeof element !== "object" || typeof element.type !== "string") {
132
+ error({
133
+ code: "invalid-element",
134
+ elementId: id,
135
+ path,
136
+ message: `Element "${id}" needs a string \`type\`.`
137
+ });
138
+ continue;
139
+ }
140
+ const definition = catalog.component(element.type);
141
+ if (!definition) error({
142
+ code: "unknown-type",
143
+ elementId: id,
144
+ path: `${path}/type`,
145
+ message: `Element "${id}" has unknown type "${element.type}". Known: ${Object.keys(catalog.components).join(", ")}.`
146
+ });
147
+ else {
148
+ for (const issue of catalog.validateProps(element.type, element.props)) error({
149
+ code: "invalid-props",
150
+ elementId: id,
151
+ path: `${path}/props${issue.path === "/" ? "" : issue.path}`,
152
+ message: `${element.type} "${id}" prop ${issue.path === "/" ? "" : `${issue.path.slice(1)} `}${issue.message}.`
153
+ });
154
+ const slots = definition.slots ?? [];
155
+ for (const list of childLists(id, element)) {
156
+ if (Array.isArray(list.ids) && list.ids.length === 0) continue;
157
+ if (!slots.includes(list.slot)) error({
158
+ code: list.slot === "default" ? "children-not-allowed" : "unknown-slot",
159
+ elementId: id,
160
+ path: list.path,
161
+ message: list.slot === "default" ? `${element.type} "${id}" takes no children.` : `${element.type} "${id}" has no slot "${list.slot}"${slots.length ? `; slots: ${slots.join(", ")}` : ""}.`
162
+ });
163
+ }
164
+ for (const event of Object.keys(element.on ?? {})) if (!(definition.events ?? []).includes(event)) error({
165
+ code: "unknown-event",
166
+ elementId: id,
167
+ path: `${path}/on/${escapePointerToken(event)}`,
168
+ message: `${element.type} "${id}" does not emit "${event}"${definition.events?.length ? `; events: ${definition.events.join(", ")}` : ""}.`
169
+ });
170
+ }
171
+ for (const list of childLists(id, element)) {
172
+ if (!Array.isArray(list.ids)) {
173
+ error({
174
+ code: "invalid-element",
175
+ elementId: id,
176
+ path: list.path,
177
+ message: `Children of "${id}" must be an array of ids.`
178
+ });
179
+ continue;
180
+ }
181
+ list.ids.forEach((childId, index) => {
182
+ if (typeof childId !== "string") error({
183
+ code: "invalid-element",
184
+ elementId: id,
185
+ path: `${list.path}/${index}`,
186
+ message: `Child ${index} of "${id}" must be an element id string.`
187
+ });
188
+ else if (!Object.hasOwn(elements, childId) && !options.partial) error({
189
+ code: "missing-child",
190
+ elementId: id,
191
+ path: `${list.path}/${index}`,
192
+ message: `"${id}" lists child "${childId}", which is not an element.`
193
+ });
194
+ });
195
+ }
196
+ for (const [event, bindings] of Object.entries(element.on ?? {})) checkBindings(id, `${path}/on/${escapePointerToken(event)}`, bindingsOf(bindings));
197
+ for (const [watched, bindings] of Object.entries(element.watch ?? {})) checkBindings(id, `${path}/watch/${escapePointerToken(watched)}`, bindingsOf(bindings));
198
+ checkExpressions(id, `${path}/props`, element.props);
199
+ checkExpressions(id, `${path}/visible`, element.visible);
200
+ for (const key of ["on", "watch"]) for (const [name, bindings] of Object.entries(element[key] ?? {})) {
201
+ const at = `${path}/${key}/${escapePointerToken(name)}`;
202
+ if (Array.isArray(bindings)) bindings.forEach((binding, index) => checkExpressions(id, `${at}/${index}/params`, binding?.params));
203
+ else checkExpressions(id, `${at}/params`, bindings?.params);
204
+ }
205
+ if (element.repeat !== void 0 && typeof element.repeat?.path !== "string") error({
206
+ code: "invalid-repeat",
207
+ elementId: id,
208
+ path: `${path}/repeat`,
209
+ message: `"repeat" of "${id}" needs a state \`path\`.`
210
+ });
211
+ }
212
+ const childIds = (element) => childLists("", element).flatMap((list) => Array.isArray(list.ids) ? list.ids.filter((c) => typeof c === "string") : []);
213
+ const state = /* @__PURE__ */ new Map();
214
+ const reported = /* @__PURE__ */ new Set();
215
+ const visit = (id, trail) => {
216
+ const element = elements[id];
217
+ if (!element || typeof element !== "object") return;
218
+ state.set(id, "visiting");
219
+ for (const child of childIds(element)) if (state.get(child) === "visiting") {
220
+ const stack = [...trail, id];
221
+ const loop = [...stack.slice(stack.indexOf(child)), child];
222
+ const key = [...loop].sort().join("|");
223
+ if (!reported.has(key)) {
224
+ reported.add(key);
225
+ error({
226
+ code: "cycle",
227
+ elementId: id,
228
+ path: elementPath(id),
229
+ message: `Children form a cycle: ${loop.join(" → ")}.`
230
+ });
231
+ }
232
+ } else if (!state.has(child)) visit(child, [...trail, id]);
233
+ state.set(id, "done");
234
+ };
235
+ if (spec?.root) visit(spec.root, []);
236
+ for (const id of Object.keys(elements)) {
237
+ if (state.has(id)) continue;
238
+ if (!options.partial) issues.push({
239
+ code: "unreachable",
240
+ severity: "warning",
241
+ elementId: id,
242
+ path: elementPath(id),
243
+ message: `"${id}" is not reachable from the root.`
244
+ });
245
+ visit(id, []);
246
+ }
247
+ return {
248
+ ok: !issues.some((issue) => issue.severity === "error"),
249
+ issues
250
+ };
251
+ }
252
+ /** Formats issues as model-readable repair feedback. */
253
+ function formatSpecIssues(issues) {
254
+ if (issues.length === 0) return "The spec is valid.";
255
+ const errors = issues.filter((issue) => issue.severity === "error");
256
+ const warnings = issues.filter((issue) => issue.severity === "warning");
257
+ const lines = [];
258
+ if (errors.length) lines.push(`The spec has ${errors.length} error${errors.length === 1 ? "" : "s"}. Fix them with patches on the paths shown:`, ...errors.map((issue) => `- ${issue.path}: ${issue.message}`));
259
+ if (warnings.length) lines.push(...lines.length ? [""] : [], "Warnings:", ...warnings.map((issue) => `- ${issue.path}: ${issue.message}`));
260
+ return lines.join("\n");
261
+ }
262
+ export { formatSpecIssues, validateSpec };
263
+
264
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","names":[],"sources":["../../src/spec/validate.ts"],"sourcesContent":["import { formulaIssue } from \"./calc\";\nimport type { Catalog } from \"./catalog\";\nimport { isExpressionKey } from \"./expressions\";\nimport { escapePointerToken } from \"./pointer\";\nimport type { ActionBinding, Spec, SpecElement } from \"./types\";\n\nexport type SpecIssueCode =\n | \"missing-root\"\n | \"unknown-root\"\n | \"invalid-element\"\n | \"unknown-type\"\n | \"invalid-props\"\n | \"missing-child\"\n | \"children-not-allowed\"\n | \"unknown-slot\"\n | \"cycle\"\n | \"unknown-event\"\n | \"unknown-action\"\n | \"invalid-params\"\n | \"invalid-formula\"\n | \"unfilled-placeholder\"\n | \"invalid-repeat\"\n | \"unreachable\"\n | \"invalid-patch\"\n | \"invalid-state\"\n | \"missing-tool-result\";\n\nexport type SpecIssue = {\n code: SpecIssueCode;\n severity: \"error\" | \"warning\";\n message: string;\n /** JSON Pointer into the spec where the issue is. */\n path: string;\n elementId?: string;\n};\n\nexport type SpecValidation = { ok: boolean; issues: SpecIssue[] };\n\nexport type ValidateSpecOptions = {\n /**\n * The spec is still streaming: children that are not added yet are not\n * errors, and unreachable elements are not reported.\n */\n partial?: boolean;\n};\n\nconst elementPath = (id: string) => `/elements/${escapePointerToken(id)}`;\n\nconst PLACEHOLDER = /\\$\\{\\s*(?:\\/|\\$item\\b|\\$index\\b)[^}]*\\}/;\n\nconst bindingsOf = (\n value: ActionBinding | ActionBinding[] | undefined,\n): ActionBinding[] =>\n value === undefined ? [] : Array.isArray(value) ? value : [value];\n\n/**\n * Checks a spec against a catalog: the root exists, every element has a\n * known type and valid props, children resolve and form no cycle, slots and\n * events are declared, and actions are known with valid params. Issues carry\n * JSON Pointers so a repair prompt can point at the exact place.\n */\nexport function validateSpec(\n spec: Spec,\n catalog: Catalog,\n options: ValidateSpecOptions = {},\n): SpecValidation {\n const issues: SpecIssue[] = [];\n const error = (issue: Omit<SpecIssue, \"severity\">) =>\n issues.push({ severity: \"error\", ...issue });\n const elements: Record<string, SpecElement> =\n spec && typeof spec.elements === \"object\" && spec.elements\n ? spec.elements\n : {};\n\n if (!spec?.root) {\n error({\n code: \"missing-root\",\n message: \"The spec has no root element id.\",\n path: \"/root\",\n });\n } else if (!Object.hasOwn(elements, spec.root) && !options.partial) {\n error({\n code: \"unknown-root\",\n message: `The root \"${spec.root}\" is not an element.`,\n path: \"/root\",\n });\n }\n const specState: unknown = spec?.state;\n if (\n specState !== undefined &&\n (typeof specState !== \"object\" ||\n specState === null ||\n Array.isArray(specState))\n ) {\n error({\n code: \"invalid-state\",\n message: \"The spec's state is not an object.\",\n path: \"/state\",\n });\n }\n\n const childLists = (id: string, element: SpecElement) => {\n const lists: { slot: string; path: string; ids: unknown }[] = [];\n if (element.children !== undefined) {\n lists.push({\n slot: \"default\",\n path: `${elementPath(id)}/children`,\n ids: element.children,\n });\n }\n for (const [slot, ids] of Object.entries(element.slots ?? {})) {\n lists.push({\n slot,\n path: `${elementPath(id)}/slots/${escapePointerToken(slot)}`,\n ids,\n });\n }\n return lists;\n };\n\n const checkBindings = (\n id: string,\n path: string,\n bindings: ActionBinding[],\n ) => {\n bindings.forEach((binding, index) => {\n const at = bindings.length > 1 ? `${path}/${index}` : path;\n if (!binding || typeof binding.action !== \"string\") {\n error({\n code: \"unknown-action\",\n elementId: id,\n path: at,\n message: \"An action binding needs an `action` name.\",\n });\n return;\n }\n if (!catalog.action(binding.action)) {\n error({\n code: \"unknown-action\",\n elementId: id,\n path: `${at}/action`,\n message: `Unknown action \"${binding.action}\". Known: ${[\n \"setState\",\n \"sendMessage\",\n \"updateModelContext\",\n \"copyText\",\n ...Object.keys(catalog.actions),\n ].join(\", \")}.`,\n });\n return;\n }\n for (const issue of catalog.validateParams(\n binding.action,\n binding.params,\n )) {\n error({\n code: \"invalid-params\",\n elementId: id,\n path: `${at}/params${issue.path === \"/\" ? \"\" : issue.path}`,\n message: `${binding.action} params ${issue.path === \"/\" ? \"\" : `${issue.path} `}${issue.message}`,\n });\n }\n });\n };\n\n const checkExpressions = (id: string, path: string, value: unknown) => {\n const seen = new Set<object>();\n const pending: [string, unknown][] = [[path, value]];\n for (let next = pending.pop(); next; next = pending.pop()) {\n const [at, current] = next;\n if (typeof current !== \"object\" || current === null) continue;\n if (seen.has(current)) continue;\n seen.add(current);\n const children: [string, unknown][] = [];\n for (const [key, child] of Object.entries(current)) {\n const childPath = `${at}/${escapePointerToken(key)}`;\n if (key !== \"$calc\" || Array.isArray(current)) {\n const plain =\n typeof child === \"string\" &&\n (key !== \"$template\" || Array.isArray(current))\n ? child\n : undefined;\n // Ending the scan at the last `}` keeps it linear on a long string whose placeholders never close.\n const placeholder =\n plain === undefined\n ? undefined\n : PLACEHOLDER.exec(\n plain.slice(0, plain.lastIndexOf(\"}\") + 1),\n )?.[0];\n if (placeholder) {\n error({\n code: \"unfilled-placeholder\",\n elementId: id,\n path: childPath,\n message: `\"${id}\" shows \\`${placeholder}\\` as written, since only \\`$template\\` and \\`$calc\\` fill placeholders. Write the string as \\`{ \"$template\": \"…\" }\\`, or compute the value with \\`$calc\\`.`,\n });\n }\n if (plain !== undefined && isExpressionKey(plain)) {\n const name = plain.trim();\n error({\n code: \"unfilled-placeholder\",\n elementId: id,\n path: childPath,\n message: `\"${id}\" shows \\`\"${name}\"\\` as written, since an expression is an object, not a string. Write it as \\`{ \"${name}\": … }\\`.`,\n });\n }\n children.push([childPath, child]);\n continue;\n }\n const issue =\n typeof child === \"string\"\n ? formulaIssue(child)\n : \"`$calc` needs a formula string\";\n if (issue) {\n error({\n code: \"invalid-formula\",\n elementId: id,\n path: childPath,\n message: `Formula in \"${id}\": ${issue}.`,\n });\n }\n }\n for (let i = children.length - 1; i >= 0; i--) pending.push(children[i]!);\n }\n };\n\n for (const [id, element] of Object.entries(elements)) {\n const path = elementPath(id);\n if (\n !element ||\n typeof element !== \"object\" ||\n typeof element.type !== \"string\"\n ) {\n error({\n code: \"invalid-element\",\n elementId: id,\n path,\n message: `Element \"${id}\" needs a string \\`type\\`.`,\n });\n continue;\n }\n const definition = catalog.component(element.type);\n if (!definition) {\n error({\n code: \"unknown-type\",\n elementId: id,\n path: `${path}/type`,\n message: `Element \"${id}\" has unknown type \"${element.type}\". Known: ${Object.keys(catalog.components).join(\", \")}.`,\n });\n } else {\n for (const issue of catalog.validateProps(element.type, element.props)) {\n error({\n code: \"invalid-props\",\n elementId: id,\n path: `${path}/props${issue.path === \"/\" ? \"\" : issue.path}`,\n message: `${element.type} \"${id}\" prop ${issue.path === \"/\" ? \"\" : `${issue.path.slice(1)} `}${issue.message}.`,\n });\n }\n const slots = definition.slots ?? [];\n for (const list of childLists(id, element)) {\n if (Array.isArray(list.ids) && list.ids.length === 0) continue;\n if (!slots.includes(list.slot)) {\n error({\n code:\n list.slot === \"default\" ? \"children-not-allowed\" : \"unknown-slot\",\n elementId: id,\n path: list.path,\n message:\n list.slot === \"default\"\n ? `${element.type} \"${id}\" takes no children.`\n : `${element.type} \"${id}\" has no slot \"${list.slot}\"${slots.length ? `; slots: ${slots.join(\", \")}` : \"\"}.`,\n });\n }\n }\n for (const event of Object.keys(element.on ?? {})) {\n if (!(definition.events ?? []).includes(event)) {\n error({\n code: \"unknown-event\",\n elementId: id,\n path: `${path}/on/${escapePointerToken(event)}`,\n message: `${element.type} \"${id}\" does not emit \"${event}\"${definition.events?.length ? `; events: ${definition.events.join(\", \")}` : \"\"}.`,\n });\n }\n }\n }\n\n for (const list of childLists(id, element)) {\n if (!Array.isArray(list.ids)) {\n error({\n code: \"invalid-element\",\n elementId: id,\n path: list.path,\n message: `Children of \"${id}\" must be an array of ids.`,\n });\n continue;\n }\n list.ids.forEach((childId, index) => {\n if (typeof childId !== \"string\") {\n error({\n code: \"invalid-element\",\n elementId: id,\n path: `${list.path}/${index}`,\n message: `Child ${index} of \"${id}\" must be an element id string.`,\n });\n } else if (!Object.hasOwn(elements, childId) && !options.partial) {\n error({\n code: \"missing-child\",\n elementId: id,\n path: `${list.path}/${index}`,\n message: `\"${id}\" lists child \"${childId}\", which is not an element.`,\n });\n }\n });\n }\n\n for (const [event, bindings] of Object.entries(element.on ?? {})) {\n checkBindings(\n id,\n `${path}/on/${escapePointerToken(event)}`,\n bindingsOf(bindings),\n );\n }\n for (const [watched, bindings] of Object.entries(element.watch ?? {})) {\n checkBindings(\n id,\n `${path}/watch/${escapePointerToken(watched)}`,\n bindingsOf(bindings),\n );\n }\n checkExpressions(id, `${path}/props`, element.props);\n checkExpressions(id, `${path}/visible`, element.visible);\n for (const key of [\"on\", \"watch\"] as const) {\n for (const [name, bindings] of Object.entries(element[key] ?? {})) {\n const at = `${path}/${key}/${escapePointerToken(name)}`;\n if (Array.isArray(bindings)) {\n bindings.forEach((binding, index) =>\n checkExpressions(id, `${at}/${index}/params`, binding?.params),\n );\n } else {\n checkExpressions(id, `${at}/params`, bindings?.params);\n }\n }\n }\n if (\n element.repeat !== undefined &&\n typeof element.repeat?.path !== \"string\"\n ) {\n error({\n code: \"invalid-repeat\",\n elementId: id,\n path: `${path}/repeat`,\n message: `\"repeat\" of \"${id}\" needs a state \\`path\\`.`,\n });\n }\n }\n\n const childIds = (element: SpecElement) =>\n childLists(\"\", element).flatMap((list) =>\n Array.isArray(list.ids)\n ? list.ids.filter((c): c is string => typeof c === \"string\")\n : [],\n );\n\n // Depth-first search for cycles and reachability from the root.\n const state = new Map<string, \"visiting\" | \"done\">();\n const reported = new Set<string>();\n const visit = (id: string, trail: string[]) => {\n const element = elements[id];\n if (!element || typeof element !== \"object\") return;\n state.set(id, \"visiting\");\n for (const child of childIds(element)) {\n if (state.get(child) === \"visiting\") {\n const stack = [...trail, id];\n const loop = [...stack.slice(stack.indexOf(child)), child];\n const key = [...loop].sort().join(\"|\");\n if (!reported.has(key)) {\n reported.add(key);\n error({\n code: \"cycle\",\n elementId: id,\n path: elementPath(id),\n message: `Children form a cycle: ${loop.join(\" → \")}.`,\n });\n }\n } else if (!state.has(child)) {\n visit(child, [...trail, id]);\n }\n }\n state.set(id, \"done\");\n };\n if (spec?.root) visit(spec.root, []);\n for (const id of Object.keys(elements)) {\n if (state.has(id)) continue;\n if (!options.partial) {\n issues.push({\n code: \"unreachable\",\n severity: \"warning\",\n elementId: id,\n path: elementPath(id),\n message: `\"${id}\" is not reachable from the root.`,\n });\n }\n visit(id, []);\n }\n\n return { ok: !issues.some((issue) => issue.severity === \"error\"), issues };\n}\n\n/** Formats issues as model-readable repair feedback. */\nexport function formatSpecIssues(issues: readonly SpecIssue[]): string {\n if (issues.length === 0) return \"The spec is valid.\";\n const errors = issues.filter((issue) => issue.severity === \"error\");\n const warnings = issues.filter((issue) => issue.severity === \"warning\");\n const lines: string[] = [];\n if (errors.length) {\n lines.push(\n `The spec has ${errors.length} error${errors.length === 1 ? \"\" : \"s\"}. Fix them with patches on the paths shown:`,\n ...errors.map((issue) => `- ${issue.path}: ${issue.message}`),\n );\n }\n if (warnings.length) {\n lines.push(\n ...(lines.length ? [\"\"] : []),\n \"Warnings:\",\n ...warnings.map((issue) => `- ${issue.path}: ${issue.message}`),\n );\n }\n return lines.join(\"\\n\");\n}\n"],"mappings":";;;;AA8CA,MAAM,eAAe,OAAe,aAAa,mBAAmB,EAAE;AAEtE,MAAM,cAAc;AAEpB,MAAM,cACJ,UAEA,UAAU,KAAA,IAAY,CAAC,IAAI,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;;;;;;;AAQlE,SAAgB,aACd,MACA,SACA,UAA+B,CAAC,GAChB;CAChB,MAAM,SAAsB,CAAC;CAC7B,MAAM,SAAS,UACb,OAAO,KAAK;EAAE,UAAU;EAAS,GAAG;CAAM,CAAC;CAC7C,MAAM,WACJ,QAAQ,OAAO,KAAK,aAAa,YAAY,KAAK,WAC9C,KAAK,WACL,CAAC;CAEP,IAAI,CAAC,MAAM,MACT,MAAM;EACJ,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;MACI,IAAI,CAAC,OAAO,OAAO,UAAU,KAAK,IAAI,KAAK,CAAC,QAAQ,SACzD,MAAM;EACJ,MAAM;EACN,SAAS,aAAa,KAAK,KAAK;EAChC,MAAM;CACR,CAAC;CAEH,MAAM,YAAqB,MAAM;CACjC,IACE,cAAc,KAAA,MACb,OAAO,cAAc,YACpB,cAAc,QACd,MAAM,QAAQ,SAAS,IAEzB,MAAM;EACJ,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CAGH,MAAM,cAAc,IAAY,YAAyB;EACvD,MAAM,QAAwD,CAAC;EAC/D,IAAI,QAAQ,aAAa,KAAA,GACvB,MAAM,KAAK;GACT,MAAM;GACN,MAAM,GAAG,YAAY,EAAE,EAAE;GACzB,KAAK,QAAQ;EACf,CAAC;EAEH,KAAK,MAAM,CAAC,MAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,GAC1D,MAAM,KAAK;GACT;GACA,MAAM,GAAG,YAAY,EAAE,EAAE,SAAS,mBAAmB,IAAI;GACzD;EACF,CAAC;EAEH,OAAO;CACT;CAEA,MAAM,iBACJ,IACA,MACA,aACG;EACH,SAAS,SAAS,SAAS,UAAU;GACnC,MAAM,KAAK,SAAS,SAAS,IAAI,GAAG,KAAK,GAAG,UAAU;GACtD,IAAI,CAAC,WAAW,OAAO,QAAQ,WAAW,UAAU;IAClD,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM;KACN,SAAS;IACX,CAAC;IACD;GACF;GACA,IAAI,CAAC,QAAQ,OAAO,QAAQ,MAAM,GAAG;IACnC,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM,GAAG,GAAG;KACZ,SAAS,mBAAmB,QAAQ,OAAO,YAAY;MACrD;MACA;MACA;MACA;MACA,GAAG,OAAO,KAAK,QAAQ,OAAO;KAChC,CAAC,CAAC,KAAK,IAAI,EAAE;IACf,CAAC;IACD;GACF;GACA,KAAK,MAAM,SAAS,QAAQ,eAC1B,QAAQ,QACR,QAAQ,MACV,GACE,MAAM;IACJ,MAAM;IACN,WAAW;IACX,MAAM,GAAG,GAAG,SAAS,MAAM,SAAS,MAAM,KAAK,MAAM;IACrD,SAAS,GAAG,QAAQ,OAAO,UAAU,MAAM,SAAS,MAAM,KAAK,GAAG,MAAM,KAAK,KAAK,MAAM;GAC1F,CAAC;EAEL,CAAC;CACH;CAEA,MAAM,oBAAoB,IAAY,MAAc,UAAmB;EACrE,MAAM,uBAAO,IAAI,IAAY;EAC7B,MAAM,UAA+B,CAAC,CAAC,MAAM,KAAK,CAAC;EACnD,KAAK,IAAI,OAAO,QAAQ,IAAI,GAAG,MAAM,OAAO,QAAQ,IAAI,GAAG;GACzD,MAAM,CAAC,IAAI,WAAW;GACtB,IAAI,OAAO,YAAY,YAAY,YAAY,MAAM;GACrD,IAAI,KAAK,IAAI,OAAO,GAAG;GACvB,KAAK,IAAI,OAAO;GAChB,MAAM,WAAgC,CAAC;GACvC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAAG;IAClD,MAAM,YAAY,GAAG,GAAG,GAAG,mBAAmB,GAAG;IACjD,IAAI,QAAQ,WAAW,MAAM,QAAQ,OAAO,GAAG;KAC7C,MAAM,QACJ,OAAO,UAAU,aAChB,QAAQ,eAAe,MAAM,QAAQ,OAAO,KACzC,QACA,KAAA;KAEN,MAAM,cACJ,UAAU,KAAA,IACN,KAAA,IACA,YAAY,KACV,MAAM,MAAM,GAAG,MAAM,YAAY,GAAG,IAAI,CAAC,CAC3C,CAAC,GAAG;KACV,IAAI,aACF,MAAM;MACJ,MAAM;MACN,WAAW;MACX,MAAM;MACN,SAAS,IAAI,GAAG,YAAY,YAAY;KAC1C,CAAC;KAEH,IAAI,UAAU,KAAA,KAAa,gBAAgB,KAAK,GAAG;MACjD,MAAM,OAAO,MAAM,KAAK;MACxB,MAAM;OACJ,MAAM;OACN,WAAW;OACX,MAAM;OACN,SAAS,IAAI,GAAG,aAAa,KAAK,mFAAmF,KAAK;MAC5H,CAAC;KACH;KACA,SAAS,KAAK,CAAC,WAAW,KAAK,CAAC;KAChC;IACF;IACA,MAAM,QACJ,OAAO,UAAU,WACb,aAAa,KAAK,IAClB;IACN,IAAI,OACF,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM;KACN,SAAS,eAAe,GAAG,KAAK,MAAM;IACxC,CAAC;GAEL;GACA,KAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK,QAAQ,KAAK,SAAS,EAAG;EAC1E;CACF;CAEA,KAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,QAAQ,GAAG;EACpD,MAAM,OAAO,YAAY,EAAE;EAC3B,IACE,CAAC,WACD,OAAO,YAAY,YACnB,OAAO,QAAQ,SAAS,UACxB;GACA,MAAM;IACJ,MAAM;IACN,WAAW;IACX;IACA,SAAS,YAAY,GAAG;GAC1B,CAAC;GACD;EACF;EACA,MAAM,aAAa,QAAQ,UAAU,QAAQ,IAAI;EACjD,IAAI,CAAC,YACH,MAAM;GACJ,MAAM;GACN,WAAW;GACX,MAAM,GAAG,KAAK;GACd,SAAS,YAAY,GAAG,sBAAsB,QAAQ,KAAK,YAAY,OAAO,KAAK,QAAQ,UAAU,CAAC,CAAC,KAAK,IAAI,EAAE;EACpH,CAAC;OACI;GACL,KAAK,MAAM,SAAS,QAAQ,cAAc,QAAQ,MAAM,QAAQ,KAAK,GACnE,MAAM;IACJ,MAAM;IACN,WAAW;IACX,MAAM,GAAG,KAAK,QAAQ,MAAM,SAAS,MAAM,KAAK,MAAM;IACtD,SAAS,GAAG,QAAQ,KAAK,IAAI,GAAG,SAAS,MAAM,SAAS,MAAM,KAAK,GAAG,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,MAAM,QAAQ;GAC/G,CAAC;GAEH,MAAM,QAAQ,WAAW,SAAS,CAAC;GACnC,KAAK,MAAM,QAAQ,WAAW,IAAI,OAAO,GAAG;IAC1C,IAAI,MAAM,QAAQ,KAAK,GAAG,KAAK,KAAK,IAAI,WAAW,GAAG;IACtD,IAAI,CAAC,MAAM,SAAS,KAAK,IAAI,GAC3B,MAAM;KACJ,MACE,KAAK,SAAS,YAAY,yBAAyB;KACrD,WAAW;KACX,MAAM,KAAK;KACX,SACE,KAAK,SAAS,YACV,GAAG,QAAQ,KAAK,IAAI,GAAG,wBACvB,GAAG,QAAQ,KAAK,IAAI,GAAG,iBAAiB,KAAK,KAAK,GAAG,MAAM,SAAS,YAAY,MAAM,KAAK,IAAI,MAAM,GAAG;IAChH,CAAC;GAEL;GACA,KAAK,MAAM,SAAS,OAAO,KAAK,QAAQ,MAAM,CAAC,CAAC,GAC9C,IAAI,EAAE,WAAW,UAAU,CAAC,EAAA,CAAG,SAAS,KAAK,GAC3C,MAAM;IACJ,MAAM;IACN,WAAW;IACX,MAAM,GAAG,KAAK,MAAM,mBAAmB,KAAK;IAC5C,SAAS,GAAG,QAAQ,KAAK,IAAI,GAAG,mBAAmB,MAAM,GAAG,WAAW,QAAQ,SAAS,aAAa,WAAW,OAAO,KAAK,IAAI,MAAM,GAAG;GAC3I,CAAC;EAGP;EAEA,KAAK,MAAM,QAAQ,WAAW,IAAI,OAAO,GAAG;GAC1C,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,GAAG;IAC5B,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM,KAAK;KACX,SAAS,gBAAgB,GAAG;IAC9B,CAAC;IACD;GACF;GACA,KAAK,IAAI,SAAS,SAAS,UAAU;IACnC,IAAI,OAAO,YAAY,UACrB,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM,GAAG,KAAK,KAAK,GAAG;KACtB,SAAS,SAAS,MAAM,OAAO,GAAG;IACpC,CAAC;SACI,IAAI,CAAC,OAAO,OAAO,UAAU,OAAO,KAAK,CAAC,QAAQ,SACvD,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM,GAAG,KAAK,KAAK,GAAG;KACtB,SAAS,IAAI,GAAG,iBAAiB,QAAQ;IAC3C,CAAC;GAEL,CAAC;EACH;EAEA,KAAK,MAAM,CAAC,OAAO,aAAa,OAAO,QAAQ,QAAQ,MAAM,CAAC,CAAC,GAC7D,cACE,IACA,GAAG,KAAK,MAAM,mBAAmB,KAAK,KACtC,WAAW,QAAQ,CACrB;EAEF,KAAK,MAAM,CAAC,SAAS,aAAa,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,GAClE,cACE,IACA,GAAG,KAAK,SAAS,mBAAmB,OAAO,KAC3C,WAAW,QAAQ,CACrB;EAEF,iBAAiB,IAAI,GAAG,KAAK,SAAS,QAAQ,KAAK;EACnD,iBAAiB,IAAI,GAAG,KAAK,WAAW,QAAQ,OAAO;EACvD,KAAK,MAAM,OAAO,CAAC,MAAM,OAAO,GAC9B,KAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,QAAQ,QAAQ,CAAC,CAAC,GAAG;GACjE,MAAM,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,mBAAmB,IAAI;GACpD,IAAI,MAAM,QAAQ,QAAQ,GACxB,SAAS,SAAS,SAAS,UACzB,iBAAiB,IAAI,GAAG,GAAG,GAAG,MAAM,UAAU,SAAS,MAAM,CAC/D;QAEA,iBAAiB,IAAI,GAAG,GAAG,UAAU,UAAU,MAAM;EAEzD;EAEF,IACE,QAAQ,WAAW,KAAA,KACnB,OAAO,QAAQ,QAAQ,SAAS,UAEhC,MAAM;GACJ,MAAM;GACN,WAAW;GACX,MAAM,GAAG,KAAK;GACd,SAAS,gBAAgB,GAAG;EAC9B,CAAC;CAEL;CAEA,MAAM,YAAY,YAChB,WAAW,IAAI,OAAO,CAAC,CAAC,SAAS,SAC/B,MAAM,QAAQ,KAAK,GAAG,IAClB,KAAK,IAAI,QAAQ,MAAmB,OAAO,MAAM,QAAQ,IACzD,CAAC,CACP;CAGF,MAAM,wBAAQ,IAAI,IAAiC;CACnD,MAAM,2BAAW,IAAI,IAAY;CACjC,MAAM,SAAS,IAAY,UAAoB;EAC7C,MAAM,UAAU,SAAS;EACzB,IAAI,CAAC,WAAW,OAAO,YAAY,UAAU;EAC7C,MAAM,IAAI,IAAI,UAAU;EACxB,KAAK,MAAM,SAAS,SAAS,OAAO,GAClC,IAAI,MAAM,IAAI,KAAK,MAAM,YAAY;GACnC,MAAM,QAAQ,CAAC,GAAG,OAAO,EAAE;GAC3B,MAAM,OAAO,CAAC,GAAG,MAAM,MAAM,MAAM,QAAQ,KAAK,CAAC,GAAG,KAAK;GACzD,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG;GACrC,IAAI,CAAC,SAAS,IAAI,GAAG,GAAG;IACtB,SAAS,IAAI,GAAG;IAChB,MAAM;KACJ,MAAM;KACN,WAAW;KACX,MAAM,YAAY,EAAE;KACpB,SAAS,0BAA0B,KAAK,KAAK,KAAK,EAAE;IACtD,CAAC;GACH;EACF,OAAO,IAAI,CAAC,MAAM,IAAI,KAAK,GACzB,MAAM,OAAO,CAAC,GAAG,OAAO,EAAE,CAAC;EAG/B,MAAM,IAAI,IAAI,MAAM;CACtB;CACA,IAAI,MAAM,MAAM,MAAM,KAAK,MAAM,CAAC,CAAC;CACnC,KAAK,MAAM,MAAM,OAAO,KAAK,QAAQ,GAAG;EACtC,IAAI,MAAM,IAAI,EAAE,GAAG;EACnB,IAAI,CAAC,QAAQ,SACX,OAAO,KAAK;GACV,MAAM;GACN,UAAU;GACV,WAAW;GACX,MAAM,YAAY,EAAE;GACpB,SAAS,IAAI,GAAG;EAClB,CAAC;EAEH,MAAM,IAAI,CAAC,CAAC;CACd;CAEA,OAAO;EAAE,IAAI,CAAC,OAAO,MAAM,UAAU,MAAM,aAAa,OAAO;EAAG;CAAO;AAC3E;;AAGA,SAAgB,iBAAiB,QAAsC;CACrE,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,MAAM,SAAS,OAAO,QAAQ,UAAU,MAAM,aAAa,OAAO;CAClE,MAAM,WAAW,OAAO,QAAQ,UAAU,MAAM,aAAa,SAAS;CACtE,MAAM,QAAkB,CAAC;CACzB,IAAI,OAAO,QACT,MAAM,KACJ,gBAAgB,OAAO,OAAO,QAAQ,OAAO,WAAW,IAAI,KAAK,IAAI,8CACrE,GAAG,OAAO,KAAK,UAAU,KAAK,MAAM,KAAK,IAAI,MAAM,SAAS,CAC9D;CAEF,IAAI,SAAS,QACX,MAAM,KACJ,GAAI,MAAM,SAAS,CAAC,EAAE,IAAI,CAAC,GAC3B,aACA,GAAG,SAAS,KAAK,UAAU,KAAK,MAAM,KAAK,IAAI,MAAM,SAAS,CAChE;CAEF,OAAO,MAAM,KAAK,IAAI;AACxB"}
@@ -0,0 +1,43 @@
1
+ import { type Component, type VNodeChild } from "vue";
2
+ import { type ActionHandler, type ActionSource } from "../actions.js";
3
+ import type { Catalog } from "../catalog.js";
4
+ import { type SpecStateStore } from "../state.js";
5
+ import type { Spec, SpecElement } from "../types.js";
6
+ export type SpecComponentProps<P extends Record<string, unknown> = Record<string, unknown>> = {
7
+ id: string;
8
+ element: SpecElement;
9
+ props: P;
10
+ /** The rendered default slot, also supplied as a native Vue default slot. */
11
+ children: VNodeChild;
12
+ /** Named slot nodes, also supplied as native Vue named slots. */
13
+ slots: Record<string, VNodeChild>;
14
+ emit(event: string, payload?: unknown): void;
15
+ setProp(name: string, value: unknown): void;
16
+ bindings: Record<string, string>;
17
+ state: SpecStateStore;
18
+ streaming: boolean;
19
+ };
20
+ export type SpecComponents = Record<string, Component>;
21
+ export type SpecPlaceholderProps = {
22
+ id: string;
23
+ reason: "missing" | "pending" | "unknown-type" | "invalid-props" | "cycle" | "error";
24
+ message: string;
25
+ };
26
+ export type SpecRendererProps = {
27
+ spec: Spec;
28
+ components: SpecComponents;
29
+ catalog?: Catalog;
30
+ state?: SpecStateStore;
31
+ handlers?: Record<string, ActionHandler>;
32
+ onAction?: (name: string, params: Record<string, unknown>, context: ActionSource & {
33
+ state: SpecStateStore;
34
+ }) => unknown;
35
+ onError?: (error: Error, context: {
36
+ elementId?: string;
37
+ }) => void;
38
+ streaming?: boolean;
39
+ placeholder?: Component;
40
+ };
41
+ export declare const SpecPlaceholder: import("vue").DefineSetupFnComponent<SpecPlaceholderProps, {}, {}, SpecPlaceholderProps & {}, import("vue").PublicProps>;
42
+ export declare const SpecRenderer: import("vue").DefineSetupFnComponent<SpecRendererProps, {}, {}, SpecRendererProps & {}, import("vue").PublicProps>;
43
+ //# sourceMappingURL=SpecRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpecRenderer.d.ts","mappings":"AAAA,OAAO,EAeL,KAAK,SAAS,EAGd,KAAK,UAAU,EAChB,MAAM,KAAK;AACZ,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,eAAY;AACnB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAY;AAazC,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,aAAU;AAEhE,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,aAAU;AACjD,MAAM,MAAM,kBAAkB,CAC5B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IACzD;IACF,EAAE,EAAE,MAAM;IACV,OAAO,EAAE,WAAW;IACpB,KAAK,EAAE,CAAC;IACR;IACA,QAAQ,EAAE,UAAU;IACpB;IACA,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI;IAC5C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAChC,KAAK,EAAE,cAAc;IACrB,SAAS,EAAE,OAAO;CACnB;AACD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;AACtD,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM;IACV,MAAM,EACF,SAAS,GACT,SAAS,GACT,cAAc,GACd,eAAe,GACf,OAAO,GACP,OAAO;IACX,OAAO,EAAE,MAAM;CAChB;AACD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,cAAc;IAC1B,OAAO,CAAC,EAAE,OAAO;IACjB,KAAK,CAAC,EAAE,cAAc;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC;IACxC,QAAQ,CAAC,EAAE,CACT,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,YAAY,GAAG;QAAE,KAAK,EAAE,cAAc;KAAE,KAC9C,OAAO;IACZ,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM;KAAE,KAAK,IAAI;IACjE,SAAS,CAAC,EAAE,OAAO;IACnB,WAAW,CAAC,EAAE,SAAS;CACxB;AAiDD,eAAO,MAAM,eAAe,0HAsB3B;AAgQD,eAAO,MAAM,YAAY,oHAoIxB","names":[],"ignoreList":[],"sources":["../../../src/spec/vue/SpecRenderer.tsx"],"sourcesContent":[null]}