sygnal 5.3.7 → 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 (438) hide show
  1. package/CHANGELOG.md +646 -0
  2. package/README.md +77 -47
  3. package/dist/astro/client.cjs.js +33 -8114
  4. package/dist/astro/client.cjs.js.map +1 -0
  5. package/dist/astro/client.mjs +33 -8114
  6. package/dist/astro/client.mjs.map +1 -0
  7. package/dist/astro/index.cjs.js +1039 -9
  8. package/dist/astro/index.cjs.js.map +1 -0
  9. package/dist/astro/index.mjs +1038 -9
  10. package/dist/astro/index.mjs.map +1 -0
  11. package/dist/astro/server.cjs.js +3400 -166
  12. package/dist/astro/server.cjs.js.map +1 -0
  13. package/dist/astro/server.mjs +3400 -166
  14. package/dist/astro/server.mjs.map +1 -0
  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 +4033 -0
  20. package/dist/diagnostics.cjs.js.map +1 -0
  21. package/dist/diagnostics.esm.js +4003 -0
  22. package/dist/diagnostics.esm.js.map +1 -0
  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 +15283 -6279
  67. package/dist/index.cjs.js.map +1 -0
  68. package/dist/index.d.ts +3739 -370
  69. package/dist/index.esm.js +15230 -6274
  70. package/dist/index.esm.js.map +1 -0
  71. package/dist/jsx-dev-runtime.cjs.js +27 -329
  72. package/dist/jsx-dev-runtime.cjs.js.map +1 -0
  73. package/dist/jsx-dev-runtime.esm.js +20 -322
  74. package/dist/jsx-dev-runtime.esm.js.map +1 -0
  75. package/dist/jsx-runtime.cjs.js +27 -329
  76. package/dist/jsx-runtime.cjs.js.map +1 -0
  77. package/dist/jsx-runtime.esm.js +20 -322
  78. package/dist/jsx-runtime.esm.js.map +1 -0
  79. package/dist/jsx.cjs.js +11 -309
  80. package/dist/jsx.cjs.js.map +1 -0
  81. package/dist/jsx.esm.js +9 -310
  82. package/dist/jsx.esm.js.map +1 -0
  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 +2 -1
  89. package/dist/sygnal.min.js.map +1 -0
  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 +5 -14
  107. package/dist/vike/ClientOnly.cjs.js.map +1 -0
  108. package/dist/vike/ClientOnly.mjs +5 -14
  109. package/dist/vike/ClientOnly.mjs.map +1 -0
  110. package/dist/vike/{+config.js → config/+config.js} +10 -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 +166 -95
  114. package/dist/vike/onRenderClient.cjs.js.map +1 -0
  115. package/dist/vike/onRenderClient.mjs +166 -95
  116. package/dist/vike/onRenderClient.mjs.map +1 -0
  117. package/dist/vike/onRenderHtml.cjs.js +60 -24
  118. package/dist/vike/onRenderHtml.cjs.js.map +1 -0
  119. package/dist/vike/onRenderHtml.mjs +61 -25
  120. package/dist/vike/onRenderHtml.mjs.map +1 -0
  121. package/dist/vite/plugin.cjs.js +926 -65
  122. package/dist/vite/plugin.cjs.js.map +1 -0
  123. package/dist/vite/plugin.mjs +925 -65
  124. package/dist/vite/plugin.mjs.map +1 -0
  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 +313 -0
  130. package/package.json +109 -16
  131. package/src/astro/client.ts +40 -18
  132. package/src/astro/index.d.ts +48 -1
  133. package/src/astro/index.ts +106 -9
  134. package/src/astro/server.ts +11 -3
  135. package/src/collection.ts +6 -90
  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 +13 -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 +76 -0
  162. package/src/cycle/dom/controlledInputModule.ts +50 -0
  163. package/src/cycle/dom/enrichEventStream.ts +29 -45
  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 -57
  167. package/src/cycle/dom/mockDOMSource.ts +83 -9
  168. package/src/cycle/dom/modules.ts +21 -4
  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 +20 -4
  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 +109 -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 +67 -0
  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 +250 -0
  201. package/src/extra/diagnostics/checks/elementCommands.ts +175 -0
  202. package/src/extra/diagnostics/checks/events.ts +83 -0
  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 +202 -0
  206. package/src/extra/diagnostics/checks/inspect.ts +427 -0
  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 +56 -0
  210. package/src/extra/diagnostics/checks/public.d.ts +302 -0
  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 +88 -0
  214. package/src/extra/diagnostics/checks/shared.ts +203 -0
  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 +148 -0
  218. package/src/extra/diagnostics/checks/statics.ts +48 -0
  219. package/src/extra/diagnostics/checks/strict.ts +55 -0
  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 +121 -0
  225. package/src/extra/diagnostics/codes.ts +477 -0
  226. package/src/extra/diagnostics/index.ts +353 -0
  227. package/src/extra/diagnostics/legacy.ts +76 -0
  228. package/src/extra/driverFactories.ts +172 -60
  229. package/src/extra/elementCommands.ts +53 -0
  230. package/src/extra/eventDriver.ts +4 -0
  231. package/src/extra/fetchDriver.ts +519 -0
  232. package/src/extra/flatten.ts +75 -0
  233. package/src/extra/focusWithin.ts +27 -0
  234. package/src/extra/form.ts +268 -0
  235. package/src/extra/formHelpers.ts +139 -0
  236. package/src/extra/head.ts +106 -0
  237. package/src/extra/hmr.ts +2 -3
  238. package/src/extra/owned.ts +24 -0
  239. package/src/extra/pager.ts +50 -0
  240. package/src/extra/persist.ts +133 -0
  241. package/src/extra/pwa.ts +1 -1
  242. package/src/extra/queryCache.ts +107 -0
  243. package/src/extra/reducers.ts +13 -6
  244. package/src/extra/reduxDevtools.ts +92 -0
  245. package/src/extra/replies.ts +54 -0
  246. package/src/extra/router.ts +323 -0
  247. package/src/extra/run.ts +94 -210
  248. package/src/extra/selection.ts +76 -0
  249. package/src/extra/socketDriver.ts +265 -0
  250. package/src/extra/sortable.ts +377 -0
  251. package/src/extra/ssr.ts +427 -160
  252. package/src/extra/standardSchema.ts +27 -0
  253. package/src/extra/testing.ts +3158 -190
  254. package/src/extra/timers.ts +95 -0
  255. package/src/extra/undo.ts +261 -0
  256. package/src/extra/viewTransitions.ts +38 -0
  257. package/src/extra/virtual.ts +513 -0
  258. package/src/extra/widget.ts +201 -0
  259. package/src/extra/xstreamExtras.ts +269 -0
  260. package/src/index.d.ts +3012 -87
  261. package/src/index.ts +32 -10
  262. package/src/jsx-runtime.ts +15 -1
  263. package/src/jsx.ts +2 -1
  264. package/src/lazy.ts +50 -7
  265. package/src/portal.ts +3 -1
  266. package/src/pragma/index.ts +262 -134
  267. package/src/react-peers.d.ts +5 -0
  268. package/src/react.d.ts +43 -0
  269. package/src/react.ts +110 -0
  270. package/src/shared.ts +48 -0
  271. package/src/slot.ts +1 -1
  272. package/src/suspense.ts +3 -1
  273. package/src/switchable.ts +6 -119
  274. package/src/transition.ts +3 -1
  275. package/src/ui/accordion.ts +64 -0
  276. package/src/ui/dialog.ts +129 -0
  277. package/src/ui/disclosure.ts +35 -0
  278. package/src/ui/popover.ts +45 -0
  279. package/src/ui/shared.ts +94 -0
  280. package/src/ui/tabs.ts +82 -0
  281. package/src/ui/toaster.ts +198 -0
  282. package/src/ui/tooltip.ts +70 -0
  283. package/src/ui/zag/combobox.ts +115 -0
  284. package/src/ui/zag/menu.ts +40 -0
  285. package/src/ui/zag/select.ts +54 -0
  286. package/src/ui/zag/shared.ts +43 -0
  287. package/src/ui-combobox.d.ts +20 -0
  288. package/src/ui-combobox.ts +6 -0
  289. package/src/ui-menu.d.ts +30 -0
  290. package/src/ui-menu.ts +6 -0
  291. package/src/ui-select.d.ts +17 -0
  292. package/src/ui-select.ts +6 -0
  293. package/src/ui-zag-types.d.ts +42 -0
  294. package/src/ui.d.ts +208 -0
  295. package/src/ui.ts +15 -0
  296. package/src/vike/+config.ts +9 -1
  297. package/src/vike/ClientOnly.ts +1 -1
  298. package/src/vike/onRenderClient.ts +144 -96
  299. package/src/vike/onRenderHtml.ts +69 -26
  300. package/src/vike/types.ts +27 -4
  301. package/src/vite/globalthis-shim.ts +18 -0
  302. package/src/vite/globalthis.ts +56 -0
  303. package/src/vite/plugin.d.ts +114 -2
  304. package/src/vite/plugin.ts +920 -56
  305. package/src/zag.d.ts +64 -0
  306. package/src/zag.ts +238 -0
  307. package/dist/astro/astro/client.d.ts +0 -5
  308. package/dist/astro/astro/index.d.ts +0 -16
  309. package/dist/astro/astro/server.d.ts +0 -12
  310. package/dist/astro/client.d.ts +0 -5
  311. package/dist/astro/client.esm.js +0 -4665
  312. package/dist/astro/collection.d.ts +0 -12
  313. package/dist/astro/component.d.ts +0 -22
  314. package/dist/astro/cycle/dom/BodyDOMSource.d.ts +0 -10
  315. package/dist/astro/cycle/dom/DOMSource.d.ts +0 -11
  316. package/dist/astro/cycle/dom/DocumentDOMSource.d.ts +0 -12
  317. package/dist/astro/cycle/dom/ElementFinder.d.ts +0 -8
  318. package/dist/astro/cycle/dom/EventDelegator.d.ts +0 -34
  319. package/dist/astro/cycle/dom/IsolateModule.d.ts +0 -23
  320. package/dist/astro/cycle/dom/MainDOMSource.d.ts +0 -32
  321. package/dist/astro/cycle/dom/PriorityQueue.d.ts +0 -7
  322. package/dist/astro/cycle/dom/ScopeChecker.d.ts +0 -9
  323. package/dist/astro/cycle/dom/SymbolTree.d.ts +0 -9
  324. package/dist/astro/cycle/dom/VNodeWrapper.d.ts +0 -8
  325. package/dist/astro/cycle/dom/enrichEventStream.d.ts +0 -24
  326. package/dist/astro/cycle/dom/fromEvent.d.ts +0 -6
  327. package/dist/astro/cycle/dom/index.d.ts +0 -8
  328. package/dist/astro/cycle/dom/isolate.d.ts +0 -9
  329. package/dist/astro/cycle/dom/makeDOMDriver.d.ts +0 -11
  330. package/dist/astro/cycle/dom/mockDOMSource.d.ts +0 -17
  331. package/dist/astro/cycle/dom/modules.d.ts +0 -5
  332. package/dist/astro/cycle/dom/snabbdom.d.ts +0 -22
  333. package/dist/astro/cycle/dom/styleModule.d.ts +0 -13
  334. package/dist/astro/cycle/dom/thunk.d.ts +0 -11
  335. package/dist/astro/cycle/dom/utils.d.ts +0 -8
  336. package/dist/astro/cycle/isolate/index.d.ts +0 -42
  337. package/dist/astro/cycle/run/adapt.d.ts +0 -6
  338. package/dist/astro/cycle/run/index.d.ts +0 -36
  339. package/dist/astro/cycle/run/internals.d.ts +0 -8
  340. package/dist/astro/cycle/run/types.d.ts +0 -49
  341. package/dist/astro/cycle/state/Collection.d.ts +0 -29
  342. package/dist/astro/cycle/state/StateSource.d.ts +0 -20
  343. package/dist/astro/cycle/state/index.d.ts +0 -5
  344. package/dist/astro/cycle/state/pickCombine.d.ts +0 -3
  345. package/dist/astro/cycle/state/pickMerge.d.ts +0 -3
  346. package/dist/astro/cycle/state/types.d.ts +0 -18
  347. package/dist/astro/cycle/state/withState.d.ts +0 -17
  348. package/dist/astro/extra/classes.d.ts +0 -7
  349. package/dist/astro/extra/devtools.d.ts +0 -78
  350. package/dist/astro/extra/dragDriver.d.ts +0 -20
  351. package/dist/astro/extra/driverFactories.d.ts +0 -12
  352. package/dist/astro/extra/eventDriver.d.ts +0 -9
  353. package/dist/astro/extra/exactState.d.ts +0 -1
  354. package/dist/astro/extra/hmr.d.ts +0 -17
  355. package/dist/astro/extra/logDriver.d.ts +0 -2
  356. package/dist/astro/extra/processDrag.d.ts +0 -19
  357. package/dist/astro/extra/processForm.d.ts +0 -15
  358. package/dist/astro/extra/run.d.ts +0 -13
  359. package/dist/astro/extra/xstreamCompat.d.ts +0 -5
  360. package/dist/astro/index.d.ts +0 -19
  361. package/dist/astro/index.esm.js +0 -27
  362. package/dist/astro/jsx-dev-runtime.d.ts +0 -1
  363. package/dist/astro/jsx-runtime.d.ts +0 -4
  364. package/dist/astro/jsx.d.ts +0 -2
  365. package/dist/astro/pragma/fn.d.ts +0 -7
  366. package/dist/astro/pragma/index.d.ts +0 -7
  367. package/dist/astro/pragma/is.d.ts +0 -10
  368. package/dist/astro/server.d.ts +0 -12
  369. package/dist/astro/server.esm.js +0 -25
  370. package/dist/astro/switchable.d.ts +0 -7
  371. package/dist/collection.d.ts +0 -12
  372. package/dist/component.d.ts +0 -22
  373. package/dist/cycle/dom/BodyDOMSource.d.ts +0 -10
  374. package/dist/cycle/dom/DOMSource.d.ts +0 -11
  375. package/dist/cycle/dom/DocumentDOMSource.d.ts +0 -12
  376. package/dist/cycle/dom/ElementFinder.d.ts +0 -8
  377. package/dist/cycle/dom/EventDelegator.d.ts +0 -34
  378. package/dist/cycle/dom/IsolateModule.d.ts +0 -23
  379. package/dist/cycle/dom/MainDOMSource.d.ts +0 -32
  380. package/dist/cycle/dom/PriorityQueue.d.ts +0 -7
  381. package/dist/cycle/dom/ScopeChecker.d.ts +0 -9
  382. package/dist/cycle/dom/SymbolTree.d.ts +0 -9
  383. package/dist/cycle/dom/VNodeWrapper.d.ts +0 -8
  384. package/dist/cycle/dom/enrichEventStream.d.ts +0 -24
  385. package/dist/cycle/dom/fromEvent.d.ts +0 -6
  386. package/dist/cycle/dom/index.d.ts +0 -8
  387. package/dist/cycle/dom/isolate.d.ts +0 -9
  388. package/dist/cycle/dom/makeDOMDriver.d.ts +0 -11
  389. package/dist/cycle/dom/mockDOMSource.d.ts +0 -17
  390. package/dist/cycle/dom/modules.d.ts +0 -5
  391. package/dist/cycle/dom/snabbdom.d.ts +0 -22
  392. package/dist/cycle/dom/styleModule.d.ts +0 -13
  393. package/dist/cycle/dom/thunk.d.ts +0 -11
  394. package/dist/cycle/dom/utils.d.ts +0 -8
  395. package/dist/cycle/isolate/index.d.ts +0 -42
  396. package/dist/cycle/run/adapt.d.ts +0 -6
  397. package/dist/cycle/run/index.d.ts +0 -36
  398. package/dist/cycle/run/internals.d.ts +0 -8
  399. package/dist/cycle/run/types.d.ts +0 -49
  400. package/dist/cycle/state/Collection.d.ts +0 -29
  401. package/dist/cycle/state/StateSource.d.ts +0 -20
  402. package/dist/cycle/state/index.d.ts +0 -5
  403. package/dist/cycle/state/pickCombine.d.ts +0 -3
  404. package/dist/cycle/state/pickMerge.d.ts +0 -3
  405. package/dist/cycle/state/types.d.ts +0 -18
  406. package/dist/cycle/state/withState.d.ts +0 -17
  407. package/dist/extra/classes.d.ts +0 -7
  408. package/dist/extra/devtools.d.ts +0 -78
  409. package/dist/extra/dragDriver.d.ts +0 -20
  410. package/dist/extra/driverFactories.d.ts +0 -12
  411. package/dist/extra/eventDriver.d.ts +0 -9
  412. package/dist/extra/exactState.d.ts +0 -1
  413. package/dist/extra/hmr.d.ts +0 -17
  414. package/dist/extra/logDriver.d.ts +0 -2
  415. package/dist/extra/processDrag.d.ts +0 -19
  416. package/dist/extra/processForm.d.ts +0 -15
  417. package/dist/extra/run.d.ts +0 -13
  418. package/dist/extra/xstreamCompat.d.ts +0 -5
  419. package/dist/jsx-dev-runtime.d.ts +0 -1
  420. package/dist/jsx-dev-runtime.js +0 -224
  421. package/dist/jsx-runtime.d.ts +0 -4
  422. package/dist/jsx-runtime.js +0 -224
  423. package/dist/jsx.d.ts +0 -2
  424. package/dist/pragma/fn.d.ts +0 -7
  425. package/dist/pragma/index.d.ts +0 -7
  426. package/dist/pragma/is.d.ts +0 -10
  427. package/dist/switchable.d.ts +0 -7
  428. package/dist/vike/+config.cjs.js +0 -65
  429. package/src/component.ts +0 -2256
  430. package/src/cycle/isolate/index.ts +0 -196
  431. package/src/cycle/run/index.ts +0 -151
  432. package/src/cycle/run/internals.ts +0 -143
  433. package/src/cycle/state/Collection.ts +0 -174
  434. package/src/cycle/state/index.ts +0 -5
  435. package/src/cycle/state/pickCombine.ts +0 -167
  436. package/src/cycle/state/pickMerge.ts +0 -122
  437. package/src/cycle/state/withState.ts +0 -47
  438. package/src/pragma/fn.ts +0 -55
