sygnal 5.3.6 → 5.4.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 (226) hide show
  1. package/README.md +53 -38
  2. package/dist/astro/client.cjs.js +18 -8106
  3. package/dist/astro/client.cjs.js.map +1 -0
  4. package/dist/astro/client.mjs +17 -8105
  5. package/dist/astro/client.mjs.map +1 -0
  6. package/dist/astro/index.cjs.js +768 -9
  7. package/dist/astro/index.cjs.js.map +1 -0
  8. package/dist/astro/index.mjs +768 -9
  9. package/dist/astro/index.mjs.map +1 -0
  10. package/dist/astro/server.cjs.js +4 -1
  11. package/dist/astro/server.cjs.js.map +1 -0
  12. package/dist/astro/server.mjs +4 -1
  13. package/dist/astro/server.mjs.map +1 -0
  14. package/dist/diagnostics.cjs.js +1297 -0
  15. package/dist/diagnostics.cjs.js.map +1 -0
  16. package/dist/diagnostics.esm.js +1267 -0
  17. package/dist/diagnostics.esm.js.map +1 -0
  18. package/dist/index.cjs.js +2981 -1386
  19. package/dist/index.cjs.js.map +1 -0
  20. package/dist/index.d.ts +848 -111
  21. package/dist/index.esm.js +2997 -1411
  22. package/dist/index.esm.js.map +1 -0
  23. package/dist/jsx-dev-runtime.cjs.js +15 -9
  24. package/dist/jsx-dev-runtime.cjs.js.map +1 -0
  25. package/dist/jsx-dev-runtime.esm.js +15 -9
  26. package/dist/jsx-dev-runtime.esm.js.map +1 -0
  27. package/dist/jsx-runtime.cjs.js +15 -9
  28. package/dist/jsx-runtime.cjs.js.map +1 -0
  29. package/dist/jsx-runtime.esm.js +15 -9
  30. package/dist/jsx-runtime.esm.js.map +1 -0
  31. package/dist/jsx.cjs.js +15 -9
  32. package/dist/jsx.cjs.js.map +1 -0
  33. package/dist/jsx.esm.js +15 -9
  34. package/dist/jsx.esm.js.map +1 -0
  35. package/dist/sygnal.min.js +2 -1
  36. package/dist/sygnal.min.js.map +1 -0
  37. package/dist/vike/+config.cjs.js +1 -0
  38. package/dist/vike/+config.cjs.js.map +1 -0
  39. package/dist/vike/+config.js +1 -0
  40. package/dist/vike/+config.js.map +1 -0
  41. package/dist/vike/ClientOnly.cjs.js +1 -0
  42. package/dist/vike/ClientOnly.cjs.js.map +1 -0
  43. package/dist/vike/ClientOnly.mjs +1 -0
  44. package/dist/vike/ClientOnly.mjs.map +1 -0
  45. package/dist/vike/onRenderClient.cjs.js +1 -0
  46. package/dist/vike/onRenderClient.cjs.js.map +1 -0
  47. package/dist/vike/onRenderClient.mjs +1 -0
  48. package/dist/vike/onRenderClient.mjs.map +1 -0
  49. package/dist/vike/onRenderHtml.cjs.js +1 -0
  50. package/dist/vike/onRenderHtml.cjs.js.map +1 -0
  51. package/dist/vike/onRenderHtml.mjs +1 -0
  52. package/dist/vike/onRenderHtml.mjs.map +1 -0
  53. package/dist/vite/plugin.cjs.js +680 -47
  54. package/dist/vite/plugin.cjs.js.map +1 -0
  55. package/dist/vite/plugin.mjs +680 -47
  56. package/dist/vite/plugin.mjs.map +1 -0
  57. package/llms.txt +250 -0
  58. package/package.json +15 -6
  59. package/src/astro/client.ts +13 -2
  60. package/src/astro/index.d.ts +24 -1
  61. package/src/astro/index.ts +40 -9
  62. package/src/astro/server.ts +3 -1
  63. package/src/collection.ts +5 -2
  64. package/src/component.ts +375 -330
  65. package/src/cycle/dom/MainDOMSource.ts +4 -0
  66. package/src/cycle/dom/classNameModule.ts +74 -0
  67. package/src/cycle/dom/controlledInputModule.ts +33 -0
  68. package/src/cycle/dom/enrichEventStream.ts +9 -3
  69. package/src/cycle/dom/makeDOMDriver.ts +1 -2
  70. package/src/cycle/dom/mockDOMSource.ts +62 -8
  71. package/src/cycle/dom/modules.ts +5 -1
  72. package/src/cycle/state/Collection.ts +13 -3
  73. package/src/cycle/state/StateSource.ts +1 -1
  74. package/src/cycle/state/pickCombine.ts +35 -1
  75. package/src/cycle/state/withState.ts +1 -1
  76. package/src/extra/devtools.ts +8 -0
  77. package/src/extra/diagnostics/checks/collections.ts +67 -0
  78. package/src/extra/diagnostics/checks/dom.ts +241 -0
  79. package/src/extra/diagnostics/checks/events.ts +68 -0
  80. package/src/extra/diagnostics/checks/index.ts +109 -0
  81. package/src/extra/diagnostics/checks/inspect.ts +319 -0
  82. package/src/extra/diagnostics/checks/props.ts +51 -0
  83. package/src/extra/diagnostics/checks/public.d.ts +211 -0
  84. package/src/extra/diagnostics/checks/rxjsHints.ts +88 -0
  85. package/src/extra/diagnostics/checks/shared.ts +119 -0
  86. package/src/extra/diagnostics/checks/state.ts +55 -0
  87. package/src/extra/diagnostics/checks/strict.ts +112 -0
  88. package/src/extra/diagnostics/checks/wiring.ts +65 -0
  89. package/src/extra/diagnostics/codes.ts +232 -0
  90. package/src/extra/diagnostics/index.ts +328 -0
  91. package/src/extra/diagnostics/legacy.ts +59 -0
  92. package/src/extra/driverFactories.ts +106 -58
  93. package/src/extra/eventDriver.ts +4 -0
  94. package/src/extra/flatten.ts +75 -0
  95. package/src/extra/reducers.ts +12 -5
  96. package/src/extra/run.ts +11 -0
  97. package/src/extra/testing.ts +890 -180
  98. package/src/extra/xstreamExtras.ts +269 -0
  99. package/src/index.d.ts +428 -17
  100. package/src/index.ts +7 -6
  101. package/src/pragma/index.ts +14 -9
  102. package/src/switchable.ts +10 -8
  103. package/src/vike/types.ts +21 -4
  104. package/src/vite/plugin.d.ts +95 -2
  105. package/src/vite/plugin.ts +730 -55
  106. package/dist/astro/astro/client.d.ts +0 -5
  107. package/dist/astro/astro/index.d.ts +0 -16
  108. package/dist/astro/astro/server.d.ts +0 -12
  109. package/dist/astro/client.d.ts +0 -5
  110. package/dist/astro/client.esm.js +0 -4665
  111. package/dist/astro/collection.d.ts +0 -12
  112. package/dist/astro/component.d.ts +0 -22
  113. package/dist/astro/cycle/dom/BodyDOMSource.d.ts +0 -10
  114. package/dist/astro/cycle/dom/DOMSource.d.ts +0 -11
  115. package/dist/astro/cycle/dom/DocumentDOMSource.d.ts +0 -12
  116. package/dist/astro/cycle/dom/ElementFinder.d.ts +0 -8
  117. package/dist/astro/cycle/dom/EventDelegator.d.ts +0 -34
  118. package/dist/astro/cycle/dom/IsolateModule.d.ts +0 -23
  119. package/dist/astro/cycle/dom/MainDOMSource.d.ts +0 -32
  120. package/dist/astro/cycle/dom/PriorityQueue.d.ts +0 -7
  121. package/dist/astro/cycle/dom/ScopeChecker.d.ts +0 -9
  122. package/dist/astro/cycle/dom/SymbolTree.d.ts +0 -9
  123. package/dist/astro/cycle/dom/VNodeWrapper.d.ts +0 -8
  124. package/dist/astro/cycle/dom/enrichEventStream.d.ts +0 -24
  125. package/dist/astro/cycle/dom/fromEvent.d.ts +0 -6
  126. package/dist/astro/cycle/dom/index.d.ts +0 -8
  127. package/dist/astro/cycle/dom/isolate.d.ts +0 -9
  128. package/dist/astro/cycle/dom/makeDOMDriver.d.ts +0 -11
  129. package/dist/astro/cycle/dom/mockDOMSource.d.ts +0 -17
  130. package/dist/astro/cycle/dom/modules.d.ts +0 -5
  131. package/dist/astro/cycle/dom/snabbdom.d.ts +0 -22
  132. package/dist/astro/cycle/dom/styleModule.d.ts +0 -13
  133. package/dist/astro/cycle/dom/thunk.d.ts +0 -11
  134. package/dist/astro/cycle/dom/utils.d.ts +0 -8
  135. package/dist/astro/cycle/isolate/index.d.ts +0 -42
  136. package/dist/astro/cycle/run/adapt.d.ts +0 -6
  137. package/dist/astro/cycle/run/index.d.ts +0 -36
  138. package/dist/astro/cycle/run/internals.d.ts +0 -8
  139. package/dist/astro/cycle/run/types.d.ts +0 -49
  140. package/dist/astro/cycle/state/Collection.d.ts +0 -29
  141. package/dist/astro/cycle/state/StateSource.d.ts +0 -20
  142. package/dist/astro/cycle/state/index.d.ts +0 -5
  143. package/dist/astro/cycle/state/pickCombine.d.ts +0 -3
  144. package/dist/astro/cycle/state/pickMerge.d.ts +0 -3
  145. package/dist/astro/cycle/state/types.d.ts +0 -18
  146. package/dist/astro/cycle/state/withState.d.ts +0 -17
  147. package/dist/astro/extra/classes.d.ts +0 -7
  148. package/dist/astro/extra/devtools.d.ts +0 -78
  149. package/dist/astro/extra/dragDriver.d.ts +0 -20
  150. package/dist/astro/extra/driverFactories.d.ts +0 -12
  151. package/dist/astro/extra/eventDriver.d.ts +0 -9
  152. package/dist/astro/extra/exactState.d.ts +0 -1
  153. package/dist/astro/extra/hmr.d.ts +0 -17
  154. package/dist/astro/extra/logDriver.d.ts +0 -2
  155. package/dist/astro/extra/processDrag.d.ts +0 -19
  156. package/dist/astro/extra/processForm.d.ts +0 -15
  157. package/dist/astro/extra/run.d.ts +0 -13
  158. package/dist/astro/extra/xstreamCompat.d.ts +0 -5
  159. package/dist/astro/index.d.ts +0 -19
  160. package/dist/astro/index.esm.js +0 -27
  161. package/dist/astro/jsx-dev-runtime.d.ts +0 -1
  162. package/dist/astro/jsx-runtime.d.ts +0 -4
  163. package/dist/astro/jsx.d.ts +0 -2
  164. package/dist/astro/pragma/fn.d.ts +0 -7
  165. package/dist/astro/pragma/index.d.ts +0 -7
  166. package/dist/astro/pragma/is.d.ts +0 -10
  167. package/dist/astro/server.d.ts +0 -12
  168. package/dist/astro/server.esm.js +0 -25
  169. package/dist/astro/switchable.d.ts +0 -7
  170. package/dist/collection.d.ts +0 -12
  171. package/dist/component.d.ts +0 -22
  172. package/dist/cycle/dom/BodyDOMSource.d.ts +0 -10
  173. package/dist/cycle/dom/DOMSource.d.ts +0 -11
  174. package/dist/cycle/dom/DocumentDOMSource.d.ts +0 -12
  175. package/dist/cycle/dom/ElementFinder.d.ts +0 -8
  176. package/dist/cycle/dom/EventDelegator.d.ts +0 -34
  177. package/dist/cycle/dom/IsolateModule.d.ts +0 -23
  178. package/dist/cycle/dom/MainDOMSource.d.ts +0 -32
  179. package/dist/cycle/dom/PriorityQueue.d.ts +0 -7
  180. package/dist/cycle/dom/ScopeChecker.d.ts +0 -9
  181. package/dist/cycle/dom/SymbolTree.d.ts +0 -9
  182. package/dist/cycle/dom/VNodeWrapper.d.ts +0 -8
  183. package/dist/cycle/dom/enrichEventStream.d.ts +0 -24
  184. package/dist/cycle/dom/fromEvent.d.ts +0 -6
  185. package/dist/cycle/dom/index.d.ts +0 -8
  186. package/dist/cycle/dom/isolate.d.ts +0 -9
  187. package/dist/cycle/dom/makeDOMDriver.d.ts +0 -11
  188. package/dist/cycle/dom/mockDOMSource.d.ts +0 -17
  189. package/dist/cycle/dom/modules.d.ts +0 -5
  190. package/dist/cycle/dom/snabbdom.d.ts +0 -22
  191. package/dist/cycle/dom/styleModule.d.ts +0 -13
  192. package/dist/cycle/dom/thunk.d.ts +0 -11
  193. package/dist/cycle/dom/utils.d.ts +0 -8
  194. package/dist/cycle/isolate/index.d.ts +0 -42
  195. package/dist/cycle/run/adapt.d.ts +0 -6
  196. package/dist/cycle/run/index.d.ts +0 -36
  197. package/dist/cycle/run/internals.d.ts +0 -8
  198. package/dist/cycle/run/types.d.ts +0 -49
  199. package/dist/cycle/state/Collection.d.ts +0 -29
  200. package/dist/cycle/state/StateSource.d.ts +0 -20
  201. package/dist/cycle/state/index.d.ts +0 -5
  202. package/dist/cycle/state/pickCombine.d.ts +0 -3
  203. package/dist/cycle/state/pickMerge.d.ts +0 -3
  204. package/dist/cycle/state/types.d.ts +0 -18
  205. package/dist/cycle/state/withState.d.ts +0 -17
  206. package/dist/extra/classes.d.ts +0 -7
  207. package/dist/extra/devtools.d.ts +0 -78
  208. package/dist/extra/dragDriver.d.ts +0 -20
  209. package/dist/extra/driverFactories.d.ts +0 -12
  210. package/dist/extra/eventDriver.d.ts +0 -9
  211. package/dist/extra/exactState.d.ts +0 -1
  212. package/dist/extra/hmr.d.ts +0 -17
  213. package/dist/extra/logDriver.d.ts +0 -2
  214. package/dist/extra/processDrag.d.ts +0 -19
  215. package/dist/extra/processForm.d.ts +0 -15
  216. package/dist/extra/run.d.ts +0 -13
  217. package/dist/extra/xstreamCompat.d.ts +0 -5
  218. package/dist/jsx-dev-runtime.d.ts +0 -1
  219. package/dist/jsx-dev-runtime.js +0 -224
  220. package/dist/jsx-runtime.d.ts +0 -4
  221. package/dist/jsx-runtime.js +0 -224
  222. package/dist/jsx.d.ts +0 -2
  223. package/dist/pragma/fn.d.ts +0 -7
  224. package/dist/pragma/index.d.ts +0 -7
  225. package/dist/pragma/is.d.ts +0 -10
  226. package/dist/switchable.d.ts +0 -7
