@symbiote-native/engine 0.1.7 → 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.
Files changed (87) hide show
  1. package/README.md +17 -10
  2. package/build/action-sheet-ios/index.js +4 -1
  3. package/build/alert/index.ios.js +10 -0
  4. package/build/animated/animations/composition.js +3 -1
  5. package/build/animated/animations/spring-config.js +4 -1
  6. package/build/animated/animations/spring.js +23 -9
  7. package/build/animated/animations/timing.js +3 -2
  8. package/build/animated/bezier.js +2 -1
  9. package/build/animated/color.d.ts +2 -8
  10. package/build/animated/color.js +8 -47
  11. package/build/animated/easing.js +0 -8
  12. package/build/animated/event.js +7 -3
  13. package/build/animated/graph.d.ts +13 -5
  14. package/build/animated/graph.js +92 -13
  15. package/build/animated/index.d.ts +3 -3
  16. package/build/animated/index.js +3 -3
  17. package/build/animated/interpolation.js +8 -3
  18. package/build/animated/leaf-lifecycle.d.ts +7 -0
  19. package/build/animated/leaf-lifecycle.js +185 -0
  20. package/build/animated/mock.js +1 -1
  21. package/build/animated/native/native-animated.js +2 -1
  22. package/build/animated/operators.js +27 -6
  23. package/build/animated/props.js +1 -1
  24. package/build/animated/rgba.d.ts +8 -0
  25. package/build/animated/rgba.js +70 -0
  26. package/build/animated/style.js +13 -3
  27. package/build/animated/value-xy.d.ts +8 -5
  28. package/build/animated/value-xy.js +4 -1
  29. package/build/animated/value.js +12 -7
  30. package/build/appearance/index.js +4 -1
  31. package/build/commit.d.ts +13 -0
  32. package/build/commit.js +146 -14
  33. package/build/debug.d.ts +1 -1
  34. package/build/debug.js +10 -3
  35. package/build/events/index.js +19 -10
  36. package/build/fabric-props.js +8 -2
  37. package/build/image-loader.js +3 -2
  38. package/build/index.d.ts +23 -19
  39. package/build/index.js +19 -11
  40. package/build/interaction-manager/index.js +2 -1
  41. package/build/layout-animation/index.js +12 -5
  42. package/build/native-events.js +2 -1
  43. package/build/native-modules/index.js +3 -1
  44. package/build/node.d.ts +25 -0
  45. package/build/node.js +168 -2
  46. package/build/pan-responder/index.js +20 -9
  47. package/build/permissions-android/index.js +3 -1
  48. package/build/platform/index.android.d.ts +1 -1
  49. package/build/platform/index.android.js +1 -1
  50. package/build/platform/index.ios.d.ts +1 -1
  51. package/build/platform-color/index.js +3 -1
  52. package/build/post-commit.d.ts +1 -0
  53. package/build/post-commit.js +6 -0
  54. package/build/process-background-image/index.js +30 -9
  55. package/build/process-filter.js +11 -4
  56. package/build/process-font-variant.js +0 -1
  57. package/build/process-transform/index.js +13 -19
  58. package/build/registry.js +10 -2
  59. package/build/report-error.d.ts +5 -0
  60. package/build/report-error.js +63 -0
  61. package/build/share/index.android.js +1 -1
  62. package/build/share/index.ios.js +1 -1
  63. package/build/status-bar/index.android.js +8 -10
  64. package/build/status-bar/index.ios.js +1 -1
  65. package/build/style-registry/index.d.ts +9 -2
  66. package/build/style-registry/index.js +149 -95
  67. package/build/style-registry/scope.d.ts +15 -1
  68. package/build/style-registry/scope.js +29 -27
  69. package/build/style-sheet/index.js +4 -2
  70. package/build/styles.d.ts +11 -1
  71. package/build/surface.d.ts +1 -1
  72. package/build/surface.js +7 -1
  73. package/build/tags.d.ts +1 -0
  74. package/build/tags.js +31 -1
  75. package/build/touch-history.js +9 -2
  76. package/build/vibration/index.android.js +2 -3
  77. package/build/vibration/index.ios.js +1 -1
  78. package/build/view-config.js +14 -2
  79. package/package.json +2 -2
  80. package/build/animated/interpolation-node.d.ts +0 -15
  81. package/build/animated/interpolation-node.js +0 -58
  82. package/build/style-registry/scope/index.d.ts +0 -3
  83. package/build/style-registry/scope/index.js +0 -41
  84. package/build/touch-history/index.d.ts +0 -23
  85. package/build/touch-history/index.js +0 -150
  86. package/build/type-guards/index.d.ts +0 -4
  87. package/build/type-guards/index.js +0 -15
package/build/commit.js CHANGED
@@ -13,20 +13,52 @@
13
13
  // references to specific child handles. That bubble is inherent to a persistent
14
14
  // tree and is exactly what React's own Fabric renderer does.
15
15
  import { getSlot, } from './fabric.js';
16
- import { createElement, debugNodeId, isAnchor, VIRTUAL_TEXT_COMPONENT, } from './node.js';
16
+ import { createElement, debugNodeId, isAnchor, isEmptyRawText, markDirty, takePropStats, VIRTUAL_TEXT_COMPONENT, } from './node.js';
17
17
  import { dlog, isDebug } from './debug.js';
18
18
  import { flattenStyle } from './style/index.js';
19
19
  import { nextTag } from './tags.js';
20
20
  import { registerPostCommit, runPostCommitHooks } from './post-commit.js';
21
21
  import { fabricProps } from './fabric-props.js';
22
22
  import { isRecord } from './type-guards.js';
23
- // processColor/setColorProcessor now live in ./platform-color (the stable color-processing
24
- // leaf every color-touching module imports from); re-exported here so nothing outside this
25
- // module needs to change its import path.
23
+ // Re-exported from ./platform-color so callers don't need to change their import path.
26
24
  export { processColor, setColorProcessor } from './platform-color/index.js';
27
25
  // Per-commit work counters, surfaced via dlog so a device run can prove the
28
26
  // engine is incremental (created=0 with clones after the first mount).
29
27
  const stats = { created: 0, cloneProps: 0, cloneChildren: 0, reused: 0 };
