@react-native-harness/runtime 1.0.0-canary.1761046904277 → 1.0.0-canary.1761733411323
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.
- package/dist/bundler/bundle.d.ts.map +1 -1
- package/dist/bundler/bundle.js +1 -2
- package/dist/client/factory.d.ts.map +1 -1
- package/dist/client/factory.js +21 -64
- package/dist/client/setup-files.d.ts +12 -0
- package/dist/client/setup-files.d.ts.map +1 -0
- package/dist/client/setup-files.js +60 -0
- package/dist/collector/functions.d.ts +1 -1
- package/dist/collector/functions.d.ts.map +1 -1
- package/dist/collector/functions.js +2 -2
- package/dist/collector/types.d.ts +1 -1
- package/dist/collector/types.d.ts.map +1 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/render/ErrorBoundary.d.ts +17 -0
- package/dist/render/ErrorBoundary.d.ts.map +1 -0
- package/dist/render/ErrorBoundary.js +73 -0
- package/dist/render/TestComponentOverlay.d.ts +3 -0
- package/dist/render/TestComponentOverlay.d.ts.map +1 -0
- package/dist/render/TestComponentOverlay.js +36 -0
- package/dist/render/cleanup.d.ts +2 -0
- package/dist/render/cleanup.d.ts.map +1 -0
- package/dist/render/cleanup.js +6 -0
- package/dist/render/index.d.ts +6 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +66 -0
- package/dist/render/setup.d.ts +2 -0
- package/dist/render/setup.d.ts.map +1 -0
- package/dist/render/setup.js +7 -0
- package/dist/render/types.d.ts +12 -0
- package/dist/render/types.d.ts.map +1 -0
- package/dist/render/types.js +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/ui/ReadyScreen.d.ts.map +1 -1
- package/dist/ui/ReadyScreen.js +3 -10
- package/dist/ui/WrongEnvironmentScreen.d.ts.map +1 -1
- package/dist/ui/WrongEnvironmentScreen.js +2 -10
- package/dist/ui/state.d.ts +13 -0
- package/dist/ui/state.d.ts.map +1 -1
- package/dist/ui/state.js +22 -0
- package/package.json +2 -2
- package/src/__tests__/collector.test.ts +55 -55
- package/src/__tests__/error-handling.test.ts +34 -34
- package/src/bundler/bundle.ts +1 -2
- package/src/client/factory.ts +22 -70
- package/src/client/setup-files.ts +81 -0
- package/src/collector/functions.ts +4 -2
- package/src/collector/types.ts +4 -1
- package/src/constants.ts +0 -1
- package/src/index.ts +1 -0
- package/src/render/ErrorBoundary.tsx +108 -0
- package/src/render/TestComponentOverlay.tsx +47 -0
- package/src/render/cleanup.ts +7 -0
- package/src/render/index.ts +96 -0
- package/src/render/setup.ts +8 -0
- package/src/render/types.ts +11 -0
- package/src/ui/ReadyScreen.tsx +2 -12
- package/src/ui/WrongEnvironmentScreen.tsx +1 -19
- package/src/ui/state.ts +39 -0
- package/assets/logo.png +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/bundler/bundle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../src/bundler/bundle.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,WAAW,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAUlE,CAAC"}
|
package/dist/bundler/bundle.js
CHANGED
|
@@ -7,9 +7,8 @@ const getModuleUrl = (fileName) => {
|
|
|
7
7
|
const urlSearchParams = new URLSearchParams({
|
|
8
8
|
modulesOnly: 'true',
|
|
9
9
|
platform: Platform.OS,
|
|
10
|
-
'resolver.isHarness': 'true',
|
|
11
10
|
});
|
|
12
|
-
return `${devServerUrl}
|
|
11
|
+
return `${devServerUrl}${bundleName}?${urlSearchParams.toString()}`;
|
|
13
12
|
};
|
|
14
13
|
export const fetchModule = async (fileName) => {
|
|
15
14
|
const url = getModuleUrl(fileName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/client/factory.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,SAAS,2EAgFrB,CAAC"}
|
package/dist/client/factory.js
CHANGED
|
@@ -6,6 +6,8 @@ import { combineEventEmitters } from '../utils/emitter.js';
|
|
|
6
6
|
import { getWSServer } from './getWSServer.js';
|
|
7
7
|
import { getBundler, evaluateModule } from '../bundler/index.js';
|
|
8
8
|
import { markTestsAsSkippedByName } from '../filtering/index.js';
|
|
9
|
+
import { setup } from '../render/setup.js';
|
|
10
|
+
import { runSetupFiles } from './setup-files.js';
|
|
9
11
|
export const getClient = async () => {
|
|
10
12
|
const client = await getBridgeClient(getWSServer(), {
|
|
11
13
|
runTests: async () => {
|
|
@@ -29,71 +31,26 @@ export const getClient = async () => {
|
|
|
29
31
|
events.addListener((event) => {
|
|
30
32
|
client.rpc.emitEvent(event.type, event);
|
|
31
33
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
setupType: 'setupFiles',
|
|
40
|
-
});
|
|
41
|
-
try {
|
|
42
|
-
const setupModuleJs = await bundler.getModule(setupFile);
|
|
43
|
-
events.emit({
|
|
44
|
-
type: 'setup-file-bundling-finished',
|
|
45
|
-
file: setupFile,
|
|
46
|
-
setupType: 'setupFiles',
|
|
47
|
-
duration: Date.now() - startTime,
|
|
48
|
-
});
|
|
49
|
-
evaluateModule(setupModuleJs, setupFile);
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
53
|
-
events.emit({
|
|
54
|
-
type: 'setup-file-bundling-failed',
|
|
55
|
-
file: setupFile,
|
|
56
|
-
setupType: 'setupFiles',
|
|
57
|
-
duration: Date.now() - startTime,
|
|
58
|
-
error: errorMessage,
|
|
59
|
-
});
|
|
60
|
-
throw error;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (options.setupFilesAfterEnv) {
|
|
65
|
-
for (const setupFile of options.setupFilesAfterEnv) {
|
|
66
|
-
const startTime = Date.now();
|
|
67
|
-
events.emit({
|
|
68
|
-
type: 'setup-file-bundling-started',
|
|
69
|
-
file: setupFile,
|
|
70
|
-
setupType: 'setupFilesAfterEnv',
|
|
71
|
-
});
|
|
72
|
-
try {
|
|
73
|
-
const setupModuleJs = await bundler.getModule(setupFile);
|
|
74
|
-
events.emit({
|
|
75
|
-
type: 'setup-file-bundling-finished',
|
|
76
|
-
file: setupFile,
|
|
77
|
-
setupType: 'setupFilesAfterEnv',
|
|
78
|
-
duration: Date.now() - startTime,
|
|
79
|
-
});
|
|
80
|
-
evaluateModule(setupModuleJs, setupFile);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
84
|
-
events.emit({
|
|
85
|
-
type: 'setup-file-bundling-failed',
|
|
86
|
-
file: setupFile,
|
|
87
|
-
setupType: 'setupFilesAfterEnv',
|
|
88
|
-
duration: Date.now() - startTime,
|
|
89
|
-
error: errorMessage,
|
|
90
|
-
});
|
|
91
|
-
throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
34
|
+
await runSetupFiles({
|
|
35
|
+
setupFiles: options.setupFiles ?? [],
|
|
36
|
+
setupFilesAfterEnv: [],
|
|
37
|
+
events: events,
|
|
38
|
+
bundler: bundler,
|
|
39
|
+
evaluateModule,
|
|
40
|
+
});
|
|
95
41
|
const moduleJs = await bundler.getModule(path);
|
|
96
|
-
const collectionResult = await collector.collect(() =>
|
|
42
|
+
const collectionResult = await collector.collect(async () => {
|
|
43
|
+
await runSetupFiles({
|
|
44
|
+
setupFiles: [],
|
|
45
|
+
setupFilesAfterEnv: options.setupFilesAfterEnv ?? [],
|
|
46
|
+
events: events,
|
|
47
|
+
bundler: bundler,
|
|
48
|
+
evaluateModule,
|
|
49
|
+
});
|
|
50
|
+
// Setup automatic cleanup for rendered components
|
|
51
|
+
setup();
|
|
52
|
+
evaluateModule(moduleJs, path);
|
|
53
|
+
}, path);
|
|
97
54
|
// Apply test name pattern by marking non-matching tests as skipped
|
|
98
55
|
const processedTestSuite = options.testNamePattern
|
|
99
56
|
? markTestsAsSkippedByName(collectionResult.testSuite, options.testNamePattern)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EventEmitter } from '../utils/emitter.js';
|
|
2
|
+
import { Bundler } from '../bundler/index.js';
|
|
3
|
+
import { BundlerEvents } from '@react-native-harness/bridge';
|
|
4
|
+
export type RunSetupFilesOptions = {
|
|
5
|
+
setupFiles: string[];
|
|
6
|
+
setupFilesAfterEnv: string[];
|
|
7
|
+
events: EventEmitter<BundlerEvents>;
|
|
8
|
+
bundler: Bundler;
|
|
9
|
+
evaluateModule: (moduleJs: string, filePath: string) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare const runSetupFiles: ({ setupFiles, setupFilesAfterEnv, events, bundler, evaluateModule, }: RunSetupFilesOptions) => Promise<void>;
|
|
12
|
+
//# sourceMappingURL=setup-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-files.d.ts","sourceRoot":"","sources":["../../src/client/setup-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC,aAAa,CAAC,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9D,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,sEAMjC,oBAAoB,kBA8DtB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export const runSetupFiles = async ({ setupFiles, setupFilesAfterEnv, events, bundler, evaluateModule, }) => {
|
|
2
|
+
for (const setupFile of setupFiles) {
|
|
3
|
+
const startTime = Date.now();
|
|
4
|
+
events.emit({
|
|
5
|
+
type: 'setup-file-bundling-started',
|
|
6
|
+
file: setupFile,
|
|
7
|
+
setupType: 'setupFiles',
|
|
8
|
+
});
|
|
9
|
+
try {
|
|
10
|
+
const setupModuleJs = await bundler.getModule(setupFile);
|
|
11
|
+
events.emit({
|
|
12
|
+
type: 'setup-file-bundling-finished',
|
|
13
|
+
file: setupFile,
|
|
14
|
+
setupType: 'setupFiles',
|
|
15
|
+
duration: Date.now() - startTime,
|
|
16
|
+
});
|
|
17
|
+
evaluateModule(setupModuleJs, setupFile);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
21
|
+
events.emit({
|
|
22
|
+
type: 'setup-file-bundling-failed',
|
|
23
|
+
file: setupFile,
|
|
24
|
+
setupType: 'setupFiles',
|
|
25
|
+
duration: Date.now() - startTime,
|
|
26
|
+
error: errorMessage,
|
|
27
|
+
});
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
for (const setupFile of setupFilesAfterEnv) {
|
|
32
|
+
const startTime = Date.now();
|
|
33
|
+
events.emit({
|
|
34
|
+
type: 'setup-file-bundling-started',
|
|
35
|
+
file: setupFile,
|
|
36
|
+
setupType: 'setupFilesAfterEnv',
|
|
37
|
+
});
|
|
38
|
+
try {
|
|
39
|
+
const setupModuleJs = await bundler.getModule(setupFile);
|
|
40
|
+
events.emit({
|
|
41
|
+
type: 'setup-file-bundling-finished',
|
|
42
|
+
file: setupFile,
|
|
43
|
+
setupType: 'setupFilesAfterEnv',
|
|
44
|
+
duration: Date.now() - startTime,
|
|
45
|
+
});
|
|
46
|
+
evaluateModule(setupModuleJs, setupFile);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
50
|
+
events.emit({
|
|
51
|
+
type: 'setup-file-bundling-failed',
|
|
52
|
+
file: setupFile,
|
|
53
|
+
setupType: 'setupFilesAfterEnv',
|
|
54
|
+
duration: Date.now() - startTime,
|
|
55
|
+
error: errorMessage,
|
|
56
|
+
});
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
@@ -18,5 +18,5 @@ export declare function beforeAll(fn: TestFn): void;
|
|
|
18
18
|
export declare function afterAll(fn: TestFn): void;
|
|
19
19
|
export declare function beforeEach(fn: TestFn): void;
|
|
20
20
|
export declare function afterEach(fn: TestFn): void;
|
|
21
|
-
export declare const collectTests: (fn: () => void) => CollectionResult
|
|
21
|
+
export declare const collectTests: (fn: () => void | Promise<void>) => Promise<CollectionResult>;
|
|
22
22
|
//# sourceMappingURL=functions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/collector/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA4LzC,eAAO,MAAM,QAAQ,UACZ,MAAM,MAAM,MAAM,IAAI;iBAsBd,MAAM,MAAM,MAAM,IAAI;iBAqBtB,MAAM,MAAM,MAAM,IAAI;CAsBtC,CAAC;AAEF,eAAO,MAAM,IAAI,UACR,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAiBtB,CAAC;AAEF,eAAO,MAAM,EAAE,UAtDN,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAmBD,CAAC;AAEvB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,QAQlC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,QAQpC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAgBD,eAAO,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../../src/collector/functions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA4LzC,eAAO,MAAM,QAAQ,UACZ,MAAM,MAAM,MAAM,IAAI;iBAsBd,MAAM,MAAM,MAAM,IAAI;iBAqBtB,MAAM,MAAM,MAAM,IAAI;CAsBtC,CAAC;AAEF,eAAO,MAAM,IAAI,UACR,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAiBtB,CAAC;AAEF,eAAO,MAAM,EAAE,UAtDN,MAAM,MAAM,MAAM;iBAaV,MAAM,MAAM,MAAM;iBAWlB,MAAM,MAAM,MAAM;iBAWlB,MAAM;CAmBD,CAAC;AAEvB,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,QAQlC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,QAQpC;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,QAQnC;AAgBD,eAAO,MAAM,YAAY,GACvB,IAAI,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAC7B,OAAO,CAAC,gBAAgB,CAiB1B,CAAC"}
|
|
@@ -261,10 +261,10 @@ const countTests = (suite) => {
|
|
|
261
261
|
}
|
|
262
262
|
return count;
|
|
263
263
|
};
|
|
264
|
-
export const collectTests = (fn) => {
|
|
264
|
+
export const collectTests = async (fn) => {
|
|
265
265
|
currentContext = clearState();
|
|
266
266
|
try {
|
|
267
|
-
fn();
|
|
267
|
+
await fn();
|
|
268
268
|
// Convert raw structure to final structure using computation phase
|
|
269
269
|
const testSuite = convertRawTestSuiteToTestSuite(getRootSuite());
|
|
270
270
|
const totalTests = countTests(testSuite);
|
|
@@ -4,7 +4,7 @@ export type TestFn = () => void | Promise<void>;
|
|
|
4
4
|
export type TestCollectorEventsEmitter = EventEmitter<TestCollectorEvents>;
|
|
5
5
|
export type TestCollector = {
|
|
6
6
|
events: TestCollectorEventsEmitter;
|
|
7
|
-
collect: (fn: () => void
|
|
7
|
+
collect: (fn: () => void | Promise<void>, testFilePath: string) => Promise<CollectionResult>;
|
|
8
8
|
dispose: () => void;
|
|
9
9
|
};
|
|
10
10
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/collector/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD,MAAM,MAAM,0BAA0B,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,0BAA0B,CAAC;IACnC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/collector/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD,MAAM,MAAM,0BAA0B,GAAG,YAAY,CAAC,mBAAmB,CAAC,CAAC;AAE3E,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,0BAA0B,CAAC;IACnC,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC9B,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC"}
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,OAAO,CAAC"}
|
package/dist/constants.js
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,EAAE,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,gBAAgB,CAAC;AAExB,OAAO,EAAE,EAAE,IAAI,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACzD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type ErrorBoundaryProps = {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
};
|
|
5
|
+
type ErrorBoundaryState = {
|
|
6
|
+
hasError: boolean;
|
|
7
|
+
error: Error | null;
|
|
8
|
+
};
|
|
9
|
+
export declare class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
10
|
+
constructor(props: ErrorBoundaryProps);
|
|
11
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
12
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
|
|
13
|
+
componentDidUpdate(prevProps: ErrorBoundaryProps): void;
|
|
14
|
+
render(): React.ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=ErrorBoundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../src/render/ErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK,CAAC,SAAS,CAChD,kBAAkB,EAClB,kBAAkB,CACnB;gBACa,KAAK,EAAE,kBAAkB;IAKrC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB;IAIxD,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,GAAG,IAAI;IAIjE,kBAAkB,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI;IAOvD,MAAM,IAAI,KAAK,CAAC,SAAS;CAwBnC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { View, Text, StyleSheet, ScrollView } from 'react-native';
|
|
4
|
+
export class ErrorBoundary extends React.Component {
|
|
5
|
+
constructor(props) {
|
|
6
|
+
super(props);
|
|
7
|
+
this.state = { hasError: false, error: null };
|
|
8
|
+
}
|
|
9
|
+
static getDerivedStateFromError(error) {
|
|
10
|
+
return { hasError: true, error };
|
|
11
|
+
}
|
|
12
|
+
componentDidCatch(error, errorInfo) {
|
|
13
|
+
console.error('Error caught by ErrorBoundary:', error, errorInfo);
|
|
14
|
+
}
|
|
15
|
+
componentDidUpdate(prevProps) {
|
|
16
|
+
// Reset error state when children change (new component rendered)
|
|
17
|
+
if (prevProps.children !== this.props.children && this.state.hasError) {
|
|
18
|
+
this.setState({ hasError: false, error: null });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
render() {
|
|
22
|
+
if (this.state.hasError && this.state.error) {
|
|
23
|
+
return (_jsx(View, { style: styles.errorContainer, children: _jsxs(View, { style: styles.errorContent, children: [_jsx(Text, { style: styles.errorTitle, children: "Component Error" }), _jsx(Text, { style: styles.errorSubtitle, children: "The rendered component threw an error:" }), _jsxs(ScrollView, { style: styles.errorScrollView, children: [_jsx(Text, { style: styles.errorMessage, children: this.state.error.message }), this.state.error.stack && (_jsx(Text, { style: styles.errorStack, children: this.state.error.stack }))] })] }) }));
|
|
24
|
+
}
|
|
25
|
+
return this.props.children;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const styles = StyleSheet.create({
|
|
29
|
+
errorContainer: {
|
|
30
|
+
flex: 1,
|
|
31
|
+
backgroundColor: 'rgba(220, 38, 38, 0.1)',
|
|
32
|
+
justifyContent: 'center',
|
|
33
|
+
alignItems: 'center',
|
|
34
|
+
padding: 20,
|
|
35
|
+
},
|
|
36
|
+
errorContent: {
|
|
37
|
+
backgroundColor: '#1f2937',
|
|
38
|
+
borderRadius: 12,
|
|
39
|
+
padding: 20,
|
|
40
|
+
maxWidth: 500,
|
|
41
|
+
width: '100%',
|
|
42
|
+
maxHeight: '80%',
|
|
43
|
+
borderWidth: 2,
|
|
44
|
+
borderColor: '#dc2626',
|
|
45
|
+
},
|
|
46
|
+
errorTitle: {
|
|
47
|
+
fontSize: 24,
|
|
48
|
+
fontWeight: '700',
|
|
49
|
+
color: '#dc2626',
|
|
50
|
+
marginBottom: 8,
|
|
51
|
+
},
|
|
52
|
+
errorSubtitle: {
|
|
53
|
+
fontSize: 14,
|
|
54
|
+
color: '#9ca3af',
|
|
55
|
+
marginBottom: 16,
|
|
56
|
+
},
|
|
57
|
+
errorScrollView: {
|
|
58
|
+
maxHeight: 400,
|
|
59
|
+
},
|
|
60
|
+
errorMessage: {
|
|
61
|
+
fontSize: 16,
|
|
62
|
+
fontWeight: '600',
|
|
63
|
+
color: '#fca5a5',
|
|
64
|
+
marginBottom: 12,
|
|
65
|
+
fontFamily: 'Courier',
|
|
66
|
+
},
|
|
67
|
+
errorStack: {
|
|
68
|
+
fontSize: 12,
|
|
69
|
+
color: '#d1d5db',
|
|
70
|
+
fontFamily: 'Courier',
|
|
71
|
+
lineHeight: 18,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestComponentOverlay.d.ts","sourceRoot":"","sources":["../../src/render/TestComponentOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAMzC,eAAO,MAAM,oBAAoB,QAAO,KAAK,CAAC,YAAY,GAAG,IAgC5D,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { View, StyleSheet } from 'react-native';
|
|
4
|
+
import { useRenderedElement } from '../ui/state.js';
|
|
5
|
+
import { store } from '../ui/state.js';
|
|
6
|
+
import { ErrorBoundary } from './ErrorBoundary.js';
|
|
7
|
+
export const TestComponentOverlay = () => {
|
|
8
|
+
const { element, key } = useRenderedElement();
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
// Call onRenderCallback when element changes
|
|
11
|
+
const callback = store.getState().onRenderCallback;
|
|
12
|
+
if (callback) {
|
|
13
|
+
callback();
|
|
14
|
+
store.getState().setOnRenderCallback(null);
|
|
15
|
+
}
|
|
16
|
+
}, [element]);
|
|
17
|
+
if (!element) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const handleLayout = () => {
|
|
21
|
+
const callback = store.getState().onLayoutCallback;
|
|
22
|
+
if (callback) {
|
|
23
|
+
callback();
|
|
24
|
+
// Clear the callback after calling it
|
|
25
|
+
store.getState().setOnLayoutCallback(null);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return (_jsx(View, { style: styles.overlay, onLayout: handleLayout, children: _jsx(ErrorBoundary, { children: element }) }, key));
|
|
29
|
+
};
|
|
30
|
+
const styles = StyleSheet.create({
|
|
31
|
+
overlay: {
|
|
32
|
+
...StyleSheet.absoluteFillObject,
|
|
33
|
+
backgroundColor: '#0a1628',
|
|
34
|
+
zIndex: 1000,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/render/cleanup.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,QAAO,IAI1B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { RenderResult, RenderOptions } from './types.js';
|
|
3
|
+
export declare const render: (element: React.ReactElement, options?: RenderOptions) => Promise<RenderResult>;
|
|
4
|
+
export { cleanup } from './cleanup.js';
|
|
5
|
+
export type { RenderResult, RenderOptions } from './types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAY9D,eAAO,MAAM,MAAM,GACjB,SAAS,KAAK,CAAC,YAAY,EAC3B,UAAS,aAAkB,KAC1B,OAAO,CAAC,YAAY,CA2EtB,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { store } from '../ui/state.js';
|
|
3
|
+
const wrapElement = (element, wrapper) => {
|
|
4
|
+
if (!wrapper) {
|
|
5
|
+
return element;
|
|
6
|
+
}
|
|
7
|
+
return React.createElement(wrapper, { children: element });
|
|
8
|
+
};
|
|
9
|
+
export const render = async (element, options = {}) => {
|
|
10
|
+
const { timeout = 1000, wrapper } = options;
|
|
11
|
+
// If an element is already rendered, unmount it first
|
|
12
|
+
if (store.getState().renderedElement !== null) {
|
|
13
|
+
store.getState().setRenderedElement(null);
|
|
14
|
+
store.getState().setOnLayoutCallback(null);
|
|
15
|
+
store.getState().setOnRenderCallback(null);
|
|
16
|
+
}
|
|
17
|
+
// Create a promise that resolves when the element is laid out
|
|
18
|
+
const layoutPromise = new Promise((resolve, reject) => {
|
|
19
|
+
const timeoutId = setTimeout(() => {
|
|
20
|
+
store.getState().setOnLayoutCallback(null);
|
|
21
|
+
reject(new Error(`Render timeout: Element did not mount within ${timeout}ms`));
|
|
22
|
+
}, timeout);
|
|
23
|
+
store.getState().setOnLayoutCallback(() => {
|
|
24
|
+
clearTimeout(timeoutId);
|
|
25
|
+
resolve();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
// Wrap and set the element in state (key is generated automatically)
|
|
29
|
+
const wrappedElement = wrapElement(element, wrapper);
|
|
30
|
+
store.getState().setRenderedElement(wrappedElement);
|
|
31
|
+
// Wait for layout
|
|
32
|
+
await layoutPromise;
|
|
33
|
+
const rerender = async (newElement) => {
|
|
34
|
+
if (store.getState().renderedElement === null) {
|
|
35
|
+
throw new Error('No element is currently rendered. Call render() first.');
|
|
36
|
+
}
|
|
37
|
+
// Create a promise that resolves when the element is re-rendered
|
|
38
|
+
const renderPromise = new Promise((resolve, reject) => {
|
|
39
|
+
const timeoutId = setTimeout(() => {
|
|
40
|
+
store.getState().setOnRenderCallback(null);
|
|
41
|
+
reject(new Error(`Rerender timeout: Element did not update within ${timeout}ms`));
|
|
42
|
+
}, timeout);
|
|
43
|
+
store.getState().setOnRenderCallback(() => {
|
|
44
|
+
clearTimeout(timeoutId);
|
|
45
|
+
resolve();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
const wrappedNewElement = wrapElement(newElement, wrapper);
|
|
49
|
+
store.getState().updateRenderedElement(wrappedNewElement);
|
|
50
|
+
// Wait for render
|
|
51
|
+
await renderPromise;
|
|
52
|
+
};
|
|
53
|
+
const unmount = () => {
|
|
54
|
+
if (store.getState().renderedElement === null) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
store.getState().setRenderedElement(null);
|
|
58
|
+
store.getState().setOnLayoutCallback(null);
|
|
59
|
+
store.getState().setOnRenderCallback(null);
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
rerender,
|
|
63
|
+
unmount,
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
export { cleanup } from './cleanup.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/render/setup.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,KAAK,YAIjB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export type RenderResult = {
|
|
3
|
+
rerender: (element: React.ReactElement) => Promise<void>;
|
|
4
|
+
unmount: () => void;
|
|
5
|
+
};
|
|
6
|
+
export type RenderOptions = {
|
|
7
|
+
timeout?: number;
|
|
8
|
+
wrapper?: React.ComponentType<{
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
}>;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/render/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAC9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|