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,133 @@
1
+ import {warn} from './diagnostics/legacy';
2
+
3
+ /*
4
+ * PLAN-4 GS-5 (D114): state persistence for the root component, as a helper value:
5
+ *
6
+ * TodoApp.persist = persist({ key: 'todo-app', pick: ['todos', 'filter'], version: 2, migrate })
7
+ *
8
+ * The core has no persistence code: a root component calls `persist.setup(this)` once, in its
9
+ * root setup (src/core/runtime.ts rootShim); an app that never imports persist() pays 0 B.
10
+ *
11
+ * - Stored as JSON `{ version, state }` under `key`; `state` has the picked top-level keys
12
+ * (`pick`), or all but `omit` and the calculated fields. A `uses` key whose behavior is marked
13
+ * `persist: false` (sortable: drag state) is left out of both the save and the restore (the root's own
14
+ * `uses` only: a sub-component's or Collection item's behavior slice is part of its data, 3-L G-476). `format: 'plain'` (4-G1, D143) stores
15
+ * that object itself, with no envelope; `version` / `migrate` then don't apply (a type error;
16
+ * ignored here), and a stored value that isn't an object is ignored.
17
+ * - Restore: a synchronous read before INITIALIZE, merged into initialState, so the restore is
18
+ * part of the initial-state action. A stored `version` other than `version` (default 1) goes
19
+ * through `migrate(old, fromVersion)`; without migrate, or when it returns nothing, the entry
20
+ * is ignored. Hydrating server HTML, the restore is a RESTORE action after the first state
21
+ * instead, so the first render matches the server's. Hydrating: the `hydrate` option when given,
22
+ * else the integration's `__hydrate` source (Astro: a server-rendered island; Vike: a hydration),
23
+ * else whether run()'s mount point (its `__m` source) starts with renderToString's markup (the
24
+ * root element carries `data-sygnal-ssr`; 3-R).
25
+ * - Writes: debounced (`debounceMs`, default 100), skipped when the stored text is the same,
26
+ * flushed on `pagehide` and on dispose.
27
+ * - `PERSIST: { clear: true }` in any model entry's object form (a value or a function of
28
+ * (state, data)) removes the stored copy; the state that same action produces isn't written
29
+ * (later changes are). The entry's PERSIST sink is turned into an EFFECT here, so it needs no
30
+ * driver. An 'ACTION | PERSIST' key (non-canonical) isn't handled (3-B2).
31
+ * - `sync: true`: another tab's write is applied through RESTORE (the `storage` event, or an
32
+ * adapter's `subscribe(fn)`).
33
+ * - `storage`: 'local' (default), 'session', or a synchronous { getItem, setItem, removeItem }
34
+ * adapter (optionally with subscribe). renderComponent passes its fake stores as the
35
+ * `__storage` source ({ local, session, f: flush functions t.settle() calls }).
36
+ * - Failures (unreadable entry, migrate throws, quota) are SYG642 (warn, printed in production
37
+ * too), once per kind (restore / save / clear; a save that works again re-arms it); the app
38
+ * continues on initialState / unsaved, and a failed save is retried at the next change.
39
+ */
40
+ const g: any = globalThis;
41
+
42
+ export const setupPersist = (c: any, o: any): void => {
43
+ const {key, pick, omit, version = 1, migrate, sync, debounceMs = 100} = o, plain = o.format == 'plain', src = c.sources, m = src.__m;
44
+ const env = src.__storage, calc = c.calculated || {};
45
+ // hydrating: the option, else the integration's signal (__hydrate: Astro, Vike), else whether
46
+ // run()'s mount point starts with renderToString's markup (its root element is marked; a
47
+ // client-only app's loading placeholder isn't server markup)
48
+ const hydrate = o.hydrate ?? src.__hydrate ?? !!(typeof m == 'string' ? g.document?.querySelector(m) : m)?.firstElementChild?.hasAttribute('data-sygnal-ssr');
49
+ let S: any, t: any, last: any, raw: any, skip: any, off: any;
50
+ // (the docs link the message ends with explains the causes and fixes). Once per kind (restore,
51
+ // save, clear): a storage that throws on every write must not warn on every change; a save that
52
+ // works again re-arms the save report
53
+ const bad: any = {};
54
+ const fail = (what: string, e?: any) => bad[what] || (bad[what] = 1, warn('SYG642', c, `persist '${key}': ${what} failed`, undefined, e));
55
+ // a behavior's slice marked `persist: false` (UI state: sortable's drag) is never saved or restored (3-H G-452)
56
+ const uses = c.view?.uses || {};
57
+ const only = (s: any) => {
58
+ const out: any = {};
59
+ for (const k in s) if ((pick ? pick.includes(k) : !omit?.includes(k)) && !(k in calc) && uses[k]?.persist !== false) out[k] = s[k];
60
+ return out;
61
+ };
62
+ const read = (r: any) => {
63
+ try {
64
+ if (r == null) return;
65
+ const j = JSON.parse(r);
66
+ if (plain) return j && typeof j == 'object' && !Array.isArray(j) ? only(j) : undefined;
67
+ const {version: v = 1, state} = j, s = v === version ? state : migrate && migrate(state, v);
68
+ return s && only(s);
69
+ } catch (e) { fail('restore', e); }
70
+ };
71
+ const write = () => {
72
+ clearTimeout(t); t = 0;
73
+ const r = JSON.stringify(plain ? only(last) : {version, state: only(last)}), p = raw;
74
+ // a failed save is retried at the next change (raw stays the stored text)
75
+ if (r != raw) try { raw = r; S.setItem(key, r); bad.save = 0; } catch (e) { raw = p; fail('save', e); }
76
+ };
77
+ const clear = () => {
78
+ clearTimeout(t); t = 0; skip = 1; raw = null;
79
+ setTimeout(() => skip = 0);
80
+ try { S?.removeItem(key); } catch (e) { fail('clear', e); }
81
+ };
82
+ const send = (d: any) => d && c.action$.shamefullySendNext({type: 'RESTORE', data: d});
83
+ // PERSIST sinks become EFFECTs (no driver); a model RESTORE entry replaces the built-in one
84
+ const wrap = (p: any, e?: any) => (...a: any[]) => { const r = e?.(...a), v = typeof p == 'function' ? p(...a) : p; v?.clear && clear(); return r; };
85
+ const model: any = {RESTORE: (s: any, d: any) => ({...s, ...d})};
86
+ for (const k in c.model) {
87
+ let v = c.model[k];
88
+ if (v && typeof v == 'object' && 'PERSIST' in v) { const {PERSIST, ...rest} = v; v = {...rest, EFFECT: wrap(PERSIST, rest.EFFECT)}; }
89
+ model[k] = v;
90
+ }
91
+ c.model = model;
92
+ try { S = typeof o.storage == 'object' ? o.storage : (env || g)[(o.storage || 'local') + (env ? '' : 'Storage')]; } catch (_) {}
93
+ if (!S) return;
94
+ try {
95
+ raw = S.getItem(key);
96
+ if (!hydrate) { const r = read(raw); if (r) c.initialState = {...c.initialState, ...r}; }
97
+ } catch (e) { fail('restore', e); }
98
+ const state$ = c.sources[c.stateSourceName].stream;
99
+ let first = 1;
100
+ const L = {next: (s: any) => {
101
+ last = s;
102
+ // the initial state (restored or not) isn't written back. hydrate: it is the server's; restore
103
+ // once it has rendered (the DOM driver patches before this listener hears the vtree)
104
+ if (first) {
105
+ first = 0;
106
+ let once = hydrate;
107
+ const v$ = c.vdom$, l = {next: () => once && setTimeout(() => (v$.removeListener(l), send(read(raw))), once = 0)};
108
+ return hydrate && v$.addListener(l);
109
+ }
110
+ if (!skip) clearTimeout(t), t = setTimeout(write, debounceMs);
111
+ }};
112
+ state$.addListener(L);
113
+ const flush = () => t && write();
114
+ const onSync = (k: any, v: any) => { if (k == key && v != raw) send(read(raw = v)); };
115
+ const onStorage = (e: any) => (!e.storageArea || e.storageArea == S) && onSync(e.key, e.newValue);
116
+ if (sync) off = S.subscribe ? S.subscribe(onSync) : (g.addEventListener?.('storage', onStorage), () => g.removeEventListener?.('storage', onStorage));
117
+ g.addEventListener?.('pagehide', flush);
118
+ env?.f.add(flush);
119
+ c._dispose$.addListener({next: () => {
120
+ flush();
121
+ state$.removeListener(L);
122
+ off?.();
123
+ g.removeEventListener?.('pagehide', flush);
124
+ env?.f.delete(flush);
125
+ }});
126
+ };
127
+
128
+ /**
129
+ * `App.persist = persist({ key, pick | omit, version, migrate, format, storage, sync, hydrate, debounceMs })`:
130
+ * the root component's state, saved to localStorage (or sessionStorage, or an adapter) and
131
+ * restored at startup. Only an app that imports it pays for it.
132
+ */
133
+ export const persist = (o: any) => ({options: o, setup: (c: any) => setupPersist(c, o)});
package/src/extra/pwa.ts CHANGED
@@ -118,7 +118,7 @@ export function makeServiceWorkerDriver(
118
118
 
119
119
  let _onlineCleanup: (() => void) | undefined;
120
120
 
121
- export const onlineStatus$: Stream<boolean> = xs.create<boolean>({
121
+ export const onlineStatus$: Stream<boolean> = /*#__PURE__*/ xs.create<boolean>({
122
122
  start(listener: Listener<boolean>) {
123
123
  if (typeof window === 'undefined') {
124
124
  listener.next(true);
@@ -0,0 +1,107 @@
1
+ import {onBrowserSignals} from './browserSignals';
2
+ import {withQuery, hit} from './fetchDriver';
3
+
4
+ /*
5
+ * queryCache(options?) (PLAN-3 D88, 5-5): the opt-in query cache of makeFetchDriver, in its own
6
+ * export so apps that only make requests don't pay for it:
7
+ *
8
+ * makeFetchDriver({ cache: queryCache({ staleTime, gcTime, refetchOnFocus, refetchOnReconnect, initial }) })
9
+ *
10
+ * It owns the entries (key → { k, q (the request), v (data), at (fetched at), s (marked stale),
11
+ * n (resources using it), g (gc timer) }), gc, freshness (the stale-while-revalidate decision),
12
+ * the fetches identical requests share (de-duplication, `f`), entry invalidation, the focus /
13
+ * reconnect trigger and SSR seeding. The driver calls its hooks (key, fresh, get, put, use,
14
+ * inval, on, list) and keeps resources, polling, retries and validation.
15
+ *
16
+ * - Keys: method + URL as written (the driver's baseUrl left out, query sorted) + body + parse.
17
+ * Cacheable: a resource's GET/HEAD request, and any request with `cache: true` or `staleTime`
18
+ * (`cache: false` opts out; a `parse` function / 'response' or a non-string body never is).
19
+ * - SSR seeding (H-7): `dehydrate()` returns a JSON-safe snapshot `[{ key, data, updatedAt, tags }]`
20
+ * of the entries with data; `hydrate(snapshot)` / `queryCache({ initial })` write it back (an
21
+ * entry newer than the snapshot's is kept). `set(request, data)` writes one entry (a loader on
22
+ * the server). Entries keep their `updatedAt`, so a seeded entry is fresh for `staleTime`.
23
+ * - `prefetch(request)`: the attached driver (the last makeFetchDriver given this cache) fetches
24
+ * the request into the cache without a reply, like the `{ prefetch }` sink command.
25
+ */
26
+
27
+ const IDEMPOTENT = /^(GET|HEAD)$/i;
28
+
29
+ export function queryCache(o: any = {}): any {
30
+ const map = new Map<string, any>();
31
+ const now = () => Date.now();
32
+ const gc = (E: any) => {
33
+ clearTimeout(E.g);
34
+ const ms = o.gcTime ?? 3e5;
35
+ // unref: a server's seeded cache never keeps Node alive
36
+ if (ms < 1 / 0) (E.g = setTimeout(() => E.n || map.delete(E.k), ms) as any).unref?.();
37
+ };
38
+ const entry = (k: string, q: any) => {
39
+ let E = map.get(k);
40
+ if (!E) map.set(k, (E = {k, q, n: 0}));
41
+ return E;
42
+ };
43
+ // the key of a cacheable request (else undefined); `res`: a resource's
44
+ const key = (q: any, res?: any) => {
45
+ if (typeof q == 'string') q = {url: q};
46
+ const {method, json, body, parse, query} = q;
47
+ const m = (method || (json !== undefined || body !== undefined ? 'POST' : 'GET')).toUpperCase();
48
+ const b = json !== undefined ? JSON.stringify(json) : body ?? '';
49
+ if (q.cache === false || typeof b != 'string' || typeof parse == 'function' || parse == 'response' ||
50
+ !(q.cache || q.staleTime != null || (res && IDEMPOTENT.test(m)))) return;
51
+ return [m, withQuery(q.url ?? '', query, 1), b, parse].join(' ').trim();
52
+ };
53
+ const fresh = (k: any, q: any) => {
54
+ const E = map.get(k);
55
+ return E?.at > 0 && !E.s && now() - E.at < (q?.staleTime ?? o.staleTime ?? 0);
56
+ };
57
+ const put = (k: string, q: any, v: any, at = now()) => {
58
+ const E = entry(k, q);
59
+ E.v = v;
60
+ E.at = at;
61
+ E.s = 0;
62
+ E.q = q;
63
+ E.n || gc(E);
64
+ };
65
+ const C: any = {
66
+ key,
67
+ fresh,
68
+ put,
69
+ get: (k: any) => map.get(k),
70
+ // the fetches identical cacheable requests share (the driver's flight records), key → flight
71
+ f: new Map(),
72
+ // resource R now uses key k (or none): the entries' subscriber counts, gc when unused
73
+ use: (R: any, k?: string) => {
74
+ if (R.k === k) return;
75
+ const O = map.get(R.k);
76
+ if (O && !--O.n) gc(O);
77
+ if ((R.k = k) !== undefined) {
78
+ const E = entry(k as string, R.q);
79
+ E.n++;
80
+ clearTimeout(E.g);
81
+ }
82
+ },
83
+ // D80: marks the matching entries stale (`dry`: only counts them)
84
+ inval: (x: any, dry?: any) => {
85
+ let n = 0;
86
+ map.forEach(E => { if (hit(x, E.q)) { n++; dry || (E.s = 1); } });
87
+ return n;
88
+ },
89
+ // focus / reconnect call `fn` (the driver refetches its stale mounted resources); `on`: the
90
+ // test fake's signal source
91
+ on: (on: any, fn: () => void) => (on || onBrowserSignals)((sig: string) => {
92
+ o[sig == 'focus' ? 'refetchOnFocus' : 'refetchOnReconnect'] === false || fn();
93
+ }),
94
+ list: () => [...map.values()].map(E => ({key: E.k, age: E.at && now() - E.at, stale: !fresh(E.k, E.q), subscribers: E.n, data: E.v, tags: E.q?.tags})),
95
+ dehydrate: () => [...map.values()].filter(E => E.at > 0).map(E => ({key: E.k, data: E.v, updatedAt: E.at, tags: E.q?.tags})),
96
+ hydrate: (snap: any) => snap?.forEach?.((e: any) => {
97
+ if (!(map.get(e.key)?.at >= e.updatedAt)) put(e.key, {url: e.key.split(' ')[1], tags: e.tags}, e.data, e.updatedAt);
98
+ }),
99
+ set: (q: any, data: any) => {
100
+ const k = key(q, 1);
101
+ if (k !== undefined) put(k, typeof q == 'string' ? {url: q} : q, data);
102
+ },
103
+ prefetch: (q: any) => C.d?.({prefetch: q}),
104
+ };
105
+ C.hydrate(o.initial);
106
+ return C;
107
+ }
@@ -17,7 +17,7 @@
17
17
  * set((state, title) => ({ title }))
18
18
  */
19
19
  export function set<S = any>(
20
- partial: Partial<S> | ((state: S, data: any, next: Function, props: any) => Partial<S>)
20
+ partial: (Partial<S> & object) | ((state: S, data: any, next: Function, props: any) => Partial<S>)
21
21
  ): (state: S, data: any, next: Function, props: any) => S {
22
22
  if (typeof partial === 'function') {
23
23
  return (state, data, next, props) => ({
@@ -39,6 +39,17 @@ export function toggle<S = any>(field: keyof S & string): (state: S) => S {
39
39
  return (state) => ({ ...state, [field]: !state[field] })
40
40
  }
41
41
 
42
+ // event(type, payload?) → EVENTS sink fn for the object form:
43
+ // `ACTION: { EVENTS: event('TYPE', (state, data) => payload) }` (static payloads allowed)
44
+ export function event(
45
+ type: string,
46
+ payload?: any | ((state: any, data: any, next: Function, props: any) => any)
47
+ ): (state: any, data: any, next: Function, props: any) => { type: string; data: any } {
48
+ return typeof payload === 'function'
49
+ ? (state, data, next, props) => ({ type, data: payload(state, data, next, props) })
50
+ : () => ({ type, data: payload })
51
+ }
52
+
42
53
  // ── emit() ─────────────────────────────────────────────────────────
43
54
  /**
44
55
  * Create a model entry that emits an EVENTS bus event.
@@ -56,9 +67,5 @@ export function emit(
56
67
  type: string,
57
68
  data?: any | ((state: any, actionData: any, next: Function, props: any) => any)
58
69
  ): { EVENTS: (state: any, actionData: any, next: Function, props: any) => { type: string; data: any } } {
59
- return {
60
- EVENTS: typeof data === 'function'
61
- ? (state, actionData, next, props) => ({ type, data: data(state, actionData, next, props) })
62
- : () => ({ type, data }),
63
- }
70
+ return { EVENTS: event(type, data) }
64
71
  }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * PLAN-4 3-E (GS-10 stretch): a dev-only bridge to the Redux DevTools extension
3
+ * (window.__REDUX_DEVTOOLS_EXTENSION__), in 'sygnal/devtools'. Sends each recorded action
4
+ * (./devtoolsActions; built-in ones left out) with the root's state after it, as
5
+ * `{ type: '<Component>/<ACTION>', payload, cause, instance }`. Jump to state / action in the
6
+ * extension replaces the root's state (the Sygnal DevTools time-travel path). sygnal/vite calls it
7
+ * in dev with sygnal({ devtools: { redux: true } }).
8
+ */
9
+ import {recordActions, onAction, resolveInstance, preview} from './devtoolsActions'
10
+ import type {DevtoolsAction} from './devtoolsActions'
11
+
12
+ export interface ReduxDevtoolsOptions {
13
+ /** the instance name in the extension (default 'Sygnal') */
14
+ name?: string
15
+ /** which actions to send (default: all but 'built-in' ones) */
16
+ filter?: (action: DevtoolsAction) => boolean
17
+ }
18
+
19
+ const clone = (s: any) => preview(s)
20
+
21
+ let shared: (() => void) | undefined
22
+
23
+ /**
24
+ * Connect the app's root (run()'s result, a component, an instance id; default: the newest root)
25
+ * to the Redux DevTools extension. Returns a disconnect function; does nothing without the
26
+ * extension.
27
+ */
28
+ export function connectReduxDevtools(target?: any, options?: ReduxDevtoolsOptions): () => void {
29
+ // the default connection (sygnal/vite may inject the call in several files) is made once
30
+ if (target === undefined && options === undefined) {
31
+ if (!shared) {
32
+ const off = connect(undefined, {})
33
+ shared = () => { off(); shared = undefined }
34
+ }
35
+ return shared
36
+ }
37
+ return connect(target, options || {})
38
+ }
39
+
40
+ function connect(target: any, options: ReduxDevtoolsOptions): () => void {
41
+ const ext = typeof window != 'undefined' && (window as any).__REDUX_DEVTOOLS_EXTENSION__
42
+ if (!ext || typeof ext.connect != 'function') return () => {}
43
+ recordActions()
44
+ const conn = ext.connect({name: options.name || 'Sygnal', features: {jump: true, pause: true, export: true}})
45
+ const keep = options.filter || ((a: DevtoolsAction) => a.cause != 'built-in')
46
+ let root: any, started = false, timer: any = null
47
+ const queue: DevtoolsAction[] = []
48
+
49
+ const rootOf = () => {
50
+ if (!root || root.disposed || !root.c) root = resolveInstance(target)
51
+ return root
52
+ }
53
+ const flush = () => {
54
+ timer = null
55
+ const r = start()
56
+ if (!r) return
57
+ for (const a of queue.splice(0)) {
58
+ const state = a.instance === r.id && 'after' in a ? a.after : r.c.currentState
59
+ conn.send({type: `${a.component}/${a.type}`, payload: preview(a.data), cause: a.cause, instance: a.instance}, clone(state))
60
+ }
61
+ }
62
+ const start = () => {
63
+ const r = rootOf()
64
+ if (r && !started) { started = true; conn.init(clone(r.c.currentState)) }
65
+ return r
66
+ }
67
+ start()
68
+ const off = onAction((a, kind) => {
69
+ if (kind == 'reset') { queue.length = 0; started = false; start(); return }
70
+ if (kind != 'add') return
71
+ // connected before run() (sygnal/vite): the root's first action, its state still the initial one
72
+ if (!started) start()
73
+ if (!keep(a!)) return
74
+ queue.push(a!)
75
+ if (timer === null) timer = setTimeout(flush, 0)
76
+ })
77
+ const unsubscribe = conn.subscribe((msg: any) => {
78
+ if (msg?.type !== 'DISPATCH' || !msg.state) return
79
+ const t = msg.payload?.type
80
+ if (t !== 'JUMP_TO_STATE' && t !== 'JUMP_TO_ACTION') return
81
+ const r = rootOf()
82
+ const dt = (window as any).__SYGNAL_DEVTOOLS__
83
+ if (!r || !dt || typeof dt._timeTravel != 'function') return
84
+ try { dt._timeTravel({componentId: Number(r.id), componentName: r.name, state: JSON.parse(msg.state)}) } catch (_) { /* a bad state from the extension */ }
85
+ })
86
+ return () => {
87
+ off()
88
+ if (timer !== null) clearTimeout(timer)
89
+ if (typeof unsubscribe == 'function') unsubscribe()
90
+ try { ext.disconnect?.() } catch (_) { /* ignore */ }
91
+ }
92
+ }
@@ -0,0 +1,54 @@
1
+ import xs from 'xstream';
2
+ import {error as logError} from './diagnostics/legacy';
3
+
4
+ /*
5
+ * PLAN-3 reply actions: the shared part of every driver that answers a request
6
+ * with the sender's own actions (makeFetchDriver, driverFromAsync, the socket driver).
7
+ *
8
+ * - The core stamps each object a component sends to a source marked
9
+ * `__sygnalReplies: true` with the sending instance (`__emitterId`, the same
10
+ * non-enumerable stamp EVENTS gets), and merges `source.replies(instance)` into
11
+ * that instance's actions.
12
+ * - A request that names `ok` / `error` actions from a stamped sender gets reply actions:
13
+ * the driver answers it with `reply(sender, type, data)`, which reaches exactly
14
+ * that instance (never select()/errors()).
15
+ * - When the instance stops listening (disposed), `onStop(sender)` lets the
16
+ * driver abort what it still has in flight for it.
17
+ */
18
+
19
+ const SENDER = '__emitterId';
20
+
21
+ /** the instance that sent a request (undefined when it wasn't sent by a component) */
22
+ export const senderOf = (req: any) => req[SENDER];
23
+
24
+ /** `to` (a copy of `from`) with `from`'s sender stamp (a spread drops non-enumerables) */
25
+ export const keepSender = (from: any, to: any) => {
26
+ if (from[SENDER] !== undefined) Object.defineProperty(to, SENDER, {value: from[SENDER]});
27
+ return to;
28
+ };
29
+
30
+ /**
31
+ * D57: a request object with a `then` / `catch` key is a thenable (it breaks `await`), so
32
+ * reply-action drivers refuse it (SYG610). True when the request may be sent.
33
+ */
34
+ export const allowed = (req: any, driver: string) =>
35
+ !('then' in req || 'catch' in req) ||
36
+ logError('SYG610', req.__emitterName, `${driver}: request not sent: it has a 'then'/'catch' key`, "Use ok: 'ACTION' / error: 'ACTION'", req);
37
+
38
+ /** the reply-action half of a driver's source */
39
+ export const makeReplies = (onStop?: (sender: any) => void) => {
40
+ const to = new Map<any, any>();
41
+ return {
42
+ replies: {
43
+ __sygnalReplies: true,
44
+ replies: (sender: any) => xs.create<any>({
45
+ start: l => { to.set(sender, l); },
46
+ stop: () => { to.delete(sender); onStop?.(sender); },
47
+ }),
48
+ },
49
+ /** deliver `{ type, data }` to the sender's actions (dropped when it's gone) */
50
+ reply: (sender: any, type: any, data: any) => { to.get(sender)?.next({type, data}); },
51
+ /** whether the sender listens to its replies now (a reply to it would not be dropped) */
52
+ listening: (sender: any) => to.has(sender),
53
+ };
54
+ };