miaoda-expo-devkit 0.1.1-beta.98 → 0.1.1-dev.development-build.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +154 -110
  2. package/dist/babel/plugin-lucide-react-native.js +184 -184
  3. package/dist/cli/lint.js +317 -309
  4. package/dist/index.d.mts +1 -110
  5. package/dist/index.d.ts +1 -110
  6. package/dist/index.js +0 -159
  7. package/dist/index.mjs +0 -132
  8. package/dist/metro.d.mts +25 -5
  9. package/dist/metro.d.ts +25 -5
  10. package/dist/metro.js +49 -18
  11. package/dist/metro.mjs +50 -20
  12. package/dist/rules/no-expo-audio-compat.js +2041 -0
  13. package/dist/rules/no-expo-video-compat.js +90 -90
  14. package/dist/stubs/entry-inject.js +0 -2
  15. package/dist/stubs/expo-native-wechat-stub.js +116 -0
  16. package/dist/stubs/expo-router-entry-native-stub.js +4 -0
  17. package/dist/stubs/i18n/en.js +16 -1
  18. package/dist/stubs/i18n/zh.js +16 -1
  19. package/dist/stubs/logbox-control.js +9 -0
  20. package/dist/stubs/screenshot-control.js +1 -1
  21. package/dist/stubs/sentry-react-native-stub.js +15 -180
  22. package/oxlint-config.json +11 -4
  23. package/package.json +60 -5
  24. package/pnpm-patches/@expo__cli@55.0.16-55.0.22.patch +627 -0
  25. package/pnpm-patches/@expo__cli@55.0.16.patch +218 -0
  26. package/pnpm-patches/@expo__cli@55.0.17.patch +218 -0
  27. package/pnpm-patches/@expo__cli@55.0.18.patch +218 -0
  28. package/pnpm-patches/@expo__cli@55.0.19.patch +218 -0
  29. package/pnpm-patches/@expo__cli@55.0.20.patch +218 -0
  30. package/pnpm-patches/@expo__cli@55.0.21.patch +218 -0
  31. package/pnpm-patches/@expo__cli@55.0.22.patch +218 -0
  32. package/pnpm-patches/@shopify__react-native-skia@2.4.18.patch +14 -0
  33. package/pnpm-patches/expo-modules-core@55.0.15.patch +21 -0
  34. package/pnpm-patches/expo@55.0.6.patch +235 -0
  35. package/pnpm-patches/metro-file-map@0.83.3.patch +24 -0
  36. package/pnpm-patches/metro-runtime@0.83.3.patch +13 -0
  37. package/pnpm-patches/react-native-css-interop@0.2.6.patch +12 -0
  38. package/pnpm-patches/react-native-reanimated@4.2.1.patch +53 -0
  39. package/pnpm-patches/react-native-worklets@0.7.2.patch +91 -0
  40. package/pnpm-patches/react-native@0.83.2.patch +384 -0
  41. package/pnpmfile.cjs +168 -0
  42. package/dist/stubs/preview-control.js +0 -60
