@solidrt/cli 0.0.52 → 0.0.54

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/AGENTS.md CHANGED
@@ -11,7 +11,9 @@ bundled `flux` runtime, not on Bun. Invoke via `bunx srt <command>`.
11
11
  The dev loop against a running app is pause_watch -> edit -> reload ->
12
12
  resume_watch -> get_logs -> get_snapshot, with mute_user_input while you
13
13
  measure or test and unmute_user_input after; agents/debugging.md has the
14
- why of each hold. `reload` surfaces build errors but not type errors:
14
+ why of each hold. Several clients may be attached at once: `reload` reaches
15
+ all of them, while call_debug / send_input / get_snapshot are per client
16
+ (debugging.md). `reload` surfaces build errors but not type errors:
15
17
  `bunx srt check` is for those.
16
18
 
17
19
  agents/ carries the depth this one leaves out; read the one that matches
package/README.md CHANGED
@@ -20,7 +20,7 @@ android` (and `server`, `client`, `pack` for the rest).
20
20
  | [`srt server [file]`](src/server/docs.md) | dev server only |
21
21
  | [`srt client`](src/client/docs.md) | client only, attached to the project's dev server |
22
22
  | [`srt android`](src/android/docs.md) | install and launch the client on a connected Android device |
23
- | [`srt demo [n]`](src/demo/docs.md) | list the demos the installed packages ship, or run one |
23
+ | [`srt demo [n]`](src/demo/docs.md) | list the demos the CLI ships, or run one |
24
24
  | [`srt console`](src/console/docs.md) | start the dev console: the dev servers on this machine and their clients |
25
25
  | [`srt check [file]`](src/check/docs.md) | build and typecheck, writing nothing |
26
26
  | [`srt bundle [file]`](src/bundle/docs.md) | transpile to JS or bytecode (dist/bundle/) |
@@ -156,16 +156,26 @@ when exactly one client is connected.
156
156
  window root.
157
157
  - `/texture?id=<textureId>` - same shape and options as `/snapshot`, at the
158
158
  texture's native size (a scene or shader target behind a `<texture>` leaf).
159
- - `/gpu?label=<text>` - the GPU resource inventory; `label` keeps only the
160
- resources created with exactly that label (ids change on reload, labels
161
- do not).
159
+ - `/gpu?label=<text>&draw=<id>` - the GPU resource inventory; `label` keeps
160
+ only the resources created with exactly that label (ids change on reload,
161
+ labels do not). A draw target's entries report uniforms wider than a vec4
162
+ (matrices) as their length, `"[16]"`; `draw` names the one entry (ids are
163
+ per target, so pair it with `label`) reported in full.
162
164
  - `/buffer?id=<bufferId>&offset=<n>&length=<n>&as=<f32|u16|u8>` - vertex
163
165
  buffer contents (default f32; reads cap at 64 KiB).
164
166
  - `/stats?window=<ms>` - the performance statistics. POST
165
167
  `/stats?active=true|false` switches the on-screen stats overlay instead
166
168
  (the `set_stats_overlay` tool): one client with `&client=<id>`, every
167
169
  client (and the setting new clients join with) without; `/clients`
168
- reports each client's `stats`.
170
+ reports each client's `stats`. `frames` counts the frames that changed
171
+ the picture: tree rebuilds, plus GPU content changes presented without
172
+ one (a layer write, a shader param, an upload - a sprite or shader app
173
+ rebuilds nothing, every frame of it is one of these).
174
+ `fps` is the refresh rate presented at: when motion looks wrong and `fps`
175
+ looks fine, `frames` is the number to read - a picture that only changes
176
+ 26 times a second shows 26 there, and the stutter is the app's update
177
+ cadence, not the engine's. `frames: 0` means the picture did not change
178
+ at all in the window.
169
179
  - `/debug` - the app's registered debug commands; POST
170
180
  `/debug?name=<cmd>` with a JSON body as its args to call one.
171
181
  - POST `/input` with `{ "events": [...] }` - synthetic input through the
@@ -259,6 +269,21 @@ The loop is the same as over MCP: `/reload`, then `/logs?since=`, then
259
269
  Math.min(dt, cap) lets it through, and one bad frame can corrupt anything
260
270
  integrated from dt (positions fly off, accumulators go so negative they
261
271
  never recover). Math.max(0, Math.min(dt, cap)) costs nothing.
272
+ - A fixed-timestep simulation on that clamped dt still drifts: no panel
273
+ presents at exactly its nominal rate (a "60 Hz" panel measured 60.3) and
274
+ the paced tick tracks the real cadence, so a 16.667 ms step against a
275
+ 16.59 ms average dt comes up one step short every few seconds - one frame
276
+ runs no step (freeze), the next runs two (jump), and frame jitter
277
+ scatters which frame it lands on, so it reads as random stutter. The
278
+ runtime hands every callback the refresh rate,
279
+ `onFrame((tick, frame, rate) => ...)` (SDL's nominal Hz): when the step is
280
+ within a few percent of `1000 / rate`, run whole steps per frame
281
+ (`Math.round(dt / STEP_MS)`, clamped to [0, cap]) so the world rides the
282
+ refresh; only accumulate (`acc += dt; while (acc >= STEP_MS) ...`) when
283
+ the display is genuinely off-rate (50, 120, 144 Hz), or interpolate the
284
+ render by `acc / STEP_MS` if the game does not snap to whole pixels. It
285
+ is invisible in a five-second look and survives every renderer
286
+ optimisation; measure it with a steps-per-frame histogram, not by eye.
262
287
  - A registered onFrame is a standing request, not demand-gated: it re-requests
263
288
  the next frame every time it runs, so the runtime keeps calling it - and
264
289
  presents - every frame at the refresh rate until you deregister it (fps