expo 54.0.13 → 54.0.14

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.
@@ -32,7 +32,7 @@ buildscript {
32
32
  def reactNativeVersion = project.extensions.getByType(ExpoModuleExtension).reactNativeVersion
33
33
 
34
34
  group = 'host.exp.exponent'
35
- version = '54.0.13'
35
+ version = '54.0.14'
36
36
 
37
37
  expoModule {
38
38
  // We can't prebuild the module because it depends on the generated files.
@@ -43,7 +43,7 @@ android {
43
43
  namespace "expo.core"
44
44
  defaultConfig {
45
45
  versionCode 1
46
- versionName "54.0.13"
46
+ versionName "54.0.14"
47
47
  consumerProguardFiles("proguard-rules.pro")
48
48
  }
49
49
  testOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"buildUrlForBundle.d.ts","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAgB5D"}
1
+ {"version":3,"file":"buildUrlForBundle.d.ts","sourceRoot":"","sources":["../../src/async-require/buildUrlForBundle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAM5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../src/async-require/hmr.ts"],"names":[],"mappings":"AA4CA,KAAK,QAAQ,GACT,OAAO,GACP,MAAM,GACN,MAAM,GACN,OAAO,GACP,KAAK,GACL,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,OAAO,CAAC;AAEZ,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACxC,KAAK,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5C,CAAC;AAMF;;;GAGG;AACH,QAAA,MAAM,SAAS,EAAE,wBAsMhB,CAAC;AAuEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../../src/async-require/hmr.ts"],"names":[],"mappings":"AA4CA,KAAK,QAAQ,GACT,OAAO,GACP,MAAM,GACN,MAAM,GACN,OAAO,GACP,KAAK,GACL,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,OAAO,CAAC;AAEZ,MAAM,MAAM,wBAAwB,GAAG;IACrC,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;IAChB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACxC,KAAK,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CAC5C,CAAC;AAMF;;;GAGG;AACH,QAAA,MAAM,SAAS,EAAE,wBAwMhB,CAAC;AAuEF,eAAe,SAAS,CAAC"}
@@ -1,5 +1,5 @@
1
1
  {
2
- "@expo/fingerprint": "~0.15.1",
2
+ "@expo/fingerprint": "~0.15.2",
3
3
  "@expo/metro-runtime": "~6.1.2",
4
4
  "@expo/vector-icons": "^15.0.2",
5
5
  "@expo/ui": "~0.2.0-beta.7",
@@ -34,9 +34,9 @@
34
34
  "expo-checkbox": "~5.0.7",
35
35
  "expo-clipboard": "~8.0.7",
36
36
  "expo-constants": "~18.0.9",
37
- "expo-contacts": "~15.0.9",
37
+ "expo-contacts": "~15.0.10",
38
38
  "expo-crypto": "~15.0.7",
39
- "expo-dev-client": "~6.0.13",
39
+ "expo-dev-client": "~6.0.15",
40
40
  "expo-device": "~8.0.9",
41
41
  "expo-document-picker": "~14.0.7",
42
42
  "expo-file-system": "~19.0.17",
@@ -45,7 +45,7 @@
45
45
  "expo-glass-effect": "~0.1.4",
46
46
  "expo-google-app-auth": "~8.3.0",
47
47
  "expo-haptics": "~15.0.7",
48
- "expo-image": "~3.0.9",
48
+ "expo-image": "~3.0.10",
49
49
  "expo-image-loader": "~6.0.0",
50
50
  "expo-image-manipulator": "~14.0.7",
51
51
  "expo-image-picker": "~17.0.8",
@@ -63,13 +63,13 @@
63
63
  "expo-media-library": "~18.2.0",
64
64
  "expo-mesh-gradient": "~0.4.7",
65
65
  "expo-module-template": "~11.0.15",
66
- "expo-modules-core": "~3.0.21",
66
+ "expo-modules-core": "~3.0.22",
67
67
  "expo-navigation-bar": "~5.0.8",
68
68
  "expo-network": "~8.0.7",
69
69
  "expo-notifications": "~0.32.12",
70
70
  "expo-print": "~15.0.7",
71
71
  "expo-live-photo": "~1.0.7",
72
- "expo-router": "~6.0.11",
72
+ "expo-router": "~6.0.13",
73
73
  "expo-screen-capture": "~8.0.8",
74
74
  "expo-screen-orientation": "~9.0.7",
75
75
  "expo-secure-store": "~15.0.7",
@@ -83,7 +83,7 @@
83
83
  "expo-store-review": "~9.0.8",
84
84
  "expo-symbols": "~1.0.7",
85
85
  "expo-system-ui": "~6.0.7",
86
- "expo-task-manager": "~14.0.7",
86
+ "expo-task-manager": "~14.0.8",
87
87
  "expo-tracking-transparency": "~6.0.7",
88
88
  "expo-updates": "~29.0.12",
89
89
  "expo-video-thumbnails": "~10.0.7",
@@ -100,8 +100,8 @@
100
100
  "react-native-keyboard-controller": "1.18.5",
101
101
  "react-native-maps": "1.20.1",
102
102
  "react-native-pager-view": "6.9.1",
103
- "react-native-worklets": "0.5.1",
104
- "react-native-reanimated": "~4.1.1",
103
+ "react-native-worklets": "0.6.1",
104
+ "react-native-reanimated": "~4.1.3",
105
105
  "react-native-screens": "~4.16.0",
106
106
  "react-native-safe-area-context": "~5.6.0",
107
107
  "react-native-svg": "15.12.1",
@@ -73,52 +73,23 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
73
73
  _ application: UIApplication,
74
74
  willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
75
75
  ) -> Bool {
76
- let parsedSubscribers = ExpoAppDelegateSubscriberRepository.subscribers.filter {
77
- $0.responds(to: #selector(application(_:willFinishLaunchingWithOptions:)))
78
- }
79
-
80
- // If we can't find a subscriber that implements `willFinishLaunchingWithOptions`, we will delegate the decision if we can handel the passed URL to
81
- // the `didFinishLaunchingWithOptions` method by returning `true` here.
82
- // You can read more about how iOS handles deep links here: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application#discussion
83
- if parsedSubscribers.isEmpty {
84
- return true
85
- }
86
-
87
- return parsedSubscribers.reduce(false) { result, subscriber in
88
- return subscriber.application?(application, willFinishLaunchingWithOptions: launchOptions) ?? false || result
89
- }
76
+ return ExpoAppDelegateSubscriberManager.application(application, willFinishLaunchingWithOptions: launchOptions)
90
77
  }
91
78
 
92
79
  open func application(
93
80
  _ application: UIApplication,
94
81
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
95
82
  ) -> Bool {
96
- ExpoAppDelegateSubscriberRepository.subscribers.forEach { subscriber in
97
- // Subscriber result is ignored as it doesn't matter if any subscriber handled the incoming URL – we always return `true` anyway.
98
- _ = subscriber.application?(application, didFinishLaunchingWithOptions: launchOptions)
99
- }
100
-
101
- return true
83
+ return ExpoAppDelegateSubscriberManager.application(application, didFinishLaunchingWithOptions: launchOptions)
102
84
  }
103
85
 
104
86
  #elseif os(macOS)
105
87
  open func applicationWillFinishLaunching(_ notification: Notification) {
106
- let parsedSubscribers = ExpoAppDelegateSubscriberRepository.subscribers.filter {
107
- $0.responds(to: #selector(applicationWillFinishLaunching(_:)))
108
- }
109
-
110
- parsedSubscribers.forEach { subscriber in
111
- subscriber.applicationWillFinishLaunching?(notification)
112
- }
88
+ ExpoAppDelegateSubscriberManager.applicationWillFinishLaunching(notification)
113
89
  }
114
90
 
115
91
  open func applicationDidFinishLaunching(_ notification: Notification) {
116
- ExpoAppDelegateSubscriberRepository
117
- .subscribers
118
- .forEach { subscriber in
119
- // Subscriber result is ignored as it doesn't matter if any subscriber handled the incoming URL – we always return `true` anyway.
120
- _ = subscriber.applicationDidFinishLaunching?(notification)
121
- }
92
+ ExpoAppDelegateSubscriberManager.applicationDidFinishLaunching(notification)
122
93
  }
123
94
 
124
95
  // TODO: - Configuring and Discarding Scenes
@@ -130,69 +101,49 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
130
101
 
131
102
  @objc
132
103
  open func applicationDidBecomeActive(_ application: UIApplication) {
133
- ExpoAppDelegateSubscriberRepository
134
- .subscribers
135
- .forEach { $0.applicationDidBecomeActive?(application) }
104
+ ExpoAppDelegateSubscriberManager.applicationDidBecomeActive(application)
136
105
  }
137
106
 
138
107
  @objc
139
108
  open func applicationWillResignActive(_ application: UIApplication) {
140
- ExpoAppDelegateSubscriberRepository
141
- .subscribers
142
- .forEach { $0.applicationWillResignActive?(application) }
109
+ ExpoAppDelegateSubscriberManager.applicationWillResignActive(application)
143
110
  }
144
111
 
145
112
  @objc
146
113
  open func applicationDidEnterBackground(_ application: UIApplication) {
147
- ExpoAppDelegateSubscriberRepository
148
- .subscribers
149
- .forEach { $0.applicationDidEnterBackground?(application) }
114
+ ExpoAppDelegateSubscriberManager.applicationDidEnterBackground(application)
150
115
  }
151
116
 
152
117
  open func applicationWillEnterForeground(_ application: UIApplication) {
153
- ExpoAppDelegateSubscriberRepository
154
- .subscribers
155
- .forEach { $0.applicationWillEnterForeground?(application) }
118
+ ExpoAppDelegateSubscriberManager.applicationWillEnterForeground(application)
156
119
  }
157
120
 
158
121
  open func applicationWillTerminate(_ application: UIApplication) {
159
- ExpoAppDelegateSubscriberRepository
160
- .subscribers
161
- .forEach { $0.applicationWillTerminate?(application) }
122
+ ExpoAppDelegateSubscriberManager.applicationWillTerminate(application)
162
123
  }
163
124
 
164
125
  #elseif os(macOS)
165
126
  @objc
166
127
  open func applicationDidBecomeActive(_ notification: Notification) {
167
- ExpoAppDelegateSubscriberRepository
168
- .subscribers
169
- .forEach { $0.applicationDidBecomeActive?(notification) }
128
+ ExpoAppDelegateSubscriberManager.applicationDidBecomeActive(notification)
170
129
  }
171
130
 
172
131
  @objc
173
132
  open func applicationWillResignActive(_ notification: Notification) {
174
- ExpoAppDelegateSubscriberRepository
175
- .subscribers
176
- .forEach { $0.applicationWillResignActive?(notification) }
133
+ ExpoAppDelegateSubscriberManager.applicationWillResignActive(notification)
177
134
  }
178
135
 
179
136
  @objc
180
137
  open func applicationDidHide(_ notification: Notification) {
181
- ExpoAppDelegateSubscriberRepository
182
- .subscribers
183
- .forEach { $0.applicationDidHide?(notification) }
138
+ ExpoAppDelegateSubscriberManager.applicationDidHide(notification)
184
139
  }
185
140
 
186
141
  open func applicationWillUnhide(_ notification: Notification) {
187
- ExpoAppDelegateSubscriberRepository
188
- .subscribers
189
- .forEach { $0.applicationWillUnhide?(notification) }
142
+ ExpoAppDelegateSubscriberManager.applicationWillUnhide(notification)
190
143
  }
191
144
 
192
145
  open func applicationWillTerminate(_ notification: Notification) {
193
- ExpoAppDelegateSubscriberRepository
194
- .subscribers
195
- .forEach { $0.applicationWillTerminate?(notification) }
146
+ ExpoAppDelegateSubscriberManager.applicationWillTerminate(notification)
196
147
  }
197
148
  #endif
198
149
 
@@ -208,28 +159,7 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
208
159
  handleEventsForBackgroundURLSession identifier: String,
209
160
  completionHandler: @escaping () -> Void
210
161
  ) {
211
- let selector = #selector(application(_:handleEventsForBackgroundURLSession:completionHandler:))
212
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
213
- var subscribersLeft = subs.count
214
- let dispatchQueue = DispatchQueue(label: "expo.application.handleBackgroundEvents")
215
-
216
- let handler = {
217
- dispatchQueue.sync {
218
- subscribersLeft -= 1
219
-
220
- if subscribersLeft == 0 {
221
- completionHandler()
222
- }
223
- }
224
- }
225
-
226
- if subs.isEmpty {
227
- completionHandler()
228
- } else {
229
- subs.forEach {
230
- $0.application?(application, handleEventsForBackgroundURLSession: identifier, completionHandler: handler)
231
- }
232
- }
162
+ ExpoAppDelegateSubscriberManager.application(application, handleEventsForBackgroundURLSession: identifier, completionHandler: completionHandler)
233
163
  }
234
164
 
235
165
  #endif
@@ -237,15 +167,11 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
237
167
  // MARK: - Handling Remote Notification Registration
238
168
 
239
169
  open func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
240
- ExpoAppDelegateSubscriberRepository
241
- .subscribers
242
- .forEach { $0.application?(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) }
170
+ ExpoAppDelegateSubscriberManager.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
243
171
  }
244
172
 
245
173
  open func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
246
- ExpoAppDelegateSubscriberRepository
247
- .subscribers
248
- .forEach { $0.application?(application, didFailToRegisterForRemoteNotificationsWithError: error) }
174
+ ExpoAppDelegateSubscriberManager.application(application, didFailToRegisterForRemoteNotificationsWithError: error)
249
175
  }