package/README.md CHANGED
@@ -26,7 +26,7 @@ cd my-app
26
26
  npm run dev
27
27
  ```
28
28
 
29
- Choose from Vite (SPA), Vite + PWA, Vike (SSR), or Astro templates in JavaScript or TypeScript.
29
+ Choose from Vite (SPA), Vite + PWA, Vike (SSR), or Astro templates in JavaScript or TypeScript. Without prompts (scripts, CI, coding agents): `npm create sygnal-app@latest my-app -- --template vite --js --install`.
30
30
 
31
31
  **Or add to an existing project:**
32
32
 
@@ -73,6 +73,20 @@ run(Counter)
73
73
 
74
74
  No store setup, no providers, no hooks — just a function and some properties.
75
75
 
76
+ ## Built for Agents
77
+
78
+ Sygnal includes tooling so that coding agents (and people) can write and debug Sygnal code without guessing:
79
+
80
+ - **[`llms.txt`](https://sygnal.js.org/llms.txt)**: one compact reference of the API in its canonical forms, written for language models.
81
+ - **Diagnostics**: silent wiring mistakes (a selector that matches nothing, an action with no model entry, an EVENTS type nobody selects) are reported as coded messages, such as `[Sygnal SYG104]`, with a fix and a link to the [error reference](https://sygnal.js.org/reference/errors/). They're on automatically in the Vite dev server and in tests, and add nothing to production bundles.
82
+ - **[`sygnal-check`](./sygnal-check)**: a static checker for the same mistakes, with a strict mode for the canonical forms, `--fix`, an app graph (`--graph`) and `explain <code>`.
83
+ - **MCP server**: `sygnal-check mcp` exposes `check`, `graph` and `explain` as tools (`claude mcp add sygnal-check -- npx --no-install sygnal-check mcp`).
84
+ - **`inspect()`**: a machine-readable graph of the running app, in the browser or from `renderComponent()` in a test.
85
+
86
+ The repository also contains an evaluation harness ([`evals/agent-ergonomics`](./evals/agent-ergonomics)) that runs coding agents on the same tasks in a Sygnal app and an equivalent React app, scores each run with hidden acceptance tests, and records time and iteration counts. The baseline results, from before this tooling existed, are in [`results/BASELINE.md`](./evals/agent-ergonomics/results/BASELINE.md).
87
+
88
+ See [Building with AI Agents](https://sygnal.js.org/integration/agents/).
89
+
76
90
  ## Features
77
91
 
78
92
  ### Collections
@@ -113,12 +127,12 @@ Structured message passing between components:
113
127
  ```jsx