28
+ // Cumulative cost of the reconcile walk. Unlike `stats` (per-commit, zeroed at the top of every
29
+ // commit), this ACCUMULATES: one scroll frame produces a burst of commits and the frame's real cost
30
+ // is only visible as their sum. Read-and-zeroed via readCommitProfile().
31
+ //
32
+ // Deliberately NOT gated behind isDebug(): two performance.now() calls per commit are noise next to
33
+ // the walk they measure, and the number is only meaningful from a RELEASE build - dev-mode JS
34
+ // drowns the signal. The dlog below stays gated as usual.
35
+ const profile = { commits: 0, walkMs: 0, nodesVisited: 0 };
36
+ // What `renderableChildren` costs, accumulated over the same window as `profile`. Anchors are the
37
+ // only reason that function is not free, and how many a tree carries is a property of the ADAPTER,
38
+ // not of the app: a Vue/React/Svelte/Solid component is a function returning children and allocates
39
+ // no node, while an Angular component is bound to a host ELEMENT and therefore always has one
40
+ // (anchor-host-registry.ts keeps it from painting). So the same screen is a no-anchor tree under
41
+ // four adapters and an anchor-per-composed-component tree under the fifth, and only a counter tells
42
+ // them apart at runtime - a source-level grep for "anchor" measures instrumentation density, not
43
+ // trees.
44
+ //
45
+ // `scans` counts invocations; `probed` counts children actually examined by the fast-path probe,
46
+ // which is why that probe is a counted loop rather than `.some()` (a `.some` short-circuits at the
47
+ // first anchor, so children.length would overstate a defeated scan by however much it skipped).
48
+ // `flattens` is the probe defeated: a fresh array, a second pass, and a recursion into every
49
+ // anchor. `widest` is the widest single flatten in the window, because a defeated scan over 3
50
+ // children is noise and one over 1000 is not - a count alone cannot separate them.
51
+ //
52
+ // Not gated behind isDebug(), for the same reason the rest of the profile is not: integer
53
+ // increments are noise next to the array work they price, and the number is only meaningful from a
54
+ // release build.
55
+ const childScan = {
56
+ scans: 0,
57
+ probed: 0,
58
+ flattens: 0,
59
+ flattenProbed: 0,
60
+ widest: 0,
61
+ };
30
62
  // Diagnostic (gated): Fabric serializes props to folly::dynamic, which rejects a JS
31
63
  // Symbol or function with "JS Symbols are not convertible to dynamic". A hard native
32
64
  // throw deep in cloneNode*. Walk a props payload and return the dotted path of the