250
176
 
251
177
  #if os(iOS) || os(tvOS)
@@ -254,42 +180,7 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
254
180
  didReceiveRemoteNotification userInfo: [AnyHashable: Any],
255
181
  fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
256
182
  ) {
257
- let selector = #selector(application(_:didReceiveRemoteNotification:fetchCompletionHandler:))
258
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
259
- var subscribersLeft = subs.count
260
- let dispatchQueue = DispatchQueue(label: "expo.application.remoteNotification", qos: .userInteractive)
261
- var failedCount = 0
262
- var newDataCount = 0
263
-
264
- let handler = { (result: UIBackgroundFetchResult) in
265
- dispatchQueue.sync {
266
- if result == .failed {
267
- failedCount += 1
268
- } else if result == .newData {
269
- newDataCount += 1
270
- }
271
-
272
- subscribersLeft -= 1
273
-
274
- if subscribersLeft == 0 {
275
- if newDataCount > 0 {
276
- completionHandler(.newData)
277
- } else if failedCount > 0 {
278
- completionHandler(.failed)
279
- } else {
280
- completionHandler(.noData)
281
- }
282
- }
283
- }
284
- }
285
-
286
- if subs.isEmpty {
287
- completionHandler(.noData)
288
- } else {
289
- subs.forEach { subscriber in
290
- subscriber.application?(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: handler)
291
- }
292
- }
183
+ ExpoAppDelegateSubscriberManager.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
293
184
  }