@@ -0,0 +1,302 @@
1
+ /**
2
+ * Types for the 'sygnal/diagnostics' entry (runtime consistency checks).
3
+ *
4
+ * import 'sygnal/diagnostics' // registers all checks (side effect)
5
+ *
6
+ * Checks only run while diagnostics are on: run(App, drivers, { diagnostics: 'warn' }),
7
+ * or globalThis.__SYGNAL_DEV__ (set by the Vite plugin in dev).
8
+ */
9
+
10
+ export type DiagnosticSeverity = 'error' | 'warn' | 'info'
11
+
12
+ export interface DiagnosticCodeInfo {
13
+ code: string
14
+ severity: DiagnosticSeverity
15
+ title: string
16
+ /** anchor on https://sygnal.js.org/reference/errors, e.g. 'syg101' */
17
+ docsSlug: string
18
+ }
19
+
20
+ /** A runtime check, as registered with the diagnostics core. */
21
+ export interface DiagnosticCheck {
22
+ id: string
23
+ onIntent?: (component: any, actionNames: string[], selectorsUsed: string[] | undefined) => void
24
+ onModel?: (component: any, modelMap: Record<string, string[]>) => void
25
+ onRender?: (component: any, rootVnode: any) => void
26
+ onReducer?: (component: any, action: string, prevState: any, nextState: any, sinkName: string) => void
27
+ onDispose?: (component: any) => void
28
+ onSelector?: (domSource: any, selector: string) => void
29
+ onBusEmit?: (type: string, emitterName?: string) => void
30
+ onBusSelect?: (type: string | string[] | undefined) => void
31
+ }
32
+
33
+ /**
34
+ * Strict mode (canonical forms, SYG5xx): turn the runtime strict checks on
35
+ * (true), off (false), or back to the default (undefined → on only when
36
+ * globalThis.__SYGNAL_STRICT__ === true). Off by default. Diagnostics must
37
+ * also be on. Runtime rules: SYG501 (positional view args), SYG504 ('ACTION | SINK'
38
+ * keys); `sygnal-check --strict` checks SYG501-508 statically (SYG502 is retired in 6.0).
39
+ * In tests: renderComponent(C, { strict: true }).
40
+ */
41
+ export function configureStrict(on?: boolean): void
42
+
43
+ /** Whether the runtime strict checks are on. */
44
+ export function isStrictEnabled(): boolean
45
+
46
+ /** Every runtime check in this entry. */
47
+ export const checks: DiagnosticCheck[]
48
+
49
+ /** Re-register all checks and the RxJS hints (done automatically on import). Returns an uninstall function. */
50
+ export function installChecks(): () => void
51
+
52
+ export interface ChecksOptions {
53
+ /** delay after a render before the DOM checks (SYG103/104) run; default 50 ms */
54
+ settleMs?: number
55
+ /** render-idle time before SYG103 escalates to warn; default 2000 ms */
56
+ idleMs?: number
57
+ /** renders required before SYG103 escalates to warn; default 3 */
58
+ minRenders?: number
59
+ }
60
+
61
+ /** Tune the timing of the DOM checks (mostly for tests). */
62
+ export function configureChecks(options?: ChecksOptions): void
63
+
64
+ /** Forget what the checks have seen and reported (dedupe state, registries). For tests. */
65
+ export function resetChecks(): void
66
+
67
+ export interface EventBusSummary {
68
+ selected: string[]
69
+ emitted: string[]
70
+ selectedNeverEmitted: string[]
71
+ emittedNeverSelected: string[]
72
+ }
73
+
74
+ /**
75
+ * Report SYG105 (info) for every EVENTS type selected but never emitted so far,
76
+ * and return the EVENTS bus registry.
77
+ */
78
+ export function checkEventBus(): EventBusSummary
79
+
80
+ /** RxJS operator name -> xstream equivalent (used by SYG301). */
81
+ export const RXJS_HINTS: Record<string, string>
82
+
83
+ /** Metadata for every registered diagnostic code. */
84
+ export function listCodes(): DiagnosticCodeInfo[]
85
+
86
+ /** Metadata for one diagnostic code, or undefined if unknown. */
87
+ export function getCodeInfo(code: string): DiagnosticCodeInfo | undefined
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // inspect (PLAN-1 workstream 2B): a machine-readable app graph. The same shape
91
+ // is produced at runtime (inspect(), getDevTools().inspect(), renderComponent's
92
+ // t.inspect()) and statically (`sygnal-check --graph --json`); JSON Schema:
93
+ // sygnal-check/schema/inspect.schema.json. Fields one side cannot know are
94
+ // null (or omitted).
95
+ // ---------------------------------------------------------------------------
96
+
97
+ /** How an action is dispatched. */
98
+ export type InspectActionTrigger = 'intent' | 'next' | 'reply' | 'builtin' | 'unknown'
99
+
100
+ export interface InspectAction {
101
+ name: string
102
+ /**
103
+ * 'intent': returned by the component's intent. 'builtin': BOOTSTRAP,
104
+ * INITIALIZE, DISPOSE or READY. 'reply': named as a reply action by a request
105
+ * (`ok: 'NAME'` / `error: 'NAME'`) or a `connections` entry (statically: a
106
+ * string literal; at runtime: a request the instance was seen sending).
107
+ * 'next': dispatched with next() (statically: a next('NAME') literal; at
108
+ * runtime: a model-only action whose STATE reducer was seen running).
109
+ * 'unknown': none of these is known.
110
+ */
111
+ trigger: InspectActionTrigger
112
+ /** sinks of the model entry (STATE, EVENTS, EFFECT, PARENT, custom drivers); [] without a model entry */
113
+ sinks: string[]
114
+ }
115
+
116
+ export interface InspectChild {
117
+ name: string
118
+ via: 'tag' | 'collection' | 'switchable' | 'slot'
119
+ /** Collection: the `from` state field, when known */
120
+ from?: string | null
121
+ /** runtime: number of live instances behind this entry (e.g. Collection items) */
122
+ count?: number
123
+ }
124
+
125
+ export interface InspectSelector {
126
+ /** CSS selector passed to DOM.select() (chained selects joined with a space) */
127
+ selector: string
128
+ /** event types listened to; null when unknown (runtime, real DOM) */
129
+ events: string[] | null
130
+ /**
131
+ * whether it matches an element the component itself renders; null when unknown.
132
+ * static: the class/id is in the view source. renderComponent: an element of the latest
133
+ * render matches (a conditionally rendered element that is hidden right now gives false).
134
+ * real DOM: true once a DOM check saw it match, false after SYG103/SYG104, else null.
135
+ */
136
+ matched: boolean | null
137
+ /** the child component whose (isolated) elements it matches instead, if any */
138
+ isolationHit: string | null
139
+ /** PLAN-4 CT-1: the control this selector is (its key), when it is `[data-control="<Key>"]` */
140
+ control?: string
141
+ }
142
+
143
+ /** PLAN-4 CT-1: a control (controls()) a component renders */
144
+ export interface InspectControl {
145
+ /** the control's key (rendered as data-control="<name>") */
146
+ name: string
147
+ /** the intrinsic tag of a tag spec; null for a spec object */
148
+ element: string | null
149
+ /** a spec object's kind (e.g. 'widget') */
150
+ kind?: string
151
+ /** whether the component's intent listens to it; null when unknown */
152
+ listened: boolean | null
153
+ }
154
+
155
+ export interface InspectDiagnostic {
156
+ code: string
157
+ severity: DiagnosticSeverity
158
+ component?: string
159
+ message: string
160
+ fix?: string
161
+ docsUrl?: string
162
+ data?: any
163
+ /** static only */
164
+ file?: string
165
+ line?: number
166
+ column?: number
167
+ }
168
+
169
+ export interface InspectComponent {
170
+ name: string
171
+ /** runtime: instance number (as a string); static: 'file:line' of the definition */
172
+ id: string
173
+ /** runtime: the parent instance's id; static: null (see the parents' `children`) */
174
+ parentId: string | null
175
+ /** static only: source file, relative to the working directory */
176
+ file?: string
177
+ /**
178
+ * runtime: how the instance was created; static: 'root' when no scanned
179
+ * component renders it, else how it is first rendered
180
+ */
181
+ kind: 'root' | 'child' | 'collection-item' | 'switchable'
182
+ actions: InspectAction[]
183
+ /** state keys (runtime: current state; static: initialState) */
184
+ stateKeys: string[]
185
+ /** calculated field names */
186
+ calculated: string[]
187
+ /** context fields this component provides (Component.context) */
188
+ contextProvides: string[]
189
+ /** context fields its view reads (static only; null at runtime) */
190
+ contextConsumes?: string[] | null
191
+ /** EVENTS types this component emits */
192
+ eventsEmitted: string[]
193
+ /** EVENTS types this component selects ('*' = EVENTS.select() without a type) */
194
+ eventsSelected: string[]
195
+ children: InspectChild[]
196
+ selectors: InspectSelector[]
197
+ /** PLAN-4 CT-1: the controls it renders (runtime: seen in its renders); omitted when none */
198
+ controls?: InspectControl[]
199
+ /** static only, PLAN-4 GS-2 (G-224): the element commands (ELEMENT sink) its model sends; omitted when none */
200
+ commands?: InspectCommand[]
201
+ /** static only, PLAN-4 GS-7 (G-224): the literal timer specs of its `timers` static; omitted when none */
202
+ timers?: InspectTimer[]
203
+ diagnostics: InspectDiagnostic[]
204
+ /** runtime, PLAN-3 5-3: the instance's `resources` and their state */
205
+ resources?: InspectResource[]
206
+ }
207
+
208
+ /** PLAN-4 GS-2: an element command a model entry sends (static inspect, sygnal-check --graph) */
209
+ export interface InspectCommand {
210
+ /** the model entry that sends it */
211
+ action: string
212
+ /** the command's method (its first key) */
213
+ method: string
214
+ /** the control's key or the selector; null when not static */
215
+ target: string | null
216
+ /** the control it targets (its key) */
217
+ control?: string
218
+ /** intent actions listening on the target for a native event the command causes (close, toggle...) */
219
+ triggers?: string[]
220
+ }
221
+
222
+ /** PLAN-4 GS-7: a literal timer spec of a `timers` static (static inspect, sygnal-check --graph) */
223
+ export interface InspectTimer {
224
+ name: string
225
+ every?: number | null
226
+ after?: number | null
227
+ /** the action a frame timer dispatches */
228
+ frame?: string | null
229
+ action?: string | null
230
+ background?: true
231
+ }
232
+
233
+ /** PLAN-3 5-3: a resource of a component instance (runtime inspect()) */
234
+ export interface InspectResource {
235
+ name: string
236
+ status: 'idle' | 'loading' | 'success' | 'error'
237
+ refreshing: boolean
238
+ /** `data` is set (a success, or kept through a refetch) */
239
+ hasData: boolean
240
+ /** the error message while 'error' */
241
+ error?: string
242
+ }
243
+
244
+ /** PLAN-3 5-3: a makeFetchDriver cache entry (runtime inspect(), t.cache) */
245
+ export interface InspectCacheEntry {
246
+ key: string
247
+ age?: number
248
+ stale: boolean
249
+ subscribers: number
250
+ data: any
251
+ }
252
+
253
+ export interface InspectGraph {
254
+ version: 1
255
+ /** which implementation produced the graph */
256
+ source?: 'runtime' | 'static'
257
+ components: InspectComponent[]
258
+ /** EVENTS bus: type -> names of the components that emit / select it */
259
+ events: Record<string, { emitters: string[]; selectors: string[] }>
260
+ /** diagnostics not tied to a listed component */
261
+ diagnostics: InspectDiagnostic[]
262
+ /** runtime, PLAN-3 5-3: makeFetchDriver cache entries, by sink name (empty when no cache) */
263
+ cache?: Record<string, InspectCacheEntry[]>
264
+ /** runtime, PLAN-4 2-C (GS-10): with `inspect({ actions })`, the most recent actions, oldest first */
265
+ recentActions?: InspectRecentAction[]
266
+ }
267
+
268
+ /** PLAN-4 2-C (GS-10): one recent action (inspect({ actions })) */
269
+ export interface InspectRecentAction {
270
+ type: string
271
+ /** the action's data, when it is JSON-safe and small (a DOM event is left out) */
272
+ data?: any
273
+ /** the component's name */
274
+ component: string
275
+ /** the instance's id (InspectComponent.id) */
276
+ instance: string
277
+ /** the sinks that produced a value for it (not ABORT) */
278
+ sinks: string[]
279
+ cause: 'intent' | 'next' | 'reply' | 'built-in' | 'simulateAction' | 'behavior'
280
+ /** ms since the dev entry started recording (or the last resetChecks()) */
281
+ at: number
282
+ }
283
+
284
+ export interface InspectOptions {
285
+ /** only these component instances (ids as in InspectComponent.id) */
286
+ ids?: Array<string | number>
287
+ /** selector details by component id (renderComponent passes its mock-DOM view) */
288
+ selectors?: Record<string, InspectSelector[]>
289
+ /** diagnostics to attach (default: the devtools' collected diagnostics, when available) */
290
+ diagnostics?: Array<{ code: string; severity: DiagnosticSeverity; component?: string; message: string; [key: string]: any }>
291
+ /** PLAN-4 2-C: add `recentActions`: true for every kept one (the last 200), a number for the last n */
292
+ actions?: boolean | number
293
+ }
294
+
295
+ /**
296
+ * The app graph of the live component instances, built from what the
297
+ * diagnostics hooks have seen (so diagnostics must be on while the app runs).
298
+ * Disposed components are pruned. Also available as `getDevTools().inspect()`
299
+ * / `window.__SYGNAL_DEVTOOLS__.inspect()` once the devtools bridge exists
300
+ * (run() in a browser), and as renderComponent's `t.inspect()`.
301
+ */
302
+ export function inspect(options?: InspectOptions): InspectGraph
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Reply actions (PLAN-3 §1.1, workstream 1-D).
3
+ *
4
+ * SYG112 — a request names a reply action the sending component has no
5
+ * model entry for (error: the reply is dropped). Dev-entry code
6
+ * (DEV_CODE_SEVERITY).
7
+ * SYG508 — strict: the component reads the replies to its own request with
8
+ * X.select('cat') / X.errors('cat') where reply actions would do.
9
+ *
10
+ * Mechanism:
11
+ * onSink (checks/next.ts: checkRequest) every value an instance sends to a
12
+ * reply-capable sink (`__sygnalReplies === true`: makeFetchDriver,
13
+ * driverFromAsync, the socket driver) is checked as it is sent.
14
+ * The names it sees feed inspect()'s 'reply' trigger.
15
+ * sources (strict only) wraps those sources for the intent, recording the
16
+ * select()/errors() categories the instance reads.
17
+ * A request's `category` is compared for SYG508 (driverFromAsync's custom
18
+ * `selector` property is not known at run time; sygnal-check covers it).
19
+ * Reported once per component name and action / category.
20
+ *
21
+ * `{ connections }` values (the `connections` static, which the core sends to
22
+ * the same sink, or one a model entry sends) are checked the same way:
23
+ * each connection's message / open / close / error and its SSE `events` names.
24
+ */
25
+ import type {DiagnosticCheck} from '../index'
26
+ import {STRICT_CODE_SEVERITY} from '../codes'
27
+ import {devReport, reportSafely, once, nameOf, suggest, replySeen} from './shared'
28
+ import {isStrictEnabled} from './strict'
29
+
30
+ const REPLY_KEYS = ['ok', 'error']
31
+ // PLAN-3 5-4b: on the router's sink, `{ route }` (the route static) and `{ block }` name reply actions
32
+ const ROUTER_KEYS = ['route', 'block']
33
+ const CONNECTION_KEYS = ['message', 'open', 'close', 'error']
34
+
35
+ /** [action, key, connection name?] for every reply action name a sink value names */
36
+ function replyNames(req: any, router?: boolean): Array<[string, string, string?]> {
37
+ const out: Array<[string, string, string?]> = []
38
+ for (const key of router ? REPLY_KEYS.concat(ROUTER_KEYS) : REPLY_KEYS) if (typeof req[key] === 'string') out.push([req[key], key])
39
+ const conns = req.connections
40
+ if (conns && typeof conns === 'object') {
41
+ for (const name of Object.keys(conns)) {
42
+ const spec = conns[name]
43
+ if (!spec || typeof spec !== 'object') continue
44
+ for (const key of CONNECTION_KEYS) if (typeof spec[key] === 'string') out.push([spec[key], key, name])
45
+ const events = spec.events
46
+ if (events && typeof events === 'object') {
47
+ for (const ev of Object.keys(events)) if (typeof events[ev] === 'string') out.push([events[ev], `events.${ev}`, name])
48
+ }
49
+ }
50
+ }
51
+ return out
52
+ }
53
+
54
+ /** instance → 'SINK\0category' → the select/errors call that read it */
55
+ const selected = new WeakMap<object, Map<string, string>>()
56
+
57
+
58
+ function readingSource(component: any, sink: string, source: any) {
59
+ const wrapped = Object.create(source)
60
+ for (const method of ['select', 'errors']) {
61
+ if (typeof source[method] !== 'function') continue
62
+ wrapped[method] = (category?: any, ...rest: any[]) => {
63
+ if (typeof category === 'string') {
64
+ let reads = selected.get(component)
65
+ if (!reads) selected.set(component, reads = new Map())
66
+ reads.set(`${sink}\0${category}`, `${sink}.${method}('${category}')`)
67
+ }
68
+ return source[method](category, ...rest)
69
+ }
70
+ }
71
+ return wrapped
72
+ }
73
+
74
+ export function checkRequest(component: any, sink: string, req: any, modelActions: string[]) {
75
+ if (!req || typeof req !== 'object') return
76
+ const name = nameOf(component)
77
+ let replies = false
78
+ for (const [action, key, connection] of replyNames(req, !!component?.sources?.[sink]?.__sygnalRouter)) {
79
+ replies = true
80
+ let seen = replySeen.get(component)
81
+ if (!seen) replySeen.set(component, seen = new Set())
82
+ seen.add(action)
83
+ if (modelActions.includes(action) || !once(`SYG112:${name}:${action}`)) continue
84
+ const near = suggest(action, modelActions.filter(a => !a.startsWith('__')))
85
+ devReport('SYG112', {
86
+ component,
87
+ message: (connection
88
+ ? `${sink} connection '${connection}' names '${action}' as its ${key} reply action, but ${name} has no model entry '${action}', so those events are dropped`
89
+ : `A ${sink} request names '${action}' as its ${key} reply action, but ${name} has no model entry '${action}', so the reply is dropped`) +
90
+ (near ? ` (did you mean '${near}'?)` : ''),
91
+ fix: near
92
+ ? `Use the existing entry: ${key.startsWith('events.') ? `events: { '${key.slice(7)}': '${near}' }` : `${key}: '${near}'`}`
93
+ : `Add '${action}' to ${name}.model, e.g. ${action}: (state, data) => ({ ...state, ... }), or fix the name`,
94
+ data: {action, key, sink, ...(connection ? {connection} : {}), ...(near ? {suggestion: near} : {}), modelActions},
95
+ })
96
+ }
97
+
98
+ // SYG508 (strict): a request without reply actions whose replies this instance reads back with select()/errors()
99
+ if (replies || 'abort' in req || typeof req.category !== 'string' || !isStrictEnabled()) return
100
+ const read = selected.get(component)?.get(`${sink}\0${req.category}`)
101
+ if (!read || !once(`SYG508:${name}:${sink}:${req.category}`)) return
102
+ // (inside a sink stream: reportSafely, so 'error' mode can't break the stream)
103
+ reportSafely('SYG508', {
104
+ severity: STRICT_CODE_SEVERITY.SYG508,
105
+ component,
106
+ message: `${name} sends a ${sink} request with category: '${req.category}' and reads the reply back with ${read}`,
107
+ fix: `Use reply actions instead: name them in the request, ${sink}: (state) => ({ url, ok: 'LOADED', error: 'FAILED' }), ` +
108
+ `handle LOADED (the parsed body) and FAILED ({ error, status, body, request }) in the model, and remove ${read} from the intent`,
109
+ data: {sink, category: req.category, read},
110
+ })
111
+ }
112
+
113
+ export const repliesCheck: DiagnosticCheck = {
114
+ id: 'replies',
115
+
116
+ sources(component, sources) {
117
+ if (!isStrictEnabled() || typeof Proxy != 'function') return
118
+ const cache = new Map<string, any>()
119
+ return new Proxy(sources, {
120
+ get(t: any, k: any) {
121
+ const v = t[k]
122
+ if (typeof k != 'string' || !v || v.__sygnalReplies !== true) return v
123
+ if (!cache.has(k)) cache.set(k, readingSource(component, k, v))
124
+ return cache.get(k)
125
+ },
126
+ })
127
+ },
128
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Router and declaration statics (PLAN-3 5-4b). Dev-entry-only codes (DEV_CODE_SEVERITY):
3
+ *
4
+ * SYG130 — href() names no route, or leaves out a param its pattern needs (the link is broken).
5
+ * (A `{ to }` command with the same problem is SYG620, reported by the router itself
6
+ * in production too, and not navigated.)
7
+ * SYG131 — href() or a `{ to, params }` command passes params the route's pattern doesn't use.
8
+ * SYG132 — G-167: a component declares a static the core sends to a driver (`route`,
9
+ * `resources`, `connections`, `head`) but never sends it: it has no model (the core
10
+ * wires statics in its model setup), or it is a root without initialState (a static is
11
+ * computed from the state stream, which a root without state never emits).
12
+ * SYG133 — the SPA router (makeRouter().driver without `navigate`) runs inside a Vike app,
13
+ * where Vike owns links and history.
14
+ *
15
+ * Mechanism: the router's href() calls `__SYGNAL_DIAGNOSTICS__.routerHref(routes, name, params)`
16
+ * when it exists (installRouterHooks() sets it); onModel looks at the component's sources for
17
+ * `__sygnalStatic` / `__sygnalRouter` markers.
18
+ */
19
+ import type {DiagnosticCheck} from '../index'
20
+ import {bridge, devReport, once, nameOf, suggest} from './shared'
21
+
22
+ const PARAM = /:(\w+)/g
23
+ const paramsOf = (pat: string) => (pat.match(PARAM) || []).map(p => p.slice(1))
24
+
25
+ function checkHref(routes: Record<string, string>, name: string, params: any) {
26
+ const names = Object.keys(routes).filter(k => routes[k] != '*')
27
+ const pat = routes[name]
28
+ if (pat == null || pat == '*') {
29
+ if (!once(`SYG130:${name}`)) return
30
+ const near = suggest(String(name), names)
31
+ devReport('SYG130', {
32
+ message: `href('${name}') names no route, so the link points to '/'` + (near ? ` (did you mean '${near}'?)` : ''),
33
+ fix: `Use one of the route names: ${names.join(', ')}`,
34
+ data: {name, routes: names, ...(near ? {suggestion: near} : {})},
35
+ })
36
+ return
37
+ }
38
+ const wanted = paramsOf(pat)
39
+ const given = params && typeof params == 'object' ? params : {}
40
+ const missing = wanted.filter(k => given[k] == null)
41
+ const extra = Object.keys(given).filter(k => !wanted.includes(k))
42
+ if (missing.length && once(`SYG130:${name}:${missing}`)) {
43
+ devReport('SYG130', {
44
+ message: `href('${name}') leaves out ${missing.map(k => `'${k}'`).join(', ')} (${pat}), so that segment is empty`,
45
+ fix: `href('${name}', { ${wanted.join(', ')} })`,
46
+ data: {name, pattern: pat, missing},
47
+ })
48
+ }
49
+ if (extra.length && once(`SYG131:${name}:${extra}`)) {
50
+ devReport('SYG131', {
51
+ message: `Route '${name}' (${pat}) has no param ${extra.map(k => `'${k}'`).join(', ')}; it is ignored`,
52
+ fix: wanted.length ? `Pass only ${wanted.join(', ')}; put other values in the query: href('${name}', params, { ${extra[0]} })` : `Put it in the query: href('${name}', {}, { ${extra[0]} })`,
53
+ data: {name, pattern: pat, extra},
54
+ })
55
+ }
56
+ }
57
+
58
+ /** install the hook the router's href() calls (removed by the returned function) */
59
+ export function installRouterHooks(): () => void {
60
+ const core = bridge()
61
+ if (!core) return () => {}
62
+ core.routerHref = checkHref
63
+ return () => { if (core.routerHref === checkHref) core.routerHref = undefined }
64
+ }
65
+
66
+ export const routerCheck: DiagnosticCheck = {
67
+ id: 'router',
68
+
69
+ onModel(component) {
70
+ const sources = component?.sources
71
+ if (!sources || typeof sources != 'object') return
72
+ const name = nameOf(component)
73
+ for (const n of component.sourceNames || Object.keys(sources)) {
74
+ const src = sources[n]
75
+ const k = src?.__sygnalStatic
76
+ if (typeof k == 'string' && component.view?.[k] != null) {
77
+ // statics are computed from state (G-167: with or without a model): a root whose state
78
+ // never emits (a model but no initialState) never sends one
79
+ if (!component.isSubComponent && component.initialState === undefined && once(`SYG132:${name}:${k}`)) {
80
+ devReport('SYG132', {
81
+ component,
82
+ message: `${name} declares ${name}.${k}, but a root without initialState has no state, so ${k} is never sent to ${n}`,
83
+ fix: `Add ${name}.initialState (e.g. { }${k == 'route' ? ', or { route: router.current() }' : ''})`,
84
+ data: {static: k, source: n, reason: 'state'},
85
+ })
86
+ }
87
+ }
88
+ const opts = src?.__sygnalRouter
89
+ const g: any = globalThis
90
+ if (opts && typeof opts == 'object' && !opts.navigate && g.document?.getElementById?.('vike_pageContext') && once('SYG133')) {
91
+ devReport('SYG133', {
92
+ component,
93
+ message: `The SPA router (${n}) runs inside a Vike app: Vike owns links and history, so both would handle a click`,
94
+ fix: "Pass Vike's navigate: makeRouter({ routes, navigate }) with import { navigate } from 'vike/client/router', or use Vike's routing",
95
+ data: {source: n},
96
+ })
97
+ }
98
+ }
99
+ },
100
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * SYG301 — an RxJS operator was called on an xstream stream (error).
3
+ *
4
+ * Without help this fails with a bare "x.switchMap is not a function" inside
5
+ * the intent function. Mechanism: when 'sygnal/diagnostics' is loaded, every
6
+ * RxJS operator name below that xstream's Stream does NOT already have is
7
+ * defined on Stream.prototype (non-enumerable) as a method that throws an
8
+ * enriched TypeError: same "stream.<op> is not a function" shape, plus the
9
+ * xstream equivalent and the SYG301 docs link. The error is also reported
10
+ * (collected / printed per the diagnostics mode; in 'error' mode report()
11
+ * throws the DiagnosticError itself). It works anywhere a stream is used
12
+ * (intent, peers, drivers), with no hook in the core.
13
+ *
14
+ * Caveat: `typeof stream.pipe === 'function'` is true while this entry is
15
+ * loaded (dev only).
16
+ */
17
+ import {report} from './shared'
18
+ import {docsUrlFor} from '../codes'
19
+
20
+ /** RxJS operator -> xstream equivalent. */
21
+ export const RXJS_HINTS: Record<string, string> = {
22
+ pipe: `chain xstream operators directly (.map(...).filter(...)), or use .compose(operator) for extra operators`,
23
+ switchMap: `.map(x => inner$).flatten()`,
24
+ mergeMap: `.map(x => inner$).compose(flattenConcurrently) (import { flattenConcurrently } from 'sygnal')`,
25
+ flatMap: `.map(x => inner$).compose(flattenConcurrently) (import { flattenConcurrently } from 'sygnal')`,
26
+ concatMap: `.map(x => inner$).compose(flattenSequentially) (import { flattenSequentially } from 'sygnal')`,
27
+ exhaustMap: `.map(x => inner$).flatten() (xstream has no exhaustMap; ignore new values while busy with .filter())`,
28
+ switchAll: `.flatten()`,
29
+ mergeAll: `.compose(flattenConcurrently) (import { flattenConcurrently } from 'sygnal')`,
30
+ concatAll: `.compose(flattenSequentially) (import { flattenSequentially } from 'sygnal')`,
31
+ debounceTime: `.compose(debounce(ms)) (import { debounce } from 'sygnal')`,
32
+ debounce: `.compose(debounce(ms)) (import { debounce } from 'sygnal')`,
33
+ throttleTime: `.compose(throttle(ms)) (import { throttle } from 'sygnal')`,
34
+ throttle: `.compose(throttle(ms)) (import { throttle } from 'sygnal')`,
35
+ auditTime: `.compose(throttle(ms)) (import { throttle } from 'sygnal')`,
36
+ delay: `.compose(delay(ms)) (import { delay } from 'sygnal')`,
37
+ distinctUntilChanged: `.compose(dropRepeats()) (import { dropRepeats } from 'sygnal')`,
38
+ withLatestFrom: `.compose(sampleCombine(other$)) (import { sampleCombine } from 'sygnal')`,
39
+ combineLatest: `xs.combine(a$, b$) (import { xs } from 'sygnal')`,
40
+ combineLatestWith: `xs.combine(a$, b$) (import { xs } from 'sygnal')`,
41
+ merge: `xs.merge(a$, b$) (import { xs } from 'sygnal')`,
42
+ mergeWith: `xs.merge(a$, b$) (import { xs } from 'sygnal')`,
43
+ concat: `concat(a$, b$) (import { concat } from 'sygnal')`,
44
+ scan: `.fold((acc, x) => next, seed)`,
45
+ reduce: `.fold((acc, x) => next, seed).last()`,
46
+ skip: `.drop(n)`,
47
+ first: `.take(1)`,
48
+ takeUntil: `.endWhen(other$)`,
49
+ tap: `.debug(fn)`,
50
+ do: `.debug(fn)`,
51
+ catchError: `.replaceError(err => fallback$)`,
52
+ catch: `.replaceError(err => fallback$)`,
53
+ pluck: `.map(x => x.field)`,
54
+ share: `xstream streams are already shared (hot); use .remember() to replay the latest value`,
55
+ shareReplay: `.remember()`,
56
+ publishReplay: `.remember()`,
57
+ finalize: `.debug({ complete: fn }) or handle completion in the subscriber`,
58
+ }
59
+
60
+ const SYG301_URL = docsUrlFor('SYG301')
61
+
62
+ function rxjsError(op: string): TypeError {
63
+ const hint = RXJS_HINTS[op]
64
+ const message = `stream.${op} is not a function: '${op}' is an RxJS operator, but Sygnal streams are xstream streams`
65
+ const fix = `Use ${hint}`
66
+ // In 'error' mode report() throws the DiagnosticError itself (we are about to throw anyway).
67
+ const d = report('SYG301', {message, fix, data: {operator: op, hint}})
68
+ const err: any = new TypeError(d ? d.text : `[Sygnal SYG301] ${message}. ${fix}. ${SYG301_URL}`)
69
+ err.diagnostic = d
70
+ return err
71
+ }
72
+
73
+ /** Install the hints on xstream's Stream.prototype. Returns an uninstall function. */
74
+ export function installRxjsHints(proto: any): () => void {
75
+ const added: string[] = []
76
+ if (!proto) return () => {}
77
+ for (const op of Object.keys(RXJS_HINTS)) {
78
+ if (op in proto) continue
79
+ Object.defineProperty(proto, op, {
80
+ configurable: true,
81
+ writable: true,
82
+ enumerable: false,
83
+ value: function rxjsOperatorHint() { throw rxjsError(op) },
84
+ })
85
+ added.push(op)
86
+ }
87
+ return () => { for (const op of added) delete proto[op] }
88
+ }