@@ -81,7 +113,9 @@ function guardSerializable(propsDiff, viewName, tag) {
81
113
  function viewNameFor(node, hasTextAncestor) {
82
114
  // The only position-dependent name: a <Text> inside another <Text> becomes a
83
115
  // virtual span. Everything else is the component string the adapter chose.
84
- return node.isText && hasTextAncestor ? VIRTUAL_TEXT_COMPONENT : node.component;
116
+ return node.isText && hasTextAncestor
117
+ ? VIRTUAL_TEXT_COMPONENT
118
+ : node.component;
85
119
  }
86
120
  // Fabric's clone*WithNewProps MERGES the raw payload onto the node's existing props,
87
121
  // so the payload must be a MINIMAL diff: only the keys that actually changed, plus any
@@ -131,18 +165,46 @@ function jsonEqual(a, b) {
131
165
  return keys.every(key => key in b && jsonEqual(a[key], b[key]));
132
166
  }
133
167
  const mirror = new WeakMap();
168
+ function isSkippedAtCommit(node) {
169
+ return isAnchor(node) || isEmptyRawText(node);
170
+ }
134
171
  function renderableChildren(node) {
135
172
  // Anchor nodes (Vue fragment/v-if/v-for placeholders, Angular component hosts that should
136
173
  // not paint) live in the retained tree for sibling ordering but never become Fabric views.
137
174
  // When an anchor owns children, flatten them into the parent's renderable list: this lets a
138
175
  // DOM-less framework use an anchor as a fragment/component host without adding a native
139
176
  // wrapper node. Fast path: no anchors reuses the array, so the common case allocates nothing.
140
- if (!node.children.some(isAnchor))
177
+ // An empty raw text is skipped for a different reason and with no flattening: it has no
178
+ // children, and committing it aborts the app inside Fabric's text walk (isEmptyRawText).
179
+ //
180
+ // The probe is a counted loop rather than `.some()` only so childScan can price it honestly;
181
+ // see the childScan declaration for what the five counters mean and what they were built to
182
+ // settle.
183
+ childScan.scans += 1;
184
+ const total = node.children.length;
185
+ let index = 0;
186
+ while (index < total && !isSkippedAtCommit(node.children[index]))
187
+ index += 1;
188
+ // The defeating child was examined too, so it counts.
189
+ childScan.probed += index === total ? total : index + 1;
190
+ if (index === total)
141
191
  return node.children;
192
+ childScan.flattens += 1;
193
+ childScan.flattenProbed += total;
194
+ if (total > childScan.widest)
195
+ childScan.widest = total;
142
196
  const children = [];
143
197
  for (const child of node.children) {
144
- if (isAnchor(child))
145
- children.push(...renderableChildren(child));
198
+ if (isSkippedAtCommit(child)) {
199
+ // A skipped child is flattened away here and never reaches reconcile, so this is the only
200
+ // place that can clear its dirty flag. Leaving it set would be a silent stale-UI bug:
201
+ // markDirty stops at the first dirty ancestor, so a permanently-dirty skipped node swallows
202
+ // every later mark - from an anchor's subtree, or from the setText that turns an empty raw
203
+ // text back into real content - and the real parent never learns anything changed.
204
+ child.dirty = false;
205
+ if (isAnchor(child))
206
+ children.push(...renderableChildren(child));
207
+ }
146
208
  else
147
209
  children.push(child);
148
210
  }
@@ -168,13 +230,41 @@ function logScrollChildren(node, viewName, selfTag) {
168
230
  const flag = kids.length === 1 ? 'OK' : 'MULTI!!';
169
231
  dlog(`SCROLL-${flag} ${viewName} tag=${selfTag} children(${kids.length})=[${kids.join(',')}]`);
170
232
  }
233
+ // The failure mode dirty-marking introduces: a mutation path that forgets to markDirty leaves a
234
+ // node whose desired props have drifted from what Fabric holds, and the screen silently keeps
235
+ // showing the old value - no error, no crash, nothing to grep for. So under DEBUG pay back the full
236
+ // price just saved and verify the skip was honest, naming the node loudly enough to find the
237
+ // missing mark.
238
+ function warnIfStale(node, committed) {
239
+ if (!isDebug())
240
+ return;
241
+ const fresh = fabricProps(node);
242
+ if (propsEqual(committed.props, fresh))
243
+ return;
244
+ dlog(`DIRTY-MISS ${committed.viewName}#${committed.tag} node=${debugNodeId(node)} skipped as clean ` +
245
+ `but props differ: committed=${JSON.stringify(committed.props)} desired=${JSON.stringify(fresh)}`);
246
+ }
171
247
  function reconcile(slot, node, rootTag, hasTextAncestor, renderableParent, forceFreshFamily) {
248
+ profile.nodesVisited += 1;
172
249
  const viewName = viewNameFor(node, hasTextAncestor);
250
+ const committed = mirror.get(node);
251
+ // Nothing under here changed: hand back the committed handle without rebuilding this node's
252
+ // Fabric props or descending into it at all. The walk below costs ~13 us/node on device, and an
253
+ // untouched sibling subtree would pay it on every commit. `committed.parent` is re-checked rather
254
+ // than trusted to the flag because a MOVED node can still be legitimately clean (see node.ts's
255
+ // structural ops), and a reparent must fall through to the fresh-family path below.
256
+ if (!forceFreshFamily &&
257
+ !node.dirty &&
258
+ committed !== undefined &&
259
+ committed.parent === renderableParent &&
260
+ committed.viewName === viewName) {
261
+ stats.reused += 1;
262
+ warnIfStale(node, committed);
263
+ return { handle: committed.handle, changed: false };
264
+ }
265
+ node.dirty = false;
173
266
  const props = fabricProps(node);
174
267
  const childInText = node.isText || hasTextAncestor;
175
- const committed = mirror.get(node);
176
- // The children that actually reach Fabric. Anchors are filtered out here so the
177
- // whole walk (child-set emission, identity diff, mirror) is anchor-blind.
178
268
  const kids = renderableChildren(node);
179
269
  // First mount, or the view kind flipped (RCTText <-> RCTVirtualText when a
180
270
  // <Text> moves in or out of another <Text>): a different native component
@@ -199,7 +289,8 @@ function reconcile(slot, node, rootTag, hasTextAncestor, renderableParent, force
199
289
  `bg=${JSON.stringify(props.backgroundColor)} color=${JSON.stringify(props.color)} ` +
200
290
  `opacity=${JSON.stringify(props.opacity)}`);
201
291
  }
202
- if (viewName === 'AndroidSwipeRefreshLayout' || viewName === 'RCTScrollView') {
292
+ if (viewName === 'AndroidSwipeRefreshLayout' ||
293
+ viewName === 'RCTScrollView') {
203
294
  dlog(`commit root=${rootTag} layoutProbe tag=${tag} view=${viewName} ` +
204
295
  `flex=${JSON.stringify(props.flex)} height=${JSON.stringify(props.height)} ` +
205
296
  `width=${JSON.stringify(props.width)} minHeight=${JSON.stringify(props.minHeight)} ` +
@@ -333,6 +424,13 @@ export function commitChildren(rootTag, children) {
333
424
  function commitContainer(rootTag) {
334
425
  const slot = getSlot();
335
426
  const container = rootContainerFor(rootTag);
427
+ // The synthetic container is dirtied here, at the one entry point, because markDirty can never
428
+ // bubble up to it: a surface's top-level nodes carry `parent === undefined` (surface.ts sets it
429
+ // deliberately), so a mark stops at the top-level node and the container above it stays clean -
430
+ // it would then early-exit and swallow the whole commit. Marking unconditionally costs one node's
431
+ // props rebuild per commit and closes the hole for both callers, mutation commit and
432
+ // setNativeProps alike.
433
+ markDirty(container);
336
434
  stats.created = 0;
337
435
  stats.cloneProps = 0;
338
436
  stats.cloneChildren = 0;
@@ -342,7 +440,11 @@ function commitContainer(rootTag) {
342
440
  // tree walk); if `start` itself never prints, the stall is upstream: React's commit
343
441
  // phase or the mutation ops before we are even called.
344
442
  dlog(`commit root=${rootTag} start children=${container.children.length}`);
443
+ const walkStart = performance.now();
345
444
  const result = reconcile(slot, container, rootTag, false, undefined, false);
445
+ const walkMs = performance.now() - walkStart;
446
+ profile.walkMs += walkMs;
447
+ profile.commits += 1;
346
448
  // Boundary seam: prints once reconcile returns. If a commit hangs and this line
347
449
  // never appears, the stall is inside reconcile (JS); if it appears but the
348
450
  // post-completeRoot line below never does, the stall is inside the native commit.
@@ -365,9 +467,34 @@ function commitContainer(rootTag) {
365
467
  const mode = stats.created > 0 && stats.reused === 0 ? 'full' : 'incremental';
366
468
  dlog(`commit root=${rootTag} ${mode} ` +
367
469
  `created=${stats.created} cloneProps=${stats.cloneProps} ` +
368
- `cloneChildren=${stats.cloneChildren} reused=${stats.reused}`);
470
+ `cloneChildren=${stats.cloneChildren} reused=${stats.reused} ` +
471
+ `walk=${walkMs.toFixed(3)}ms`);
369
472
  }
370
473
  }
474
+ export function readCommitProfile() {
475
+ const props = takePropStats();
476
+ const snapshot = {
477
+ commits: profile.commits,
478
+ walkMs: profile.walkMs,
479
+ nodesVisited: profile.nodesVisited,
480
+ propWrites: props.writes,
481
+ propNoops: props.noops,
482
+ childScans: childScan.scans,
483
+ childScanProbed: childScan.probed,
484
+ childFlattens: childScan.flattens,
485
+ childFlattenProbed: childScan.flattenProbed,
486
+ childFlattenWidest: childScan.widest,
487
+ };
488
+ profile.commits = 0;
489
+ profile.walkMs = 0;
490
+ profile.nodesVisited = 0;
491
+ childScan.scans = 0;
492
+ childScan.probed = 0;
493
+ childScan.flattens = 0;
494
+ childScan.flattenProbed = 0;
495
+ childScan.widest = 0;
496
+ return snapshot;
497
+ }
371
498
  // Targeted per-frame prop write for the JS-driven Animated path. RN flushes an
372
499
  // animation frame with an in-place `instance.setNativeProps(...)`; we have no
373
500
  // in-place mutation (Fabric is persistent), so a frame is one scoped commit: mutate
@@ -386,12 +513,17 @@ export function setNativeProps(node, partial) {
386
513
  // A partial style override MERGES onto the declarative style (RN semantics):
387
514
  // setNativeProps({style:{backgroundColor}}) recolors without dropping height
388
515
  // or radius. Transient: the next React commit re-applies the full style.
389
- node.props.style = { ...flattenStyle(node.props.style), ...flattenStyle(value) };
516
+ node.props.style = {
517
+ ...flattenStyle(node.props.style),
518
+ ...flattenStyle(value),
519
+ };
390
520
  }
391
521
  else {
392
522
  node.props[key] = value;
393
523
  }
394
524
  }
525
+ // Writes node.props directly rather than through setProp, so it owes its own mark.
526
+ markDirty(node);
395
527
  dlog(`setNativeProps root=${record.rootTag} tag=${record.tag} keys=${Object.keys(partial)}`);
396
528
  commitContainer(record.rootTag);
397
529
  }
package/build/debug.d.ts CHANGED
@@ -2,4 +2,4 @@ declare global {
2
2
  var __SYMBIOTE_DEBUG__: boolean | undefined;
3
3
  }
4
4
  export declare function isDebug(): boolean;
5
- export declare function dlog(message: string): void;
5
+ export declare function dlog(message: string | (() => string)): void;
package/build/debug.js CHANGED
@@ -5,7 +5,13 @@
5
5
  // Metro start (--reset-cache), not a rebuild.
6
6
  // - runtime: globalThis.__SYMBIOTE_DEBUG__ = true, an escape hatch for hosts
7
7
  // where the env isn't reachable.
8
- // Production with neither set pays one property read per call and nothing else.
8
+ // Production with neither set pays one property read per call and nothing else -
9
+ // but ONLY if the caller does not build the message itself first. A template
10
+ // literal is evaluated at the CALL SITE, before dlog can decide anything, so a
11
+ // `dlog(\`… ${JSON.stringify(x)}\`)` on a per-frame path costs its full price with
12
+ // logging off. On a hot path (a getter Angular re-reads every change-detection
13
+ // pass, an Animated reconcile, a scroll-driven apply) pass a THUNK instead:
14
+ // `dlog(() => \`…\`)` - it is only called once the switch is on.
9
15
  function envEnabled() {
10
16
  return typeof process !== 'undefined' && process.env.DEBUG === '1';
11
17
  }
@@ -13,6 +19,7 @@ export function isDebug() {
13
19
  return globalThis.__SYMBIOTE_DEBUG__ === true || envEnabled();
14
20
  }
15
21
  export function dlog(message) {
16
- if (isDebug())
17
- console.log(`[symbiote] ${message}`);
22
+ if (!isDebug())
23
+ return;
24
+ console.log(`[symbiote] ${typeof message === 'function' ? message() : message}`);
18
25
  }
@@ -8,7 +8,7 @@
8
8
  import { dlog } from '../debug.js';
9
9
  import { runWrapped } from '../dispatch.js';
10
10
  import { getSlot } from '../fabric.js';
11
- import { isAnchor, isSymbioteNode } from '../node.js';
11
+ import { isAnchor, isSymbioteNode, } from '../node.js';
12
12
  import { registeredNativeEvent } from '../registry.js';
13
13
  import { attachTouchHistory, recordTouchTrack, resetTouchHistory, touchHistory, } from '../touch-history.js';
14
14
  import { isRecord } from '../type-guards.js';
@@ -228,12 +228,14 @@ function lowestCommonAncestor(a, b) {
228
228
  // handler, so asking the responder again would zero its move).
229
229
  function findWantsResponder(path, captureName, bubbleName, nativeEvent, skip) {
230
230
  for (let i = path.length - 1; i >= 0; i--) {
231
- if (path[i] !== skip && callOwnListener(path[i], captureName, nativeEvent) === true) {
231
+ if (path[i] !== skip &&
232
+ callOwnListener(path[i], captureName, nativeEvent) === true) {
232
233
  return path[i];
233
234
  }
234
235
  }
235
236
  for (const node of path) {
236
- if (node !== skip && callOwnListener(node, bubbleName, nativeEvent) === true)
237
+ if (node !== skip &&
238
+ callOwnListener(node, bubbleName, nativeEvent) === true)
237
239
  return node;
238
240
  }
239
241
  return undefined;
@@ -248,7 +250,9 @@ function negotiateResponder(target, phase, nativeEvent) {
248
250
  // the responder) and skips the deepest node when it IS the responder (Responder-
249
251
  // EventPlugin.setResponderAndExtractTransfer). At touch start currentResponder is
250
252
  // cleared, so this collapses to the plain target->root start walk.
251
- const from = currentResponder === undefined ? target : lowestCommonAncestor(currentResponder, target);
253
+ const from = currentResponder === undefined
254
+ ? target
255
+ : lowestCommonAncestor(currentResponder, target);
252
256
  if (!from)
253
257
  return;
254
258
  const path = pathToRoot(from);
@@ -268,7 +272,9 @@ function negotiateResponder(target, phase, nativeEvent) {
268
272
  // A missing termination-request listener means implicit consent (RN default true);
269
273
  // only an explicit non-true answer keeps the incumbent and rejects the taker.
270
274
  const guarded = incumbent.listeners?.has(RESPONDER_TERMINATION_REQUEST) === true;
271
- const allowed = !guarded || callOwnListener(incumbent, RESPONDER_TERMINATION_REQUEST, nativeEvent) === true;
275
+ const allowed = !guarded ||
276
+ callOwnListener(incumbent, RESPONDER_TERMINATION_REQUEST, nativeEvent) ===
277
+ true;
272
278
  if (allowed) {
273
279
  // RN's transfer order (setResponderAndExtractTransfer): grant the TAKER first, then
274
280
  // terminate the incumbent. RN dispatches grant ahead of the terminationRequest too,
@@ -362,7 +368,8 @@ export function installEventHandler() {
362
368
  // started inside it; lifting ONE finger in a multi-touch gesture must NOT release.
363
369
  // onResponderEnd still fires on every finger-up. (ResponderEventPlugin: responderEnd
364
370
  // is unconditional, responderRelease is gated on noResponderTouches.)
365
- const releases = responder !== undefined && !hasRemainingResponderTouch(responder, nativeEvent);
371
+ const releases = responder !== undefined &&
372
+ !hasRemainingResponderTouch(responder, nativeEvent);
366
373
  if (releases)
367
374
  currentResponder = undefined;
368
375
  // A completed long press eats the tap (RN), but pressOut still fires below.
@@ -495,7 +502,9 @@ function bubble(target, listenerName, nativeEvent) {
495
502
  // machinery (already delivered directly, e.g. Angular's EventEmitter.subscribe) also
496
503
  // registered it through Renderer2.listen. Bubbling into it would refire that same
497
504
  // callback a second time, so anchors are transparent to listener lookup, not just paint.
498
- const listener = isAnchor(node) ? undefined : node.listeners?.get(captureName);
505
+ const listener = isAnchor(node)
506
+ ? undefined
507
+ : node.listeners?.get(captureName);
499
508
  if (listener) {
500
509
  dlog(`event ${listenerName} capture on ${node.component}`);
501
510
  listener({
@@ -513,9 +522,10 @@ function bubble(target, listenerName, nativeEvent) {
513
522
  // transparent here too, same reason (see the capture-phase comment above).
514
523
  let node = target;
515
524
  while (node) {
516
- const listener = isAnchor(node) ? undefined : node.listeners?.get(listenerName);
525
+ const listener = isAnchor(node)
526
+ ? undefined
527
+ : node.listeners?.get(listenerName);
517
528
  if (listener) {
518
- // engine owner adds currentTarget + stopPropagation to SymbioteEvent
519
529
  const event = {
520
530
  type: listenerName,
521
531
  target,
@@ -535,7 +545,6 @@ function deliverDirect(target, listenerName, nativeEvent) {
535
545
  const listener = target.listeners?.get(listenerName);
536
546
  if (!listener)
537
547
  return;
538
- // engine owner adds currentTarget + stopPropagation to SymbioteEvent
539
548
  listener({
540
549
  type: listenerName,
541
550
  target,
@@ -70,11 +70,17 @@ const COLOR_PROPS = new Set([
70
70
  const STYLE_PROCESSORS = new Map([
71
71
  ['boxShadow', value => processBoxShadow(asBoxShadowInput(value))],
72
72
  ['filter', value => processFilter(asFilterInput(value))],
73
- ['transformOrigin', value => processTransformOrigin(asTransformOriginInput(value))],
73
+ [
74
+ 'transformOrigin',
75
+ value => processTransformOrigin(asTransformOriginInput(value)),
76
+ ],
74
77
  ['transform', processTransformValue],
75
78
  ['aspectRatio', value => processAspectRatio(asAspectRatioInput(value))],
76
79
  ['fontVariant', value => processFontVariant(asFontVariantInput(value))],
77
- ['experimental_backgroundImage', value => processBackgroundImage(asBackgroundImageInput(value))],
80
+ [
81
+ 'experimental_backgroundImage',
82
+ value => processBackgroundImage(asBackgroundImageInput(value)),
83
+ ],
78
84
  ]);
79
85
  // boxShadow accepts a CSS string or an array of shadow objects; anything else is
80
86
  // undefined to processBoxShadow (which returns []). Narrowing avoids an `as` cast.
@@ -14,7 +14,7 @@
14
14
  // alongside Alert/Share, not in a view/render-*.ts file (whose contract is zero state / zero
15
15
  // native bridge).
16
16
  import { dlog } from './debug.js';
17
- import { resolveImageSource } from './image-source-resolver.js';
17
+ import { resolveImageSource, } from './image-source-resolver.js';
18
18
  import { getNativeModule } from './native-modules/index.js';
19
19
  import { Platform } from './platform';
20
20
  import { isNumber } from './type-guards.js';
@@ -26,7 +26,8 @@ const IMAGE_LOADER_MODULE = 'ImageLoader';
26
26
  let imageLoaderModule;
27
27
  function getImageLoader() {
28
28
  if (imageLoaderModule === undefined) {
29
- imageLoaderModule = getNativeModule(IMAGE_LOADER_MODULE);
29
+ imageLoaderModule =
30
+ getNativeModule(IMAGE_LOADER_MODULE);
30
31
  dlog(`Image: ImageLoader module ${imageLoaderModule ? 'resolved' : 'NOT resolved (null)'}`);
31
32
  }
32
33
  return imageLoaderModule;
package/build/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { createElement, createRawText, createAnchor, isAnchor, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, getExplicitStyle, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, } from './node';
1
+ export { createElement, createRawText, createAnchor, isAnchor, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, censusRetainedTree, getExplicitStyle, setNodeHidden, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, } from './node';
2
2
  export { isEventFor } from './view-config';
3
3
  export { registerComponent, setNativeViewConfigSource } from './registry';
4
4
  export { isRecord } from './type-guards';
5
- export { InteractionManager, Events as InteractionManagerEvents } from './interaction-manager';
5
+ export { InteractionManager, Events as InteractionManagerEvents, } from './interaction-manager';
6
6
  export type { IInteractionEvent, ISimpleTask, IPromiseTask, ITask, IHandle, ICancellable, } from './interaction-manager';
7
7
  export { default as PanResponder } from './pan-responder';
8
8
  export type { IPanResponderGestureState, IPanResponderCallbacks, IGestureResponderHandlers, IPanResponderInstance, } from './pan-responder';
@@ -10,11 +10,13 @@ export type { IComponentRegistration, INativeEventBinding, INativeViewConfig, IN
10
10
  export type { ISymbioteNode, ISymbioteEvent, IListener } from './node';
11
11
  export { SymbioteSurface, createSurface } from './surface';
12
12
  export { setEventDispatcher } from './dispatch';
13
- export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, } from './commit';
13
+ export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, readCommitProfile, } from './commit';
14
+ export type { ICommitProfile } from './commit';
15
+ export { registerPostCommit, unregisterPostCommit } from './post-commit';
14
16
  export { toPublicInstance } from './host-instance';
15
17
  export type { IHostInstance } from './host-instance';
16
- export { PlatformColor, DynamicColorIOS, isOpaqueColorValue } from './platform-color';
17
- export type { IColorValue, IOpaqueColorValue, IDynamicColorIOSTuple } from './platform-color';
18
+ export { PlatformColor, DynamicColorIOS, isOpaqueColorValue, } from './platform-color';
19
+ export type { IColorValue, IOpaqueColorValue, IDynamicColorIOSTuple, } from './platform-color';
18
20
  export { processBoxShadow } from './process-box-shadow';
19
21
  export type { IParsedBoxShadow } from './process-box-shadow';
20
22
  export { processFilter } from './process-filter';
@@ -28,20 +30,22 @@ export type { IParsedBackgroundImage } from './process-background-image';
28
30
  export { flattenStyle } from './style';
29
31
  export type { IViewStyle, ITextStyle, IStyleProp, IDimensionValue, IFlexAlign, IFlexJustify, ITransformProp, IBoxShadowValue, IDropShadowValue, IFilterFunction, IColorStopValue, ILinearGradientValue, IRadialGradientValue, IRadialGradientPosition, IRadialGradientShape, IRadialGradientSize, IBackgroundImageValue, IBlendMode, } from './styles';
30
32
  export { StyleSheet, computeHairlineWidth } from './style-sheet';
31
- export { registerStyles, resolveClassName, clearGlobalStyles, isClassNameValue, } from './style-registry';
32
- export type { IClassNameValue } from './style-registry';
33
- export { scopeClassName } from './style-registry/scope';
34
- export type { IClassToggleMap, IScopableClassValue } from './style-registry/scope';
33
+ export { registerRules, resolveClassName, clearGlobalStyles, isClassNameValue, } from './style-registry';
34
+ export type { IClassNameValue, IStyleRule } from './style-registry';
35
+ export { renameClassTokens } from './style-registry/scope';
36
+ export type { IClassNameRenames, IClassToggleMap, IScopableClassValue, } from './style-registry/scope';
35
37
  export { Platform } from './platform';
36
- export type { IPlatformStatic, IPlatformOSType, IPlatformSelectSpec } from './platform';
38
+ export type { IPlatformStatic, IPlatformOSType, IPlatformSelectSpec, } from './platform';
37
39
  export type { IPlatformConstantsIOS } from './platform/index.ios';
38
40
  export type { IPlatformConstantsAndroid } from './platform/index.android';
39
41
  export { dlog, isDebug } from './debug';
42
+ export { reportUncaughtError } from './report-error';
43
+ export type { IUncaughtErrorInfo } from './report-error';
40
44
  export { getNativeModule, getEnforcingNativeModule } from './native-modules';
41
- export { installDeviceEventHub, NativeEventEmitter, setDeviceEventSource } from './native-events';
45
+ export { installDeviceEventHub, NativeEventEmitter, setDeviceEventSource, } from './native-events';
42
46
  export type { IEventSubscription, IEventEmitterModule, INativeEventListener, IDeviceEventSource, } from './native-events';
43
- export { AnimatedNode, AnimatedWithChildren, AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedInterpolation, AnimatedAddition, AnimatedSubtraction, AnimatedMultiplication, AnimatedDivision, AnimatedModulo, AnimatedDiffClamp, AnimatedEvent, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, attachNativeEvent, attachNativeEventHandler, flushValue, Easing, createNumericInterpolation, checkValidRanges, TimingAnimation, SpringAnimation, DecayAnimation, AnimatedTracking, timing, spring, decay, parallel, sequence, stagger, loop, delay, nativeAnimated, isNativeAnimatedAvailable, AnimatedProps, AnimatedStyle, AnimatedTransform, AnimatedMock, reduceProps, isAnimatedNode, readPassthroughStyle, resolveHostNode, } from './animated';
44
- export type { IValueXY, IRgbaValue, IColorInput, IEventConfig, IEventListener, IAnimatedEventHandler, INativeEventAttachment, IValueListener, IEasingFunction, IInterpolationConfig, IExtrapolateType, IAnimation, IEndCallback, IEndResult, ICompositeAnimation, ITimingConfig, ISpringConfig, IDecayConfig, IParallelConfig, ILoopAnimationConfig, INativeNodeConfig, INativeAnimationConfig, INativeEventMapping, IPlatformConfig, } from './animated';
47
+ export { AnimatedNode, AnimatedWithChildren, AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedInterpolation, AnimatedAddition, AnimatedSubtraction, AnimatedMultiplication, AnimatedDivision, AnimatedModulo, AnimatedDiffClamp, AnimatedEvent, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, attachNativeEvent, attachNativeEventHandler, flushValue, Easing, createNumericInterpolation, checkValidRanges, TimingAnimation, SpringAnimation, DecayAnimation, AnimatedTracking, timing, spring, decay, parallel, sequence, stagger, loop, delay, nativeAnimated, isNativeAnimatedAvailable, AnimatedProps, createAnimatedLeafLifecycle, AnimatedStyle, AnimatedTransform, AnimatedMock, reduceProps, isAnimatedNode, readPassthroughStyle, resolveHostNode, } from './animated';
48
+ export type { IAnimatedLeafLifecycle, IValueXY, IRgbaValue, IColorInput, IEventConfig, IEventListener, IAnimatedEventHandler, INativeEventAttachment, IValueListener, IEasingFunction, IInterpolationConfig, IExtrapolateType, IAnimation, IEndCallback, IEndResult, ICompositeAnimation, ITimingConfig, ISpringConfig, IDecayConfig, IParallelConfig, ILoopAnimationConfig, INativeNodeConfig, INativeAnimationConfig, INativeEventMapping, IPlatformConfig, } from './animated';
45
49
  export { getSlot } from './fabric';
46
50
  export type { IFabricSlot, IFabricNode, IFabricChildSet, IFabricProps, IFabricEventHandler, IRootTag, IMeasureOnSuccess, IMeasureInWindowOnSuccess, IMeasureLayoutOnSuccess, } from './fabric';
47
51
  export { Alert } from './alert';
@@ -49,8 +53,8 @@ export type { IAlertType, IAlertButtonStyle, IAlertButton, IAlertButtons, IAlert
49
53
  export { Share } from './share';
50
54
  export type { IShareContent, IShareOptions, IShareAction } from './share';
51
55
  export { imageStatics } from './image-loader';
52
- export type { IImageStatics, IImageSize, IImageCacheStatus } from './image-loader';
53
- export { setImageSourceResolver, resolveImageSource } from './image-source-resolver';
56
+ export type { IImageStatics, IImageSize, IImageCacheStatus, } from './image-loader';
57
+ export { setImageSourceResolver, resolveImageSource, } from './image-source-resolver';
54
58
  export type { IImageSource, IImageSourceProp } from './image-source-resolver';
55
59
  export { ActionSheetIOS } from './action-sheet-ios';
56
60
  export type { IActionSheetIOSOptions, IShareActionSheetIOSOptions, IShareActionSheetError, } from './action-sheet-ios';
@@ -72,16 +76,16 @@ export type { IAppStateStatus, IAppStateEvent } from './app-state';
72
76
  export { createAppRegistry } from './app-registry';
73
77
  export type { IAppRegistry, ICreateAppRegistryResult, IAppParameters, IRunnable, IHostRegistrar, IRegistry, IHeadlessTask, ITaskProvider, ITaskCanceller, ITaskCancelProvider, } from './app-registry';
74
78
  export { Keyboard, KEYBOARD_EVENT } from './keyboard';
75
- export type { IKeyboardEventName, IKeyboardEvent, IKeyboardMetrics } from './keyboard';
79
+ export type { IKeyboardEventName, IKeyboardEvent, IKeyboardMetrics, } from './keyboard';
76
80
  export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, } from './text-input-state';
77
81
  export { LayoutAnimation } from './layout-animation';
78
82
  export type { ILayoutAnimationType, ILayoutAnimationProperty, ILayoutAnimationConfig, ILayoutAnimationAnim, ILayoutAnimationTypes, ILayoutAnimationProperties, } from './layout-animation';
79
83
  export { BackHandler } from './back-handler';
80
84
  export type { IBackPressEventName, IBackPressHandler } from './back-handler';
81
- export { PermissionsAndroid, PERMISSIONS, RESULTS } from './permissions-android';
82
- export type { IPermission, IPermissionStatus, IRationale } from './permissions-android';
85
+ export { PermissionsAndroid, PERMISSIONS, RESULTS, } from './permissions-android';
86
+ export type { IPermission, IPermissionStatus, IRationale, } from './permissions-android';
83
87
  export { AccessibilityInfo } from './accessibility-info';
84
88
  export type { IAccessibilityChangeEvent, IAccessibilityChangeEventName, IAccessibilityChangeEventHandler, IAccessibilityAnnouncementFinishedEvent, IAnnounceForAccessibilityOptions, IAccessibilityInfoStatic, IAccessibilityEventType, IAccessibilityHandle, } from './accessibility-info/shared';
85
- export { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight } from './status-bar';
89
+ export { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight, } from './status-bar';
86
90
  export { hideTransition, STATUS_BAR_MANAGER, ANIMATED_HIDE_TRANSITION, STATIC_HIDE_TRANSITION, } from './status-bar/shared';
87
91
  export type { IStatusBarProps, IStatusBarStyle, IStatusBarAnimation, IStatusBarImperative, } from './status-bar/shared';
package/build/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Every framework adapter drives this tiny mutation API; all Fabric-specific
3
3
  // logic (tag allocation, view-name resolution, clone-on-write, event
4
4
  // normalization) lives behind it, in one place.
5
- export { createElement, createRawText, createAnchor, isAnchor, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, getExplicitStyle, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, } from './node.js';
5
+ export { createElement, createRawText, createAnchor, isAnchor, appendChild, insertBefore, removeChild, setProp, setEventListener, routeProp, censusRetainedTree, getExplicitStyle, setNodeHidden, setText, isSymbioteNode, isSymbioteEvent, RAW_TEXT_COMPONENT, debugNodeId, } from './node.js';
6
6
  export { isEventFor } from './view-config.js';
7
7
  export { registerComponent, setNativeViewConfigSource } from './registry.js';
8
8
  // Real cross-package consumer: core/components' KeyboardAvoidingView render narrows
@@ -10,18 +10,25 @@ export { registerComponent, setNativeViewConfigSource } from './registry.js';
10
10
  export { isRecord } from './type-guards.js';
11
11
  // InteractionManager: pure JS (timers + emitter), framework-agnostic, so it lives
12
12
  // here; every adapter re-exports it.
13
- export { InteractionManager, Events as InteractionManagerEvents } from './interaction-manager/index.js';
13
+ export { InteractionManager, Events as InteractionManagerEvents, } from './interaction-manager/index.js';
14
14
  // PanResponder: pure JS gesture recognition over the View responder props,
15
15
  // framework-agnostic, so it lives here; every adapter re-exports it.
16
16
  export { default as PanResponder } from './pan-responder/index.js';
17
17
  export { SymbioteSurface, createSurface } from './surface.js';
18
18
  export { setEventDispatcher } from './dispatch.js';
19
- export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, } from './commit.js';
19
+ export { setColorProcessor, processColor, dispatchViewCommand, sendAccessibilityEvent, setNativeProps, getNativeTag, getNativeNode, whenCommitted, measure, measureInWindow, measureLayout, disposeRoot, readCommitProfile, } from './commit.js';
20
+ // "A commit just reached completeRoot." The one seam that means the same thing under every
21
+ // adapter: React commits synchronously inside its own commit phase, while Vue / Svelte / Angular
22
+ // schedule completeRoot on a microtask, so each framework's own after-render hook fires at a
23
+ // DIFFERENT point relative to the native commit. Anything timing or comparing the commit path
24
+ // across adapters has to hang off this, not off a per-framework lifecycle hook, or it measures a
25
+ // different quantity in each one under the same name.
26
+ export { registerPostCommit, unregisterPostCommit } from './post-commit.js';
20
27
  // The public instance grafted onto a host node by every adapter (React's getPublicInstance,
21
28
  // the Vue renderer's createElement): the imperative measure/setNativeProps/focus API. Lives
22
29
  // here because it depends only on engine internals, so all adapters inherit it identically.
23
30
  export { toPublicInstance } from './host-instance/index.js';
24
- export { PlatformColor, DynamicColorIOS, isOpaqueColorValue } from './platform-color/index.js';
31
+ export { PlatformColor, DynamicColorIOS, isOpaqueColorValue, } from './platform-color/index.js';
25
32
  // CSS-style processors (boxShadow/filter): RN parses these in JS before native because
26
33
  // enableNativeCSSParsing() defaults to false. Exported so an adapter / test can reuse them.
27
34
  export { processBoxShadow } from './process-box-shadow/index.js';
@@ -33,13 +40,14 @@ export { processFontVariant } from './process-font-variant.js';
33
40
  export { processBackgroundImage } from './process-background-image/index.js';
34
41
  export { flattenStyle } from './style/index.js';
35
42
  export { StyleSheet, computeHairlineWidth } from './style-sheet/index.js';
36
- export { registerStyles, resolveClassName, clearGlobalStyles, isClassNameValue, } from './style-registry/index.js';
37
- export { scopeClassName } from './style-registry/scope.js';
43
+ export { registerRules, resolveClassName, clearGlobalStyles, isClassNameValue, } from './style-registry/index.js';
44
+ export { renameClassTokens } from './style-registry/scope.js';
38
45
  export { Platform } from './platform';
39
46
  export { dlog, isDebug } from './debug.js';
47
+ export { reportUncaughtError } from './report-error.js';
40
48
  export { getNativeModule, getEnforcingNativeModule } from './native-modules/index.js';
41
- export { installDeviceEventHub, NativeEventEmitter, setDeviceEventSource } from './native-events.js';
42
- export { AnimatedNode, AnimatedWithChildren, AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedInterpolation, AnimatedAddition, AnimatedSubtraction, AnimatedMultiplication, AnimatedDivision, AnimatedModulo, AnimatedDiffClamp, AnimatedEvent, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, attachNativeEvent, attachNativeEventHandler, flushValue, Easing, createNumericInterpolation, checkValidRanges, TimingAnimation, SpringAnimation, DecayAnimation, AnimatedTracking, timing, spring, decay, parallel, sequence, stagger, loop, delay, nativeAnimated, isNativeAnimatedAvailable, AnimatedProps, AnimatedStyle, AnimatedTransform, AnimatedMock, reduceProps, isAnimatedNode, readPassthroughStyle, resolveHostNode, } from './animated/index.js';
49
+ export { installDeviceEventHub, NativeEventEmitter, setDeviceEventSource, } from './native-events.js';
50
+ export { AnimatedNode, AnimatedWithChildren, AnimatedValue, AnimatedValueXY, AnimatedColor, AnimatedInterpolation, AnimatedAddition, AnimatedSubtraction, AnimatedMultiplication, AnimatedDivision, AnimatedModulo, AnimatedDiffClamp, AnimatedEvent, add, subtract, multiply, divide, modulo, diffClamp, event, forkEvent, unforkEvent, attachNativeEvent, attachNativeEventHandler, flushValue, Easing, createNumericInterpolation, checkValidRanges, TimingAnimation, SpringAnimation, DecayAnimation, AnimatedTracking, timing, spring, decay, parallel, sequence, stagger, loop, delay, nativeAnimated, isNativeAnimatedAvailable, AnimatedProps, createAnimatedLeafLifecycle, AnimatedStyle, AnimatedTransform, AnimatedMock, reduceProps, isAnimatedNode, readPassthroughStyle, resolveHostNode, } from './animated/index.js';
43
51
  export { getSlot } from './fabric.js';
44
52
  // Imperative runtime modules: framework-agnostic native-bridge consumers (no visual, no
45
53
  // lifecycle), moved here from @symbiote-native/react so every adapter re-exports the SAME module.
@@ -51,7 +59,7 @@ export { Share } from './share';
51
59
  // no view of its own, same shape as Alert/Share. The source-resolution seam it shares with
52
60
  // @symbiote-native/components' renderImage lives alongside it in image-source-resolver.
53
61
  export { imageStatics } from './image-loader.js';
54
- export { setImageSourceResolver, resolveImageSource } from './image-source-resolver.js';
62
+ export { setImageSourceResolver, resolveImageSource, } from './image-source-resolver.js';
55
63
  export { ActionSheetIOS } from './action-sheet-ios/index.js';
56
64
  export { Linking } from './linking';
57
65
  export { Vibration } from './vibration';
@@ -73,9 +81,9 @@ export { Keyboard, KEYBOARD_EVENT } from './keyboard/index.js';
73
81
  export { currentlyFocusedInput, setInputFocused, setInputBlurred, blurTextInput, } from './text-input-state.js';
74
82
  export { LayoutAnimation } from './layout-animation/index.js';
75
83
  export { BackHandler } from './back-handler/index.js';
76
- export { PermissionsAndroid, PERMISSIONS, RESULTS } from './permissions-android/index.js';
84
+ export { PermissionsAndroid, PERMISSIONS, RESULTS, } from './permissions-android/index.js';
77
85
  export { AccessibilityInfo } from './accessibility-info';
78
86
  // StatusBar: values from the platform-selected './status-bar', types from '-shared' (the
79
87
  // .ios re-export would otherwise duplicate-export the type symbols).
80
- export { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight } from './status-bar';
88
+ export { applyStatusBarProps, statusBarImperative, statusBarCurrentHeight, } from './status-bar';
81
89
  export { hideTransition, STATUS_BAR_MANAGER, ANIMATED_HIDE_TRANSITION, STATIC_HIDE_TRANSITION, } from './status-bar/shared.js';
@@ -202,7 +202,8 @@ class InteractionManagerImpl {
202
202
  break;
203
203
  if (typeof next === 'function')
204
204
  next();
205
- if (this.deadline > DEFAULT_DEADLINE && Date.now() - startTime >= this.deadline) {
205
+ if (this.deadline > DEFAULT_DEADLINE &&
206
+ Date.now() - startTime >= this.deadline) {
206
207
  if (this.taskQueue.length > 0) {
207
208
  scheduleTimeout(() => {
208
209
  this.flushQueue();