294
185
 
295
186
  #elseif os(macOS)
@@ -297,23 +188,14 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
297
188
  _ application: NSApplication,
298
189
  didReceiveRemoteNotification userInfo: [String: Any]
299
190
  ) {
300
- let selector = #selector(application(_:didReceiveRemoteNotification:))
301
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
302
-
303
- subs.forEach { subscriber in
304
- subscriber.application?(application, didReceiveRemoteNotification: userInfo)
305
- }
191
+ ExpoAppDelegateSubscriberManager.application(application, didReceiveRemoteNotification: userInfo)
306
192
  }
307
193
  #endif
308
194
 
309
195
  // MARK: - Continuing User Activity and Handling Quick Actions
310
196
 
311
197
  open func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
312
- return ExpoAppDelegateSubscriberRepository
313
- .subscribers
314
- .reduce(false) { result, subscriber in
315
- return subscriber.application?(application, willContinueUserActivityWithType: userActivityType) ?? false || result
316
- }
198
+ return ExpoAppDelegateSubscriberManager.application(application, willContinueUserActivityWithType: userActivityType)
317
199
  }
318
200
 
319
201
  #if os(iOS) || os(tvOS)
@@ -322,29 +204,7 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
322
204
  continue userActivity: NSUserActivity,
323
205
  restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
