@solidrt/cli 0.0.40 → 0.0.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/cli",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "type": "module",
@@ -28,17 +28,17 @@
28
28
  "zod": "^4.4.3"
29
29
  },
30
30
  "optionalDependencies": {
31
- "@solidrt/darwin-arm64": "0.0.40",
32
- "@solidrt/linux-arm64-gnu": "0.0.40",
33
- "@solidrt/linux-x64-gnu": "0.0.40",
34
- "@solidrt/win32-x64-msvc": "0.0.40"
31
+ "@solidrt/darwin-arm64": "0.0.42",
32
+ "@solidrt/linux-arm64-gnu": "0.0.42",
33
+ "@solidrt/linux-x64-gnu": "0.0.42",
34
+ "@solidrt/win32-x64-msvc": "0.0.42"
35
35
  },
36
36
  "peerDependencies": {
37
- "@solidrt/core": "0.0.40",
37
+ "@solidrt/core": "0.0.42",
38
38
  "typescript": "^7"
39
39
  },
40
40
  "devDependencies": {
41
- "@solidrt/flux-types": "0.0.40",
41
+ "@solidrt/flux-types": "0.0.42",
42
42
  "@types/babel__core": "^7.20.5",
43
43
  "@types/bun": "latest"
44
44
  }
@@ -140,9 +140,11 @@ nearly free. That holds on desktop and on current mobile hardware; "Where GPU
140
140
  work stops being free" below is where it does not. Rules, in order of leverage:
141
141
 
142
142
  1. Continuous effects (snow, particles, animated backgrounds) belong in a
143
- fragment shader: createShader (from @solidrt/core/gpu) + `<texture
144
- params={{ iTime }}>`. The whole effect then costs one setProperty per
145
- frame - the iTime write - regardless of visual complexity. Shader output
143
+ fragment shader: createShaderTexture (from @solidrt/core/gpu) + `<texture
144
+ params={{ uTime }}>` (the shader declares `uniform float uTime;` itself -
145
+ the preamble declares only what the runtime fills). The whole effect then
146
+ costs one setProperty per frame - the uTime write - regardless of visual
147
+ complexity. Shader output
146
148
  must be premultiplied alpha (white flakes are `vec4(vec3(a), a)`);
147
149
  straight alpha (`vec4(1,1,1,a)`) composites as opaque white. A source that
148
150
  starts with `#version 300 es` is compiled exactly as written - no preamble
@@ -155,15 +157,18 @@ work stops being free" below is where it does not. Rules, in order of leverage:
155
157
  `vec3 iResolution` needs no splitting into scalars. To combine several
156
158
  GPU passes, stack `<texture>` elements and set `blendMode` (e.g. a base
157
159
  pass plus an additive `blendMode="plus"` pass) rather than writing a
158
- compositing shader. Within one pipeline draw, createPipeline's
160
+ compositing shader. Within one pipeline draw, createPipelineTexture's
159
161
  `blend: "add"` accumulates overlapping geometry additively (soft point
160
162
  splats, glow) - pair it with `depthWrite: false` when depth-tested;
161
- neither option implies the other. Sampling is a create-time option on
162
- every texture: `{ filter: "nearest" }` for hard-pixel upscaling (render a
163
- small target, display it big - the retro/pixel-art path) and
164
- `{ wrap: "repeat" }` to tile outside 0..1 in shaders; the defaults are
165
- linear and clamp, and the choice applies both on screen and to shaders
166
- sampling the texture.
163
+ neither option implies the other. A pipeline's own vertex stage writes
164
+ into a y-down clip space: `gl_Position` y = -1 is the top row of the
165
+ target and +1 the bottom, so camera-up geometry must negate y (or fold
166
+ the flip into its projection) or it draws upside down. Sampling is a
167
+ create-time option on every texture: `{ filter: "nearest" }` for
168
+ hard-pixel upscaling (render a small target, display it big - the
169
+ retro/pixel-art path) and `{ wrap: "repeat" }` to tile outside 0..1 in
170
+ shaders; the defaults are linear and clamp, and the choice applies both
171
+ on screen and to shaders sampling the texture.
167
172
  2. Reduce setProperty calls wherever possible: one path string rebuilt per
