@reactiive/ennio 0.0.1

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 (57) hide show
  1. package/EnnioCore.podspec +61 -0
  2. package/LICENSE +21 -0
  3. package/README.md +50 -0
  4. package/android/CMakeLists.txt +40 -0
  5. package/android/build.gradle +64 -0
  6. package/cpp/ElementMatcher.cpp +661 -0
  7. package/cpp/ElementMatcher.hpp +244 -0
  8. package/cpp/EnnioLog.hpp +182 -0
  9. package/cpp/HybridEnnio.cpp +1161 -0
  10. package/cpp/HybridEnnio.hpp +174 -0
  11. package/cpp/IdleMonitor.hpp +277 -0
  12. package/cpp/Protocol.cpp +135 -0
  13. package/cpp/Protocol.hpp +47 -0
  14. package/cpp/SelectorCriteria.hpp +281 -0
  15. package/cpp/SelectorParser.cpp +649 -0
  16. package/cpp/SelectorParser.hpp +94 -0
  17. package/cpp/ShadowTreeTraverser.cpp +305 -0
  18. package/cpp/ShadowTreeTraverser.hpp +142 -0
  19. package/cpp/TestIDRegistry.cpp +109 -0
  20. package/cpp/TestIDRegistry.hpp +84 -0
  21. package/dist/cli.js +16221 -0
  22. package/ios/EnnioAutoInit.mm +338 -0
  23. package/ios/EnnioDebugBanner.h +19 -0
  24. package/ios/EnnioDebugBanner.mm +178 -0
  25. package/ios/EnnioRuntimeHelper.h +264 -0
  26. package/ios/EnnioRuntimeHelper.mm +2443 -0
  27. package/lib/Ennio.nitro.d.ts +263 -0
  28. package/lib/Ennio.nitro.d.ts.map +1 -0
  29. package/lib/Ennio.nitro.js +2 -0
  30. package/lib/Ennio.nitro.js.map +1 -0
  31. package/lib/index.d.ts +16 -0
  32. package/lib/index.d.ts.map +1 -0
  33. package/lib/index.js +45 -0
  34. package/lib/index.js.map +1 -0
  35. package/nitro.json +24 -0
  36. package/nitrogen/generated/.gitattributes +1 -0
  37. package/nitrogen/generated/android/EnnioCore+autolinking.cmake +81 -0
  38. package/nitrogen/generated/android/EnnioCore+autolinking.gradle +27 -0
  39. package/nitrogen/generated/android/EnnioCoreOnLoad.cpp +49 -0
  40. package/nitrogen/generated/android/EnnioCoreOnLoad.hpp +34 -0
  41. package/nitrogen/generated/android/kotlin/com/margelo/nitro/ennio/EnnioCoreOnLoad.kt +35 -0
  42. package/nitrogen/generated/ios/EnnioCore+autolinking.rb +62 -0
  43. package/nitrogen/generated/ios/EnnioCore-Swift-Cxx-Bridge.cpp +17 -0
  44. package/nitrogen/generated/ios/EnnioCore-Swift-Cxx-Bridge.hpp +27 -0
  45. package/nitrogen/generated/ios/EnnioCore-Swift-Cxx-Umbrella.hpp +38 -0
  46. package/nitrogen/generated/ios/EnnioCoreAutolinking.mm +35 -0
  47. package/nitrogen/generated/ios/EnnioCoreAutolinking.swift +16 -0
  48. package/nitrogen/generated/shared/c++/ExtendedElementInfo.hpp +118 -0
  49. package/nitrogen/generated/shared/c++/HybridEnnioSpec.cpp +44 -0
  50. package/nitrogen/generated/shared/c++/HybridEnnioSpec.hpp +93 -0
  51. package/nitrogen/generated/shared/c++/LayoutMetrics.hpp +103 -0
  52. package/nitrogen/generated/shared/c++/ScrollDirection.hpp +84 -0
  53. package/package.json +78 -0
  54. package/react-native.config.js +14 -0
  55. package/src/Ennio.nitro.ts +363 -0
  56. package/src/cli/hid-daemon.py +129 -0
  57. package/src/index.ts +72 -0