324
206
  ) -> Bool {
325
- let selector = #selector(application(_:continue:restorationHandler:))
326
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
327
- var subscribersLeft = subs.count
328
- let dispatchQueue = DispatchQueue(label: "expo.application.continueUserActivity", qos: .userInteractive)
329
- var allRestorableObjects = [UIUserActivityRestoring]()
330
-
331
- let handler = { (restorableObjects: [UIUserActivityRestoring]?) in
332
- dispatchQueue.sync {
333
- if let restorableObjects = restorableObjects {
334
- allRestorableObjects.append(contentsOf: restorableObjects)
335
- }
336
-
337
- subscribersLeft -= 1
338
-
339
- if subscribersLeft == 0 {
340
- restorationHandler(allRestorableObjects)
341
- }
342
- }
343
- }
344
-
345
- return subs.reduce(false) { result, subscriber in
346
- return subscriber.application?(application, continue: userActivity, restorationHandler: handler) ?? false || result
347
- }
207
+ return ExpoAppDelegateSubscriberManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
348
208
  }
349
209
  #elseif os(macOS)
350
210
  open func application(
@@ -352,44 +212,16 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
352
212
  continue userActivity: NSUserActivity,
353
213
  restorationHandler: @escaping ([any NSUserActivityRestoring]) -> Void
354
214
  ) -> Bool {
355
- let selector = #selector(application(_:continue:restorationHandler:))
356
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
357
- var subscribersLeft = subs.count
358
- let dispatchQueue = DispatchQueue(label: "expo.application.continueUserActivity", qos: .userInteractive)
359
- var allRestorableObjects = [NSUserActivityRestoring]()
360
-
361
- let handler = { (restorableObjects: [NSUserActivityRestoring]?) in
362
- dispatchQueue.sync {
363
- if let restorableObjects = restorableObjects {
364
- allRestorableObjects.append(contentsOf: restorableObjects)
365
- }
366
-
367
- subscribersLeft -= 1
368
-
369
- if subscribersLeft == 0 {
370
- restorationHandler(allRestorableObjects)
371
- }
372
- }
373
- }
374
-
375
- return subs.reduce(false) { result, subscriber in
376
- return subscriber.application?(application, continue: userActivity, restorationHandler: handler) ?? false || result
377
- }
215
+ return ExpoAppDelegateSubscriberManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
378
216
  }
