aix 0.0.15 → 0.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 (241) hide show
  1. package/Aix.podspec +32 -0
  2. package/LICENSE +2 -2
  3. package/README.md +165 -33
  4. package/android/CMakeLists.txt +32 -0
  5. package/android/build.gradle +148 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +5 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  10. package/android/src/main/java/com/aix/AixPackage.kt +29 -0
  11. package/android/src/main/java/com/aix/HybridAix.kt +27 -0
  12. package/ios/Bridge.h +8 -0
  13. package/ios/HybridAix.swift +1072 -0
  14. package/ios/HybridAixCellView.swift +174 -0
  15. package/ios/HybridAixComposer.swift +119 -0
  16. package/lib/commonjs/aix.js +25 -0
  17. package/lib/commonjs/aix.js.map +1 -0
  18. package/lib/commonjs/fade-in/createUsePool.js +50 -0
  19. package/lib/commonjs/fade-in/createUsePool.js.map +1 -0
  20. package/lib/commonjs/fade-in/createUseStaggered.js +82 -0
  21. package/lib/commonjs/fade-in/createUseStaggered.js.map +1 -0
  22. package/lib/commonjs/fade-in/index.js +78 -0
  23. package/lib/commonjs/fade-in/index.js.map +1 -0
  24. package/lib/commonjs/footer.js +28 -0
  25. package/lib/commonjs/footer.js.map +1 -0
  26. package/lib/commonjs/index.js +48 -0
  27. package/lib/commonjs/index.js.map +1 -0
  28. package/lib/commonjs/package.json +1 -0
  29. package/lib/commonjs/views/aix.nitro.js +6 -0
  30. package/lib/commonjs/views/aix.nitro.js.map +1 -0
  31. package/lib/module/aix.js +20 -0
  32. package/lib/module/aix.js.map +1 -0
  33. package/lib/module/fade-in/createUsePool.js +46 -0
  34. package/lib/module/fade-in/createUsePool.js.map +1 -0
  35. package/lib/module/fade-in/createUseStaggered.js +79 -0
  36. package/lib/module/fade-in/createUseStaggered.js.map +1 -0
  37. package/lib/module/fade-in/index.js +74 -0
  38. package/lib/module/fade-in/index.js.map +1 -0
  39. package/lib/module/footer.js +23 -0
  40. package/lib/module/footer.js.map +1 -0
  41. package/lib/module/index.js +13 -0
  42. package/lib/module/index.js.map +1 -0
  43. package/lib/module/package.json +1 -0
  44. package/lib/module/views/aix.nitro.js +4 -0
  45. package/lib/module/views/aix.nitro.js.map +1 -0
  46. package/lib/typescript/src/aix.d.ts +14 -0
  47. package/lib/typescript/src/aix.d.ts.map +1 -0
  48. package/lib/typescript/src/fade-in/createUsePool.d.ts +5 -0
  49. package/lib/typescript/src/fade-in/createUsePool.d.ts.map +1 -0
  50. package/lib/typescript/src/fade-in/createUseStaggered.d.ts +2 -0
  51. package/lib/typescript/src/fade-in/createUseStaggered.d.ts.map +1 -0
  52. package/lib/typescript/src/fade-in/index.d.ts +5 -0
  53. package/lib/typescript/src/fade-in/index.d.ts.map +1 -0
  54. package/lib/typescript/src/footer.d.ts +5 -0
  55. package/lib/typescript/src/footer.d.ts.map +1 -0
  56. package/lib/typescript/src/index.d.ts +10 -0
  57. package/lib/typescript/src/index.d.ts.map +1 -0
  58. package/lib/typescript/src/views/aix.nitro.d.ts +101 -0
  59. package/lib/typescript/src/views/aix.nitro.d.ts.map +1 -0
  60. package/nitro.json +26 -0
  61. package/nitrogen/generated/.gitattributes +1 -0
  62. package/nitrogen/generated/android/Aix+autolinking.cmake +91 -0
  63. package/nitrogen/generated/android/Aix+autolinking.gradle +27 -0
  64. package/nitrogen/generated/android/AixOnLoad.cpp +70 -0
  65. package/nitrogen/generated/android/AixOnLoad.hpp +25 -0
  66. package/nitrogen/generated/android/c++/JAixAdditionalContentInsets.hpp +61 -0
  67. package/nitrogen/generated/android/c++/JAixAdditionalContentInsetsProp.hpp +63 -0
  68. package/nitrogen/generated/android/c++/JAixScrollIndicatorInsetValue.hpp +61 -0
  69. package/nitrogen/generated/android/c++/JAixScrollIndicatorInsets.hpp +63 -0
  70. package/nitrogen/generated/android/c++/JAixScrollOnFooterSizeUpdate.hpp +65 -0
  71. package/nitrogen/generated/android/c++/JHybridAixCellViewSpec.cpp +65 -0
  72. package/nitrogen/generated/android/c++/JHybridAixCellViewSpec.hpp +68 -0
  73. package/nitrogen/generated/android/c++/JHybridAixComposerSpec.cpp +48 -0
  74. package/nitrogen/generated/android/c++/JHybridAixComposerSpec.hpp +65 -0
  75. package/nitrogen/generated/android/c++/JHybridAixSpec.cpp +137 -0
  76. package/nitrogen/generated/android/c++/JHybridAixSpec.hpp +79 -0
  77. package/nitrogen/generated/android/c++/views/JHybridAixCellViewStateUpdater.cpp +60 -0
  78. package/nitrogen/generated/android/c++/views/JHybridAixCellViewStateUpdater.hpp +49 -0
  79. package/nitrogen/generated/android/c++/views/JHybridAixComposerStateUpdater.cpp +53 -0
  80. package/nitrogen/generated/android/c++/views/JHybridAixComposerStateUpdater.hpp +49 -0
  81. package/nitrogen/generated/android/c++/views/JHybridAixStateUpdater.cpp +80 -0
  82. package/nitrogen/generated/android/c++/views/JHybridAixStateUpdater.hpp +49 -0
  83. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixAdditionalContentInsets.kt +41 -0
  84. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixAdditionalContentInsetsProp.kt +41 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixOnLoad.kt +35 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixScrollIndicatorInsetValue.kt +41 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixScrollIndicatorInsets.kt +41 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/AixScrollOnFooterSizeUpdate.kt +44 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/HybridAixCellViewSpec.kt +65 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/HybridAixComposerSpec.kt +55 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/HybridAixSpec.kt +101 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixCellViewManager.kt +50 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixCellViewStateUpdater.kt +23 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixComposerManager.kt +50 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixComposerStateUpdater.kt +23 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixManager.kt +50 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/aix/views/HybridAixStateUpdater.kt +23 -0
  98. package/nitrogen/generated/ios/Aix+autolinking.rb +60 -0
  99. package/nitrogen/generated/ios/Aix-Swift-Cxx-Bridge.cpp +67 -0
  100. package/nitrogen/generated/ios/Aix-Swift-Cxx-Bridge.hpp +222 -0
  101. package/nitrogen/generated/ios/Aix-Swift-Cxx-Umbrella.hpp +70 -0
  102. package/nitrogen/generated/ios/AixAutolinking.mm +49 -0
  103. package/nitrogen/generated/ios/AixAutolinking.swift +55 -0
  104. package/nitrogen/generated/ios/c++/HybridAixCellViewSpecSwift.cpp +11 -0
  105. package/nitrogen/generated/ios/c++/HybridAixCellViewSpecSwift.hpp +80 -0
  106. package/nitrogen/generated/ios/c++/HybridAixComposerSpecSwift.cpp +11 -0
  107. package/nitrogen/generated/ios/c++/HybridAixComposerSpecSwift.hpp +69 -0
  108. package/nitrogen/generated/ios/c++/HybridAixSpecSwift.cpp +11 -0
  109. package/nitrogen/generated/ios/c++/HybridAixSpecSwift.hpp +142 -0
  110. package/nitrogen/generated/ios/c++/views/HybridAixCellViewComponent.mm +101 -0
  111. package/nitrogen/generated/ios/c++/views/HybridAixComponent.mm +126 -0
  112. package/nitrogen/generated/ios/c++/views/HybridAixComposerComponent.mm +92 -0
  113. package/nitrogen/generated/ios/swift/AixAdditionalContentInsets.swift +47 -0
  114. package/nitrogen/generated/ios/swift/AixAdditionalContentInsetsProp.swift +71 -0
  115. package/nitrogen/generated/ios/swift/AixScrollIndicatorInsetValue.swift +47 -0
  116. package/nitrogen/generated/ios/swift/AixScrollIndicatorInsets.swift +71 -0
  117. package/nitrogen/generated/ios/swift/AixScrollOnFooterSizeUpdate.swift +89 -0
  118. package/nitrogen/generated/ios/swift/HybridAixCellViewSpec.swift +57 -0
  119. package/nitrogen/generated/ios/swift/HybridAixCellViewSpec_cxx.swift +151 -0
  120. package/nitrogen/generated/ios/swift/HybridAixComposerSpec.swift +56 -0
  121. package/nitrogen/generated/ios/swift/HybridAixComposerSpec_cxx.swift +131 -0
  122. package/nitrogen/generated/ios/swift/HybridAixSpec.swift +63 -0
  123. package/nitrogen/generated/ios/swift/HybridAixSpec_cxx.swift +292 -0
  124. package/nitrogen/generated/shared/c++/AixAdditionalContentInsets.hpp +79 -0
  125. package/nitrogen/generated/shared/c++/AixAdditionalContentInsetsProp.hpp +81 -0
  126. package/nitrogen/generated/shared/c++/AixScrollIndicatorInsetValue.hpp +79 -0
  127. package/nitrogen/generated/shared/c++/AixScrollIndicatorInsets.hpp +81 -0
  128. package/nitrogen/generated/shared/c++/AixScrollOnFooterSizeUpdate.hpp +83 -0
  129. package/nitrogen/generated/shared/c++/HybridAixCellViewSpec.cpp +24 -0
  130. package/nitrogen/generated/shared/c++/HybridAixCellViewSpec.hpp +65 -0
  131. package/nitrogen/generated/shared/c++/HybridAixComposerSpec.cpp +21 -0
  132. package/nitrogen/generated/shared/c++/HybridAixComposerSpec.hpp +62 -0
  133. package/nitrogen/generated/shared/c++/HybridAixSpec.cpp +36 -0
  134. package/nitrogen/generated/shared/c++/HybridAixSpec.hpp +85 -0
  135. package/nitrogen/generated/shared/c++/views/HybridAixCellViewComponent.cpp +99 -0
  136. package/nitrogen/generated/shared/c++/views/HybridAixCellViewComponent.hpp +108 -0
  137. package/nitrogen/generated/shared/c++/views/HybridAixComponent.cpp +159 -0
  138. package/nitrogen/generated/shared/c++/views/HybridAixComponent.hpp +117 -0
  139. package/nitrogen/generated/shared/c++/views/HybridAixComposerComponent.cpp +75 -0
  140. package/nitrogen/generated/shared/c++/views/HybridAixComposerComponent.hpp +106 -0
  141. package/nitrogen/generated/shared/json/AixCellViewConfig.json +11 -0
  142. package/nitrogen/generated/shared/json/AixComposerConfig.json +9 -0
  143. package/nitrogen/generated/shared/json/AixConfig.json +16 -0
  144. package/package.json +113 -14
  145. package/src/aix.tsx +43 -0
  146. package/src/fade-in/createUsePool.ts +46 -0
  147. package/src/fade-in/createUseStaggered.ts +82 -0
  148. package/src/fade-in/index.tsx +97 -0
  149. package/src/footer.tsx +30 -0
  150. package/src/index.ts +20 -16
  151. package/src/views/aix.nitro.ts +148 -0
  152. package/docs/API.md +0 -288
  153. package/jest.config.js +0 -17
  154. package/lib/__tests__/deferredIterable.test.d.ts +0 -1
  155. package/lib/__tests__/deferredIterable.test.js +0 -108
  156. package/lib/__tests__/filter.test.d.ts +0 -1
  157. package/lib/__tests__/filter.test.js +0 -53
  158. package/lib/__tests__/flatMap.test.d.ts +0 -1
  159. package/lib/__tests__/flatMap.test.js +0 -77
  160. package/lib/__tests__/lookahead.test.d.ts +0 -1
  161. package/lib/__tests__/lookahead.test.js +0 -57
  162. package/lib/__tests__/map.test.d.ts +0 -1
  163. package/lib/__tests__/map.test.js +0 -53
  164. package/lib/__tests__/merge.test.d.ts +0 -1
  165. package/lib/__tests__/merge.test.js +0 -55
  166. package/lib/__tests__/reduce.test.d.ts +0 -1
  167. package/lib/__tests__/reduce.test.js +0 -52
  168. package/lib/__tests__/spanAll.test.d.ts +0 -1
  169. package/lib/__tests__/spanAll.test.js +0 -120
  170. package/lib/concat.d.ts +0 -4
  171. package/lib/concat.js +0 -126
  172. package/lib/deferred.d.ts +0 -9
  173. package/lib/deferred.js +0 -18
  174. package/lib/deferredIterable.d.ts +0 -22
  175. package/lib/deferredIterable.js +0 -111
  176. package/lib/filter.d.ts +0 -7
  177. package/lib/filter.js +0 -99
  178. package/lib/flatMap.d.ts +0 -1
  179. package/lib/flatMap.js +0 -119
  180. package/lib/fromEvent.d.ts +0 -5
  181. package/lib/fromEvent.js +0 -13
  182. package/lib/index.d.ts +0 -16
  183. package/lib/index.js +0 -34
  184. package/lib/insert.d.ts +0 -4
  185. package/lib/insert.js +0 -113
  186. package/lib/interval.d.ts +0 -4
  187. package/lib/interval.js +0 -64
  188. package/lib/iterableToArray.d.ts +0 -1
  189. package/lib/iterableToArray.js +0 -87
  190. package/lib/iteratorToIterable.d.ts +0 -6
  191. package/lib/iteratorToIterable.js +0 -70
  192. package/lib/lookahead.d.ts +0 -10
  193. package/lib/lookahead.js +0 -78
  194. package/lib/map.d.ts +0 -4
  195. package/lib/map.js +0 -98
  196. package/lib/merge.d.ts +0 -6
  197. package/lib/merge.js +0 -21
  198. package/lib/of.d.ts +0 -3
  199. package/lib/of.js +0 -5
  200. package/lib/reduce.d.ts +0 -4
  201. package/lib/reduce.js +0 -92
  202. package/lib/restToIterable.d.ts +0 -4
  203. package/lib/restToIterable.js +0 -73
  204. package/lib/spanAll.d.ts +0 -1
  205. package/lib/spanAll.js +0 -29
  206. package/lib/tap.d.ts +0 -4
  207. package/lib/tap.js +0 -96
  208. package/lib/toCallbacks.d.ts +0 -11
  209. package/lib/toCallbacks.js +0 -97
  210. package/lib/zip.d.ts +0 -4
  211. package/lib/zip.js +0 -75
  212. package/src/__tests__/deferredIterable.test.ts +0 -22
  213. package/src/__tests__/filter.test.ts +0 -10
  214. package/src/__tests__/flatMap.test.ts +0 -12
  215. package/src/__tests__/lookahead.test.ts +0 -9
  216. package/src/__tests__/map.test.ts +0 -10
  217. package/src/__tests__/merge.test.ts +0 -9
  218. package/src/__tests__/reduce.test.ts +0 -10
  219. package/src/__tests__/spanAll.test.ts +0 -17
  220. package/src/concat.ts +0 -13
  221. package/src/deferred.ts +0 -16
  222. package/src/deferredIterable.ts +0 -111
  223. package/src/filter.ts +0 -16
  224. package/src/flatMap.ts +0 -9
  225. package/src/fromEvent.ts +0 -16
  226. package/src/insert.ts +0 -13
  227. package/src/interval.ts +0 -20
  228. package/src/iterableToArray.ts +0 -7
  229. package/src/iteratorToIterable.ts +0 -12
  230. package/src/lookahead.ts +0 -27
  231. package/src/map.ts +0 -11
  232. package/src/merge.ts +0 -18
  233. package/src/of.ts +0 -4
  234. package/src/reduce.ts +0 -12
  235. package/src/restToIterable.ts +0 -8
  236. package/src/spanAll.ts +0 -26
  237. package/src/tap.ts +0 -11
  238. package/src/toCallbacks.ts +0 -27
  239. package/src/zip.ts +0 -19
  240. package/tsconfig.json +0 -63
  241. package/yarn.lock +0 -3514
