@hueest/xray 0.2.0 → 0.3.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.
@@ -1,5 +1,5 @@
1
- import { r as Plate } from "./plate-Bv6W-GkA.js";
2
- import { o as XrayCaptureWalker } from "./serialize-B--oY2bV.js";
1
+ import { r as Plate } from "./plate-BIr62u7l.js";
2
+ import { a as XrayCaptureWalker } from "./serialize-Cs7hUxmK.js";
3
3
  import { ReactNode } from "react";
4
4
 
5
5
  //#region src/react.core.d.ts
@@ -44,7 +44,7 @@ interface SkeletonBase {
44
44
  * The escape hatch beyond the declarative `data-xr-*` annotations: a closure
45
45
  * that decides, per element, whether to ignore it, collapse it to one Bone, or
46
46
  * defer to the built-in walk. Threaded through the dev adapter into
47
- * `captureRegime`; PRODUCTION ignores it entirely (it never captures). On both
47
+ * `captureView`; PRODUCTION ignores it entirely (it never captures). On both
48
48
  * `root` variants of the union, so a manual root may carry one too.
49
49
  */
50
50
  captureWalker?: XrayCaptureWalker;
@@ -1,4 +1,4 @@
1
- import { a as ROOT_ATTR, o as ROOT_CLASS, s as ROOT_INSTANT_ATTR, t as BASE_CSS } from "./plate-DoE1HEXp.js";
1
+ import { a as ROOT_ATTR, o as ROOT_CLASS, s as ROOT_INSTANT_ATTR, t as BASE_CSS } from "./plate-BRR6d8Se.js";
2
2
  import { t as escapeStyleText } from "./css-escape-N7bOusGW.js";
3
3
  import { Fragment, useEffect, useRef, useState } from "react";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -74,6 +74,7 @@ function collectStitchNames(chunks) {
74
74
  const walk = (cs) => {
75
75
  for (const chunk of cs) {
76
76
  if (typeof chunk === "string") continue;
77
+ if ("t" in chunk) continue;
77
78
  if ("r" in chunk) names.push(chunk.r);
78
79
  else walk(chunk.k);
79
80
  }
@@ -256,6 +257,10 @@ function renderChunks(chunks, resolveStitch) {
256
257
  style: DISPLAY_CONTENTS,
257
258
  dangerouslySetInnerHTML: { __html: chunk }
258
259
  }, i);
260
+ if ("t" in chunk) return /* @__PURE__ */ jsx("div", {
261
+ style: DISPLAY_CONTENTS,
262
+ dangerouslySetInnerHTML: { __html: chunk.t.repeat(chunk.n) }
263
+ }, i);
259
264
  if ("r" in chunk) return /* @__PURE__ */ jsx(Fragment, { children: resolveStitch(chunk.r) }, i);
260
265
  return /* @__PURE__ */ jsx("div", {
261
266
  className: chunk.c,
package/dist/react.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { t as SkeletonProps } from "./react.core-BzMG_cDy.js";
1
+ import { t as SkeletonProps } from "./react.core-BUj8ziwh.js";
2
2
 
3
3
  //#region src/react.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { t as SkeletonProps } from "./react.core-BzMG_cDy.js";
1
+ import { t as SkeletonProps } from "./react.core-BUj8ziwh.js";
2
2
 
3
3
  //#region src/react.dev.d.ts
4
4
  /**
package/dist/react.dev.js CHANGED
@@ -1,5 +1,5 @@
1
- import { n as BOUNDARY_ATTR } from "./plate-DoE1HEXp.js";
2
- import { a as renderPlate, i as markStitchesLive, n as isRenderProp, o as resolveContent, r as isStitchLive, s as useSkeletonTiming, t as collectStitchNames } from "./react.core-IyFy2b_8.js";
1
+ import { n as BOUNDARY_ATTR } from "./plate-BRR6d8Se.js";
2
+ import { a as renderPlate, i as markStitchesLive, n as isRenderProp, o as resolveContent, r as isStitchLive, s as useSkeletonTiming, t as collectStitchNames } from "./react.core-DMIhXHZF.js";
3
3
  import { Suspense, useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
5
5
  //#region src/react.dev.tsx
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as renderPlate, i as markStitchesLive, o as resolveContent, r as isStitchLive, s as useSkeletonTiming, t as collectStitchNames } from "./react.core-IyFy2b_8.js";
1
+ import { a as renderPlate, i as markStitchesLive, o as resolveContent, r as isStitchLive, s as useSkeletonTiming, t as collectStitchNames } from "./react.core-DMIhXHZF.js";
2
2
  import { Suspense, useEffect, useRef, useState } from "react";
3
3
  import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
4
4
  //#region src/react.tsx
@@ -0,0 +1,107 @@
1
+ import { t as LeafKind } from "./plate-BIr62u7l.js";
2
+
3
+ //#region src/serialize.d.ts
4
+ /**
5
+ * Browser-side capture: walk a live rendered subtree into a Plate — one node
6
+ * tree plus one self-contained, scoped CSS string (ADR 0003). The CSS is
7
+ * lifted from the author rules that matched each node, rewritten to
8
+ * plate-local selectors — it carries `@media` for free and keeps layout live
9
+ * (the M1 bake-off winner; ADR 0005).
10
+ */
11
+ interface CaptureOptions {
12
+ /** Plate name; comes from the virtual-module specifier. */
13
+ name: string;
14
+ /**
15
+ * Optional programmable capture walker (ADR 0018). The declarative `data-xr-*`
16
+ * annotations cover the 90%; this is the escape hatch for the 10% a markup
17
+ * attribute cannot express. Capture-only: it shapes the resulting `PlateNode`
18
+ * tree but is never persisted into the Plate, and the production adapter never
19
+ * captures so it ignores this entirely.
20
+ */
21
+ walker?: XrayCaptureWalker;
22
+ /**
23
+ * Whether the top-level capture roots ARE this plate's own boundary, so the
24
+ * stitch guard must be SKIPPED for them (ADR 0006/0014, finding #6). True ONLY
25
+ * for a MANUAL root: there `site.el` is the consumer's own element and its
26
+ * `data-xr-boundary` marks the boundary of THIS plate, so the root must be
27
+ * serialized as a real Entry (its box/classes/padding/border) rather than a
28
+ * stitch-to-itself. Defaults to `false` — the auto path, where the top-level
29
+ * roots are the wrapper's CHILDREN and any boundary marker on a direct-child
30
+ * root is a NESTED `<Skeleton>` that MUST stitch (the capture-leak guard).
31
+ */
32
+ captureRootIsBoundary?: boolean;
33
+ }
34
+ /**
35
+ * What a capture walker decides for one element (ADR 0018; ADR 0022 §5). The
36
+ * `applyWalker` PASS reads the decision and applies it to the measured IR node —
37
+ * a walker NEVER hand-builds a `PlateNode`, so xray keeps ownership of the Plate
38
+ * format. `ignore` drops the element + its subtree; `bone` collapses it to one
39
+ * Bone leaf (inferring the kind when omitted); `keep` defers to the default
40
+ * classifier (`markInk`).
41
+ */
42
+ type WalkerDecision = {
43
+ type: 'ignore';
44
+ } | {
45
+ type: 'bone';
46
+ kind?: LeafKind;
47
+ } | {
48
+ type: 'keep';
49
+ };
50
+ /**
51
+ * The context handed to a capture walker's `element` hook (ADR 0018). The
52
+ * helpers are PURE — each returns a `WalkerDecision` the `applyWalker` pass
53
+ * applies; they do NOT mutate. `el` is the element under consideration.
54
+ */
55
+ interface CaptureWalkerContext {
56
+ /** The element currently being classified. */
57
+ el: Element;
58
+ /** Drop this element AND its whole subtree (no bone). */
59
+ ignore(): WalkerDecision;
60
+ /**
61
+ * Collapse this element's subtree into ONE Bone leaf. `kind` omitted shares
62
+ * the default classifier's kind-inference heuristic (`inferLeafKind`; ADR 0018,
63
+ * Q4 — ONE code path).
64
+ */
65
+ bone(opts?: {
66
+ kind?: LeafKind;
67
+ }): WalkerDecision;
68
+ /** Defer to the default classifier (`markInk`) — recurse into the subtree. */
69
+ keep(): WalkerDecision;
70
+ }
71
+ /**
72
+ * The programmable capture walker (ADR 0018; ADR 0022 §5). `element` is offered
73
+ * each non-boundary element TOP-DOWN over the measured IR (the `applyWalker`
74
+ * pass, NOT the DOM walk) and returns a `WalkerDecision` the pass applies. The
75
+ * declarative `data-xr-*` annotations cover the 90%; this is the 10% escape
76
+ * hatch for what a markup attribute cannot express.
77
+ */
78
+ interface XrayCaptureWalker {
79
+ /**
80
+ * Called for every non-boundary element node (a stitch carries no element and
81
+ * is skipped — ADR 0006 — so a boundary never reaches here). Return one of
82
+ * `ctx.ignore()`, `ctx.bone()`, or `ctx.keep()`. An `ignore`/`bone` decision
83
+ * stops the descent (the subtree lowers); `keep` recurses.
84
+ */
85
+ element?(ctx: CaptureWalkerContext): WalkerDecision;
86
+ }
87
+ /**
88
+ * Typed identity wrapper for authoring a capture walker (ADR 0018) — the
89
+ * `defineConfig` pattern. It returns its argument unchanged at runtime; its only
90
+ * job is to infer and check the `XrayCaptureWalker` shape at the call site so an
91
+ * author gets completion and a typo in a hook name is caught.
92
+ */
93
+ declare function defineXrayCaptureWalker(walker: XrayCaptureWalker): XrayCaptureWalker;
94
+ /**
95
+ * Thrown when a subtree has more nodes than the capture limit — almost always
96
+ * a `<Skeleton>` sitting too high in the tree. Raised after the cheap walk and
97
+ * before the O(rules × nodes) CSS extraction, so an oversized capture is
98
+ * refused without freezing the main thread on it.
99
+ */
100
+ declare class CaptureTooLargeError extends Error {
101
+ readonly nodeCount: number;
102
+ /** Folds the oversized-capture warning into the shared diagnostics vocabulary (diagnostics.ts). */
103
+ readonly code: "too-large";
104
+ constructor(nodeCount: number);
105
+ }
106
+ //#endregion
107
+ export { XrayCaptureWalker as a, WalkerDecision as i, CaptureTooLargeError as n, defineXrayCaptureWalker as o, CaptureWalkerContext as r, CaptureOptions as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hueest/xray",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Auto-captured skeleton loading screens for Vite — capture the structure, ship the plate.",
5
5
  "keywords": [
6
6
  "loading",
@@ -58,6 +58,7 @@
58
58
  "access": "public"
59
59
  },
60
60
  "dependencies": {
61
+ "@chenglou/pretext": "0.0.8",
61
62
  "devalue": "5.8.1",
62
63
  "valibot": "1.4.1"
63
64
  },