379
217
  #endif
380
218
 
381
219
  open func application(_ application: UIApplication, didUpdate userActivity: NSUserActivity) {
382
- return ExpoAppDelegateSubscriberRepository
383
- .subscribers
384
- .forEach { $0.application?(application, didUpdate: userActivity) }
220
+ return ExpoAppDelegateSubscriberManager.application(application, didUpdate: userActivity)
385
221
  }
386
222
 
387
223
  open func application(_ application: UIApplication, didFailToContinueUserActivityWithType userActivityType: String, error: Error) {
388
- return ExpoAppDelegateSubscriberRepository
389
- .subscribers
390
- .forEach {
391
- $0.application?(application, didFailToContinueUserActivityWithType: userActivityType, error: error)
392
- }
224
+ return ExpoAppDelegateSubscriberManager.application(application, didFailToContinueUserActivityWithType: userActivityType, error: error)
393
225
  }
394
226
 
395
227
  #if os(iOS)
@@ -398,30 +230,7 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
398
230
  performActionFor shortcutItem: UIApplicationShortcutItem,
399
231
  completionHandler: @escaping (Bool) -> Void
400
232
  ) {
401
- let selector = #selector(application(_:performActionFor:completionHandler:))
402
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
403
- var subscribersLeft = subs.count
404
- var result: Bool = false
405
- let dispatchQueue = DispatchQueue(label: "expo.application.performAction", qos: .userInteractive)
406
-
407
- let handler = { (succeeded: Bool) in
408
- dispatchQueue.sync {
409
- result = result || succeeded
410
- subscribersLeft -= 1
411
-
412
- if subscribersLeft == 0 {
413
- completionHandler(result)
414
- }
415
- }
416
- }
417
-
418
- if subs.isEmpty {
419
- completionHandler(result)
420
- } else {
421
- subs.forEach { subscriber in
422
- subscriber.application?(application, performActionFor: shortcutItem, completionHandler: handler)
423
- }
424
- }
233
+ ExpoAppDelegateSubscriberManager.application(application, performActionFor: shortcutItem, completionHandler: completionHandler)
425
234
  }
