@symbiote-native/engine 0.5.0 → 1.1.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 (91) hide show
  1. package/README.md +39 -14
  2. package/android/CMakeLists.txt +51 -0
  3. package/android/build.gradle +90 -0
  4. package/android/src/main/AndroidManifest.xml +1 -0
  5. package/android/src/main/cpp/SymbioteEngineJni.cpp +72 -0
  6. package/android/src/main/java/dev/symbiotenative/engine/SymbioteEngineModule.kt +43 -0
  7. package/android/src/main/java/dev/symbiotenative/engine/SymbioteEnginePackage.kt +35 -0
  8. package/build/accessibility-info/shared.js +1 -1
  9. package/build/accessibility-props.d.ts +1 -8
  10. package/build/accessibility-props.js +13 -16
  11. package/build/animated/animations/composition.d.ts +1 -1
  12. package/build/animated/animations/composition.js +18 -4
  13. package/build/animated/easing.d.ts +3 -2
  14. package/build/animated/easing.js +17 -88
  15. package/build/animated/event.js +6 -1
  16. package/build/animated/host-binding.d.ts +1 -1
  17. package/build/animated/host-binding.js +19 -4
  18. package/build/animated/index.d.ts +1 -1
  19. package/build/animated/mock.d.ts +1 -19
  20. package/build/animated/props.js +1 -1
  21. package/build/animated/rgba.js +16 -50
  22. package/build/events/index.js +88 -40
  23. package/build/fabric-props.d.ts +1 -1
  24. package/build/fabric-props.js +116 -184
  25. package/build/fabric.d.ts +9 -0
  26. package/build/fabric.js +32 -0
  27. package/build/host-access.d.ts +145 -0
  28. package/build/host-access.js +315 -0
  29. package/build/host-behavior.d.ts +84 -21
  30. package/build/host-behavior.js +236 -51
  31. package/build/image-source-write.d.ts +16 -0
  32. package/build/image-source-write.js +65 -0
  33. package/build/imperative.d.ts +49 -0
  34. package/build/imperative.js +258 -0
  35. package/build/index.d.ts +14 -7
  36. package/build/index.js +53 -10
  37. package/build/mutation-buffer.d.ts +238 -0
  38. package/build/mutation-buffer.js +513 -0
  39. package/build/native-engine.d.ts +185 -0
  40. package/build/native-engine.js +182 -0
  41. package/build/native-tree-host.d.ts +25 -0
  42. package/build/native-tree-host.js +68 -0
  43. package/build/node.d.ts +195 -58
  44. package/build/node.js +852 -383
  45. package/build/pan-responder/index.js +27 -52
  46. package/build/platform-color/index.d.ts +1 -1
  47. package/build/platform-color/index.js +11 -4
  48. package/build/process-background-image/index.js +30 -566
  49. package/build/process-background-longhands.d.ts +4 -0
  50. package/build/process-background-longhands.js +44 -0
  51. package/build/process-box-shadow/index.js +23 -187
  52. package/build/process-filter.js +27 -300
  53. package/build/process-transform/index.d.ts +1 -1
  54. package/build/process-transform/index.js +25 -107
  55. package/build/process-transform-origin/index.d.ts +1 -1
  56. package/build/process-transform-origin/index.js +29 -102
  57. package/build/registry.d.ts +36 -0
  58. package/build/registry.js +73 -0
  59. package/build/sound-manager/index.d.ts +3 -0
  60. package/build/sound-manager/index.js +36 -0
  61. package/build/structured-style.d.ts +10 -0
  62. package/build/structured-style.js +180 -0
  63. package/build/style-registry/index.d.ts +14 -0
  64. package/build/style-registry/index.js +60 -11
  65. package/build/surface.d.ts +31 -2
  66. package/build/surface.js +138 -56
  67. package/build/text-input-state.d.ts +1 -0
  68. package/build/text-input-state.js +17 -3
  69. package/build/tree-host.d.ts +322 -0
  70. package/build/tree-host.js +211 -0
  71. package/build/view-config.js +4 -4
  72. package/codegen-specs/NativeSymbioteEngine.ts +27 -0
  73. package/cpp/SymbioteDebug.cpp +51 -0
  74. package/cpp/SymbioteDebug.h +54 -0
  75. package/cpp/SymbioteEngineBindings.cpp +234 -0
  76. package/cpp/SymbioteEngineBindings.h +59 -0
  77. package/cpp/SymbioteFabricProps.cpp +2619 -0
  78. package/cpp/SymbioteFabricProps.h +223 -0
  79. package/cpp/SymbioteTree.cpp +2593 -0
  80. package/cpp/SymbioteTree.h +294 -0
  81. package/ios/SymbioteEngineModule.h +25 -0
  82. package/ios/SymbioteEngineModule.mm +44 -0
  83. package/package.json +31 -3
  84. package/react-native.config.cjs +23 -0
  85. package/symbiote-engine.podspec +42 -0
  86. package/build/animated/bezier.d.ts +0 -1
  87. package/build/animated/bezier.js +0 -102
  88. package/build/commit.d.ts +0 -49
  89. package/build/commit.js +0 -1058
  90. package/build/tags.d.ts +0 -2
  91. package/build/tags.js +0 -40