114
128
  // Child emits
115
129
  TaskCard.model = {
116
- DELETE: { PARENT: (state) => ({ type: 'DELETE', taskId: state.id }) }
130
+ DELETE: { PARENT: (state) => ({ taskId: state.id }) }
117
131
  }
118
132
 
119
- // Parent receives (use component reference — minification-safe)
133
+ // Parent receives (pass the component itself)
120
134
  Lane.intent = ({ CHILD }) => ({
121
- TASK_DELETED: CHILD.select(TaskCard).filter(e => e.type === 'DELETE'),
135
+ TASK_DELETED: CHILD.select(TaskCard).map(e => e.taskId),
122
136
  })
123
137
  ```
124
138
 
@@ -127,14 +141,16 @@ Lane.intent = ({ CHILD }) => ({
127
141
  Global broadcast for cross-component communication:
128
142
 
129
143
  ```jsx
144
+ import { event } from 'sygnal'
145
+
130
146
  // Any component can emit
131
147
  Publisher.model = {
132
- NOTIFY: { EVENTS: (state) => ({ type: 'notification', data: state.message }) }
148
+ NOTIFY: { EVENTS: event('NOTIFICATION', (state) => state.message) }
133
149
  }
134
150
 
135
151
  // Any component can subscribe
136
152
  Subscriber.intent = ({ EVENTS }) => ({
137
- HANDLE: EVENTS.select('notification'),
153
+ HANDLE: EVENTS.select('NOTIFICATION'),
138
154
  })
