sygnal 5.4.0 → 6.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 (316) hide show
  1. package/CHANGELOG.md +646 -0
  2. package/README.md +24 -9
  3. package/dist/astro/client.cjs.js +16 -9
  4. package/dist/astro/client.cjs.js.map +1 -1
  5. package/dist/astro/client.mjs +16 -9
  6. package/dist/astro/client.mjs.map +1 -1
  7. package/dist/astro/index.cjs.js +362 -91
  8. package/dist/astro/index.cjs.js.map +1 -1
  9. package/dist/astro/index.mjs +362 -92
  10. package/dist/astro/index.mjs.map +1 -1
  11. package/dist/astro/server.cjs.js +3396 -165
  12. package/dist/astro/server.cjs.js.map +1 -1
  13. package/dist/astro/server.mjs +3396 -165
  14. package/dist/astro/server.mjs.map +1 -1
  15. package/dist/devtools.cjs.js +1431 -0
  16. package/dist/devtools.cjs.js.map +1 -0
  17. package/dist/devtools.esm.js +1419 -0
  18. package/dist/devtools.esm.js.map +1 -0
  19. package/dist/diagnostics.cjs.js +3032 -296
  20. package/dist/diagnostics.cjs.js.map +1 -1
  21. package/dist/diagnostics.esm.js +3032 -296
  22. package/dist/diagnostics.esm.js.map +1 -1
  23. package/dist/element.cjs.js +230 -0
  24. package/dist/element.cjs.js.map +1 -0
  25. package/dist/element.esm.js +228 -0
  26. package/dist/element.esm.js.map +1 -0
  27. package/dist/guide/accessibility.md +257 -0
  28. package/dist/guide/adapters.md +221 -0
  29. package/dist/guide/behaviors.md +312 -0
  30. package/dist/guide/browser-sources.md +203 -0
  31. package/dist/guide/drag-and-drop.md +342 -0
  32. package/dist/guide/element-commands.md +306 -0
  33. package/dist/guide/error-boundaries.md +169 -0
  34. package/dist/guide/forms-reference.md +381 -0
  35. package/dist/guide/forms.md +250 -0
  36. package/dist/guide/http.md +299 -0
  37. package/dist/guide/inputs.md +173 -0
  38. package/dist/guide/persistence.md +245 -0
  39. package/dist/guide/recipes/carousel.md +155 -0
  40. package/dist/guide/recipes/charts.md +177 -0
  41. package/dist/guide/recipes/code-editor.md +135 -0
  42. package/dist/guide/recipes/data-grid.md +155 -0
  43. package/dist/guide/recipes/data-table.md +196 -0
  44. package/dist/guide/recipes/i18n.md +222 -0
  45. package/dist/guide/recipes/icons.md +115 -0
  46. package/dist/guide/recipes/overview.md +33 -0
  47. package/dist/guide/recipes/rich-text.md +154 -0
  48. package/dist/guide/resources.md +471 -0
  49. package/dist/guide/ssr.md +255 -0
  50. package/dist/guide/timers.md +178 -0
  51. package/dist/guide/ui/accordion.md +93 -0
  52. package/dist/guide/ui/combobox.md +144 -0
  53. package/dist/guide/ui/dialog.md +124 -0
  54. package/dist/guide/ui/disclosure.md +60 -0
  55. package/dist/guide/ui/menu.md +125 -0
  56. package/dist/guide/ui/overview.md +166 -0
  57. package/dist/guide/ui/popover.md +101 -0
  58. package/dist/guide/ui/select.md +114 -0
  59. package/dist/guide/ui/tabs.md +161 -0
  60. package/dist/guide/ui/toaster.md +152 -0
  61. package/dist/guide/ui/tooltip.md +103 -0
  62. package/dist/guide/undo.md +178 -0
  63. package/dist/guide/virtual-collections.md +183 -0
  64. package/dist/guide/web-components.md +179 -0
  65. package/dist/guide/widgets.md +217 -0
  66. package/dist/index.cjs.js +13178 -5769
  67. package/dist/index.cjs.js.map +1 -1
  68. package/dist/index.d.ts +2908 -276
  69. package/dist/index.esm.js +13149 -5779
  70. package/dist/index.esm.js.map +1 -1
  71. package/dist/jsx-dev-runtime.cjs.js +26 -334
  72. package/dist/jsx-dev-runtime.cjs.js.map +1 -1
  73. package/dist/jsx-dev-runtime.esm.js +19 -327
  74. package/dist/jsx-dev-runtime.esm.js.map +1 -1
  75. package/dist/jsx-runtime.cjs.js +26 -334
  76. package/dist/jsx-runtime.cjs.js.map +1 -1
  77. package/dist/jsx-runtime.esm.js +19 -327
  78. package/dist/jsx-runtime.esm.js.map +1 -1
  79. package/dist/jsx.cjs.js +10 -314
  80. package/dist/jsx.cjs.js.map +1 -1
  81. package/dist/jsx.esm.js +8 -315
  82. package/dist/jsx.esm.js.map +1 -1
  83. package/dist/react.cjs.js +117 -0
  84. package/dist/react.cjs.js.map +1 -0
  85. package/dist/react.esm.js +115 -0
  86. package/dist/react.esm.js.map +1 -0
  87. package/dist/shims/globalthis.cjs +20 -0
  88. package/dist/sygnal.min.js +1 -1
  89. package/dist/sygnal.min.js.map +1 -1
  90. package/dist/ui-combobox.cjs.js +169 -0
  91. package/dist/ui-combobox.cjs.js.map +1 -0
  92. package/dist/ui-combobox.esm.js +148 -0
  93. package/dist/ui-combobox.esm.js.map +1 -0
  94. package/dist/ui-menu.cjs.js +87 -0
  95. package/dist/ui-menu.cjs.js.map +1 -0
  96. package/dist/ui-menu.esm.js +66 -0
  97. package/dist/ui-menu.esm.js.map +1 -0
  98. package/dist/ui-select.cjs.js +104 -0
  99. package/dist/ui-select.cjs.js.map +1 -0
  100. package/dist/ui-select.esm.js +83 -0
  101. package/dist/ui-select.esm.js.map +1 -0
  102. package/dist/ui.cjs.js +738 -0
  103. package/dist/ui.cjs.js.map +1 -0
  104. package/dist/ui.esm.js +727 -0
  105. package/dist/ui.esm.js.map +1 -0
  106. package/dist/vike/ClientOnly.cjs.js +4 -14
  107. package/dist/vike/ClientOnly.cjs.js.map +1 -1
  108. package/dist/vike/ClientOnly.mjs +4 -14
  109. package/dist/vike/ClientOnly.mjs.map +1 -1
  110. package/dist/vike/{+config.js → config/+config.js} +9 -1
  111. package/dist/vike/config/+config.js.map +1 -0
  112. package/dist/vike/config/package.json +6 -0
  113. package/dist/vike/onRenderClient.cjs.js +165 -95
  114. package/dist/vike/onRenderClient.cjs.js.map +1 -1
  115. package/dist/vike/onRenderClient.mjs +165 -95
  116. package/dist/vike/onRenderClient.mjs.map +1 -1
  117. package/dist/vike/onRenderHtml.cjs.js +59 -24
  118. package/dist/vike/onRenderHtml.cjs.js.map +1 -1
  119. package/dist/vike/onRenderHtml.mjs +60 -25
  120. package/dist/vike/onRenderHtml.mjs.map +1 -1
  121. package/dist/vite/plugin.cjs.js +323 -88
  122. package/dist/vite/plugin.cjs.js.map +1 -1
  123. package/dist/vite/plugin.mjs +323 -89
  124. package/dist/vite/plugin.mjs.map +1 -1
  125. package/dist/zag.cjs.js +408 -0
  126. package/dist/zag.cjs.js.map +1 -0
  127. package/dist/zag.esm.js +405 -0
  128. package/dist/zag.esm.js.map +1 -0
  129. package/llms.txt +166 -103
  130. package/package.json +98 -14
  131. package/src/astro/client.ts +27 -16
  132. package/src/astro/index.d.ts +24 -0
  133. package/src/astro/index.ts +69 -3
  134. package/src/astro/server.ts +8 -2
  135. package/src/collection.ts +6 -93
  136. package/src/core/actions.ts +134 -0
  137. package/src/core/cell.ts +202 -0
  138. package/src/core/debug.ts +23 -0
  139. package/src/core/define.ts +242 -0
  140. package/src/core/hooks.ts +314 -0
  141. package/src/core/hosts/collection.ts +325 -0
  142. package/src/core/hosts/switchable.ts +146 -0
  143. package/src/core/instance.ts +592 -0
  144. package/src/core/markers/clientonly.ts +13 -0
  145. package/src/core/markers/lazy.ts +40 -0
  146. package/src/core/markers/portal.ts +96 -0
  147. package/src/core/markers/suspense.ts +41 -0
  148. package/src/core/markers/transition.ts +70 -0
  149. package/src/core/registry.ts +25 -0
  150. package/src/core/runtime.ts +573 -0
  151. package/src/core/statics.ts +104 -0
  152. package/src/core/teardown.ts +60 -0
  153. package/src/core/view.ts +37 -0
  154. package/src/cycle/dom/DocumentDOMSource.ts +13 -8
  155. package/src/cycle/dom/ElementFinder.ts +7 -9
  156. package/src/cycle/dom/EventDelegator.ts +174 -223
  157. package/src/cycle/dom/IsolateModule.ts +65 -35
  158. package/src/cycle/dom/MainDOMSource.ts +9 -2
  159. package/src/cycle/dom/PriorityQueue.ts +4 -2
  160. package/src/cycle/dom/SymbolTree.ts +18 -47
  161. package/src/cycle/dom/classNameModule.ts +9 -7
  162. package/src/cycle/dom/controlledInputModule.ts +23 -6
  163. package/src/cycle/dom/enrichEventStream.ts +25 -47
  164. package/src/cycle/dom/fragment.ts +7 -0
  165. package/src/cycle/dom/isolate.ts +30 -27
  166. package/src/cycle/dom/makeDOMDriver.ts +115 -56
  167. package/src/cycle/dom/mockDOMSource.ts +21 -1
  168. package/src/cycle/dom/modules.ts +16 -3
  169. package/src/cycle/dom/propsModule.ts +65 -0
  170. package/src/cycle/dom/selectModule.ts +22 -17
  171. package/src/cycle/dom/snabbdom.ts +1 -6
  172. package/src/cycle/dom/thunk.ts +3 -0
  173. package/src/cycle/dom/utils.ts +98 -0
  174. package/src/cycle/dom/viewTransition.ts +43 -0
  175. package/src/cycle/state/StateSource.ts +19 -3
  176. package/src/cycle/state/objIsEqual.ts +50 -0
  177. package/src/cycle/state/types.ts +0 -10
  178. package/src/defineComponent.ts +34 -0
  179. package/src/devtools.d.ts +151 -0
  180. package/src/devtools.ts +34 -0
  181. package/src/element.d.ts +59 -0
  182. package/src/element.ts +235 -0
  183. package/src/extra/backoff.ts +9 -0
  184. package/src/extra/behaviors.ts +169 -0
  185. package/src/extra/browserSignals.ts +23 -0
  186. package/src/extra/browserSources.ts +326 -0
  187. package/src/extra/command.ts +3 -3
  188. package/src/extra/controls.ts +47 -0
  189. package/src/extra/copyAsTest.ts +286 -0
  190. package/src/extra/devtools.ts +101 -31
  191. package/src/extra/devtoolsActions.ts +379 -0
  192. package/src/extra/devtoolsHook.ts +9 -0
  193. package/src/extra/devtoolsNext.ts +83 -0
  194. package/src/extra/diagnostics/checks/actionLog.ts +108 -0
  195. package/src/extra/diagnostics/checks/behaviors.ts +49 -0
  196. package/src/extra/diagnostics/checks/browserSources.ts +96 -0
  197. package/src/extra/diagnostics/checks/collections.ts +1 -1
  198. package/src/extra/diagnostics/checks/controls.ts +148 -0
  199. package/src/extra/diagnostics/checks/dataset.ts +57 -0
  200. package/src/extra/diagnostics/checks/dom.ts +20 -11
  201. package/src/extra/diagnostics/checks/elementCommands.ts +175 -0
  202. package/src/extra/diagnostics/checks/events.ts +17 -2
  203. package/src/extra/diagnostics/checks/fetch.ts +135 -0
  204. package/src/extra/diagnostics/checks/forms.ts +163 -0
  205. package/src/extra/diagnostics/checks/index.ts +97 -4
  206. package/src/extra/diagnostics/checks/inspect.ts +140 -32
  207. package/src/extra/diagnostics/checks/next.ts +417 -0
  208. package/src/extra/diagnostics/checks/persist.ts +54 -0
  209. package/src/extra/diagnostics/checks/props.ts +10 -5
  210. package/src/extra/diagnostics/checks/public.d.ts +98 -7
  211. package/src/extra/diagnostics/checks/replies.ts +128 -0
  212. package/src/extra/diagnostics/checks/router.ts +100 -0
  213. package/src/extra/diagnostics/checks/rxjsHints.ts +1 -1
  214. package/src/extra/diagnostics/checks/shared.ts +86 -2
  215. package/src/extra/diagnostics/checks/shorthand.ts +115 -0
  216. package/src/extra/diagnostics/checks/sortable.ts +129 -0
  217. package/src/extra/diagnostics/checks/state.ts +100 -7
  218. package/src/extra/diagnostics/checks/statics.ts +48 -0
  219. package/src/extra/diagnostics/checks/strict.ts +10 -67
  220. package/src/extra/diagnostics/checks/timers.ts +80 -0
  221. package/src/extra/diagnostics/checks/viewTransitions.ts +47 -0
  222. package/src/extra/diagnostics/checks/virtual.ts +73 -0
  223. package/src/extra/diagnostics/checks/widgets.ts +109 -0
  224. package/src/extra/diagnostics/checks/wiring.ts +66 -10
  225. package/src/extra/diagnostics/codes.ts +268 -23
  226. package/src/extra/diagnostics/index.ts +34 -9
  227. package/src/extra/diagnostics/legacy.ts +17 -0
  228. package/src/extra/driverFactories.ts +83 -19
  229. package/src/extra/elementCommands.ts +53 -0
  230. package/src/extra/fetchDriver.ts +519 -0
  231. package/src/extra/focusWithin.ts +27 -0
  232. package/src/extra/form.ts +268 -0
  233. package/src/extra/formHelpers.ts +139 -0
  234. package/src/extra/head.ts +106 -0
  235. package/src/extra/hmr.ts +2 -3
  236. package/src/extra/owned.ts +24 -0
  237. package/src/extra/pager.ts +50 -0
  238. package/src/extra/persist.ts +133 -0
  239. package/src/extra/pwa.ts +1 -1
  240. package/src/extra/queryCache.ts +107 -0
  241. package/src/extra/reducers.ts +1 -1
  242. package/src/extra/reduxDevtools.ts +92 -0
  243. package/src/extra/replies.ts +54 -0
  244. package/src/extra/router.ts +323 -0
  245. package/src/extra/run.ts +90 -217
  246. package/src/extra/selection.ts +76 -0
  247. package/src/extra/socketDriver.ts +265 -0
  248. package/src/extra/sortable.ts +377 -0
  249. package/src/extra/ssr.ts +427 -160
  250. package/src/extra/standardSchema.ts +27 -0
  251. package/src/extra/testing.ts +2433 -175
  252. package/src/extra/timers.ts +95 -0
  253. package/src/extra/undo.ts +261 -0
  254. package/src/extra/viewTransitions.ts +38 -0
  255. package/src/extra/virtual.ts +513 -0
  256. package/src/extra/widget.ts +201 -0
  257. package/src/index.d.ts +2631 -117
  258. package/src/index.ts +25 -4
  259. package/src/jsx-runtime.ts +15 -1
  260. package/src/jsx.ts +2 -1
  261. package/src/lazy.ts +50 -7
  262. package/src/portal.ts +3 -1
  263. package/src/pragma/index.ts +256 -133
  264. package/src/react-peers.d.ts +5 -0
  265. package/src/react.d.ts +43 -0
  266. package/src/react.ts +110 -0
  267. package/src/shared.ts +48 -0
  268. package/src/slot.ts +1 -1
  269. package/src/suspense.ts +3 -1
  270. package/src/switchable.ts +6 -121
  271. package/src/transition.ts +3 -1
  272. package/src/ui/accordion.ts +64 -0
  273. package/src/ui/dialog.ts +129 -0
  274. package/src/ui/disclosure.ts +35 -0
  275. package/src/ui/popover.ts +45 -0
  276. package/src/ui/shared.ts +94 -0
  277. package/src/ui/tabs.ts +82 -0
  278. package/src/ui/toaster.ts +198 -0
  279. package/src/ui/tooltip.ts +70 -0
  280. package/src/ui/zag/combobox.ts +115 -0
  281. package/src/ui/zag/menu.ts +40 -0
  282. package/src/ui/zag/select.ts +54 -0
  283. package/src/ui/zag/shared.ts +43 -0
  284. package/src/ui-combobox.d.ts +20 -0
  285. package/src/ui-combobox.ts +6 -0
  286. package/src/ui-menu.d.ts +30 -0
  287. package/src/ui-menu.ts +6 -0
  288. package/src/ui-select.d.ts +17 -0
  289. package/src/ui-select.ts +6 -0
  290. package/src/ui-zag-types.d.ts +42 -0
  291. package/src/ui.d.ts +208 -0
  292. package/src/ui.ts +15 -0
  293. package/src/vike/+config.ts +9 -1
  294. package/src/vike/ClientOnly.ts +1 -1
  295. package/src/vike/onRenderClient.ts +144 -96
  296. package/src/vike/onRenderHtml.ts +69 -26
  297. package/src/vike/types.ts +7 -1
  298. package/src/vite/globalthis-shim.ts +18 -0
  299. package/src/vite/globalthis.ts +56 -0
  300. package/src/vite/plugin.d.ts +22 -3
  301. package/src/vite/plugin.ts +222 -24
  302. package/src/zag.d.ts +64 -0
  303. package/src/zag.ts +238 -0
  304. package/dist/vike/+config.cjs.js +0 -66
  305. package/dist/vike/+config.cjs.js.map +0 -1
  306. package/dist/vike/+config.js.map +0 -1
  307. package/src/component.ts +0 -2301
  308. package/src/cycle/isolate/index.ts +0 -196
  309. package/src/cycle/run/index.ts +0 -151
  310. package/src/cycle/run/internals.ts +0 -143
  311. package/src/cycle/state/Collection.ts +0 -184
  312. package/src/cycle/state/index.ts +0 -5
  313. package/src/cycle/state/pickCombine.ts +0 -201
  314. package/src/cycle/state/pickMerge.ts +0 -122
  315. package/src/cycle/state/withState.ts +0 -47
  316. package/src/pragma/fn.ts +0 -55