@@ -0,0 +1,218 @@
1
+ diff --git a/build/src/start/server/metro/instantiateMetro.js b/build/src/start/server/metro/instantiateMetro.js
2
+ --- a/build/src/start/server/metro/instantiateMetro.js
3
+ +++ b/build/src/start/server/metro/instantiateMetro.js
4
+ @@ -90,6 +90,7 @@
5
+ const _attachAtlas = require("./debugging/attachAtlas");
6
+ const _createDebugMiddleware = require("./debugging/createDebugMiddleware");
7
+ const _createMetroMiddleware = require("./dev-server/createMetroMiddleware");
8
+ +const _aiErrorCollector = require("./aiErrorCollector");
9
+ const _runServerfork = require("./runServer-fork");
10
+ const _withMetroMultiPlatform = require("./withMetroMultiPlatform");
11
+ const _events = require("../../../events");
12
+ @@ -274,6 +275,7 @@
13
+ const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = (0, _createMetroMiddleware.createMetroMiddleware)(metroConfig, {
14
+ getMetroBundler
15
+ });
16
+ + const aiErrorCollector = !isExporting ? (0, _aiErrorCollector.createAiErrorCollector)(projectRoot) : null;
17
+ // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)
18
+ const serverBaseUrl = metroBundler.getUrlCreator().constructUrl({
19
+ scheme: 'http',
20
+ @@ -348,7 +350,10 @@
21
+ }
22
+ }), fileBuffer);
23
+ };
24
+ - setEventReporter(eventsSocket.reportMetroEvent);
25
+ + setEventReporter((event)=>{
26
+ + eventsSocket.reportMetroEvent(event);
27
+ + aiErrorCollector == null ? void 0 : aiErrorCollector.handleMetroEvent(event);
28
+ + });
29
+ // This function ensures that modules in source maps are sorted in the same
30
+ // order as in a plain JS bundle.
31
+ metro._getSortedModules = function(graph) {
32
+ @@ -493,1 +498,1 @@
33
+ -//# sourceMappingURL=instantiateMetro.js.map
34
+
35
+ +//# sourceMappingURL=instantiateMetro.js.map
36
+ diff --git a/build/src/start/server/metro/aiErrorCollector.js b/build/src/start/server/metro/aiErrorCollector.js
37
+ new file mode 100644
38
+ --- /dev/null
39
+ +++ b/build/src/start/server/metro/aiErrorCollector.js
40
+ @@ -0,0 +1,178 @@
41
+ +"use strict";
42
+ +Object.defineProperty(exports, "__esModule", {
43
+ + value: true
44
+ +});
45
+ +Object.defineProperty(exports, "createAiErrorCollector", {
46
+ + enumerable: true,
47
+ + get: function() {
48
+ + return createAiErrorCollector;
49
+ + }
50
+ +});
51
+ +const fs = require("fs");
52
+ +const os = require("os");
53
+ +const path = require("path");
54
+ +
55
+ +const MAX_VALUE_DEPTH = 4;
56
+ +const MAX_STRING_LENGTH = 20000;
57
+ +
58
+ +function isEnabled() {
59
+ + return process.env.EXPO_AI_ERROR_COLLECTOR === '1';
60
+ +}
61
+ +
62
+ +function getOutputPath(projectRoot) {
63
+ + const configured = process.env.EXPO_AI_ERROR_FILE;
64
+ + if (!configured) return path.join(projectRoot, 'node_modules', '.miaoda-expo', 'ai-error.json');
65
+ + return path.isAbsolute(configured) ? configured : path.resolve(projectRoot, configured);
66
+ +}
67
+ +
68
+ +function toSerializable(value, depth = 0, seen = new Set()) {
69
+ + if (value == null || typeof value === 'boolean' || typeof value === 'number') return value;
70
+ + if (typeof value === 'string') return value.length > MAX_STRING_LENGTH ? value.slice(0, MAX_STRING_LENGTH) + '...[truncated]' : value;
71
+ + if (depth >= MAX_VALUE_DEPTH) return '[truncated]';
72
+ + if (typeof value === 'function' || typeof value === 'symbol') return String(value);
73
+ + if (seen.has(value)) return '[circular]';
74
+ + seen.add(value);
75
+ + if (value instanceof Error) {
76
+ + const error = {
77
+ + name: value.name,
78
+ + message: value.message,
79
+ + stack: value.stack
80
+ + };
81
+ + for (const key of Object.keys(value)) error[key] = toSerializable(value[key], depth + 1, seen);
82
+ + seen.delete(value);
83
+ + return error;
84
+ + }
85
+ + if (Array.isArray(value)) {
86
+ + const result = value.map((item)=>toSerializable(item, depth + 1, seen));
87
+ + seen.delete(value);
88
+ + return result;
89
+ + }
90
+ + if (typeof value === 'object') {
91
+ + const result = {};
92
+ + for (const key of Object.keys(value)) result[key] = toSerializable(value[key], depth + 1, seen);
93
+ + seen.delete(value);
94
+ + return result;
95
+ + }
96
+ + return String(value);
97
+ +}
98
+ +
99
+ +function normalizeError(error, projectRoot, buildID) {
100
+ + const raw = error && typeof error === 'object' ? error : {
101
+ + message: String(error ?? 'Metro bundling failed')
102
+ + };
103
+ + const message = String(raw.message ?? raw.reason ?? error ?? 'Metro bundling failed');
104
+ + const record = {
105
+ + schemaVersion: 1,
106
+ + id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`,
107
+ + timestamp: new Date().toISOString(),
108
+ + source: 'metro',
109
+ + eventType: 'bundling_error',
110
+ + buildID: buildID ?? undefined,
111
+ + projectRoot,
112
+ + type: String(raw.type ?? raw.name ?? 'MetroError'),
113
+ + name: raw.name == null ? undefined : String(raw.name),
114
+ + message,
115
+ + filename: raw.filename == null ? undefined : String(raw.filename),
116
+ + lineNumber: typeof raw.lineNumber === 'number' ? raw.lineNumber : undefined,
117
+ + column: typeof raw.column === 'number' ? raw.column : undefined,
118
+ + errors: Array.isArray(raw.errors) ? toSerializable(raw.errors) : [],
119
+ + stack: raw.stack == null ? undefined : String(raw.stack),
120
+ + cause: raw.cause == null ? undefined : toSerializable(raw.cause)
121
+ + };
122
+ + const extra = {};
123
+ + for (const key of Object.keys(raw)) {
124
+ + if (!['type', 'name', 'message', 'filename', 'lineNumber', 'column', 'errors', 'stack', 'cause'].includes(key)) {
125
+ + extra[key] = toSerializable(raw[key]);
126
+ + }
127
+ + }
128
+ + if (Object.keys(extra).length) record.extra = extra;
129
+ + return omitUndefined(record);
130
+ +}
131
+ +
132
+ +function omitUndefined(value) {
133
+ + if (!value || typeof value !== 'object') return value;
134
+ + if (Array.isArray(value)) return value.map(omitUndefined);
135
+ + const result = {};
136
+ + for (const [key, item] of Object.entries(value)) {
137
+ + if (item !== undefined) result[key] = omitUndefined(item);
138
+ + }
139
+ + return result;
140
+ +}
141
+ +
142
+ +function createAiErrorCollector(projectRoot) {
143
+ + if (!isEnabled()) return null;
144
+ + const outputFile = getOutputPath(projectRoot);
145
+ + let activeBuildID = null;
146
+ + let lastFailedBuildID = null;
147
+ + let state = {
148
+ + schemaVersion: 1,
149
+ + status: 'compiling',
150
+ + buildID: null,
151
+ + updatedAt: new Date().toISOString(),
152
+ + error: null
153
+ + };
154
+ + let warned = false;
155
+ + const publish = (nextState)=>{
156
+ + state = omitUndefined({ ...nextState, updatedAt: new Date().toISOString() });
157
+ + let temporaryFile;
158
+ + try {
159
+ + fs.mkdirSync(path.dirname(outputFile), { recursive: true });
160
+ + temporaryFile = `${outputFile}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
161
+ + fs.writeFileSync(temporaryFile, JSON.stringify(state, null, 2) + os.EOL, 'utf8');
162
+ + fs.renameSync(temporaryFile, outputFile);
163
+ + } catch (error) {
164
+ + try {
165
+ + if (temporaryFile) fs.rmSync(temporaryFile, { force: true });
166
+ + } catch {}
167
+ + if (!warned) {
168
+ + warned = true;
169
+ + console.warn(`[expo-ai-error] Could not write ${outputFile}: ${error.message}`);
170
+ + }
171
+ + }
172
+ + };
173
+ + const isCurrentBuild = (buildID, allowMissing = false)=>buildID == null ? allowMissing || activeBuildID == null : activeBuildID == null || buildID === activeBuildID;
174
+ + return {
175
+ + getState() {
176
+ + return state;
177
+ + },
178
+ + handleMetroEvent(event) {
179
+ + if (!event || typeof event !== 'object') return;
180
+ + const type = event.type;
181
+ + const buildID = event.buildID ?? event.bundleDetails?.buildID ?? null;
182
+ + if (type === 'bundle_build_started') {
183
+ + activeBuildID = buildID;
184
+ + lastFailedBuildID = null;
185
+ + publish({ schemaVersion: 1, status: 'compiling', buildID, error: null });
186
+ + return;
187
+ + }
188
+ + if (type === 'bundle_build_failed') {
189
+ + if (!isCurrentBuild(buildID)) return;
190
+ + lastFailedBuildID = buildID ?? activeBuildID;
191
+ + publish({
192
+ + schemaVersion: 1,
193
+ + status: 'failed',
194
+ + buildID: lastFailedBuildID,
195
+ + error: normalizeError(event.error ?? { type: 'MetroBundleError', message: 'Metro bundling failed' }, projectRoot, lastFailedBuildID)
196
+ + });
197
+ + return;
198
+ + }
199
+ + if (type === 'bundling_error') {
200
+ + const errorBuildID = buildID ?? lastFailedBuildID ?? activeBuildID;
201
+ + if (!isCurrentBuild(errorBuildID, true)) return;
202
+ + publish({
203
+ + schemaVersion: 1,
204
+ + status: 'failed',
205
+ + buildID: errorBuildID,
206
+ + error: normalizeError(event.error, projectRoot, errorBuildID)
207
+ + });
208
+ + return;
209
+ + }
210
+ + if (type === 'bundle_build_done') {
211
+ + if (!isCurrentBuild(buildID)) return;
212
+ + publish({ schemaVersion: 1, status: 'succeeded', buildID: buildID ?? activeBuildID, error: null });
213
+ + }
214
+ + }
215
+ + };
216
+ +}
217
+ +
218
+ +//# sourceMappingURL=aiErrorCollector.js.map
@@ -0,0 +1,218 @@
1
+ diff --git a/build/src/start/server/metro/instantiateMetro.js b/build/src/start/server/metro/instantiateMetro.js
2
+ --- a/build/src/start/server/metro/instantiateMetro.js
3
+ +++ b/build/src/start/server/metro/instantiateMetro.js
4
+ @@ -90,6 +90,7 @@
5
+ const _attachAtlas = require("./debugging/attachAtlas");
6
+ const _createDebugMiddleware = require("./debugging/createDebugMiddleware");
7
+ const _createMetroMiddleware = require("./dev-server/createMetroMiddleware");
8
+ +const _aiErrorCollector = require("./aiErrorCollector");
9
+ const _runServerfork = require("./runServer-fork");
10
+ const _withMetroMultiPlatform = require("./withMetroMultiPlatform");
11
+ const _events = require("../../../events");
12
+ @@ -274,6 +275,7 @@
13
+ const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = (0, _createMetroMiddleware.createMetroMiddleware)(metroConfig, {
14
+ getMetroBundler
15
+ });
16
+ + const aiErrorCollector = !isExporting ? (0, _aiErrorCollector.createAiErrorCollector)(projectRoot) : null;
17
+ // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)
18
+ const serverBaseUrl = metroBundler.getUrlCreator().constructUrl({
19
+ scheme: 'http',
20
+ @@ -348,7 +350,10 @@
21
+ }
22
+ }), fileBuffer);
23
+ };
24
+ - setEventReporter(eventsSocket.reportMetroEvent);
25
+ + setEventReporter((event)=>{
26
+ + eventsSocket.reportMetroEvent(event);
27
+ + aiErrorCollector == null ? void 0 : aiErrorCollector.handleMetroEvent(event);
28
+ + });
29
+ // This function ensures that modules in source maps are sorted in the same
30
+ // order as in a plain JS bundle.
31
+ metro._getSortedModules = function(graph) {
32
+ @@ -493,1 +498,1 @@
33
+ -//# sourceMappingURL=instantiateMetro.js.map
34
+
35
+ +//# sourceMappingURL=instantiateMetro.js.map
36
+ diff --git a/build/src/start/server/metro/aiErrorCollector.js b/build/src/start/server/metro/aiErrorCollector.js
37
+ new file mode 100644
38
+ --- /dev/null
39
+ +++ b/build/src/start/server/metro/aiErrorCollector.js
40
+ @@ -0,0 +1,178 @@
41
+ +"use strict";
42
+ +Object.defineProperty(exports, "__esModule", {
43
+ + value: true
44
+ +});
45
+ +Object.defineProperty(exports, "createAiErrorCollector", {
46
+ + enumerable: true,
47
+ + get: function() {
48
+ + return createAiErrorCollector;
49
+ + }
50
+ +});
51
+ +const fs = require("fs");
52
+ +const os = require("os");
53
+ +const path = require("path");
54
+ +
55
+ +const MAX_VALUE_DEPTH = 4;
56
+ +const MAX_STRING_LENGTH = 20000;
57
+ +
58
+ +function isEnabled() {
59
+ + return process.env.EXPO_AI_ERROR_COLLECTOR === '1';
60
+ +}
61
+ +
62
+ +function getOutputPath(projectRoot) {
63
+ + const configured = process.env.EXPO_AI_ERROR_FILE;
64
+ + if (!configured) return path.join(projectRoot, 'node_modules', '.miaoda-expo', 'ai-error.json');
65
+ + return path.isAbsolute(configured) ? configured : path.resolve(projectRoot, configured);
66
+ +}
67
+ +
68
+ +function toSerializable(value, depth = 0, seen = new Set()) {
69
+ + if (value == null || typeof value === 'boolean' || typeof value === 'number') return value;
70
+ + if (typeof value === 'string') return value.length > MAX_STRING_LENGTH ? value.slice(0, MAX_STRING_LENGTH) + '...[truncated]' : value;
71
+ + if (depth >= MAX_VALUE_DEPTH) return '[truncated]';
72
+ + if (typeof value === 'function' || typeof value === 'symbol') return String(value);
73
+ + if (seen.has(value)) return '[circular]';
74
+ + seen.add(value);
75
+ + if (value instanceof Error) {
76
+ + const error = {
77
+ + name: value.name,
78
+ + message: value.message,
79
+ + stack: value.stack
80
+ + };
81
+ + for (const key of Object.keys(value)) error[key] = toSerializable(value[key], depth + 1, seen);
82
+ + seen.delete(value);
83
+ + return error;
84
+ + }
85
+ + if (Array.isArray(value)) {
86
+ + const result = value.map((item)=>toSerializable(item, depth + 1, seen));
87
+ + seen.delete(value);
88
+ + return result;
89
+ + }
90
+ + if (typeof value === 'object') {
91
+ + const result = {};
92
+ + for (const key of Object.keys(value)) result[key] = toSerializable(value[key], depth + 1, seen);
93
+ + seen.delete(value);
94
+ + return result;
95
+ + }
96
+ + return String(value);
97
+ +}
98
+ +
99
+ +function normalizeError(error, projectRoot, buildID) {
100
+ + const raw = error && typeof error === 'object' ? error : {
101
+ + message: String(error ?? 'Metro bundling failed')
102
+ + };
103
+ + const message = String(raw.message ?? raw.reason ?? error ?? 'Metro bundling failed');
104
+ + const record = {
105
+ + schemaVersion: 1,
106
+ + id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`,
107
+ + timestamp: new Date().toISOString(),
108
+ + source: 'metro',
109
+ + eventType: 'bundling_error',
110
+ + buildID: buildID ?? undefined,
111
+ + projectRoot,
112
+ + type: String(raw.type ?? raw.name ?? 'MetroError'),
113
+ + name: raw.name == null ? undefined : String(raw.name),
114
+ + message,
115
+ + filename: raw.filename == null ? undefined : String(raw.filename),
116
+ + lineNumber: typeof raw.lineNumber === 'number' ? raw.lineNumber : undefined,
117
+ + column: typeof raw.column === 'number' ? raw.column : undefined,
118
+ + errors: Array.isArray(raw.errors) ? toSerializable(raw.errors) : [],
119
+ + stack: raw.stack == null ? undefined : String(raw.stack),
120
+ + cause: raw.cause == null ? undefined : toSerializable(raw.cause)
121
+ + };
122
+ + const extra = {};
123
+ + for (const key of Object.keys(raw)) {
124
+ + if (!['type', 'name', 'message', 'filename', 'lineNumber', 'column', 'errors', 'stack', 'cause'].includes(key)) {
125
+ + extra[key] = toSerializable(raw[key]);
126
+ + }
127
+ + }
128
+ + if (Object.keys(extra).length) record.extra = extra;
129
+ + return omitUndefined(record);
130
+ +}
131
+ +
132
+ +function omitUndefined(value) {
133
+ + if (!value || typeof value !== 'object') return value;
134
+ + if (Array.isArray(value)) return value.map(omitUndefined);
135
+ + const result = {};
136
+ + for (const [key, item] of Object.entries(value)) {
137
+ + if (item !== undefined) result[key] = omitUndefined(item);
138
+ + }
139
+ + return result;
140
+ +}
141
+ +
142
+ +function createAiErrorCollector(projectRoot) {
143
+ + if (!isEnabled()) return null;
144
+ + const outputFile = getOutputPath(projectRoot);
145
+ + let activeBuildID = null;
146
+ + let lastFailedBuildID = null;
147
+ + let state = {
148
+ + schemaVersion: 1,
149
+ + status: 'compiling',
150
+ + buildID: null,
151
+ + updatedAt: new Date().toISOString(),
152
+ + error: null
153
+ + };
154
+ + let warned = false;
155
+ + const publish = (nextState)=>{
156
+ + state = omitUndefined({ ...nextState, updatedAt: new Date().toISOString() });
157
+ + let temporaryFile;
158
+ + try {
159
+ + fs.mkdirSync(path.dirname(outputFile), { recursive: true });
160
+ + temporaryFile = `${outputFile}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
161
+ + fs.writeFileSync(temporaryFile, JSON.stringify(state, null, 2) + os.EOL, 'utf8');
162
+ + fs.renameSync(temporaryFile, outputFile);
163
+ + } catch (error) {
164
+ + try {
165
+ + if (temporaryFile) fs.rmSync(temporaryFile, { force: true });
166
+ + } catch {}
167
+ + if (!warned) {
168
+ + warned = true;
169
+ + console.warn(`[expo-ai-error] Could not write ${outputFile}: ${error.message}`);
170
+ + }
171
+ + }
172
+ + };
173
+ + const isCurrentBuild = (buildID, allowMissing = false)=>buildID == null ? allowMissing || activeBuildID == null : activeBuildID == null || buildID === activeBuildID;
174
+ + return {
175
+ + getState() {
176
+ + return state;
177
+ + },
178
+ + handleMetroEvent(event) {
179
+ + if (!event || typeof event !== 'object') return;
180
+ + const type = event.type;
181
+ + const buildID = event.buildID ?? event.bundleDetails?.buildID ?? null;
182
+ + if (type === 'bundle_build_started') {
183
+ + activeBuildID = buildID;
184
+ + lastFailedBuildID = null;
185
+ + publish({ schemaVersion: 1, status: 'compiling', buildID, error: null });
186
+ + return;
187
+ + }
188
+ + if (type === 'bundle_build_failed') {
189
+ + if (!isCurrentBuild(buildID)) return;
190
+ + lastFailedBuildID = buildID ?? activeBuildID;
191
+ + publish({
192
+ + schemaVersion: 1,
193
+ + status: 'failed',
194
+ + buildID: lastFailedBuildID,
195
+ + error: normalizeError(event.error ?? { type: 'MetroBundleError', message: 'Metro bundling failed' }, projectRoot, lastFailedBuildID)
196
+ + });
197
+ + return;
198
+ + }
199
+ + if (type === 'bundling_error') {
200
+ + const errorBuildID = buildID ?? lastFailedBuildID ?? activeBuildID;
201
+ + if (!isCurrentBuild(errorBuildID, true)) return;
202
+ + publish({
203
+ + schemaVersion: 1,
204
+ + status: 'failed',
205
+ + buildID: errorBuildID,
206
+ + error: normalizeError(event.error, projectRoot, errorBuildID)
207
+ + });
208
+ + return;
209
+ + }
210
+ + if (type === 'bundle_build_done') {
211
+ + if (!isCurrentBuild(buildID)) return;
212
+ + publish({ schemaVersion: 1, status: 'succeeded', buildID: buildID ?? activeBuildID, error: null });
213
+ + }
214
+ + }
215
+ + };
216
+ +}
217
+ +
218
+ +//# sourceMappingURL=aiErrorCollector.js.map
@@ -0,0 +1,218 @@
1
+ diff --git a/build/src/start/server/metro/instantiateMetro.js b/build/src/start/server/metro/instantiateMetro.js
2
+ --- a/build/src/start/server/metro/instantiateMetro.js
3
+ +++ b/build/src/start/server/metro/instantiateMetro.js
4
+ @@ -90,6 +90,7 @@
5
+ const _attachAtlas = require("./debugging/attachAtlas");
6
+ const _createDebugMiddleware = require("./debugging/createDebugMiddleware");
7
+ const _createMetroMiddleware = require("./dev-server/createMetroMiddleware");
8
+ +const _aiErrorCollector = require("./aiErrorCollector");
9
+ const _runServerfork = require("./runServer-fork");
10
+ const _withMetroMultiPlatform = require("./withMetroMultiPlatform");
11
+ const _events = require("../../../events");
12
+ @@ -274,6 +275,7 @@
13
+ const { middleware, messagesSocket, eventsSocket, websocketEndpoints } = (0, _createMetroMiddleware.createMetroMiddleware)(metroConfig, {
14
+ getMetroBundler
15
+ });
16
+ + const aiErrorCollector = !isExporting ? (0, _aiErrorCollector.createAiErrorCollector)(projectRoot) : null;
17
+ // Get local URL to Metro bundler server (typically configured as 127.0.0.1:8081)
18
+ const serverBaseUrl = metroBundler.getUrlCreator().constructUrl({
19
+ scheme: 'http',
20
+ @@ -348,7 +350,10 @@
21
+ }
22
+ }), fileBuffer);
23
+ };
24
+ - setEventReporter(eventsSocket.reportMetroEvent);
25
+ + setEventReporter((event)=>{
26
+ + eventsSocket.reportMetroEvent(event);
27
+ + aiErrorCollector == null ? void 0 : aiErrorCollector.handleMetroEvent(event);
28
+ + });
29
+ // This function ensures that modules in source maps are sorted in the same
30
+ // order as in a plain JS bundle.
31
+ metro._getSortedModules = function(graph) {
32
+ @@ -493,1 +498,1 @@
33
+ -//# sourceMappingURL=instantiateMetro.js.map
34
+
35
+ +//# sourceMappingURL=instantiateMetro.js.map
36
+ diff --git a/build/src/start/server/metro/aiErrorCollector.js b/build/src/start/server/metro/aiErrorCollector.js
37
+ new file mode 100644
38
+ --- /dev/null
39
+ +++ b/build/src/start/server/metro/aiErrorCollector.js
40
+ @@ -0,0 +1,178 @@
41
+ +"use strict";
42
+ +Object.defineProperty(exports, "__esModule", {
43
+ + value: true
44
+ +});
45
+ +Object.defineProperty(exports, "createAiErrorCollector", {
46
+ + enumerable: true,
47
+ + get: function() {
48
+ + return createAiErrorCollector;
49
+ + }
50
+ +});
51
+ +const fs = require("fs");
52
+ +const os = require("os");
53
+ +const path = require("path");
54
+ +
55
+ +const MAX_VALUE_DEPTH = 4;
56
+ +const MAX_STRING_LENGTH = 20000;
57
+ +
58
+ +function isEnabled() {
59
+ + return process.env.EXPO_AI_ERROR_COLLECTOR === '1';
60
+ +}
61
+ +
62
+ +function getOutputPath(projectRoot) {
63
+ + const configured = process.env.EXPO_AI_ERROR_FILE;
64
+ + if (!configured) return path.join(projectRoot, 'node_modules', '.miaoda-expo', 'ai-error.json');
65
+ + return path.isAbsolute(configured) ? configured : path.resolve(projectRoot, configured);
66
+ +}
67
+ +
68
+ +function toSerializable(value, depth = 0, seen = new Set()) {
69
+ + if (value == null || typeof value === 'boolean' || typeof value === 'number') return value;
70
+ + if (typeof value === 'string') return value.length > MAX_STRING_LENGTH ? value.slice(0, MAX_STRING_LENGTH) + '...[truncated]' : value;
71
+ + if (depth >= MAX_VALUE_DEPTH) return '[truncated]';
72
+ + if (typeof value === 'function' || typeof value === 'symbol') return String(value);
73
+ + if (seen.has(value)) return '[circular]';
74
+ + seen.add(value);
75
+ + if (value instanceof Error) {
76
+ + const error = {
77
+ + name: value.name,
78
+ + message: value.message,
79
+ + stack: value.stack
80
+ + };
81
+ + for (const key of Object.keys(value)) error[key] = toSerializable(value[key], depth + 1, seen);
82
+ + seen.delete(value);
83
+ + return error;
84
+ + }
85
+ + if (Array.isArray(value)) {
86
+ + const result = value.map((item)=>toSerializable(item, depth + 1, seen));
87
+ + seen.delete(value);
88
+ + return result;
89
+ + }
90
+ + if (typeof value === 'object') {
91
+ + const result = {};
92
+ + for (const key of Object.keys(value)) result[key] = toSerializable(value[key], depth + 1, seen);
93
+ + seen.delete(value);
94
+ + return result;
95
+ + }
96
+ + return String(value);
97
+ +}
98
+ +
99
+ +function normalizeError(error, projectRoot, buildID) {
100
+ + const raw = error && typeof error === 'object' ? error : {
101
+ + message: String(error ?? 'Metro bundling failed')
102
+ + };
103
+ + const message = String(raw.message ?? raw.reason ?? error ?? 'Metro bundling failed');
104
+ + const record = {
105
+ + schemaVersion: 1,
106
+ + id: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`,
107
+ + timestamp: new Date().toISOString(),
108
+ + source: 'metro',
109
+ + eventType: 'bundling_error',
110
+ + buildID: buildID ?? undefined,
111
+ + projectRoot,
112
+ + type: String(raw.type ?? raw.name ?? 'MetroError'),
113
+ + name: raw.name == null ? undefined : String(raw.name),
114
+ + message,
115
+ + filename: raw.filename == null ? undefined : String(raw.filename),
116
+ + lineNumber: typeof raw.lineNumber === 'number' ? raw.lineNumber : undefined,
117
+ + column: typeof raw.column === 'number' ? raw.column : undefined,
118
+ + errors: Array.isArray(raw.errors) ? toSerializable(raw.errors) : [],
119
+ + stack: raw.stack == null ? undefined : String(raw.stack),
120
+ + cause: raw.cause == null ? undefined : toSerializable(raw.cause)
121
+ + };
122
+ + const extra = {};
123
+ + for (const key of Object.keys(raw)) {
124
+ + if (!['type', 'name', 'message', 'filename', 'lineNumber', 'column', 'errors', 'stack', 'cause'].includes(key)) {
125
+ + extra[key] = toSerializable(raw[key]);
126
+ + }
127
+ + }
128
+ + if (Object.keys(extra).length) record.extra = extra;
129
+ + return omitUndefined(record);
130
+ +}
131
+ +
132
+ +function omitUndefined(value) {
133
+ + if (!value || typeof value !== 'object') return value;
134
+ + if (Array.isArray(value)) return value.map(omitUndefined);
135
+ + const result = {};
136
+ + for (const [key, item] of Object.entries(value)) {
137
+ + if (item !== undefined) result[key] = omitUndefined(item);
138
+ + }
139
+ + return result;
140
+ +}
141
+ +
142
+ +function createAiErrorCollector(projectRoot) {
143
+ + if (!isEnabled()) return null;
144
+ + const outputFile = getOutputPath(projectRoot);
145
+ + let activeBuildID = null;
146
+ + let lastFailedBuildID = null;
147
+ + let state = {
148
+ + schemaVersion: 1,
149
+ + status: 'compiling',
150
+ + buildID: null,
151
+ + updatedAt: new Date().toISOString(),
152
+ + error: null
153
+ + };
154
+ + let warned = false;
155
+ + const publish = (nextState)=>{
156
+ + state = omitUndefined({ ...nextState, updatedAt: new Date().toISOString() });
157
+ + let temporaryFile;
158
+ + try {
159
+ + fs.mkdirSync(path.dirname(outputFile), { recursive: true });
160
+ + temporaryFile = `${outputFile}.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
161
+ + fs.writeFileSync(temporaryFile, JSON.stringify(state, null, 2) + os.EOL, 'utf8');
162
+ + fs.renameSync(temporaryFile, outputFile);
163
+ + } catch (error) {
164
+ + try {
165
+ + if (temporaryFile) fs.rmSync(temporaryFile, { force: true });
166
+ + } catch {}
167
+ + if (!warned) {
168
+ + warned = true;
169
+ + console.warn(`[expo-ai-error] Could not write ${outputFile}: ${error.message}`);
170
+ + }
171
+ + }
172
+ + };
173
+ + const isCurrentBuild = (buildID, allowMissing = false)=>buildID == null ? allowMissing || activeBuildID == null : activeBuildID == null || buildID === activeBuildID;
174
+ + return {
175
+ + getState() {
176
+ + return state;
177
+ + },
178
+ + handleMetroEvent(event) {
179
+ + if (!event || typeof event !== 'object') return;
180
+ + const type = event.type;
181
+ + const buildID = event.buildID ?? event.bundleDetails?.buildID ?? null;
182
+ + if (type === 'bundle_build_started') {
183
+ + activeBuildID = buildID;
184
+ + lastFailedBuildID = null;
185
+ + publish({ schemaVersion: 1, status: 'compiling', buildID, error: null });
186
+ + return;
187
+ + }
188
+ + if (type === 'bundle_build_failed') {
189
+ + if (!isCurrentBuild(buildID)) return;
190
+ + lastFailedBuildID = buildID ?? activeBuildID;
191
+ + publish({
192
+ + schemaVersion: 1,
193
+ + status: 'failed',
194
+ + buildID: lastFailedBuildID,
195
+ + error: normalizeError(event.error ?? { type: 'MetroBundleError', message: 'Metro bundling failed' }, projectRoot, lastFailedBuildID)
196
+ + });
197
+ + return;
198
+ + }
199
+ + if (type === 'bundling_error') {
200
+ + const errorBuildID = buildID ?? lastFailedBuildID ?? activeBuildID;
201
+ + if (!isCurrentBuild(errorBuildID, true)) return;
202
+ + publish({
203
+ + schemaVersion: 1,
204
+ + status: 'failed',
205
+ + buildID: errorBuildID,
206
+ + error: normalizeError(event.error, projectRoot, errorBuildID)
207
+ + });
208
+ + return;
209
+ + }
210
+ + if (type === 'bundle_build_done') {
211
+ + if (!isCurrentBuild(buildID)) return;
212
+ + publish({ schemaVersion: 1, status: 'succeeded', buildID: buildID ?? activeBuildID, error: null });
213
+ + }
214
+ + }
215
+ + };
216
+ +}
217
+ +
218
+ +//# sourceMappingURL=aiErrorCollector.js.map