139
155
  ```
140
156
 
@@ -258,8 +274,10 @@ Access DOM elements declaratively:
258
274
 
259
275
  ```jsx
260
276
  const inputRef = createRef()
261
- <input ref={inputRef} />
262
- // inputRef.current.focus()
277
+
278
+ function Search({ state }) {
279
+ return <input ref={inputRef} /> // inputRef.current is the element once mounted
280
+ }
263
281
  ```
264
282
 
265
283
  ### Commands
@@ -270,10 +288,14 @@ Send imperative commands from parent to child:
270
288
  import { createCommand } from 'sygnal'
271
289
 
272
290
  const playerCmd = createCommand()
273
- <VideoPlayer commands={playerCmd} />
274
291
 
275
- // Parent sends commands with optional data
276
- playerCmd.send('seek', { time: 30 })
292
+ // Parent passes the command as a prop and sends commands with optional data
293
+ function App({ state }) {
294
+ return <VideoPlayer commands={playerCmd} />
295
+ }
296
+ App.model = {
297
+ SEEK: { EFFECT: () => playerCmd.send('seek', { time: 30 }) },
298
+ }
277
299
 
278
300
  // Child receives via commands$ source
279
301
  VideoPlayer.intent = ({ commands$ }) => ({
@@ -283,7 +305,7 @@ VideoPlayer.intent = ({ commands$ }) => ({
283
305
 
284
306
  ### Effect Handlers
285
307
 
286
- Run side effects without state changes — no more `ABORT` workarounds:
308
+ Run side effects without state changes:
287
309
 
288
310
  ```jsx