@@ -0,0 +1,117 @@
1
+ ///
2
+ /// HybridAixComponent.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <optional>
11
+ #include <NitroModules/NitroDefines.hpp>
12
+ #include <NitroModules/NitroHash.hpp>
13
+ #include <NitroModules/CachedProp.hpp>
14
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
15
+ #include <react/renderer/core/PropsParserContext.h>
16
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
17
+ #include <react/renderer/components/view/ViewProps.h>
18
+
19
+ #include "AixScrollOnFooterSizeUpdate.hpp"
20
+ #include <optional>
21
+ #include "AixAdditionalContentInsetsProp.hpp"
22
+ #include "AixScrollIndicatorInsets.hpp"
23
+ #include <string>
24
+ #include <memory>
25
+ #include "HybridAixSpec.hpp"
26
+ #include <functional>
27
+
28
+ namespace margelo::nitro::aix::views {
29
+
30
+ using namespace facebook;
31
+
32
+ /**
33
+ * The name of the actual native View.
34
+ */
35
+ extern const char HybridAixComponentName[];
36
+
37
+ /**
38
+ * Props for the "Aix" View.
39
+ */
40
+ class HybridAixProps final: public react::ViewProps {
41
+ public:
42
+ HybridAixProps() = default;
43
+ HybridAixProps(const HybridAixProps&);
44
+ HybridAixProps(const react::PropsParserContext& context,
45
+ const HybridAixProps& sourceProps,
46
+ const react::RawProps& rawProps);
47
+
48
+ public:
49
+ CachedProp<bool> shouldStartAtEnd;
50
+ CachedProp<std::optional<AixScrollOnFooterSizeUpdate>> scrollOnFooterSizeUpdate;
51
+ CachedProp<std::optional<double>> scrollEndReachedThreshold;
52
+ CachedProp<std::optional<AixAdditionalContentInsetsProp>> additionalContentInsets;
53
+ CachedProp<std::optional<AixScrollIndicatorInsets>> additionalScrollIndicatorInsets;
54
+ CachedProp<std::optional<std::string>> mainScrollViewID;
55
+ CachedProp<std::optional<double>> penultimateCellIndex;
56
+ CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixSpec>& /* ref */)>>> hybridRef;
57
+
58
+ private:
59
+ static bool filterObjectKeys(const std::string& propName);
60
+ };
61
+
62
+ /**
63
+ * State for the "Aix" View.
64
+ */
65
+ class HybridAixState final {
66
+ public:
67
+ HybridAixState() = default;
68
+
69
+ public:
70
+ void setProps(const HybridAixProps& props) { _props.emplace(props); }
71
+ const std::optional<HybridAixProps>& getProps() const { return _props; }
72
+
73
+ public:
74
+ #ifdef ANDROID
75
+ HybridAixState(const HybridAixState& /* previousState */, folly::dynamic /* data */) {}
76
+ folly::dynamic getDynamic() const {
77
+ throw std::runtime_error("HybridAixState does not support folly!");
78
+ }
79
+ react::MapBuffer getMapBuffer() const {
80
+ throw std::runtime_error("HybridAixState does not support MapBuffer!");
81
+ };
82
+ #endif
83
+
84
+ private:
85
+ std::optional<HybridAixProps> _props;
86
+ };
87
+
88
+ /**
89
+ * The Shadow Node for the "Aix" View.
90
+ */
91
+ using HybridAixShadowNode = react::ConcreteViewShadowNode<HybridAixComponentName /* "HybridAix" */,
92
+ HybridAixProps /* custom props */,
93
+ react::ViewEventEmitter /* default */,
94
+ HybridAixState /* custom state */>;
95
+
96
+ /**
97
+ * The Component Descriptor for the "Aix" View.
98
+ */
99
+ class HybridAixComponentDescriptor final: public react::ConcreteComponentDescriptor<HybridAixShadowNode> {
100
+ public:
101
+ HybridAixComponentDescriptor(const react::ComponentDescriptorParameters& parameters);
102
+
103
+ public:
104
+ /**
105
+ * A faster path for cloning props - reuses the caching logic from `HybridAixProps`.
106
+ */
107
+ std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
108
+ const std::shared_ptr<const react::Props>& props,
109
+ react::RawProps rawProps) const override;
110
+ #ifdef ANDROID
111
+ void adopt(react::ShadowNode& shadowNode) const override;
112
+ #endif
113
+ };
114
+
115
+ /* The actual view for "Aix" needs to be implemented in platform-specific code. */
116
+
117
+ } // namespace margelo::nitro::aix::views
@@ -0,0 +1,75 @@
1
+ ///
2
+ /// HybridAixComposerComponent.cpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #include "HybridAixComposerComponent.hpp"
9
+
10
+ #include <string>
11
+ #include <exception>
12
+ #include <utility>
13
+ #include <NitroModules/NitroDefines.hpp>
14
+ #include <NitroModules/JSIConverter.hpp>
15
+ #include <react/renderer/core/RawValue.h>
16
+ #include <react/renderer/core/ShadowNode.h>
17
+ #include <react/renderer/core/ComponentDescriptor.h>
18
+ #include <react/renderer/components/view/ViewProps.h>
19
+
20
+ namespace margelo::nitro::aix::views {
21
+
22
+ extern const char HybridAixComposerComponentName[] = "AixComposer";
23
+
24
+ HybridAixComposerProps::HybridAixComposerProps(const react::PropsParserContext& context,
25
+ const HybridAixComposerProps& sourceProps,
26
+ const react::RawProps& rawProps):
27
+ react::ViewProps(context, sourceProps, rawProps, filterObjectKeys),
28
+ hybridRef([&]() -> CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixComposerSpec>& /* ref */)>>> {
29
+ try {
30
+ const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
31
+ if (rawValue == nullptr) return sourceProps.hybridRef;
32
+ const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
33
+ return CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixComposerSpec>& /* ref */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, "f"), sourceProps.hybridRef);
34
+ } catch (const std::exception& exc) {
35
+ throw std::runtime_error(std::string("AixComposer.hybridRef: ") + exc.what());
36
+ }
37
+ }()) { }
38
+
39
+ HybridAixComposerProps::HybridAixComposerProps(const HybridAixComposerProps& other):
40
+ react::ViewProps(),
41
+ hybridRef(other.hybridRef) { }
42
+
43
+ bool HybridAixComposerProps::filterObjectKeys(const std::string& propName) {
44
+ switch (hashString(propName)) {
45
+ case hashString("hybridRef"): return true;
46
+ default: return false;
47
+ }
48
+ }
49
+
50
+ HybridAixComposerComponentDescriptor::HybridAixComposerComponentDescriptor(const react::ComponentDescriptorParameters& parameters)
51
+ : ConcreteComponentDescriptor(parameters,
52
+ react::RawPropsParser(/* enableJsiParser */ true)) {}
53
+
54
+ std::shared_ptr<const react::Props> HybridAixComposerComponentDescriptor::cloneProps(const react::PropsParserContext& context,
55
+ const std::shared_ptr<const react::Props>& props,
56
+ react::RawProps rawProps) const {
57
+ // 1. Prepare raw props parser
58
+ rawProps.parse(rawPropsParser_);
59
+ // 2. Copy props with Nitro's cached copy constructor
60
+ return HybridAixComposerShadowNode::Props(context, /* & */ rawProps, props);
61
+ }
62
+
63
+ #ifdef ANDROID
64
+ void HybridAixComposerComponentDescriptor::adopt(react::ShadowNode& shadowNode) const {
65
+ // This is called immediately after `ShadowNode` is created, cloned or in progress.
66
+ // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
67
+ auto& concreteShadowNode = dynamic_cast<HybridAixComposerShadowNode&>(shadowNode);
68
+ const HybridAixComposerProps& props = concreteShadowNode.getConcreteProps();
69
+ HybridAixComposerState state;
70
+ state.setProps(props);
71
+ concreteShadowNode.setStateData(std::move(state));
72
+ }
73
+ #endif
74
+
75
+ } // namespace margelo::nitro::aix::views
@@ -0,0 +1,106 @@
1
+ ///
2
+ /// HybridAixComposerComponent.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © 2026 Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #include <optional>
11
+ #include <NitroModules/NitroDefines.hpp>
12
+ #include <NitroModules/NitroHash.hpp>
13
+ #include <NitroModules/CachedProp.hpp>
14
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
15
+ #include <react/renderer/core/PropsParserContext.h>
16
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
17
+ #include <react/renderer/components/view/ViewProps.h>
18
+
19
+ #include <memory>
20
+ #include "HybridAixComposerSpec.hpp"
21
+ #include <functional>
22
+ #include <optional>
23
+
24
+ namespace margelo::nitro::aix::views {
25
+
26
+ using namespace facebook;
27
+
28
+ /**
29
+ * The name of the actual native View.
30
+ */
31
+ extern const char HybridAixComposerComponentName[];
32
+
33
+ /**
34
+ * Props for the "AixComposer" View.
35
+ */
36
+ class HybridAixComposerProps final: public react::ViewProps {
37
+ public:
38
+ HybridAixComposerProps() = default;
39
+ HybridAixComposerProps(const HybridAixComposerProps&);
40
+ HybridAixComposerProps(const react::PropsParserContext& context,
41
+ const HybridAixComposerProps& sourceProps,
42
+ const react::RawProps& rawProps);
43
+
44
+ public:
45
+ CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridAixComposerSpec>& /* ref */)>>> hybridRef;
46
+
47
+ private:
48
+ static bool filterObjectKeys(const std::string& propName);
49
+ };
50
+
51
+ /**
52
+ * State for the "AixComposer" View.
53
+ */
54
+ class HybridAixComposerState final {
55
+ public:
56
+ HybridAixComposerState() = default;
57
+
58
+ public:
59
+ void setProps(const HybridAixComposerProps& props) { _props.emplace(props); }
60
+ const std::optional<HybridAixComposerProps>& getProps() const { return _props; }
61
+
62
+ public:
63
+ #ifdef ANDROID
64
+ HybridAixComposerState(const HybridAixComposerState& /* previousState */, folly::dynamic /* data */) {}
65
+ folly::dynamic getDynamic() const {
66
+ throw std::runtime_error("HybridAixComposerState does not support folly!");
67
+ }
68
+ react::MapBuffer getMapBuffer() const {
69
+ throw std::runtime_error("HybridAixComposerState does not support MapBuffer!");
70
+ };
71
+ #endif
72
+
73
+ private:
74
+ std::optional<HybridAixComposerProps> _props;
75
+ };
76
+
77
+ /**
78
+ * The Shadow Node for the "AixComposer" View.
79
+ */
80
+ using HybridAixComposerShadowNode = react::ConcreteViewShadowNode<HybridAixComposerComponentName /* "HybridAixComposer" */,
81
+ HybridAixComposerProps /* custom props */,
82
+ react::ViewEventEmitter /* default */,
83
+ HybridAixComposerState /* custom state */>;
84
+
85
+ /**
86
+ * The Component Descriptor for the "AixComposer" View.
87
+ */
88
+ class HybridAixComposerComponentDescriptor final: public react::ConcreteComponentDescriptor<HybridAixComposerShadowNode> {
89
+ public:
90
+ HybridAixComposerComponentDescriptor(const react::ComponentDescriptorParameters& parameters);
91
+
92
+ public:
93
+ /**
94
+ * A faster path for cloning props - reuses the caching logic from `HybridAixComposerProps`.
95
+ */
96
+ std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
97
+ const std::shared_ptr<const react::Props>& props,
98
+ react::RawProps rawProps) const override;
99
+ #ifdef ANDROID
100
+ void adopt(react::ShadowNode& shadowNode) const override;
101
+ #endif
102
+ };
103
+
104
+ /* The actual view for "AixComposer" needs to be implemented in platform-specific code. */
105
+
106
+ } // namespace margelo::nitro::aix::views
@@ -0,0 +1,11 @@
1
+ {
2
+ "uiViewClassName": "AixCellView",
3
+ "supportsRawText": false,
4
+ "bubblingEventTypes": {},
5
+ "directEventTypes": {},
6
+ "validAttributes": {
7
+ "isLast": true,
8
+ "index": true,
9
+ "hybridRef": true
10
+ }
11
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "uiViewClassName": "AixComposer",
3
+ "supportsRawText": false,
4
+ "bubblingEventTypes": {},
5
+ "directEventTypes": {},
6
+ "validAttributes": {
7
+ "hybridRef": true
8
+ }
9
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "uiViewClassName": "Aix",
3
+ "supportsRawText": false,
4
+ "bubblingEventTypes": {},
5
+ "directEventTypes": {},
6
+ "validAttributes": {
7
+ "shouldStartAtEnd": true,
8
+ "scrollOnFooterSizeUpdate": true,
9
+ "scrollEndReachedThreshold": true,
10
+ "additionalContentInsets": true,
11
+ "additionalScrollIndicatorInsets": true,
12
+ "mainScrollViewID": true,
13
+ "penultimateCellIndex": true,
14
+ "hybridRef": true
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,23 +1,122 @@
1
1
  {
2
2
  "name": "aix",
3
- "version": "0.0.15",
4
- "license": "MIT",
3
+ "version": "0.1.0",
4
+ "author": "Fernando Rojo",
5
5
  "repository": {
6
- "url": "https://github.com/jamiemccrindle/aix",
7
- "type": "git"
6
+ "type": "git",
7
+ "url": "git+https://github.com/vercel/aix.git"
8
8
  },
9
+ "main": "./lib/commonjs/index.js",
10
+ "module": "./lib/module/index.js",
9
11
  "devDependencies": {
10
- "@types/jest": "^23.1.1",
11
- "@types/node": "^10.3.5",
12
- "jest": "^23.1.0",
13
- "ts-jest": "^22.4.6",
14
- "tslint": "^5.10.0",
15
- "typescript": "^2.9.2"
12
+ "@jamesacarr/eslint-formatter-github-actions": "^0.2.0",
13
+ "@semantic-release/changelog": "^6.0.3",
14
+ "@semantic-release/git": "^10.0.1",
15
+ "@types/jest": "^29.5.12",
16
+ "@types/react": "19.1.1",
17
+ "nitrogen": "0.31.10",
18
+ "react": "19.1.1",
19
+ "react-native": "0.82",
20
+ "react-native-builder-bob": "^0.37.0",
21
+ "react-native-nitro-modules": "0.31.10",
22
+ "conventional-changelog-conventionalcommits": "^9.1.0",
23
+ "semantic-release": "^24.2.9",
24
+ "typescript": "^5.8.3"
25
+ },
26
+ "peerDependencies": {
27
+ "react": "*",
28
+ "react-native": "*",
29
+ "react-native-nitro-modules": "*"
30
+ },
31
+ "bugs": "https://github.com/vercel/aix/issues",
32
+ "description": "aix is a react native package built with Nitro",
33
+ "eslintConfig": {
34
+ "root": true,
35
+ "extends": [
36
+ "@react-native",
37
+ "prettier"
38
+ ],
39
+ "plugins": [
40
+ "prettier"
41
+ ],
42
+ "rules": {
43
+ "prettier/prettier": [
44
+ "warn",
45
+ {
46
+ "quoteProps": "consistent",
47
+ "singleQuote": true,
48
+ "tabWidth": 2,
49
+ "trailingComma": "es5",
50
+ "useTabs": false
51
+ }
52
+ ]
53
+ }
54
+ },
55
+ "eslintIgnore": [
56
+ "node_modules/",
57
+ "lib/"
58
+ ],
59
+ "files": [
60
+ "src",
61
+ "react-native.config.js",
62
+ "lib",
63
+ "nitrogen",
64
+ "cpp",
65
+ "nitro.json",
66
+ "android/build.gradle",
67
+ "android/fix-prefab.gradle",
68
+ "android/gradle.properties",
69
+ "android/CMakeLists.txt",
70
+ "android/src",
71
+ "ios/**/*.h",
72
+ "ios/**/*.m",
73
+ "ios/**/*.mm",
74
+ "ios/**/*.cpp",
75
+ "ios/**/*.swift",
76
+ "app.plugin.js",
77
+ "*.podspec",
78
+ "README.md"
79
+ ],
80
+ "homepage": "https://github.com/vercel/aix#readme",
81
+ "keywords": [
82
+ "react-native",
83
+ "aix"
84
+ ],
85
+ "license": "MIT",
86
+ "prettier": {
87
+ "quoteProps": "consistent",
88
+ "singleQuote": true,
89
+ "tabWidth": 2,
90
+ "trailingComma": "es5",
91
+ "useTabs": false,
92
+ "semi": false
93
+ },
94
+ "publishConfig": {
95
+ "access": "public",
96
+ "registry": "https://registry.npmjs.org/"
97
+ },
98
+ "react-native": "src/index",
99
+ "react-native-builder-bob": {
100
+ "source": "src",
101
+ "output": "lib",
102
+ "targets": [
103
+ "commonjs",
104
+ "module",
105
+ [
106
+ "typescript",
107
+ {
108
+ "project": "tsconfig.json"
109
+ }
110
+ ]
111
+ ]
16
112
  },
17
113
  "scripts": {
18
- "test": "jest",
19
- "build": "tsc"
114
+ "typecheck": "tsc --noEmit",
115
+ "clean": "git clean -dfX",
116
+ "release": "semantic-release",
117
+ "build": "bun run typecheck && bob build",
118
+ "codegen": "nitrogen --logLevel=\"debug\" && bun run build && node post-script.js"
20
119
  },
21
- "main": "lib/index.js",
22
- "types": "lib/index.d.ts"
120
+ "source": "src/index",
121
+ "types": "./lib/typescript/src/index.d.ts"
23
122
  }
package/src/aix.tsx ADDED
@@ -0,0 +1,43 @@
1
+ import {
2
+ callback,
3
+ getHostComponent,
4
+ type HybridRef,
5
+ } from 'react-native-nitro-modules'
6
+ import AixConfig from '../nitrogen/generated/shared/json/AixConfig.json'
7
+ import type { AixProps, AixMethods } from './views/aix.nitro'
8
+ import { forwardRef } from 'react'
9
+
10
+ export type AixRef = HybridRef<AixProps, AixMethods>
11
+
12
+ const AixInternal = getHostComponent<AixProps, AixMethods>(
13
+ 'Aix',
14
+ () => AixConfig
15
+ )
16
+
17
+ export const Aix = forwardRef<AixRef, React.ComponentProps<typeof AixInternal>>(
18
+ function Aix(props, ref) {
19
+ return (
20
+ <AixInternal
21
+ {...props}
22
+ scrollOnFooterSizeUpdate={
23
+ props.scrollOnFooterSizeUpdate ?? {
24
+ enabled: true,
25
+ scrolledToEndThreshold: 100,
26
+ animated: false,
27
+ }
28
+ }
29
+ hybridRef={
30
+ ref
31
+ ? callback((r) => {
32
+ if (typeof ref === 'function') {
33
+ ref(r)
34
+ } else {
35
+ ref.current = r
36
+ }
37
+ })
38
+ : undefined
39
+ }
40
+ />
41
+ )
42
+ }
43
+ )
@@ -0,0 +1,46 @@
1
+ import { useState, useRef, useEffect, useCallback } from 'react'
2
+
3
+ export function createUsePool(maxPoolSize?: number) {
4
+ // Use parallel arrays instead of one array for fast array operations
5
+ const items: object[] = []
6
+ const setters: ((value: boolean) => void)[] = []
7
+
8
+ const removeItem = (item: object, setInactive?: boolean) => {
9
+ const index = items.indexOf(item)
10
+ if (index !== -1) {
11
+ if (setInactive) {
12
+ setters[index]!(false)
13
+ }
14
+ items.splice(index, 1)
15
+ setters.splice(index, 1)
16
+ }
17
+ }
18
+
19
+ const usePool = () => {
20
+ // Use a stable object reference as the key
21
+ const item = useRef({}).current
22
+ const [isActive, setIsActive] = useState(true)
23
+
24
+ // A function that is stable and only changes when the item changes
25
+ const evict = useCallback(() => removeItem(item, true), [item])
26
+
27
+ useEffect(() => {
28
+ items.push(item)
29
+ setters.push(setIsActive)
30
+
31
+ // Evict oldest item if over capacity
32
+ if (maxPoolSize && items.length > maxPoolSize) {
33
+ items.shift()
34
+ const evictedListener = setters.shift()!
35
+ evictedListener(false)
36
+ }
37
+
38
+ // Remove from pool when unmounting
39
+ return () => removeItem(item)
40
+ }, [item])
41
+
42
+ return { isActive, evict }
43
+ }
44
+
45
+ return usePool
46
+ }
@@ -0,0 +1,82 @@
1
+ import { useEffect, useRef } from 'react'
2
+
3
+ // Creates a staggered animation system - only one animation starts per frame/delay
4
+ export function createUseStaggered(delay: number) {
5
+ const animationQueue: (() => void)[] = []
6
+ let isProcessing = false
7
+
8
+ // Schedule next animation with delay or requestAnimationFrame
9
+ const scheduleNext = () => {
10
+ if (delay && delay > 0) {
11
+ setTimeout(processNextAnimation, delay)
12
+ } else {
13
+ requestAnimationFrame(processNextAnimation)
14
+ }
15
+ }
16
+
17
+ const processNextAnimation = () => {
18
+ if (animationQueue.length === 0) {
19
+ isProcessing = false
20
+ return
21
+ }
22
+
23
+ // Calculate how many animations to process this cycle
24
+ const queueLength = animationQueue.length
25
+ let animationsToProcess = 1
26
+
27
+ // Catch-up logic: process more animations when queue is long
28
+ if (queueLength > 10) {
29
+ animationsToProcess = Math.min(5, Math.ceil(queueLength / 4))
30
+ } else if (queueLength > 5) {
31
+ animationsToProcess = 2
32
+ }
33
+
34
+ // Process the calculated number of animations
35
+ for (let i = 0; i < animationsToProcess && animationQueue.length > 0; i++) {
36
+ const startAnimation = animationQueue.shift()!
37
+ startAnimation()
38
+ }
39
+
40
+ // Continue processing or mark as idle
41
+ if (animationQueue.length > 0) {
42
+ scheduleNext()
43
+ } else {
44
+ isProcessing = false
45
+ }
46
+ }
47
+
48
+ const queueAnimation = (startFn: () => void) => {
49
+ animationQueue.push(startFn)
50
+
51
+ if (!isProcessing) {
52
+ isProcessing = true
53
+ scheduleNext()
54
+ }
55
+ }
56
+
57
+ const useStaggered = (animationFn: () => void) => {
58
+ const animationRef = useRef<(() => void) | null>(animationFn)
59
+
60
+ // Queue animation on mount
61
+ useEffect(() => {
62
+ if (animationRef.current) {
63
+ queueAnimation(animationRef.current)
64
+ }
65
+ }, [])
66
+
67
+ useEffect(() => {
68
+ const animation = animationRef.current
69
+ return () => {
70
+ // Clean up pending animation on unmount
71
+ if (animation) {
72
+ const index = animationQueue.indexOf(animation)
73
+ if (index !== -1) {
74
+ animationQueue.splice(index, 1)
75
+ }
76
+ }
77
+ }
78
+ }, [])
79
+ }
80
+
81
+ return useStaggered
82
+ }