@goliapkg/sentori-react-native 1.0.0-rc.2 → 1.0.0-rc.3

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,7 +1,6 @@
1
1
  package com.sentori
2
2
 
3
3
  import android.app.Activity
4
- import android.graphics.Rect
5
4
  import android.view.View
6
5
  import android.view.ViewGroup
7
6
  import android.widget.EditText
@@ -25,11 +24,29 @@ import org.json.JSONObject
25
24
  object SentoriReplayCapture {
26
25
 
27
26
  private const val MAX_NODES = 800
28
-
29
- // v0.9.12 — diagnostic readout so the JS side can ask "why is the
30
- // ring empty?" without parsing logcat. Mirrors the iOS side.
27
+ private const val MAX_DEPTH = 60
28
+
29
+ // Diagnostic readouts. Mirrors the iOS side. Surfaced via
30
+ // `probe()` so JS can answer "why is the ring shallow?" without
31
+ // parsing logcat.
32
+ //
33
+ // v0.9.12: lastPath + lastNodes
34
+ // v1.0.0-rc.3:
35
+ // * lastDepthMax — deepest descendant the walker reached. If
36
+ // this stays at 2 or 3 we know the recursion bailed early
37
+ // (the rc.2 zero-size-bails-subtree bug).
38
+ // * lastSizeBytes — byte length of the serialised payload. ~50
39
+ // bytes per node is typical; a 1 KB result with 800 nodes
40
+ // would be a red flag.
41
+ // * totalTicks / lastEmptyResultTicks — lifetime counters for
42
+ // ring health, so a thin-but-non-null capture doesn't slip
43
+ // through unnoticed.
31
44
  @Volatile private var lastDiagPath: String = "none(not-yet-called)"
32
45
  @Volatile private var lastDiagNodes: Int = 0
46
+ @Volatile private var lastDiagDepthMax: Int = 0
47
+ @Volatile private var lastDiagSizeBytes: Int = 0
48
+ @Volatile private var totalTicks: Long = 0
49
+ @Volatile private var totalEmptyResultTicks: Long = 0
33
50
 
34
51
  @JvmStatic
35
52
  fun probe(): Map<String, Any> {
@@ -37,6 +54,10 @@ object SentoriReplayCapture {
37
54
  return mapOf(
38
55
  "lastPath" to lastDiagPath,
39
56
  "lastNodes" to lastDiagNodes,
57
+ "lastDepthMax" to lastDiagDepthMax,
58
+ "lastSizeBytes" to lastDiagSizeBytes,
59
+ "totalTicks" to totalTicks,
60
+ "totalEmptyResultTicks" to totalEmptyResultTicks,
40
61
  "trackedSource" to SentoriForegroundActivity.lastPath,
41
62
  "trackedActivity" to (activity?.javaClass?.name ?: "null"),
42
63
  "decorViewFound" to (activity?.window?.decorView != null),
@@ -61,29 +82,30 @@ object SentoriReplayCapture {
61
82
 
62
83
  @JvmStatic
63
84
  fun captureWireframe(maskedIds: List<String>): String? {
85
+ totalTicks++
64
86
  val activity = SentoriForegroundActivity.current()
65
87
  if (activity == null) {
66
88
  lastDiagPath = "activity.null"
89
+ totalEmptyResultTicks++
67
90
  return null
68
91
  }
69
92
  val root = activity.window?.decorView
70
93
  if (root == null) {
71
94
  lastDiagPath = "decorView.null"
95
+ totalEmptyResultTicks++
72
96
  return null
73
97
  }
74
98
  if (root.width <= 0 || root.height <= 0) {
75
99
  lastDiagPath = "root.zero-size"
100
+ totalEmptyResultTicks++
76
101
  return null
77
102
  }
78
103
 
79
104
  val maskedSet = maskedIds.toHashSet()
80
105
  val nodes = JSONArray()
81
- val rect = Rect()
82
106
  val rootLoc = IntArray(2).also { root.getLocationInWindow(it) }
83
- walk(root, false, maskedSet, rootLoc, rect, nodes)
84
-
85
- lastDiagPath = "ok(${SentoriForegroundActivity.lastPath})"
86
- lastDiagNodes = nodes.length()
107
+ val ctx = WalkContext(rootLoc = rootLoc, maskedSet = maskedSet)
108
+ walk(root, depth = 0, parentMasked = false, ctx = ctx, nodes = nodes)
87
109
 
88
110
  val payload = JSONObject().apply {
89
111
  put("ts", System.currentTimeMillis())
@@ -91,77 +113,123 @@ object SentoriReplayCapture {
91
113
  put("height", root.height)
92
114
  put("nodes", nodes)
93
115
  }
94
- return payload.toString()
116
+ val serialised = payload.toString()
117
+
118
+ lastDiagPath = "ok(${SentoriForegroundActivity.lastPath})"
119
+ lastDiagNodes = nodes.length()
120
+ lastDiagDepthMax = ctx.depthMax
121
+ lastDiagSizeBytes = serialised.length
122
+
123
+ if (nodes.length() == 0) totalEmptyResultTicks++
124
+
125
+ return serialised
95
126
  }
96
127
 
128
+ /** Per-walk scratch: tracks the deepest descendant reached so
129
+ * the probe can surface whether the recursion ran or bailed.
130
+ * Bundled into one object to keep the recursive signature
131
+ * manageable. */
132
+ private class WalkContext(
133
+ val rootLoc: IntArray,
134
+ val maskedSet: Set<String>,
135
+ var depthMax: Int = 0,
136
+ )
137
+
138
+ /**
139
+ * Recursive walker.
140
+ *
141
+ * v1.0.0-rc.3 fix: previously this function returned ENTIRELY
142
+ * when the view itself had `width <= 0 || height <= 0`. That
143
+ * meant any ViewGroup wrapper that happened to measure to zero
144
+ * size during the tick (common on Fabric / RN's intermediate
145
+ * shadow-tree wrappers, and on lazy-layout phases) skipped the
146
+ * whole descendant subtree — Insight 2026-05-17 verify event
147
+ * saw 800-node frames whose subtree was actually thousands of
148
+ * Views deep but only the root + 2-3 wrappers made it into the
149
+ * JSON.
150
+ *
151
+ * Now we separate "emit a node for this view" from "recurse into
152
+ * its children". A zero-size view doesn't get an emitted node
153
+ * (no visual contribution) but its descendants still get walked
154
+ * — they may have real frames.
155
+ */
97
156
  private fun walk(
98
157
  view: View,
158
+ depth: Int,
99
159
  parentMasked: Boolean,
100
- maskedSet: Set<String>,
101
- rootLoc: IntArray,
102
- scratch: Rect,
160
+ ctx: WalkContext,
103
161
  nodes: JSONArray,
104
162
  ) {
105
163
  if (nodes.length() >= MAX_NODES) return
164
+ if (depth >= MAX_DEPTH) return
106
165
  if (view.visibility != View.VISIBLE || view.alpha < 0.01) return
107
166
 
167
+ if (depth > ctx.depthMax) ctx.depthMax = depth
168
+
108
169
  val viewTag = view.tag as? String
109
- val isThisMasked = viewTag != null && maskedSet.contains(viewTag)
170
+ val isThisMasked = viewTag != null && ctx.maskedSet.contains(viewTag)
110
171
  val masked = parentMasked || isThisMasked
111
172
 
112
- val loc = IntArray(2)
113
- view.getLocationInWindow(loc)
114
- val x = loc[0] - rootLoc[0]
115
- val y = loc[1] - rootLoc[1]
116
173
  val w = view.width
117
174
  val h = view.height
118
- if (w <= 0 || h <= 0) return
119
-
120
- val node = JSONObject().apply {
121
- put("x", x)
122
- put("y", y)
123
- put("w", w)
124
- put("h", h)
125
- }
126
175
 
127
- var kindEmitted = false
128
- when {
129
- masked -> {
130
- node.put("kind", "mask")
131
- kindEmitted = true
132
- }
133
- view is TextView && !view.text.isNullOrEmpty() -> {
134
- node.put("kind", "text")
135
- val text = view.text.toString().let { if (it.length > 200) it.substring(0, 200) else it }
136
- node.put("text", text)
137
- node.put("color", colorToHex(view.currentTextColor))
138
- kindEmitted = true
139
- }
140
- view is EditText -> {
141
- node.put("kind", "text")
142
- val text = (view.text ?: "").toString().let { if (it.length > 200) it.substring(0, 200) else it }
143
- node.put("text", text)
144
- kindEmitted = true
176
+ // Emit a node ONLY when the view has visual extent. A zero-
177
+ // size view contributes nothing to render but its subtree
178
+ // might; recurse below regardless.
179
+ if (w > 0 && h > 0) {
180
+ val loc = IntArray(2)
181
+ view.getLocationInWindow(loc)
182
+ val x = loc[0] - ctx.rootLoc[0]
183
+ val y = loc[1] - ctx.rootLoc[1]
184
+
185
+ val node = JSONObject().apply {
186
+ put("x", x)
187
+ put("y", y)
188
+ put("w", w)
189
+ put("h", h)
145
190
  }
146
- view is ImageView -> {
147
- node.put("kind", "image")
148
- kindEmitted = true
149
- }
150
- view.background != null -> {
151
- node.put("kind", "rect")
152
- // Background drawables don't always expose color directly.
153
- // Skip color for non-ColorDrawable; renderer falls back to neutral.
154
- kindEmitted = true
191
+
192
+ var kindEmitted = false
193
+ when {
194
+ masked -> {
195
+ node.put("kind", "mask")
196
+ kindEmitted = true
197
+ }
198
+ view is TextView && !view.text.isNullOrEmpty() -> {
199
+ node.put("kind", "text")
200
+ val text = view.text.toString().let { if (it.length > 200) it.substring(0, 200) else it }
201
+ node.put("text", text)
202
+ node.put("color", colorToHex(view.currentTextColor))
203
+ kindEmitted = true
204
+ }
205
+ view is EditText -> {
206
+ node.put("kind", "text")
207
+ val text = (view.text ?: "").toString().let { if (it.length > 200) it.substring(0, 200) else it }
208
+ node.put("text", text)
209
+ kindEmitted = true
210
+ }
211
+ view is ImageView -> {
212
+ node.put("kind", "image")
213
+ kindEmitted = true
214
+ }
215
+ view.background != null -> {
216
+ node.put("kind", "rect")
217
+ // Background drawables don't always expose color directly.
218
+ // Skip color for non-ColorDrawable; renderer falls back to neutral.
219
+ kindEmitted = true
220
+ }
155
221
  }
156
- }
157
222
 
158
- if (kindEmitted) {
159
- nodes.put(node)
223
+ if (kindEmitted) {
224
+ nodes.put(node)
225
+ }
160
226
  }
161
227
 
228
+ // Always recurse — even zero-size wrappers can host real
229
+ // descendants (the rc.3 fix).
162
230
  if (!masked && view is ViewGroup) {
163
231
  for (i in 0 until view.childCount) {
164
- walk(view.getChildAt(i), masked, maskedSet, rootLoc, scratch, nodes)
232
+ walk(view.getChildAt(i), depth + 1, masked, ctx, nodes)
165
233
  }
166
234
  }
167
235
  }
@@ -29,22 +29,31 @@ import UIKit
29
29
  return result
30
30
  }
31
31
 
32
- /// Last path the keyWindow lookup took. Exposed to JS via
33
- /// `probeWireframe()` so the failure-mode diagnostic in Metro can
34
- /// tell scene-race from "no window at all" without re-rolling the
35
- /// pod. Updated on every captureSync call.
32
+ /// Diagnostic readouts exposed to JS via `probeWireframe()`.
33
+ ///
34
+ /// v0.9.12: lastPath / lastNodes / scene-window counts
35
+ /// v1.0.0-rc.3: + lastDepthMax / lastSizeBytes / totalTicks /
36
+ /// totalEmptyResultTicks — answers "the ring isn't
37
+ /// empty but the dashboard renders nothing, which
38
+ /// layer dropped the data?" without a re-roll.
36
39
  @objc public static var lastDiagPath: String = "none(not-yet-called)"
37
40
  @objc public static var lastDiagNodes: Int = 0
38
41
  @objc public static var lastDiagSceneCount: Int = 0
39
42
  @objc public static var lastDiagWindowCount: Int = 0
43
+ @objc public static var lastDiagDepthMax: Int = 0
44
+ @objc public static var lastDiagSizeBytes: Int = 0
45
+ @objc public static var totalTicks: Int = 0
46
+ @objc public static var totalEmptyResultTicks: Int = 0
40
47
  private static var loggedFirstResult = false
41
48
 
42
49
  private static func captureSync(maskedIds: Set<String>) -> String? {
50
+ totalTicks += 1
43
51
  let (winOpt, path) = resolveKeyWindow()
44
52
  lastDiagPath = path
45
53
  lastDiagSceneCount = currentSceneCount()
46
54
  lastDiagWindowCount = currentWindowCount()
47
55
  guard let window = winOpt else {
56
+ totalEmptyResultTicks += 1
48
57
  if !loggedFirstResult {
49
58
  NSLog(
50
59
  "[sentori] wireframe: returning nil — keyWindow path=%@ scenes=%d windows=%d",
@@ -57,21 +66,29 @@ import UIKit
57
66
  return nil
58
67
  }
59
68
  var nodes: [[String: Any]] = []
69
+ var depthMax = 0
60
70
  walk(
61
71
  view: window,
72
+ depth: 0,
73
+ depthMax: &depthMax,
62
74
  parentMasked: false,
63
75
  maskedIds: maskedIds,
64
76
  window: window,
65
77
  nodes: &nodes
66
78
  )
67
79
  lastDiagNodes = nodes.count
80
+ lastDiagDepthMax = depthMax
81
+ if nodes.isEmpty {
82
+ totalEmptyResultTicks += 1
83
+ }
68
84
  if !loggedFirstResult {
69
85
  NSLog(
70
- "[sentori] wireframe: first capture ok — keyWindow path=%@ bounds=%.0fx%.0f nodes=%d",
86
+ "[sentori] wireframe: first capture ok — keyWindow path=%@ bounds=%.0fx%.0f nodes=%d depthMax=%d",
71
87
  path,
72
88
  window.bounds.width,
73
89
  window.bounds.height,
74
- nodes.count
90
+ nodes.count,
91
+ depthMax
75
92
  )
76
93
  loggedFirstResult = true
77
94
  }
@@ -82,7 +99,9 @@ import UIKit
82
99
  "nodes": nodes,
83
100
  ]
84
101
  if let data = try? JSONSerialization.data(withJSONObject: payload, options: []) {
85
- return String(data: data, encoding: .utf8)
102
+ let s = String(data: data, encoding: .utf8)
103
+ lastDiagSizeBytes = s?.utf8.count ?? 0
104
+ return s
86
105
  }
87
106
  return nil
88
107
  }
@@ -157,23 +176,33 @@ import UIKit
157
176
  "lastNodes": lastDiagNodes,
158
177
  "sceneCount": lastDiagSceneCount,
159
178
  "windowCount": lastDiagWindowCount,
179
+ "lastDepthMax": lastDiagDepthMax,
180
+ "lastSizeBytes": lastDiagSizeBytes,
181
+ "totalTicks": totalTicks,
182
+ "totalEmptyResultTicks": totalEmptyResultTicks,
160
183
  ]
161
184
  }
162
185
 
163
186
  /// Cap on nodes per snapshot — extremely deep / wide trees can
164
187
  /// have thousands of subviews (UICollectionView recyclers).
165
188
  private static let MAX_NODES = 800
189
+ private static let MAX_DEPTH = 60
166
190
 
167
191
  private static func walk(
168
192
  view: UIView,
193
+ depth: Int,
194
+ depthMax: inout Int,
169
195
  parentMasked: Bool,
170
196
  maskedIds: Set<String>,
171
197
  window: UIWindow,
172
198
  nodes: inout [[String: Any]]
173
199
  ) {
174
200
  if nodes.count >= MAX_NODES { return }
201
+ if depth >= MAX_DEPTH { return }
175
202
  if view.isHidden || view.alpha < 0.01 { return }
176
203
 
204
+ if depth > depthMax { depthMax = depth }
205
+
177
206
  let isThisMasked = view.accessibilityIdentifier
178
207
  .map { maskedIds.contains($0) } ?? false
179
208
  let masked = parentMasked || isThisMasked
@@ -219,6 +248,8 @@ import UIKit
219
248
  for sub in view.subviews {
220
249
  walk(
221
250
  view: sub,
251
+ depth: depth + 1,
252
+ depthMax: &depthMax,
222
253
  parentMasked: masked,
223
254
  maskedIds: maskedIds,
224
255
  window: window,
package/lib/native.d.ts CHANGED
@@ -106,6 +106,17 @@ export declare function probeNativeWireframe(): {
106
106
  lastPath: string;
107
107
  sceneCount: number;
108
108
  windowCount: number;
109
+ /** v1.0.0-rc.3: max recursion depth reached by the walker on
110
+ * the last tick. Healthy on an RN app: 20-40. If it's 2-3 the
111
+ * walker bailed early (zero-size parent, masked root). */
112
+ lastDepthMax: number;
113
+ /** v1.0.0-rc.3: byte length of the last serialised payload. */
114
+ lastSizeBytes: number;
115
+ /** v1.0.0-rc.3: lifetime totals. `totalEmptyResultTicks /
116
+ * totalTicks` is the failure rate. */
117
+ totalTicks: number;
118
+ totalEmptyResultTicks: number;
119
+ raw: Record<string, unknown>;
109
120
  };
110
121
  /**
111
122
  * v1.0.0-rc.2 — JS entry to the `probeScreenshot` native diagnostic.
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyIH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,IAAI,CAMP;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,IAAI,CAMP;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,IAAI,GAAG,MAAM,CAOpD;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,IAAI,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMhF;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED;;yBAEyB;AACzB,wBAAgB,wBAAwB,IAAI,IAAI,GAAG;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAMA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCvD;AAED;;sEAEsE;AACtE,wBAAgB,uBAAuB,IAAI;IACzC,KAAK,EAAE,OAAO,CAAA;IACd,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAOA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAiCA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,IAAI;IACvC,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7B,CAkBA"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsJH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd,GAAG,IAAI,CAMP;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAQ5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAMzC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IACzC,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,GAAG,IAAI,CAMP;AAED,wBAAgB,eAAe,IAAI,IAAI,CAMtC;AAED,+DAA+D;AAC/D,wBAAgB,uBAAuB,IAAI,IAAI,CAM9C;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,IAAI,IAAI,GAAG,MAAM,CAOpD;AAED,oEAAoE;AACpE,wBAAgB,sBAAsB,IAAI,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAMhF;AAED,iEAAiE;AACjE,wBAAgB,wBAAwB,IAAI,IAAI,CAM/C;AAED;;yBAEyB;AACzB,wBAAgB,wBAAwB,IAAI,IAAI,GAAG;IACjD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAMA;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAoCvD;AAED;;sEAEsE;AACtE,wBAAgB,uBAAuB,IAAI;IACzC,KAAK,EAAE,OAAO,CAAA;IACd,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iBAAiB,EAAE,OAAO,CAAA;CAC3B,CAOA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB;;+DAE2D;IAC3D,YAAY,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAA;IACrB;2CACuC;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7B,CAkDA;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,IAAI;IACvC,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC7B,CAkBA"}
package/lib/native.js CHANGED
@@ -221,19 +221,30 @@ export function probeNativeWireframe() {
221
221
  if (!n || typeof n.probeWireframe !== 'function') {
222
222
  return {
223
223
  available: false,
224
+ lastDepthMax: 0,
224
225
  lastNodes: 0,
225
226
  lastPath: 'native.unavailable',
227
+ lastSizeBytes: 0,
228
+ raw: {},
226
229
  sceneCount: 0,
230
+ totalEmptyResultTicks: 0,
231
+ totalTicks: 0,
227
232
  windowCount: 0,
228
233
  };
229
234
  }
230
235
  try {
231
236
  const r = n.probeWireframe();
237
+ const raw = (r ?? {});
232
238
  return {
233
239
  available: true,
240
+ lastDepthMax: typeof r?.lastDepthMax === 'number' ? r.lastDepthMax : 0,
234
241
  lastNodes: typeof r?.lastNodes === 'number' ? r.lastNodes : 0,
235
242
  lastPath: typeof r?.lastPath === 'string' ? r.lastPath : 'unknown',
243
+ lastSizeBytes: typeof r?.lastSizeBytes === 'number' ? r.lastSizeBytes : 0,
244
+ raw,
236
245
  sceneCount: typeof r?.sceneCount === 'number' ? r.sceneCount : 0,
246
+ totalEmptyResultTicks: typeof r?.totalEmptyResultTicks === 'number' ? r.totalEmptyResultTicks : 0,
247
+ totalTicks: typeof r?.totalTicks === 'number' ? r.totalTicks : 0,
237
248
  windowCount: typeof r?.windowCount === 'number' ? r.windowCount : 0,
238
249
  };
239
250
  }
@@ -244,9 +255,14 @@ export function probeNativeWireframe() {
244
255
  }
245
256
  return {
246
257
  available: false,
258
+ lastDepthMax: 0,
247
259
  lastNodes: 0,
248
260
  lastPath: 'native.threw',
261
+ lastSizeBytes: 0,
262
+ raw: {},
249
263
  sceneCount: 0,
264
+ totalEmptyResultTicks: 0,
265
+ totalTicks: 0,
250
266
  windowCount: 0,
251
267
  };
252
268
  }
package/lib/native.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4GH,IAAI,OAA+C,CAAA;AAEnD,SAAS,MAAM;IACb,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAA;IACzC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAEvC,CAAA;QACD,OAAO,GAAG,IAAI,CAAC,mBAAmB,CAAsB,SAAS,CAAC,CAAA;QAClE,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YAClE,8DAA8D;YAC9D,8DAA8D;YAC9D,8DAA8D;YAC9D,4DAA4D;YAC5D,+BAA+B;YAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAiB,CAAC,CAAC,IAAI,EAAE,CAAA;YAClD,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,CAAA;QAC9F,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,GAAG,IAAI,CAAA;QACd,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,gDAAgD,EAAE,CAAC,CAAC,CAAA;QACnE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAI/B;IACC,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;IAClB,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAA;IACjB,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,CAAC,YAAY,EAAE,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,sBAAsB,EAAE,EAAE,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;IACxC,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAIhC;IACC,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAA;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,gCAAgC;IAClC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,eAAe,EAAE,EAAE,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,uBAAuB;IACrC,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,iBAAiB,EAAE,EAAE,CAAA;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,EAAE,EAAE,cAAc,EAAE,EAAE,CAAA;QACtC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,sBAAsB;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,gBAAgB,EAAE,EAAE,IAAI,IAAI,CAAA;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,EAAE,kBAAkB,EAAE,EAAE,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED;;yBAEyB;AACzB,MAAM,UAAU,wBAAwB;IAMtC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,EAAE,wBAAwB,EAAE,EAAE,IAAI,IAAI,CAAA;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,SAAmB;IAEnB,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;IAClB,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,0EAA0E,CAC3E,CAAA;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC,CAAC,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,+EAA+E,CAChF,CAAA;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,CAAC,CAAC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YACpD,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,2EAA2E,CAC5E,CAAA;QACH,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,CAAA;QACtD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED;;sEAEsE;AACtE,MAAM,UAAU,uBAAuB;IAKrC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;IAClB,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,IAAI;QACjB,mBAAmB,EAAE,OAAO,CAAC,CAAC,EAAE,gBAAgB,CAAC;QACjD,iBAAiB,EAAE,OAAO,CAAC,CAAC,EAAE,cAAc,CAAC;KAC9C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,oBAAoB;IAOlC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;IAClB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;QACjD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,oBAAoB;YAC9B,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;SACf,CAAA;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,CAAA;QAC5B,OAAO;YACL,SAAS,EAAE,IAAI;YACf,SAAS,EAAE,OAAO,CAAC,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YAC7D,QAAQ,EAAE,OAAO,CAAC,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;YAClE,UAAU,EAAE,OAAO,CAAC,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAChE,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;SACpE,CAAA;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAA;QACnD,CAAC;QACD,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,SAAS,EAAE,CAAC;YACZ,QAAQ,EAAE,cAAc;YACxB,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;SACf,CAAA;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,qBAAqB;IAKnC,MAAM,CAAC,GAAG,MAAM,EAAE,CAAA;IAClB,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;QAClD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,EAAE,EAAE,EAAE,CAAA;IACtE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,CAAA;QAC7B,MAAM,GAAG,GACP,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAA6B,CAAC,CAAC,CAAC,EAAE,CAAA;QACvF,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;QAC5E,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;IAC3C,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,CAAC,CAAC,CAAA;QACpD,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,EAAE,EAAE,EAAE,CAAA;IAChE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAkEA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;IAC3B,mCAAmC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CA+CrD;AAED,wBAAgB,UAAU,IAAI,IAAI,CAUjC;AAsGD;;2BAE2B;AAC3B,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C"}
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAkEA,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;IAC3B,mCAAmC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CA+CrD;AAED,wBAAgB,UAAU,IAAI,IAAI,CAUjC;AAuKD;;2BAE2B;AAC3B,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C"}
package/lib/replay.js CHANGED
@@ -111,7 +111,16 @@ export function stopReplay() {
111
111
  }
112
112
  let _emptyTickCount = 0;
113
113
  let _emptyTickLogStride = 1;
114
+ let _thinTickCount = 0;
115
+ let _thinTickLogStride = 1;
116
+ let _okTickCount = 0;
114
117
  let _firstTickLogged = false;
118
+ /** Anything below this many nodes is suspicious — likely the
119
+ * walker bailed early (zero-size parent, masked root, etc.).
120
+ * Insight 2026-05-18 verify event saw 800-node payloads on some
121
+ * ticks and 1-3-node payloads on others; this threshold flags
122
+ * the latter without spamming on small-but-valid screens. */
123
+ const THIN_RESULT_NODES = 6;
115
124
  function captureTick() {
116
125
  if (!_running)
117
126
  return;
@@ -152,6 +161,34 @@ function captureTick() {
152
161
  }
153
162
  _emptyTickCount = 0;
154
163
  _emptyTickLogStride = 1;
164
+ // v1.0.0-rc.3 — Insight 2026-05-18 report: some ticks land
165
+ // valid non-empty JSON but with only the root View + 1-2 wrappers
166
+ // (the Android zero-size-bails-subtree bug, now fixed natively;
167
+ // this log catches similar regressions). Cheap node-count parse
168
+ // — we only look at one digit-level character class.
169
+ _okTickCount += 1;
170
+ if (typeof __DEV__ !== 'undefined' && __DEV__) {
171
+ const nodeCount = countNodesQuick(snapshot);
172
+ const sizeBytes = snapshot.length;
173
+ const isThin = nodeCount < THIN_RESULT_NODES;
174
+ if (isThin) {
175
+ _thinTickCount += 1;
176
+ if (_thinTickCount === 1 || _thinTickCount === _thinTickLogStride) {
177
+ // eslint-disable-next-line no-console
178
+ console.warn(`[sentori] replay tick: thin result nodes=${nodeCount} sizeBytes=${sizeBytes} (thin ticks so far: ${_thinTickCount})`);
179
+ _thinTickLogStride = Math.max(_thinTickLogStride * 10, 10);
180
+ }
181
+ }
182
+ else {
183
+ _thinTickCount = 0;
184
+ _thinTickLogStride = 1;
185
+ }
186
+ // First good tick logs the shape so devs see it once.
187
+ if (_okTickCount === 1) {
188
+ // eslint-disable-next-line no-console
189
+ console.warn(`[sentori] replay tick: first ok — nodes=${nodeCount} sizeBytes=${sizeBytes}`);
190
+ }
191
+ }
155
192
  }
156
193
  else if (typeof __DEV__ !== 'undefined' && __DEV__) {
157
194
  // v0.9.11 — Insight 2026-05-17 Finding 6: tick fires hundreds
@@ -182,6 +219,29 @@ function captureTick() {
182
219
  }
183
220
  }
184
221
  }
222
+ /**
223
+ * Approximate node-count parse — counts occurrences of the
224
+ * `"x":` key in the serialised payload. Every node JSON object
225
+ * starts with `{"x":<n>,"y":<n>,"w":<n>,"h":<n>...}` so the
226
+ * occurrence count matches the array length without paying for a
227
+ * full `JSON.parse`. Cheap enough to run inside the 1 Hz tick.
228
+ */
229
+ function countNodesQuick(payload) {
230
+ let count = 0;
231
+ let i = 0;
232
+ // Skip the outer {"ts":..,"width":..,"height":..,"nodes":[
233
+ // and count `"x":` thereafter. The outer payload doesn't contain
234
+ // a top-level "x" key so any match must be a node.
235
+ const needle = '"x":';
236
+ while (true) {
237
+ const at = payload.indexOf(needle, i);
238
+ if (at < 0)
239
+ break;
240
+ count += 1;
241
+ i = at + needle.length;
242
+ }
243
+ return count;
244
+ }
185
245
  function readMaskIds() {
186
246
  const q = getRegisteredMaskQuery();
187
247
  if (!q)
package/lib/replay.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,mEAAmE;AACnE,mEAAmE;AACnE,kEAAkE;AAClE,kEAAkE;AAClE,4DAA4D;AAC5D,EAAE;AACF,gCAAgC;AAChC,kEAAkE;AAClE,iEAAiE;AACjE,+DAA+D;AAC/D,6DAA6D;AAC7D,wDAAwD;AACxD,iEAAiE;AACjE,iEAAiE;AACjE,4DAA4D;AAC5D,wBAAwB;AAExB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAInD,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,SAAS,GAAG,EAAE,CAAC;AAErB;;;wCAGwC;AACxC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,IAAI,KAAK,GAAa,EAAE,CAAC;AACzB,IAAI,MAAM,GAA0C,IAAI,CAAC;AACzD,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB;;;;;;;;;;;;;;;;;GAiBG;AACH,IAAI,WAAW,GAAkB,IAAI,CAAC;AAEtC;;;;uCAIuC;AACvC,IAAI,UAAU,GAA8B,IAAI,CAAC;AAQjD,MAAM,UAAU,WAAW,CAAC,IAAmB;IAC7C,IAAI,QAAQ;QAAE,OAAO;IACrB,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;QAAE,OAAO;IACtC,iEAAiE;IACjE,gEAAgE;IAChE,6DAA6D;IAC7D,8DAA8D;IAC9D,iEAAiE;IACjE,qEAAqE;IACrE,MAAM,IAAI,GAAG,uBAAuB,EAAE,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CACV,4GAA4G,CAC7G,CAAC;QACJ,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;QAC9C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CACV,4BAA4B,EAC5B,QAAQ,EAAE,IAAI,CAAC,KAAK,EACpB,sBAAsB,EAAE,IAAI,CAAC,mBAAmB,CACjD,CAAC;IACJ,CAAC;IACD,QAAQ,GAAG,IAAI,CAAC;IAChB,UAAU,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3F,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QACxB,WAAW,EAAE,CAAC;IAChB,CAAC,EAAE,MAAM,CAAC,CAAC;IACX,0DAA0D;IAC1D,kEAAkE;IAClE,gEAAgE;IAChE,kEAAkE;IAClE,6DAA6D;IAC7D,0DAA0D;IAC1D,iEAAiE;IACjE,8DAA8D;IAC9D,8DAA8D;IAC9D,2BAA2B;IAC3B,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;QAC9C,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,0CAA0C,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACzE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,QAAQ,GAAG,KAAK,CAAC;IACjB,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;IACD,UAAU,GAAG,IAAI,CAAC;IAClB,eAAe,GAAG,CAAC,CAAC;IACpB,mBAAmB,GAAG,CAAC,CAAC;IACxB,gBAAgB,GAAG,KAAK,CAAC;AAC3B,CAAC;AAED,IAAI,eAAe,GAAG,CAAC,CAAC;AACxB,IAAI,mBAAmB,GAAG,CAAC,CAAC;AAC5B,IAAI,cAAc,GAAG,CAAC,CAAC;AACvB,IAAI,kBAAkB,GAAG,CAAC,CAAC;AAC3B,IAAI,YAAY,GAAG,CAAC,CAAC;AACrB,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAE7B;;;;8DAI8D;AAC9D,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAE5B,SAAS,WAAW;IAClB,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,iEAAiE;IACjE,8DAA8D;IAC9D,qEAAqE;IACrE,iEAAiE;IACjE,2DAA2D;IAC3D,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACnE,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACxD,gBAAgB,GAAG,IAAI,CAAC;IAC1B,CAAC;IACD,sDAAsD;IACtD,8DAA8D;IAC9D,+DAA+D;IAC/D,kEAAkE;IAClE,wCAAwC;IACxC,IAAI,QAAQ,GAAwC,IAAI,CAAC;IACzD,IAAI,CAAC;QACH,QAAQ,GAAG,SAAS,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,UAAU,EAAE,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,+DAA+D;YAC/D,yDAAyD;YACzD,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACrB,WAAW,GAAG,QAAQ,CAAC;gBACvB,OAAO,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;oBAChC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,CAAC;YACH,CAAC;YACD,eAAe,GAAG,CAAC,CAAC;YACpB,mBAAmB,GAAG,CAAC,CAAC;YAExB,2DAA2D;YAC3D,kEAAkE;YAClE,gEAAgE;YAChE,gEAAgE;YAChE,qDAAqD;YACrD,YAAY,IAAI,CAAC,CAAC;YAClB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;gBAC9C,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;gBAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAClC,MAAM,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAAC;gBAC7C,IAAI,MAAM,EAAE,CAAC;oBACX,cAAc,IAAI,CAAC,CAAC;oBACpB,IAAI,cAAc,KAAK,CAAC,IAAI,cAAc,KAAK,kBAAkB,EAAE,CAAC;wBAClE,sCAAsC;wBACtC,OAAO,CAAC,IAAI,CACV,4CAA4C,SAAS,cAAc,SAAS,wBAAwB,cAAc,GAAG,CACtH,CAAC;wBACF,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,cAAc,GAAG,CAAC,CAAC;oBACnB,kBAAkB,GAAG,CAAC,CAAC;gBACzB,CAAC;gBACD,sDAAsD;gBACtD,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;oBACvB,sCAAsC;oBACtC,OAAO,CAAC,IAAI,CACV,2CAA2C,SAAS,cAAc,SAAS,EAAE,CAC9E,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YACrD,8DAA8D;YAC9D,8DAA8D;YAC9D,0DAA0D;YAC1D,6DAA6D;YAC7D,qBAAqB;YACrB,eAAe,IAAI,CAAC,CAAC;YACrB,IAAI,eAAe,KAAK,CAAC,IAAI,eAAe,KAAK,mBAAmB,EAAE,CAAC;gBACrE,sCAAsC;gBACtC,OAAO,CAAC,IAAI,CACV,wCAAwC,EACxC,QAAQ,KAAK,IAAI;oBACf,CAAC,CAAC,MAAM;oBACR,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ;wBAC5B,CAAC,CAAC,iBAAiB,QAAQ,CAAC,MAAM,GAAG;wBACrC,CAAC,CAAC,OAAO,QAAQ,EACrB,wBAAwB,eAAe,GAAG,CAC3C,CAAC;gBACF,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,mBAAmB,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QACD,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,KAAK;YAAE,QAAQ,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QACrE,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,CAAC;YAC9C,sCAAsC;YACtC,OAAO,CAAC,IAAI,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,OAAe;IACtC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,2DAA2D;IAC3D,iEAAiE;IACjE,mDAAmD;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtC,IAAI,EAAE,GAAG,CAAC;YAAE,MAAM;QAClB,KAAK,IAAI,CAAC,CAAC;QACX,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,CAAC,GAAG,sBAAsB,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,IAAI,CAAC;QACH,OAAO,CAAC,EAAE,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAMD,SAAS,gBAAgB;IACvB,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAEvC,CAAC;QACF,OAAO,IAAI,CAAC,mBAAmB,CAAqB,SAAS,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;2BAE2B;AAC3B,MAAM,UAAU,WAAW;IACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,KAAK,GAAG,EAAE,CAAC;IACX,WAAW,GAAG,IAAI,CAAC;IACnB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,UAAU,EAAE,CAAC;IACb,KAAK,GAAG,EAAE,CAAC;IACX,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goliapkg/sentori-react-native",
3
- "version": "1.0.0-rc.2",
3
+ "version": "1.0.0-rc.3",
4
4
  "description": "Sentori SDK for React Native \u2014 JS-layer error capture, native crash handlers (iOS / Android), batched transport, fetch + react-navigation tracing.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://sentori.golia.jp",
package/src/native.ts CHANGED
@@ -83,6 +83,19 @@ type SentoriNativeModule = {
83
83
  trackedSource?: string
84
84
  trackedActivity?: string
85
85
  decorViewFound?: boolean
86
+ /** v1.0.0-rc.3: deepest descendant reached by the walker. If
87
+ * this is 2-3 the walker bailed early; if it matches the
88
+ * expected view-tree depth (~20-40 for RN apps) the capture
89
+ * is healthy. */
90
+ lastDepthMax?: number
91
+ /** v1.0.0-rc.3: byte length of the last serialised payload. */
92
+ lastSizeBytes?: number
93
+ /** v1.0.0-rc.3: lifetime counters — totalTicks is the number
94
+ * of times native captureWireframe ran; totalEmptyResultTicks
95
+ * is the subset that came back null or empty. Ratio surfaces
96
+ * intermittent failures (e.g. 200/240 ≈ 80% failure rate). */
97
+ totalTicks?: number
98
+ totalEmptyResultTicks?: number
86
99
  }
87
100
  /**
88
101
  * v1.0.0-rc.2 — diagnostic mirror of probeWireframe for the
@@ -356,24 +369,47 @@ export function probeNativeWireframe(): {
356
369
  lastPath: string
357
370
  sceneCount: number
358
371
  windowCount: number
372
+ /** v1.0.0-rc.3: max recursion depth reached by the walker on
373
+ * the last tick. Healthy on an RN app: 20-40. If it's 2-3 the
374
+ * walker bailed early (zero-size parent, masked root). */
375
+ lastDepthMax: number
376
+ /** v1.0.0-rc.3: byte length of the last serialised payload. */
377
+ lastSizeBytes: number
378
+ /** v1.0.0-rc.3: lifetime totals. `totalEmptyResultTicks /
379
+ * totalTicks` is the failure rate. */
380
+ totalTicks: number
381
+ totalEmptyResultTicks: number
382
+ raw: Record<string, unknown>
359
383
  } {
360
384
  const n = native()
361
385
  if (!n || typeof n.probeWireframe !== 'function') {
362
386
  return {
363
387
  available: false,
388
+ lastDepthMax: 0,
364
389
  lastNodes: 0,
365
390
  lastPath: 'native.unavailable',
391
+ lastSizeBytes: 0,
392
+ raw: {},
366
393
  sceneCount: 0,
394
+ totalEmptyResultTicks: 0,
395
+ totalTicks: 0,
367
396
  windowCount: 0,
368
397
  }
369
398
  }
370
399
  try {
371
400
  const r = n.probeWireframe()
401
+ const raw = (r ?? {}) as Record<string, unknown>
372
402
  return {
373
403
  available: true,
404
+ lastDepthMax: typeof r?.lastDepthMax === 'number' ? r.lastDepthMax : 0,
374
405
  lastNodes: typeof r?.lastNodes === 'number' ? r.lastNodes : 0,
375
406
  lastPath: typeof r?.lastPath === 'string' ? r.lastPath : 'unknown',
407
+ lastSizeBytes: typeof r?.lastSizeBytes === 'number' ? r.lastSizeBytes : 0,
408
+ raw,
376
409
  sceneCount: typeof r?.sceneCount === 'number' ? r.sceneCount : 0,
410
+ totalEmptyResultTicks:
411
+ typeof r?.totalEmptyResultTicks === 'number' ? r.totalEmptyResultTicks : 0,
412
+ totalTicks: typeof r?.totalTicks === 'number' ? r.totalTicks : 0,
377
413
  windowCount: typeof r?.windowCount === 'number' ? r.windowCount : 0,
378
414
  }
379
415
  } catch (e) {
@@ -383,9 +419,14 @@ export function probeNativeWireframe(): {
383
419
  }
384
420
  return {
385
421
  available: false,
422
+ lastDepthMax: 0,
386
423
  lastNodes: 0,
387
424
  lastPath: 'native.threw',
425
+ lastSizeBytes: 0,
426
+ raw: {},
388
427
  sceneCount: 0,
428
+ totalEmptyResultTicks: 0,
429
+ totalTicks: 0,
389
430
  windowCount: 0,
390
431
  }
391
432
  }
package/src/replay.ts CHANGED
@@ -133,8 +133,18 @@ export function stopReplay(): void {
133
133
 
134
134
  let _emptyTickCount = 0;
135
135
  let _emptyTickLogStride = 1;
136
+ let _thinTickCount = 0;
137
+ let _thinTickLogStride = 1;
138
+ let _okTickCount = 0;
136
139
  let _firstTickLogged = false;
137
140
 
141
+ /** Anything below this many nodes is suspicious — likely the
142
+ * walker bailed early (zero-size parent, masked root, etc.).
143
+ * Insight 2026-05-18 verify event saw 800-node payloads on some
144
+ * ticks and 1-3-node payloads on others; this threshold flags
145
+ * the latter without spamming on small-but-valid screens. */
146
+ const THIN_RESULT_NODES = 6;
147
+
138
148
  function captureTick(): void {
139
149
  if (!_running) return;
140
150
  // v0.9.12 — UNCONDITIONAL first-tick log. Proves the setInterval
@@ -173,6 +183,38 @@ function captureTick(): void {
173
183
  }
174
184
  _emptyTickCount = 0;
175
185
  _emptyTickLogStride = 1;
186
+
187
+ // v1.0.0-rc.3 — Insight 2026-05-18 report: some ticks land
188
+ // valid non-empty JSON but with only the root View + 1-2 wrappers
189
+ // (the Android zero-size-bails-subtree bug, now fixed natively;
190
+ // this log catches similar regressions). Cheap node-count parse
191
+ // — we only look at one digit-level character class.
192
+ _okTickCount += 1;
193
+ if (typeof __DEV__ !== 'undefined' && __DEV__) {
194
+ const nodeCount = countNodesQuick(snapshot);
195
+ const sizeBytes = snapshot.length;
196
+ const isThin = nodeCount < THIN_RESULT_NODES;
197
+ if (isThin) {
198
+ _thinTickCount += 1;
199
+ if (_thinTickCount === 1 || _thinTickCount === _thinTickLogStride) {
200
+ // eslint-disable-next-line no-console
201
+ console.warn(
202
+ `[sentori] replay tick: thin result nodes=${nodeCount} sizeBytes=${sizeBytes} (thin ticks so far: ${_thinTickCount})`,
203
+ );
204
+ _thinTickLogStride = Math.max(_thinTickLogStride * 10, 10);
205
+ }
206
+ } else {
207
+ _thinTickCount = 0;
208
+ _thinTickLogStride = 1;
209
+ }
210
+ // First good tick logs the shape so devs see it once.
211
+ if (_okTickCount === 1) {
212
+ // eslint-disable-next-line no-console
213
+ console.warn(
214
+ `[sentori] replay tick: first ok — nodes=${nodeCount} sizeBytes=${sizeBytes}`,
215
+ );
216
+ }
217
+ }
176
218
  } else if (typeof __DEV__ !== 'undefined' && __DEV__) {
177
219
  // v0.9.11 — Insight 2026-05-17 Finding 6: tick fires hundreds
178
220
  // of times but ring stays empty → native returned null/empty.
@@ -205,6 +247,29 @@ function captureTick(): void {
205
247
  }
206
248
  }
207
249
 
250
+ /**
251
+ * Approximate node-count parse — counts occurrences of the
252
+ * `"x":` key in the serialised payload. Every node JSON object
253
+ * starts with `{"x":<n>,"y":<n>,"w":<n>,"h":<n>...}` so the
254
+ * occurrence count matches the array length without paying for a
255
+ * full `JSON.parse`. Cheap enough to run inside the 1 Hz tick.
256
+ */
257
+ function countNodesQuick(payload: string): number {
258
+ let count = 0;
259
+ let i = 0;
260
+ // Skip the outer {"ts":..,"width":..,"height":..,"nodes":[
261
+ // and count `"x":` thereafter. The outer payload doesn't contain
262
+ // a top-level "x" key so any match must be a node.
263
+ const needle = '"x":';
264
+ while (true) {
265
+ const at = payload.indexOf(needle, i);
266
+ if (at < 0) break;
267
+ count += 1;
268
+ i = at + needle.length;
269
+ }
270
+ return count;
271
+ }
272
+
208
273
  function readMaskIds(): string[] {
209
274
  const q = getRegisteredMaskQuery();
210
275
  if (!q) return [];