426
235
  #endif
427
236
 
@@ -432,42 +241,7 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
432
241
  _ application: UIApplication,
433
242
  performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
434
243
  ) {
435
- let selector = #selector(application(_:performFetchWithCompletionHandler:))
436
- let subs = ExpoAppDelegateSubscriberRepository.subscribers.filter { $0.responds(to: selector) }
437
- var subscribersLeft = subs.count
438
- let dispatchQueue = DispatchQueue(label: "expo.application.performFetch", qos: .userInteractive)
439
- var failedCount = 0
440
- var newDataCount = 0
441
-
442
- let handler = { (result: UIBackgroundFetchResult) in
443
- dispatchQueue.sync {
444
- if result == .failed {
445
- failedCount += 1
446
- } else if result == .newData {
447
- newDataCount += 1
448
- }
449
-
450
- subscribersLeft -= 1
451
-
452
- if subscribersLeft == 0 {
453
- if newDataCount > 0 {
454
- completionHandler(.newData)
455
- } else if failedCount > 0 {
456
- completionHandler(.failed)
457
- } else {
458
- completionHandler(.noData)
459
- }
460
- }
461
- }
462
- }
463
-
464
- if subs.isEmpty {
465
- completionHandler(.noData)
466
- } else {
467
- subs.forEach { subscriber in
468
- subscriber.application?(application, performFetchWithCompletionHandler: handler)
469
- }
470
- }
244
+ ExpoAppDelegateSubscriberManager.application(application, performFetchWithCompletionHandler: completionHandler)
471
245
  }
472
246
 
473
247
  // TODO: - Interacting With WatchKit
@@ -479,15 +253,11 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
479
253
  #if os(iOS) || os(tvOS)
480
254
 
481
255
  open func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
482
- return ExpoAppDelegateSubscriberRepository.subscribers.reduce(false) { result, subscriber in
483
- return subscriber.application?(app, open: url, options: options) ?? false || result
484
- }
256
+ return ExpoAppDelegateSubscriberManager.application(app, open: url, options: options)
485
257
  }
486
258
  #elseif os(macOS)
487
259
  open func application(_ app: NSApplication, open urls: [URL]) {
488
- ExpoAppDelegateSubscriberRepository.subscribers.forEach { subscriber in
489
- subscriber.application?(app, open: urls)
490
- }
260
+ ExpoAppDelegateSubscriberManager.application(app, open: urls)
491
261
  }
492
262
  #endif
493
263
  // TODO: - Disallowing Specified App Extension Types
@@ -504,49 +274,7 @@ open class ExpoAppDelegate: NSObject, @preconcurrency ReactNativeFactoryProvider
504
274
  * a different orientation.
505
275
  */
506
276
  open func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
507
- let deviceOrientationMask = allowedOrientations(for: UIDevice.current.userInterfaceIdiom)
508
- let universalOrientationMask = allowedOrientations(for: .unspecified)
509
- let infoPlistOrientations = deviceOrientationMask.isEmpty ? universalOrientationMask : deviceOrientationMask
510
-
511
- let parsedSubscribers = ExpoAppDelegateSubscriberRepository.subscribers.filter {
512
- $0.responds(to: #selector(application(_:supportedInterfaceOrientationsFor:)))
513
- }
514
-
515
- // We want to create an intersection of all orientations set by subscribers.
516
- let subscribersMask: UIInterfaceOrientationMask = parsedSubscribers.reduce(.all) { result, subscriber in
517
- guard let requestedOrientation = subscriber.application?(application, supportedInterfaceOrientationsFor: window) else {
518
- return result
519
- }
520
- return requestedOrientation.intersection(result)
521
- }
522
- return parsedSubscribers.isEmpty ? infoPlistOrientations : subscribersMask
277
+ return ExpoAppDelegateSubscriberManager.application(application, supportedInterfaceOrientationsFor: window)
523
278
  }
