sygnal 6.4.0 → 6.6.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 (65) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/astro/index.cjs.js +398 -25
  3. package/dist/astro/index.cjs.js.map +1 -1
  4. package/dist/astro/index.mjs +398 -25
  5. package/dist/astro/index.mjs.map +1 -1
  6. package/dist/astro/server.cjs.js +3 -2
  7. package/dist/astro/server.cjs.js.map +1 -1
  8. package/dist/astro/server.mjs +3 -2
  9. package/dist/astro/server.mjs.map +1 -1
  10. package/dist/devtools.cjs.js +141 -3
  11. package/dist/devtools.cjs.js.map +1 -1
  12. package/dist/devtools.esm.js +141 -4
  13. package/dist/devtools.esm.js.map +1 -1
  14. package/dist/diagnostics.cjs.js +140 -21
  15. package/dist/diagnostics.cjs.js.map +1 -1
  16. package/dist/diagnostics.esm.js +140 -21
  17. package/dist/diagnostics.esm.js.map +1 -1
  18. package/dist/index.cjs.js +54 -24
  19. package/dist/index.cjs.js.map +1 -1
  20. package/dist/index.d.ts +139 -16
  21. package/dist/index.esm.js +54 -24
  22. package/dist/index.esm.js.map +1 -1
  23. package/dist/sygnal.min.js +1 -1
  24. package/dist/sygnal.min.js.map +1 -1
  25. package/dist/vike/config/package.json +1 -1
  26. package/dist/vike/onRenderClient.cjs.js +63 -43
  27. package/dist/vike/onRenderClient.cjs.js.map +1 -1
  28. package/dist/vike/onRenderClient.mjs +63 -43
  29. package/dist/vike/onRenderClient.mjs.map +1 -1
  30. package/dist/vike/onRenderHtml.cjs.js +21 -25
  31. package/dist/vike/onRenderHtml.cjs.js.map +1 -1
  32. package/dist/vike/onRenderHtml.mjs +21 -25
  33. package/dist/vike/onRenderHtml.mjs.map +1 -1
  34. package/dist/vite/plugin.cjs.js +398 -25
  35. package/dist/vite/plugin.cjs.js.map +1 -1
  36. package/dist/vite/plugin.mjs +398 -25
  37. package/dist/vite/plugin.mjs.map +1 -1
  38. package/llms.txt +3 -3
  39. package/package.json +1 -1
  40. package/src/core/cell.ts +25 -7
  41. package/src/core/hooks.ts +6 -0
  42. package/src/core/hosts/collection.ts +6 -11
  43. package/src/core/hosts/switchable.ts +2 -2
  44. package/src/core/instance.ts +2 -2
  45. package/src/core/view.ts +2 -0
  46. package/src/cycle/dom/utils.ts +4 -2
  47. package/src/devtools.d.ts +13 -0
  48. package/src/devtools.ts +3 -0
  49. package/src/extra/devGraph.ts +111 -0
  50. package/src/extra/devMcp.ts +1 -1
  51. package/src/extra/devtools.ts +18 -0
  52. package/src/extra/diagnostics/checks/collections.ts +31 -25
  53. package/src/extra/diagnostics/checks/index.ts +1 -1
  54. package/src/extra/diagnostics/checks/inspect.ts +68 -6
  55. package/src/extra/diagnostics/checks/next.ts +22 -0
  56. package/src/extra/diagnostics/checks/public.d.ts +121 -12
  57. package/src/extra/diagnostics/codes.ts +10 -0
  58. package/src/index.d.ts +19 -3
  59. package/src/vike/onRenderClient.ts +44 -46
  60. package/src/vike/onRenderHtml.ts +5 -26
  61. package/src/vike/shell.ts +33 -0
  62. package/src/vite/graph.ts +247 -0
  63. package/src/vite/mcp.ts +3 -3
  64. package/src/vite/plugin.d.ts +12 -0
  65. package/src/vite/plugin.ts +136 -22
package/dist/index.d.ts CHANGED
@@ -2041,9 +2041,23 @@ type DiagnosticSeverity$1 = 'error' | 'warn' | 'info'
2041
2041
 
2042
2042
  /** How an action is dispatched. */
2043
2043
  /** 'agent' (static, PLAN-6 K-1): only the component's `agent` declaration dispatches it */
2044
- type InspectActionTrigger = 'intent' | 'next' | 'reply' | 'builtin' | 'agent' | 'unknown'
2044
+ /**
2045
+ * 'behavior' (static, PLAN-10 A-8): a `uses` entry's action nothing else triggers that the behavior
2046
+ * may dispatch itself where the checker can't list it (a package behavior, an open model, ...)
2047
+ */
2048
+ type InspectActionTrigger = 'intent' | 'next' | 'reply' | 'builtin' | 'agent' | 'behavior' | 'unknown'
2049
+
2050
+ /**
2051
+ * PLAN-10 A-4 (static only): a source position, 1-based. `file` (relative to the working
2052
+ * directory) only when it isn't the component's file.
2053
+ */
2054
+ interface InspectLocation {
2055
+ line: number
2056
+ column: number
2057
+ file?: string
2058
+ }
2045
2059
 
