foldkit 0.132.0 → 0.133.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 +51 -96
- package/dist/devTools/protocol.d.ts +19 -1
- package/dist/devTools/protocol.d.ts.map +1 -1
- package/dist/devTools/protocol.js +13 -1
- package/dist/devTools/public.d.ts +1 -1
- package/dist/devTools/public.d.ts.map +1 -1
- package/dist/devTools/public.js +1 -1
- package/dist/devTools/store.d.ts +6 -0
- package/dist/devTools/store.d.ts.map +1 -1
- package/dist/devTools/store.js +7 -1
- package/dist/devTools/webSocketBridge.d.ts +7 -0
- package/dist/devTools/webSocketBridge.d.ts.map +1 -1
- package/dist/devTools/webSocketBridge.js +36 -8
- package/dist/html/boundary.d.ts.map +1 -1
- package/dist/html/boundary.js +48 -2
- package/dist/html/index.d.ts +21 -6
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +4 -1
- package/dist/html/public.d.ts +1 -1
- package/dist/html/public.d.ts.map +1 -1
- package/dist/html/public.js +1 -1
- package/dist/route/transition.d.ts +35 -29
- package/dist/route/transition.d.ts.map +1 -1
- package/dist/route/transition.js +36 -30
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +16 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -13,33 +13,21 @@
|
|
|
13
13
|
<h3 align="center">The frontend framework for correctness.</h3>
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
|
-
<a href="https://foldkit.dev"><strong>Documentation</strong></a> · <a href="https://foldkit.dev/get-started/manifesto"><strong>Manifesto</strong></a> · <a href="https://foldkit.dev/example-apps"><strong>Examples</strong></a> · <a href="https://foldkit.dev/get-started/getting-started"><strong>Getting Started</strong></a>
|
|
16
|
+
<a href="https://foldkit.dev"><strong>Documentation</strong></a> · <a href="https://foldkit.dev/get-started/manifesto"><strong>Manifesto</strong></a> · <a href="https://foldkit.dev/example-apps"><strong>Examples</strong></a> · <a href="https://foldkit.dev/get-started/getting-started"><strong>Getting Started</strong></a> · <a href="https://discord.gg/kav8VNxqGm"><strong>Discord</strong></a>
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Foldkit is a TypeScript frontend framework built on [Effect](https://effect.website/) and architected like [Elm](https://guide.elm-lang.org/architecture/). One Model, one update function, one way to do things. No hooks, no local state, no hidden mutations. It's all in on Effect with no escape hatch, though a program doesn't have to own the whole page: [`Runtime.embed`](https://foldkit.dev/core/embedding) runs a Foldkit widget inside any existing app, React included.
|
|
22
|
+
|
|
23
|
+
Your Model is a [Schema](https://effect.website/docs/schema/introduction/) and side effects are values you return, not callbacks you fire. If you know Effect, Foldkit feels natural. If you're new to it, Foldkit is a good way in. Coming from React? [Start here](https://foldkit.dev/react/coming-from-react), or read the [same pixel-art editor built in both frameworks](https://foldkit.dev/react/foldkit-vs-react-side-by-side).
|
|
22
24
|
|
|
23
25
|
> [!NOTE]
|
|
24
26
|
> Foldkit is pre-1.0. The core API is stable, but breaking changes may occur in minor releases. See the [changelog](./CHANGELOG.md) for details.
|
|
25
27
|
|
|
26
|
-
## Who It's For
|
|
27
|
-
|
|
28
|
-
Foldkit is for developers who want to build their product with confidence instead of fighting their architecture. If you want a single pattern that scales from a counter to a multiplayer game without complexity creep, this is it.
|
|
29
|
-
|
|
30
|
-
It's not incremental. There's no React interop, no escape hatch from Effect, no way to "just use hooks for this one part." You're all in or you're not.
|
|
31
|
-
|
|
32
|
-
## Built on Effect
|
|
33
|
-
|
|
34
|
-
Every Foldkit application is an [Effect](https://effect.website/) program. Your Model is a [Schema](https://effect.website/docs/schema/introduction/). Side effects are values you return as Commands to the runtime, not callbacks you fire. If you already know Effect, Foldkit feels natural. If you're new to Effect, Foldkit is a great way to immerse yourself in it.
|
|
35
|
-
|
|
36
|
-
## Coming from React?
|
|
37
|
-
|
|
38
|
-
[Coming from React](https://foldkit.dev/react/coming-from-react) is a guided walk through the differences. [Foldkit vs React: Side by Side](https://foldkit.dev/react/foldkit-vs-react-side-by-side) implements the same pixel-art editor in both frameworks so you can read them line by line.
|
|
39
|
-
|
|
40
28
|
## Get Started
|
|
41
29
|
|
|
42
|
-
`create-foldkit-app`
|
|
30
|
+
`create-foldkit-app` scaffolds a complete setup with Tailwind, TypeScript, [Oxlint](https://foldkit.dev/tooling/oxlint-plugin), Prettier, and the Vite plugin for state-preserving HMR, starting from an example you choose.
|
|
43
31
|
|
|
44
32
|
```bash
|
|
45
33
|
npx create-foldkit-app@latest
|
|
@@ -47,9 +35,7 @@ npx create-foldkit-app@latest
|
|
|
47
35
|
|
|
48
36
|
## Counter
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
`src/main.ts` defines the program. `src/entry.ts` boots the runtime. The split keeps `main.ts` importable from tests without booting a runtime as a side effect.
|
|
38
|
+
A complete Foldkit program. State lives in a single Model, events become Messages, and a pure function handles every transition. `main.ts` defines the program and `entry.ts` boots the runtime, so `main.ts` stays importable from tests without booting a runtime as a side effect.
|
|
53
39
|
|
|
54
40
|
```ts
|
|
55
41
|
// src/main.ts
|
|
@@ -108,41 +94,16 @@ export const view = (model: Model): Document => {
|
|
|
108
94
|
return {
|
|
109
95
|
title: `Counter: ${model.count}`,
|
|
110
96
|
body: h.div(
|
|
97
|
+
[],
|
|
111
98
|
[
|
|
112
|
-
h.
|
|
113
|
-
|
|
114
|
-
),
|
|
115
|
-
|
|
116
|
-
[
|
|
117
|
-
h.div(
|
|
118
|
-
[h.Class('text-6xl font-bold text-gray-800')],
|
|
119
|
-
[model.count.toString()],
|
|
120
|
-
),
|
|
121
|
-
h.div(
|
|
122
|
-
[h.Class('flex flex-wrap justify-center gap-4')],
|
|
123
|
-
[
|
|
124
|
-
h.button(
|
|
125
|
-
[h.OnClick(ClickedDecrement()), h.Class(buttonStyle)],
|
|
126
|
-
['-'],
|
|
127
|
-
),
|
|
128
|
-
h.button(
|
|
129
|
-
[h.OnClick(ClickedReset()), h.Class(buttonStyle)],
|
|
130
|
-
['Reset'],
|
|
131
|
-
),
|
|
132
|
-
h.button(
|
|
133
|
-
[h.OnClick(ClickedIncrement()), h.Class(buttonStyle)],
|
|
134
|
-
['+'],
|
|
135
|
-
),
|
|
136
|
-
],
|
|
137
|
-
),
|
|
99
|
+
h.p([], [model.count.toString()]),
|
|
100
|
+
h.button([h.OnClick(ClickedDecrement())], ['-']),
|
|
101
|
+
h.button([h.OnClick(ClickedReset())], ['Reset']),
|
|
102
|
+
h.button([h.OnClick(ClickedIncrement())], ['+']),
|
|
138
103
|
],
|
|
139
104
|
),
|
|
140
105
|
}
|
|
141
106
|
}
|
|
142
|
-
|
|
143
|
-
// STYLE
|
|
144
|
-
|
|
145
|
-
const buttonStyle = 'bg-black text-white hover:bg-gray-700 px-4 py-2 transition'
|
|
146
107
|
```
|
|
147
108
|
|
|
148
109
|
```ts
|
|
@@ -162,62 +123,56 @@ const application = Runtime.makeApplication({
|
|
|
162
123
|
Runtime.run(application)
|
|
163
124
|
```
|
|
164
125
|
|
|
165
|
-
Source: [examples/counter
|
|
126
|
+
Source: [examples/counter](https://github.com/foldkit/foldkit/blob/main/examples/counter/src/main.ts).
|
|
166
127
|
|
|
167
128
|
## What Ships With Foldkit
|
|
168
129
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
- **Commands**: Side effects
|
|
172
|
-
- **
|
|
173
|
-
- **
|
|
174
|
-
- **
|
|
175
|
-
- **
|
|
176
|
-
- **Submodels**: A
|
|
177
|
-
- **OutMessage**: A typed channel for a child Submodel to emit domain events up to its parent
|
|
178
|
-
- **
|
|
179
|
-
- **
|
|
180
|
-
- **Field Validation**: Per-field validation state modeled as a discriminated union.
|
|
181
|
-
- **Virtual DOM**: Declarative views powered by [Snabbdom](https://github.com/snabbdom/snabbdom)
|
|
182
|
-
- **DevTools**:
|
|
183
|
-
- **DevTools MCP**: Expose a running
|
|
184
|
-
- **Crash View and Reporting**:
|
|
185
|
-
- **Story Testing**: Exercise the update function directly
|
|
186
|
-
- **Scene Testing**: Drive your
|
|
187
|
-
- **Slow Warnings**:
|
|
130
|
+
A complete system, not a collection of libraries you stitch together. Each of these is documented in depth at [foldkit.dev](https://foldkit.dev).
|
|
131
|
+
|
|
132
|
+
- **Commands**: Side effects as named Effects that return Messages and are run by the runtime.
|
|
133
|
+
- **Routing**: Type-safe bidirectional routing from parser combinators. URLs parse to Routes, Routes build URLs.
|
|
134
|
+
- **Subscriptions**: External event streams declared as a function of the Model.
|
|
135
|
+
- **Managed Resources**: Model-driven lifecycle for WebSockets, AudioContext, and other long-lived handles.
|
|
136
|
+
- **Mount**: The seam where view code hands a real DOM element to a third-party library that owns its own DOM.
|
|
137
|
+
- **Submodels**: A self-contained Model, update, and view that a parent embeds, wrapping child Messages in a `Got*` envelope.
|
|
138
|
+
- **OutMessage**: A typed channel for a child Submodel to emit domain events up to its parent.
|
|
139
|
+
- **Embedding**: Run a Foldkit program inside a host app through Schema-typed Ports with `Runtime.embed`.
|
|
140
|
+
- **UI Components**: Accessible, keyboard-friendly primitives in the `@foldkit/ui` package.
|
|
141
|
+
- **Field Validation**: Per-field validation state modeled as a discriminated union.
|
|
142
|
+
- **Virtual DOM**: Declarative views with lazy memoization and keyed diffing, powered by [Snabbdom](https://github.com/snabbdom/snabbdom).
|
|
143
|
+
- **DevTools**: In-browser overlay for inspecting Messages, Model, and Commands, with time-travel.
|
|
144
|
+
- **DevTools MCP**: Expose a running app to AI agents over the Model Context Protocol.
|
|
145
|
+
- **Crash View and Reporting**: A custom fallback UI when the update loop throws, plus a report callback.
|
|
146
|
+
- **Story Testing**: Exercise the update function directly, resolving Commands inline. No mocks, no fake timers.
|
|
147
|
+
- **Scene Testing**: Drive your real view the way a user does, with accessible locators. No browser required.
|
|
148
|
+
- **Slow Warnings**: Development warnings when update, view, patch, or Subscription extraction exceeds its budget.
|
|
188
149
|
- **HMR**: Vite plugin with state-preserving hot module replacement. Change your view, keep your state.
|
|
189
150
|
|
|
190
151
|
## Correctness You (And Your LLM) Can See
|
|
191
152
|
|
|
192
|
-
Every state change flows through one update function
|
|
193
|
-
|
|
194
|
-
This is what makes Foldkit unusually AI-friendly. The same property that makes the code easy for humans to reason about makes it easy for LLMs to generate and review. The architecture makes correctness visible, whether the reader is a person or an LLM.
|
|
153
|
+
Every state change flows through one update function, and every side effect is declared explicitly. You don't have to hold a mental model of what runs when, you can point at it. That's what makes Foldkit unusually AI-friendly: the property that makes the code easy for humans to reason about makes it easy for an LLM to generate and review.
|
|
195
154
|
|
|
196
155
|
## Examples
|
|
197
156
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
- **[
|
|
201
|
-
- **[
|
|
202
|
-
- **[
|
|
203
|
-
- **[
|
|
204
|
-
- **[
|
|
205
|
-
- **[
|
|
206
|
-
- **[Routing](https://foldkit.dev/example-apps/routing)
|
|
207
|
-
- **[
|
|
208
|
-
- **[
|
|
209
|
-
- **[
|
|
210
|
-
- **[Auth](https://foldkit.dev/example-apps/auth)
|
|
211
|
-
- **[Shopping Cart](https://foldkit.dev/example-apps/shopping-cart)
|
|
212
|
-
- **[
|
|
213
|
-
- **[
|
|
214
|
-
- **[
|
|
215
|
-
- **[
|
|
216
|
-
- **[
|
|
217
|
-
- **[Web Components](https://foldkit.dev/example-apps/web-components)**: QR code designer wiring two real third-party web components into Foldkit with `CustomElement.define` (vanilla-colorful + Shoelace)
|
|
218
|
-
- **[Embedding](https://foldkit.dev/example-apps/embedding)** — A Foldkit widget embedded in a plain TypeScript host page via `Runtime.embed`, with typed Ports in both directions and `dispose` on unmount
|
|
219
|
-
- **[UI Showcase](https://foldkit.dev/example-apps/ui-showcase)** — Interactive showcase of every Foldkit UI component
|
|
220
|
-
- **[Typing Game](https://github.com/foldkit/foldkit/tree/main/packages/typing-game)** — Multiplayer typing game with Effect RPC backend ([play it live](https://typingterminal.com))
|
|
157
|
+
Some of what you can build with Foldkit. [See all example apps on foldkit.dev](https://foldkit.dev/example-apps).
|
|
158
|
+
|
|
159
|
+
- **[Counter](https://foldkit.dev/example-apps/counter)**: Increment/decrement with reset
|
|
160
|
+
- **[Todo](https://foldkit.dev/example-apps/todo)**: CRUD operations with localStorage persistence
|
|
161
|
+
- **[Form](https://foldkit.dev/example-apps/form)**: Form validation with async email checking
|
|
162
|
+
- **[Job Application](https://foldkit.dev/example-apps/job-application)**: Multi-step form with cross-field validation, file uploads, and per-step error indicators
|
|
163
|
+
- **[Weather](https://foldkit.dev/example-apps/weather)**: HTTP requests with async state handling
|
|
164
|
+
- **[API Cache](https://foldkit.dev/example-apps/api-cache)**: Query caching with stale-while-revalidate, request deduplication, and interval refetching
|
|
165
|
+
- **[Routing](https://foldkit.dev/example-apps/routing)**: URL routing with parser combinators
|
|
166
|
+
- **[Route Transitions](https://foldkit.dev/example-apps/route-transitions)**: Live transition log with entry, exit, and stayed navigation policies
|
|
167
|
+
- **[Query Sync](https://foldkit.dev/example-apps/query-sync)**: URL query parameter sync with filtering and sorting
|
|
168
|
+
- **[Snake](https://foldkit.dev/example-apps/snake)**: Classic game built with Subscriptions
|
|
169
|
+
- **[Auth](https://foldkit.dev/example-apps/auth)**: Authentication flow with Submodels and OutMessage
|
|
170
|
+
- **[Shopping Cart](https://foldkit.dev/example-apps/shopping-cart)**: Nested models and complex state
|
|
171
|
+
- **[WebSocket Chat](https://foldkit.dev/example-apps/websocket-chat)**: Managed Resources with WebSocket integration
|
|
172
|
+
- **[Kanban](https://foldkit.dev/example-apps/kanban)**: Drag-and-drop kanban board with cross-column reordering and keyboard navigation
|
|
173
|
+
- **[Pixel Art](https://foldkit.dev/example-apps/pixel-art)**: Grid-based pixel editor with painting, erasing, and palette selection
|
|
174
|
+
- **[UI Showcase](https://foldkit.dev/example-apps/ui-showcase)**: Interactive showcase of every Foldkit UI component
|
|
175
|
+
- **[Typing Game](https://github.com/foldkit/foldkit/tree/main/packages/typing-game)**: Multiplayer typing game with Effect RPC backend ([play it live](https://typingterminal.com))
|
|
221
176
|
|
|
222
177
|
## License
|
|
223
178
|
|
|
@@ -102,6 +102,12 @@ export declare const RequestGetRuntimeState: import("../schema/index.js").Callab
|
|
|
102
102
|
export declare const RequestDispatchMessage: import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessage", {
|
|
103
103
|
message: S.Unknown;
|
|
104
104
|
}>;
|
|
105
|
+
/** The largest batch `RequestDispatchMessages` accepts. Matches the DevTools store's default history size, so a batch cannot evict its own earliest entries before the caller reads them back. The runtime rejects a larger batch with `ResponseError`, and MCP clients reject it earlier still, at their own input boundary. */
|
|
106
|
+
export declare const MAX_DISPATCH_BATCH_SIZE = 100;
|
|
107
|
+
/** Request the runtime dispatch an ordered batch of Messages at the current state. Payloads are opaque to the protocol; the runtime decodes every entry against the app's Message Schema before dispatching any of them, so one invalid entry rejects the whole batch and no Message from it is dispatched. Decoded Messages dispatch in array order through the same path as single dispatch, so the runtime may still record its own Messages between entries, exactly as with rapid user input. Batches larger than `MAX_DISPATCH_BATCH_SIZE` are rejected outright. */
|
|
108
|
+
export declare const RequestDispatchMessages: import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessages", {
|
|
109
|
+
messages: S.$Array<S.Unknown>;
|
|
110
|
+
}>;
|
|
105
111
|
/** Request a description of the app's Message Schema. The runtime derives a JSON Schema document once at bridge boot from the configured `DevToolsConfig.Message`; the response is `None` when no Message Schema was configured. With `maybeVariantTag: None`, the response carries a small variant index (tag names plus payload field names and a tagged-union indicator) so MCP clients can enumerate the top-level variants without paying for the full schema. With `maybeVariantTag: Some(path)`, the value is interpreted as a dot-separated path of variant `_tag` values walked through each variant's single tagged-union payload field; the response carries the JSON Schema document narrowed along that chain, with any deeper unions collapsed to summary placeholders. Use the index to discover variants, then fetch one variant before calling `RequestDispatchMessage`. */
|
|
106
112
|
export declare const RequestGetMessageSchema: import("../schema/index.js").CallableTaggedStruct<"RequestGetMessageSchema", {
|
|
107
113
|
maybeVariantTag: S.OptionFromNullOr<S.String>;
|
|
@@ -134,6 +140,8 @@ export declare const Request: S.Union<readonly [import("../schema/index.js").Cal
|
|
|
134
140
|
keyframeIndex: S.Number;
|
|
135
141
|
}>, import("../schema/index.js").CallableTaggedStruct<"RequestResume", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessage", {
|
|
136
142
|
message: S.Unknown;
|
|
143
|
+
}>, import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessages", {
|
|
144
|
+
messages: S.$Array<S.Unknown>;
|
|
137
145
|
}>, import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetInit", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetRuntimeState", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetMessageSchema", {
|
|
138
146
|
maybeVariantTag: S.OptionFromNullOr<S.String>;
|
|
139
147
|
}>]>;
|
|
@@ -265,10 +273,14 @@ export declare const ResponseReplayed: import("../schema/index.js").CallableTagg
|
|
|
265
273
|
}>;
|
|
266
274
|
/** Response confirming the runtime resumed normal execution. */
|
|
267
275
|
export declare const ResponseResumed: import("../schema/index.js").CallableTaggedStruct<"ResponseResumed", {}>;
|
|
268
|
-
/** Response confirming a Message was dispatched. The `acceptedAtIndex` is the absolute history index where the entry is predicted to land. Computed from the runtime's history length at dispatch time. The runtime processes Messages in arrival order
|
|
276
|
+
/** Response confirming a Message was dispatched. The `acceptedAtIndex` is the absolute history index where the entry is predicted to land. Computed from the runtime's history length at dispatch time. The runtime processes Messages in arrival order, so the index is reliable whenever the bridge is the only Message source, but the app produces its own Messages too (user input, Subscription emissions, Command results); one recorded between the snapshot and the dispatch shifts the entry past this index. Messages excluded from history via `excludeFromHistory` still drive `update` but are never recorded, so no entry lands at the predicted index for them, and a Message dispatched into a crashed or disposed runtime is dropped without recording anything. */
|
|
269
277
|
export declare const ResponseDispatched: import("../schema/index.js").CallableTaggedStruct<"ResponseDispatched", {
|
|
270
278
|
acceptedAtIndex: S.Number;
|
|
271
279
|
}>;
|
|
280
|
+
/** Response confirming a batch dispatch. `acceptedAtIndices` aligns with the request's `messages` order; each value is the absolute history index where that entry is predicted to land, computed from one history snapshot at dispatch time with the same caveats as `ResponseDispatched.acceptedAtIndex`. An `excludeFromHistory` Message inside the batch records no entry, so entries after it land below their predicted index. */
|
|
281
|
+
export declare const ResponseDispatchedBatch: import("../schema/index.js").CallableTaggedStruct<"ResponseDispatchedBatch", {
|
|
282
|
+
acceptedAtIndices: S.$Array<S.Number>;
|
|
283
|
+
}>;
|
|
272
284
|
/** One variant entry in a `MessageSchemaIndex`. `payloadFields` lists the variant's payload property names (excluding `_tag`); `unionFields` lists the subset of those properties whose schemas are themselves `_tag`-discriminated unions. A Submodel-wrapper variant always shows up with `unionFields: ['message']`, but the same flag also catches plain tagged-union value types like `UrlRequest = Internal | External`. Either way, the agent will need to pick a variant when filling these fields. */
|
|
273
285
|
export declare const MessageSchemaIndexEntry: S.Struct<{
|
|
274
286
|
readonly tag: S.String;
|
|
@@ -443,6 +455,8 @@ export declare const Response: S.Union<readonly [import("../schema/index.js").Ca
|
|
|
443
455
|
model: S.Unknown;
|
|
444
456
|
}>, import("../schema/index.js").CallableTaggedStruct<"ResponseResumed", {}>, import("../schema/index.js").CallableTaggedStruct<"ResponseDispatched", {
|
|
445
457
|
acceptedAtIndex: S.Number;
|
|
458
|
+
}>, import("../schema/index.js").CallableTaggedStruct<"ResponseDispatchedBatch", {
|
|
459
|
+
acceptedAtIndices: S.$Array<S.Number>;
|
|
446
460
|
}>, import("../schema/index.js").CallableTaggedStruct<"ResponseRuntimes", {
|
|
447
461
|
runtimes: S.$Array<S.Struct<{
|
|
448
462
|
readonly connectionId: S.String;
|
|
@@ -536,6 +550,8 @@ export declare const RequestFrame: S.Struct<{
|
|
|
536
550
|
keyframeIndex: S.Number;
|
|
537
551
|
}>, import("../schema/index.js").CallableTaggedStruct<"RequestResume", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessage", {
|
|
538
552
|
message: S.Unknown;
|
|
553
|
+
}>, import("../schema/index.js").CallableTaggedStruct<"RequestDispatchMessages", {
|
|
554
|
+
messages: S.$Array<S.Unknown>;
|
|
539
555
|
}>, import("../schema/index.js").CallableTaggedStruct<"RequestListRuntimes", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetInit", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetRuntimeState", {}>, import("../schema/index.js").CallableTaggedStruct<"RequestGetMessageSchema", {
|
|
540
556
|
maybeVariantTag: S.OptionFromNullOr<S.String>;
|
|
541
557
|
}>]>;
|
|
@@ -626,6 +642,8 @@ export declare const ResponseFrame: S.Struct<{
|
|
|
626
642
|
model: S.Unknown;
|
|
627
643
|
}>, import("../schema/index.js").CallableTaggedStruct<"ResponseResumed", {}>, import("../schema/index.js").CallableTaggedStruct<"ResponseDispatched", {
|
|
628
644
|
acceptedAtIndex: S.Number;
|
|
645
|
+
}>, import("../schema/index.js").CallableTaggedStruct<"ResponseDispatchedBatch", {
|
|
646
|
+
acceptedAtIndices: S.$Array<S.Number>;
|
|
629
647
|
}>, import("../schema/index.js").CallableTaggedStruct<"ResponseRuntimes", {
|
|
630
648
|
runtimes: S.$Array<S.Struct<{
|
|
631
649
|
readonly connectionId: S.String;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/devTools/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAM5C,0NAA0N;AAC1N,eAAO,MAAM,iBAAiB;;;EAG5B,CAAA;AACF,2EAA2E;AAC3E,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAA;AAE7D,0MAA0M;AAC1M,eAAO,MAAM,eAAe;;;EAG1B,CAAA;AACF,yFAAyF;AACzF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAEzD,wfAAwf;AACxf,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;EAa1B,CAAA;AACF,iFAAiF;AACjF,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAEzD,wHAAwH;AACxH,eAAO,MAAM,YAAY;;EAEvB,CAAA;AACF,wCAAwC;AACxC,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAA;AAEnD,kDAAkD;AAClD,eAAO,MAAM,WAAW;;;;EAItB,CAAA;AACF,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAA;AAIjD,yFAAyF;AACzF,eAAO,MAAM,eAAe;;;EAG1B,CAAA;AAEF,8JAA8J;AAC9J,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAA;AAEF,2pBAA2pB;AAC3pB,eAAO,MAAM,mBAAmB;;;;;EAO9B,CAAA;AAEF,sPAAsP;AACtP,eAAO,MAAM,yBAAyB;;;EAGpC,CAAA;AAEF,8TAA8T;AAC9T,eAAO,MAAM,iBAAiB;;;;EAI5B,CAAA;AAEF,8JAA8J;AAC9J,eAAO,MAAM,iBAAiB;;EAE5B,CAAA;AAEF,+CAA+C;AAC/C,eAAO,MAAM,oBAAoB,+EAA6B,CAAA;AAE9D,mHAAmH;AACnH,eAAO,MAAM,uBAAuB;;EAElC,CAAA;AAEF,uEAAuE;AACvE,eAAO,MAAM,aAAa,wEAAsB,CAAA;AAEhD,wGAAwG;AACxG,eAAO,MAAM,cAAc,yEAAuB,CAAA;AAElD,oIAAoI;AACpI,eAAO,MAAM,sBAAsB,iFAA+B,CAAA;AAElE,kKAAkK;AAClK,eAAO,MAAM,sBAAsB;;EAEjC,CAAA;AAEF,61BAA61B;AAC71B,eAAO,MAAM,uBAAuB;;EAElC,CAAA;AAEF,wHAAwH;AACxH,eAAO,MAAM,mBAAmB,8EAA4B,CAAA;AAE5D,kJAAkJ;AAClJ,eAAO,MAAM,OAAO
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/devTools/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,6 +86,12 @@ export const RequestGetRuntimeState = ts('RequestGetRuntimeState');
|
|
|
86
86
|
export const RequestDispatchMessage = ts('RequestDispatchMessage', {
|
|
87
87
|
message: S.Unknown,
|
|
88
88
|
});
|
|
89
|
+
/** The largest batch `RequestDispatchMessages` accepts. Matches the DevTools store's default history size, so a batch cannot evict its own earliest entries before the caller reads them back. The runtime rejects a larger batch with `ResponseError`, and MCP clients reject it earlier still, at their own input boundary. */
|
|
90
|
+
export const MAX_DISPATCH_BATCH_SIZE = 100;
|
|
91
|
+
/** Request the runtime dispatch an ordered batch of Messages at the current state. Payloads are opaque to the protocol; the runtime decodes every entry against the app's Message Schema before dispatching any of them, so one invalid entry rejects the whole batch and no Message from it is dispatched. Decoded Messages dispatch in array order through the same path as single dispatch, so the runtime may still record its own Messages between entries, exactly as with rapid user input. Batches larger than `MAX_DISPATCH_BATCH_SIZE` are rejected outright. */
|
|
92
|
+
export const RequestDispatchMessages = ts('RequestDispatchMessages', {
|
|
93
|
+
messages: S.Array(S.Unknown),
|
|
94
|
+
});
|
|
89
95
|
/** Request a description of the app's Message Schema. The runtime derives a JSON Schema document once at bridge boot from the configured `DevToolsConfig.Message`; the response is `None` when no Message Schema was configured. With `maybeVariantTag: None`, the response carries a small variant index (tag names plus payload field names and a tagged-union indicator) so MCP clients can enumerate the top-level variants without paying for the full schema. With `maybeVariantTag: Some(path)`, the value is interpreted as a dot-separated path of variant `_tag` values walked through each variant's single tagged-union payload field; the response carries the JSON Schema document narrowed along that chain, with any deeper unions collapsed to summary placeholders. Use the index to discover variants, then fetch one variant before calling `RequestDispatchMessage`. */
|
|
90
96
|
export const RequestGetMessageSchema = ts('RequestGetMessageSchema', {
|
|
91
97
|
maybeVariantTag: S.OptionFromNullOr(S.String),
|
|
@@ -104,6 +110,7 @@ export const Request = S.Union([
|
|
|
104
110
|
RequestReplayToKeyframe,
|
|
105
111
|
RequestResume,
|
|
106
112
|
RequestDispatchMessage,
|
|
113
|
+
RequestDispatchMessages,
|
|
107
114
|
RequestListRuntimes,
|
|
108
115
|
RequestGetInit,
|
|
109
116
|
RequestGetRuntimeState,
|
|
@@ -165,10 +172,14 @@ export const ResponseReplayed = ts('ResponseReplayed', {
|
|
|
165
172
|
});
|
|
166
173
|
/** Response confirming the runtime resumed normal execution. */
|
|
167
174
|
export const ResponseResumed = ts('ResponseResumed');
|
|
168
|
-
/** Response confirming a Message was dispatched. The `acceptedAtIndex` is the absolute history index where the entry is predicted to land. Computed from the runtime's history length at dispatch time. The runtime processes Messages in arrival order
|
|
175
|
+
/** Response confirming a Message was dispatched. The `acceptedAtIndex` is the absolute history index where the entry is predicted to land. Computed from the runtime's history length at dispatch time. The runtime processes Messages in arrival order, so the index is reliable whenever the bridge is the only Message source, but the app produces its own Messages too (user input, Subscription emissions, Command results); one recorded between the snapshot and the dispatch shifts the entry past this index. Messages excluded from history via `excludeFromHistory` still drive `update` but are never recorded, so no entry lands at the predicted index for them, and a Message dispatched into a crashed or disposed runtime is dropped without recording anything. */
|
|
169
176
|
export const ResponseDispatched = ts('ResponseDispatched', {
|
|
170
177
|
acceptedAtIndex: S.Number,
|
|
171
178
|
});
|
|
179
|
+
/** Response confirming a batch dispatch. `acceptedAtIndices` aligns with the request's `messages` order; each value is the absolute history index where that entry is predicted to land, computed from one history snapshot at dispatch time with the same caveats as `ResponseDispatched.acceptedAtIndex`. An `excludeFromHistory` Message inside the batch records no entry, so entries after it land below their predicted index. */
|
|
180
|
+
export const ResponseDispatchedBatch = ts('ResponseDispatchedBatch', {
|
|
181
|
+
acceptedAtIndices: S.Array(S.Number),
|
|
182
|
+
});
|
|
172
183
|
/** One variant entry in a `MessageSchemaIndex`. `payloadFields` lists the variant's payload property names (excluding `_tag`); `unionFields` lists the subset of those properties whose schemas are themselves `_tag`-discriminated unions. A Submodel-wrapper variant always shows up with `unionFields: ['message']`, but the same flag also catches plain tagged-union value types like `UrlRequest = Internal | External`. Either way, the agent will need to pick a variant when filling these fields. */
|
|
173
184
|
export const MessageSchemaIndexEntry = S.Struct({
|
|
174
185
|
tag: S.String,
|
|
@@ -229,6 +240,7 @@ export const Response = S.Union([
|
|
|
229
240
|
ResponseReplayed,
|
|
230
241
|
ResponseResumed,
|
|
231
242
|
ResponseDispatched,
|
|
243
|
+
ResponseDispatchedBatch,
|
|
232
244
|
ResponseRuntimes,
|
|
233
245
|
ResponseInit,
|
|
234
246
|
ResponseRuntimeState,
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, DiffValue, DiffValueAbsent, DiffValuePresent, MessageTagCount, ModelDiffChange, RequestCountMessagesByTag, RequestDiffModels, RequestDispatchMessage, RequestFrame, RequestGetInit, RequestGetMessage, RequestGetMessageSchema, RequestGetModel, RequestGetModelAt, RequestGetRuntimeState, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessageCounts, ResponseMessages, ResponseMessageSchema, ResponseModel, ResponseModelDiff, ResponseReplayed, ResponseResumed, ResponseRuntimes, ResponseRuntimeState, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
|
|
1
|
+
export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, DiffValue, DiffValueAbsent, DiffValuePresent, MAX_DISPATCH_BATCH_SIZE, MessageTagCount, ModelDiffChange, RequestCountMessagesByTag, RequestDiffModels, RequestDispatchMessage, RequestDispatchMessages, RequestFrame, RequestGetInit, RequestGetMessage, RequestGetMessageSchema, RequestGetModel, RequestGetModelAt, RequestGetRuntimeState, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseDispatchedBatch, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessageCounts, ResponseMessages, ResponseMessageSchema, ResponseModel, ResponseModelDiff, 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,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,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,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,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,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,eAAe,EACf,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,uBAAuB,EACvB,aAAa,EACb,OAAO,EACP,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACX,eAAe,GAChB,MAAM,eAAe,CAAA"}
|
package/dist/devTools/public.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, DiffValue, DiffValueAbsent, DiffValuePresent, MessageTagCount, ModelDiffChange, RequestCountMessagesByTag, RequestDiffModels, RequestDispatchMessage, RequestFrame, RequestGetInit, RequestGetMessage, RequestGetMessageSchema, RequestGetModel, RequestGetModelAt, RequestGetRuntimeState, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessageCounts, ResponseMessages, ResponseMessageSchema, ResponseModel, ResponseModelDiff, ResponseReplayed, ResponseResumed, ResponseRuntimes, ResponseRuntimeState, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
|
|
1
|
+
export { EventConnected, EventDisconnected, EventFrame, Event, KeyframeInfo, DiffValue, DiffValueAbsent, DiffValuePresent, MAX_DISPATCH_BATCH_SIZE, MessageTagCount, ModelDiffChange, RequestCountMessagesByTag, RequestDiffModels, RequestDispatchMessage, RequestDispatchMessages, RequestFrame, RequestGetInit, RequestGetMessage, RequestGetMessageSchema, RequestGetModel, RequestGetModelAt, RequestGetRuntimeState, RequestListKeyframes, RequestListMessages, RequestListRuntimes, RequestReplayToKeyframe, RequestResume, Request, ResponseDispatched, ResponseDispatchedBatch, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessageCounts, ResponseMessages, ResponseMessageSchema, ResponseModel, ResponseModelDiff, ResponseReplayed, ResponseResumed, ResponseRuntimes, ResponseRuntimeState, Response, RuntimeInfo, SerializedEntry, } from './protocol.js';
|
package/dist/devTools/store.d.ts
CHANGED
|
@@ -45,6 +45,12 @@ export type Bridge = Readonly<{
|
|
|
45
45
|
* when no Messages have been recorded yet.
|
|
46
46
|
*/
|
|
47
47
|
export declare const latestEntryIndex: (state: StoreState) => number;
|
|
48
|
+
/**
|
|
49
|
+
* The absolute index the next recorded entry will land at. `recordMessage`
|
|
50
|
+
* assigns indices from this formula, so dispatch predictions derived from it
|
|
51
|
+
* match where entries are actually recorded.
|
|
52
|
+
*/
|
|
53
|
+
export declare const nextEntryIndex: (state: StoreState) => number;
|
|
48
54
|
/**
|
|
49
55
|
* Options for `createDevToolsStore`.
|
|
50
56
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/devTools/store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/devTools/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,OAAO,EACP,OAAO,EAEP,MAAM,EAIN,eAAe,EAEhB,MAAM,QAAQ,CAAA;AAIf,eAAO,MAAM,UAAU,KAAK,CAAA;AAM5B,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACrC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;CACvC,CAAC,CAAA;AAEF,eAAO,MAAM,SAAS,EAAE,UAGvB,CAAA;AAID,eAAO,MAAM,WAAW,GACtB,UAAU,OAAO,EACjB,SAAS,OAAO,KACf,UA4FF,CAAA;AAID,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B,CAAC,CAAA;AAEF,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B,CAAC,CAAA;AAEF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IACtC,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IACvC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,OAAO,CAAA;IACvB,IAAI,EAAE,UAAU,CAAA;CACjB,CAAC,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;IACpC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC3C,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACtC,YAAY,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IAC1C,eAAe,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IAC3C,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;CACzC,CAAC,CAAA;AAEF,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC;IAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;IACrD,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC/C,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CACvC,CAAC,CAAA;AAcF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,KAAG,MAIjD,CAAA;AAEJ;;;;GAIG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,KAAG,MACV,CAAA;AAEzC;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAC,CAAA;AAEF,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,MAAM,EACd,UAAS,0BAA+B,KACvC,MAAM,CAAC,MAAM,CAAC,aAAa,CAkR1B,CAAA;AAEJ,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,UAAU,EAAE,CACV,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,EACtC,WAAW,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,KACrC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxB,aAAa,EAAE,CACb,OAAO,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EACnC,iBAAiB,EAAE,OAAO,EAC1B,gBAAgB,EAAE,OAAO,EACzB,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,EACtC,cAAc,EAAE,OAAO,KACpB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxB,iBAAiB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1D,oBAAoB,EAAE,CACpB,WAAW,EAAE,aAAa,CAAC,WAAW,CAAC,EACvC,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,KAClC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACxB,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC1D,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3E,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IAC5D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,QAAQ,EAAE,eAAe,CAAC,eAAe,CAAC,UAAU,CAAC,CAAA;CACtD,CAAC,CAAA"}
|
package/dist/devTools/store.js
CHANGED
|
@@ -91,6 +91,12 @@ export const latestEntryIndex = (state) => Array.match(state.entries, {
|
|
|
91
91
|
onEmpty: () => INIT_INDEX,
|
|
92
92
|
onNonEmpty: entries => state.startIndex + entries.length - 1,
|
|
93
93
|
});
|
|
94
|
+
/**
|
|
95
|
+
* The absolute index the next recorded entry will land at. `recordMessage`
|
|
96
|
+
* assigns indices from this formula, so dispatch predictions derived from it
|
|
97
|
+
* match where entries are actually recorded.
|
|
98
|
+
*/
|
|
99
|
+
export const nextEntryIndex = (state) => state.startIndex + state.entries.length;
|
|
94
100
|
export const createDevToolsStore = (bridge, options = {}) => Effect.gen(function* () {
|
|
95
101
|
const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
|
|
96
102
|
const keyframeInterval = options.keyframeInterval ?? DEFAULT_KEYFRAME_INTERVAL;
|
|
@@ -135,7 +141,7 @@ export const createDevToolsStore = (bridge, options = {}) => Effect.gen(function
|
|
|
135
141
|
maybeLatestModel: () => Option.some(model),
|
|
136
142
|
}));
|
|
137
143
|
const recordMessage = (message, modelBeforeUpdate, modelAfterUpdate, commands, isModelChanged) => SubscriptionRef.update(stateRef, state => {
|
|
138
|
-
const absoluteIndex = state
|
|
144
|
+
const absoluteIndex = nextEntryIndex(state);
|
|
139
145
|
const diff = isModelChanged
|
|
140
146
|
? computeDiff(modelBeforeUpdate, modelAfterUpdate)
|
|
141
147
|
: emptyDiff;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Effect, Option, Schema as S, Scope } from 'effect';
|
|
2
|
+
import { type Request, type Response } from './protocol.js';
|
|
2
3
|
import { type DevToolsStore } from './store.js';
|
|
3
4
|
type Hot = NonNullable<ImportMeta['hot']>;
|
|
4
5
|
/**
|
|
@@ -33,5 +34,11 @@ type Hot = NonNullable<ImportMeta['hot']>;
|
|
|
33
34
|
* invoking this. The function assumes a live HMR connection.
|
|
34
35
|
*/
|
|
35
36
|
export declare const startWebSocketBridge: (store: DevToolsStore, hot: Hot, dispatch: (message: unknown) => Effect.Effect<void>, maybeMessageSchema: Option.Option<S.Codec<any, any>>) => Effect.Effect<void, never, Scope.Scope>;
|
|
37
|
+
/**
|
|
38
|
+
* Fulfill one bridge Request against the DevTools store. `startWebSocketBridge`
|
|
39
|
+
* wires this to the HMR request channel; exported so tests can drive request
|
|
40
|
+
* handling without a live HMR connection.
|
|
41
|
+
*/
|
|
42
|
+
export declare const dispatchRequest: (store: DevToolsStore, dispatch: (message: unknown) => Effect.Effect<void>, maybeDispatchSchema: Option.Option<S.Codec<any, any>>, maybeJsonSchemaDocument: Option.Option<unknown>, request: Request) => Effect.Effect<Response>;
|
|
36
43
|
export {};
|
|
37
44
|
//# sourceMappingURL=webSocketBridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webSocketBridge.d.ts","sourceRoot":"","sources":["../../src/devTools/webSocketBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAIN,MAAM,EAEN,MAAM,IAAI,CAAC,EACX,KAAK,EAGN,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"webSocketBridge.d.ts","sourceRoot":"","sources":["../../src/devTools/webSocketBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,MAAM,EAIN,MAAM,EAEN,MAAM,IAAI,CAAC,EACX,KAAK,EAGN,MAAM,QAAQ,CAAA;AAcf,OAAO,EAYL,KAAK,OAAO,EAEZ,KAAK,QAAQ,EAiBd,MAAM,eAAe,CAAA;AAatB,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,YAAY,CAAA;AAQnB,KAAK,GAAG,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;AAuBzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,aAAa,EACpB,KAAK,GAAG,EACR,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EACnD,oBAAoB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KACnD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAkGrC,CAAA;AAsIJ;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,aAAa,EACpB,UAAU,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EACnD,qBAAqB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EACrD,yBAAyB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAC/C,SAAS,OAAO,KACf,MAAM,CAAC,MAAM,CAAC,QAAQ,CA4UtB,CAAA"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Array, Cause, Effect, Exit, HashMap, Match, Option, Order, Schema as S, SubscriptionRef, pipe, } from 'effect';
|
|
2
2
|
import { OptionExt } from '../effectExtensions/index.js';
|
|
3
3
|
import { collectMatchingEntries, countEntriesByTag, findUnanchoredPattern, formatIndexNotReadable, isIndexReadable, matchesAnyPathPattern, pageMatchingEntries, pathOrder, readSummarizedValueAt, } from './historyQuery.js';
|
|
4
|
-
import { DiffValueAbsent, DiffValuePresent, EventConnected, EventDisconnected, EventFrame, KeyframeInfo, MessageSchemaDocumentResult, MessageSchemaIndexResult, RequestFrame, ResponseDispatched, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessageCounts, ResponseMessageSchema, ResponseMessages, ResponseModel, ResponseModelDiff, ResponseReplayed, ResponseResumed, ResponseRuntimeState, RuntimeInfo, } from './protocol.js';
|
|
4
|
+
import { DiffValueAbsent, DiffValuePresent, EventConnected, EventDisconnected, EventFrame, KeyframeInfo, MAX_DISPATCH_BATCH_SIZE, MessageSchemaDocumentResult, MessageSchemaIndexResult, RequestFrame, ResponseDispatched, ResponseDispatchedBatch, ResponseError, ResponseFrame, ResponseInit, ResponseKeyframes, ResponseMessage, ResponseMessageCounts, ResponseMessageSchema, ResponseMessages, ResponseModel, ResponseModelDiff, ResponseReplayed, ResponseResumed, ResponseRuntimeState, RuntimeInfo, } from './protocol.js';
|
|
5
5
|
import { diagnoseVariantPath, indexMessageSchemaDocument, narrowToVariant, splitVariantPath, } from './schemaSummarize.js';
|
|
6
6
|
import { toInspectableValue, toSerializedCommand, toSerializedEntry, toSerializedMount, } from './serialize.js';
|
|
7
|
-
import { INIT_INDEX, computeDiff, latestEntryIndex, } from './store.js';
|
|
7
|
+
import { INIT_INDEX, computeDiff, latestEntryIndex, nextEntryIndex, } from './store.js';
|
|
8
8
|
import { formatPathNotFound, resolvePath, summarizeValue, } from './summarize.js';
|
|
9
9
|
const REQUEST_CHANNEL = 'foldkit:devTools:request';
|
|
10
10
|
const RESPONSE_CHANNEL = 'foldkit:devTools:response';
|
|
@@ -175,7 +175,16 @@ const formatUnknownVariantError = (document, variantPath) => {
|
|
|
175
175
|
},
|
|
176
176
|
});
|
|
177
177
|
};
|
|
178
|
-
const
|
|
178
|
+
const missingMessageSchemaResponse = ResponseError({
|
|
179
|
+
reason: 'Cannot dispatch: DevToolsConfig.Message not configured. Pass your Message Schema to enable dispatch.',
|
|
180
|
+
});
|
|
181
|
+
const formatInvalidMessageReason = (error, message) => `${error instanceof Error ? error.message : String(error)}\n\nReceived (typeof ${typeof message}): ${JSON.stringify(message)}`;
|
|
182
|
+
/**
|
|
183
|
+
* Fulfill one bridge Request against the DevTools store. `startWebSocketBridge`
|
|
184
|
+
* wires this to the HMR request channel; exported so tests can drive request
|
|
185
|
+
* handling without a live HMR connection.
|
|
186
|
+
*/
|
|
187
|
+
export const dispatchRequest = (store, dispatch, maybeDispatchSchema, maybeJsonSchemaDocument, request) => Match.value(request).pipe(Match.tagsExhaustive({
|
|
179
188
|
RequestGetModel: ({ maybePath, expand }) => Effect.gen(function* () {
|
|
180
189
|
const state = yield* SubscriptionRef.get(store.stateRef);
|
|
181
190
|
const index = latestEntryIndex(state);
|
|
@@ -297,19 +306,38 @@ const dispatchRequest = (store, dispatch, maybeDispatchSchema, maybeJsonSchemaDo
|
|
|
297
306
|
reason: `Failed to resume: ${Cause.pretty(cause)}`,
|
|
298
307
|
})))),
|
|
299
308
|
RequestDispatchMessage: ({ message }) => Option.match(maybeDispatchSchema, {
|
|
300
|
-
onNone: () => Effect.succeed(
|
|
301
|
-
reason: 'Cannot dispatch: DevToolsConfig.Message not configured. Pass your Message Schema to enable dispatch.',
|
|
302
|
-
})),
|
|
309
|
+
onNone: () => Effect.succeed(missingMessageSchemaResponse),
|
|
303
310
|
onSome: dispatchSchema => Effect.gen(function* () {
|
|
304
311
|
const decodedMessage = yield* S.decodeUnknownEffect(dispatchSchema)(message);
|
|
305
312
|
const stateBefore = yield* SubscriptionRef.get(store.stateRef);
|
|
306
|
-
const acceptedAtIndex = stateBefore
|
|
313
|
+
const acceptedAtIndex = nextEntryIndex(stateBefore);
|
|
307
314
|
yield* dispatch(decodedMessage);
|
|
308
315
|
return ResponseDispatched({ acceptedAtIndex });
|
|
309
316
|
}).pipe(Effect.catch(error => Effect.succeed(ResponseError({
|
|
310
|
-
reason: `Invalid Message: ${
|
|
317
|
+
reason: `Invalid Message: ${formatInvalidMessageReason(error, message)}`,
|
|
311
318
|
})))),
|
|
312
319
|
}),
|
|
320
|
+
RequestDispatchMessages: ({ messages }) => {
|
|
321
|
+
if (messages.length > MAX_DISPATCH_BATCH_SIZE) {
|
|
322
|
+
return Effect.succeed(ResponseError({
|
|
323
|
+
reason: `Batch too large: ${messages.length} Messages exceeds the limit of ${MAX_DISPATCH_BATCH_SIZE}. No Messages from the batch were dispatched.`,
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
return Option.match(maybeDispatchSchema, {
|
|
327
|
+
onNone: () => Effect.succeed(missingMessageSchemaResponse),
|
|
328
|
+
onSome: dispatchSchema => Effect.gen(function* () {
|
|
329
|
+
const decodeMessage = S.decodeUnknownEffect(dispatchSchema);
|
|
330
|
+
const decodedMessages = yield* Effect.forEach(messages, (message, position) => Effect.mapError(decodeMessage(message), error => new Error(`Invalid Message at zero-based batch position ${position}: ${formatInvalidMessageReason(error, message)}\n\nNo Messages from the batch were dispatched.`)));
|
|
331
|
+
const stateBefore = yield* SubscriptionRef.get(store.stateRef);
|
|
332
|
+
const firstAcceptedIndex = nextEntryIndex(stateBefore);
|
|
333
|
+
yield* Effect.forEach(decodedMessages, dispatch);
|
|
334
|
+
const acceptedAtIndices = Array.map(decodedMessages, (_decodedMessage, offset) => firstAcceptedIndex + offset);
|
|
335
|
+
return ResponseDispatchedBatch({ acceptedAtIndices });
|
|
336
|
+
}).pipe(Effect.catch(error => Effect.succeed(ResponseError({
|
|
337
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
338
|
+
})))),
|
|
339
|
+
});
|
|
340
|
+
},
|
|
313
341
|
RequestGetMessageSchema: ({ maybeVariantTag }) => Effect.succeed(buildMessageSchemaResponse(maybeJsonSchemaDocument, maybeVariantTag)),
|
|
314
342
|
RequestListRuntimes: () => Effect.succeed(ResponseError({
|
|
315
343
|
reason: 'RequestListRuntimes is plugin-handled and should not reach the runtime bridge',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/html/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;CAC/C,CAAC,CAAA;AAEF;;;;eAIe;AACf,MAAM,MAAM,UAAU,GAAG,MAAM,CAAA;AAI/B,eAAO,MAAM,aAAa,EAAE,UAAe,CAAA;AAE3C,eAAO,MAAM,eAAe,GAC1B,QAAQ,UAAU,EAClB,SAAS,MAAM,KACd,UAUF,CAAA;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwCa;AACb,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;IAC/C,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAClC,YAAY,EACZ,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAC9B,CAAA;IACD,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;IAChD,QAAQ,CAAC,iBAAiB,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;IAI1D,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,sBAAsB,QAAO,gBAMxC,CAAA;AAqBF,eAAO,MAAM,oBAAoB,GAC/B,UAAU,gBAAgB,EAC1B,YAAY,UAAU,EACtB,YAAY,cAAc,KACzB,IA6BF,CAAA;AAED;;;;wCAIwC;AACxC,eAAO,MAAM,iBAAiB,GAC5B,UAAU,gBAAgB,KACzB,GAAG,CAAC,UAAU,EAAE,MAAM,CAIxB,CAAA;AAED;;yCAEyC;AACzC,eAAO,MAAM,eAAe,GAAI,UAAU,gBAAgB,KAAG,IAQ5D,CAAA;AAED;;;;;;;4CAO4C;AAC5C,eAAO,MAAM,kBAAkB,GAC7B,UAAU,gBAAgB,EAC1B,YAAY,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,KAC1C,IAWF,CAAA;AAED;;;;;;;;;gBASgB;AAChB,eAAO,MAAM,sBAAsB,GACjC,UAAU,gBAAgB,EAC1B,YAAY,UAAU,KACrB,IAEF,CAAA;
|
|
1
|
+
{"version":3,"file":"boundary.d.ts","sourceRoot":"","sources":["../../src/html/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEzD,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAA;CAC/C,CAAC,CAAA;AAEF;;;;eAIe;AACf,MAAM,MAAM,UAAU,GAAG,MAAM,CAAA;AAI/B,eAAO,MAAM,aAAa,EAAE,UAAe,CAAA;AAE3C,eAAO,MAAM,eAAe,GAC1B,QAAQ,UAAU,EAClB,SAAS,MAAM,KACd,UAUF,CAAA;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwCa;AACb,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;IAC/C,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAClC,YAAY,EACZ,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAC9B,CAAA;IACD,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;IAChD,QAAQ,CAAC,iBAAiB,EAAE,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAA;IAI1D,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CACjC,CAAA;AAED,eAAO,MAAM,sBAAsB,QAAO,gBAMxC,CAAA;AAqBF,eAAO,MAAM,oBAAoB,GAC/B,UAAU,gBAAgB,EAC1B,YAAY,UAAU,EACtB,YAAY,cAAc,KACzB,IA6BF,CAAA;AAED;;;;wCAIwC;AACxC,eAAO,MAAM,iBAAiB,GAC5B,UAAU,gBAAgB,KACzB,GAAG,CAAC,UAAU,EAAE,MAAM,CAIxB,CAAA;AAED;;yCAEyC;AACzC,eAAO,MAAM,eAAe,GAAI,UAAU,gBAAgB,KAAG,IAQ5D,CAAA;AAED;;;;;;;4CAO4C;AAC5C,eAAO,MAAM,kBAAkB,GAC7B,UAAU,gBAAgB,EAC1B,YAAY,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,KAC1C,IAWF,CAAA;AAED;;;;;;;;;gBASgB;AAChB,eAAO,MAAM,sBAAsB,GACjC,UAAU,gBAAgB,EAC1B,YAAY,UAAU,KACrB,IAEF,CAAA;AAmGD;;;;;;;;;;;;mFAYmF;AACnF,eAAO,MAAM,4BAA4B,GACvC,UAAU,gBAAgB,EAC1B,eAAe,YAAY,EAC3B,YAAY,UAAU,EACtB,SAAS,OAAO,KACf,CAAC,MAAM,IAAI,CAqBb,CAAA;AAED;;;;;;;8EAO8E;AAC9E,eAAO,MAAM,eAAe,GAC1B,UAAU,gBAAgB,EAC1B,YAAY,UAAU,KACrB,aAAa,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAiB7C,CAAA;AAED,eAAO,MAAM,2BAA2B,GACtC,UAAU,gBAAgB,EAC1B,eAAe,YAAY,EAC3B,YAAY,UAAU,KACrB,YAkBF,CAAA;AAED;;;;;;;;;;iEAUiE;AACjE,eAAO,MAAM,WAAW,GAAI,UAAU,gBAAgB,KAAG,IAGxD,CAAA"}
|