expo-modules-core 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +26 -6
  2. package/ExpoModulesCore.podspec +38 -4
  3. package/android/CMakeLists.txt +21 -71
  4. package/android/ExpoModulesCorePlugin.gradle +200 -0
  5. package/android/build.gradle +42 -205
  6. package/android/legacy/CMakeLists.txt +194 -0
  7. package/android/{src → legacy}/fabric/Android-prebuilt.cmake +2 -0
  8. package/android/legacy/fabric/CMakeLists.txt +40 -0
  9. package/android/proguard-rules.pro +13 -0
  10. package/android/src/fabric/CMakeLists.txt +23 -16
  11. package/android/src/main/java/expo/modules/kotlin/AppContext.kt +7 -0
  12. package/android/src/main/java/expo/modules/kotlin/exception/CommonExceptions.kt +5 -0
  13. package/android/src/main/java/expo/modules/kotlin/objects/ObjectDefinitionBuilder.kt +44 -0
  14. package/android/src/main/java/expo/modules/kotlin/views/ViewDefinitionBuilder.kt +9 -1
  15. package/android/src/main/java/expo/modules/kotlin/views/ViewManagerDefinitionBuilder.kt +46 -0
  16. package/build/EventEmitter.d.ts +2 -2
  17. package/build/EventEmitter.d.ts.map +1 -1
  18. package/build/NativeModulesProxy.types.d.ts +1 -1
  19. package/build/NativeModulesProxy.types.d.ts.map +1 -1
  20. package/build/NativeViewManagerAdapter.native.d.ts +1 -1
  21. package/build/NativeViewManagerAdapter.native.d.ts.map +1 -1
  22. package/build/NativeViewManagerAdapter.native.js +3 -3
  23. package/build/NativeViewManagerAdapter.native.js.map +1 -1
  24. package/build/PermissionsHook.d.ts +4 -4
  25. package/build/PermissionsHook.d.ts.map +1 -1
  26. package/build/PermissionsInterface.d.ts +1 -1
  27. package/build/PermissionsInterface.d.ts.map +1 -1
  28. package/build/Platform.d.ts +2 -2
  29. package/build/Platform.d.ts.map +1 -1
  30. package/build/TypedArrays.types.d.ts +9 -0
  31. package/build/TypedArrays.types.d.ts.map +1 -0
  32. package/build/TypedArrays.types.js +2 -0
  33. package/build/TypedArrays.types.js.map +1 -0
  34. package/build/index.d.ts +1 -0
  35. package/build/index.d.ts.map +1 -1
  36. package/build/index.js +1 -0
  37. package/build/index.js.map +1 -1
  38. package/build/requireNativeModule.d.ts +1 -1
  39. package/build/requireNativeModule.d.ts.map +1 -1
  40. package/common/cpp/fabric/ExpoViewProps.cpp +2 -0
  41. package/ios/AppDelegates/EXAppDelegateWrapper.h +22 -0
  42. package/ios/AppDelegates/EXAppDelegateWrapper.mm +100 -0
  43. package/ios/JSI/EXJavaScriptRuntime.mm +5 -5
  44. package/ios/ReactDelegates/EXReactCompatibleHelpers.h +1 -1
  45. package/ios/ReactDelegates/EXReactCompatibleHelpers.m +8 -2
  46. package/ios/ReactDelegates/EXReactDelegateWrapper.h +5 -0
  47. package/ios/ReactDelegates/EXReactDelegateWrapper.m +14 -1
  48. package/ios/ReactDelegates/ExpoReactDelegate.swift +7 -2
  49. package/ios/Swift/AppContext.swift +9 -0
  50. package/ios/Swift/Arguments/Enumerable.swift +2 -16
  51. package/ios/Swift/Classes/ClassComponentElement.swift +1 -1
  52. package/ios/Swift/Convertibles/Either.swift +5 -14
  53. package/ios/Swift/DynamicTypes/DynamicEnumType.swift +1 -1
  54. package/ios/Swift/DynamicTypes/DynamicSharedObjectType.swift +4 -0
  55. package/ios/Swift/DynamicTypes/DynamicType.swift +1 -1
  56. package/ios/Swift/Functions/AnyFunction.swift +18 -0
  57. package/ios/Swift/JavaScriptUtils.swift +25 -8
  58. package/ios/Swift/Objects/ObjectDefinition.swift +4 -4
  59. package/ios/Swift/Objects/ObjectDefinitionComponents.swift +7 -0
  60. package/ios/Swift/Objects/PropertyComponent.swift +138 -48
  61. package/ios/Swift/SharedObjects/SharedObject.swift +5 -0
  62. package/ios/Tests/ClassComponentSpec.swift +15 -0
  63. package/ios/Tests/EitherSpec.swift +28 -0
  64. package/ios/Tests/FunctionSpec.swift +31 -0
  65. package/ios/Tests/PropertyComponentSpec.swift +131 -33
  66. package/package.json +2 -2
  67. package/src/NativeViewManagerAdapter.native.tsx +4 -4
  68. package/src/TypedArrays.types.ts +11 -0
  69. package/src/index.ts +1 -0
  70. package/ios/AppDelegates/EXAppDelegateWrapper.m +0 -45
