foldkit 0.76.1 → 0.78.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.
package/README.md CHANGED
@@ -150,7 +150,7 @@ Foldkit is a complete system, not a collection of libraries you stitch together.
150
150
  - **Field Validation**: Per-field validation state modeled as a discriminated union. Define rules as data, apply them in update, and the Model tracks the result.
151
151
  - **Virtual DOM**: Declarative views powered by [Snabbdom](https://github.com/snabbdom/snabbdom), with lazy memoization and fast, keyed diffing. Views are plain functions of your Model.
152
152
  - **DevTools**: Built-in overlay for inspecting Messages, Model state, and Commands. Time-travel mode rewinds your UI to any past Model, Inspect mode browses snapshots without pausing, and Submodel drill-in filtering scopes the Message list to any nested module.
153
- - **DevTools MCP**: Expose a running Foldkit app to AI agents over the Model Context Protocol. Agents read the current Model, list and inspect Message history, rewind the UI to any past Model, and dispatch Messages into the runtime. The runtime's own Message Schema is published as JSON Schema so the agent discovers exactly what it can dispatch, and every payload is validated against the Schema before it reaches your update function. One command sets it up: `npx @foldkit/devtools-mcp init`.
153
+ - **DevTools MCP**: Expose a running Foldkit app to AI agents over the Model Context Protocol. Agents read the current Model, list and inspect Message history, rewind the UI to any past Model, and dispatch Messages into the runtime. To dispatch, agents read your application source to learn the Message Schema; the runtime decodes every payload against the Schema and returns a clean error if the shape does not match. One command sets it up: `npx @foldkit/devtools-mcp init`.
154
154
  - **Crash View and Reporting**: Configure `crash.view` to render a custom fallback UI when the update loop throws. A `crash.report` callback fires first with the error, Model, and triggering Message, so you can ship it straight to Sentry or your logger.
155
155
  - **Story Testing**: Exercise the update function directly. Send Messages, resolve Commands inline with `resolve` and `resolveAll`, and assert with focused helpers: `Story.model`, `Story.expectHasCommands`, `Story.expectExactCommands`, `Story.expectNoCommands`, and `Story.expectOutMessage`. No mocking libraries, no fake timers.
156
156
  - **Scene Testing**: Drive your app the way a user does. Scene renders your real view, then clicks buttons, types into inputs, presses keys, and asserts on what's on screen. Accessible locators (`role`, `label`, `placeholder`, `altText`, `title`, `testId`, `displayValue`) with full options (`name`, `level`, `checked`, `selected`, `pressed`, `expanded`, `disabled`), multi-match `Scene.all` with `Scene.filter` and `Scene.nth`, scoped steps via `Scene.inside`, pointer events, event bubbling, and Vitest matchers like `toHaveText`, `toBeVisible`, `toHaveAccessibleName`, and `toHaveCount`. API parity with React Testing Library and Playwright, without a browser.
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/devTools/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,MAAM,EAGN,OAAO,EAGP,MAAM,EASP,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAK9C,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAQ3E,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,YAAY,CAAA;AAuOnB,eAAO,MAAM,MAAM;;EAA0C,CAAA;AAC7D,eAAO,MAAM,YAAY;;;;;;EAGxB,CAAA;AACD,eAAO,MAAM,aAAa;;;;;;EAGzB,CAAA;AACD,eAAO,MAAM,MAAM;;EAA4C,CAAA;AAC/D,eAAO,MAAM,KAAK;;EAA0C,CAAA;AAC5D,eAAO,MAAM,UAAU;;EAA6C,CAAA;AACpE,eAAO,MAAM,YAAY;;EAAiD,CAAA;AAC1E,eAAO,MAAM,WAAW;;EAA+C,CAAA;AAgzCvE,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,sCAkDhC,CAAA"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/devTools/overlay.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,MAAM,EAGN,OAAO,EAGP,MAAM,EASP,MAAM,QAAQ,CAAA;AAEf,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAA;AAU9C,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAQ3E,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,YAAY,CAAA;AA4M5E,eAAO,MAAM,MAAM;;EAA0C,CAAA;AAC7D,eAAO,MAAM,YAAY;;;;;;EAGxB,CAAA;AACD,eAAO,MAAM,aAAa;;;;;;EAGzB,CAAA;AACD,eAAO,MAAM,MAAM;;EAA4C,CAAA;AAC/D,eAAO,MAAM,KAAK;;EAA0C,CAAA;AAC5D,eAAO,MAAM,UAAU;;EAA6C,CAAA;AACpE,eAAO,MAAM,YAAY;;EAAiD,CAAA;AAC1E,eAAO,MAAM,WAAW;;EAA+C,CAAA;AAkzCvE,eAAO,MAAM,aAAa,GACxB,OAAO,aAAa,EACpB,UAAU,gBAAgB,EAC1B,MAAM,YAAY,EAClB,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,sCAkDhC,CAAA"}
@@ -2,7 +2,7 @@ import { clsx } from 'clsx';
2
2
  import { Array as Array_, Effect, Equal, Function, HashSet, Match as M, Number as Number_, Option, Order, Predicate, Record, Schema as S, Stream, String as String_, SubscriptionRef, pipe, } from 'effect';
3
3
  import * as Command from '../command/index.js';
4
4
  import { OptionExt } from '../effectExtensions/index.js';
5
- import { createKeyedLazy, html } from '../html/index.js';
5
+ import { createKeyedLazy, html, } from '../html/index.js';
6
6
  import { m } from '../message/index.js';
7
7
  import { makeProgram } from '../runtime/runtime.js';
8
8
  import { makeSubscriptions } from '../runtime/subscription.js';
