sitepong 0.2.9 → 0.2.10

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.
@@ -802,6 +802,7 @@ declare class StructuralCapture {
802
802
  private flushing;
803
803
  private readonly scrollOffsets;
804
804
  private overloadSkip;
805
+ private explicitRoot;
805
806
  private appStateSub;
806
807
  private readonly teardowns;
807
808
  private now;
@@ -812,6 +813,13 @@ declare class StructuralCapture {
812
813
  private installCrashFlush;
813
814
  /** Flush on background/inactive so timer suspension doesn't strand the tail. */
814
815
  private installBackgroundFlush;
816
+ /**
817
+ * Acquire the FiberRoot from the provider's root-View public instance (a ref).
818
+ * Called once on provider mount. This makes capture independent of the React
819
+ * DevTools commit hook, which Release builds strip — without it the fiber walk
820
+ * never runs in production and only the initial viewport message is emitted.
821
+ */
822
+ setRootInstance(instance: unknown): void;
815
823
  private sample;
816
824
  setScreen(name: string): void;
817
825
  /** Resolve a native touch to a node + emit a tap. `target` is the RN
@@ -3920,6 +3920,16 @@ function walkFiberRoot(root) {
3920
3920
  const tree = { key: rootKey, tag: "View", attrs: { style: JSON.stringify({ flex: 1 }) }, children };
3921
3921
  return { tree, index };
3922
3922
  }
3923
+ function fiberRootFromInstance(instance) {
3924
+ if (!instance || typeof instance !== "object") return null;
3925
+ const inst = instance;
3926
+ const fiber = inst.__internalInstanceHandle ?? inst._internalFiberInstanceHandleDEV ?? null;
3927
+ if (!fiber || typeof fiber !== "object") return null;
3928
+ let top = fiber;
3929
+ for (let guard = 0; top.return && guard < 1e5; guard++) top = top.return;
3930
+ const fiberRoot = top.stateNode;
3931
+ return fiberRoot && typeof fiberRoot === "object" && fiberRoot.current ? fiberRoot : null;
3932
+ }
3923
3933
 
3924
3934
  // src/react-native/structural/capture.ts
3925
3935
  var WALK_BUDGET_MS = 24;
@@ -3950,6 +3960,14 @@ var StructuralCapture = class {
3950
3960
  this.scrollOffsets = /* @__PURE__ */ new Map();
3951
3961
  // Adaptive sampling: skip this many upcoming ticks after a heavy walk.
3952
3962
  this.overloadSkip = 0;
3963
+ // FiberRoot acquired from the provider's root-View ref (fiber.ts). This is the
3964
+ // production path: Release builds strip the React DevTools commit hook, so
3965
+ // `hookState.latestRoot` never populates and hook-based capture emits only the
3966
+ // initial viewport message. The FiberRoot persists for the app lifetime and
3967
+ // walkFiberRoot reads its live `.current` each sample, so we hold it here and
3968
+ // walk every tick (no `dirty` signal exists without the hook).
3969
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3970
+ this.explicitRoot = null;
3953
3971
  this.appStateSub = null;
3954
3972
  this.teardowns = [];
3955
3973
  }
@@ -3972,6 +3990,7 @@ var StructuralCapture = class {
3972
3990
  this.sentCount = 0;
3973
3991
  this.scrollOffsets.clear();
3974
3992
  this.overloadSkip = 0;
3993
+ this.explicitRoot = null;
3975
3994
  const { width, height } = reactNative.Dimensions.get("window");
3976
3995
  this.recorder.setViewport(Math.round(width), Math.round(height), 0);
3977
3996
  this.sampleTimer = setInterval(() => this.sample(), cfg.sampleIntervalMs ?? 120);
@@ -4004,15 +4023,31 @@ var StructuralCapture = class {
4004
4023
  this.appStateSub = null;
4005
4024
  });
4006
4025
  }
4026
+ /**
4027
+ * Acquire the FiberRoot from the provider's root-View public instance (a ref).
4028
+ * Called once on provider mount. This makes capture independent of the React
4029
+ * DevTools commit hook, which Release builds strip — without it the fiber walk
4030
+ * never runs in production and only the initial viewport message is emitted.
4031
+ */
4032
+ setRootInstance(instance) {
4033
+ const root = fiberRootFromInstance(instance);
4034
+ if (root) {
4035
+ this.explicitRoot = root;
4036
+ if (this.cfg?.debug) console.log("[structural] fiber root acquired via ref");
4037
+ this.sample(true);
4038
+ } else if (this.cfg?.debug) {
4039
+ console.log("[structural] ref did not yield a fiber root \u2014 relying on the commit hook (dev only)");
4040
+ }
4041
+ }
4007
4042
  sample(force = false) {
4008
4043
  if (!this.running) return;
4009
4044
  if (!force && this.overloadSkip > 0) {
4010
4045
  this.overloadSkip--;
4011
4046
  return;
4012
4047
  }
4013
- if (!force && !hookState.dirty) return;
4048
+ if (!force && !this.explicitRoot && !hookState.dirty) return;
4014
4049
  hookState.dirty = false;
4015
- const root = hookState.latestRoot;
4050
+ const root = hookState.latestRoot ?? this.explicitRoot;
4016
4051
  if (!root) return;
4017
4052
  const t0 = Date.now();
4018
4053
  try {
@@ -4122,6 +4157,7 @@ var StructuralCapture = class {
4122
4157
  this.sampleTimer = null;
4123
4158
  this.flushTimer = null;
4124
4159
  this.running = false;
4160
+ this.explicitRoot = null;
4125
4161
  for (const t of this.teardowns.splice(0)) {
4126
4162
  try {
4127
4163
  t();
@@ -4738,8 +4774,10 @@ var TAP_MOVE_THRESHOLD_PX = 12;
4738
4774
  function StructuralCaptureProvider({ children, ...cfg }) {
4739
4775
  const cfgRef = React2.useRef(cfg);
4740
4776
  cfgRef.current = cfg;
4777
+ const rootRef = React2.useRef(null);
4741
4778
  React2.useEffect(() => {
4742
4779
  structuralCapture.start(cfgRef.current);
4780
+ structuralCapture.setRootInstance(rootRef.current);
4743
4781
  return () => {
4744
4782
  void structuralCapture.stop();
4745
4783
  };
@@ -4781,7 +4819,7 @@ function StructuralCaptureProvider({ children, ...cfg }) {
4781
4819
  }
4782
4820
  structuralCapture.handleTap(g2.target, ne.pageX, ne.pageY);
4783
4821
  };
4784
- return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flex: 1 }, onTouchStart, onTouchMove, onTouchEnd, children });
4822
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { ref: rootRef, style: { flex: 1 }, onTouchStart, onTouchMove, onTouchEnd, children });
4785
4823
  }
4786
4824
  function useStructuralScreen(name) {
4787
4825
  React2.useEffect(() => {