@@ -179,6 +179,37 @@ class FunctionSpec: ExpoSpec {
179
179
  }
180
180
  }
181
181
 
182
+ it("allows to skip trailing optional arguments") {
183
+ let returnedValue = "something"
184
+ let fn = Function(functionName) { (a: String, b: Int?, c: Bool?) in
185
+ expect(c).to(beNil())
186
+ return returnedValue
187
+ }
188
+
189
+ expect({ try fn.call(by: nil, withArguments: ["test"]) })
190
+ .notTo(throwError())
191
+ .to(be(returnedValue))
192
+
193
+ expect({ try fn.call(by: nil, withArguments: ["test", 3]) })
194
+ .notTo(throwError())
195
+ .to(be(returnedValue))
196
+ }
197
+
198
+ it("throws when called without required arguments") {
199
+ let fn = Function(functionName) { (requiredArgument: String, optionalArgument: Int?) in
200
+ return "something"
201
+ }
202
+
203
+ expect({ try fn.call(by: nil, withArguments: []) })
204
+ .to(throwError(errorType: FunctionCallException.self) { error in
205
+ expect(error.rootCause).to(beAKindOf(InvalidArgsNumberException.self))
206
+ let exception = error.rootCause as! InvalidArgsNumberException
207
+ expect(exception.param.received) == 0
208
+ expect(exception.param.required) == 1
209
+ expect(exception.param.expected) == 2
210
+ })
211
+ }
212
+
182
213
  it("throws when called with arguments of incompatible types") {
183
214
  waitUntil { done in
184
215
  mockModuleHolder(appContext) {
@@ -7,7 +7,7 @@ class PropertyComponentSpec: ExpoSpec {
7
7
  describe("property") {
8
8
  it("gets the value") {
9
9
  let property = Property("test") { return "expo" }
10
- expect(property.getValue()) == "expo"
10
+ expect(try property.getValue()) == "expo"
11
11
  }
12
12
 
13
13
  it("sets the value") {
@@ -21,7 +21,7 @@ class PropertyComponentSpec: ExpoSpec {
21
21
  let newValue = Int.random(in: 0..<100)
22
22
  property.setValue(newValue)
23
23
 
24
- expect(property.getValue()) == value
24
+ expect(try property.getValue()) == value
25
25
  expect(value) == newValue
26
26
  }
27
27
  }
@@ -31,32 +31,6 @@ class PropertyComponentSpec: ExpoSpec {
31
31
  let runtime = appContext.runtime
32
32
 
33
33
  beforeSuite {
34
- class PropertyTestModule: Module {
35
- func definition() -> ModuleDefinition {
36
- Name("PropertyTest")
37
-
38
- Property("readOnly") {
39
- return "foo"
40
- }
41
-
42
- var writablePropertyValue = 444
43
- Property("writable")
44
- .get {
45
- return writablePropertyValue
46
- }
47
- .set { value in
48
- writablePropertyValue = value
49
- }
50
-
51
- Property("withCaller") { (caller: JavaScriptObject) -> String in
52
- // Here, the caller is a JS object of the module.
53
- // Return another property of itself.
54
- return caller.getProperty("readOnly").getString()
55
- }
56
-
57
- Property("undefined")
58
- }
59
- }
60
34
  appContext.moduleRegistry.register(moduleType: PropertyTestModule.self)
61
35
  }
62
36
 
@@ -78,18 +52,142 @@ class PropertyComponentSpec: ExpoSpec {
78
52
 
79
53
  it("is enumerable") {
80
54
  let keys = try runtime?.eval("Object.keys(expo.modules.PropertyTest)").getArray().map { $0.getString() } ?? []
81
- expect(keys).to(contain("readOnly", "writable", "withCaller", "undefined"))
55
+ expect(keys).to(contain("readOnly", "writable", "undefined"))
82
56
  }
83
57
 
84
- it("is called with the caller") {
85
- let value = try runtime?.eval("expo.modules.PropertyTest.withCaller")
86
- expect(value?.getString()) == "foo"
87
- }
58
+ // TODO: Using JavaScriptObject as the owner is no longer possible, but we may want to bring this feature back
59
+ // it("is called with the caller") {
60
+ // let value = try runtime?.eval("expo.modules.PropertyTest.withCaller")
61
+ // expect(value?.getString()) == "foo"
62
+ // }
88
63
 
89
64
  it("returns undefined when getter is not specified") {
90
65
  let value = try runtime?.eval("expo.modules.PropertyTest.undefined")
91
66
  expect(value?.isUndefined()) == true
92
67
  }
93
68
  }
69
+
70
+ describe("class property") {
71
+ let appContext = AppContext.create()
72
+ let runtime = appContext.runtime
73
+
74
+ beforeSuite {
75
+ appContext.moduleRegistry.register(moduleType: PropertyTestModule.self)
76
+ }
77
+
78
+ it("gets the value") {
79
+ let value = try runtime?.eval("new expo.modules.PropertyTest.TestClass().someValue")
80
+
81
+ expect(value?.kind) == .number
82
+ expect(value?.getInt()) == TestClass.constantValue
83
+ }
84
+
85
+ it("sets the value") {
86
+ let newValue = Int.random(in: 1..<100)
87
+ let value = try runtime?.eval([
88
+ "object = new expo.modules.PropertyTest.TestClass()",
89
+ "object.someValue = \(newValue)",
90
+ "object.someValue"
91
+ ])
92
+
93
+ expect(value?.kind) == .number
94
+ expect(value?.getInt()) == newValue
95
+ }
96
+
97
+ // Tests for accessing shared object properties through KeyPath and ReferenceWritableKeyPath
98
+ describe("key path") {
99
+ it("gets immutable property") {
100
+ let value = try runtime?.eval([
101
+ "object = new expo.modules.PropertyTest.TestClass()",
102
+ "object.immutableKeyPathProperty"
103
+ ])
104
+
105
+ expect(value?.kind) == .number
106
+ expect(value?.getInt()) == TestClass.constantValue
107
+ }
108
+
109
+ it("cannot set immutable property") {
110
+ let newValue = Int.random(in: 100..<200)
111
+ let value = try runtime?.eval([
112
+ "object = new expo.modules.PropertyTest.TestClass()",
113
+ "object.immutableKeyPathProperty = \(newValue)",
114
+ "object.immutableKeyPathProperty"
115
+ ])
116
+
117
+ // Returned value didn't change, it doesn't equal to `newValue`
118
+ expect(value?.kind) == .number
119
+ expect(value?.getInt()) == TestClass.constantValue
120
+ }
121
+
122
+ it("sets mutable property") {
123
+ let newValue = Int.random(in: 100..<200)
124
+ let value = try runtime?.eval([
125
+ "object = new expo.modules.PropertyTest.TestClass()",
126
+ "object.mutableKeyPathProperty = \(newValue)",
127
+ "object.mutableKeyPathProperty"
128
+ ])
129
+
130
+ expect(value?.kind) == .number
131
+ expect(value?.getInt()) == newValue
132
+ }
133
+ }
134
+ }
94
135
  }
95
136
  }
137
+
138
+ class PropertyTestModule: Module {
139
+ func definition() -> ModuleDefinition {
140
+ Name("PropertyTest")
141
+
142
+ Property("readOnly") {
143
+ return "foo"
144
+ }
145
+
146
+ var writablePropertyValue = 444
147
+ Property("writable")
148
+ .get {
149
+ return writablePropertyValue
150
+ }
151
+ .set { value in
152
+ writablePropertyValue = value
153
+ }
154
+
155
+ // TODO: Using JavaScriptObject as the owner is no longer possible, but we may want to bring this feature back
156
+ // Property("withCaller") { (caller: JavaScriptObject) -> String in
157
+ // // Here, the caller is a JS object of the module.
158
+ // // Return another property of itself.
159
+ // return caller.getProperty("readOnly").getString()
160
+ // }
161
+
162
+ Property("undefined")
163
+
164
+ Class(TestClass.self) {
165
+ Constructor {
166
+ return TestClass()
167
+ }
168
+
169
+ Property("someValue") { object in
170
+ return object.someValue
171
+ }
172
+ .set { object, newValue in
173
+ object.someValue = newValue
174
+ }
175
+
176
+ // KeyPath<TestClass, Int>
177
+ Property("immutableKeyPathProperty", \.immutableKeyPathProperty)
178
+
179
+ // ReferenceWritableKeyPath<TestClass, Int>
180
+ Property("mutableKeyPathProperty", \.mutableKeyPathProperty)
181
+ }
182
+ }
183
+ }
184
+
185
+ fileprivate final class TestClass: SharedObject {
186
+ static let constantValue = Int.random(in: 1..<100)
187
+
188
+ var someValue = TestClass.constantValue
189
+
190
+ // For "key path" tests
191
+ let immutableKeyPathProperty = TestClass.constantValue
192
+ var mutableKeyPathProperty = TestClass.constantValue
193
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-core",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "The core of Expo Modules architecture",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -42,5 +42,5 @@
42
42
  "@testing-library/react-hooks": "^7.0.1",
43
43
  "expo-module-scripts": "^3.0.0"
44
44
  },
45
- "gitHead": "a4a37bbc631362ec2a6d83eb6361d5059bbc67da"
45
+ "gitHead": "ba80e8181b79d06e00a245653727f4eaeb80420e"
46
46
  }
@@ -17,7 +17,7 @@ type NativeExpoComponentProps = {
17
17
  /**
18
18
  * A drop-in replacement for `requireNativeComponent`.
19
19
  */
20
- export function requireNativeViewManager<P = any>(viewName: string): React.ComponentType<P> {
20
+ export function requireNativeViewManager<P>(viewName: string): React.ComponentType<P> {
21
21
  const { viewManagersMetadata } = NativeModules.NativeUnimoduleProxy;
22
22
  const viewManagerConfig = viewManagersMetadata?.[viewName];
23
23
 
@@ -36,13 +36,13 @@ export function requireNativeViewManager<P = any>(viewName: string): React.Compo
36
36
  const proxiedPropsNames = viewManagerConfig?.propsNames ?? [];
37
37
 
38
38
  // Define a component for universal-module authors to access their native view manager
39
- function NativeComponentAdapter(props, ref) {
39
+ const NativeComponentAdapter = React.forwardRef<any>((props, ref) => {
40
40
  const nativeProps = omit(props, proxiedPropsNames);
41
41
  const proxiedProps = pick(props, proxiedPropsNames);
42
42
  return <ReactNativeComponent {...nativeProps} proxiedProperties={proxiedProps} ref={ref} />;
43
- }
43
+ }) as React.ComponentType<P>;
44
44
  NativeComponentAdapter.displayName = `Adapter<${viewName}>`;
45
- return React.forwardRef(NativeComponentAdapter);
45
+ return NativeComponentAdapter;
46
46
  }
47
47
 
48
48
  function omit(props: Record<string, any>, propNames: string[]) {
@@ -0,0 +1,11 @@
1
+ /** A union type for all integer based [`TypedArray` objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects). */
2
+ export type IntBasedTypedArray = Int8Array | Int16Array | Int32Array;
3
+
4
+ /** A union type for all unsigned integer based [`TypedArray` objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects). */
5
+ export type UintBasedTypedArray = Uint8Array | Uint8ClampedArray | Uint16Array | Uint32Array;
6
+
7
+ /** A union type for all floating point based [`TypedArray` objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#typedarray_objects). */
8
+ export type FloatBasedTypedArray = Float32Array | Float64Array;
9
+
10
+ /** A [`TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) describes an array-like view of an underlying binary data buffer. */
11
+ export type TypedArray = IntBasedTypedArray | UintBasedTypedArray | FloatBasedTypedArray;
package/src/index.ts CHANGED
@@ -28,6 +28,7 @@ export {
28
28
  };
29
29
 
30
30
  export * from './requireNativeModule';
31
+ export * from './TypedArrays.types';
31
32
 
32
33
  /**
33
34
  * @deprecated renamed to `DeviceEventEmitter`
@@ -1,45 +0,0 @@
1
- // Copyright 2018-present 650 Industries. All rights reserved.
2
-
3
- #import <ExpoModulesCore/EXAppDelegateWrapper.h>
4
- #import <ExpoModulesCore/EXReactDelegateWrapper+Private.h>
5
- #import <ExpoModulesCore/Swift.h>
6
-
7
-
8
- @interface EXAppDelegateWrapper()
9
-
10
- @property (nonatomic, strong) EXReactDelegateWrapper *reactDelegate;
11
-
12
- @end
13
-
14
- @implementation EXAppDelegateWrapper {
15
- EXExpoAppDelegate *_expoAppDelegate;
16
- }
17
-
18
- // Synthesize window, so the AppDelegate can synthesize it too.
19
- @synthesize window = _window;
20
-
21
- - (instancetype)init
22
- {
23
- if (self = [super init]) {
24
- _expoAppDelegate = [[EXExpoAppDelegate alloc] init];
25
- _reactDelegate = [[EXReactDelegateWrapper alloc] initWithExpoReactDelegate:_expoAppDelegate.reactDelegate];
26
- }
27
- return self;
28
- }
29
-
30
- // This needs to be implemented, otherwise forwarding won't be called.
31
- // When the app starts, `UIApplication` uses it to check beforehand
32
- // which `UIApplicationDelegate` selectors are implemented.
33
- - (BOOL)respondsToSelector:(SEL)selector
34
- {
35
- return [super respondsToSelector:selector]
36
- || [_expoAppDelegate respondsToSelector:selector];
37
- }
38
-
39
- // Forwards all invocations to `ExpoAppDelegate` object.
40
- - (id)forwardingTargetForSelector:(SEL)selector
41
- {
42
- return _expoAppDelegate;
43
- }
44
-
45
- @end