524
279
  #endif
525
280
  }
526
-
527
- #if os(iOS)
528
- private func allowedOrientations(for userInterfaceIdiom: UIUserInterfaceIdiom) -> UIInterfaceOrientationMask {
529
- // For now only iPad-specific orientations are supported
530
- let deviceString = userInterfaceIdiom == .pad ? "~pad" : ""
531
- var mask: UIInterfaceOrientationMask = []
532
- guard let orientations = Bundle.main.infoDictionary?["UISupportedInterfaceOrientations\(deviceString)"] as? [String] else {
533
- return mask
534
- }
535
-
536
- for orientation in orientations {
537
- switch orientation {
538
- case "UIInterfaceOrientationPortrait":
539
- mask.insert(.portrait)
540
- case "UIInterfaceOrientationLandscapeLeft":
541
- mask.insert(.landscapeLeft)
542
- case "UIInterfaceOrientationLandscapeRight":
543
- mask.insert(.landscapeRight)
544
- case "UIInterfaceOrientationPortraitUpsideDown":
545
- mask.insert(.portraitUpsideDown)
546
- default:
547
- break
548
- }
549
- }
550
- return mask
551
- }
552
- #endif // os(iOS)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo",
3
- "version": "54.0.13",
3
+ "version": "54.0.14",
4
4
  "description": "The Expo SDK",
5
5
  "main": "src/Expo.ts",
6
6
  "module": "src/Expo.ts",
@@ -75,23 +75,23 @@
75
75
  "homepage": "https://github.com/expo/expo/tree/main/packages/expo",
76
76
  "dependencies": {
77
77
  "@babel/runtime": "^7.20.0",
78
- "@expo/cli": "54.0.11",
78
+ "@expo/cli": "54.0.12",
79
79
  "@expo/config": "~12.0.10",
80
80
  "@expo/config-plugins": "~54.0.2",
81
81
  "@expo/devtools": "0.1.7",
82
- "@expo/fingerprint": "0.15.1",
83
- "@expo/metro": "~54.0.0",
84
- "@expo/metro-config": "54.0.6",
82
+ "@expo/fingerprint": "0.15.2",
83
+ "@expo/metro": "~54.1.0",
84
+ "@expo/metro-config": "54.0.7",
85
85
  "@expo/vector-icons": "^15.0.2",
86
86
  "@ungap/structured-clone": "^1.3.0",
87
- "babel-preset-expo": "~54.0.3",
87
+ "babel-preset-expo": "~54.0.5",
88
88
  "expo-asset": "~12.0.9",
89
89
  "expo-constants": "~18.0.9",
90
90
  "expo-file-system": "~19.0.17",
91
91
  "expo-font": "~14.0.9",
92
92
  "expo-keep-awake": "~15.0.7",
93
- "expo-modules-autolinking": "3.0.15",
94
- "expo-modules-core": "3.0.21",
93
+ "expo-modules-autolinking": "3.0.16",
94
+ "expo-modules-core": "3.0.22",
95
95
  "pretty-format": "^29.7.0",
96
96
  "react-refresh": "^0.14.2",
97
97
  "whatwg-url-without-unicode": "8.0.0-3"
@@ -124,5 +124,5 @@
124
124
  "optional": true
125
125
  }
126
126
  },
127
- "gitHead": "a2c8477a3fc5744980494805ae46f20dda94c852"
127
+ "gitHead": "ea56136a4420322f46d00e4b1549595d8f85150e"
128
128
  }
@@ -1,8 +1,8 @@
1
1
  import { buildUrlForBundle } from '../buildUrlForBundle';
2
2
 
3
3
  it(`returns an expected URL`, () => {
4
- expect(buildUrlForBundle('foobar')).toEqual('/foobar');
4
+ expect(buildUrlForBundle('foobar')).toEqual(expect.stringMatching(/\/foobar$/));
5
5
  });
6
6
  it(`returns an expected URL with non standard root`, () => {
7
- expect(buildUrlForBundle('/more/than/one')).toEqual('/more/than/one');
7
+ expect(buildUrlForBundle('/more/than/one')).toEqual(expect.stringMatching(/\/more\/than\/one$/));
8
8
  });
