@hueest/xray 0.5.0 → 0.7.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/LICENSE +21 -0
- package/README.md +59 -0
- package/dist/client.d.ts +42 -51
- package/dist/client.js +136 -142
- package/dist/core.d.ts +42 -34
- package/dist/core.js +39 -33
- package/dist/css-escape-DJ-BsrNm.js +47 -0
- package/dist/hud.d.ts +7 -8
- package/dist/hud.js +5 -5
- package/dist/index.d.ts +268 -250
- package/dist/index.js +369 -240
- package/dist/measure-CUQxB-Ic.d.ts +524 -0
- package/dist/{plate-BRR6d8Se.js → plate-CXIh5_OB.js} +61 -45
- package/dist/react.core-BS2yvqeh.js +301 -0
- package/dist/react.core-BkJoCgWJ.d.ts +115 -0
- package/dist/react.d.ts +11 -13
- package/dist/react.dev.d.ts +4 -6
- package/dist/react.dev.js +58 -64
- package/dist/react.js +27 -25
- package/dist/{project-BZosujs9.js → serialize-Cj-EHvMv.js} +877 -1027
- package/package.json +8 -6
- package/virtual.d.ts +25 -32
- package/dist/css-escape-N7bOusGW.js +0 -52
- package/dist/react.core-BC02ukac.js +0 -294
- package/dist/react.core-NhWc9qan.d.ts +0 -89
- package/dist/serialize-BgdGt34A.d.ts +0 -501
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Stefan Maric
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @hueest/xray
|
|
2
|
+
|
|
3
|
+
Auto-captured skeleton loading screens for [Vite](https://vite.dev). Capture the structure, ship the plate.
|
|
4
|
+
|
|
5
|
+
xray captures the **real rendered DOM** of your components as you browse your dev server, then renders faithful skeleton loading states from those captures. Placeholders are captured rather than hand-drawn, with no separate headless browser and no fixed-height hacks.
|
|
6
|
+
|
|
7
|
+
> Beta: APIs may move before 1.0. Docs, guides, and the API reference live at
|
|
8
|
+
> **[xray-js.dev](https://xray-js.dev)**; source and issues at
|
|
9
|
+
> [github.com/hueest/xray](https://github.com/hueest/xray).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pnpm add @hueest/xray
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Use
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
// vite.config.ts
|
|
21
|
+
import { xrayVitePlugin } from '@hueest/xray'
|
|
22
|
+
|
|
23
|
+
export default defineConfig({
|
|
24
|
+
plugins: [xrayVitePlugin({ hud: true })],
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { Skeleton } from '@hueest/xray/react'
|
|
30
|
+
import plate from 'virtual:xray/plates/my-banner'
|
|
31
|
+
|
|
32
|
+
// skeleton while loading; content + (dev) capture when ready
|
|
33
|
+
;<Skeleton plate={plate} loading={loading} fallback={<Spinner />}>
|
|
34
|
+
<RealBanner data={data} />
|
|
35
|
+
</Skeleton>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
To inspect skeletons without waiting on loading states, tick **Light Box**
|
|
39
|
+
in the HUD (or open the page with `?xray-lightbox`); every mounted
|
|
40
|
+
`<Skeleton>` flips to its skeleton until unticked.
|
|
41
|
+
|
|
42
|
+
Capture starts off. Tick **Capture** in the HUD (or pass `capture: true` to
|
|
43
|
+
`xrayVitePlugin`) to start writing Plates as you browse. With Capture on,
|
|
44
|
+
captures land in `plates/` (commit them). Resize to capture other views: each
|
|
45
|
+
width lands as its own View, carried whole in the one plate and gated by
|
|
46
|
+
`@media display:none` (JS-driven structure differences become Projections).
|
|
47
|
+
Add `"@hueest/xray/virtual"` to the tsconfig `types` for the
|
|
48
|
+
`virtual:xray/plates/*` imports.
|
|
49
|
+
|
|
50
|
+
## Learn more
|
|
51
|
+
|
|
52
|
+
- **[xray-js.dev](https://xray-js.dev)** — the docs site: how it works, the
|
|
53
|
+
radiographic mental model (Plate / Capture / Stitch / View / Projection / Light
|
|
54
|
+
Box), and guides for responsive Views, the HUD & Light Box, capture-all-views,
|
|
55
|
+
and theming.
|
|
56
|
+
- **[xray-js.dev/reference/api/xray](https://xray-js.dev/reference/api/xray)** —
|
|
57
|
+
full API reference, generated from source.
|
|
58
|
+
- **[GitHub](https://github.com/hueest/xray)** — source, issues, and the
|
|
59
|
+
architecture/decision-record trail.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { b as CaptureDiagnostic, g as StoredPlate, o as CollectLimits } from "./measure-CUQxB-Ic.js";
|
|
3
2
|
//#region src/client.d.ts
|
|
4
3
|
/**
|
|
5
|
-
* The dev capture client
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* crosses into another view while a site is still mounted.
|
|
4
|
+
* The dev capture client. Runs in the browser during dev only: installs the `__XRAY__` hook
|
|
5
|
+
* `<Skeleton>` calls when content becomes ready, settles, measures the subtree into a per-Plate
|
|
6
|
+
* `PlateIR`, projects it to the structured `StoredPlate` in the browser (the ADR 0022 in-browser
|
|
7
|
+
* Serialize), and hands the envelope to the sink (the plugin's POST endpoint). Re-captures when the
|
|
8
|
+
* viewport crosses into another view while a site is still mounted.
|
|
11
9
|
*
|
|
12
|
-
* Two paths produce a Plate. BROWSE-TIME is a
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
10
|
+
* Two paths produce a Plate. BROWSE-TIME is a CAPTURE SESSION (the Capture toggle): while on, each
|
|
11
|
+
* capture accumulates a View into a name-keyed `PlateIR` buffer (deduped per breakpoint band) and
|
|
12
|
+
* live-previews it in-memory; toggling off writes each accumulated Plate to the sink ONCE. The
|
|
13
|
+
* capture-all SWEEP threads ONE `PlateIR` through every emulated width (one View each) and posts
|
|
14
|
+
* the projected StoredPlate once.
|
|
17
15
|
*/
|
|
18
16
|
/**
|
|
19
|
-
* The `/__xray` POST envelope (ADR 0022
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* artifact (ADR 0008).
|
|
17
|
+
* The `/__xray` POST envelope (ADR 0022). `plate` is the finished, in-browser-projected
|
|
18
|
+
* `StoredPlate` written to disk as-is; `diagnostics` is a SIBLING dev-only field the server logs
|
|
19
|
+
* and drops — it NEVER reaches the stored artifact (ADR 0008).
|
|
23
20
|
*/
|
|
24
21
|
interface CaptureEnvelope {
|
|
25
22
|
plate: StoredPlate;
|
|
@@ -29,59 +26,53 @@ interface ClientOptions {
|
|
|
29
26
|
/** Settle delay (ms) once the subtree goes quiet. Default 200. */
|
|
30
27
|
delay?: number;
|
|
31
28
|
/**
|
|
32
|
-
* Upper bound (ms) on waiting for quiet before capturing anyway. Raise it
|
|
33
|
-
*
|
|
29
|
+
* Upper bound (ms) on waiting for quiet before capturing anyway. Raise it for pages that stream
|
|
30
|
+
* content for a long time. Default 5000.
|
|
34
31
|
*/
|
|
35
32
|
settleCap?: number;
|
|
36
33
|
/**
|
|
37
|
-
* Collect limits (ADR 0022): refuse a capture whose measured tree exceeds any
|
|
38
|
-
*
|
|
39
|
-
* `
|
|
40
|
-
*
|
|
41
|
-
* is omitted it derives as `round(maxBreadth × maxDepth / 4)`.
|
|
34
|
+
* Collect limits (ADR 0022): refuse a capture whose measured tree exceeds any axis — that big
|
|
35
|
+
* means the Skeleton sits too high in the component tree. `maxNodes` caps total surviving nodes
|
|
36
|
+
* (default 4096), `maxBreadth` the widest level (default 512), `maxDepth` the nesting depth
|
|
37
|
+
* (default 32). When `maxNodes` is omitted it derives as `round(maxBreadth × maxDepth / 4)`.
|
|
42
38
|
*/
|
|
43
39
|
collect?: CollectLimits;
|
|
44
40
|
/**
|
|
45
|
-
* Initial state of the capture toggle: whether the
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* off-by-default policy; a direct caller can pass `true` to capture on boot.
|
|
41
|
+
* Initial state of the capture toggle: whether the capture session is active at boot. A per-tab
|
|
42
|
+
* override (sessionStorage / `?xray-capture`) wins over it. Defaults to `false` — capturing is
|
|
43
|
+
* explicit opt-in (turn it on, browse/resize to accumulate Views, turn it off to write), so
|
|
44
|
+
* normal browsing never accumulates and an HMR/close can't drop an unsaved session. The plugin
|
|
45
|
+
* passes the same off-by-default policy; a direct caller can pass `true` to capture on boot.
|
|
51
46
|
*/
|
|
52
47
|
capture?: boolean;
|
|
53
48
|
/**
|
|
54
|
-
* Where finished captures go. May be synchronous (fire-and-forget) or return
|
|
55
|
-
*
|
|
56
|
-
* capture
|
|
57
|
-
*
|
|
58
|
-
* been accepted by the dev server (backpressure — capture-all-backpressure plan).
|
|
49
|
+
* Where finished captures go. May be synchronous (fire-and-forget) or return a promise that
|
|
50
|
+
* resolves once the write is server-confirmed. Browse-time capture ignores the return value; the
|
|
51
|
+
* capture-all sweep awaits it so it does not advance to the next emulated width until the current
|
|
52
|
+
* writes have been accepted by the dev server (backpressure).
|
|
59
53
|
*/
|
|
60
54
|
sink: (envelope: CaptureEnvelope) => void | Promise<void>;
|
|
61
55
|
/**
|
|
62
|
-
* Re-pull the on-disk per-plate coverage and feed it into the coverage store.
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* plan). Optional: browse-time capture never needs it, and the unit tests
|
|
67
|
-
* drive coverage directly through the store.
|
|
56
|
+
* Re-pull the on-disk per-plate coverage and feed it into the coverage store. The capture-all
|
|
57
|
+
* sweep calls this after each pass so the next `sweepWidths()` sees the breakpoints just written
|
|
58
|
+
* by that pass, rather than racing the async `xray:plate` HMR event. Optional: browse-time
|
|
59
|
+
* capture never needs it, and the unit tests drive coverage directly through the store.
|
|
68
60
|
*/
|
|
69
61
|
refreshCoverage?: () => void | Promise<void>;
|
|
70
62
|
/**
|
|
71
|
-
* Fixtures boot state (ADR 0015). `record` is when to write the live `data` to a
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* `
|
|
75
|
-
*
|
|
63
|
+
* Fixtures boot state (ADR 0015). `record` is when to write the live `data` to a sidecar
|
|
64
|
+
* (`'manual'` — HUD button only, the default; `'first-ready'`; or `'always'`); `replay` is
|
|
65
|
+
* whether to substitute a recorded Fixture for live `data` (`false`, `'prefer'`, or
|
|
66
|
+
* `'missing-only'`). The HUD overrides the replay toggle per tab. Absent ≡ defaults (`'manual'` /
|
|
67
|
+
* `false`).
|
|
76
68
|
*/
|
|
77
69
|
record?: 'manual' | 'first-ready' | 'always';
|
|
78
70
|
replay?: false | 'prefer' | 'missing-only';
|
|
79
71
|
/**
|
|
80
|
-
* Where a recorded Fixture's OPAQUE devalue string is POSTed (the sidecar write
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* unit tests inject their own).
|
|
72
|
+
* Where a recorded Fixture's OPAQUE devalue string is POSTed (the sidecar write endpoint). The
|
|
73
|
+
* client owns the devalue stringify; this only ships the bytes. Resolves once the write is
|
|
74
|
+
* server-confirmed, rejects on a non-2xx so the HUD Record button can surface a failed write.
|
|
75
|
+
* Absent ≡ Record is a no-op (the unit tests inject their own).
|
|
85
76
|
*/
|
|
86
77
|
recordFixtureSink?: (payload: {
|
|
87
78
|
name: string;
|