@@ -0,0 +1,109 @@
1
+ /**
2
+ * PLAN-5 W-1: widget diagnostics (dev entry; `defineWidget` in src/extra/widget.ts carries no text).
3
+ *
4
+ * The widget module calls `__SYGNAL_DIAGNOSTICS__.widget(code, widgetTag, owner, extra)`:
5
+ * 140 dispatch(name) (mount's third parameter) — SYG140 (warn) when `name` is not in the widget's `events`: sygnal-check and
6
+ * the docs read `events`, so an undeclared name is a typo or a missing declaration
7
+ * 143 the widget tag used as a selector (DOM.select(DatePicker), `${DatePicker}`) — SYG143
8
+ * (warn, once per widget): it matches nothing
9
+ * 144 a host mounted — SYG144 (info, once per widget): a declared event name the host element
10
+ * also fires natively (`'change'` on an `<input>` host), so the intent sees both; not
11
+ * for the first-party Zag parts (`def.$own`: Menu's `select`, D211)
12
+ * 660/661/662 mount / update / unmount threw (`extra` is the error) — SYG660–662 (error);
13
+ * 661 with a fifth argument (G-580): the widget reported the error through mount's
14
+ * error(e) (its own timer or callback), worded as such (data.phase 'error')
15
+ * 669 fromZag (G-410): its render returned Sygnal components / widget tags / special JSX
16
+ * (`extra`: their tags, e.g. ['<Badge>', '<Transition>']) — SYG669 (warn, once per widget)
17
+ * It returns the reported diagnostic (the widget module logs a bare `[Sygnal SYG66x]` otherwise).
18
+ *
19
+ * SYG141 (listening to an event a widget doesn't declare) is static only (sygnal-check): the
20
+ * runtime doesn't see which listener a selector serves. SYG142 for an undeclared command sent to a
21
+ * widget's host is reported by the element command check (checks/elementCommands.ts).
22
+ */
23
+ import {devReport, once, unsee, nameOf} from './shared'
24
+ import {DEV_CODE_SEVERITY} from '../codes'
25
+
26
+ /** a widget's name for messages: `name` from its definition, else its host tag */
27
+ export const widgetName = (w: any): string => w?.def?.name ? `widget ${w.def.name}` : `widget <${w?.def?.tag || 'div'}>`
28
+
29
+ const ids = new WeakMap<object, number>()
30
+ let next = 0
31
+ const idOf = (w: any): number => {
32
+ let id = ids.get(w)
33
+ if (id === undefined) ids.set(w, id = ++next)
34
+ return id
35
+ }
36
+
37
+ const PHASE: Record<number, string> = {660: 'mount', 661: 'update', 662: 'unmount'}
38
+
39
+ export function reportWidget(code: number, w: any, owner?: any, x?: any, reported?: any): any {
40
+ const name = widgetName(w), component = owner ? nameOf(owner) : name
41
+ if (code == 140) {
42
+ if (w.events.includes(x) || !once(`SYG140:${idOf(w)}:${x}`)) return
43
+ return devReport('SYG140', {
44
+ component,
45
+ message: `${name} dispatched '${x}', which is not one of its declared events (${w.events.length ? w.events.join(', ') : 'it declares none'})`,
46
+ fix: `Add '${x}' to the widget's events (defineWidget({ events: [${[...w.events, x].map((e: string) => `'${e}'`).join(', ')}] })), or dispatch a declared name`,
47
+ data: {event: x, events: w.events},
48
+ })
49
+ }
50
+ if (code == 143) {
51
+ if (!once(`SYG143:${idOf(w)}`)) return
52
+ return devReport('SYG143', {
53
+ component: name,
54
+ message: `${name} was used as a selector (DOM.select(${w.def.name || 'Widget'}) or in a template string); a widget tag matches nothing`,
55
+ fix: `Give the widget a className and select that (<${w.def.name || 'Widget'} className="due" />, DOM.select('.due')), or make it a control: controls({ Due: ${w.def.name || 'Widget'} })`,
56
+ })
57
+ }
58
+ if (code == 144) {
59
+ // D211: not for Sygnal's own parts (Menu's `select` is its documented event)
60
+ if (!x || w.def.$own || !once(`SYG144:${idOf(w)}`)) return
61
+ const native = w.events.filter((e: string) => 'on' + e in x)
62
+ if (!native.length) return
63
+ return devReport('SYG144', {
64
+ component: name,
65
+ message: `${name} declares ${native.map((e: string) => `'${e}'`).join(', ')}, which its <${x.localName}> host also fires natively, so a listener gets both the widget's events and the element's`,
66
+ fix: `Name the widget's event differently (e.g. 'pick' for a date picker's change), or read only what both carry`,
67
+ data: {events: native, element: x.localName},
68
+ })
69
+ }
70
+ if (code == 669) {
71
+ // G-470: once per widget tag, counted only when reported (not with diagnostics off)
72
+ const k = `SYG669:${idOf(w)}`
73
+ if (!once(k)) return
74
+ const d = devReport('SYG669', {
75
+ component: name,
76
+ message: `${name}'s fromZag render returned ${x.join(', ')}; the adapter patches its render outside the component tree, so they don't run there (a component isn't instantiated, a widget doesn't mount, special JSX renders as an unknown element)`,
77
+ fix: `Render plain elements in the fromZag render (with Zag's prop getters spread on them), pass data in through the widget's props, and put components, widgets and special JSX around the widget tag in the view`,
78
+ data: {found: x},
79
+ })
80
+ if (!d) unsee(k)
81
+ return d
82
+ }
83
+ const phase = PHASE[code]
84
+ if (!phase) return
85
+ const sev = DEV_CODE_SEVERITY[`SYG${code}`]
86
+ // G-580: a 661 from error(e) is not a throwing update()
87
+ const by = code == 661 && reported
88
+ const d = devReport(`SYG${code}`, {
89
+ component,
90
+ message: (by ? `${name} reported an error through error(e) (mount's fourth parameter)` : `${name}'s ${phase}() threw`) + `: ${x?.message ?? x}` +
91
+ (code < 662 ? `; ${owner ? `${nameOf(owner)}'s onError fallback renders in its place` : 'it is not mounted'}` : ''),
92
+ fix: code < 662
93
+ ? `Fix ${by ? 'the failure the widget reports through error(e) (its own timer, callback or redraw)' : `the widget's ${phase}()`}, or give ${owner ? nameOf(owner) : 'the component'} an .onError for a custom fallback`
94
+ : `Fix the widget's unmount()`,
95
+ data: {phase: by ? 'error' : phase, error: x},
96
+ severity: sev,
97
+ })
98
+ // the error with its stack (the text is printed by report() in 'warn' mode, collected otherwise)
99
+ if (d) console.error(x)
100
+ return d
101
+ }
102
+
103
+ /** Publish the widget hook on the core bridge. Returns an uninstall function. */
104
+ export function installWidgetHooks(): () => void {
105
+ const c = (globalThis as any).__SYGNAL_DIAGNOSTICS__
106
+ if (!c) return () => {}
107
+ c.widget = reportWidget
108
+ return () => { if (c.widget === reportWidget) c.widget = undefined }
109
+ }
@@ -1,13 +1,19 @@
1
1
  /**
2
2
  * SYG101 — intent action has no model entry (warn)
3
3
  * SYG102 — model entry has no intent trigger (info; it may still be reached
4
- * with next(), which is only known at call time)
4
+ * with next(), which is only known at call time). An action a request
5
+ * names as a reply action, or `connections` names (`ok: 'LOADED'`, PLAN-3) counts as
6
+ * triggered: replyNamesOf() reads the names from the sink functions'
7
+ * source. A behavior's own actions (D199: in `_behaviorActions`) are not
8
+ * reported
9
+ * SYG609 — a model sink or an intent source has no driver (warn; see below)
5
10
  *
6
11
  * Mechanism: onIntent records the intent's action names per component;
7
12
  * onModel (always called right after, once per instance) compares them with
8
13
  * the normalized model map (shorthand already expanded by the core).
9
14
  * Synthetic actions (`__*`, e.g. renderComponent's `__TEST_ACTION__`) and the
10
- * built-ins BOOTSTRAP/INITIALIZE/HYDRATE/DISPOSE/READY are never reported.
15
+ * built-ins BOOTSTRAP/INITIALIZE/DISPOSE/READY are never reported (HYDRATE is an
16
+ * ordinary action since 6.0).
11
17
  * Under renderComponent, intent streams injected for model actions (so that
12
18
  * simulateAction can dispatch them by their real names) are listed on the
13
19
  * intent object's non-enumerable `__sygnalTestActions` property. They are not
@@ -15,10 +21,25 @@
15
21
  * for those model actions (the test dispatches them with simulateAction).
16
22
  */
17
23
  import type {DiagnosticCheck} from '../index'
18
- import {report, once, isInternalAction, nameOf, didYouMean} from './shared'
24
+ import {report, once, isInternalAction, nameOf, didYouMean, replyNamesOf} from './shared'
19
25
 
20
26
  const intentActions = new WeakMap<object, string[]>()
21
27
 
28
+ // SYG609 (G-110, PLAN-2 E2): sinks/sources that no driver provides. Sinks the core handles
29
+ // itself never need one. renderComponent (mock DOM source) records such sinks and fakes such
30
+ // sources (t.requests / t.respond), so its components are skipped.
31
+ // PLAN-4 GS-2: ELEMENT (element commands) is built in; GS-5: PERSIST is persist()'s (an EFFECT)
32
+ const NO_DRIVER_NEEDED = /^(STATE|EFFECT|PARENT|READY|DOM|CHILD|ELEMENT|PERSIST)$/
33
+ const DRIVER_NAME = /^[A-Z][A-Z0-9_]*$/
34
+ // (`in`, not a read: the DOM source's shorthand Proxy returns a function for any property)
35
+ const underTest = (c: any) => {
36
+ const dom = c?.sources?.[c.DOMSourceName || 'DOM']
37
+ return !!dom && typeof dom == 'object' && '_hub' in dom
38
+ }
39
+ const driverFix = (sink: string) =>
40
+ `Pass a driver named ${sink} to run(): run(App, { ${sink}: makeFetchDriver() }) for HTTP, or driverFromAsync(fn) / your own driver. ` +
41
+ `Check the spelling against the drivers you pass`
42
+
22
43
  export const wiringCheck: DiagnosticCheck = {
23
44
  id: 'wiring',
24
45
 
@@ -26,8 +47,44 @@ export const wiringCheck: DiagnosticCheck = {
26
47
  intentActions.set(component, actionNames || [])
27
48
  },
28
49
 
50
+ // SYG609: an intent that reads a source no driver provides (`HTTP.select(...)` with no HTTP
51
+ // driver) would crash with "Cannot read properties of undefined": say why first
52
+ sources(component, sources) {
53
+ if (underTest(component) || typeof Proxy != 'function') return
54
+ const name = nameOf(component)
55
+ return new Proxy(sources, {
56
+ get(t: any, k: any) {
57
+ if (typeof k == 'string' && !(k in t) && DRIVER_NAME.test(k) && once(`SYG609:${name}:source:${k}`)) {
58
+ report('SYG609', {
59
+ component,
60
+ message: `${name}.intent reads the ${k} source, but no driver named ${k} was passed to run(), so it is undefined`,
61
+ fix: driverFix(k),
62
+ data: {name: k, kind: 'source', drivers: Object.keys(t).filter(n => DRIVER_NAME.test(n))},
63
+ })
64
+ }
65
+ return t[k]
66
+ },
67
+ })
68
+ },
69
+
29
70
  onModel(component, modelMap) {
30
71
  const name = nameOf(component)
72
+ // SYG609: a sink no driver receives is dropped silently by run()
73
+ if (!underTest(component)) {
74
+ const own = new Set<string>(component?.sourceNames || [])
75
+ for (const action of Object.keys(modelMap || {})) {
76
+ for (const sink of modelMap[action] || []) {
77
+ if (own.has(sink) || NO_DRIVER_NEEDED.test(sink) || sink === component?.stateSourceName) continue
78
+ if (!once(`SYG609:${name}:sink:${sink}`)) continue
79
+ report('SYG609', {
80
+ component,
81
+ message: `Model entry '${action}' sends to the ${sink} sink, but no driver named ${sink} was passed to run(), so every value sent there is dropped`,
82
+ fix: driverFix(sink),
83
+ data: {name: sink, kind: 'sink', action, drivers: [...own].filter(n => DRIVER_NAME.test(n))},
84
+ })
85
+ }
86
+ }
87
+ }
31
88
  const intent$ = component && component.intent$
32
89
  const injected = new Set<string>(
33
90
  (intent$ && typeof intent$ === 'object' && intent$.__sygnalTestActions) || [])
@@ -46,18 +103,17 @@ export const wiringCheck: DiagnosticCheck = {
46
103
  })
47
104
  }
48
105
 
49
- // A single-stream intent (intent returns one action$ stream) has no
50
- // action names to compare against.
51
- if (intent$ && typeof intent$.addListener === 'function') return
52
-
53
- const hmr = ([] as string[]).concat(component?.hmrActions || [])
106
+ const replies = replyNamesOf(component)
107
+ // D199: a behavior's own actions ('tip.SHOW') are its business: a timer, next() or a reply
108
+ // may trigger them (the behavior-owned map, behaviors.ts)
109
+ const owned = component?._behaviorActions || {}
54
110
  for (const action of modelActions) {
55
- if (isInternalAction(action) || actions.includes(action) || hmr.includes(action) || injected.has(action)) continue
111
+ if (isInternalAction(action) || actions.includes(action) || injected.has(action) || replies.has(action) || action in owned) continue
56
112
  if (!once(`SYG102:${name}:${action}`)) continue
57
113
  report('SYG102', {
58
114
  component,
59
115
  message: `Model entry '${action}' has no intent action with that name${didYouMean(action, actions)}`,
60
- fix: `Add '${action}' to ${name}.intent, or remove the model entry. If it is only dispatched with next('${action}'), ignore this`,
116
+ fix: `Add '${action}' to ${name}.intent, name it in a request (ok: '${action}'), or remove the model entry. If it is only dispatched with next('${action}'), ignore this`,
61
117
  data: {action, intentActions: actions},
62
118
  })
63
119
  }
@@ -20,10 +20,18 @@
20
20
  * (Comments are attached to type-only declarations so the TypeScript emit
21
21
  * drops them — keeps them out of the published bundle and the size gate.)
22
22
  *
23
- * Severity:
24
- * - 'error' — throws (or is rethrown, enriched) at the call site
25
- * - 'warn' — console + collected (when diagnostics mode is 'warn')
23
+ * Severity (PLAN-2 1-B, G-044):
24
+ * - 'error' — the operation failed: thrown at the call site, or caught there
25
+ * (reducer, EFFECT, view, sub-component) and logged with
26
+ * console.error while the app keeps running
27
+ * - 'warn' — likely mistake, behaviour continues: console + collected
28
+ * (when diagnostics mode is 'warn')
26
29
  * - 'info' — collected only; surfaced through inspect / test helpers
30
+ * A call site may report a lower severity than the default (SYG405 for
31
+ * Collection/Switchable children, SYG406 handled by onError: 'warn').
32
+ * Every code surfaces under its own code: an error thrown by fail() and
33
+ * caught by a reducer/EFFECT/instantiation handler is reported under the
34
+ * thrown code (legacy.caught), not the handler's.
27
35
  *
28
36
  * Ranges (see dev-plans/PLAN-1.md §2):
29
37
  * SYG1xx Wiring: intent <-> model <-> view <-> events
@@ -32,6 +40,7 @@
32
40
  * SYG4xx Collections, Switchable, sub-components, context
33
41
  * SYG5xx Strict mode / canonical-form violations
34
42
  * SYG6xx Drivers & run configuration
43
+ * SYG7xx Accessibility (a11y; static only, sygnal-check, PLAN-4 GS-3)
35
44
  * SYG9xx Internal invariants
36
45
  *
37
46
  * ---------------------------------------------------------------------------
@@ -93,7 +102,7 @@ export const CODE_SEVERITY: Record<string, DiagnosticSeverity> = {
93
102
  SYG402: 'error',
94
103
  SYG403: 'error',
95
104
  SYG404: 'error',
96
- SYG405: 'warn',
105
+ SYG405: 'error',
97
106
  SYG406: 'error',
98
107
  SYG407: 'error',
99
108
  SYG408: 'error',
@@ -116,6 +125,9 @@ export const CODE_SEVERITY: Record<string, DiagnosticSeverity> = {
116
125
  SYG605: 'error',
117
126
  SYG606: 'error',
118
127
  SYG607: 'error',
128
+ SYG608: 'warn',
129
+ SYG609: 'warn',
130
+ SYG610: 'error',
119
131
  SYG901: 'error',
120
132
  SYG902: 'error',
121
133
  SYG903: 'error',
@@ -132,6 +144,40 @@ export const CODE_TITLES: Record<string, string> = {
132
144
  SYG106: 'Parent prop is overwritten by a reserved view argument',
133
145
  SYG110: 'Intent selector not present in the component view',
134
146
  SYG111: 'Controlled input has no input listener',
147
+ SYG115: 'Unknown DOM event shorthand',
148
+ SYG116: 'EVENTS value has no string type',
149
+ SYG124: 'Component used as a control or selector',
150
+ SYG125: 'Control given .intent, .model or .initialState',
151
+ SYG126: 'Control rendered but never listened to',
152
+ SYG127: 'Behavior collision or unresolvable uses entry',
153
+ SYG128: 'Duplicate control key',
154
+ SYG129: "CHILD.select() of a component this one doesn't render",
155
+ SYG112: 'Reply action has no model entry',
156
+ SYG130: 'href() names no route or leaves out a param',
157
+ SYG131: 'Route params the pattern does not use',
158
+ SYG132: 'Declaration static that is never sent',
159
+ SYG133: 'SPA router inside a Vike app',
160
+ // PLAN-5 W-1: widgets (defineWidget; checks/widgets.ts, checks/elementCommands.ts; SYG141 static only)
161
+ SYG140: 'Widget dispatched an undeclared event',
162
+ SYG141: 'Listener for an event the widget does not declare',
163
+ SYG142: 'Widget command not declared',
164
+ SYG143: 'Widget tag used as a selector',
165
+ SYG144: 'Widget event the host element also fires natively',
166
+ // PLAN-5 B-1 (3-D): the sortable behavior (checks/sortable.ts; sortable.ts calls the bridge's sortable hook)
167
+ SYG145: 'Sortable item without its id attribute',
168
+ SYG146: 'Sortable item or handle selector matches nothing',
169
+ SYG147: 'Sortable list key is not an array in the host state',
170
+ // PLAN-5 3-F G-419: a Collection's viewTransitionName (checks/next.ts)
171
+ SYG148: 'Collection viewTransitionName is not a CSS identifier',
172
+ SYG149: 'Two items with the same view-transition name',
173
+ // PLAN-5 V-1: VirtualCollection (checks/virtual.ts)
174
+ SYG430: 'VirtualCollection has no bounded height',
175
+ SYG431: 'VirtualCollection items without ids',
176
+ SYG432: 'VirtualCollection item does not render one element',
177
+ SYG433: 'VirtualCollection scroll target not in the list',
178
+ SYG434: 'Invalid VirtualCollection estimateSize or overscan',
179
+ // PLAN-5 3-H (G-449): sortable over a list shown in another order (checks/sortable.ts)
180
+ SYG435: 'Sortable list shown filtered or in another order',
135
181
  // SYG2xx state & reducers (1A)
136
182
  SYG201: 'STATE reducer dropped keys from the previous state',
137
183
  SYG202: 'STATE reducer returned undefined',
@@ -140,13 +186,14 @@ export const CODE_TITLES: Record<string, string> = {
140
186
  // SYG4xx collections / switchable / sub-components / context (1A)
141
187
  SYG401: "Collection 'from' field is missing or not an array",
142
188
  // SYG5xx strict mode / canonical forms (2A; dev-plans/PLAN-1-canonical-forms.md)
143
- SYG501: 'View uses positional arguments',
144
- SYG502: 'STATE reducer signals no change without ABORT',
189
+ SYG501: "Removed in 6.0: view with positional arguments",
190
+ SYG502: 'Retired in 6.0: STATE reducer signals no change without ABORT',
145
191
  SYG503: 'Side effect in a STATE reducer that returns ABORT',
146
- SYG504: "'ACTION | SINK' shorthand model key",
192
+ SYG504: "Removed in 6.0: 'ACTION | SINK' model key",
147
193
  SYG505: 'Non-canonical EVENTS emit',
148
- SYG506: 'CHILD.select() with a string component name',
194
+ SYG506: "Removed in 6.0: CHILD.select() with a component name",
149
195
  SYG507: 'Prop drilled through more than 2 component levels',
196
+ SYG508: 'select()/errors() round trip where reply actions would do',
150
197
  // SYG9xx internal (0B)
151
198
  SYG900: 'A diagnostics check threw',
152
199
  // ---- 1E retrofit codes (SYG206-299, 402-499, 601-699, 901-999) ----
@@ -155,9 +202,9 @@ export const CODE_TITLES: Record<string, string> = {
155
202
  SYG208: 'Calculated field depends on an unknown key',
156
203
  SYG209: 'Circular calculated field dependency',
157
204
  SYG210: 'INITIALIZE used with a sink other than STATE',
158
- SYG211: 'Invalid model shorthand entry',
205
+ SYG211: "Retired in 6.0: Invalid model shorthand entry",
159
206
  SYG212: 'Model entry is not a function or an object of sinks',
160
- SYG213: 'Duplicate model entry for the same action and sink',
207
+ SYG213: "Retired in 6.0: Duplicate model entry for the same action and sink",
161
208
  SYG214: 'EFFECT handler threw',
162
209
  SYG215: 'next() delay is not a number',
163
210
  SYG216: 'Reducer threw',
@@ -165,6 +212,22 @@ export const CODE_TITLES: Record<string, string> = {
165
212
  SYG218: 'Reducer returned an unsupported type',
166
213
  SYG219: 'EFFECT handler returned a value',
167
214
  SYG220: 'Calculated field threw',
215
+ SYG221: 'set() called with a string',
216
+ SYG222: 'STATE reducer returned the same object after it was mutated in place',
217
+ SYG223: 'persist pick or omit names a key that is not in initialState',
218
+ SYG224: 'persist on a component that is not the root',
219
+ SYG226: 'Undo track, resetOn or coalesce names an unknown action',
220
+ // PLAN-5 F-1: the form behavior (checks/forms.ts)
221
+ SYG230: 'Form field name not in values',
222
+ SYG231: 'form() schema is not a Standard Schema',
223
+ SYG232: 'Form submit dropped while one is in progress',
224
+ SYG233: 'Form value missing from the schema output',
225
+ SYG234: 'Form submit action has no model entry',
226
+ SYG235: 'Form check names an unknown field or sets reply fields',
227
+ SYG236: 'Form array rows without an id',
228
+ SYG237: 'Two forms in one component listen on the same form selector',
229
+ // PLAN-5 2-R (G-393; checks/state.ts; dev entry)
230
+ SYG238: 'Root component with a model but no initial state',
168
231
  SYG402: 'Context is not an object',
169
232
  SYG403: 'Invalid context entry',
170
233
  SYG404: 'Context stream errored',
@@ -176,24 +239,86 @@ export const CODE_TITLES: Record<string, string> = {
176
239
  SYG410: "Invalid sub-component 'state' prop",
177
240
  SYG411: "Collection 'of' is missing or not a component",
178
241
  SYG412: "Invalid Collection 'from' prop",
179
- SYG413: 'Unnamed component factory not found',
180
- SYG414: 'Component not found',
242
+ SYG413: "Retired in 6.0: Unnamed component factory not found",
243
+ SYG414: "Retired in 6.0: Component not found",
181
244
  SYG415: "Switchable 'of' is missing or invalid",
182
245
  SYG416: "Switchable 'current' is missing or invalid",
183
246
  SYG417: 'Portal target not found',
184
247
  SYG418: 'Invalid Collection sort prop',
185
- SYG419: "Invalid switchable() 'name$' parameter",
248
+ SYG419: "Retired in 6.0: Invalid switchable() 'name$' parameter",
186
249
  SYG420: 'JSX tag is undefined',
187
- SYG601: 'Missing or invalid sources',
250
+ SYG421: 'Invalid data (dataset) key',
251
+ SYG422: 'Invalid timer spec',
252
+ // PLAN-4.6 R4: the core's dev checks (checks/next.ts; dev entry)
253
+ SYG423: 'Context change skipped a view whose output it changes',
254
+ SYG424: 'Duplicate Collection item id',
255
+ SYG425: 'isolatedState slice lacks initialState keys',
256
+ SYG601: "Retired in 6.0: Missing or invalid sources",
188
257
  SYG602: 'Intent is not a function',
189
258
  SYG603: 'Intent returned an invalid value',
190
- SYG604: 'Invalid hmrActions',
191
- SYG605: "Intent action name contains '|'",
259
+ SYG604: "Retired in 6.0: Invalid hmrActions",
260
+ SYG605: "Retired in 6.0: Intent action name contains '|'",
192
261
  SYG606: 'calculated is not an object',
193
- SYG607: 'State source not found',
194
- SYG901: 'Sub-component sink stream errored',
195
- SYG902: 'EFFECT stream errored',
196
- SYG903: 'Component factory returned invalid sinks',
262
+ SYG607: "Retired in 6.0: State source not found",
263
+ SYG608: 'Strict mode requested without the diagnostics entry',
264
+ SYG609: 'Sink or source has no driver',
265
+ SYG610: "Request has a 'then' or 'catch' key",
266
+ SYG611: 'Socket message not sent or connection not opened',
267
+ // PLAN-4.6 R4 (D173): a form 6.0 removed, met at runtime (checks/next.ts; dev entry)
268
+ SYG612: 'Removed in 6.0',
269
+ SYG620: 'Router command not performed',
270
+ // PLAN-3 5-3: makeFetchDriver's cache, invalidation and validation (dev entry; SYG634 static only)
271
+ SYG630: 'Cached request is not idempotent',
272
+ SYG631: 'validate is not a Standard Schema',
273
+ SYG632: 'invalidate matched nothing',
274
+ SYG633: 'abort names a lane the requests do not use',
275
+ SYG634: 'latest: true with a computed key',
276
+ // PLAN-3 5-5 (D88)
277
+ SYG635: 'Caching asked for without a queryCache',
278
+ // PLAN-4 GS-2: element commands (reported by the dev entry, checks/elementCommands.ts)
279
+ SYG640: 'Element command target not found',
280
+ SYG641: 'Unknown element command',
281
+ // PLAN-4 GS-5: persist() (src/extra/persist.ts reports SYG642 with an explicit severity, like SYG611)
282
+ SYG642: 'Persisted state could not be restored or saved',
283
+ // PLAN-4 GS-7: timers (checks/timers.ts; dev entry)
284
+ SYG643: 'Declaration static with no driver to take it',
285
+ // PLAN-4 D131: sygnal/element (reported through the core bridge when diagnostics are on)
286
+ SYG644: 'Custom element prop hides an HTMLElement member',
287
+ // PLAN-4 GS-12 (D129): View Transitions (checks/viewTransitions.ts; dev entry)
288
+ SYG645: "viewTransitions that can't run",
289
+ // PLAN-5 W-1: a widget's mount / update / unmount threw (checks/widgets.ts; dev entry)
290
+ SYG660: 'Widget mount threw',
291
+ SYG661: 'Widget update threw or reported an error',
292
+ SYG662: 'Widget unmount threw',
293
+ // PLAN-5 B-3: browser sources (makeBrowserDriver; checks/browserSources.ts; dev entry)
294
+ SYG663: 'Invalid browser-source spec or command',
295
+ SYG664: 'Browser source not in the driver',
296
+ SYG665: 'Browser source failed with no error action',
297
+ // PLAN-5 W-2 (D203): the adapter entries (sygnal/react, sygnal/zag, sygnal/ui/menu|select|combobox): SYG666 from
298
+ // sygnal/vite (an entry imported without its optional peer dependencies), SYG667 thrown by
299
+ // fromZag / fromReact
300
+ SYG666: 'Adapter peer dependency missing',
301
+ SYG667: 'Invalid adapter argument',
302
+ // PLAN-5 2-R (G-383, G-387)
303
+ SYG668: 'Browser source has no element to observe',
304
+ // PLAN-5 2-T (G-410): Sygnal components / widget tags / special JSX inside a fromZag render
305
+ SYG669: 'Sygnal component inside a fromZag render',
306
+ // PLAN-4 GS-3: a11y lane (static only, sygnal-check)
307
+ SYG701: 'Click listener on a non-interactive element',
308
+ SYG702: 'Form field without an accessible label',
309
+ SYG703: 'Image without alt text',
310
+ SYG704: 'Link without href used as a button',
311
+ SYG705: 'Button without an accessible name',
312
+ SYG706: 'Positive tabIndex',
313
+ SYG707: 'Unknown ARIA attribute or invalid role',
314
+ SYG708: 'Label or ARIA reference to an id that is not rendered',
315
+ // PLAN-5 2-T (D211): Zag UI parts (sygnal-check rules/a11y/syg722-ui-name.js)
316
+ SYG722: 'Menu, Select or Combobox without an accessible name',
317
+ // PLAN-5 B-1 (3-D): static only (sygnal-check)
318
+ SYG724: 'Sortable handle not keyboard-accessible, or no live region',
319
+ SYG901: "Retired in 6.0: Sub-component sink stream errored",
320
+ SYG902: "Retired in 6.0: EFFECT stream errored",
321
+ SYG903: "Retired in 6.0: Component factory returned invalid sinks",
197
322
  // ---- end 1E retrofit codes ----
198
323
  }
199
324
 
@@ -202,13 +327,133 @@ export const CODE_TITLES: Record<string, string> = {
202
327
  // entry registers them (registerCodes) and its reports pass the severity
203
328
  // explicitly. sygnal-check keeps the same table in sygnal-check/src/codes.js.
204
329
  export const STRICT_CODE_SEVERITY: Record<string, DiagnosticSeverity> = {
205
- SYG501: 'warn',
330
+ SYG501: 'error',
206
331
  SYG502: 'warn',
207
332
  SYG503: 'warn',
208
- SYG504: 'warn',
333
+ SYG504: 'error',
209
334
  SYG505: 'warn',
210
- SYG506: 'warn',
335
+ SYG506: 'error',
211
336
  SYG507: 'info',
337
+ SYG508: 'warn',
338
+ }
339
+
340
+ // PLAN-3 1-G (G-143): codes only the 'sygnal/diagnostics' dev entry reports. Like the strict
341
+ // table, kept OUT of CODE_SEVERITY (zero bytes in the main bundle); the entry registers them
342
+ // and passes the severity explicitly.
343
+ // PLAN-3 1-D: SYG112 (a reply action has no model entry) too.
344
+ // PLAN-3 2-A: SYG611 too, though makeSocketDriver reports it (legacy error(), severity passed
345
+ // explicitly): kept out of CODE_SEVERITY so the core bundle doesn't pay for an opt-in driver.
346
+ export const DEV_CODE_SEVERITY: Record<string, DiagnosticSeverity> = {
347
+ SYG112: 'error',
348
+ SYG115: 'warn',
349
+ SYG116: 'error',
350
+ // PLAN-4 1-D: controls, static (sygnal-check)
351
+ SYG124: 'error',
352
+ SYG125: 'error',
353
+ SYG126: 'info',
354
+ // PLAN-4 GS-1: behaviors (checks/behaviors.ts)
355
+ SYG127: 'error',
356
+ SYG128: 'error',
357
+ // PLAN-4 4-G2: static only (sygnal-check); listed so the entry knows its title
358
+ SYG129: 'warn',
359
+ SYG221: 'error',
360
+ // PLAN-4 GS-4 (state.ts)
361
+ SYG222: 'warn',
362
+ // PLAN-4 GS-5 (checks/persist.ts; sygnal-check statically)
363
+ SYG223: 'warn',
364
+ SYG224: 'error',
365
+ // PLAN-4 GS-8 (undo.ts reports it when diagnostics are on; sygnal-check statically)
366
+ SYG226: 'warn',
367
+ // PLAN-5 F-1: the form behavior (checks/forms.ts; form.ts calls the bridge's form hook)
368
+ SYG230: 'warn',
369
+ SYG231: 'error',
370
+ SYG232: 'info',
371
+ SYG233: 'warn',
372
+ SYG234: 'warn',
373
+ SYG235: 'warn',
374
+ SYG236: 'warn',
375
+ SYG237: 'warn',
376
+ SYG238: 'warn',
377
+ SYG421: 'error',
378
+ SYG611: 'error',
379
+ // PLAN-3 5-4b: router (SYG620 is reported by the router itself, like SYG611) and G-167
380
+ SYG130: 'error',
381
+ SYG131: 'warn',
382
+ SYG132: 'warn',
383
+ SYG133: 'warn',
384
+ SYG620: 'error',
385
+ // PLAN-3 5-3 (fetch.ts)
386
+ SYG630: 'warn',
387
+ SYG631: 'error',
388
+ SYG632: 'info',
389
+ SYG633: 'warn',
390
+ // static only (sygnal-check); listed so the entry knows its title
391
+ SYG634: 'info',
392
+ // PLAN-3 5-5 (fetch.ts)
393
+ SYG635: 'warn',
394
+ // PLAN-4 GS-2 (checks/elementCommands.ts, through the core bridge; renderComponent too)
395
+ SYG640: 'warn',
396
+ SYG641: 'error',
397
+ // PLAN-4 GS-5 (persist.ts, through legacy warn(): printed in production too)
398
+ SYG642: 'warn',
399
+ // PLAN-4 GS-7 (timers.ts): an invalid timer spec (not started); timers / connections /
400
+ // resources declared with no driver registered
401
+ SYG422: 'error',
402
+ SYG643: 'warn',
403
+ // PLAN-4.6 R4 (checks/next.ts): D168 context-tracking safety net, D169 duplicate ids, D174 kept
404
+ // slice, D173 removed forms
405
+ SYG423: 'warn',
406
+ SYG424: 'warn',
407
+ SYG425: 'warn',
408
+ SYG612: 'error',
409
+ // PLAN-4 D131 (element.ts, through the core bridge; a console warning in dev with diagnostics off)
410
+ SYG644: 'warn',
411
+ // PLAN-4 GS-12 (viewTransitions.ts): the static set, but the app's DOM driver isn't makeViewTransitionDOMDriver()
412
+ SYG645: 'warn',
413
+ // PLAN-5 W-1: widgets (checks/widgets.ts, checks/elementCommands.ts; SYG141 static only, listed
414
+ // so the entry knows its title)
415
+ SYG140: 'warn',
416
+ SYG141: 'warn',
417
+ SYG142: 'error',
418
+ SYG143: 'warn',
419
+ SYG144: 'info',
420
+ // PLAN-5 B-1 (3-D): the sortable behavior (checks/sortable.ts)
421
+ SYG145: 'warn',
422
+ SYG146: 'warn',
423
+ SYG147: 'warn',
424
+ // PLAN-5 3-F G-419 (checks/next.ts: onHostProps, onPatch)
425
+ SYG148: 'warn',
426
+ SYG149: 'warn',
427
+ SYG660: 'error',
428
+ SYG661: 'error',
429
+ SYG662: 'error',
430
+ SYG663: 'error',
431
+ SYG664: 'error',
432
+ SYG665: 'warn',
433
+ SYG666: 'error',
434
+ SYG667: 'error',
435
+ SYG668: 'warn',
436
+ SYG669: 'warn',
437
+ // PLAN-5 V-1: VirtualCollection (checks/virtual.ts, through the core bridge)
438
+ SYG430: 'warn',
439
+ SYG431: 'warn',
440
+ SYG432: 'warn',
441
+ SYG433: 'warn',
442
+ SYG434: 'warn',
443
+ // PLAN-5 3-H (G-449): sortable (checks/sortable.ts)
444
+ SYG435: 'warn',
445
+ // PLAN-4 GS-3: a11y lane, static only (sygnal-check; warn, also under --strict; error with --a11y=error, D144); listed so the entry knows its title
446
+ SYG701: 'warn',
447
+ SYG702: 'warn',
448
+ SYG703: 'warn',
449
+ SYG704: 'warn',
450
+ SYG705: 'warn',
451
+ SYG706: 'warn',
452
+ SYG707: 'warn',
453
+ SYG708: 'warn',
454
+ SYG722: 'warn',
455
+ // PLAN-5 B-1 (3-D): static only (sygnal-check)
456
+ SYG724: 'warn',
212
457
  }
213
458
 
214
459
  export function getCodeInfo(code: string): DiagnosticCodeInfo | undefined {