289
311
  App.model = {
@@ -299,18 +321,6 @@ App.model = {
299
321
  }
300
322
  ```
301
323
 
302
- ### Model Shorthand
303
-
304
- Compact syntax for single-driver model entries:
305
-
306
- ```jsx
307
- App.model = {
308
- 'SEND_CMD | EFFECT': () => playerCmd.send('play'),
309
- 'NOTIFY | EVENTS': (state) => ({ type: 'alert', data: state.message }),
310
- 'DELETE | PARENT': (state) => ({ type: 'DELETE', id: state.id }),
311
- }
312
- ```
313
-
314
324
  ### Disposal Hooks
315
325
 
316
326
  Cleanup on unmount with the built-in `DISPOSE` action:
@@ -346,15 +356,16 @@ App.intent = ({ DOM, SW }) => ({
346
356
 
347
357
  ### Testing
348
358
 
349
- Test components in isolation with `renderComponent`:
359
+ Test components in isolation with `renderComponent`, driving them with DOM events:
350
360
 
351
361
  ```jsx
352
362
  import { renderComponent } from 'sygnal'
353
363
 
354
364
  const t = renderComponent(Counter, { initialState: { count: 0 } })
355
365
 
356
- t.simulateAction('INCREMENT')
357
- await t.waitForState(s => s.count === 1)
366
+ t.simulateEvent('.increment', 'click')
367
+ await t.next(s => s.count === 1)
368
+ t.expectNoDiagnostics()
358
369
 
359
370
  t.dispose()
360
371
  ```
@@ -374,7 +385,7 @@ const html = renderToString(App, {
374
385
 
375
386
  ### Vite Plugin
376
387
 
377
- Auto-configures JSX and HMR with state preservation:
388
+ Auto-configures JSX, HMR with state preservation, and dev-only diagnostics:
378
389
 
379
390
  ```javascript
380
391
  // vite.config.js
@@ -430,27 +441,31 @@ Pages are standard Sygnal components in `pages/*/+Page.jsx`. Supports layouts, d
430
441
  Full type definitions included:
431
442
 
432
443
  ```tsx
433
- import type { RootComponent } from 'sygnal'
444
+ import type { RootComponent, IntentSources, ActionsOf } from 'sygnal'
434
445
 
435
446
  type State = { count: number }
436
- type Actions = { INCREMENT: null }
437
447
 
438
- const App: RootComponent<State, {}, Actions> = ({ state }) => (
439
- <div>{state.count}</div>
448
+ const intent = ({ DOM }: IntentSources<State>) => ({
449
+ INCREMENT: DOM.click('.inc'),
450
+ })
451
+
452
+ const App: RootComponent<State, {}, ActionsOf<typeof intent>> = ({ state }) => (
453
+ <button className="inc">{state.count}</button>
440
454
  )
455
+ App.intent = intent
456
+ App.model = { INCREMENT: (state) => ({ ...state, count: state.count + 1 }) }
441
457
  ```
442
458
 
459
+ Typed actions from the intent, a typed EVENTS registry, typed `CHILD.select()` payloads and type-checked Collection `from`.
460
+
443
461
  ## Bundler Setup
444
462
 
445
- **Vite** (recommended):
463
+ **Vite** (recommended): use the plugin above (`plugins: [sygnal()]`). Without it, configure the automatic JSX runtime yourself:
446
464
 
447
465
  ```javascript
448
- // vite.config.js
466
+ // vite.config.js (Vite 8; under Vite 7 use esbuild: { jsx: 'automatic', jsxImportSource: 'sygnal' })
449
467
  export default defineConfig({
450
- esbuild: {
451
- jsx: 'automatic',
452
- jsxImportSource: 'sygnal',
453
- },
468
+ oxc: { jsx: { runtime: 'automatic', importSource: 'sygnal' } },
454
469
  })
455
470
  ```
456
471