expo 56.0.11 → 56.0.12

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.
@@ -10,7 +10,7 @@ buildscript {
10
10
  }
11
11
 
12
12
  group = 'host.exp.exponent'
13
- version = '56.0.11'
13
+ version = '56.0.12'
14
14
 
15
15
  expoModule {
16
16
  // We can't prebuild the module because it depends on the generated files.
@@ -21,7 +21,7 @@ android {
21
21
  namespace "expo.core"
22
22
  defaultConfig {
23
23
  versionCode 1
24
- versionName "56.0.11"
24
+ versionName "56.0.12"
25
25
  consumerProguardFiles("proguard-rules.pro")
26
26
  }
27
27
  testOptions {
@@ -2,7 +2,7 @@
2
2
  "@expo/fingerprint": "~0.19.4",
3
3
  "@expo/metro-runtime": "~56.0.15",
4
4
  "@expo/vector-icons": "^15.0.2",
5
- "@expo/ui": "~56.0.17",
5
+ "@expo/ui": "~56.0.18",
6
6
  "@react-native-async-storage/async-storage": "2.2.0",
7
7
  "@react-native-community/datetimepicker": "9.1.0",
8
8
  "@react-native-masked-view/masked-view": "0.3.2",
@@ -16,19 +16,19 @@
16
16
  "expo-analytics-amplitude": "~11.3.0",
17
17
  "expo-app-auth": "~11.1.0",
18
18
  "expo-app-loader-provider": "~8.0.0",
19
- "expo-app-metrics": "~56.0.18",
19
+ "expo-app-metrics": "~56.0.19",
20
20
  "expo-apple-authentication": "~56.0.4",
21
21
  "expo-application": "~56.0.3",
22
22
  "expo-asset": "~56.0.17",
23
23
  "expo-audio": "~56.0.12",
24
24
  "expo-auth-session": "~56.0.14",
25
- "expo-background-fetch": "~56.0.18",
26
- "expo-background-task": "~56.0.18",
25
+ "expo-background-fetch": "~56.0.19",
26
+ "expo-background-task": "~56.0.19",
27
27
  "expo-battery": "~56.0.4",
28
28
  "expo-blur": "~56.0.3",
29
29
  "expo-brightness": "~56.0.5",
30
- "expo-brownfield": "~56.0.19",
31
- "expo-build-properties": "~56.0.18",
30
+ "expo-brownfield": "~56.0.20",
31
+ "expo-build-properties": "~56.0.19",
32
32
  "expo-calendar": "~56.0.8",
33
33
  "expo-camera": "~56.0.8",
34
34
  "expo-cellular": "~56.0.5",
@@ -41,23 +41,23 @@
41
41
  "expo-device": "~56.0.4",
42
42
  "expo-document-picker": "~56.0.4",
43
43
  "expo-file-system": "~56.0.8",
44
- "expo-font": "~56.0.6",
44
+ "expo-font": "~56.0.7",
45
45
  "expo-gl": "~56.0.5",
46
46
  "expo-glass-effect": "~56.0.4",
47
47
  "expo-google-app-auth": "~8.3.0",
48
48
  "expo-haptics": "~56.0.3",
49
49
  "expo-image": "~56.0.11",
50
50
  "expo-image-loader": "~56.0.3",
51
- "expo-image-manipulator": "~56.0.18",
52
- "expo-image-picker": "~56.0.17",
51
+ "expo-image-manipulator": "~56.0.19",
52
+ "expo-image-picker": "~56.0.18",
53
53
  "expo-intent-launcher": "~56.0.4",
54
- "expo-insights": "~56.0.17",
54
+ "expo-insights": "~56.0.18",
55
55
  "expo-keep-awake": "~56.0.3",
56
56
  "expo-linear-gradient": "~56.0.4",
57
57
  "expo-linking": "~56.0.14",
58
58
  "expo-local-authentication": "~56.0.4",
59
59
  "expo-localization": "~56.0.6",
60
- "expo-location": "~56.0.17",
60
+ "expo-location": "~56.0.18",
61
61
  "expo-mail-composer": "~56.0.4",
62
62
  "expo-manifests": "~56.0.4",
63
63
  "expo-maps": "~56.0.7",
@@ -65,20 +65,20 @@
65
65
  "expo-media-library": "~56.0.7",
66
66
  "expo-mesh-gradient": "~56.0.3",
67
67
  "expo-module-template": "~56.0.14",
68
- "expo-modules-core": "~56.0.16",
68
+ "expo-modules-core": "~56.0.17",
69
69
  "expo-navigation-bar": "~56.0.3",
70
70
  "expo-network": "~56.0.5",
71
- "expo-notifications": "~56.0.17",
72
- "expo-observe": "~56.0.20",
71
+ "expo-notifications": "~56.0.18",
72
+ "expo-observe": "~56.0.21",
73
73
  "expo-print": "~56.0.4",
74
74
  "expo-live-photo": "~56.0.4",
75
- "expo-router": "~56.2.10",
75
+ "expo-router": "~56.2.11",
76
76
  "expo-screen-capture": "~56.0.4",
77
77
  "expo-screen-orientation": "~56.0.5",
78
78
  "expo-secure-store": "~56.0.4",
79
79
  "expo-sensors": "~56.0.6",
80
80
  "expo-server": "~56.0.5",
81
- "expo-sharing": "~56.0.17",
81
+ "expo-sharing": "~56.0.18",
82
82
  "expo-sms": "~56.0.3",
83
83
  "expo-speech": "~56.0.3",
84
84
  "expo-splash-screen": "~56.0.10",
@@ -87,13 +87,13 @@
87
87
  "expo-store-review": "~56.0.3",
88
88
  "expo-symbols": "~56.0.6",
89
89
  "expo-system-ui": "~56.0.5",
90
- "expo-task-manager": "~56.0.18",
90
+ "expo-task-manager": "~56.0.19",
91
91
  "expo-tracking-transparency": "~56.0.5",
92
92
  "expo-updates": "~56.0.19",
93
93
  "expo-video-thumbnails": "~56.0.3",
94
- "expo-video": "~56.1.3",
94
+ "expo-video": "~56.1.4",
95
95
  "expo-web-browser": "~56.0.5",
96
- "expo-widgets": "~56.0.18",
96
+ "expo-widgets": "~56.0.19",
97
97
  "jest-expo": "~56.0.5",
98
98
  "lottie-react-native": "~7.3.4",
99
99
  "react": "19.2.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo",
3
- "version": "56.0.11",
3
+ "version": "56.0.12",
4
4
  "description": "The Expo SDK",
5
5
  "main": "src/Expo.ts",
6
6
  "module": "src/Expo.ts",
@@ -68,9 +68,9 @@
68
68
  "homepage": "https://github.com/expo/expo/tree/main/packages/expo",
69
69
  "dependencies": {
70
70
  "@babel/runtime": "^7.20.0",
71
- "@expo/cli": "^56.1.15",
71
+ "@expo/cli": "^56.1.16",
72
72
  "@expo/config": "~56.0.9",
73
- "@expo/config-plugins": "~56.0.8",
73
+ "@expo/config-plugins": "~56.0.9",
74
74
  "@expo/devtools": "~56.0.2",
75
75
  "@expo/dom-webview": "~56.0.5",
76
76
  "@expo/fingerprint": "^0.19.4",
@@ -83,10 +83,10 @@
83
83
  "expo-asset": "~56.0.17",
84
84
  "expo-constants": "~56.0.18",
85
85
  "expo-file-system": "~56.0.8",
86
- "expo-font": "~56.0.6",
86
+ "expo-font": "~56.0.7",
87
87
  "expo-keep-awake": "~56.0.3",
88
- "expo-modules-autolinking": "~56.0.15",
89
- "expo-modules-core": "~56.0.16",
88
+ "expo-modules-autolinking": "~56.0.16",
89
+ "expo-modules-core": "~56.0.17",
90
90
  "pretty-format": "^29.7.0",
91
91
  "react-refresh": "^0.14.2",
92
92
  "whatwg-url-minimum": "^0.1.2"
@@ -139,7 +139,7 @@
139
139
  "scripts/resolveAppEntry.js"
140
140
  ]
141
141
  },
142
- "gitHead": "94e54b342509684ee4f352f38c74fb1928b29ef9",
142
+ "gitHead": "812dc007aefed0c432c0439fdfe05ee2f4f21da2",
143
143
  "scripts": {
144
144
  "build": "tsc",
145
145
  "clean": "rimraf build",
@@ -15,6 +15,7 @@ describe('asyncRequireModule', () => {
15
15
  let mockImportAll: jest.Mock;
16
16
  let mockRequire: any;
17
17
  let asyncRequire: any;
18
+ const originalExpoOs = process.env.EXPO_OS;
18
19
 
19
20
  beforeEach(() => {
20
21
  mockImportAll = jest.fn((id: number, _moduleName?: string) => ({
@@ -64,16 +65,27 @@ describe('asyncRequireModule', () => {
64
65
 
65
66
  function asyncRequireImpl(moduleID, paths, moduleName) {
66
67
  var importAll = function() { return require.importAll(moduleID, moduleName); };
67
- try {
68
- // Try importing first to skip bundle loading when the bundle is already preloaded.
69
- return importAll();
70
- } catch (error) {
71
- var maybeLoadBundlePromise = maybeLoadBundle(moduleID, paths);
72
- if (maybeLoadBundlePromise != null) {
73
- return maybeLoadBundlePromise.then(importAll);
68
+
69
+ // On web, importing synchronously first prevents double-loading preloaded scripts
70
+ if (process.env.EXPO_OS === 'web') {
71
+ try {
72
+ return importAll();
73
+ } catch (error) {
74
+ var maybeLoadBundlePromise = maybeLoadBundle(moduleID, paths);
75
+ if (maybeLoadBundlePromise != null) {
76
+ return maybeLoadBundlePromise.then(importAll);
77
+ }
78
+ throw error;
74
79
  }
75
- throw error;
76
80
  }
81
+
82
+ // On native, requiring a missing module reports a fatal error instead of
83
+ // throwing, so the split bundle must be loaded before importing
84
+ var maybeLoadBundlePromise = maybeLoadBundle(moduleID, paths);
85
+ if (maybeLoadBundlePromise != null) {
86
+ return maybeLoadBundlePromise.then(importAll);
87
+ }
88
+ return importAll();
77
89
  }
78
90
 
79
91
  function asyncRequire(moduleID, paths, moduleName) {
@@ -113,6 +125,7 @@ describe('asyncRequireModule', () => {
113
125
  afterEach(() => {
114
126
  delete (globalThis as any).__loadBundleAsync;
115
127
  delete (globalThis as any).__METRO_GLOBAL_PREFIX__;
128
+ process.env.EXPO_OS = originalExpoOs;
116
129
  });
117
130
 
118
131
  it('calls importAll with moduleID and moduleName when no bundle loading needed', async () => {
@@ -129,7 +142,8 @@ describe('asyncRequireModule', () => {
129
142
  expect(result).toEqual({ default: 'module-42' });
130
143
  });
131
144
 
132
- it('falls back to bundle load when importAll throws, then retries with moduleName', async () => {
145
+ it('falls back to bundle load on web when importAll throws, then retries with moduleName', async () => {
146
+ process.env.EXPO_OS = 'web';
133
147
  mockImportAll
134
148
  .mockImplementationOnce(() => {
135
149
  throw new Error('Module not loaded');
@@ -158,7 +172,8 @@ describe('asyncRequireModule', () => {
158
172
  expect(result).toEqual({ default: 'module-42' });
159
173
  });
160
174
 
161
- it('does not load the bundle when importAll succeeds (preloaded bundle case)', async () => {
175
+ it('does not load the bundle on web when importAll succeeds (preloaded bundle case)', async () => {
176
+ process.env.EXPO_OS = 'web';
162
177
  (globalThis as any).__loadBundleAsync = jest.fn(() => Promise.resolve());
163
178
 
164
179
  const paths = { '42': '/bundles/my-module.bundle' };
@@ -169,7 +184,8 @@ describe('asyncRequireModule', () => {
169
184
  expect(result).toEqual({ default: 'module-42' });
170
185
  });
171
186
 
172
- it('re-throws the import error when no bundle path is configured', () => {
187
+ it('re-throws the import error on web when no bundle path is configured', () => {
188
+ process.env.EXPO_OS = 'web';
173
189
  mockImportAll.mockImplementationOnce(() => {
174
190
  throw new Error('Module not loaded');
175
191
  });
@@ -177,6 +193,37 @@ describe('asyncRequireModule', () => {
177
193
  expect(() => asyncRequire(42, null, 'my-module')).toThrow('Module not loaded');
178
194
  });
179
195
 
196
+ it('loads the bundle on native before requiring split modules', async () => {
197
+ process.env.EXPO_OS = 'ios';
198
+ let bundleLoaded = false;
199
+ mockImportAll.mockImplementation((id: number) =>
200
+ bundleLoaded ? { default: `module-${id}` } : undefined
201
+ );
202
+ (globalThis as any).__loadBundleAsync = jest.fn(() => {
203
+ bundleLoaded = true;
204
+ return Promise.resolve();
205
+ });
206
+
207
+ const paths = { '42': '/bundles/my-module.bundle' };
208
+ const result = await asyncRequire(42, paths, 'my-module');
209
+
210
+ expect((globalThis as any).__loadBundleAsync).toHaveBeenCalledWith('/bundles/my-module.bundle');
211
+ expect(mockImportAll).toHaveBeenCalledTimes(1);
212
+ expect(mockImportAll).toHaveBeenCalledWith(42, 'my-module');
213
+ expect(result).toEqual({ default: 'module-42' });
214
+ });
215
+
216
+ it('imports synchronously on native when the module is inlined (no split bundle path)', () => {
217
+ process.env.EXPO_OS = 'ios';
218
+ (globalThis as any).__loadBundleAsync = jest.fn(() => Promise.resolve());
219
+
220
+ const ret = asyncRequire(42, null, 'my-module');
221
+
222
+ expect((globalThis as any).__loadBundleAsync).not.toHaveBeenCalled();
223
+ expect(mockImportAll).toHaveBeenCalledWith(42, 'my-module');
224
+ expect(ret._result).toEqual({ default: 'module-42' });
225
+ });
226
+
180
227
  describe('thenable return value', () => {
181
228
  it('exposes a synchronous _result when no bundle load was needed', () => {
182
229
  const ret = asyncRequire(42, null, 'my-module');
@@ -186,6 +233,7 @@ describe('asyncRequireModule', () => {
186
233
  });
187
234
 
188
235
  it('exposes a Promise _result when a bundle load was needed', async () => {
236
+ process.env.EXPO_OS = 'web';
189
237
  mockImportAll
190
238
  .mockImplementationOnce(() => {
191
239
  throw new Error('Module not loaded');
@@ -68,16 +68,30 @@ function asyncRequireImpl<T>(
68
68
  moduleName?: string
69
69
  ): Promise<T> | T {
70
70
  const importAll = () => (require as unknown as MetroRequire).importAll<T>(moduleID, moduleName);
71
- try {
72
- // Try importing first to prevent double-loading script when the page already preloaded it
73
- return importAll();
74
- } catch (error) {
75
- const maybeLoadBundlePromise = maybeLoadBundle(moduleID, paths);
76
- if (maybeLoadBundlePromise != null) {
77
- return maybeLoadBundlePromise.then(importAll);
71
+
72
+ // NOTE(@hassankhan): We need to come back and improve this, ideally we shouldn't need to have a
73
+ // separate conditional specifically for web
74
+ // On web, split chunks may already be preloaded via `<script>` tags, so importing
75
+ // synchronously first prevents double-loading the script
76
+ if (process.env.EXPO_OS === 'web') {
77
+ try {
78
+ return importAll();
79
+ } catch (error) {
80
+ const maybeLoadBundlePromise = maybeLoadBundle(moduleID, paths);
81
+ if (maybeLoadBundlePromise != null) {
82
+ return maybeLoadBundlePromise.then(importAll);
83
+ }
84
+ throw error;
78
85
  }
79
- throw error;
80
86
  }
87
+
88
+ // On native, requiring a missing module reports a fatal error via `global.ErrorUtils`
89
+ // instead of throwing, so the split bundle must be loaded before importing
90
+ const maybeLoadBundlePromise = maybeLoadBundle(moduleID, paths);
91
+ if (maybeLoadBundlePromise != null) {
92
+ return maybeLoadBundlePromise.then(importAll);
93
+ }
94
+ return importAll();
81
95
  }
82
96
 
83
97
  function asyncRequire<T>(
package/template.tgz CHANGED
Binary file