@hueest/xray 0.6.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/dist/react.dev.js CHANGED
@@ -1,5 +1,5 @@
1
- import { n as BOUNDARY_ATTR } from "./plate-BwJUgHDc.js";
2
- import { a as markStitchesLive, c as useSkeletonTiming, i as isStitchLive, n as collectStitchNames, o as renderPlate, r as isRenderProp, s as resolveContent, t as SuspendWhileLoading } from "./react.core-DeEli0Lp.js";
1
+ import { n as BOUNDARY_ATTR } from "./plate-CXIh5_OB.js";
2
+ import { a as markStitchesLive, c as useSkeletonTiming, i as isStitchLive, n as collectStitchNames, o as renderPlate, r as isRenderProp, s as resolveContent, t as SuspendWhileLoading } from "./react.core-BS2yvqeh.js";
3
3
  import { Suspense, useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
5
  //#region src/react.dev.tsx
@@ -16,36 +16,31 @@ function useReplayOn() {
16
16
  return useSyncExternalStore(replay?.subscribe ?? noSubscribe, replay?.get ?? alwaysFalse, alwaysFalse);
17
17
  }
18
18
  /**
19
- * The Fixtures (ADR 0015) seam, applied at the ready (`loading=false`) path right
20
- * before `resolveContent`. It is the ONE place Record reads `data` and Replay
21
- * substitutes it — the render-prop `data` argument is in scope here (open Q1,
22
- * confirmed).
19
+ * The Fixtures (ADR 0015) seam, applied at the ready (`loading=false`) path right before
20
+ * `resolveContent`. It is the ONE place Record reads `data` and Replay substitutes it — the
21
+ * render-prop `data` argument is in scope here.
23
22
  *
24
- * Replay: when the toggle is on and a Fixture exists, the recorded `data` is
25
- * substituted for the live `data` according to `replayMode` — `'prefer'` always
26
- * uses the Fixture; `'missing-only'` uses it only when live `data` is NULLISH
27
- * (`missing nullish`, so an empty array/object is present and stays
28
- * capturable). The substituted value is returned synchronously so it feeds
29
- * `resolveContent` for THIS render; the capture-all sweep only re-renders at each
30
- * width and reads the SAME Fixture from the store (which the sweep never changes
31
- * per width), so every View is captured from one width-independent Fixture with
32
- * no new capture trigger (open Q2, confirmed — capture follows whatever renders,
33
- * ADR 0002).
23
+ * Replay: when the toggle is on and a Fixture exists, the recorded `data` is substituted for the
24
+ * live `data` according to `replayMode` — `'prefer'` always uses the Fixture; `'missing-only'` uses
25
+ * it only when live `data` is NULLISH (`missing ≡ nullish`, so an empty array/object is present and
26
+ * stays capturable). The substituted value is returned synchronously so it feeds `resolveContent`
27
+ * for THIS render; the capture-all sweep only re-renders at each width and reads the SAME Fixture
28
+ * from the store (which the sweep never changes per width), so every View is captured from one
29
+ * width-independent Fixture with no new capture trigger (capture follows whatever renders, ADR
30
+ * 0002).
34
31
  *
35
- * Record: the live `data` is registered (in an effect, so render stays pure) so
36
- * the HUD button and the auto modes always have the current input in scope. The
37
- * auto modes (`'first-ready'`, `'always'`) fire from the same effect; `'manual'`
38
- * (the default) records nothing automatically. We register and auto-record the
39
- * LIVE `data`, never the replayed value, so Replay and Record never feed each
40
- * other.
32
+ * Record: the live `data` is registered (in an effect, so render stays pure) so the HUD button and
33
+ * the auto modes always have the current input in scope. The auto modes (`'first-ready'`,
34
+ * `'always'`) fire from the same effect; `'manual'` (the default) records nothing automatically.
35
+ * Register and auto-record the LIVE `data`, never the replayed value, so Replay and Record never
36
+ * feed each other.
41
37
  *
42
- * Only the render-prop children form is the `data` seam (ADR 0014/0015), so
43
- * Fixtures apply to it alone: `renderProp` gates participation. A plain-children
44
- * Skeleton has no `data` input, so it must NOT register, auto-record, or replay —
45
- * the hook is a pass-through for it, which keeps a never-registered plain name out
46
- * of `recordAll` and lets `record(name)` throw loudly (no render-prop data) as the
47
- * store contract documents. A render-prop Skeleton passed `data={undefined}` is
48
- * still a render prop and participates exactly as any other.
38
+ * Only the render-prop children form is the `data` seam (ADR 0014/0015), so Fixtures apply to it
39
+ * alone: `renderProp` gates participation. A plain-children Skeleton has no `data` input, so it
40
+ * must NOT register, auto-record, or replay — the hook is a pass-through for it, which keeps a
41
+ * never-registered plain name out of `recordAll` and lets `record(name)` throw loudly (no
42
+ * render-prop data) as the store contract documents. A render-prop Skeleton passed
43
+ * `data={undefined}` is still a render prop and participates exactly as any other.
49
44
  */
50
45
  function useFixtureData(name, data, renderProp) {
51
46
  const replayOn = useReplayOn();
@@ -72,8 +67,8 @@ function useFixtureData(name, data, renderProp) {
72
67
  return recordedFixture.data;
73
68
  }
74
69
  /**
75
- * The plate to render: the freshest capture from the client store (hot-swapped
76
- * in place, no remount) when present, else the imported prop.
70
+ * The plate to render: the freshest capture from the client store (hot-swapped in place, no
71
+ * remount) when present, else the imported prop.
77
72
  */
78
73
  function useLivePlate(plate) {
79
74
  const store = globalThis.__XRAY__?.plates;
@@ -82,10 +77,9 @@ function useLivePlate(plate) {
82
77
  return useSyncExternalStore(subscribe, getSnapshot, () => plate);
83
78
  }
84
79
  /**
85
- * Dev `<Skeleton>`: production behavior plus the Light Box override, the
86
- * live-store hot-swap, and browse-time capture. The xray plugin aliases
87
- * `@hueest/xray/react` to this module in `serve`; production gets the hook-free
88
- * `react.tsx`.
80
+ * Dev `<Skeleton>`: production behavior plus the Light Box override, the live-store hot-swap, and
81
+ * browse-time capture. The xray plugin aliases `@hueest/xray/react` to this module in `serve`;
82
+ * production gets the lean `react.tsx`.
89
83
  */
90
84
  function Skeleton(props) {
91
85
  const { plate, css, loading = false, suspense = false, fallback, delay, children, data, captureWalker, maxNodes, maxBreadth, maxDepth } = props;
@@ -132,10 +126,10 @@ function Content(props) {
132
126
  return /* @__PURE__ */ jsx(CaptureBoundary, { ...props });
133
127
  }
134
128
  /**
135
- * Assemble the per-site Collect limits (ADR 0022) from the flat `<Skeleton>` props
136
- * into the nested shape `captured` expects, or `undefined` when none are set (so
137
- * the client's plugin defaults apply). Called inside the capture effect, keyed on
138
- * the flat primitives, so it never builds an object during render.
129
+ * Assemble the per-site Collect limits (ADR 0022) from the flat `<Skeleton>` props into the nested
130
+ * shape `captured` expects, or `undefined` when none are set (so the client's plugin defaults
131
+ * apply). Called inside the capture effect, keyed on the flat primitives, so it never builds an
132
+ * object during render.
139
133
  */
140
134
  function collectLimits(maxNodes, maxBreadth, maxDepth) {
141
135
  if (maxNodes === void 0 && maxBreadth === void 0 && maxDepth === void 0) return void 0;
@@ -146,12 +140,11 @@ function collectLimits(maxNodes, maxBreadth, maxDepth) {
146
140
  };
147
141
  }
148
142
  /**
149
- * `root="auto"` (default): the existing `display:contents` boundary wrapper marks
150
- * the capture seam so a parent capture stops here and references this plate by
151
- * name rather than re-serializing the content (ADR 0006). A render prop is called
152
- * with the verbatim `data` and a no-op `ref` (the wrapper, not the consumer's
153
- * element, carries the marker); its result renders inside the wrapper exactly as
154
- * plain children do.
143
+ * `root="auto"` (default): the existing `display:contents` boundary wrapper marks the capture seam
144
+ * so a parent capture stops here and references this plate by name rather than re-serializing the
145
+ * content (ADR 0006). A render prop is called with the verbatim `data` and a no-op `ref` (the
146
+ * wrapper, not the consumer's element, carries the marker); its result renders inside the wrapper
147
+ * exactly as plain children do.
155
148
  */
156
149
  function CaptureBoundary({ plate, delay, children, data, captureWalker, maxNodes, maxBreadth, maxDepth }) {
157
150
  const ref = useRef(null);
@@ -181,17 +174,15 @@ function CaptureBoundary({ plate, delay, children, data, captureWalker, maxNodes
181
174
  });
182
175
  }
183
176
  /**
184
- * `root="manual"` (ADR 0014): no wrapper. The render prop is handed a CALLBACK
185
- * ref that, when spread onto the consumer's root element, writes the existing
186
- * `data-xr-boundary` marker onto it and registers it as the capture root, so a
187
- * parent capture reads the identical marker (`serialize.ts` does
188
- * `BOUNDARY_ATTR ?? ROOT_ATTR`) and cannot tell a manual root from an auto one.
177
+ * `root="manual"` (ADR 0014): no wrapper. The render prop is handed a CALLBACK ref that, when
178
+ * spread onto the consumer's root element, writes the existing `data-xr-boundary` marker onto it
179
+ * and registers it as the capture root, so a parent capture reads the identical marker
180
+ * (`measure.ts` does `BOUNDARY_ATTR ?? ROOT_ATTR`) and cannot tell a manual root from an auto one.
189
181
  *
190
- * If the consumer forgets to spread the ref, the marker never lands and the
191
- * parent capture descends into and silently swallows this subtree's DOM: the
192
- * exact stitch-isolation breakage ADR 0006 prevents, and the worst failure xray
193
- * can produce. A dev-time effect asserts the ref fired and loudly `console.error`s
194
- * when it did not.
182
+ * If the consumer forgets to spread the ref, the marker never lands and the parent capture descends
183
+ * into and silently swallows this subtree's DOM: the exact stitch-isolation breakage ADR 0006
184
+ * prevents, and the worst failure xray can produce. A dev-time effect asserts the ref fired and
185
+ * loudly `console.error`s when it did not.
195
186
  */
196
187
  function ManualBoundary({ plate, delay, children, data, captureWalker, maxNodes, maxBreadth, maxDepth }) {
197
188
  const disposeRef = useRef(void 0);
@@ -222,9 +213,11 @@ function ManualBoundary({ plate, delay, children, data, captureWalker, maxNodes,
222
213
  }, [plate.name]);
223
214
  return /* @__PURE__ */ jsx(Fragment$1, { children: resolveContent(children, useFixtureData(plate.name, data, isRenderProp(children)), ref) });
224
215
  }
225
- /** Render a plate's skeleton, seeding the live store from its resolved refs so a
226
- * stitch resolves before its child is re-captured and survives a parent
227
- * hot-swap (which pushes a refs-less plate). Never overwrites a live capture. */
216
+ /**
217
+ * Render a plate's skeleton, seeding the live store from its resolved refs so a stitch resolves
218
+ * before its child is re-captured and survives a parent hot-swap (which pushes a refs-less plate).
219
+ * Never overwrites a live capture.
220
+ */
228
221
  function PlateView({ plate, css, fallback, nested = false, rootRef, instant }) {
229
222
  useEffect(() => {
230
223
  const store = globalThis.__XRAY__?.plates;
@@ -238,9 +231,9 @@ function PlateView({ plate, css, fallback, nested = false, rootRef, instant }) {
238
231
  }), nested, rootRef, instant, css);
239
232
  }
240
233
  /**
241
- * A stitch in dev: resolve the child plate from the live store (so re-capturing
242
- * it hot-swaps it inside every parent), falling back to the parent's statically
243
- * imported `refs` until the first capture lands.
234
+ * A stitch in dev: resolve the child plate from the live store (so re-capturing it hot-swaps it
235
+ * inside every parent), falling back to the parent's statically imported `refs` until the first
236
+ * capture lands.
244
237
  */
245
238
  function RefNode({ name, staticRefs }) {
246
239
  const store = globalThis.__XRAY__?.plates;
package/dist/react.js CHANGED
@@ -1,33 +1,32 @@
1
- import { a as markStitchesLive, c as useSkeletonTiming, i as isStitchLive, n as collectStitchNames, o as renderPlate, s as resolveContent, t as SuspendWhileLoading } from "./react.core-DeEli0Lp.js";
1
+ import { a as markStitchesLive, c as useSkeletonTiming, i as isStitchLive, n as collectStitchNames, o as renderPlate, s as resolveContent, t as SuspendWhileLoading } from "./react.core-BS2yvqeh.js";
2
2
  import { Suspense, useEffect, useRef, useState } from "react";
3
3
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/react.tsx
5
5
  /**
6
6
  * React adapter for rendering committed Plates through `<Skeleton>`.
7
7
  *
8
- * In production this adapter is hook-free and renders only committed Plate data.
9
- * During `vite serve`, `xrayVitePlugin()` aliases this export to the dev adapter
10
- * so ready children can be captured without shipping the capture client, HUD, or
11
- * Light Box code in production builds.
8
+ * In production this adapter renders only committed Plate data (its only hooks are the
9
+ * display-timing and instant-reveal ones). During `vite serve`, `xrayVitePlugin()` aliases this
10
+ * export to the dev adapter so ready children can be captured without shipping the capture client,
11
+ * HUD, or Light Box code in production builds.
12
12
  *
13
13
  * @module @hueest/xray/react
14
14
  */
15
15
  /**
16
16
  * Render a committed Plate while content is loading.
17
17
  *
18
- * Use `loading` when your data source exposes an explicit pending state. Use
19
- * `suspense` when the child suspends; in that mode `<Skeleton>` is the Suspense
20
- * boundary and the Plate is the fallback. You can also render a bare Skeleton
21
- * with no children when another framework or router owns the loading boundary.
18
+ * Use `loading` when your data source exposes an explicit pending state. Use `suspense` when the
19
+ * child suspends; in that mode `<Skeleton>` is the Suspense boundary and the Plate is the fallback.
20
+ * You can also render a bare Skeleton with no children when another framework or router owns the
21
+ * loading boundary.
22
22
  *
23
- * In dev, the plugin aliases this component to the dev adapter. When children
24
- * are ready, that adapter marks the capture boundary, waits for the subtree to
25
- * settle, and sends the rendered DOM to the xray client. Nested `<Skeleton>`
26
- * boundaries become Stitches so a parent Plate records a child Plate reference
27
- * instead of serializing the child subtree again.
23
+ * In dev, the plugin aliases this component to the dev adapter. When children are ready, that
24
+ * adapter marks the capture boundary, waits for the subtree to settle, and sends the rendered DOM
25
+ * to the xray client. Nested `<Skeleton>` boundaries become Stitches so a parent Plate records a
26
+ * child Plate reference instead of serializing the child subtree again.
28
27
  *
29
- * In production this component ships no capture client, HUD, Light Box, store,
30
- * or subscriptions. Stitches resolve from the statically imported `refs` graph.
28
+ * In production this component ships no capture client, HUD, Light Box, store, or subscriptions.
29
+ * Stitches resolve from the statically imported `refs` graph.
31
30
  */
32
31
  function Skeleton(props) {
33
32
  const { plate, css, loading = false, suspense = false, fallback, children, data } = props;
@@ -57,11 +56,12 @@ function PlateView({ plate, css, fallback, rootRef, instant }) {
57
56
  if (!plate.chunks) return /* @__PURE__ */ jsx(Fragment$1, { children: fallback ?? null });
58
57
  return renderStatic(plate, false, rootRef, instant, css);
59
58
  }
60
- /** Resolve stitches statically through the import graph (ADR 0006) — pure
61
- * recursion, no store, no subscription. An unknown child renders nothing. The
62
- * `instant` flag (ADR 0020) and the inline `css` (two-artifact contract) ride
63
- * the outermost root only; nested stitches pass neither, so `renderPlate`
64
- * never marks or styles a nested root. */
59
+ /**
60
+ * Resolve stitches statically through the import graph (ADR 0006) pure recursion, no store, no
61
+ * subscription. An unknown child renders nothing. The `instant` flag (ADR 0020) and the inline
62
+ * `css` (two-artifact contract) ride the outermost root only; nested stitches pass neither, so
63
+ * `renderPlate` never marks or styles a nested root.
64
+ */
65
65
  function renderStatic(plate, nested, rootRef, instant, css) {
66
66
  return renderPlate(plate, (name) => {
67
67
  const child = plate.refs?.[name];