react-native-list 1.0.0 → 2.0.0-alpha.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 (200) hide show
  1. package/README.md +190 -32
  2. package/ReactNativeList.podspec +39 -0
  3. package/android/CMakeLists.txt +48 -0
  4. package/android/build.gradle +151 -0
  5. package/android/fix-prefab.gradle +51 -0
  6. package/android/gradle.properties +5 -0
  7. package/android/src/main/AndroidManifest.xml +2 -0
  8. package/android/src/main/cpp/JHybridUiListModule.cpp +192 -0
  9. package/android/src/main/cpp/JHybridUiListModule.h +50 -0
  10. package/android/src/main/cpp/cpp-adapter.cpp +12 -0
  11. package/android/src/main/java/com/hannojg/reactnativelist/ReactNativeListPackage.kt +27 -0
  12. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridNativeListDataSource.kt +146 -0
  13. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridNativeListLayout.kt +86 -0
  14. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridUiListModule.kt +116 -0
  15. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridUiListView.kt +410 -0
  16. package/android/src/main/java/com/margelo/nitro/reactnativelist/HybridViewHolder.kt +9 -0
  17. package/android/src/main/java/com/margelo/nitro/reactnativelist/NativeListAdapter.kt +217 -0
  18. package/ios/DataSource/HybridNativeListDataSource.swift +213 -0
  19. package/ios/HybridObjects/HybridUiListModule.swift +49 -0
  20. package/ios/HybridObjects/HybridViewHolder.swift +16 -0
  21. package/ios/Layout/HybridNativeListLayout.swift +128 -0
  22. package/ios/Utils/ErrorUtils.h +26 -0
  23. package/ios/Utils/HybridIOSWorkletsModuleProxyHolder.swift +10 -0
  24. package/ios/Utils/SurfaceHelper.h +20 -0
  25. package/ios/Utils/SurfaceHelper.mm +144 -0
  26. package/ios/Utils/SurfacePresenterRegistry.h +17 -0
  27. package/ios/Utils/SurfacePresenterRegistry.m +31 -0
  28. package/ios/Utils/TurboModuleInstaller.h +18 -0
  29. package/ios/Utils/TurboModuleInstaller.mm +267 -0
  30. package/ios/Views/HostCell.swift +216 -0
  31. package/ios/Views/HybridUiListView.swift +695 -0
  32. package/metro/RendererProxyThreadSwitch.js +66 -0
  33. package/metro-config.d.ts +1 -0
  34. package/metro-config.js +52 -0
  35. package/nitro.json +47 -0
  36. package/nitrogen/generated/.gitattributes +1 -0
  37. package/nitrogen/generated/android/ReactNativeList+autolinking.cmake +99 -0
  38. package/nitrogen/generated/android/ReactNativeList+autolinking.gradle +27 -0
  39. package/nitrogen/generated/android/ReactNativeListOnLoad.cpp +156 -0
  40. package/nitrogen/generated/android/ReactNativeListOnLoad.hpp +34 -0
  41. package/nitrogen/generated/android/c++/JFunc_bool_NativeListItem_NativeListItem.hpp +83 -0
  42. package/nitrogen/generated/android/c++/JFunc_bool_double_NativeListItem_double.hpp +83 -0
  43. package/nitrogen/generated/android/c++/JFunc_double_std__string.hpp +78 -0
  44. package/nitrogen/generated/android/c++/JHybridIOSWorkletsModuleProxyHolderSpec.cpp +49 -0
  45. package/nitrogen/generated/android/c++/JHybridIOSWorkletsModuleProxyHolderSpec.hpp +63 -0
  46. package/nitrogen/generated/android/c++/JHybridNativeLinearListLayoutSpec.cpp +63 -0
  47. package/nitrogen/generated/android/c++/JHybridNativeLinearListLayoutSpec.hpp +65 -0
  48. package/nitrogen/generated/android/c++/JHybridNativeListDataSourceSpec.cpp +101 -0
  49. package/nitrogen/generated/android/c++/JHybridNativeListDataSourceSpec.hpp +70 -0
  50. package/nitrogen/generated/android/c++/JHybridNativeListLayoutSpec.cpp +49 -0
  51. package/nitrogen/generated/android/c++/JHybridNativeListLayoutSpec.hpp +63 -0
  52. package/nitrogen/generated/android/c++/JHybridUiListModuleSpec.cpp +65 -0
  53. package/nitrogen/generated/android/c++/JHybridUiListModuleSpec.hpp +64 -0
  54. package/nitrogen/generated/android/c++/JHybridUiListViewSpec.cpp +92 -0
  55. package/nitrogen/generated/android/c++/JHybridUiListViewSpec.hpp +67 -0
  56. package/nitrogen/generated/android/c++/JHybridViewHolderSpec.cpp +49 -0
  57. package/nitrogen/generated/android/c++/JHybridViewHolderSpec.hpp +63 -0
  58. package/nitrogen/generated/android/c++/JNativeItemSizeEstimate.hpp +61 -0
  59. package/nitrogen/generated/android/c++/JNativeLinearListLayoutConfig.hpp +81 -0
  60. package/nitrogen/generated/android/c++/JNativeLinearListLayoutIOSConfig.hpp +59 -0
  61. package/nitrogen/generated/android/c++/JNativeListItem.hpp +76 -0
  62. package/nitrogen/generated/android/c++/JVariant_NullType_HybridIOSWorkletsModuleProxyHolderSpec.cpp +26 -0
  63. package/nitrogen/generated/android/c++/JVariant_NullType_HybridIOSWorkletsModuleProxyHolderSpec.hpp +72 -0
  64. package/nitrogen/generated/android/c++/views/JHybridUiListViewStateUpdater.cpp +53 -0
  65. package/nitrogen/generated/android/c++/views/JHybridUiListViewStateUpdater.hpp +49 -0
  66. package/nitrogen/generated/android/c++/views/JHybridViewHolderStateUpdater.cpp +53 -0
  67. package/nitrogen/generated/android/c++/views/JHybridViewHolderStateUpdater.hpp +49 -0
  68. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Func_bool_NativeListItem_NativeListItem.kt +80 -0
  69. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Func_bool_double_NativeListItem_double.kt +80 -0
  70. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Func_double_std__string.kt +80 -0
  71. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridIOSWorkletsModuleProxyHolderSpec.kt +52 -0
  72. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridNativeLinearListLayoutSpec.kt +54 -0
  73. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridNativeListDataSourceSpec.kt +87 -0
  74. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridNativeListLayoutSpec.kt +52 -0
  75. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridUiListModuleSpec.kt +59 -0
  76. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridUiListViewSpec.kt +76 -0
  77. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/HybridViewHolderSpec.kt +53 -0
  78. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeItemSizeEstimate.kt +56 -0
  79. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeLinearListLayoutConfig.kt +76 -0
  80. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeLinearListLayoutIOSConfig.kt +51 -0
  81. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/NativeListItem.kt +71 -0
  82. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/ReactNativeListOnLoad.kt +35 -0
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/Variant_NullType_HybridIOSWorkletsModuleProxyHolderSpec.kt +62 -0
  84. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridUiListViewManager.kt +80 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridUiListViewStateUpdater.kt +23 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridViewHolderManager.kt +80 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativelist/views/HybridViewHolderStateUpdater.kt +23 -0
  88. package/nitrogen/generated/ios/ReactNativeList+autolinking.rb +62 -0
  89. package/nitrogen/generated/ios/ReactNativeList-Swift-Cxx-Bridge.cpp +162 -0
  90. package/nitrogen/generated/ios/ReactNativeList-Swift-Cxx-Bridge.hpp +368 -0
  91. package/nitrogen/generated/ios/ReactNativeList-Swift-Cxx-Umbrella.hpp +92 -0
  92. package/nitrogen/generated/ios/ReactNativeListAutolinking.mm +83 -0
  93. package/nitrogen/generated/ios/ReactNativeListAutolinking.swift +86 -0
  94. package/nitrogen/generated/ios/c++/HybridIOSWorkletsModuleProxyHolderSpecSwift.cpp +11 -0
  95. package/nitrogen/generated/ios/c++/HybridIOSWorkletsModuleProxyHolderSpecSwift.hpp +75 -0
  96. package/nitrogen/generated/ios/c++/HybridNativeLinearListLayoutSpecSwift.cpp +11 -0
  97. package/nitrogen/generated/ios/c++/HybridNativeLinearListLayoutSpecSwift.hpp +92 -0
  98. package/nitrogen/generated/ios/c++/HybridNativeListDataSourceSpecSwift.cpp +11 -0
  99. package/nitrogen/generated/ios/c++/HybridNativeListDataSourceSpecSwift.hpp +132 -0
  100. package/nitrogen/generated/ios/c++/HybridNativeListLayoutSpecSwift.cpp +11 -0
  101. package/nitrogen/generated/ios/c++/HybridNativeListLayoutSpecSwift.hpp +75 -0
  102. package/nitrogen/generated/ios/c++/HybridUiListModuleSpecSwift.cpp +11 -0
  103. package/nitrogen/generated/ios/c++/HybridUiListModuleSpecSwift.hpp +93 -0
  104. package/nitrogen/generated/ios/c++/HybridUiListViewSpecSwift.cpp +11 -0
  105. package/nitrogen/generated/ios/c++/HybridUiListViewSpecSwift.hpp +121 -0
  106. package/nitrogen/generated/ios/c++/HybridViewHolderSpecSwift.cpp +11 -0
  107. package/nitrogen/generated/ios/c++/HybridViewHolderSpecSwift.hpp +75 -0
  108. package/nitrogen/generated/ios/c++/views/HybridUiListViewComponent.mm +118 -0
  109. package/nitrogen/generated/ios/c++/views/HybridViewHolderComponent.mm +118 -0
  110. package/nitrogen/generated/ios/swift/Func_bool_NativeListItem_NativeListItem.swift +47 -0
  111. package/nitrogen/generated/ios/swift/Func_bool_double_NativeListItem_double.swift +47 -0
  112. package/nitrogen/generated/ios/swift/Func_double_std__string.swift +47 -0
  113. package/nitrogen/generated/ios/swift/HybridIOSWorkletsModuleProxyHolderSpec.swift +55 -0
  114. package/nitrogen/generated/ios/swift/HybridIOSWorkletsModuleProxyHolderSpec_cxx.swift +128 -0
  115. package/nitrogen/generated/ios/swift/HybridNativeLinearListLayoutSpec.swift +55 -0
  116. package/nitrogen/generated/ios/swift/HybridNativeLinearListLayoutSpec_cxx.swift +140 -0
  117. package/nitrogen/generated/ios/swift/HybridNativeListDataSourceSpec.swift +62 -0
  118. package/nitrogen/generated/ios/swift/HybridNativeListDataSourceSpec_cxx.swift +222 -0
  119. package/nitrogen/generated/ios/swift/HybridNativeListLayoutSpec.swift +55 -0
  120. package/nitrogen/generated/ios/swift/HybridNativeListLayoutSpec_cxx.swift +128 -0
  121. package/nitrogen/generated/ios/swift/HybridUiListModuleSpec.swift +56 -0
  122. package/nitrogen/generated/ios/swift/HybridUiListModuleSpec_cxx.swift +175 -0
  123. package/nitrogen/generated/ios/swift/HybridUiListViewSpec.swift +59 -0
  124. package/nitrogen/generated/ios/swift/HybridUiListViewSpec_cxx.swift +227 -0
  125. package/nitrogen/generated/ios/swift/HybridViewHolderSpec.swift +55 -0
  126. package/nitrogen/generated/ios/swift/HybridViewHolderSpec_cxx.swift +147 -0
  127. package/nitrogen/generated/ios/swift/NativeItemSizeEstimate.swift +60 -0
  128. package/nitrogen/generated/ios/swift/NativeLinearListLayoutConfig.swift +60 -0
  129. package/nitrogen/generated/ios/swift/NativeLinearListLayoutIOSConfig.swift +35 -0
  130. package/nitrogen/generated/ios/swift/NativeListItem.swift +75 -0
  131. package/nitrogen/generated/ios/swift/Variant_NullType__any_HybridIOSWorkletsModuleProxyHolderSpec_.swift +30 -0
  132. package/nitrogen/generated/shared/c++/HybridIOSWorkletsModuleProxyHolderSpec.cpp +21 -0
  133. package/nitrogen/generated/shared/c++/HybridIOSWorkletsModuleProxyHolderSpec.hpp +62 -0
  134. package/nitrogen/generated/shared/c++/HybridNativeLinearListLayoutSpec.cpp +22 -0
  135. package/nitrogen/generated/shared/c++/HybridNativeLinearListLayoutSpec.hpp +67 -0
  136. package/nitrogen/generated/shared/c++/HybridNativeListDataSourceSpec.cpp +28 -0
  137. package/nitrogen/generated/shared/c++/HybridNativeListDataSourceSpec.hpp +72 -0
  138. package/nitrogen/generated/shared/c++/HybridNativeListLayoutSpec.cpp +21 -0
  139. package/nitrogen/generated/shared/c++/HybridNativeListLayoutSpec.hpp +62 -0
  140. package/nitrogen/generated/shared/c++/HybridUiListModuleSpec.cpp +22 -0
  141. package/nitrogen/generated/shared/c++/HybridUiListModuleSpec.hpp +68 -0
  142. package/nitrogen/generated/shared/c++/HybridUiListViewSpec.cpp +25 -0
  143. package/nitrogen/generated/shared/c++/HybridUiListViewSpec.hpp +79 -0
  144. package/nitrogen/generated/shared/c++/HybridUiManagerHelperSpec.cpp +23 -0
  145. package/nitrogen/generated/shared/c++/HybridUiManagerHelperSpec.hpp +65 -0
  146. package/nitrogen/generated/shared/c++/HybridViewHolderSpec.cpp +21 -0
  147. package/nitrogen/generated/shared/c++/HybridViewHolderSpec.hpp +62 -0
  148. package/nitrogen/generated/shared/c++/NativeItemSizeEstimate.hpp +87 -0
  149. package/nitrogen/generated/shared/c++/NativeLinearListLayoutConfig.hpp +105 -0
  150. package/nitrogen/generated/shared/c++/NativeLinearListLayoutIOSConfig.hpp +85 -0
  151. package/nitrogen/generated/shared/c++/NativeListItem.hpp +101 -0
  152. package/nitrogen/generated/shared/c++/views/HybridUiListViewComponent.cpp +72 -0
  153. package/nitrogen/generated/shared/c++/views/HybridUiListViewComponent.hpp +109 -0
  154. package/nitrogen/generated/shared/c++/views/HybridViewHolderComponent.cpp +72 -0
  155. package/nitrogen/generated/shared/c++/views/HybridViewHolderComponent.hpp +109 -0
  156. package/nitrogen/generated/shared/json/UiListViewConfig.json +9 -0
  157. package/nitrogen/generated/shared/json/ViewHolderConfig.json +9 -0
  158. package/package.json +152 -5
  159. package/react-native.config.js +16 -0
  160. package/src/ListDataSource.ts +232 -0
  161. package/src/ListLayout.ts +95 -0
  162. package/src/UiListModule.ts +5 -0
  163. package/src/hooks/useChangeEffect.ts +50 -0
  164. package/src/index.tsx +49 -0
  165. package/src/privateGlobals.ts +20 -0
  166. package/src/renderer/fabric/RenderHelper.ts +29 -0
  167. package/src/renderer/fabric/UiManagerHelper.ts +5 -0
  168. package/src/renderer/react/ReactFabricMirror.bundle.js +1984 -0
  169. package/src/renderer/react/ReactFabricMirror.ts +766 -0
  170. package/src/renderer/react/ReactFabricRenderer.ts +11 -0
  171. package/src/specs/IOSWorkletsModuleProxyHolder.nitro.ts +6 -0
  172. package/src/specs/NativeLinearListLayout.nitro.ts +23 -0
  173. package/src/specs/NativeListDataSource.nitro.ts +28 -0
  174. package/src/specs/NativeListLayout.nitro.ts +6 -0
  175. package/src/specs/UIListModule.nitro.ts +13 -0
  176. package/src/specs/UIManagerHelper.nitro.ts +34 -0
  177. package/src/specs/UiListView.nitro.ts +31 -0
  178. package/src/specs/ViewHolder.nitro.ts +11 -0
  179. package/src/views/List.tsx +525 -0
  180. package/src/views/UiListHostComponent.ts +8 -0
  181. package/FillRateHelper.js +0 -179
  182. package/FlatList.js +0 -494
  183. package/LICENSE.md +0 -31
  184. package/ListView/__mocks__/ListViewMock.js +0 -55
  185. package/MetroListView.js +0 -166
  186. package/SectionList.js +0 -291
  187. package/ViewabilityHelper.js +0 -260
  188. package/VirtualizeUtils.js +0 -163
  189. package/VirtualizedList.js +0 -861
  190. package/VirtualizedSectionList.js +0 -397
  191. package/__flowtests__/FlatList-flowtest.js +0 -90
  192. package/__flowtests__/SectionList-flowtest.js +0 -89
  193. package/__tests__/FillRateHelper-test.js +0 -106
  194. package/__tests__/FlatList-test.js +0 -64
  195. package/__tests__/SectionList-test.js +0 -67
  196. package/__tests__/ViewabilityHelper-test.js +0 -359
  197. package/__tests__/VirtualizeUtils-test.js +0 -74
  198. package/__tests__/__snapshots__/FlatList-test.js.snap +0 -251
  199. package/__tests__/__snapshots__/SectionList-test.js.snap +0 -283
  200. package/index.js +0 -5