@@ -12,7 +12,8 @@ import * as Listbox from '../ui/listbox/public.js';
12
12
  import * as Tabs from '../ui/tabs/public.js';
13
13
  import { overlayStyles } from './overlay-styles.js';
14
14
  import { toInspectableValue } from './serialize.js';
15
- import { INIT_INDEX, } from './store.js';
15
+ import { INIT_INDEX } from './store.js';
16
+ import { GOT_MESSAGE_PATTERN, extractSubmodelInfo, isTagged, } from './submodelPath.js';
16
17
  // MODEL
17
18
  const DisplayEntry = S.Struct({
18
19
  tag: S.String,
@@ -107,26 +108,8 @@ const ALL_MESSAGES_VALUE = '';
107
108
  const formatTimeDelta = (deltaMs) => M.value(deltaMs).pipe(M.when(0, () => '0ms'), M.when(Number_.lessThan(MILLIS_PER_SECOND), ms => `+${Math.round(ms)}ms`), M.orElse(ms => `+${(ms / MILLIS_PER_SECOND).toFixed(1)}s`));
108
109
  const MESSAGE_LIST_SELECTOR = '.message-list';
109
110
  const computeSubmodelTags = (entries) => pipe(entries, Array_.flatMap(({ submodelPath }) => submodelPath), Array_.dedupe, Array_.sort(Order.string));
110
- const GOT_MESSAGE_PATTERN = /^Got.+Message$/;
111
- const extractSubmodelInfo = (entry) => {
112
- if (!GOT_MESSAGE_PATTERN.test(entry.tag)) {
113
- return { submodelPath: [], maybeLeafTag: Option.none() };
114
- }
115
- const path = [entry.tag];
116
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
117
- let current = entry.message?.['message'];
118
- while (isTagged(current) && GOT_MESSAGE_PATTERN.test(current._tag)) {
119
- path.push(current._tag);
120
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
121
- current = current?.['message'];
122
- }
123
- return {
124
- submodelPath: path,
125
- maybeLeafTag: pipe(current, Option.liftPredicate(isTagged), Option.map(({ _tag }) => _tag)),
126
- };
127
- };
128
111
  const toDisplayEntries = ({ entries }) => Array_.map(entries, entry => {
129
- const { submodelPath, maybeLeafTag } = extractSubmodelInfo(entry);
112
+ const { submodelPath, maybeLeafTag } = extractSubmodelInfo(entry.tag, entry.message);
130
113
  return {
131
114
  tag: entry.tag,
132
115
  submodelPath,
@@ -144,8 +127,6 @@ const toDisplayState = (state) => ({
144
127
  pausedAtIndex: state.pausedAtIndex,
145
128
  });
146
129
  const isExpandable = (value) => Predicate.isObject(value);
147
- const Tagged = S.Struct({ _tag: S.String });
148
- const isTagged = S.is(Tagged);
149
130
  const objectPreview = (value) => pipe(value, Record.keys, Array_.filter(key => key !== '_tag'), Array_.match({
150
131
  onEmpty: () => '{}',
151
132
  onNonEmpty: keys => {
@@ -817,11 +798,14 @@ const makeView = (position, mode, maybeBanner) => {
817
798
  ]),
818
799
  ]);
819
800
  const interactionBlocker = div([Class('dt-interaction-blocker')], []);
820
- return (model) => div([], [
821
- ...OptionExt.when(model.isPaused && mode === 'TimeTravel', interactionBlocker).pipe(Option.toArray),
822
- ...OptionExt.when(model.isOpen, panelView(model)).pipe(Option.toArray),
823
- badgeView(model),
824
- ]);
801
+ return (model) => ({
802
+ title: 'Foldkit DevTools',
803
+ body: div([], [
804
+ ...OptionExt.when(model.isPaused && mode === 'TimeTravel', interactionBlocker).pipe(Option.toArray),
805
+ ...OptionExt.when(model.isOpen, panelView(model)).pipe(Option.toArray),
806
+ badgeView(model),
807
+ ]),
808
+ });
825
809
  };
826
810
  // CREATE
827
811
  const DEVTOOLS_HOST_ID = 'foldkit-devtools';
@@ -1,5 +1,5 @@
1
1
  import { Schema as S } from 'effect';
2
- /** A serialized history entry as it appears on the wire. */
2
+ /** A serialized history entry as it appears on the wire. `submodelPath` lists `Got<Child>Message` wrapper tags from outer to inner when the entry came up through a Submodel chain; `maybeLeafTag` is `Some` with the innermost child Message tag when one exists. */
3
3
  export declare const SerializedEntry: S.Struct<{
4
4
  index: typeof S.Number;
5
5
  tag: typeof S.String;
@@ -9,6 +9,8 @@ export declare const SerializedEntry: S.Struct<{
9
9
  isModelChanged: typeof S.Boolean;
10
10
  changedPaths: S.Array$<typeof S.String>;
11
11
  affectedPaths: S.Array$<typeof S.String>;
12
+ submodelPath: S.Array$<typeof S.String>;
13
+ maybeLeafTag: S.Option<typeof S.String>;
12
14
  }>;
13
15
  /** A serialized history entry suitable for transmission over the WS protocol. */
14
16
  export type SerializedEntry = typeof SerializedEntry.Type;
@@ -18,23 +20,31 @@ export declare const KeyframeInfo: S.Struct<{
18
20
  }>;
19
21
  /** Metadata about a single keyframe. */
20
22
  export type KeyframeInfo = typeof KeyframeInfo.Type;
21
- /** Metadata about a connected browser runtime. The `maybeMessageSchema` carries the runtime's app-level Message Schema as JSON Schema for `dispatch_message` validation, when the runtime exposes one via `DevToolsConfig.Message`. */
23
+ /** Metadata about a connected browser runtime. */
22
24
  export declare const RuntimeInfo: S.Struct<{
23
25
  connectionId: typeof S.String;
24
26
  url: typeof S.String;
25
27
  title: typeof S.String;
26
- maybeMessageSchema: S.Option<typeof S.Unknown>;
27
28
  }>;
28
29
  /** Metadata about a connected browser runtime. */
29
30
  export type RuntimeInfo = typeof RuntimeInfo.Type;
30
- /** Request the current Model snapshot. */
31
- export declare const RequestGetModel: import("../schema/index.js").CallableTaggedStruct<"RequestGetModel", {}>;
31
+ /** Request the current Model snapshot, optionally narrowed to a path and/or expanded. */
32
+ export declare const RequestGetModel: import("../schema/index.js").CallableTaggedStruct<"RequestGetModel", {
33
+ maybePath: S.Option<typeof S.String>;
34
+ expand: typeof S.Boolean;
35
+ }>;
36
+ /** Request a historical Model snapshot at an absolute history index, optionally narrowed to a path and/or expanded. Use `index: -1` for the initial Model. */
37
+ export declare const RequestGetModelAt: import("../schema/index.js").CallableTaggedStruct<"RequestGetModelAt", {
38
+ index: typeof S.Number;
39
+ maybePath: S.Option<typeof S.String>;
40
+ expand: typeof S.Boolean;
41
+ }>;
32
42
  /** Request recent history entries, optionally starting from a given index. */
33
43
  export declare const RequestListMessages: import("../schema/index.js").CallableTaggedStruct<"RequestListMessages", {
34
44
  limit: typeof S.Number;
35
45
  maybeSinceIndex: S.Option<typeof S.Number>;
36
46
  }>;
37
- /** Request a single history entry by index, including before/after Model snapshots. */
47
+ /** Request a single history entry by index. To inspect the Model around the entry, call `RequestGetModelAt` with `index - 1` (before) and `index` (after). */
38
48
  export declare const RequestGetMessage: import("../schema/index.js").CallableTaggedStruct<"RequestGetMessage", {
39
49
  index: typeof S.Number;
40
50
  }>;
@@ -46,6 +56,10 @@ export declare const RequestReplayToKeyframe: import("../schema/index.js").Calla
46
56
  }>;
47
57
  /** Request the runtime resume normal execution from a paused state. */
48
58
  export declare const RequestResume: import("../schema/index.js").CallableTaggedStruct<"RequestResume", {}>;
59
+ /** Request the recorded init data: the initial Model and the names of Commands returned from `init`. */
60
+ export declare const RequestGetInit: import("../schema/index.js").CallableTaggedStruct<"RequestGetInit", {}>;
61
+ /** Request a snapshot of the runtime's DevTools state: history bounds, current paused/live status, and whether init is recorded. */
62
+ export declare const RequestGetRuntimeState: import("../schema/index.js").CallableTaggedStruct<"RequestGetRuntimeState", {}>;
49
63
  /** Request the runtime dispatch a Message at the current state. The payload is opaque to the protocol; the runtime validates against the app's Message Schema. */
50
64
  export declare const RequestDispatchMessage: import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessage", {
51
65
  message: typeof S.Unknown;
@@ -53,7 +67,14 @@ export declare const RequestDispatchMessage: import("../schema/index.js").Callab
53
67
  /** Request the list of currently connected browser runtimes. Handled by the Vite plugin, not forwarded to a runtime. */
54
68
  export declare const RequestListRuntimes: import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>;
55
69
  /** A request from the MCP server. RequestListRuntimes is handled at the Vite plugin layer; all other requests are routed to a browser runtime. */
56
- export declare const Request: S.Union<[import("../schema/index.js").CallableTaggedStruct<"RequestGetModel", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestListMessages", {
70
+ export declare const Request: S.Union<[import("../schema/index.js").CallableTaggedStruct<"RequestGetModel", {
71
+ maybePath: S.Option<typeof S.String>;
72
+ expand: typeof S.Boolean;
73
+ }>, import("../schema/index.js").CallableTaggedStruct<"RequestGetModelAt", {
74
+ index: typeof S.Number;
75
+ maybePath: S.Option<typeof S.String>;
76
+ expand: typeof S.Boolean;
77
+ }>, import("../schema/index.js").CallableTaggedStruct<"RequestListMessages", {
57
78
  limit: typeof S.Number;
58
79
  maybeSinceIndex: S.Option<typeof S.Number>;
59
80
  }>, import("../schema/index.js").CallableTaggedStruct<"RequestGetMessage", {
@@ -62,12 +83,14 @@ export declare const Request: S.Union<[import("../schema/index.js").CallableTagg
62
83
  keyframeIndex: typeof S.Number;
63
84
  }>, import("../schema/index.js").CallableTaggedStruct<"RequestResume", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessage", {
64
85
  message: typeof S.Unknown;
65
- }>, import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>]>;
86
+ }>, import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetInit", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetRuntimeState", {}>]>;
66
87
  /** A request from the MCP server. */
67
88
  export type Request = typeof Request.Type;
68
- /** Response carrying the current Model snapshot. */
89
+ /** Response carrying a Model snapshot. The `value` is the resolved subtree at `atPath` (or the whole Model when no path was supplied). When `summarized` is true, large arrays/records/strings have been collapsed to `_summary` placeholders to keep payloads small for AI agents; pass `expand: true` on the Request to receive the literal value. */
69
90
  export declare const ResponseModel: import("../schema/index.js").CallableTaggedStruct<"ResponseModel", {
70
- model: typeof S.Unknown;
91
+ value: typeof S.Unknown;
92
+ atPath: typeof S.String;
93
+ summarized: typeof S.Boolean;
71
94
  }>;
72
95
  /** Response carrying a page of history entries. `maybeNextIndex` is `Some` when more entries are available beyond this page (pass it as `RequestListMessages.maybeSinceIndex` to fetch the next page) and `None` when this page reaches the current end of history. */
73
96
  export declare const ResponseMessages: import("../schema/index.js").CallableTaggedStruct<"ResponseMessages", {
@@ -80,10 +103,12 @@ export declare const ResponseMessages: import("../schema/index.js").CallableTagg
80
103
  isModelChanged: typeof S.Boolean;
81
104
  changedPaths: S.Array$<typeof S.String>;
82
105
  affectedPaths: S.Array$<typeof S.String>;
106
+ submodelPath: S.Array$<typeof S.String>;
107
+ maybeLeafTag: S.Option<typeof S.String>;
83
108
  }>>;
84
109
  maybeNextIndex: S.Option<typeof S.Number>;
85
110
  }>;
86
- /** Response carrying a single history entry with surrounding Model snapshots. */
111
+ /** Response carrying a single history entry. Model snapshots are not included; use `RequestGetModelAt` with `index - 1` and `index` to inspect Model state around the entry. */
87
112
  export declare const ResponseMessage: import("../schema/index.js").CallableTaggedStruct<"ResponseMessage", {
88
113
  entry: S.Struct<{
89
114
  index: typeof S.Number;
@@ -94,9 +119,9 @@ export declare const ResponseMessage: import("../schema/index.js").CallableTagge
94
119
  isModelChanged: typeof S.Boolean;
95
120
  changedPaths: S.Array$<typeof S.String>;
96
121
  affectedPaths: S.Array$<typeof S.String>;
122
+ submodelPath: S.Array$<typeof S.String>;
123
+ maybeLeafTag: S.Option<typeof S.String>;
97
124
  }>;
98
- modelBefore: typeof S.Unknown;
99
- modelAfter: typeof S.Unknown;
100
125
  }>;
101
126
  /** Response carrying the list of available keyframes. */
102
127
  export declare const ResponseKeyframes: import("../schema/index.js").CallableTaggedStruct<"ResponseKeyframes", {
@@ -120,16 +145,31 @@ export declare const ResponseRuntimes: import("../schema/index.js").CallableTagg
120
145
  connectionId: typeof S.String;
121
146
  url: typeof S.String;
122
147
  title: typeof S.String;
123
- maybeMessageSchema: S.Option<typeof S.Unknown>;
124
148
  }>>;
125
149
  }>;
150
+ /** Response carrying the recorded init data. `maybeModel` is `None` until the runtime has finished its first render and recorded init; once set it stays set for the rest of the runtime's life. `commandNames` lists the Commands returned from the application's `init` function in the order they were produced. */
151
+ export declare const ResponseInit: import("../schema/index.js").CallableTaggedStruct<"ResponseInit", {
152
+ maybeModel: S.Option<typeof S.Unknown>;
153
+ commandNames: S.Array$<typeof S.String>;
154
+ }>;
155
+ /** Response carrying a snapshot of the runtime's DevTools state. `currentIndex` is the absolute index of the most recently recorded Message, or -1 when no Messages have been recorded yet. `startIndex` is the earliest absolute index still retained in the rolling buffer (older entries are evicted past `maxEntries`). `totalEntries` is the number of retained entries. `isPaused` is true while the runtime is paused at a replayed snapshot; `maybePausedAtIndex` is `Some(index)` then and `None` otherwise. `hasInitModel` is true once the runtime has finished initialising. */
156
+ export declare const ResponseRuntimeState: import("../schema/index.js").CallableTaggedStruct<"ResponseRuntimeState", {
157
+ currentIndex: typeof S.Number;
158
+ startIndex: typeof S.Number;
159
+ totalEntries: typeof S.Number;
160
+ isPaused: typeof S.Boolean;
161
+ maybePausedAtIndex: S.Option<typeof S.Number>;
162
+ hasInitModel: typeof S.Boolean;
163
+ }>;
126
164
  /** Response carrying an error reason for a failed Request. */
127
165
  export declare const ResponseError: import("../schema/index.js").CallableTaggedStruct<"ResponseError", {
128
166
  reason: typeof S.String;
129
167
  }>;
130
168
  /** A response replying to a Request. */
131
169
  export declare const Response: S.Union<[import("../schema/index.js").CallableTaggedStruct<"ResponseModel", {
132
- model: typeof S.Unknown;
170
+ value: typeof S.Unknown;
171
+ atPath: typeof S.String;
172
+ summarized: typeof S.Boolean;
133
173
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseMessages", {
134
174
  entries: S.Array$<S.Struct<{
135
175
  index: typeof S.Number;
@@ -140,6 +180,8 @@ export declare const Response: S.Union<[import("../schema/index.js").CallableTag
140
180
  isModelChanged: typeof S.Boolean;
141
181
  changedPaths: S.Array$<typeof S.String>;
142
182
  affectedPaths: S.Array$<typeof S.String>;
183
+ submodelPath: S.Array$<typeof S.String>;
184
+ maybeLeafTag: S.Option<typeof S.String>;
143
185
  }>>;
144
186
  maybeNextIndex: S.Option<typeof S.Number>;
145
187
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseMessage", {
@@ -152,9 +194,9 @@ export declare const Response: S.Union<[import("../schema/index.js").CallableTag
152
194
  isModelChanged: typeof S.Boolean;
153
195
  changedPaths: S.Array$<typeof S.String>;
154
196
  affectedPaths: S.Array$<typeof S.String>;
197
+ submodelPath: S.Array$<typeof S.String>;
198
+ maybeLeafTag: S.Option<typeof S.String>;
155
199
  }>;
156
- modelBefore: typeof S.Unknown;
157
- modelAfter: typeof S.Unknown;
158
200
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseKeyframes", {
159
201
  keyframes: S.Array$<S.Struct<{
160
202
  index: typeof S.Number;
@@ -168,20 +210,28 @@ export declare const Response: S.Union<[import("../schema/index.js").CallableTag
168
210
  connectionId: typeof S.String;
169
211
  url: typeof S.String;
170
212
  title: typeof S.String;
171
- maybeMessageSchema: S.Option<typeof S.Unknown>;
172
213
  }>>;
214
+ }>, import("../schema/index.js").CallableTaggedStruct<"ResponseInit", {
215
+ maybeModel: S.Option<typeof S.Unknown>;
216
+ commandNames: S.Array$<typeof S.String>;
217
+ }>, import("../schema/index.js").CallableTaggedStruct<"ResponseRuntimeState", {
218
+ currentIndex: typeof S.Number;
219
+ startIndex: typeof S.Number;
220
+ totalEntries: typeof S.Number;
221
+ isPaused: typeof S.Boolean;
222
+ maybePausedAtIndex: S.Option<typeof S.Number>;
223
+ hasInitModel: typeof S.Boolean;
173
224
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseError", {
174
225
  reason: typeof S.String;
175
226
  }>]>;
176
227
  /** A response replying to a Request. */
177
228
  export type Response = typeof Response.Type;
178
- /** A new browser runtime connected. The `runtime.maybeMessageSchema` field carries the runtime's Message Schema (as JSON Schema) when the runtime exposes one via `DevToolsConfig.Message`. */
229
+ /** A new browser runtime connected. */
179
230
  export declare const EventConnected: import("../schema/index.js").CallableTaggedStruct<"EventConnected", {
180
231
  runtime: S.Struct<{
181
232
  connectionId: typeof S.String;
182
233
  url: typeof S.String;
183
234
  title: typeof S.String;
184
- maybeMessageSchema: S.Option<typeof S.Unknown>;
185
235
  }>;
186
236
  }>;
187
237
  /** A previously connected runtime disconnected. */
@@ -194,7 +244,6 @@ export declare const Event: S.Union<[import("../schema/index.js").CallableTagged
194
244
  connectionId: typeof S.String;
195
245
  url: typeof S.String;
196
246
  title: typeof S.String;
197
- maybeMessageSchema: S.Option<typeof S.Unknown>;
198
247
  }>;
199
248
  }>, import("../schema/index.js").CallableTaggedStruct<"EventDisconnected", {
200
249
  connectionId: typeof S.String;
@@ -205,7 +254,14 @@ export type Event = typeof Event.Type;
205
254
  export declare const RequestFrame: S.Struct<{
206
255
  id: typeof S.String;
207
256
  maybeConnectionId: S.Option<typeof S.String>;
208
- request: S.Union<[import("../schema/index.js").CallableTaggedStruct<"RequestGetModel", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestListMessages", {
257
+ request: S.Union<[import("../schema/index.js").CallableTaggedStruct<"RequestGetModel", {
258
+ maybePath: S.Option<typeof S.String>;
259
+ expand: typeof S.Boolean;
260
+ }>, import("../schema/index.js").CallableTaggedStruct<"RequestGetModelAt", {
261
+ index: typeof S.Number;
262
+ maybePath: S.Option<typeof S.String>;
263
+ expand: typeof S.Boolean;
264
+ }>, import("../schema/index.js").CallableTaggedStruct<"RequestListMessages", {
209
265
  limit: typeof S.Number;
210
266
  maybeSinceIndex: S.Option<typeof S.Number>;
211
267
  }>, import("../schema/index.js").CallableTaggedStruct<"RequestGetMessage", {
@@ -214,7 +270,7 @@ export declare const RequestFrame: S.Struct<{
214
270
  keyframeIndex: typeof S.Number;
215
271
  }>, import("../schema/index.js").CallableTaggedStruct<"RequestResume", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessage", {
216
272
  message: typeof S.Unknown;
217
- }>, import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>]>;
273
+ }>, import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetInit", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetRuntimeState", {}>]>;
218
274
  }>;
219
275
  /** A wire frame carrying a Request from the MCP server. */
220
276
  export type RequestFrame = typeof RequestFrame.Type;
@@ -222,7 +278,9 @@ export type RequestFrame = typeof RequestFrame.Type;
222
278
  export declare const ResponseFrame: S.Struct<{
223
279
  id: typeof S.String;
224
280
  response: S.Union<[import("../schema/index.js").CallableTaggedStruct<"ResponseModel", {
225
- model: typeof S.Unknown;
281
+ value: typeof S.Unknown;
282
+ atPath: typeof S.String;
283
+ summarized: typeof S.Boolean;
226
284
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseMessages", {
227
285
  entries: S.Array$<S.Struct<{
228
286
  index: typeof S.Number;
@@ -233,6 +291,8 @@ export declare const ResponseFrame: S.Struct<{
233
291
  isModelChanged: typeof S.Boolean;
234
292
  changedPaths: S.Array$<typeof S.String>;
235
293
  affectedPaths: S.Array$<typeof S.String>;
294
+ submodelPath: S.Array$<typeof S.String>;
295
+ maybeLeafTag: S.Option<typeof S.String>;
236
296
  }>>;
237
297
  maybeNextIndex: S.Option<typeof S.Number>;
238
298
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseMessage", {
@@ -245,9 +305,9 @@ export declare const ResponseFrame: S.Struct<{
245
305
  isModelChanged: typeof S.Boolean;
246
306
  changedPaths: S.Array$<typeof S.String>;
247
307
  affectedPaths: S.Array$<typeof S.String>;
308
+ submodelPath: S.Array$<typeof S.String>;
309
+ maybeLeafTag: S.Option<typeof S.String>;
248
310
  }>;
249
- modelBefore: typeof S.Unknown;
250
- modelAfter: typeof S.Unknown;
251
311
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseKeyframes", {
252
312
  keyframes: S.Array$<S.Struct<{
253
313
  index: typeof S.Number;
@@ -261,8 +321,17 @@ export declare const ResponseFrame: S.Struct<{
261
321
  connectionId: typeof S.String;
262
322
  url: typeof S.String;
263
323
  title: typeof S.String;
264
- maybeMessageSchema: S.Option<typeof S.Unknown>;
265
324
  }>>;
325
+ }>, import("../schema/index.js").CallableTaggedStruct<"ResponseInit", {
326
+ maybeModel: S.Option<typeof S.Unknown>;
327
+ commandNames: S.Array$<typeof S.String>;
328
+ }>, import("../schema/index.js").CallableTaggedStruct<"ResponseRuntimeState", {
329
+ currentIndex: typeof S.Number;
330
+ startIndex: typeof S.Number;
331
+ totalEntries: typeof S.Number;
332
+ isPaused: typeof S.Boolean;
333
+ maybePausedAtIndex: S.Option<typeof S.Number>;
334
+ hasInitModel: typeof S.Boolean;
266
335
  }>, import("../schema/index.js").CallableTaggedStruct<"ResponseError", {
267
336
  reason: typeof S.String;
268
337
  }>]>;
@@ -277,7 +346,6 @@ export declare const EventFrame: S.Struct<{
277
346
  connectionId: typeof S.String;
278
347
  url: typeof S.String;
279
348
  title: typeof S.String;
280
- maybeMessageSchema: S.Option<typeof S.Unknown>;
281
349
  }>;
282
350
  }>, import("../schema/index.js").CallableTaggedStruct<"EventDisconnected", {
283
351
  connectionId: typeof S.String;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/devTools/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/devTools/protocol.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { Schema as S } from 'effect';
2
2
  import { ts } from '../schema/index.js';
3
3
  // SHARED
4
- /** A serialized history entry as it appears on the wire. */
4
+ /** A serialized history entry as it appears on the wire. `submodelPath` lists `Got<Child>Message` wrapper tags from outer to inner when the entry came up through a Submodel chain; `maybeLeafTag` is `Some` with the innermost child Message tag when one exists. */
5
5
  export const SerializedEntry = S.Struct({
6
6
  index: S.Number,
7
7
  tag: S.String,
@@ -11,27 +11,37 @@ export const SerializedEntry = S.Struct({
11
11
  isModelChanged: S.Boolean,
12
12
  changedPaths: S.Array(S.String),
13
13
  affectedPaths: S.Array(S.String),
14
+ submodelPath: S.Array(S.String),
15
+ maybeLeafTag: S.Option(S.String),
14
16
  });
15
17
  /** Metadata about a single keyframe. The index identifies the point in history where the runtime can replay back to. */
16
18
  export const KeyframeInfo = S.Struct({
17
19
  index: S.Number,
18
20
  });
19
- /** Metadata about a connected browser runtime. The `maybeMessageSchema` carries the runtime's app-level Message Schema as JSON Schema for `dispatch_message` validation, when the runtime exposes one via `DevToolsConfig.Message`. */
21
+ /** Metadata about a connected browser runtime. */
20
22
  export const RuntimeInfo = S.Struct({
21
23
  connectionId: S.String,
22
24
  url: S.String,
23
25
  title: S.String,
24
- maybeMessageSchema: S.Option(S.Unknown),
25
26
  });
26
27
  // REQUEST
27
- /** Request the current Model snapshot. */
28
- export const RequestGetModel = ts('RequestGetModel');
28
+ /** Request the current Model snapshot, optionally narrowed to a path and/or expanded. */
29
+ export const RequestGetModel = ts('RequestGetModel', {
30
+ maybePath: S.Option(S.String),
31
+ expand: S.Boolean,
32
+ });
33
+ /** Request a historical Model snapshot at an absolute history index, optionally narrowed to a path and/or expanded. Use `index: -1` for the initial Model. */
34
+ export const RequestGetModelAt = ts('RequestGetModelAt', {
35
+ index: S.Number,
36
+ maybePath: S.Option(S.String),
37
+ expand: S.Boolean,
38
+ });
29
39
  /** Request recent history entries, optionally starting from a given index. */
30
40
  export const RequestListMessages = ts('RequestListMessages', {
31
41
  limit: S.Number,
32
42
  maybeSinceIndex: S.Option(S.Number),
33
43
  });
34
- /** Request a single history entry by index, including before/after Model snapshots. */
44
+ /** Request a single history entry by index. To inspect the Model around the entry, call `RequestGetModelAt` with `index - 1` (before) and `index` (after). */
35
45
  export const RequestGetMessage = ts('RequestGetMessage', {
36
46
  index: S.Number,
37
47
  });
@@ -43,6 +53,10 @@ export const RequestReplayToKeyframe = ts('RequestReplayToKeyframe', {
43
53
  });
44
54
  /** Request the runtime resume normal execution from a paused state. */
45
55
  export const RequestResume = ts('RequestResume');
56
+ /** Request the recorded init data: the initial Model and the names of Commands returned from `init`. */
57
+ export const RequestGetInit = ts('RequestGetInit');
58
+ /** Request a snapshot of the runtime's DevTools state: history bounds, current paused/live status, and whether init is recorded. */
59
+ export const RequestGetRuntimeState = ts('RequestGetRuntimeState');
46
60
  /** Request the runtime dispatch a Message at the current state. The payload is opaque to the protocol; the runtime validates against the app's Message Schema. */
47
61
  export const RequestDispatchMessage = ts('RequestDispatchMessage', {
48
62
  message: S.Unknown,
@@ -50,22 +64,22 @@ export const RequestDispatchMessage = ts('RequestDispatchMessage', {
50
64
  /** Request the list of currently connected browser runtimes. Handled by the Vite plugin, not forwarded to a runtime. */
51
65
  export const RequestListRuntimes = ts('RequestListRuntimes');
52
66
  /** A request from the MCP server. RequestListRuntimes is handled at the Vite plugin layer; all other requests are routed to a browser runtime. */
53
- export const Request = S.Union(RequestGetModel, RequestListMessages, RequestGetMessage, RequestListKeyframes, RequestReplayToKeyframe, RequestResume, RequestDispatchMessage, RequestListRuntimes);
67
+ export const Request = S.Union(RequestGetModel, RequestGetModelAt, RequestListMessages, RequestGetMessage, RequestListKeyframes, RequestReplayToKeyframe, RequestResume, RequestDispatchMessage, RequestListRuntimes, RequestGetInit, RequestGetRuntimeState);
54
68
  // RESPONSE
55
- /** Response carrying the current Model snapshot. */
69
+ /** Response carrying a Model snapshot. The `value` is the resolved subtree at `atPath` (or the whole Model when no path was supplied). When `summarized` is true, large arrays/records/strings have been collapsed to `_summary` placeholders to keep payloads small for AI agents; pass `expand: true` on the Request to receive the literal value. */
56
70
  export const ResponseModel = ts('ResponseModel', {
57
- model: S.Unknown,
71
+ value: S.Unknown,
72
+ atPath: S.String,
73
+ summarized: S.Boolean,
58
74
  });
59
75
  /** Response carrying a page of history entries. `maybeNextIndex` is `Some` when more entries are available beyond this page (pass it as `RequestListMessages.maybeSinceIndex` to fetch the next page) and `None` when this page reaches the current end of history. */
60
76
  export const ResponseMessages = ts('ResponseMessages', {
61
77
  entries: S.Array(SerializedEntry),
62
78
  maybeNextIndex: S.Option(S.Number),
63
79
  });
64
- /** Response carrying a single history entry with surrounding Model snapshots. */
80
+ /** Response carrying a single history entry. Model snapshots are not included; use `RequestGetModelAt` with `index - 1` and `index` to inspect Model state around the entry. */
65
81
  export const ResponseMessage = ts('ResponseMessage', {
66
82
  entry: SerializedEntry,
67
- modelBefore: S.Unknown,
68
- modelAfter: S.Unknown,
69
83
  });
70
84
  /** Response carrying the list of available keyframes. */
71
85
  export const ResponseKeyframes = ts('ResponseKeyframes', {
@@ -85,14 +99,28 @@ export const ResponseDispatched = ts('ResponseDispatched', {
85
99
  export const ResponseRuntimes = ts('ResponseRuntimes', {
86
100
  runtimes: S.Array(RuntimeInfo),
87
101
  });
102
+ /** Response carrying the recorded init data. `maybeModel` is `None` until the runtime has finished its first render and recorded init; once set it stays set for the rest of the runtime's life. `commandNames` lists the Commands returned from the application's `init` function in the order they were produced. */
103
+ export const ResponseInit = ts('ResponseInit', {
104
+ maybeModel: S.Option(S.Unknown),
105
+ commandNames: S.Array(S.String),
106
+ });
107
+ /** Response carrying a snapshot of the runtime's DevTools state. `currentIndex` is the absolute index of the most recently recorded Message, or -1 when no Messages have been recorded yet. `startIndex` is the earliest absolute index still retained in the rolling buffer (older entries are evicted past `maxEntries`). `totalEntries` is the number of retained entries. `isPaused` is true while the runtime is paused at a replayed snapshot; `maybePausedAtIndex` is `Some(index)` then and `None` otherwise. `hasInitModel` is true once the runtime has finished initialising. */
108
+ export const ResponseRuntimeState = ts('ResponseRuntimeState', {
109
+ currentIndex: S.Number,
110
+ startIndex: S.Number,
111
+ totalEntries: S.Number,
112
+ isPaused: S.Boolean,
113
+ maybePausedAtIndex: S.Option(S.Number),
114
+ hasInitModel: S.Boolean,
115
+ });
88
116
  /** Response carrying an error reason for a failed Request. */
89
117
  export const ResponseError = ts('ResponseError', {
90
118
  reason: S.String,
91
119
  });
92
120
  /** A response replying to a Request. */
93
- export const Response = S.Union(ResponseModel, ResponseMessages, ResponseMessage, ResponseKeyframes, ResponseReplayed, ResponseResumed, ResponseDispatched, ResponseRuntimes, ResponseError);
121
+ export const Response = S.Union(ResponseModel, ResponseMessages, ResponseMessage, ResponseKeyframes, ResponseReplayed, ResponseResumed, ResponseDispatched, ResponseRuntimes, ResponseInit, ResponseRuntimeState, ResponseError);
94
122
  // EVENT
95
- /** A new browser runtime connected. The `runtime.maybeMessageSchema` field carries the runtime's Message Schema (as JSON Schema) when the runtime exposes one via `DevToolsConfig.Message`. */
123
+ /** A new browser runtime connected. */
96
124
  export const EventConnected = ts('EventConnected', {
97
125
  runtime: RuntimeInfo,
98
126
  });
@@ -1,2 +1,2 @@
1
- export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, RequestDispatchMessage, RequestFrame, RequestGetMessage, RequestGetModel, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseError, ResponseFrame, ResponseKeyframes, ResponseMessage, ResponseMessages, ResponseModel, ResponseReplayed, ResponseResumed, ResponseRuntimes, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
1
+ export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, RequestDispatchMessage, RequestFrame, RequestGetInit, RequestGetMessage, RequestGetModel, RequestGetModelAt, RequestGetRuntimeState, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessages, ResponseModel, ResponseReplayed, ResponseResumed, ResponseRuntimes, ResponseRuntimeState, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
2
2
  //# sourceMappingURL=public.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/devTools/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,KAAK,EACL,YAAY,EACZ,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,eAAe,GAChB,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/devTools/public.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,UAAU,EACV,KAAK,EACL,YAAY,EACZ,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACX,eAAe,GAChB,MAAM,eAAe,CAAA"}
@@ -1 +1 @@
1
- export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, RequestDispatchMessage, RequestFrame, RequestGetMessage, RequestGetModel, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseError, ResponseFrame, ResponseKeyframes, ResponseMessage, ResponseMessages, ResponseModel, ResponseReplayed, ResponseResumed, ResponseRuntimes, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
1
+ export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, RequestDispatchMessage, RequestFrame, RequestGetInit, RequestGetMessage, RequestGetModel, RequestGetModelAt, RequestGetRuntimeState, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessages, ResponseModel, ResponseReplayed, ResponseResumed, ResponseRuntimes, ResponseRuntimeState, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
@@ -1 +1 @@
1
- {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/devTools/serialize.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OAiBjD,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,YAAY,EACnB,OAAO,MAAM,KACZ,eASD,CAAA"}
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/devTools/serialize.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG9C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,OAiBjD,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,OAAO,YAAY,EACnB,OAAO,MAAM,KACZ,eAkBF,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { Array as Array_, Function, HashSet, Match as M, Predicate, Record, } from 'effect';
2
+ import { extractSubmodelInfo } from './submodelPath.js';
2
3
  /**
3
4
  * Convert DOM-class instances (File, Blob, Date, URL) to plain-object
4
5
  * representations so the tree renderer's key-enumeration walk can see their
@@ -22,13 +23,18 @@ export const toInspectableValue = (value) => M.value(value).pipe(M.when(M.instan
22
23
  * plain string arrays for JSON transmission and runs the message body through
23
24
  * `toInspectableValue` so DOM-class instances become inspectable objects.
24
25
  */
25
- export const toSerializedEntry = (entry, index) => ({
26
- index,
27
- tag: entry.tag,
28
- message: toInspectableValue(entry.message),
29
- commandNames: entry.commandNames,
30
- timestamp: entry.timestamp,
31
- isModelChanged: entry.isModelChanged,
32
- changedPaths: HashSet.toValues(entry.diff.changedPaths),
33
- affectedPaths: HashSet.toValues(entry.diff.affectedPaths),
34
- });
26
+ export const toSerializedEntry = (entry, index) => {
27
+ const { submodelPath, maybeLeafTag } = extractSubmodelInfo(entry.tag, entry.message);
28
+ return {
29
+ index,
30
+ tag: entry.tag,
31
+ message: toInspectableValue(entry.message),
32
+ commandNames: entry.commandNames,
33
+ timestamp: entry.timestamp,
34
+ isModelChanged: entry.isModelChanged,
35
+ changedPaths: HashSet.toValues(entry.diff.changedPaths),
36
+ affectedPaths: HashSet.toValues(entry.diff.affectedPaths),
37
+ submodelPath,
38
+ maybeLeafTag,
39
+ };
40
+ };
@@ -0,0 +1,27 @@
1
+ import { Option } from 'effect';
2
+ export declare const GOT_MESSAGE_PATTERN: RegExp;
3
+ export declare const isTagged: (u: unknown, overrideOptions?: import("effect/SchemaAST").ParseOptions | number) => u is {
4
+ readonly _tag: string;
5
+ };
6
+ /** Submodel chain information extracted from a recorded Message. */
7
+ export type SubmodelInfo = Readonly<{
8
+ submodelPath: ReadonlyArray<string>;
9
+ maybeLeafTag: Option.Option<string>;
10
+ }>;
11
+ /**
12
+ * Walk a chain of `Got<Submodel>Message` wrappers in a recorded Message and
13
+ * return the wrapper tags plus the innermost leaf tag.
14
+ *
15
+ * The Submodel pattern propagates child Messages up to a parent by wrapping
16
+ * them in `GotChildMessage({ message: childMessage })`. Nested submodels stack
17
+ * those wrappers. Walking the chain reveals the parent → child → grandchild
18
+ * dispatch path that produced the entry.
19
+ *
20
+ * Returns an empty path and `Option.none` for top-level Messages whose tag
21
+ * doesn't match the `Got*Message` pattern. Otherwise the path lists wrapper
22
+ * tags from outer to inner, and `maybeLeafTag` is `Some` when the innermost
23
+ * wrapped value is itself a tagged Message (the underlying child Message that
24
+ * originated the chain).
25
+ */
26
+ export declare const extractSubmodelInfo: (tag: string, message: unknown) => SubmodelInfo;
27
+ //# sourceMappingURL=submodelPath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submodelPath.d.ts","sourceRoot":"","sources":["../../src/devTools/submodelPath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,QAAQ,CAAA;AAElD,eAAO,MAAM,mBAAmB,QAAmB,CAAA;AAGnD,eAAO,MAAM,QAAQ;;CAAe,CAAA;AAEpC,oEAAoE;AACpE,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;CACpC,CAAC,CAAA;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,GAC9B,KAAK,MAAM,EACX,SAAS,OAAO,KACf,YAuBF,CAAA"}