168
173
  frame beats N elements with N animated positions; a shader beats the path
169
174
  string. get_stats' setPropsPerFrame is the counter to watch.
@@ -345,8 +350,10 @@ flag: `"args": [..., "mcp", "--port", "N"]`.
345
350
  - console.log + get_logs is your primary probe into runtime state. For state
346
351
  you will want repeatedly (a pose, a mode, a counter), bind a debug key that
347
352
  logs it and read it back via get_logs.
348
- - Key events are delivered ONLY to the focused node (no bubbling): call
349
- setFocus(node.id) from the window's ref or onKeyDown never fires. `key` and
353
+ - Key events start at the focused node and bubble to the window root; with
354
+ nothing focused they go to the window root alone. So a debug key bound via
355
+ `<window onKeyDown>` always fires (unless a focused component consumes the
356
+ key with stopPropagation, as TextInput does for editing keys). `key` and
350
357
  `code` are W3C KeyboardEvent values, so arrow keys arrive as "ArrowLeft"/
351
358
  "ArrowRight"/"ArrowUp"/"ArrowDown" (not "Left"), alongside "Enter",
352
359
  "Escape", "a".
@@ -9,12 +9,12 @@
9
9
  "android": "srt client --android"
10
10
  },
11
11
  "dependencies": {
12
- "@solidrt/core": "0.0.40",
13
- "@solidrt/components": "0.0.40"
12
+ "@solidrt/core": "0.0.42",
13
+ "@solidrt/components": "0.0.42"
14
14
  },
15
15
  "devDependencies": {
16
- "@solidrt/cli": "0.0.40",
17
- "@solidrt/flux-types": "0.0.40",
16
+ "@solidrt/cli": "0.0.42",
17
+ "@solidrt/flux-types": "0.0.42",
18
18
  "typescript": "^7"
19
19
  }
20
20
  }
@@ -103,7 +103,7 @@ let TOOLS: {
103
103
  name: "get_stats",
104
104
  readOnly: true,
105
105
  description:
106
- "Performance statistics from a running app client: fps, CPU%, memory, smoothed JS/layout/paint/hover frame times (ms), setProperty writes per frame, demand-gate reuse/skip counts per second, and live texture count. Layout-activity counters cover the last full rebuild, raw: nodes (live node count, mounted AND detached), mountedNodes/orphanNodes (live at query time: nodes reachable from the root vs not - orphans growing at a stable tree shape mean an unmount leak; absent when no engine is running), measureCalls (text measures; mostly cache hits, cheap), paraShapes (paragraphs actually shaped; the expensive signal - high layoutMs with near-zero paraShapes means the cost is not text shaping), dirtiedNodes (layout caches cleared by property writes since the previous rebuild; how much of the tree a write burst invalidated), cacheGets/cacheHits (layout-cache lookups during the rebuild; a hit on a container skips its whole subtree, so a healthy incremental rebuild shows a near-100% hit rate - a low rate at scale means the layout cache is being defeated). GPU-side health, read live at query time (absent when no engine is running): rasterQueue (raster commands sent but not yet executed; stuck nonzero means the raster thread is backlogged - the state where fps and frameMs go blind because no frames complete), idleTicks (cumulative idle frame signals emitted while the GPU had nothing queued; idleTicks racing while rasterQueue sits nonzero would mean the idle-tick gate is broken), fenceTimeouts (cumulative present-fence waits that expired instead of signaling - each one is a frame where the GPU was over budget for 100ms+ and one-frame-in-flight pacing was lost; zero on a healthy machine, climbing means the GPU is the bottleneck right now).",
106
+ "Performance statistics from a running app client: fps, CPU%, memory, smoothed JS/layout/paint/hover frame times (ms), setProperty writes per frame, demand-gate reuse/skip counts per second, and live texture count. Layout-activity counters cover the last full rebuild, raw: nodes (live node count, mounted AND detached), mountedNodes/orphanNodes (live at query time: nodes reachable from the root vs not - orphans growing at a stable tree shape mean an unmount leak; absent when no engine is running), measureCalls (text measures; mostly cache hits, cheap), paraShapes (paragraphs actually shaped; the expensive signal - high layoutMs with near-zero paraShapes means the cost is not text shaping), dirtiedNodes (layout caches cleared by property writes since the previous rebuild; how much of the tree a write burst invalidated), cacheGets/cacheHits (layout-cache lookups during the rebuild; a hit on a container skips its whole subtree, so a healthy incremental rebuild shows a near-100% hit rate - a low rate at scale means the layout cache is being defeated). GPU-side health, read live at query time (absent when no engine is running): rasterQueue (raster commands sent but not yet executed; stuck nonzero means the raster thread is backlogged - the state where fps and frameMs go blind because no frames complete), idleTicks (cumulative idle frame signals emitted while the GPU had nothing queued; idleTicks racing while rasterQueue sits nonzero would mean the idle-tick gate is broken), fenceTimeouts (cumulative present-fence waits that expired instead of signaling - each one is a frame where the GPU was over budget for 100ms+ and one-frame-in-flight pacing was lost; zero on a healthy machine, climbing means the GPU is the bottleneck right now), gpuPasses/gpuPassMs (cumulative shader/pipeline target renders on the raster thread and the wall time they took in whole ms - diff two queries to get a rate; passes racing far ahead of frames means redundant target re-renders, the failure mode where fps and frameMs look healthy while the raster thread drowns; the ms figure is raster-thread occupancy issuing the passes, not GPU-side duration), rasterCmdMs (cumulative wall time in whole ms the raster thread spent executing non-frame commands - texture uploads, readbacks, offscreen rasterizations, shader compiles, param writes and the target re-renders they trigger; the work frameMs never sees, so rasterCmdMs growing much faster than frames are presented means the raster thread is drowning in side work even if every counter above looks calm).",
107
107
  inputSchema: { client: CLIENT_ARG },
108
108
  },