@@ -27,9 +27,12 @@ it('loads a bundle', async () => {
27
27
  expect(DeviceEventEmitter.emit).not.toHaveBeenCalled();
28
28
  expect(DeviceEventEmitter.emit).not.toHaveBeenCalled();
29
29
 
30
- const url = `/Second.bundle?modulesOnly=true`;
31
- expect(HMRClient.registerBundle).toHaveBeenCalledWith(url);
32
- expect(fetchThenEvalAsync).toHaveBeenCalledWith(url);
30
+ expect(HMRClient.registerBundle).toHaveBeenCalledWith(
31
+ expect.stringMatching(/Second.bundle\?modulesOnly=true$/)
32
+ );
33
+ expect(fetchThenEvalAsync).toHaveBeenCalledWith(
34
+ expect.stringMatching(/Second.bundle\?modulesOnly=true$/)
35
+ );
33
36
  });
34
37
  it('loads a bundle in production', async () => {
35
38
  DeviceEventEmitter.emit = jest.fn();
@@ -38,7 +41,8 @@ it('loads a bundle in production', async () => {
38
41
  expect(DeviceEventEmitter.emit).not.toHaveBeenCalled();
39
42
  expect(DeviceEventEmitter.emit).not.toHaveBeenCalled();
40
43
 
41
- const url = `/Second.bundle?modulesOnly=true`;
42
44
  expect(HMRClient.registerBundle).not.toHaveBeenCalled();
43
- expect(fetchThenEvalAsync).toHaveBeenCalledWith(url);
45
+ expect(fetchThenEvalAsync).toHaveBeenCalledWith(
46
+ expect.stringMatching(/Second.bundle\?modulesOnly=true$/)
47
+ );
44
48
  });
@@ -5,6 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ import getDevServer from './getDevServer';
9
+
8
10
  /**
9
11
  * Given a path and some optional additional query parameters, create the dev server bundle URL.
10
12
  * @param bundlePath like `/foobar`
@@ -12,19 +14,9 @@
12
14
  * @returns a URL like "/foobar.bundle?platform=android&modulesOnly=true&runModule=false&runtimeBytecodeVersion=null"
13
15
  */
14
16
  export function buildUrlForBundle(bundlePath: string): string {
15
- if (bundlePath.match(/^https?:\/\//)) {
16
- return bundlePath;
17
- }
18
-
19
- if (
20
- typeof window !== 'undefined' &&
21
- // @ts-expect-error
22
- typeof window.$$EXPO_INITIAL_PROPS !== 'undefined'
23
- ) {
24
- // In a webview, you cannot read from an absolute path.
17
+ if (/^https?:\/\//.test(bundlePath)) {
25
18
  return bundlePath;
26
19
  }
27
- // NOTE(EvanBacon): This must come from the window origin (at least in dev mode).
28
- // Otherwise Metro will crash from attempting to load a bundle that doesn't exist.
29
- return '/' + bundlePath.replace(/^\/+/, '');
20
+ const { url: baseURL } = getDevServer();
21
+ return baseURL ? new URL(bundlePath, baseURL).toString() : `//${bundlePath.replace(/^\/+/, '')}`;
30
22
  }
@@ -162,13 +162,15 @@ const HMRClient: HMRClientNativeInterface = {
162
162
  hmrClient = client;
163
163
 
164
164
  const fullBundleUrl = (() => {
165
- if (document?.currentScript && 'src' in document.currentScript) {
166
- return document.currentScript.src;
167
- }
168
-
169
- const bundleUrl = new URL(location.href);
165
+ const currentScript = document?.currentScript;
166
+ const bundleUrl = new URL(
167
+ currentScript && 'src' in currentScript ? currentScript.src : location.href,
168
+ location.href
169
+ );
170
170
 
171
- bundleUrl.searchParams.set('platform', process.env.EXPO_OS ?? 'web');
171
+ if (!bundleUrl.searchParams.has('platform')) {
172
+ bundleUrl.searchParams.set('platform', process.env.EXPO_OS ?? 'web');
173
+ }
172
174
 
173
175
  return bundleUrl.toString();
174
176
  })();
package/template.tgz CHANGED
Binary file