@@ -12,6 +12,8 @@
12
12
  // changed ones on `changedTouches`), so the centroid/velocity math here reads
13
13
  // those directly while keeping RN's accumulate-deltas-over-time behavior.
14
14
  import { dlog } from '../debug.js';
15
+ // @ts-expect-error - untyped Flow source. Metro compiles it; vitest.config.ts strips the types.
16
+ import TouchHistoryMath from 'react-native/Libraries/Interaction/TouchHistoryMath';
15
17
  import { isRecord } from '../type-guards.js';
16
18
  const SINGLE_TOUCH_COUNT = 1;
17
19
  // onShouldBlockNativeResponder defaults to true (RN: block native by default).
@@ -81,15 +83,6 @@ function mostRecentTimestamp(touches) {
81
83
  // that moved this frame, via each touch's own previous->current delta. Headless callers
82
84
  // that invoke the handlers directly (no shared, no store) carry no touchHistory and fall
83
85
  // back to the centroid path below, which keeps single-touch behavior.
84
- function isTouchRecord(value) {
85
- return (isRecord(value) &&
86
- typeof value.touchActive === 'boolean' &&
87
- typeof value.currentPageX === 'number' &&
88
- typeof value.currentPageY === 'number' &&
89
- typeof value.currentTimeStamp === 'number' &&
90
- typeof value.previousPageX === 'number' &&
91
- typeof value.previousPageY === 'number');
92
- }
93
86
  function isTouchHistory(value) {
94
87
  return (isRecord(value) &&
95
88
  Array.isArray(value.touchBank) &&
@@ -101,58 +94,31 @@ function touchHistoryOf(event) {
101
94
  const raw = event.nativeEvent.touchHistory;
102
95
  return isTouchHistory(raw) ? raw : undefined;
103
96
  }
104
- // Ported from RN Interaction/TouchHistoryMath.js:centroidDimension (lines 30-85). Mean
105
- // of one coordinate over the touches that moved after `touchesChangedAfter`, taking each
106
- // touch's current or previous position. The single-active-touch fast path uses a strict
107
- // `>`; the multi-touch scan uses `>=`, both kept from RN.
108
- function centroidDimension(touchHistory, touchesChangedAfter, isXAxis, ofCurrent) {
109
- const { touchBank } = touchHistory;
110
- let total = 0;
111
- let count = 0;
112
- const single = touchHistory.numberActiveTouches === SINGLE_TOUCH_COUNT
113
- ? touchBank[touchHistory.indexOfSingleActiveTouch]
114
- : undefined;
115
- if (isTouchRecord(single)) {
116
- if (single.touchActive && single.currentTimeStamp > touchesChangedAfter) {
117
- total += dimensionOf(single, isXAxis, ofCurrent);
118
- count = 1;
119
- }
120
- }
121
- else {
122
- for (const record of touchBank) {
123
- if (isTouchRecord(record) &&
124
- record.touchActive &&
125
- record.currentTimeStamp >= touchesChangedAfter) {
126
- total += dimensionOf(record, isXAxis, ofCurrent);
127
- count++;
128
- }
129
- }
130
- }
131
- return count > 0 ? total / count : NO_CENTROID;
132
- }
133
- const NO_CENTROID = -1;
134
- function dimensionOf(record, isXAxis, ofCurrent) {
135
- if (ofCurrent)
136
- return isXAxis ? record.currentPageX : record.currentPageY;
137
- return isXAxis ? record.previousPageX : record.previousPageY;
138
- }
97
+ // The six readings PanResponder needs, under this file's shorter names. Upstream's own module is
98
+ // imported rather than re-derived: it has no dependencies, no native access, and its two scans -
99
+ // a strict `>` on the single-active-touch fast path, `>=` on the multi-touch loop - are
100
+ // load-bearing and easy to reproduce subtly wrong.
101
+ //
102
+ // The per-record runtime guard that used to sit here went with it. It was forced by `nativeEvent`
103
+ // being a Record<string, unknown>; `touchHistoryOf` above already validates the bank at the
104
+ // boundary, and the records inside it are written by our own touch-history.ts.
139
105
  function currentCentroidXOfChanged(touchHistory, after) {
140
- return centroidDimension(touchHistory, after, true, true);
106
+ return TouchHistoryMath.currentCentroidXOfTouchesChangedAfter(touchHistory, after);
141
107
  }
142
108
  function currentCentroidYOfChanged(touchHistory, after) {
143
- return centroidDimension(touchHistory, after, false, true);
109
+ return TouchHistoryMath.currentCentroidYOfTouchesChangedAfter(touchHistory, after);
144
110
  }
145
111
  function previousCentroidXOfChanged(touchHistory, after) {
146
- return centroidDimension(touchHistory, after, true, false);
112
+ return TouchHistoryMath.previousCentroidXOfTouchesChangedAfter(touchHistory, after);
147
113
  }
148
114
  function previousCentroidYOfChanged(touchHistory, after) {
149
- return centroidDimension(touchHistory, after, false, false);
115
+ return TouchHistoryMath.previousCentroidYOfTouchesChangedAfter(touchHistory, after);
150
116
  }
151
117
  function currentCentroidXAll(touchHistory) {
152
- return centroidDimension(touchHistory, 0, true, true);
118
+ return TouchHistoryMath.currentCentroidX(touchHistory);
153
119
  }
154
120
  function currentCentroidYAll(touchHistory) {
155
- return centroidDimension(touchHistory, 0, false, true);
121
+ return TouchHistoryMath.currentCentroidY(touchHistory);
156
122
  }
157
123
  // RN PanResponder._updateGestureStateOnMove (Interaction/PanResponder.js lines 330-366):
158
124
  // accumulate the centroid change of touches that moved after `_accountsForMovesUpTo`,
@@ -301,8 +267,17 @@ const PanResponder = {
301
267
  : centroidY(touches);
302
268
  gestureState.dx = 0;
303
269
  gestureState.dy = 0;
304
- // The grant frame is already accounted for, so the first move's velocity
305
- // is measured from here, not from time 0.
270
+ // Two deliberate divergences from upstream's onResponderGrant (PanResponder.js:459),
271
+ // which sets x0/y0/dx/dy and nothing else. Both are decisions, not drift - recorded here
272
+ // because the first one spent months living in a comment nobody audited against upstream.
273
+ //
274
+ // 1. The grant frame is already accounted for, so the first move's velocity is measured
275
+ // from here, not from time 0. packages/navigation's drawer reads vx through
276
+ // resolveSwipeIntent with a 0.5 flick threshold, and upstream's version makes the first
277
+ // move look instantaneous.
278
+ // 2. numberActiveTouches is refreshed at grant. Upstream leaves whatever the previous
279
+ // gesture's onResponderEnd left behind - usually 0 - so an app reading it inside
280
+ // onPanResponderGrant gets a stale count there and a correct one everywhere else.
306
281
  gestureState._accountsForMovesUpTo = frameTimestampOf(event, touches);
307
282
  gestureState.numberActiveTouches =
308
283
  touchHistory?.numberActiveTouches ?? touches.length;
@@ -13,7 +13,7 @@ export interface IOpaqueColorValue {
13
13
  readonly highContrastDark?: IColorValue;
14
14
  };
15
15
  }
16
- export type IColorValue = string | IOpaqueColorValue;
16
+ export type IColorValue = string | number | IOpaqueColorValue;
17
17
  export declare function PlatformColor(...names: string[]): IOpaqueColorValue;
18
18
  export declare function DynamicColorIOS(tuple: IDynamicColorIOSTuple): IOpaqueColorValue;
19
19
  export declare function isOpaqueColorValue(value: unknown): value is IOpaqueColorValue;
@@ -43,9 +43,16 @@ export function setColorProcessor(process) {
43
43
  export function processColor(color) {
44
44
  return colorProcessor(color);
45
45
  }
46
- // A color-keyed value the platform processor must convert before Fabric: a CSS string, or an
47
- // opaque PlatformColor / DynamicColorIOS object. Numbers (already platform ints) and undefined
48
- // are left untouched.
46
+ // A color-keyed value the platform processor must convert before Fabric: a CSS string, a numeric
47
+ // literal, or an opaque PlatformColor / DynamicColorIOS object. `undefined` is left untouched.
48
+ //
49
+ // A number used to be excluded here on the reasoning that it was "already a resolved platform
50
+ // int". Nothing in the pipeline produces one: the CSS parser emits hex STRINGS, and fabricProps
51
+ // builds a fresh payload object instead of writing the resolved value back into node.props, so a
52
+ // number reaching this guard is always the author's own literal. Excluding it committed
53
+ // `color: 0xff0000ff` (opaque red, rrggbbaa) unrotated, and native reads that as aarrggbb: blue.
49
54
  export function isProcessableColor(value) {
50
- return typeof value === 'string' || isOpaqueColorValue(value);
55
+ return (typeof value === 'string' ||
56
+ typeof value === 'number' ||
57
+ isOpaqueColorValue(value));
51
58
  }