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
@@ -18,6 +18,7 @@
18
18
  // Import from the package entry so rollup externalizes it
19
19
  // @ts-ignore — resolved at runtime via package exports
20
20
  import { run } from 'sygnal'
21
+ import { owned } from '../extra/owned'
21
22
 
22
23
  declare global {
23
24
  interface Window {
@@ -31,12 +32,16 @@ interface PageContext {
31
32
  routeParams?: Record<string, string>
32
33
  urlPathname?: string
33
34
  isHydration?: boolean
35
+ /** PLAN-3 5-5 (H-7): the queryCache() snapshot a loader seeded (see onRenderHtml) */
36
+ queryCache?: any
34
37
  config: {
35
38
  Layout?: any | any[]
36
39
  Wrapper?: any | any[]
37
40
  title?: string
38
41
  ssr?: boolean
39
42
  drivers?: Record<string, (sink: any) => any>
43
+ // PLAN-4 GS-11: the app-level error hook (not Vike's own onError)
44
+ sygnalOnError?: (error: any, info: any) => void
40
45
  }
41
46
  }
42
47
 
@@ -54,40 +59,53 @@ let currentRouteParams: any = {}
54
59
  let currentUrlPathname: string = ''
55
60
  let pageNavCounter: number = 0
56
61
 
62
+ /**
63
+ * PLAN-4 G-207: the uid() path part of a shell component or the Page: wrapper_0 → 'w0',
64
+ * layout_1 → 'l1', page → 'p'. Given as the nested vnode's `id` prop, so the Page's uid is
65
+ * 'u-w0-l0-p' however the shell nests it; onRenderHtml renders each one with the same root
66
+ * (renderToString's `uid`), so server and client ids match. (Same helper in onRenderHtml.ts.)
67
+ */
68
+ function uidPart(key: string): string {
69
+ return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)
70
+ }
71
+
72
+ /**
73
+ * PLAN-4.6 R4 (04 §3.11): the core instantiates a component from the vnode's `data.c`, a
74
+ * component function, and reads its statics there (no options object). A shell component or a
75
+ * Page is wrapped once (a per-app / per-navigation function) with the statics the options
76
+ * gave the 5.x core: isolatedState, and the initial state.
77
+ */
78
+ const shellFns = new WeakMap<any, any>()
79
+ function shellFn(comp: any, initialState: any, cache = true): any {
80
+ let f = cache ? shellFns.get(comp) : undefined
81
+ if (!f) {
82
+ f = Object.assign((p: any) => comp(p), comp, { isolatedState: true, initialState })
83
+ try { Object.defineProperty(f, 'name', { value: comp.name, configurable: true }) } catch (_) {}
84
+ if (cache) shellFns.set(comp, f)
85
+ }
86
+ return f
87
+ }
88
+ let pageFn: any, pageFnNav = -1
89
+
57
90
  /**
58
91
  * Build a component vnode that matches what the JSX pragma produces.
59
92
  */
60
- function componentVNode(comp: any, stateField: string, children: any[], compInitialState?: any): any {
93
+ function componentVNode(comp: any, key: string, stateField: any, children: any[], compInitialState?: any): any {
61
94
  const name = comp.componentName || comp.name || 'FUNCTION_COMPONENT'
62
95
  return {
63
96
  sel: name,
64
97
  data: {
98
+ c: shellFn(comp, owned(comp.initialState)),
65
99
  props: {
66
100
  state: stateField,
67
- sygnalOptions: {
68
- name,
69
- view: comp,
70
- model: comp.model,
71
- intent: comp.intent,
72
- hmrActions: comp.hmrActions,
73
- context: comp.context,
74
- peers: comp.peers,
75
- components: comp.components,
76
- initialState: compInitialState,
77
- isolatedState: true,
78
- calculated: comp.calculated,
79
- storeCalculatedInState: comp.storeCalculatedInState,
80
- DOMSourceName: comp.DOMSourceName,
81
- stateSourceName: comp.stateSourceName,
82
- onError: comp.onError,
83
- debug: comp.debug,
84
- },
101
+ // G-207: the uid() base, as onRenderHtml gives this shell component (see uidPart)
102
+ id: uidPart(key),
85
103
  },
86
104
  },
87
105
  children,
88
106
  text: undefined,
89
107
  elm: undefined,
90
- key: '__vike_' + stateField + '__',
108
+ key: '__vike_' + key + '__',
91
109
  }
92
110
  }
93
111
 
@@ -96,33 +114,19 @@ function componentVNode(comp: any, stateField: string, children: any[], compInit
96
114
  * Reads from mutable `currentPage` / `currentPageName` so the wrapper
97
115
  * view picks up the new Page component on navigation without being recreated.
98
116
  */
99
- function pageChildVNode(pageState: any): any {
100
- // Include pageNavCounter in sel so instantiateSubComponents detects a
101
- // component swap even when both pages have the same function name (e.g. 'Page').
117
+ function pageChildVNode(pageState: any, stateField: any = 'page'): any {
118
+ // a new function per navigation, so the Page is made again even when both pages are the same
119
+ // function (e.g. 'Page'); the nav counter in `sel` keeps the vnodes apart
102
120
  const sel = currentPageName + '__nav' + pageNavCounter
121
+ if (pageFnNav !== pageNavCounter) { pageFnNav = pageNavCounter; pageFn = shellFn(currentPage, undefined, false) }
103
122
  return {
104
123
  sel,
105
124
  data: {
125
+ c: pageFn,
106
126
  props: {
107
- state: 'page',
108
- sygnalOptions: {
109
- name: sel,
110
- view: currentPage,
111
- model: currentPage.model,
112
- intent: currentPage.intent,
113
- hmrActions: currentPage.hmrActions,
114
- context: currentPage.context,
115
- peers: currentPage.peers,
116
- components: currentPage.components,
117
- initialState: pageState,
118
- isolatedState: true,
119
- calculated: currentPage.calculated,
120
- storeCalculatedInState: currentPage.storeCalculatedInState,
121
- DOMSourceName: currentPage.DOMSourceName,
122
- stateSourceName: currentPage.stateSourceName,
123
- onError: currentPage.onError,
124
- debug: currentPage.debug,
125
- },
127
+ state: stateField,
128
+ // G-207: the Page's uid() base, as onRenderHtml gives it (the same across navigations)
129
+ id: uidPart('page'),
126
130
  },
127
131
  },
128
132
  children: [],
@@ -146,13 +150,37 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
146
150
  currentPage = Page
147
151
  currentPageName = Page.componentName || Page.name || 'VikePageComponent'
148
152
 
149
- // Combined shell = wrappers (outermost) + layouts (innermost around Page)
150
- // State keys: wrapper_0, wrapper_1, ..., layout_0, layout_1, ...
151
- // Page state lives under the innermost shell component's slice.
152
- const shell = [
153
- ...wrappers.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),
154
- ...layouts.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),
155
- ]
153
+ // Combined shell = wrappers (outermost) + layouts (innermost around Page).
154
+ // D50: the root state holds every slice as a sibling, as in 5.4.0 but with the Page at the
155
+ // root too: { wrapper_0, ..., layout_0, ..., page }. A component's `state` prop selects from
156
+ // its parent component's state, and the shell components are nested in each other, so each
157
+ // one (and the Page) gets a { get, set } lens onto its own ROOT slice: an outer component's
158
+ // reducer replacing its state can't wipe the inner slices (R2-2), and no view sees another
159
+ // component's slice.
160
+ const keys = shellKeys(wrappers, layouts)
161
+ const shell = [...wrappers, ...layouts].map((comp: any, i: number) => ({ comp, key: keys[i] }))
162
+
163
+ // The latest root state. Only the outermost lens gets the root itself; the nested lenses get
164
+ // their parent shell component's state. In both directions the outermost lens runs first and
165
+ // synchronously (state: root -> outer get -> inner get; a reducer: outer get, inner get, inner
166
+ // set, outer set), so the nested lenses read and write through `root`.
167
+ let root: any = {}
168
+ const rootLens = (key: string, outermost: boolean, fresh: boolean) => ({
169
+ get: (state: any) => {
170
+ if (outermost) root = state || {}
171
+ const slice = root[key]
172
+ // a shell slice is a new object on every root state, so the components nested in the
173
+ // shell component see every change (their state stream drops repeated objects)
174
+ return fresh && slice && typeof slice === 'object' && !Array.isArray(slice) ? { ...slice } : slice
175
+ },
176
+ set: (state: any, slice: any) => {
177
+ root = { ...root, [key]: slice }
178
+ // a nested lens returns a changed parent state, so the parent's lens writes `root` back
179
+ return outermost ? root : { ...state }
180
+ },
181
+ })
182
+ const lenses = keys.map((key, i) => rootLens(key, i === 0, true))
183
+ const pageLens = rootLens('page', false, false)
156
184
 
157
185
  function LayoutWrapperView({ state }: any) {
158
186
  if (shell.length === 0) {
@@ -161,17 +189,17 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
161
189
  }
162
190
 
163
191
  const lastIdx = shell.length - 1
164
- const innermostState = state[shell[lastIdx].key] || {}
165
192
  let inner: any = componentVNode(
166
193
  shell[lastIdx].comp,
167
194
  shell[lastIdx].key,
168
- [pageChildVNode(innermostState.page)],
169
- innermostState
195
+ lenses[lastIdx],
196
+ [pageChildVNode(state.page, pageLens)],
197
+ state[shell[lastIdx].key]
170
198
  )
171
199
 
172
200
  // Wrap with outer shell components
173
201
  for (let i = lastIdx - 1; i >= 0; i--) {
174
- inner = componentVNode(shell[i].comp, shell[i].key, [inner], state[shell[i].key])
202
+ inner = componentVNode(shell[i].comp, shell[i].key, lenses[i], [inner], state[shell[i].key])
175
203
  }
176
204
 
177
205
  // Wrap in a plain div so the view returns a regular DOM vnode.
@@ -188,19 +216,16 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
188
216
  }
189
217
 
190
218
  LayoutWrapperView.componentName = 'VikeLayoutWrapper'
219
+ // run() names the root by `name` first
220
+ try { Object.defineProperty(LayoutWrapperView, 'name', { value: 'VikeLayoutWrapper', configurable: true }) } catch (_) {}
191
221
 
192
- // Build the wrapper's initial state with a slice for each shell component.
193
- // Page state is nested under the innermost shell component's slice.
194
- const wrapperInitialState: any = {}
195
- shell.forEach(({ comp, key }: any, i: number) => {
196
- const sliceState: any = { ...(comp.initialState || {}) }
197
- if (i === shell.length - 1) {
198
- sliceState.page = Page.initialState || {}
199
- }
200
- wrapperInitialState[key] = sliceState
201
- })
202
-
203
- LayoutWrapperView.initialState = wrapperInitialState
222
+ // The wrapper's initial state: a sibling slice for each shell component and the Page.
223
+ // Must match onRenderHtml's serialized state.
224
+ const initialState: any = {}
225
+ shell.forEach(({ comp, key }: any) => { initialState[key] = { ...(comp.initialState || {}) } })
226
+ initialState.page = Page.initialState || {}
227
+ // G-275: owned (built from the hydrated state and pageContext.data: never frozen in dev)
228
+ LayoutWrapperView.initialState = root = owned(initialState)
204
229
 
205
230
  // Context uses mutable references so navigation updates are picked up.
206
231
  // Wrapper and Layout contexts are merged once; page-level context
@@ -224,6 +249,14 @@ function createLayoutWrapper(wrappers: any[], layouts: any[], Page: any): any {
224
249
  return LayoutWrapperView
225
250
  }
226
251
 
252
+ /** State keys of the shell components, outermost first: wrapper_0, ..., layout_0, ... */
253
+ function shellKeys(wrappers: any[], layouts: any[]): string[] {
254
+ return [
255
+ ...wrappers.map((_: any, i: number) => 'wrapper_' + i),
256
+ ...layouts.map((_: any, i: number) => 'layout_' + i),
257
+ ]
258
+ }
259
+
227
260
  /**
228
261
  * Normalize a cumulative config value into an array of functions.
229
262
  */
@@ -240,37 +273,41 @@ export function onRenderClient(pageContext: PageContext) {
240
273
  const layouts = toComponentArray(config.Layout)
241
274
  const hasShell = wrappers.length > 0 || layouts.length > 0
242
275
 
243
- // The shell is wrappers (outermost) + layouts. The innermost component
244
- // holds the Page state as a nested sub-component.
245
- const shell = [
246
- ...wrappers.map((_: any, i: number) => 'wrapper_' + i),
247
- ...layouts.map((_: any, i: number) => 'layout_' + i),
248
- ]
249
- const innermostKey = shell.length > 0 ? shell[shell.length - 1] : null
276
+ // The shell is wrappers (outermost) + layouts; their state slices and the Page's are
277
+ // siblings at the root (D50).
278
+ const shell = shellKeys(wrappers, layouts)
279
+
280
+ // PLAN-3 5-5 (H-7): seed the caches of the fetch drivers (makeFetchDriver({ cache: queryCache() })
281
+ // exposes it as driver.cache) before the page renders, so its resources start at 'success'
282
+ if (pageContext.queryCache) {
283
+ for (const d of Object.values(config.drivers || {})) (d as any)?.cache?.hydrate?.(pageContext.queryCache)
284
+ }
250
285
 
251
286
  // Update mutable context references (used by the wrapper's context functions)
252
287
  currentPageData = data
253
288
  currentRouteParams = pageContext.routeParams || {}
254
- currentUrlPathname = pageContext.urlPathname || ''
289
+ // urlPathname is built in on the client with Client Routing (G-046: it is
290
+ // not in passToClient); fall back to the location with Server Routing.
291
+ currentUrlPathname = pageContext.urlPathname
292
+ || (typeof window !== 'undefined' && window.location ? window.location.pathname : '')
255
293
 
256
294
  // --- Shell path: hot-swap Page, keep Layout/Wrapper alive ---
257
295
  if (hasShell) {
258
296
  if (currentApp) {
259
297
  // Client-side navigation: swap the Page without disposing the shell.
298
+ // PLAN-3 5-4b: a router given Vike's navigate() (makeRouter({ routes, navigate })) re-reads
299
+ // the route on this event; sent before the swap, so the new Page declares after it
300
+ if (typeof window !== 'undefined') window.dispatchEvent?.(new Event('sygnal:navigate'))
260
301
  currentPage = Page
261
302
  currentPageName = Page.componentName || Page.name || 'VikePageComponent'
262
303
  pageNavCounter++
263
304
 
264
305
  const newPageState = { ...(Page.initialState || {}), ...data }
265
- if (currentApp.sinks?.STATE?.shamefullySendNext) {
266
- currentApp.sinks.STATE.shamefullySendNext((state: any) => {
267
- const shellState = state[innermostKey!] || {}
268
- return {
269
- ...state,
270
- [innermostKey!]: { ...shellState, page: newPageState },
271
- }
272
- })
273
- }
306
+ // replace the page slice, keeping every shell slice (G-106, D50)
307
+ const swapPage = (state: any) => ({ ...state, page: newPageState })
308
+ // (PLAN-4.6 core: through the runtime API, 04 §3.11)
309
+ const rt = (currentApp as any).__runtime
310
+ rt?.setState('root', swapPage)
274
311
  } else {
275
312
  // First load: read hydrated state or build from initialState
276
313
  let initialState: any
@@ -281,23 +318,25 @@ export function onRenderClient(pageContext: PageContext) {
281
318
  initialState = null
282
319
  }
283
320
 
284
- if (initialState && innermostKey && initialState[innermostKey] !== undefined) {
285
- // Hydrated combined state — distribute slices to each shell component
321
+ if (initialState && initialState[shell[shell.length - 1]] !== undefined) {
322
+ // Hydrated shell state: sibling slices (D50), or the 5.4.0 shape with the Page state
323
+ // under the innermost shell slice (R2-9) — distribute the slices to each component
286
324
  const allShellComps = [...wrappers, ...layouts]
325
+ let pageState = initialState.page
287
326
  shell.forEach((key: string, i: number) => {
288
- if (initialState[key] !== undefined) {
289
- if (i === shell.length - 1) {
290
- const { page: pageState, ...compState } = initialState[key]
291
- allShellComps[i].initialState = compState
292
- Page.initialState = pageState || { ...(Page.initialState || {}), ...data }
293
- } else {
294
- allShellComps[i].initialState = initialState[key]
295
- }
327
+ let slice = initialState[key]
328
+ if (slice === undefined) return
329
+ if (i === shell.length - 1 && slice && 'page' in slice) {
330
+ const { page, ...rest } = slice
331
+ if (pageState === undefined) pageState = page
332
+ slice = rest
296
333
  }
334
+ allShellComps[i].initialState = owned(slice)
297
335
  })
336
+ Page.initialState = owned(pageState || { ...(Page.initialState || {}), ...data })
298
337
  } else {
299
338
  // SPA mode or client-side first navigation
300
- Page.initialState = { ...(Page.initialState || {}), ...data }
339
+ Page.initialState = owned({ ...(Page.initialState || {}), ...data })
301
340
  }
302
341
 
303
342
  // Inject page-level context into Page (for SSR renderToString compat)
@@ -311,7 +350,9 @@ export function onRenderClient(pageContext: PageContext) {
311
350
  const Component = createLayoutWrapper(wrappers, layouts, Page)
312
351
 
313
352
  try {
314
- currentApp = run(Component, config.drivers || {}, { mountPoint: '#page-view' }) as any
353
+ // 3-B2: `__vike` marks the shell's components (Page, Layouts, Wrappers: sub-components of
354
+ // the shell root) for the dev entry, whose SYG224 then says persist() isn't supported there
355
+ currentApp = run(Component, { ...config.drivers, __vike: () => 1 }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any
315
356
  } catch (err: any) {
316
357
  console.error('[sygnal/vike] Client render error:', err)
317
358
  const container = document.getElementById('page-view')
@@ -332,14 +373,17 @@ export function onRenderClient(pageContext: PageContext) {
332
373
  }
333
374
 
334
375
  let initialState: any
376
+ // 3-B2: the server's state is here when the page hydrates its HTML
377
+ let serverState = false
335
378
  if (typeof window !== 'undefined' && window.__VIKE_SYGNAL_STATE__ !== undefined) {
336
379
  initialState = window.__VIKE_SYGNAL_STATE__
337
380
  delete window.__VIKE_SYGNAL_STATE__
381
+ serverState = true
338
382
  } else {
339
383
  initialState = { ...(Page.initialState || {}), ...data }
340
384
  }
341
385
 
342
- Page.initialState = initialState
386
+ Page.initialState = owned(initialState)
343
387
  Page.context = {
344
388
  ...Page.context,
345
389
  pageData: () => currentPageData,
@@ -348,7 +392,11 @@ export function onRenderClient(pageContext: PageContext) {
348
392
  }
349
393
 
350
394
  try {
351
- currentApp = run(Page, config.drivers || {}, { mountPoint: '#page-view' }) as any
395
+ // 3-B2: the Page is the root, so its persist() restores after the first render when this
396
+ // is a hydration (`__hydrate`), keeping that render equal to the server's HTML. A client-side
397
+ // navigation isn't one, though the previous page's markup is still in #page-view
398
+ const hydrating = pageContext.isHydration ?? serverState
399
+ currentApp = run(Page, { ...config.drivers, __hydrate: () => hydrating }, { mountPoint: '#page-view', onError: config.sygnalOnError }) as any
352
400
  } catch (err: any) {
353
401
  console.error('[sygnal/vike] Client render error:', err)
354
402
  const container = document.getElementById('page-view')
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  // @ts-ignore — resolved at runtime via package exports
18
- import { renderToString } from 'sygnal'
18
+ import { renderToString, renderHead, queryCache } from 'sygnal'
19
19
 
20
20
  interface PageContext {
21
21
  Page: any
@@ -31,8 +31,16 @@ interface PageContext {
31
31
  favicon?: string
32
32
  lang?: string
33
33
  ssr?: boolean
34
+ // PLAN-4 GS-11: the app-level error hook (not Vike's own onError)
35
+ sygnalOnError?: (error: any, info: any) => void
34
36
  }
35
37
  is404?: boolean
38
+ /**
39
+ * PLAN-3 5-5 (H-7): a queryCache() snapshot a loader (+data) seeded:
40
+ * `pageContext.queryCache = cache.dehydrate()`. Resources render from it here, and Vike passes
41
+ * it to the client (passToClient), where onRenderClient hydrates the drivers' caches with it
42
+ */
43
+ queryCache?: any
36
44
  }
37
45
 
38
46
  /**
@@ -46,6 +54,16 @@ function esc(str: string): string {
46
54
  .replace(/"/g, '&quot;')
47
55
  }
48
56
 
57
+ /**
58
+ * PLAN-4 G-207: the uid() path part of a shell component or the Page (wrapper_0 → 'w0',
59
+ * layout_1 → 'l1', page → 'p'), as onRenderClient gives each nested vnode in its `id` prop. Each
60
+ * one renders here as its own root, so its root is 'u' plus the parts of the shell around it and
61
+ * its own: the same uids as the client's nested instances.
62
+ */
63
+ function uidPart(key: string): string {
64
+ return key == 'page' ? 'p' : key[0] + key.slice(key.indexOf('_') + 1)
65
+ }
66
+
49
67
  export function onRenderHtml(pageContext: PageContext) {
50
68
  const { Page, config } = pageContext
51
69
  const data = pageContext.data || {}
@@ -107,6 +125,9 @@ export function onRenderHtml(pageContext: PageContext) {
107
125
  urlPathname: () => pageContext.urlPathname || '',
108
126
  }
109
127
 
128
+ // PLAN-3 5-5 (H-7): the seeded cache the components' resources render from
129
+ const cache = pageContext.queryCache ? queryCache({ initial: pageContext.queryCache }) : undefined
130
+
110
131
  // Determine if Wrapper(s) and/or Layout(s) are present — this affects hydration state shape
111
132
  const wrapperArray = config.Wrapper
112
133
  ? (Array.isArray(config.Wrapper) ? config.Wrapper : [config.Wrapper])
@@ -117,15 +138,32 @@ export function onRenderHtml(pageContext: PageContext) {
117
138
  .filter((L: any) => typeof L === 'function')
118
139
  : []
119
140
  const hasShell = wrapperArray.length > 0 || layoutArray.length > 0
141
+ // Combined shell: wrappers (outermost) + layouts (innermost around Page)
142
+ // Must match the order used in onRenderClient's createLayoutWrapper.
143
+ const shell = [
144
+ ...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),
145
+ ...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),
146
+ ]
147
+ // G-207: with a shell, the client nests each shell component and the Page in the one outside it
148
+ // with an `id` prop (onRenderClient), so their uid roots are 'u-w0', 'u-w0-l0', 'u-w0-l0-p'
149
+ const uidRoot = (i: number) => ['u', ...shell.slice(0, i + 1).map(s => uidPart(s.key))].join('-')
150
+ const pageUid = hasShell ? uidRoot(shell.length - 1) + '-' + uidPart('page') : undefined
120
151
 
121
152
  // Render the page component to HTML, with error boundary.
122
153
  // When layouts are present, the hydration state is serialized separately
123
154
  // as the wrapper's combined state (with page + layout slices).
155
+ // PLAN-3 (HEAD driver): the `head` statics of the rendered components (shell first, so the page's win)
156
+ const pageHeads: any[] = [], shellHeads: any[] = []
124
157
  let pageHtml: string
125
158
  try {
126
159
  pageHtml = renderToString(Page, {
127
160
  state: initialState,
161
+ onError: config.sygnalOnError,
162
+ // G-207: the client's uid base and `id` prop for the nested Page
163
+ ...(hasShell && { uid: pageUid, props: { id: uidPart('page') } }),
128
164
  hydrateState: hasShell ? false : '__VIKE_SYGNAL_STATE__',
165
+ head: pageHeads,
166
+ cache,
129
167
  })
130
168
  } catch (err: any) {
131
169
  // If the component has an onError boundary, try rendering its fallback
@@ -152,27 +190,33 @@ export function onRenderHtml(pageContext: PageContext) {
152
190
  // If Layout(s) and/or Wrapper(s) are defined, render them wrapping the page content.
153
191
  // HTML is rendered INSIDE #page-view so the structure matches the client-side
154
192
  // wrapper component. Nesting order: Wrapper > Layout > Page.
155
- // Each shell component receives page content via a placeholder in its children slot.
193
+ // Each shell component receives the page content as a placeholder. G-464: a placeholder element
194
+ // as its `children` (`<main>{children}</main>`, as on the client), and, for a Layout written
195
+ // for the server only, the `innerHTML` prop.
156
196
  let pageViewContent = pageHtml
157
197
  if (hasShell) {
158
- // Combined shell: wrappers (outermost) + layouts (innermost around Page)
159
- // Must match the order used in onRenderClient's createLayoutWrapper.
160
- const shell = [
161
- ...wrapperArray.map((w: any, i: number) => ({ comp: w, key: 'wrapper_' + i })),
162
- ...layoutArray.map((l: any, i: number) => ({ comp: l, key: 'layout_' + i })),
163
- ]
164
-
198
+ // G-491: with attributes too (a shell whose root, or fragment's first element, is the slot
199
+ // carries the SSR root stamp: data-sygnal-ssr="")
200
+ const SLOT = /<sygnal-page-slot(?:\s[^>]*)?><\/sygnal-page-slot>/
201
+ const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'
165
202
  // Wrap from innermost to outermost (reverse order)
166
203
  for (let i = shell.length - 1; i >= 0; i--) {
167
- const { comp } = shell[i]
168
- const PLACEHOLDER = '<!--SYGNAL_PAGE_SLOT-->'
204
+ const { comp, key } = shell[i]
205
+ const slot = { sel: 'sygnal-page-slot', data: {}, children: [], text: undefined, elm: undefined, key: undefined }
169
206
  const compHtml = renderToString(comp, {
170
207
  state: comp.initialState || {},
171
- props: { innerHTML: PLACEHOLDER },
208
+ // G-207: the uid root and `id` prop the client's nested instance has
209
+ uid: uidRoot(i),
210
+ props: { innerHTML: PLACEHOLDER, id: uidPart(key), children: [slot] },
211
+ head: shellHeads,
212
+ cache,
213
+ onError: config.sygnalOnError,
172
214
  })
173
- const splitIdx = compHtml.indexOf(PLACEHOLDER)
215
+ const m = SLOT.exec(compHtml)
216
+ let splitIdx = m ? m.index : -1, len = m ? m[0].length : 0
217
+ if (splitIdx === -1) splitIdx = compHtml.indexOf(PLACEHOLDER), len = PLACEHOLDER.length
174
218
  if (splitIdx !== -1) {
175
- pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + PLACEHOLDER.length)
219
+ pageViewContent = compHtml.substring(0, splitIdx) + pageViewContent + compHtml.substring(splitIdx + len)
176
220
  } else {
177
221
  // Fallback: component didn't use children/innerHTML, wrap content after it
178
222
  pageViewContent = compHtml + pageViewContent
@@ -181,17 +225,12 @@ export function onRenderHtml(pageContext: PageContext) {
181
225
  // Wrap in a shell div matching the client-side wrapper's root element
182
226
  pageViewContent = `<div id="vike-shell">${pageViewContent}</div>`
183
227
 
184
- // Serialize the wrapper's combined state for hydration.
185
- // Must match the state shape from createLayoutWrapper:
186
- // { wrapper_0: {...}, layout_0: { ...layoutState, page: pageState } }
228
+ // Serialize the wrapper's combined state for hydration. Must match the state shape
229
+ // from createLayoutWrapper (D50: sibling slices at the root):
230
+ // { wrapper_0: { ...wrapperState }, layout_0: { ...layoutState }, page: pageState }
187
231
  const wrapperState: any = {}
188
- shell.forEach(({ comp, key }: any, i: number) => {
189
- const compState: any = { ...(comp.initialState || {}) }
190
- if (i === shell.length - 1) {
191
- compState.page = initialState
192
- }
193
- wrapperState[key] = compState
194
- })
232
+ shell.forEach(({ comp, key }: any) => { wrapperState[key] = { ...(comp.initialState || {}) } })
233
+ wrapperState.page = initialState
195
234
  pageViewContent += `<script>window.__VIKE_SYGNAL_STATE__=${JSON.stringify(wrapperState)}</script>`
196
235
  }
197
236
 
@@ -210,8 +249,12 @@ export function onRenderHtml(pageContext: PageContext) {
210
249
  const favicon = config.favicon || ''
211
250
  const lang = config.lang || 'en'
212
251
 
213
- const titleTag = title ? `<title>${esc(title)}</title>` : ''
214
- const descTag = description
252
+ const heads = [...shellHeads, ...pageHeads].filter(Boolean)
253
+ // with `head` statics, config.title / description are the defaults they override
254
+ const titleTag = heads.length
255
+ ? renderHead([{ title: title || undefined, meta: { description: description || undefined } }, ...heads])
256
+ : title ? `<title>${esc(title)}</title>` : ''
257
+ const descTag = description && !heads.length
215
258
  ? `<meta name="description" content="${esc(description)}">`
216
259
  : ''
217
260
  const faviconTag = favicon
package/src/vike/types.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  /**
2
- * TypeScript declarations for vike-sygnal custom config settings.
2
+ * TypeScript declarations for 'sygnal/config' (also 'sygnal/vike' and
3
+ * 'sygnal/vike/config'): the Vike extension config (default export), and the
4
+ * custom config settings, which augment Vike's Config interface so users get
5
+ * autocomplete and type checking in their +config.ts files.
3
6
  *
4
- * These augment Vike's Config interface so users get autocomplete
5
- * and type checking in their +config.ts files.
7
+ * import vikeSygnal from 'sygnal/config'
8
+ * export default { extends: [vikeSygnal] }
6
9
  */
7
10
 
8
11
  declare global {
@@ -24,10 +27,30 @@ declare global {
24
27
  lang?: string
25
28
  /** Additional Cycle.js drivers to pass to run() (e.g. WebSocket, HTTP). Client-only. */
26
29
  drivers?: Record<string, (sink: any) => any>
30
+ /**
31
+ * App-level error hook (PLAN-4 GS-11), passed to run() on the client and to renderToString
32
+ * on the server: called after a component's onError boundary, reporting only. (Vike's own
33
+ * `onError` is a different, server-only hook)
34
+ */
35
+ sygnalOnError?: (error: any, info: { componentName?: string; action?: string; phase: 'view' | 'reducer' | 'effect' | 'intent' | 'context' | 'declaration' | 'driver' | 'instantiate' | 'dispose' | 'widget'; driver?: string }) => void
27
36
  /** Enable/disable SSR for this page (default: true). Set false for SPA mode. */
28
37
  ssr?: boolean
29
38
  }
30
39
  }
31
40
  }
32
41
 
33
- export {}
42
+ /**
43
+ * The Sygnal extension for Vike: put it in `extends` of your root +config.
44
+ * (Declared here; the value is the package's dist/vike/config/+config.js entry.)
45
+ */
46
+ declare const vikeSygnal: {
47
+ name: 'sygnal'
48
+ clientRouting: boolean
49
+ hydrationCanBeAborted: boolean
50
+ onRenderHtml: string
51
+ onRenderClient: string
52
+ passToClient: string[]
53
+ meta: Record<string, any>
54
+ }
55
+
56
+ export default vikeSygnal
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Stand-in for the `globalthis` npm package (built to dist/shims/globalthis.cjs).
3
+ *
4
+ * xstream does `require('globalthis').getPolyfill()`, which pulls a polyfill
5
+ * chain (define-properties, get-intrinsic, object-keys, has-symbols, ...) into
6
+ * every app bundle (~4 KB gzip). Every browser and Node version Sygnal supports
7
+ * has a native `globalThis`, so `sygnal/vite` aliases `globalthis` to this
8
+ * module (opt out with `sygnal({ nativeGlobalThis: false })`).
9
+ *
10
+ * Same shape as the package's main export (the es-shim API): a function that
11
+ * returns the global object, with `getPolyfill`, `implementation` and `shim`.
12
+ */
13
+ const getGlobal: any = () => globalThis
14
+ getGlobal.getPolyfill = getGlobal
15
+ getGlobal.implementation = globalThis
16
+ getGlobal.shim = getGlobal
17
+
18
+ export default getGlobal