109
109
  {
@@ -151,14 +151,14 @@ let TOOLS: {
151
151
  name: "get_gpu_resources",
152
152
  readOnly: true,
153
153
  description:
154
- "Inventory of a running app client's GPU resources: textures (id, size, whether a shader renders into it), vertex buffers (id, byteLength), and shader/pipeline targets (output textureId, kind, bufferId, topology, drawCount, depth, attribute layout, bound sampler texture ids, current uniform values - the most recent writes, which the next frame or readback draws with). Use it when the render tree is just a <texture> leaf and the interesting state lives behind it; follow up with get_texture or get_buffer to see contents.",
154
+ "Inventory of a running app client's GPU resources: textures (id, size, whether a shader renders into it), vertex buffers (id, byteLength), and shader/pipeline targets (output textureId, kind, bufferId, topology, drawCount plus firstVertex/instanceCount when off their 0/1 defaults, depth, attribute layout, bound sampler texture ids, current uniform values - the most recent writes, which the next frame or readback draws with - plus passes/passMs, cumulative per-target render count and raster-thread wall time in whole ms: when get_stats shows gpuPasses running hot, these attribute the cost to the specific target). Use it when the render tree is just a <texture> leaf and the interesting state lives behind it; follow up with get_texture or get_buffer to see contents.",
155
155
  inputSchema: { client: CLIENT_ARG },
156
156
  },
157
157
  {
158
158
  name: "get_texture",
159
159
  readOnly: true,
160
160
  description:
161
- "Read back any GPU texture from a running app client as a PNG, by texture id (from get_gpu_resources, or the id returned by createImage/createShader/createPipeline in app code). Works on sampled textures (atlases, data textures) and shader/pipeline render targets alike, without needing a frame: a render target reads as its current output, with any pending params, geometry or sampled-input changes resolved first. Pass x/y/width/height to crop, e.g. one tile of an atlas.",
161
+ "Read back any GPU texture from a running app client as a PNG, by texture id (from get_gpu_resources, or the id returned by createImage/createShaderTexture/createPipelineTexture in app code). Works on sampled textures (atlases, data textures) and shader/pipeline render targets alike, without needing a frame: a render target reads as its current output, with any pending params, geometry or sampled-input changes resolved first. Pass x/y/width/height to crop, e.g. one tile of an atlas.",
162
162
  inputSchema: {
163
163
  id: z.number().int().describe("Texture id, from get_gpu_resources"),
164
164
  x: z.number().int().describe("Crop rect left edge in texture pixels (requires y, width, height)").optional(),