@@ -0,0 +1,267 @@
1
+ #import "TurboModuleInstaller.h"
2
+ #import "SurfacePresenterRegistry.h"
3
+ #import "WorkletsUiCallInvoker.hpp"
4
+ #import "ErrorUtils.h"
5
+ #import "HybridUiManagerHelper.hpp"
6
+
7
+ #import <React/RCTBridge+Private.h>
8
+ #import <React/RCTBridge.h>
9
+ #import <React/RCTBridgeModule.h>
10
+ #import <React/RCTBridgeModuleDecorator.h>
11
+ #import <React/RCTBridgeProxy.h>
12
+ #import <React/RCTBridgeProxy+Cxx.h>
13
+ #import <React/RCTScheduler.h>
14
+ #import <React/RCTSurfacePresenter.h>
15
+ #import <ReactCommon/CallInvoker.h>
16
+ #import <ReactCommon/RCTTurboModuleManager.h>
17
+ #import <worklets/apple/AssertJavaScriptQueue.h>
18
+ #import <worklets/apple/WorkletsModule.h>
19
+ #import <NitroModules/NitroLogger.hpp>
20
+
21
+ #include <jsi/jsi.h>
22
+ #include <react/utils/jsi-utils.h>
23
+
24
+ using namespace facebook;
25
+ using namespace facebook::react;
26
+ using namespace worklets;
27
+
28
+ namespace {
29
+
30
+ static RCTTurboModuleManager *sUiTurboModuleManager = nil;
31
+ static uint64_t sInstalledRuntimeId = 0;
32
+ static BOOL sHasInstalledRuntime = NO;
33
+ static std::shared_ptr<facebook::react::CallInvoker> uiCallInvoker = nullptr;
34
+
35
+ } // namespace
36
+
37
+ @interface HybridWorkletsModuleProxyHolderBox ()
38
+
39
+ - (instancetype)initWithWorkletsModuleProxy:(std::shared_ptr<WorkletsModuleProxy>)workletsModuleProxy;
40
+ - (std::shared_ptr<WorkletsModuleProxy>)workletsModuleProxy;
41
+
42
+ @end
43
+
44
+ @implementation HybridWorkletsModuleProxyHolderBox {
45
+ std::shared_ptr<WorkletsModuleProxy> _workletsModuleProxy;
46
+ }
47
+
48
+ - (instancetype)initWithWorkletsModuleProxy:(std::shared_ptr<WorkletsModuleProxy>)workletsModuleProxy
49
+ {
50
+ self = [super init];
51
+ if (self != nil) {
52
+ _workletsModuleProxy = std::move(workletsModuleProxy);
53
+ }
54
+ return self;
55
+ }
56
+
57
+ - (std::shared_ptr<WorkletsModuleProxy>)workletsModuleProxy
58
+ {
59
+ return _workletsModuleProxy;
60
+ }
61
+
62
+ @end
63
+
64
+ @implementation TurboModuleInstaller
65
+
66
+ + (nullable HybridWorkletsModuleProxyHolderBox *)createWorkletsModuleProxyHolder:
67
+ (NSError *__autoreleasing _Nullable * _Nullable)error
68
+ {
69
+ @try {
70
+ RCTBridge *bridge = [RCTBridge currentBridge];
71
+ if (bridge == nil) {
72
+ assignError(error, @"Could not access RCTBridge.currentBridge.");
73
+ return nil;
74
+ }
75
+
76
+ if (!IsJavaScriptQueue()) {
77
+ assignError(error, @"iosGetWorkletsModule() must run on the JavaScript queue.");
78
+ return nil;
79
+ }
80
+
81
+ // Prime the registry module while we're on the JS queue.
82
+ id registryModule = [bridge moduleForClass:SurfacePresenterRegistry.class];
83
+ if (registryModule == nil) {
84
+ assignError(error, @"Could not initialize HybridUiListSurfacePresenterRegistry.");
85
+ return nil;
86
+ }
87
+ if ([SurfacePresenterRegistry currentSurfacePresenter] == nil) {
88
+ assignError(error, @"SurfacePresenter was not injected into HybridUiListSurfacePresenterRegistry.");
89
+ return nil;
90
+ }
91
+
92
+ WorkletsModule *workletsModule = [bridge moduleForClass:WorkletsModule.class];
93
+ if (workletsModule == nil) {
94
+ assignError(error, @"WorkletsModule is not available from the bridge.");
95
+ return nil;
96
+ }
97
+
98
+ std::shared_ptr<WorkletsModuleProxy> workletsModuleProxy = [workletsModule getWorkletsModuleProxy];
99
+ if (workletsModuleProxy == nullptr) {
100
+ assignError(error, @"Could not access WorkletsModuleProxy.");
101
+ return nil;
102
+ }
103
+
104
+ return [[HybridWorkletsModuleProxyHolderBox alloc] initWithWorkletsModuleProxy:std::move(workletsModuleProxy)];
105
+ } @catch (NSException *exception) {
106
+ assignError(error, [NSString stringWithFormat:@"Failed to create WorkletsModuleProxy holder: %@", exception.reason]);
107
+ return nil;
108
+ }
109
+ }
110
+
111
+ + (BOOL)installNativeModuleProxyInUIRuntimeWithHolder:(HybridWorkletsModuleProxyHolderBox *)holder
112
+ error:(NSError *__autoreleasing _Nullable * _Nullable)error
113
+ {
114
+ @try {
115
+ margelo::nitro::Logger::log(margelo::nitro::LogLevel::Debug, "TurboModuleInstaller", "installNativeModuleProxyInUIRuntime()");
116
+ if (holder == nil) {
117
+ assignError(error, @"Expected non-null IOSWorkletsModuleProxyHolder.");
118
+ return NO;
119
+ }
120
+
121
+ std::shared_ptr<WorkletsModuleProxy> workletsModuleProxy = [holder workletsModuleProxy];
122
+ if (workletsModuleProxy == nullptr) {
123
+ assignError(error, @"IOSWorkletsModuleProxyHolder does not contain a WorkletsModuleProxy.");
124
+ return NO;
125
+ }
126
+
127
+ std::shared_ptr<UIScheduler> uiScheduler = workletsModuleProxy->getUIScheduler();
128
+ if (uiScheduler == nullptr) {
129
+ assignError(error, @"Could not access UIScheduler from WorkletsModuleProxy.");
130
+ return NO;
131
+ }
132
+
133
+ std::shared_ptr<WorkletRuntime> uiWorkletRuntime = workletsModuleProxy->getUIWorkletRuntime();
134
+ if (uiWorkletRuntime == nullptr) {
135
+ assignError(error, @"Could not access UIWorkletRuntime from WorkletsModuleProxy.");
136
+ return NO;
137
+ }
138
+
139
+ uint64_t runtimeId = uiWorkletRuntime->getRuntimeId();
140
+ if (sHasInstalledRuntime && sInstalledRuntimeId == runtimeId) {
141
+ return YES;
142
+ }
143
+
144
+ bool hasNativeModuleProxy = false;
145
+ uiWorkletRuntime->runSync([&](jsi::Runtime &runtime) {
146
+ // We first have to set this to be bridgeless too
147
+ // TODO: upstream this to worklets to set this for their runtime if the JS runtime is bridgeless
148
+ // Note: do i want to make this xplat? have the same code dupe in android
149
+ if (!runtime.global().hasProperty(runtime, "RN$Bridgeless")) {
150
+ react::defineReadOnlyGlobal(runtime, "RN$Bridgeless", jsi::Value(true));
151
+ }
152
+
153
+ jsi::Value proxy = runtime.global().getProperty(runtime, "nativeModuleProxy");
154
+ hasNativeModuleProxy = !proxy.isUndefined() && !proxy.isNull();
155
+ });
156
+ if (hasNativeModuleProxy) {
157
+ sHasInstalledRuntime = YES;
158
+ sInstalledRuntimeId = runtimeId;
159
+ return YES;
160
+ }
161
+
162
+ RCTBridge *bridge = [RCTBridge currentBridge];
163
+ if (bridge == nil) {
164
+ assignError(error, @"Could not access RCTBridge.currentBridge.");
165
+ return NO;
166
+ }
167
+
168
+ RCTModuleRegistry *moduleRegistry = [bridge moduleRegistry];
169
+ if (moduleRegistry == nil) {
170
+ assignError(error, @"Could not access moduleRegistry from the bridge.");
171
+ return NO;
172
+ }
173
+
174
+ id turboModuleRegistry = [moduleRegistry valueForKey:@"_turboModuleRegistry"];
175
+ if (![turboModuleRegistry isKindOfClass:[RCTTurboModuleManager class]]) {
176
+ assignError(error, @"moduleRegistry does not contain an active RCTTurboModuleManager.");
177
+ return NO;
178
+ }
179
+
180
+ RCTTurboModuleManager *rootTurboModuleManager = (RCTTurboModuleManager *)turboModuleRegistry;
181
+ id<RCTTurboModuleManagerDelegate> delegate = [rootTurboModuleManager valueForKey:@"_delegate"];
182
+ if (delegate == nil) {
183
+ assignError(error, @"Could not access RCTTurboModuleManager delegate.");
184
+ return NO;
185
+ }
186
+
187
+ RCTBridgeProxy *bridgeProxy = [rootTurboModuleManager valueForKey:@"_bridgeProxy"];
188
+ if (bridgeProxy == nil && [bridge isKindOfClass:[RCTBridgeProxy class]]) {
189
+ bridgeProxy = (RCTBridgeProxy *)bridge;
190
+ }
191
+ if (bridgeProxy == nil) {
192
+ assignError(error, @"Could not access RCTBridgeProxy.");
193
+ return NO;
194
+ }
195
+
196
+ RCTBridgeModuleDecorator *bridgeModuleDecorator = [rootTurboModuleManager valueForKey:@"_bridgeModuleDecorator"];
197
+ if (bridgeModuleDecorator == nil) {
198
+ assignError(error, @"Could not access RCTBridgeModuleDecorator.");
199
+ return NO;
200
+ }
201
+
202
+ uiCallInvoker = std::make_shared<margelo::nitro::reactnativelist::WorkletsUiCallInvoker>(uiScheduler, uiWorkletRuntime, []() {
203
+ return [NSThread isMainThread];
204
+ });
205
+
206
+ RCTTurboModuleManager *uiTurboModuleManager = [[RCTTurboModuleManager alloc] initWithBridgeProxy:bridgeProxy
207
+ bridgeModuleDecorator:bridgeModuleDecorator
208
+ delegate:delegate
209
+ jsInvoker:uiCallInvoker];
210
+ if (uiTurboModuleManager == nil) {
211
+ assignError(error, @"Failed to create a UI-runtime RCTTurboModuleManager.");
212
+ return NO;
213
+ }
214
+
215
+ margelo::nitro::Logger::log(margelo::nitro::LogLevel::Debug, "TurboModuleInstaller", "schedule install JSI bindings!");
216
+ uiWorkletRuntime->runSync([uiTurboModuleManager](jsi::Runtime &runtime) {
217
+ [uiTurboModuleManager installJSBindings:runtime];
218
+ margelo::nitro::Logger::log(margelo::nitro::LogLevel::Debug, "TurboModuleInstaller", "installed JSI bindings!");
219
+ });
220
+
221
+ sUiTurboModuleManager = uiTurboModuleManager;
222
+ sHasInstalledRuntime = YES;
223
+ sInstalledRuntimeId = runtimeId;
224
+ return YES;
225
+ } @catch (NSException *exception) {
226
+ assignError(error, [NSString stringWithFormat:@"TurboModule install failed with NSException: %@", exception.reason]);
227
+ return NO;
228
+ }
229
+ }
230
+
231
+ + (BOOL)setupEventInterceptor:(NSError *__autoreleasing _Nullable * _Nullable)error {
232
+ @try {
233
+ if (uiCallInvoker == nullptr) {
234
+ assignError(error, @"UI CallInvoker must be initialized before setting up event interceptor.");
235
+ return NO;
236
+ }
237
+
238
+ id surfacePresenterObj = [SurfacePresenterRegistry currentSurfacePresenter];
239
+ if (surfacePresenterObj == nil) {
240
+ assignError(error, @"SurfacePresenter from SurfacePresenterRegistry was null!");
241
+ return NO;
242
+ }
243
+
244
+ if (![surfacePresenterObj isKindOfClass:[RCTSurfacePresenter class]]) {
245
+ assignError(error, @"SurfacePresenterRegistry did not return an RCTSurfacePresenter instance.");
246
+ return NO;
247
+ }
248
+
249
+ RCTSurfacePresenter *surfacePresenter = (RCTSurfacePresenter *)surfacePresenterObj;
250
+ RCTScheduler *scheduler = surfacePresenter.scheduler;
251
+ if (scheduler == nil) {
252
+ assignError(error, @"Could not access an active RCTScheduler from the current RCTSurfacePresenter.");
253
+ return NO;
254
+ }
255
+
256
+ std::shared_ptr<EventListener> eventInterceptor =
257
+ margelo::nitro::reactnativelist::HybridUiManagerHelper::createEventInterceptor(uiCallInvoker);
258
+ [scheduler addEventListener:eventInterceptor];
259
+
260
+ return YES;
261
+ } @catch (NSException *exception) {
262
+ assignError(error, [NSString stringWithFormat:@"Event interceptor setup failed with NSException: %@", exception.reason]);
263
+ return NO;
264
+ }
265
+ }
266
+
267
+ @end
@@ -0,0 +1,216 @@
1
+ import UIKit
2
+
3
+ final class HostCell: UICollectionViewCell {
4
+
5
+ private var hostedView: UIView?
6
+ private var topConstraint: NSLayoutConstraint?
7
+ private var leadingConstraint: NSLayoutConstraint?
8
+ private var widthConstraint: NSLayoutConstraint?
9
+ private var heightConstraint: NSLayoutConstraint?
10
+
11
+ var reactTag: Int?
12
+ var itemKey: String?
13
+ var itemType: String?
14
+ var hostedContentView: UIView? {
15
+ return hostedView
16
+ }
17
+
18
+ func install(
19
+ view: UIView,
20
+ contentSize: CGSize,
21
+ contentInset: UIEdgeInsets,
22
+ itemKey: String,
23
+ itemType: String
24
+ ) {
25
+ if let currentHostedView = hostedView {
26
+ let isCurrentViewOwnedByCell = currentHostedView.superview === contentView
27
+ if isCurrentViewOwnedByCell {
28
+ deactivateInstalledConstraints(for: currentHostedView)
29
+ currentHostedView.removeFromSuperview()
30
+ }
31
+ }
32
+
33
+ deactivateInstalledConstraints(for: view)
34
+ view.removeFromSuperview()
35
+
36
+ hostedView = view
37
+ self.itemKey = itemKey
38
+ self.itemType = itemType
39
+
40
+ view.translatesAutoresizingMaskIntoConstraints = false
41
+ contentView.addSubview(view)
42
+
43
+ let widthConstraint = view.widthAnchor.constraint(equalToConstant: contentSize.width)
44
+ let heightConstraint = view.heightAnchor.constraint(equalToConstant: contentSize.height)
45
+ let topConstraint = view.topAnchor.constraint(
46
+ equalTo: contentView.topAnchor,
47
+ constant: contentInset.top
48
+ )
49
+ let leadingConstraint = view.leadingAnchor.constraint(
50
+ equalTo: contentView.leadingAnchor,
51
+ constant: contentInset.left
52
+ )
53
+ self.topConstraint = topConstraint
54
+ self.leadingConstraint = leadingConstraint
55
+ self.widthConstraint = widthConstraint
56
+ self.heightConstraint = heightConstraint
57
+
58
+ NSLayoutConstraint.activate([
59
+ topConstraint,
60
+ leadingConstraint,
61
+ widthConstraint,
62
+ heightConstraint,
63
+ ])
64
+ }
65
+
66
+ func bind(itemKey: String) {
67
+ self.itemKey = itemKey
68
+ }
69
+
70
+ func prepareForMeasurement(width: CGFloat, height: CGFloat?) {
71
+ // Text-like rows need a concrete width to wrap before we can measure natural height.
72
+ setWidthConstraint(width)
73
+
74
+ if let height {
75
+ setHeightConstraint(height)
76
+ } else {
77
+ deactivateHeightConstraint()
78
+ }
79
+ }
80
+
81
+ func updateContentLayout(contentSize: CGSize, contentInset: UIEdgeInsets) {
82
+ setTopConstraint(contentInset.top)
83
+ setLeadingConstraint(contentInset.left)
84
+ setWidthConstraint(contentSize.width)
85
+ setHeightConstraint(contentSize.height)
86
+ }
87
+
88
+ func detachHostedView() {
89
+ if let hostedView {
90
+ let isHostedViewOwnedByCell = hostedView.superview === contentView
91
+ if isHostedViewOwnedByCell {
92
+ deactivateInstalledConstraints(for: hostedView)
93
+ hostedView.removeFromSuperview()
94
+ }
95
+ }
96
+
97
+ hostedView = nil
98
+ reactTag = nil
99
+ itemKey = nil
100
+ itemType = nil
101
+ topConstraint = nil
102
+ leadingConstraint = nil
103
+ widthConstraint = nil
104
+ heightConstraint = nil
105
+ }
106
+
107
+ override func prepareForReuse() {
108
+ super.prepareForReuse()
109
+ itemKey = nil
110
+ if let hostedView {
111
+ contentView.bringSubviewToFront(hostedView)
112
+ }
113
+ }
114
+
115
+ private func deactivateInstalledConstraints(for view: UIView) {
116
+ let localConstraints = view.constraints.filter { constraint in
117
+ let isWidthConstraint = constraint.firstAttribute == .width
118
+ let isHeightConstraint = constraint.firstAttribute == .height
119
+ let isSizeConstraint = isWidthConstraint || isHeightConstraint
120
+ let firstView = constraint.firstItem as? UIView
121
+ let isOwnedByView = firstView === view
122
+ let isLocalConstraint = constraint.secondItem == nil
123
+ return isSizeConstraint && isOwnedByView && isLocalConstraint
124
+ }
125
+ NSLayoutConstraint.deactivate(localConstraints)
126
+
127
+ guard let superview = view.superview else { return }
128
+
129
+ let parentConstraints = superview.constraints.filter { constraint in
130
+ let firstView = constraint.firstItem as? UIView
131
+ let secondView = constraint.secondItem as? UIView
132
+ let usesFirstView = firstView === view
133
+ let usesSecondView = secondView === view
134
+ return usesFirstView || usesSecondView
135
+ }
136
+ NSLayoutConstraint.deactivate(parentConstraints)
137
+ }
138
+
139
+ private func setWidthConstraint(_ width: CGFloat) {
140
+ if let widthConstraint {
141
+ widthConstraint.constant = width
142
+ if !widthConstraint.isActive {
143
+ widthConstraint.isActive = true
144
+ }
145
+ return
146
+ }
147
+
148
+ guard let hostedView else { return }
149
+ let widthConstraint = hostedView.widthAnchor.constraint(equalToConstant: width)
150
+ self.widthConstraint = widthConstraint
151
+ widthConstraint.isActive = true
152
+ }
153
+
154
+ private func setTopConstraint(_ topInset: CGFloat) {
155
+ if let topConstraint {
156
+ topConstraint.constant = topInset
157
+ if !topConstraint.isActive {
158
+ topConstraint.isActive = true
159
+ }
160
+ return
161
+ }
162
+
163
+ guard let hostedView else { return }
164
+ let topConstraint = hostedView.topAnchor.constraint(
165
+ equalTo: contentView.topAnchor,
166
+ constant: topInset
167
+ )
168
+ self.topConstraint = topConstraint
169
+ topConstraint.isActive = true
170
+ }
171
+
172
+ private func setLeadingConstraint(_ leadingInset: CGFloat) {
173
+ if let leadingConstraint {
174
+ leadingConstraint.constant = leadingInset
175
+ if !leadingConstraint.isActive {
176
+ leadingConstraint.isActive = true
177
+ }
178
+ return
179
+ }
180
+
181
+ guard let hostedView else { return }
182
+ let leadingConstraint = hostedView.leadingAnchor.constraint(
183
+ equalTo: contentView.leadingAnchor,
184
+ constant: leadingInset
185
+ )
186
+ self.leadingConstraint = leadingConstraint
187
+ leadingConstraint.isActive = true
188
+ }
189
+
190
+ private func setHeightConstraint(_ height: CGFloat) {
191
+ if let heightConstraint {
192
+ heightConstraint.constant = height
193
+ if !heightConstraint.isActive {
194
+ heightConstraint.isActive = true
195
+ }
196
+ return
197
+ }
198
+
199
+ guard let hostedView else { return }
200
+ let heightConstraint = hostedView.heightAnchor.constraint(equalToConstant: height)
201
+ self.heightConstraint = heightConstraint
202
+ heightConstraint.isActive = true
203
+ }
204
+
205
+ private func deactivateWidthConstraint() {
206
+ guard let widthConstraint else { return }
207
+ widthConstraint.isActive = false
208
+ self.widthConstraint = nil
209
+ }
210
+
211
+ private func deactivateHeightConstraint() {
212
+ guard let heightConstraint else { return }
213
+ heightConstraint.isActive = false
214
+ self.heightConstraint = nil
215
+ }
216
+ }