@@ -0,0 +1,263 @@
1
+ import type { HybridObject } from 'react-native-nitro-modules';
2
+ /**
3
+ * Layout metrics for a UI element
4
+ */
5
+ export interface LayoutMetrics {
6
+ x: number;
7
+ y: number;
8
+ width: number;
9
+ height: number;
10
+ screenX: number;
11
+ screenY: number;
12
+ }
13
+ /**
14
+ * Information about a found element
15
+ */
16
+ export interface ElementInfo {
17
+ testID: string;
18
+ type: string;
19
+ text?: string;
20
+ accessible: boolean;
21
+ enabled: boolean;
22
+ layout: LayoutMetrics;
23
+ }
24
+ /**
25
+ * Extended element info with additional state properties
26
+ */
27
+ export interface ExtendedElementInfo extends ElementInfo {
28
+ checked: boolean;
29
+ focused: boolean;
30
+ selected: boolean;
31
+ }
32
+ /**
33
+ * Text matching mode for text selectors
34
+ */
35
+ export type TextMatchMode = 'exact' | 'contains' | 'regex' | 'startsWith' | 'endsWith';
36
+ /**
37
+ * Text matcher configuration
38
+ */
39
+ export interface TextMatcher {
40
+ pattern: string;
41
+ mode?: TextMatchMode;
42
+ }
43
+ /**
44
+ * Point for coordinate-based selection
45
+ */
46
+ export interface Point {
47
+ x: number;
48
+ y: number;
49
+ isPercentage?: boolean;
50
+ }
51
+ /**
52
+ * Trait types for trait-based selection
53
+ */
54
+ export type Trait = 'text' | 'long-text' | 'square';
55
+ /**
56
+ * Direction for scroll / swipe gestures
57
+ */
58
+ export type ScrollDirection = 'up' | 'down' | 'left' | 'right';
59
+ /**
60
+ * Selector - Full Maestro selector parity
61
+ *
62
+ * Supports:
63
+ * - Primary: id, text, index, point
64
+ * - State: enabled, checked, focused, selected
65
+ * - Spatial: below, above, leftOf, rightOf
66
+ * - Hierarchical: containsChild, childOf, containsDescendants
67
+ * - Dimensions: width, height, tolerance
68
+ * - Traits: text, long-text, square
69
+ */
70
+ export interface Selector {
71
+ /**
72
+ * Match by testID (O(1) lookup when used alone)
73
+ */
74
+ id?: string;
75
+ /**
76
+ * Match by text content (string for exact match, or TextMatcher for advanced)
77
+ */
78
+ text?: string | TextMatcher;
79
+ /**
80
+ * Return the nth matching element (0-indexed)
81
+ */
82
+ index?: number;
83
+ /**
84
+ * Select element at specific coordinates
85
+ * String format: "50%,50%" or "100,200"
86
+ */
87
+ point?: Point | string;
88
+ /**
89
+ * Match by enabled state
90
+ */
91
+ enabled?: boolean;
92
+ /**
93
+ * Match by checked state (checkboxes, switches)
94
+ */
95
+ checked?: boolean;
96
+ /**
97
+ * Match by focused state
98
+ */
99
+ focused?: boolean;
100
+ /**
101
+ * Match by selected state
102
+ */
103
+ selected?: boolean;
104
+ /**
105
+ * Match elements below the reference element
106
+ */
107
+ below?: Selector;
108
+ /**
109
+ * Match elements above the reference element
110
+ */
111
+ above?: Selector;
112
+ /**
113
+ * Match elements to the left of the reference element
114
+ */
115
+ leftOf?: Selector;
116
+ /**
117
+ * Match elements to the right of the reference element
118
+ */
119
+ rightOf?: Selector;
120
+ /**
121
+ * Match elements that contain a direct child matching criteria
122
+ */
123
+ containsChild?: Selector;
124
+ /**
125
+ * Match elements that are children of an element matching criteria
126
+ */
127
+ childOf?: Selector;
128
+ /**
129
+ * Match elements that contain all descendants matching each criteria
130
+ */
131
+ containsDescendants?: Selector[];
132
+ /**
133
+ * Match by width (in points)
134
+ */
135
+ width?: number;
136
+ /**
137
+ * Match by height (in points)
138
+ */
139
+ height?: number;
140
+ /**
141
+ * Tolerance for width/height matching (default: 0)
142
+ */
143
+ tolerance?: number;
144
+ /**
145
+ * Match elements with specified traits
146
+ */
147
+ traits?: Trait[];
148
+ }
149
+ /**
150
+ * Ennio HybridObject - Direct Fabric shadow tree access for E2E testing
151
+ */
152
+ export interface Ennio extends HybridObject<{
153
+ ios: 'c++';
154
+ android: 'c++';
155
+ }> {
156
+ /**
157
+ * Check if an element with the given testID exists in the tree
158
+ * @param testID - The testID prop value to search for
159
+ */
160
+ exists(testID: string): boolean;
161
+ /**
162
+ * Check if an element is visible on screen
163
+ * Considers: opacity, display, pointerEvents, and viewport bounds
164
+ * @param testID - The testID prop value
165
+ */
166
+ isVisible(testID: string): boolean;
167
+ /**
168
+ * Get text content of an element
169
+ * @param testID - The testID prop value
170
+ * @returns Text content if available, null otherwise
171
+ */
172
+ getText(testID: string): string | null;
173
+ /**
174
+ * Wait for the shadow tree to settle (no pending updates)
175
+ * @param timeoutMs - Maximum time to wait in milliseconds
176
+ * @returns true if settled within timeout
177
+ */
178
+ waitForIdle(timeoutMs: number): boolean;
179
+ /**
180
+ * Force a synchronization point - ensures all pending JS and native updates are processed
181
+ */
182
+ synchronize(): void;
183
+ /**
184
+ * Block until React fires the next onCommitFiberRoot, or until maxMs
185
+ * elapses. Used by the CLI to wake early from blind settle sleeps —
186
+ * cap is the safety floor, commit signal is the early-wake.
187
+ * @param maxMs - Maximum time to wait in milliseconds
188
+ * @returns true if a commit fired within maxMs, false on timeout
189
+ */
190
+ waitForNextCommit(maxMs: number): boolean;
191
+ /**
192
+ * Find an element using a selector (JSON string)
193
+ * @param selectorJson - JSON-encoded Selector object
194
+ * @returns ExtendedElementInfo if found, null otherwise
195
+ */
196
+ findBySelector(selectorJson: string): ExtendedElementInfo | null;
197
+ /**
198
+ * Find all elements matching a selector (JSON string)
199
+ * @param selectorJson - JSON-encoded Selector object
200
+ * @returns Array of ExtendedElementInfo
201
+ */
202
+ findAllBySelector(selectorJson: string): ExtendedElementInfo[];
203
+ /**
204
+ * Check if an element matching the selector exists
205
+ * @param selectorJson - JSON-encoded Selector object
206
+ */
207
+ existsBySelector(selectorJson: string): boolean;
208
+ /**
209
+ * Get text content of an element using a selector (JSON string)
210
+ * @param selectorJson - JSON-encoded Selector object
211
+ * @returns Text content if available, null otherwise
212
+ */
213
+ getTextBySelector(selectorJson: string): string | null;
214
+ /**
215
+ * Check if an element matching the selector is visible
216
+ * @param selectorJson - JSON-encoded Selector object
217
+ */
218
+ isVisibleBySelector(selectorJson: string): boolean;
219
+ /**
220
+ * Check if an alert is currently presented
221
+ */
222
+ isAlertPresent(): boolean;
223
+ /**
224
+ * Get the text content of the current alert (title + message)
225
+ */
226
+ getAlertText(): string;
227
+ /**
228
+ * Get the button titles of the current alert
229
+ */
230
+ getAlertButtons(): string[];
231
+ scroll(testID: string, direction: ScrollDirection, distance: number): boolean;
232
+ scrollTo(scrollViewTestID: string, elementTestID: string): boolean;
233
+ /**
234
+ * Synthesize a pan gesture from (x1,y1) to (x2,y2) over `durationMs`.
235
+ * If the start point hits a UIScrollView, takes the fast path
236
+ * (`setContentOffset:animated:NO` with the delta) — no UITouch tax.
237
+ * Otherwise drives a UITouchPhaseMoved loop for cross-view drags
238
+ * (sheet dismiss, page swipe, non-scrollable carousel pan).
239
+ * Coordinates are window-relative. Sim-only (UITouch private API).
240
+ */
241
+ swipeAtPoints(x1: number, y1: number, x2: number, y2: number, durationMs: number): boolean;
242
+ /**
243
+ * Synthesize a hardware key press by HID keycode against the current
244
+ * first responder when it conforms to UIKeyInput. Currently maps:
245
+ * 42 → deleteBackward (backspace)
246
+ * 40 → insertText("\n") (return)
247
+ * 44 → insertText(" ") (space)
248
+ * Returns false when no first responder accepts text input. Replaces
249
+ * idb's HID `pressKey` for in-app text fields.
250
+ */
251
+ pressHardwareKey(keyCode: number): boolean;
252
+ /**
253
+ * Drive a back navigation. Pops the top view controller of the
254
+ * current UINavigationController.
255
+ */
256
+ backGesture(): boolean;
257
+ hideKeyboard(): boolean;
258
+ tapAlertButton(buttonText: string): boolean;
259
+ dismissAlert(): boolean;
260
+ copyToClipboard(text: string): boolean;
261
+ pasteFromClipboard(testID: string): boolean;
262
+ }
263
+ //# sourceMappingURL=Ennio.nitro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ennio.nitro.d.ts","sourceRoot":"","sources":["../src/Ennio.nitro.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Ennio.nitro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ennio.nitro.js","sourceRoot":"","sources":["../src/Ennio.nitro.ts"],"names":[],"mappings":""}
package/lib/index.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { Ennio, ExtendedElementInfo, LayoutMetrics, Selector, TextMatcher, TextMatchMode, Point, Trait, ScrollDirection } from './Ennio.nitro';
2
+ export type { Ennio, ExtendedElementInfo, LayoutMetrics, Selector, TextMatcher, TextMatchMode, Point, Trait, ScrollDirection, };
3
+ /**
4
+ * Get the Ennio HybridObject instance. Auto-init happens at app start
5
+ * (EnnioAutoInit swizzles RCTHost.start) — this is just a stable
6
+ * handle for callers that want to introspect from JS.
7
+ */
8
+ export declare function getEnnioModule(): Ennio | null;
9
+ /**
10
+ * Returns true when the Ennio JSI surface is reachable. The runtime
11
+ * dispatch surface (`__ennioDispatch` + commit signal) is installed
12
+ * automatically by the pod's `+load` hook — this only exposes the
13
+ * Nitro module to JS callers that want to read state directly.
14
+ */
15
+ export declare function isNativeModuleAvailable(): boolean;
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,KAAK,EACL,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,WAAW,EACX,aAAa,EACb,KAAK,EACL,KAAK,EACL,eAAe,EAChB,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,KAAK,EACL,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,WAAW,EACX,aAAa,EACb,KAAK,EACL,KAAK,EACL,eAAe,GAChB,CAAC;AAKF;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,KAAK,GAAG,IAAI,CAoB7C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD"}
package/lib/index.js ADDED
@@ -0,0 +1,45 @@
1
+ import { NitroModules } from 'react-native-nitro-modules';
2
+ let _ennioModule = null;
3
+ let _initError = null;
4
+ /**
5
+ * Get the Ennio HybridObject instance. Auto-init happens at app start
6
+ * (EnnioAutoInit swizzles RCTHost.start) — this is just a stable
7
+ * handle for callers that want to introspect from JS.
8
+ */
9
+ export function getEnnioModule() {
10
+ if (_ennioModule) {
11
+ return _ennioModule;
12
+ }
13
+ if (_initError) {
14
+ return null;
15
+ }
16
+ try {
17
+ _ennioModule = NitroModules.createHybridObject('Ennio');
18
+ return _ennioModule;
19
+ }
20
+ catch (error) {
21
+ _initError = error instanceof Error ? error : new Error(String(error));
22
+ if (__DEV__) {
23
+ console.warn('[Ennio] Native module not available:', _initError.message);
24
+ console.warn('[Ennio] E2E testing features will be disabled');
25
+ }
26
+ return null;
27
+ }
28
+ }
29
+ /**
30
+ * Returns true when the Ennio JSI surface is reachable. The runtime
31
+ * dispatch surface (`__ennioDispatch` + commit signal) is installed
32
+ * automatically by the pod's `+load` hook — this only exposes the
33
+ * Nitro module to JS callers that want to read state directly.
34
+ */
35
+ export function isNativeModuleAvailable() {
36
+ return getEnnioModule() !== null;
37
+ }
38
+ // No JS-side bootstrap. `ennio` autolinks via Pod, and the iOS
39
+ // `EnnioAutoInit` swizzle installs the JSI dispatch surface (commit
40
+ // signal + `__ennioDispatch` host function) natively, on the JS
41
+ // thread, the moment RCTHost finishes booting. The user's app never
42
+ // imports this package; it lands purely through `npm install ennio`.
43
+ // The external CLI drives the runtime via Hermes Inspector
44
+ // (`Runtime.evaluate('__ennioDispatch(...)')`).
45
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAyB1D,IAAI,YAAY,GAAiB,IAAI,CAAC;AACtC,IAAI,UAAU,GAAiB,IAAI,CAAC;AAEpC;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC;QACH,YAAY,GAAG,YAAY,CAAC,kBAAkB,CAAQ,OAAO,CAAC,CAAC;QAC/D,OAAO,YAAY,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,UAAU,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvE,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,sCAAsC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;YACzE,OAAO,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,cAAc,EAAE,KAAK,IAAI,CAAC;AACnC,CAAC;AAED,+DAA+D;AAC/D,oEAAoE;AACpE,gEAAgE;AAChE,oEAAoE;AACpE,qEAAqE;AACrE,2DAA2D;AAC3D,gDAAgD"}
package/nitro.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "https://nitro.margelo.com/nitro.schema.json",
3
+ "cxxNamespace": ["ennio"],
4
+ "ios": {
5
+ "iosModuleName": "EnnioCore"
6
+ },
7
+ "android": {
8
+ "androidNamespace": ["ennio"],
9
+ "androidCxxLibName": "EnnioCore"
10
+ },
11
+ "autolinking": {
12
+ "Ennio": {
13
+ "ios": {
14
+ "language": "c++",
15
+ "implementationClassName": "HybridEnnio"
16
+ },
17
+ "android": {
18
+ "language": "c++",
19
+ "implementationClassName": "HybridEnnio"
20
+ }
21
+ }
22
+ },
23
+ "ignorePaths": ["node_modules"]
24
+ }
@@ -0,0 +1 @@
1
+ ** linguist-generated=true
@@ -0,0 +1,81 @@
1
+ #
2
+ # EnnioCore+autolinking.cmake
3
+ # This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ # https://github.com/mrousavy/nitro
5
+ # Copyright © Marc Rousavy @ Margelo
6
+ #
7
+
8
+ # This is a CMake file that adds all files generated by Nitrogen
9
+ # to the current CMake project.
10
+ #
11
+ # To use it, add this to your CMakeLists.txt:
12
+ # ```cmake
13
+ # include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/EnnioCore+autolinking.cmake)
14
+ # ```
15
+
16
+ # Define a flag to check if we are building properly
17
+ add_definitions(-DBUILDING_ENNIOCORE_WITH_GENERATED_CMAKE_PROJECT)
18
+
19
+ # Enable Raw Props parsing in react-native (for Nitro Views)
20
+ add_definitions(-DRN_SERIALIZABLE_STATE)
21
+
22
+ # Add all headers that were generated by Nitrogen
23
+ include_directories(
24
+ "../nitrogen/generated/shared/c++"
25
+ "../nitrogen/generated/android/c++"
26
+ "../nitrogen/generated/android/"
27
+ )
28
+
29
+ # Add all .cpp sources that were generated by Nitrogen
30
+ target_sources(
31
+ # CMake project name (Android C++ library name)
32
+ EnnioCore PRIVATE
33
+ # Autolinking Setup
34
+ ../nitrogen/generated/android/EnnioCoreOnLoad.cpp
35
+ # Shared Nitrogen C++ sources
36
+ ../nitrogen/generated/shared/c++/HybridEnnioSpec.cpp
37
+ # Android-specific Nitrogen C++ sources
38
+
39
+ )
40
+
41
+ # From node_modules/react-native/ReactAndroid/cmake-utils/folly-flags.cmake
42
+ # Used in node_modules/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake
43
+ target_compile_definitions(
44
+ EnnioCore PRIVATE
45
+ -DFOLLY_NO_CONFIG=1
46
+ -DFOLLY_HAVE_CLOCK_GETTIME=1
47
+ -DFOLLY_USE_LIBCPP=1
48
+ -DFOLLY_CFG_NO_COROUTINES=1
49
+ -DFOLLY_MOBILE=1
50
+ -DFOLLY_HAVE_RECVMMSG=1
51
+ -DFOLLY_HAVE_PTHREAD=1
52
+ # Once we target android-23 above, we can comment
53
+ # the following line. NDK uses GNU style stderror_r() after API 23.
54
+ -DFOLLY_HAVE_XSI_STRERROR_R=1
55
+ )
56
+
57
+ # Add all libraries required by the generated specs
58
+ find_package(fbjni REQUIRED) # <-- Used for communication between Java <-> C++
59
+ find_package(ReactAndroid REQUIRED) # <-- Used to set up React Native bindings (e.g. CallInvoker/TurboModule)
60
+ find_package(react-native-nitro-modules REQUIRED) # <-- Used to create all HybridObjects and use the Nitro core library
61
+
62
+ # Link all libraries together
63
+ target_link_libraries(
64
+ EnnioCore
65
+ fbjni::fbjni # <-- Facebook C++ JNI helpers
66
+ ReactAndroid::jsi # <-- RN: JSI
67
+ react-native-nitro-modules::NitroModules # <-- NitroModules Core :)
68
+ )
69
+
70
+ # Link react-native (different prefab between RN 0.75 and RN 0.76)
71
+ if(ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
72
+ target_link_libraries(
73
+ EnnioCore
74
+ ReactAndroid::reactnative # <-- RN: Native Modules umbrella prefab
75
+ )
76
+ else()
77
+ target_link_libraries(
78
+ EnnioCore
79
+ ReactAndroid::react_nativemodule_core # <-- RN: TurboModules Core
80
+ )
81
+ endif()
@@ -0,0 +1,27 @@
1
+ ///
2
+ /// EnnioCore+autolinking.gradle
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ /// This is a Gradle file that adds all files generated by Nitrogen
9
+ /// to the current Gradle project.
10
+ ///
11
+ /// To use it, add this to your build.gradle:
12
+ /// ```gradle
13
+ /// apply from: '../nitrogen/generated/android/EnnioCore+autolinking.gradle'
14
+ /// ```
15
+
16
+ logger.warn("[NitroModules] 🔥 EnnioCore is boosted by nitro!")
17
+
18
+ android {
19
+ sourceSets {
20
+ main {
21
+ java.srcDirs += [
22
+ // Nitrogen files
23
+ "${project.projectDir}/../nitrogen/generated/android/kotlin"
24
+ ]
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,49 @@
1
+ ///
2
+ /// EnnioCoreOnLoad.cpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #ifndef BUILDING_ENNIOCORE_WITH_GENERATED_CMAKE_PROJECT
9
+ #error EnnioCoreOnLoad.cpp is not being built with the autogenerated CMakeLists.txt project. Is a different CMakeLists.txt building this?
10
+ #endif
11
+
12
+ #include "EnnioCoreOnLoad.hpp"
13
+
14
+ #include <jni.h>
15
+ #include <fbjni/fbjni.h>
16
+ #include <NitroModules/HybridObjectRegistry.hpp>
17
+
18
+ #include "HybridEnnio.hpp"
19
+
20
+ namespace margelo::nitro::ennio {
21
+
22
+ int initialize(JavaVM* vm) {
23
+ return facebook::jni::initialize(vm, []() {
24
+ ::margelo::nitro::ennio::registerAllNatives();
25
+ });
26
+ }
27
+
28
+
29
+
30
+ void registerAllNatives() {
31
+ using namespace margelo::nitro;
32
+ using namespace margelo::nitro::ennio;
33
+
34
+ // Register native JNI methods
35
+
36
+
37
+ // Register Nitro Hybrid Objects
38
+ HybridObjectRegistry::registerHybridObjectConstructor(
39
+ "Ennio",
40
+ []() -> std::shared_ptr<HybridObject> {
41
+ static_assert(std::is_default_constructible_v<HybridEnnio>,
42
+ "The HybridObject \"HybridEnnio\" is not default-constructible! "
43
+ "Create a public constructor that takes zero arguments to be able to autolink this HybridObject.");
44
+ return std::make_shared<HybridEnnio>();
45
+ }
46
+ );
47
+ }
48
+
49
+ } // namespace margelo::nitro::ennio
@@ -0,0 +1,34 @@
1
+ ///
2
+ /// EnnioCoreOnLoad.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #include <jni.h>
9
+ #include <functional>
10
+ #include <NitroModules/NitroDefines.hpp>
11
+
12
+ namespace margelo::nitro::ennio {
13
+
14
+ [[deprecated("Use registerNatives() instead.")]]
15
+ int initialize(JavaVM* vm);
16
+
17
+ /**
18
+ * Register the native (C++) part of EnnioCore, and autolinks all Hybrid Objects.
19
+ * Call this in your `JNI_OnLoad` function (probably inside `cpp-adapter.cpp`),
20
+ * inside a `facebook::jni::initialize(vm, ...)` call.
21
+ * Example:
22
+ * ```cpp (cpp-adapter.cpp)
23
+ * JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
24
+ * return facebook::jni::initialize(vm, []() {
25
+ * // register all EnnioCore HybridObjects
26
+ * margelo::nitro::ennio::registerNatives();
27
+ * // any other custom registrations go here.
28
+ * });
29
+ * }
30
+ * ```
31
+ */
32
+ void registerAllNatives();
33
+
34
+ } // namespace margelo::nitro::ennio
@@ -0,0 +1,35 @@
1
+ ///
2
+ /// EnnioCoreOnLoad.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.ennio
9
+
10
+ import android.util.Log
11
+
12
+ internal class EnnioCoreOnLoad {
13
+ companion object {
14
+ private const val TAG = "EnnioCoreOnLoad"
15
+ private var didLoad = false
16
+ /**
17
+ * Initializes the native part of "EnnioCore".
18
+ * This method is idempotent and can be called more than once.
19
+ */
20
+ @JvmStatic
21
+ fun initializeNative() {
22
+ if (didLoad) return
23
+ try {
24
+ Log.i(TAG, "Loading EnnioCore C++ library...")
25
+ System.loadLibrary("EnnioCore")
26
+ Log.i(TAG, "Successfully loaded EnnioCore C++ library!")
27
+ didLoad = true
28
+ } catch (e: Error) {
29
+ Log.e(TAG, "Failed to load EnnioCore C++ library! Is it properly installed and linked? " +
30
+ "Is the name correct? (see `CMakeLists.txt`, at `add_library(...)`)", e)
31
+ throw e
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,62 @@
1
+ #
2
+ # EnnioCore+autolinking.rb
3
+ # This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ # https://github.com/mrousavy/nitro
5
+ # Copyright © Marc Rousavy @ Margelo
6
+ #
7
+
8
+ # This is a Ruby script that adds all files generated by Nitrogen
9
+ # to the given podspec.
10
+ #
11
+ # To use it, add this to your .podspec:
12
+ # ```ruby
13
+ # Pod::Spec.new do |spec|
14
+ # # ...
15
+ #
16
+ # # Add all files generated by Nitrogen
17
+ # load 'nitrogen/generated/ios/EnnioCore+autolinking.rb'
18
+ # add_nitrogen_files(spec)
19
+ # end
20
+ # ```
21
+
22
+ def add_nitrogen_files(spec)
23
+ Pod::UI.puts "[NitroModules] 🔥 EnnioCore is boosted by nitro!"
24
+
25
+ spec.dependency "NitroModules"
26
+
27
+ current_source_files = Array(spec.attributes_hash['source_files'])
28
+ spec.source_files = current_source_files + [
29
+ # Generated cross-platform specs
30
+ "nitrogen/generated/shared/**/*.{h,hpp,c,cpp,swift}",
31
+ # Generated bridges for the cross-platform specs
32
+ "nitrogen/generated/ios/**/*.{h,hpp,c,cpp,mm,swift}",
33
+ ]
34
+
35
+ current_public_header_files = Array(spec.attributes_hash['public_header_files'])
36
+ spec.public_header_files = current_public_header_files + [
37
+ # Generated specs
38
+ "nitrogen/generated/shared/**/*.{h,hpp}",
39
+ # Swift to C++ bridging helpers
40
+ "nitrogen/generated/ios/EnnioCore-Swift-Cxx-Bridge.hpp"
41
+ ]
42
+
43
+ current_private_header_files = Array(spec.attributes_hash['private_header_files'])
44
+ spec.private_header_files = current_private_header_files + [
45
+ # iOS specific specs
46
+ "nitrogen/generated/ios/c++/**/*.{h,hpp}",
47
+ # Views are framework-specific and should be private
48
+ "nitrogen/generated/shared/**/views/**/*"
49
+ ]
50
+
51
+ current_pod_target_xcconfig = spec.attributes_hash['pod_target_xcconfig'] || {}
52
+ spec.pod_target_xcconfig = current_pod_target_xcconfig.merge({
53
+ # Use C++ 20
54
+ "CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
55
+ # Enables C++ <-> Swift interop (by default it's only ObjC)
56
+ "SWIFT_OBJC_INTEROP_MODE" => "objcxx",
57
+ # Enables stricter modular headers
58
+ "DEFINES_MODULE" => "YES",
59
+ # Disable auto-generated ObjC header for Swift (Static linkage on Xcode 26.4 breaks here)
60
+ "SWIFT_INSTALL_OBJC_HEADER" => "NO",
61
+ })
62
+ end