2046
- interface InspectAction {
2060
+ interface InspectAction extends Partial<InspectLocation> {
2047
2061
  name: string
2048
2062
  /**
2049
2063
  * 'intent': returned by the component's intent. 'builtin': BOOTSTRAP,
@@ -2057,18 +2071,56 @@ interface InspectAction {
2057
2071
  trigger: InspectActionTrigger
2058
2072
  /** sinks of the model entry (STATE, EVENTS, EFFECT, PARENT, custom drivers); [] without a model entry */
2059
2073
  sinks: string[]
2074
+ /** the `uses` key of the behavior that owns it ('pager' for 'pager.NEXT') */
2075
+ behavior?: string
2076
+ /** static, PLAN-10 A-4: the model entry (line/column on the action: the intent property, else this) */
2077
+ modelAt?: InspectLocation
2078
+ /**
2079
+ * static, PLAN-10 A-7 (actions with a STATE sink only): the top-level state keys the STATE
2080
+ * reducer(s) may write (a behavior's: its slice); [] when it never changes state; null when unknown
2081
+ */
2082
+ writes?: string[] | null
2083
+ /** static, PLAN-10 A-7: a STATE reducer may return undefined (removes a Collection item) */
2084
+ removes?: true
2060
2085
  }
2061
2086
 
2062
- interface InspectChild {
2087
+ interface InspectChild extends Partial<InspectLocation> {
2063
2088
  name: string
2064
- via: 'tag' | 'collection' | 'switchable' | 'slot'
2089
+ /**
2090
+ * 'layout' (static, PLAN-10 A-9): Vike's shell, a +Wrapper / +Layout rendering the next +Layout in
2091
+ * or a +Page it applies to (Wrapper(s) > Layout(s) > Page); no location (no JSX site)
2092
+ */
2093
+ via: 'tag' | 'collection' | 'switchable' | 'slot' | 'layout'
2065
2094
  /** Collection: the `from` state field, when known */
2066
2095
  from?: string | null
2067
2096
  /** runtime: number of live instances behind this entry (e.g. Collection items) */
2068
2097
  count?: number
2098
+ /** runtime, PLAN-10 D522: the ids of those instances */
2099
+ ids?: string[]
2100
+ /**
2101
+ * static, PLAN-10 A-3: the id of the component it renders (resolved through the import); null when
2102
+ * it isn't in the graph (a package, a widget, a file not scanned, a dynamic value)
2103
+ */
2104
+ id?: string | null
2105
+ /** static, PLAN-10 A-1: a literal `state` lens (`<Greeting state="host" />`) */
2106
+ state?: string
2107
+ /** static, PLAN-10 A-2: the package the tag is imported from ('sygnal/ui') */
2108
+ external?: string
2109
+ /** static, PLAN-10 A-2: a widget tag (defineWidget, fromZag, fromReact, the sygnal/ui Zag parts) */
2110
+ widget?: true
2111
+ }
2112
+
2113
+ /** PLAN-10 A-5 (static): a CHILD.select(Child) call in an intent */
2114
+ interface InspectChildSelect extends InspectLocation {
2115
+ /** the selected component's name as written */
2116
+ child: string | null
2117
+ /** its id; null when it isn't in the graph */
2118
+ id: string | null
2119
+ /** the intent actions whose stream contains the call (the receivers of the child's PARENT sink) */
2120
+ actions: string[]
2069
2121
  }
2070
2122
 
2071
- interface InspectSelector {
2123
+ interface InspectSelector extends Partial<InspectLocation> {
2072
2124
  /** CSS selector passed to DOM.select() (chained selects joined with a space) */
2073
2125
  selector: string
2074
2126
  /** event types listened to; null when unknown (runtime, real DOM) */
@@ -2084,10 +2136,12 @@ interface InspectSelector {
2084
2136
  isolationHit: string | null
2085
2137
  /** PLAN-4 CT-1: the control this selector is (its key), when it is `[data-control="<Key>"]` */
2086
2138
  control?: string
2139
+ /** the `uses` key of the behavior that listens to it */
2140
+ behavior?: string
2087
2141
  }
2088
2142
 
2089
2143
  /** PLAN-4 CT-1: a control (controls()) a component renders */
2090
- interface InspectControl {
2144
+ interface InspectControl extends Partial<InspectLocation> {
2091
2145
  /** the control's key (rendered as data-control="<name>") */
2092
2146
  name: string
2093
2147
  /** the intrinsic tag of a tag spec; null for a spec object */
@@ -2102,10 +2156,14 @@ interface InspectDiagnostic {
2102
2156
  code: string
2103
2157
  severity: DiagnosticSeverity$1
2104
2158
  component?: string
2159
+ /** static, PLAN-10 A-3: the id of the component it is attached to */
2160
+ componentId?: string
2105
2161
  message: string
2106
2162
  fix?: string
2107
2163
  docsUrl?: string
2108
2164
  data?: any
2165
+ /** runtime only: when it was reported (ms since the epoch; each is reported once per process) */
2166
+ timestamp?: number
2109
2167
  /** static only */
2110
2168
  file?: string
2111
2169
  line?: number
@@ -2160,6 +2218,12 @@ interface InspectComponent {
2160
2218
  name: string
2161
2219
  /** runtime: instance number (as a string); static: 'file:line' of the definition */
2162
2220
  id: string
2221
+ /**
2222
+ * static, PLAN-10 D521: 'file#name', stable when lines move (hosts key selection and positions by it);
2223
+ * a second component of the same name in one file gets 'file#name#2', and so on. Runtime (PLAN-10 P-2,
2224
+ * D544): the same key when sygnal/vite's dev server stamped the component function, else absent
2225
+ */
2226
+ key?: string
2163
2227
  /** runtime: the parent instance's id; static: null (see the parents' `children`) */
2164
2228
  parentId: string | null
2165
2229
  /** static only: source file, relative to the working directory */
@@ -2169,6 +2233,32 @@ interface InspectComponent {
2169
2233
  * component renders it, else how it is first rendered
2170
2234
  */
2171
2235
  kind: 'root' | 'child' | 'collection-item' | 'switchable'
2236
+ /** PLAN-10 A-1 / D522: rendered as a component (or started as an entry) but has no statics */
2237
+ viewOnly?: true
2238
+ /**
2239
+ * static, PLAN-10 A-6: started by run(), defineElement() or a Vike +Page / +Layout / +Wrapper; 'unknown' on the
2240
+ * other roots when an entry call's component can't be resolved (picked at run time).
2241
+ * runtime (D522): true on an app's root instance
2242
+ */
2243
+ entry?: true | 'unknown'
2244
+ /**
2245
+ * static, Vike only (PLAN-10 A-9): on a +Page's component its route ('/orders/@id': from the
2246
+ * filesystem, or the literal string a +route file / the config's `route` sets); null for a Route
2247
+ * Function or a route the checker can't read (with `routeDynamic`) and for _error/+Page. On a
2248
+ * +Layout's / +Wrapper's: the URL prefix of the directory it applies to
2249
+ */
2250
+ route?: string | null
2251
+ /**
2252
+ * static, Vike only (PLAN-10 A-9): every route of a component several +Page files export (`route` is
2253
+ * the first, in path order; null for a dynamic one or the error page); omitted otherwise
2254
+ */
2255
+ routes?: (string | null)[]
2256
+ /** static, Vike only (PLAN-10 A-9): the route is a Route Function or can't be read (route: null) */
2257
+ routeDynamic?: true
2258
+ /** runtime, PLAN-10 D522: the app (run()) it belongs to: its root's index among the live roots, oldest first */
2259
+ app?: number
2260
+ /** runtime, PLAN-10 D522: false on a hidden Switchable page and below it; omitted when shown */
2261
+ shown?: false
2172
2262
  actions: InspectAction[]
2173
2263
  /** state keys (runtime: current state; static: initialState) */
2174
2264
  stateKeys: string[]
@@ -2176,14 +2266,27 @@ interface InspectComponent {
2176
2266
  calculated: string[]
2177
2267
  /** context fields this component provides (Component.context) */
2178
2268
  contextProvides: string[]
2179
- /** context fields its view reads (static only; null at runtime) */
2269
+ /** context fields its view reads (static: the view source; runtime, D530: what its latest render read) */
2180
2270
  contextConsumes?: string[] | null
2271
+ /**
2272
+ * static, PLAN-10 A-7: top-level state keys the view (and its child lenses, calculated and
2273
+ * context functions) reads literally; omitted when none
2274
+ */
2275
+ stateReads?: string[]
2276
+ /** static, PLAN-10 A-7: stateReads may be incomplete (the state used whole somewhere) */
2277
+ stateReadsPartial?: true
2181
2278
  /** EVENTS types this component emits */
2182
2279
  eventsEmitted: string[]
2183
2280
  /** EVENTS types this component selects ('*' = EVENTS.select() without a type) */
2184
2281
  eventsSelected: string[]
2185
2282
  children: InspectChild[]
2186
2283
  selectors: InspectSelector[]
2284
+ /** static, PLAN-10 A-4: where the `context` static's entries are */
2285
+ contextEntries?: Array<InspectLocation & { name: string }>
2286
+ /** static, PLAN-10 A-4: the EVENTS emit and select sites of its intent and model */
2287
+ eventSites?: Array<InspectLocation & { type: string; role: 'emit' | 'select' }>
2288
+ /** static, PLAN-10 A-5: CHILD.select(Child) in its intent */
2289
+ childSelects?: InspectChildSelect[]
2187
2290
  /** PLAN-4 CT-1: the controls it renders (runtime: seen in its renders); omitted when none */
2188
2291
  controls?: InspectControl[]
2189
2292
  /** static only, PLAN-4 GS-2 (G-224): the element commands (ELEMENT sink) its model sends; omitted when none */
@@ -2198,7 +2301,7 @@ interface InspectComponent {
2198
2301
  }
2199
2302
 
2200
2303
  /** PLAN-4 GS-2: an element command a model entry sends (static inspect, sygnal-check --graph) */
2201
- interface InspectCommand {
2304
+ interface InspectCommand extends Partial<InspectLocation> {
2202
2305
  /** the model entry that sends it */
2203
2306
  action: string
2204
2307
  /** the command's method (its first key) */
@@ -2220,13 +2323,15 @@ interface InspectAgent {
2220
2323
  description: string | null
2221
2324
  /** the declaration has a read projection */
2222
2325
  read: boolean
2223
- actions: Array<{ name: string; consequential: boolean; input: boolean }>
2326
+ actions: Array<{ name: string; consequential: boolean; input: boolean } & Partial<InspectLocation>>
2327
+ /** the read-only `agent.queries` tools; omitted when none */
2328
+ queries?: Array<{ name: string; input: boolean } & Partial<InspectLocation>>
2224
2329
  /** spreads: what is listed may be incomplete */
2225
2330
  partial?: true
2226
2331
  }
2227
2332
 
2228
2333
  /** PLAN-4 GS-7: a literal timer spec of a `timers` static (static inspect, sygnal-check --graph) */
2229
- interface InspectTimer {
2334
+ interface InspectTimer extends Partial<InspectLocation> {
2230
2335
  name: string
2231
2336
  every?: number | null
2232
2337
  after?: number | null
@@ -2261,8 +2366,12 @@ interface InspectGraph {
2261
2366
  /** which implementation produced the graph */
2262
2367
  source?: 'runtime' | 'static'
2263
2368
  components: InspectComponent[]
2264
- /** EVENTS bus: type -> names of the components that emit / select it */
2265
- events: Record<string, { emitters: string[]; selectors: string[] }>
2369
+ /**
2370
+ * EVENTS bus: type -> names of the components that emit / select it (each name once); emitterIds /
2371
+ * selectorIds (PLAN-10 A-3, D522, D528): the id of every such component (static) or instance
2372
+ * (runtime), not parallel to the names
2373
+ */
2374
+ events: Record<string, { emitters: string[]; selectors: string[]; emitterIds?: string[]; selectorIds?: string[] }>
2266
2375
  /** diagnostics not tied to a listed component */
2267
2376
  diagnostics: InspectDiagnostic[]
2268
2377
  /** runtime, PLAN-3 5-3: makeFetchDriver cache entries, by sink name (empty when no cache) */
@@ -2398,7 +2507,9 @@ type ViewProps<STATE = any, PROPS = {}, CONTEXT = {}> =
2398
2507
 
2399
2508
  /**
2400
2509
  * The `state` prop a parent passes to a sub-component in JSX: the name of a field of the
2401
- * parent's state (`state="editor"`) or a lens. Without it the child shares the parent's state.
2510
+ * parent's state (`state="editor"`), a path to nested state (`state="settings.rules"`,
2511
+ * `state="boards[0].title"`; since 6.5.0: a write copies only the levels on the path), or a
2512
+ * lens. Without it the child shares the parent's state.
2402
2513
  */
2403
2514
  type StateProp = string | Lense<any, any>
2404
2515
 
@@ -3913,13 +4024,25 @@ type ArrayKeysOf<STATE> = {
3913
4024
  [KEY in keyof STATE]-?: NonNullable<STATE[KEY]> extends ReadonlyArray<any> ? KEY : never
3914
4025
  }[keyof STATE] & string
3915
4026
 
4027
+ /**
4028
+ * Array-valued keys of STATE and dotted paths to arrays in its nested objects, up to three levels
4029
+ * (`'tasks' | 'board.cards'`; since 6.5.0). Paths through array positions (`'boards.0.cards'`)
4030
+ * aren't listed: for a list item, use `byId`.
4031
+ */
4032
+ type ArrayPathsOf<STATE, DEPTH extends unknown[] = []> = DEPTH['length'] extends 3 ? never : {
4033
+ [KEY in keyof STATE & string]-?: NonNullable<STATE[KEY]> extends ReadonlyArray<any> ? KEY
4034
+ : NonNullable<STATE[KEY]> extends Record<string, any> ? `${KEY}.${ArrayPathsOf<NonNullable<STATE[KEY]>, [...DEPTH, 1]>}`
4035
+ : never
4036
+ }[keyof STATE & string]
4037
+
3916
4038
  /**
3917
4039
  * Valid `from` values for a Collection: any string or Lense while the parent STATE is unknown
3918
- * (`any`); otherwise an array-valued key of STATE or a Lense over STATE.
4040
+ * (`any`); otherwise an array-valued key of STATE, a dotted path to one (`'board.cards'`), or a
4041
+ * Lense over STATE.
3919
4042
  */
3920
4043
  type CollectionFrom<STATE = any> = 0 extends (1 & STATE)
3921
4044
  ? string | Lense
3922
- : ArrayKeysOf<STATE> | Lense<STATE, any>
4045
+ : ArrayPathsOf<STATE> | Lense<STATE, any>
3923
4046
 
3924
4047
  /**
3925
4048
  * Collection props. Pass the parent component's state type as STATE to type-check `from`:
@@ -6084,4 +6207,4 @@ declare global {
6084
6207
  */
6085
6208
  declare function byId<T = any, S = any>(field: string, id: unknown, idKey?: string): { get(state: S): T | undefined; set(state: S, value: T): S }
6086
6209
 
6087
- export { ABORT, type ActionCause, type ActionsOf, type ActiveTimer, type AgentAction, type AgentConfirm, type AgentConfirmInfo, type AgentDeclaration, type AgentIssue, type AgentQuery, type AgentQueryResult, type AgentResult, type AgentSchema, type AgentTool, type AgentToolSet, type AgentToolsOptions, type AguiOptions, type AnswerPick, type AnswerPicks, type AnthropicMessagesOptions, type AnyComponentModule, type AnyControl, type AppErrorHook, type AppErrorInfo, type AppErrorPhase, type ArrayKeysOf, type AsyncDriverError, type AsyncDriverFromFunction, type AsyncRequest, type Behavior, type BehaviorDefinition, type BehaviorFactory, type BehaviorHandler, type BehaviorModelEntry, type BehaviorProps, type BehaviorSources, type BehaviorState, type BehaviorTarget, type BrowserCommand, type BrowserFake, type BrowserFakeOptions, type BrowserIntersection, type BrowserPosition, type BrowserResize, type BrowserSource, type BrowserSources, type BrowserSpec, type Catalog, type CatalogContainer, type CatalogContainerDecl, type CatalogDecl, type CatalogOption, type CatalogParam, type CatalogParamValue, type CatalogParamsOf, type CatalogPart, type CatalogPartDecl, type CatalogRecord, type CatalogTree, type CatalogTreeNode, type ChatAbort, type ChatActions, type ChatAskOptions, type ChatCall, type ChatCard, type ChatCardStatus, type ChatClientTool, type ChatCompletionsOptions, type ChatDelta, type ChatDone, type ChatDriverOptions, type ChatError, type ChatEvent, type ChatOk, type ChatOptions, type ChatOutputOf, type ChatOutputSchema, type ChatRequest, type ChatSource, type ChatState, type ChatStatus, type ChatTool, type ChatToolCall, type ChatToolPart, type ChatTransport, type ChatUsage, type ChromePromptOptions, type ChromePromptStatus, type ChromePromptTransport, type ClassesType, Collection, type CollectionFrom, type CollectionProps, type Command, type CommandBarActions, type CommandBarOptions, type CommandBarResult, type CommandBarState, type CommandBarStatus, type CommandBarUnsure, type CommandSource, type Component, type ComposeActions, type ComposeAnswer, type ComposeBackend, type ComposeNames, type ComposeOptions, type ComposeRenderOptions, type ComposeRenderable, type ComposeState, type ComposeStatus, type ComposeTree, Composed, type ComposedProps, type Connections, type ContainerView, type Control, type ControlCommonProps, type ControlDOMSource, type ControlElementOf, type ControlEvent, type ControlH, type ControlPropsOf, type ControlSpec, type ControlSpecObject, type ControlsOf, type ConvertedSchema, type CycleDOMEvent, type CycleDriver, type DOMDriverOptions, type DOMEventShorthand, type DOMEventShorthands, type DOMSource, type DefaultDrivers, type DefineComponentOptions, type DevToolsActionCause, type DevToolsCopyAsTestOptions, type DevToolsSessionRecording, type Diagnostic, type DiagnosticCode, type DiagnosticSeverity, type DiagnosticsMode, type DiagnosticsOptions, type DragDriverCategory, type DragDriverRegistration, type DragDriverSource, type DragSource, type DragStartPayload, type DriverFactories, type DriverFromAsyncOptions, type DriverSpec, type DriverSpecs, type DropPayload, type ElementCommand, type ElementCommandRegistry, type ElementCommands, type ElementProps, type ElementTarget, type EmittedEvent, type EnrichedEventStream, type Event$1 as Event, type EventName, type EventPayload, type EventPayloadFunction, type EventSink, type EventsFnOptions, type EventsSource, type ExactShape, type ExplainedAction, type ExposeWebMcpOptions, type FakeCacheEntry, type FakeChatChunk, type FakeConnection, type FakeConnectionTarget, type FakeReplyOptions, type FetchCacheOptions, type FetchDriverOptions, type FetchError, type FetchFailure, type FetchInit, type FetchInvalidate, type FetchRequest, type FetchResponse, type FetchRetry, type FetchSource, type FieldErrors, type Filter, type FixDrivers, type FormActions, type FormCalculated, type FormData, type FormField, type FormFieldCheck, type FormOptions, type FormSource, type FormState, type FormTool, type FormToolHandle, type FormToolResult, type FromAISDKOptions, type HeadValue, type HotModuleAPI, type HttpTransportOptions, type InspectAction, type InspectActionTrigger, type InspectChild, type InspectCommand, type InspectComponent, type InspectDiagnostic, type InspectFix, type InspectGraph, type InspectRecentAction, type InspectRelatedLocation, type InspectSelector, type InspectTextEdit, type InspectTimer, type InstallPrompt, type IntentSources, type IntrinsicControlProps, type JsonSchemaObject, type Layout, type LayoutNode, type LazyComponent, type LazyOptions, type Lens, type Lense, MainDOMSource, type McpAppDisplayMode, type McpAppDriverOptions, type McpAppError, type McpAppRequest, type McpAppSource, type McpContentBlock, type McpDownloadItem, type McpHostContext, type McpHostInfo, type McpLogLevel, type McpResourceContents, type McpSamplingRequest, type McpToolResult, type MockConfig, MockedDOMSource, type NonStateSinkReturns, type OpenResponsesEvent, type OpenResponsesOptions, type PagerActions, type PagerCalculated, type PagerOptions, type PagerState, type ParamNames, type ParentPayloadOf, type Persist, type PersistOptions, type PersistOptionsFor, type PersistStorage, type PersistedEntry, Portal, type PortalProps, type ProcessFormOptions, type QueryCache, type QueryCacheSnapshot, type QueryCacheSnapshotEntry, type Ref, type Ref$, type RegisteredEvent, type RenderOptions, type RenderResult, type RenderToStringOptions, type RenderableComponent, type ReplyRequest, type Resource, type ResourceRequest, type RootComponent, type Route, type RouteName, type RouteParamsArg, type RouteQuery, type Router, type RouterBlocked, type RouterCommand, type RouterOptions, type RouterSource, type RunOptions, type SchemaOutput, type ScrollToAlign, type SelectedDOMSource, type SelectionActions, type SelectionCalculated, type SelectionOptions, type SelectionState, type ServiceWorkerCommand, type ServiceWorkerOptions, type ServiceWorkerSource, type SimulatedEventInit, Slot, type SlotProps, type SocketActions, type SocketClose, type SocketConnection, type SocketDriverOptions, type SocketError, type SocketEvent, type SocketOpen, type SocketReconnect, type SocketRequest, type SocketSource, type SortFunction, type SortObject, type SortSpec, type SortableActions, type SortableDropped, type SortableOptions, type SortableState, type SseConnection, type StandardSchemaLike, type StateProp, type StrictDialect, type StrictSchemas, Suspense, type SuspenseProps, Switchable, type SwitchableProps, type SygnalApp, type SygnalBodyDOMSource, type SygnalDOMSource, type SygnalDevTools, type SygnalDocumentDOMSource, type SygnalEvents, type SygnalSinks, type TestAction, type Thunk, type ThunkData, type TimerAfter, type TimerFrame, type TimerSpec, type TimerTick, type Timers, Transition, type TransitionProps, type UIMessageStreamOptions, type UidFunction, type UndoBehaviorOptions, type UndoHistory, type UndoOptions, type UsesActions, type UsesState, type ViewProps, VirtualCollection, type VirtualCollectionProps, type WebMcpHandle, type Widget, type WidgetDefinition, type WidgetDispatch, type WidgetElementOf, type WidgetEmit, type WidgetHandle, type WidgetHostProps, type WithinTarget, abort, agentTools, agui, answers, anthropicMessages, askCard, byId, chat, chatCompletions, checkForm, choice, chromePrompt, classes, clearDiagnostics, clipboardSource, commandBar, compose, composeWith, controls, createCommand, createInstallPrompt, createRef, createRef$, decide, defineBehavior, defineCatalog, defineComponent, defineWidget, driverFromAsync, emit, enableHMR, encodeOpenResponses, event, exactState, experimentalExposeWebMcp, fieldName, fieldNames, focusInvalid, focusWithin, form, formErrors, formTool, fromAISDK, fromTree, geolocationSource, getDevTools, getDiagnostics, getField, hasField, intersectionSource, isSelected, jsonSchema, lazy, makeBrowserDriver, makeBrowserDriverWith, makeChatDriver, makeDOMDriver, makeDragDriver, makeFetchDriver, makeHeadDriver, makeMcpAppDriver, makeRouter, makeRouterDriver, makeServiceWorkerDriver, makeSocketDriver, makeTimerDriver, makeViewTransitionDOMDriver, mediaSource, messageText, mockDOMSource, noul, onDiagnostic, onlineSource, onlineStatus$, openResponses, openToolCalls, outputJsonSchema, pager, parseInput, persist, portal, processDrag, processForm, queryCache, removeNode, renderComponent, renderHead, renderToString, replyErrors, resizeSource, run, score, selection, set, setField, sortable, storageSource, strictSchemas, thunk, toJsonSchema, toTree, toggle, uiMessageStream, undo, undoable, visibilitySource, withToolResults, xs };
6210
+ export { ABORT, type ActionCause, type ActionsOf, type ActiveTimer, type AgentAction, type AgentConfirm, type AgentConfirmInfo, type AgentDeclaration, type AgentIssue, type AgentQuery, type AgentQueryResult, type AgentResult, type AgentSchema, type AgentTool, type AgentToolSet, type AgentToolsOptions, type AguiOptions, type AnswerPick, type AnswerPicks, type AnthropicMessagesOptions, type AnyComponentModule, type AnyControl, type AppErrorHook, type AppErrorInfo, type AppErrorPhase, type ArrayKeysOf, type ArrayPathsOf, type AsyncDriverError, type AsyncDriverFromFunction, type AsyncRequest, type Behavior, type BehaviorDefinition, type BehaviorFactory, type BehaviorHandler, type BehaviorModelEntry, type BehaviorProps, type BehaviorSources, type BehaviorState, type BehaviorTarget, type BrowserCommand, type BrowserFake, type BrowserFakeOptions, type BrowserIntersection, type BrowserPosition, type BrowserResize, type BrowserSource, type BrowserSources, type BrowserSpec, type Catalog, type CatalogContainer, type CatalogContainerDecl, type CatalogDecl, type CatalogOption, type CatalogParam, type CatalogParamValue, type CatalogParamsOf, type CatalogPart, type CatalogPartDecl, type CatalogRecord, type CatalogTree, type CatalogTreeNode, type ChatAbort, type ChatActions, type ChatAskOptions, type ChatCall, type ChatCard, type ChatCardStatus, type ChatClientTool, type ChatCompletionsOptions, type ChatDelta, type ChatDone, type ChatDriverOptions, type ChatError, type ChatEvent, type ChatOk, type ChatOptions, type ChatOutputOf, type ChatOutputSchema, type ChatRequest, type ChatSource, type ChatState, type ChatStatus, type ChatTool, type ChatToolCall, type ChatToolPart, type ChatTransport, type ChatUsage, type ChromePromptOptions, type ChromePromptStatus, type ChromePromptTransport, type ClassesType, Collection, type CollectionFrom, type CollectionProps, type Command, type CommandBarActions, type CommandBarOptions, type CommandBarResult, type CommandBarState, type CommandBarStatus, type CommandBarUnsure, type CommandSource, type Component, type ComposeActions, type ComposeAnswer, type ComposeBackend, type ComposeNames, type ComposeOptions, type ComposeRenderOptions, type ComposeRenderable, type ComposeState, type ComposeStatus, type ComposeTree, Composed, type ComposedProps, type Connections, type ContainerView, type Control, type ControlCommonProps, type ControlDOMSource, type ControlElementOf, type ControlEvent, type ControlH, type ControlPropsOf, type ControlSpec, type ControlSpecObject, type ControlsOf, type ConvertedSchema, type CycleDOMEvent, type CycleDriver, type DOMDriverOptions, type DOMEventShorthand, type DOMEventShorthands, type DOMSource, type DefaultDrivers, type DefineComponentOptions, type DevToolsActionCause, type DevToolsCopyAsTestOptions, type DevToolsSessionRecording, type Diagnostic, type DiagnosticCode, type DiagnosticSeverity, type DiagnosticsMode, type DiagnosticsOptions, type DragDriverCategory, type DragDriverRegistration, type DragDriverSource, type DragSource, type DragStartPayload, type DriverFactories, type DriverFromAsyncOptions, type DriverSpec, type DriverSpecs, type DropPayload, type ElementCommand, type ElementCommandRegistry, type ElementCommands, type ElementProps, type ElementTarget, type EmittedEvent, type EnrichedEventStream, type Event$1 as Event, type EventName, type EventPayload, type EventPayloadFunction, type EventSink, type EventsFnOptions, type EventsSource, type ExactShape, type ExplainedAction, type ExposeWebMcpOptions, type FakeCacheEntry, type FakeChatChunk, type FakeConnection, type FakeConnectionTarget, type FakeReplyOptions, type FetchCacheOptions, type FetchDriverOptions, type FetchError, type FetchFailure, type FetchInit, type FetchInvalidate, type FetchRequest, type FetchResponse, type FetchRetry, type FetchSource, type FieldErrors, type Filter, type FixDrivers, type FormActions, type FormCalculated, type FormData, type FormField, type FormFieldCheck, type FormOptions, type FormSource, type FormState, type FormTool, type FormToolHandle, type FormToolResult, type FromAISDKOptions, type HeadValue, type HotModuleAPI, type HttpTransportOptions, type InspectAction, type InspectActionTrigger, type InspectChild, type InspectChildSelect, type InspectCommand, type InspectComponent, type InspectDiagnostic, type InspectFix, type InspectGraph, type InspectLocation, type InspectRecentAction, type InspectRelatedLocation, type InspectSelector, type InspectTextEdit, type InspectTimer, type InstallPrompt, type IntentSources, type IntrinsicControlProps, type JsonSchemaObject, type Layout, type LayoutNode, type LazyComponent, type LazyOptions, type Lens, type Lense, MainDOMSource, type McpAppDisplayMode, type McpAppDriverOptions, type McpAppError, type McpAppRequest, type McpAppSource, type McpContentBlock, type McpDownloadItem, type McpHostContext, type McpHostInfo, type McpLogLevel, type McpResourceContents, type McpSamplingRequest, type McpToolResult, type MockConfig, MockedDOMSource, type NonStateSinkReturns, type OpenResponsesEvent, type OpenResponsesOptions, type PagerActions, type PagerCalculated, type PagerOptions, type PagerState, type ParamNames, type ParentPayloadOf, type Persist, type PersistOptions, type PersistOptionsFor, type PersistStorage, type PersistedEntry, Portal, type PortalProps, type ProcessFormOptions, type QueryCache, type QueryCacheSnapshot, type QueryCacheSnapshotEntry, type Ref, type Ref$, type RegisteredEvent, type RenderOptions, type RenderResult, type RenderToStringOptions, type RenderableComponent, type ReplyRequest, type Resource, type ResourceRequest, type RootComponent, type Route, type RouteName, type RouteParamsArg, type RouteQuery, type Router, type RouterBlocked, type RouterCommand, type RouterOptions, type RouterSource, type RunOptions, type SchemaOutput, type ScrollToAlign, type SelectedDOMSource, type SelectionActions, type SelectionCalculated, type SelectionOptions, type SelectionState, type ServiceWorkerCommand, type ServiceWorkerOptions, type ServiceWorkerSource, type SimulatedEventInit, Slot, type SlotProps, type SocketActions, type SocketClose, type SocketConnection, type SocketDriverOptions, type SocketError, type SocketEvent, type SocketOpen, type SocketReconnect, type SocketRequest, type SocketSource, type SortFunction, type SortObject, type SortSpec, type SortableActions, type SortableDropped, type SortableOptions, type SortableState, type SseConnection, type StandardSchemaLike, type StateProp, type StrictDialect, type StrictSchemas, Suspense, type SuspenseProps, Switchable, type SwitchableProps, type SygnalApp, type SygnalBodyDOMSource, type SygnalDOMSource, type SygnalDevTools, type SygnalDocumentDOMSource, type SygnalEvents, type SygnalSinks, type TestAction, type Thunk, type ThunkData, type TimerAfter, type TimerFrame, type TimerSpec, type TimerTick, type Timers, Transition, type TransitionProps, type UIMessageStreamOptions, type UidFunction, type UndoBehaviorOptions, type UndoHistory, type UndoOptions, type UsesActions, type UsesState, type ViewProps, VirtualCollection, type VirtualCollectionProps, type WebMcpHandle, type Widget, type WidgetDefinition, type WidgetDispatch, type WidgetElementOf, type WidgetEmit, type WidgetHandle, type WidgetHostProps, type WithinTarget, abort, agentTools, agui, answers, anthropicMessages, askCard, byId, chat, chatCompletions, checkForm, choice, chromePrompt, classes, clearDiagnostics, clipboardSource, commandBar, compose, composeWith, controls, createCommand, createInstallPrompt, createRef, createRef$, decide, defineBehavior, defineCatalog, defineComponent, defineWidget, driverFromAsync, emit, enableHMR, encodeOpenResponses, event, exactState, experimentalExposeWebMcp, fieldName, fieldNames, focusInvalid, focusWithin, form, formErrors, formTool, fromAISDK, fromTree, geolocationSource, getDevTools, getDiagnostics, getField, hasField, intersectionSource, isSelected, jsonSchema, lazy, makeBrowserDriver, makeBrowserDriverWith, makeChatDriver, makeDOMDriver, makeDragDriver, makeFetchDriver, makeHeadDriver, makeMcpAppDriver, makeRouter, makeRouterDriver, makeServiceWorkerDriver, makeSocketDriver, makeTimerDriver, makeViewTransitionDOMDriver, mediaSource, messageText, mockDOMSource, noul, onDiagnostic, onlineSource, onlineStatus$, openResponses, openToolCalls, outputJsonSchema, pager, parseInput, persist, portal, processDrag, processForm, queryCache, removeNode, renderComponent, renderHead, renderToString, replyErrors, resizeSource, run, score, selection, set, setField, sortable, storageSource, strictSchemas, thunk, toJsonSchema, toTree, toggle, uiMessageStream, undo, undoable, visibilitySource, withToolResults, xs };
package/dist/index.esm.js CHANGED
@@ -702,6 +702,9 @@ const DEV_CODE_SEVERITY = {
702
702
  SYG128: 'error',
703
703
  // PLAN-4 4-G2: static only (sygnal-check); listed so the entry knows its title
704
704
  SYG129: 'warn',
705
+ // PLAN-10 X-1: static only (sygnal-check)
706
+ SYG170: 'warn',
707
+ SYG171: 'warn',
705
708
  SYG221: 'error',
706
709
  // PLAN-4 GS-4 (state.ts)
707
710
  SYG222: 'warn',
@@ -768,6 +771,8 @@ const DEV_CODE_SEVERITY = {
768
771
  SYG426: 'warn',
769
772
  // checks/next.ts: CHILD.select(undefined), usually a missing export
770
773
  SYG427: 'error',
774
+ // checks/next.ts: a path designator that 6.4 read as one key with a dot
775
+ SYG428: 'warn',
771
776
  // PLAN-9 (checks/next.ts): D470 key identity, two children with one identity
772
777
  SYG453: 'warn',
773
778
  SYG612: 'error',
@@ -1394,18 +1399,45 @@ function localCell(app, parent) {
1394
1399
  return { local: true, get: () => (own ? v : parent.get()), set: (n) => { v = n; own = true; app.commit(); } };
1395
1400
  }
1396
1401
  /**
1397
- * state="key". `owner`: the parent's name when `k` is one of its calculated fields (SYG409:
1398
- * writes ignored; `what` names the writer in the message). `dflt`: an isolated child's
1399
- * initialState, read while the slice is undefined. `has()`: the slice itself is defined (D174).
1402
+ * SPIKE (state paths): a state designator as segments. A plain key is one segment; 'a.b.0' and
1403
+ * 'a[0].b' are paths into nested objects and arrays. No array form: an array `from` / `state` is
1404
+ * the data passed by mistake (SYG410 / SYG412), and ['x', 'y'] would be ambiguous.
1405
+ */
1406
+ const pathOf$1 = (p) => p.replace(/\[(\d+)\]/g, '.$1').split('.');
1407
+ const getIn$1 = (o, ks) => { for (const k of ks) {
1408
+ if (o == null)
1409
+ return undefined;
1410
+ o = o[k];
1411
+ } return o; };
1412
+ /** `o` with the value at `ks` replaced; only the levels on the path are copied (a missing level becomes {}) */
1413
+ function setIn$1(o, ks, i, v) {
1414
+ if (i == ks.length)
1415
+ return v;
1416
+ const k = ks[i], cur = o?.[k], n = setIn$1(cur, ks, i + 1, v);
1417
+ if (n === cur && o != null)
1418
+ return o;
1419
+ if (Array.isArray(o)) {
1420
+ const c = o.slice();
1421
+ c[k] = n;
1422
+ return c;
1423
+ }
1424
+ return { ...o, [k]: n };
1425
+ }
1426
+ /**
1427
+ * state="key" (SPIKE: or a path, 'a.b' / 'a[0].b'). `owner`: the parent's name when the first
1428
+ * segment is one of its calculated fields (SYG409: writes ignored; `what` names the writer in
1429
+ * the message). `dflt`: an isolated child's initialState, read while the slice is undefined.
1430
+ * `has()`: the slice itself is defined (D174).
1400
1431
  */
1401
1432
  function keyCell(parent, k, owner, dflt, what = 'Sub-component') {
1433
+ const ks = pathOf$1(k);
1402
1434
  let lp = {}, lv;
1403
1435
  return {
1404
1436
  get() {
1405
1437
  const p = parent.get();
1406
1438
  if (p !== lp) {
1407
1439
  lp = p;
1408
- lv = p == null ? undefined : p[k];
1440
+ lv = getIn$1(p, ks);
1409
1441
  if (lv === undefined)
1410
1442
  lv = dflt;
1411
1443
  }
@@ -1413,12 +1445,12 @@ function keyCell(parent, k, owner, dflt, what = 'Sub-component') {
1413
1445
  },
1414
1446
  set(v) {
1415
1447
  if (owner)
1416
- return warn('SYG409', owner, `${what} tried to update calculated field '${k}'; ignored`, 'Bind it to a non-calculated field');
1448
+ return warn('SYG409', owner, `${what} tried to update calculated field '${ks[0]}'; ignored`, 'Bind it to a non-calculated field');
1417
1449
  const p = parent.get();
1418
- if (p?.[k] !== v)
1419
- parent.set({ ...p, [k]: v });
1450
+ if (getIn$1(p, ks) !== v)
1451
+ parent.set(setIn$1(p, ks, 0, v));
1420
1452
  },
1421
- has: () => parent.get()?.[k] !== undefined,
1453
+ has: () => getIn$1(parent.get(), ks) !== undefined,
1422
1454
  };
1423
1455
  }
1424
1456
  /**
@@ -1653,6 +1685,8 @@ class View {
1653
1685
  get state() { return this.i.cell.get(); }
1654
1686
  get props() { return this.i.props; }
1655
1687
  get context() { return this.i.context(); }
1688
+ /** D530: the context keys the last render's view read (null: none rendered, or no context) */
1689
+ get reads() { return this.i.keys; }
1656
1690
  get isRoot() { return !this.i.parent; }
1657
1691
  get kind() { return this.i.kind; }
1658
1692
  /** false on a hidden Switchable page and below it */
@@ -2038,9 +2072,11 @@ function isEqualNamespace(a, b) {
2038
2072
  return true;
2039
2073
  }
2040
2074
  // G-261: a DOM change Sygnal makes outside a patch (a Transition's leave, a Portal mounted late)
2041
- // re-emits the DOM source of the app whose root contains `el` (makeDOMDriver listens on its root)
2075
+ // re-emits the DOM source of the app whose root contains `el` (makeDOMDriver listens on its root).
2076
+ // The event comes from the element's own window: jsdom refuses an `Event` from another realm (a
2077
+ // Transition's leave timer that fires after a jsdom test environment was torn down)
2042
2078
  const POKE = 'sygnal-dom';
2043
- const pokeDOM = (el) => el?.dispatchEvent(new Event(POKE, { bubbles: true }));
2079
+ const pokeDOM = (el) => el?.dispatchEvent(new (el.ownerDocument?.defaultView?.Event || Event)(POKE, { bubbles: true }));
2044
2080
  const obj = (o) => o !== null && typeof o == 'object' && !Array.isArray(o);
2045
2081
  /**
2046
2082
  * P46-P: two vnodes' data are the same for the DOM modules: the same keys, each value identical
@@ -2764,7 +2800,7 @@ class Inst {
2764
2800
  fail$2('SYG405', def.name, 'Sub-component initialState replaces the state its parent passes in', 'Remove initialState, or set isolatedState = true');
2765
2801
  }
2766
2802
  const dflt = def.isolated ? def.initialState : undefined;
2767
- const cell = typeof st == 'string' ? keyCell(this.cell, st, calcOf?.has(st) && this.def.name, dflt)
2803
+ const cell = typeof st == 'string' ? keyCell(this.cell, st, calcOf?.has(pathOf$1(st)[0]) && this.def.name, dflt)
2768
2804
  : st !== undefined ? lensCell(this.cell, st, this.def.name, (e) => app.appError(this, e, 'view'), dflt)
2769
2805
  : def.isolated ? localCell(app, this.cell) : this.cell;
2770
2806
  const scope = app.scope();
@@ -2846,8 +2882,9 @@ class Inst {
2846
2882
  *
2847
2883
  * It stands where the `<Collection>` marker was in its owner's template and renders the items
2848
2884
  * inside the owner's render: no stream of its own, no pickCombine.
2849
- * - `of`: a component function (D163: no names). `from`: a state key (SYG409 on a calculated
2850
- * one), a `{ get, set }` lens (SYG412 without get(); SYG401 for a non-array) or none (the
2885
+ * - `of`: a component function (D163: no names). `from`: a state key or path ('board.cards';
2886
+ * SYG409 on a calculated first segment; SYG401 when it isn't an array: the dev entry's), a
2887
+ * `{ get, set }` lens (SYG412 without get(); SYG401 for a non-array) or none (the
2851
2888
  * owner's state is the array).
2852
2889
  * - Items are keyed by `id`, an id-less item by its raw index (D169); one key -> index map per
2853
2890
  * array identity serves every item (cell.ts indexer). A duplicate key renders its first element
@@ -2929,16 +2966,9 @@ function arrayCell(owner, from) {
2929
2966
  set: (v) => oc.set(v),
2930
2967
  };
2931
2968
  }
2932
- if (typeof from == 'string') {
2933
- const cs = oc.get(), calc = owner.def.calcNames?.has(from);
2934
- if (isObj$2(cs) && !(from in cs) && !calc) {
2935
- const arrays = Object.keys(cs).filter(k => Array.isArray(cs[k]));
2936
- warn('SYG401', name, `Collection from="${from}" is not in state${arrays.length ? ` (array fields: '${arrays.join("', '")}')` : ''}; it renders nothing until it exists`, 'Set it to an array in initialState');
2937
- }
2938
- else if (isObj$2(cs) && !Array.isArray(cs[from]))
2939
- warn('SYG401', name, `Collection 'from' field '${from}' is not an array; it renders nothing`, 'Set it to an array in initialState');
2940
- return keyCell(oc, from, calc && name, undefined, 'Collection');
2941
- }
2969
+ // a key or a path ('board.cards'); SYG401 for one that isn't an array is the dev entry's (checks/collections.ts)
2970
+ if (typeof from == 'string')
2971
+ return keyCell(oc, from, owner.def.calcNames?.has(pathOf$1(from)[0]) && name, undefined, 'Collection');
2942
2972
  if (isObj$2(from) && typeof from.get == 'function') {
2943
2973
  let lp = {}, lv;
2944
2974
  return {
@@ -4147,7 +4177,7 @@ class SwitchableHost {
4147
4177
  this.lr = true;
4148
4178
  this.kids = [];
4149
4179
  check$3(owner, props);
4150
- const st = props.state, calc = typeof st == 'string' && owner.def.calcNames?.has(st);
4180
+ const st = props.state, calc = typeof st == 'string' && owner.def.calcNames?.has(pathOf$1(st)[0]);
4151
4181
  this.cell = typeof st == 'string' ? keyCell(owner.cell, st, calc && owner.def.name, undefined, 'Switchable sub-component')
4152
4182
  : st !== undefined ? lensCell(owner.cell, st, owner.def.name, (e) => owner.app.appError(owner, e, 'view'))
4153
4183
  : owner.cell;