universal-test-renderer 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/index.cjs +69 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +64 -85
- package/dist/index.js.map +1 -1
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ test("example", () => {
|
|
|
29
29
|
renderer.render(<div>Hello!</div>);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
expect(renderer.root
|
|
32
|
+
expect(renderer.root).toMatchInlineSnapshot(`
|
|
33
33
|
<div>
|
|
34
34
|
Hello!
|
|
35
35
|
</div>
|
|
@@ -42,4 +42,3 @@ test("example", () => {
|
|
|
42
42
|
- Works at host component level only (no composite components)
|
|
43
43
|
- More flexible reconciler configuration options
|
|
44
44
|
- Uses `act` from the React package directly
|
|
45
|
-
|
package/dist/index.cjs
CHANGED
|
@@ -59,20 +59,36 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
59
59
|
// src/index.ts
|
|
60
60
|
var index_exports = {};
|
|
61
61
|
__export(index_exports, {
|
|
62
|
-
CONTAINER_TYPE: () => CONTAINER_TYPE,
|
|
63
62
|
createRoot: () => createRoot
|
|
64
63
|
});
|
|
65
64
|
module.exports = __toCommonJS(index_exports);
|
|
66
65
|
|
|
67
66
|
// src/renderer.ts
|
|
68
|
-
var
|
|
67
|
+
var import_constants2 = require("react-reconciler/constants");
|
|
69
68
|
|
|
70
|
-
// src/
|
|
71
|
-
|
|
69
|
+
// src/find-all.ts
|
|
70
|
+
function findAll(root, predicate, options) {
|
|
71
|
+
const results = [];
|
|
72
|
+
const matchingDescendants = [];
|
|
73
|
+
root.children.forEach((child) => {
|
|
74
|
+
if (typeof child === "string") {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
matchingDescendants.push(...findAll(child, predicate, options));
|
|
78
|
+
});
|
|
79
|
+
if (
|
|
80
|
+
// When matchDeepestOnly = true: add current element only if no descendants match
|
|
81
|
+
(!(options == null ? void 0 : options.matchDeepestOnly) || matchingDescendants.length === 0) && predicate(root)
|
|
82
|
+
) {
|
|
83
|
+
results.push(root);
|
|
84
|
+
}
|
|
85
|
+
results.push(...matchingDescendants);
|
|
86
|
+
return results;
|
|
87
|
+
}
|
|
72
88
|
|
|
73
89
|
// src/render-to-json.ts
|
|
74
90
|
function renderToJson(instance) {
|
|
75
|
-
if (
|
|
91
|
+
if (instance.isHidden) {
|
|
76
92
|
return null;
|
|
77
93
|
}
|
|
78
94
|
switch (instance.tag) {
|
|
@@ -97,35 +113,10 @@ function renderToJson(instance) {
|
|
|
97
113
|
type: instance.type,
|
|
98
114
|
props,
|
|
99
115
|
children: renderedChildren,
|
|
100
|
-
$$typeof: Symbol.for("react.test.json")
|
|
101
|
-
};
|
|
102
|
-
Object.defineProperty(result, "$$typeof", {
|
|
103
|
-
value: Symbol.for("react.test.json")
|
|
104
|
-
});
|
|
105
|
-
return result;
|
|
106
|
-
}
|
|
107
|
-
case "CONTAINER": {
|
|
108
|
-
let renderedChildren = null;
|
|
109
|
-
if (instance.children.length) {
|
|
110
|
-
for (let i = 0; i < instance.children.length; i++) {
|
|
111
|
-
const renderedChild = renderToJson(instance.children[i]);
|
|
112
|
-
if (renderedChild !== null) {
|
|
113
|
-
if (renderedChildren === null) {
|
|
114
|
-
renderedChildren = [renderedChild];
|
|
115
|
-
} else {
|
|
116
|
-
renderedChildren.push(renderedChild);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
const result = {
|
|
122
|
-
type: CONTAINER_TYPE,
|
|
123
|
-
props: {},
|
|
124
|
-
children: renderedChildren,
|
|
125
|
-
$$typeof: Symbol.for("react.test.json")
|
|
116
|
+
$$typeof: /* @__PURE__ */ Symbol.for("react.test.json")
|
|
126
117
|
};
|
|
127
118
|
Object.defineProperty(result, "$$typeof", {
|
|
128
|
-
value: Symbol.for("react.test.json")
|
|
119
|
+
value: /* @__PURE__ */ Symbol.for("react.test.json")
|
|
129
120
|
});
|
|
130
121
|
return result;
|
|
131
122
|
}
|
|
@@ -133,74 +124,61 @@ function renderToJson(instance) {
|
|
|
133
124
|
}
|
|
134
125
|
|
|
135
126
|
// src/host-element.ts
|
|
136
|
-
var
|
|
127
|
+
var instanceMap = /* @__PURE__ */ new WeakMap();
|
|
137
128
|
var HostElement = class _HostElement {
|
|
138
129
|
constructor(instance) {
|
|
139
130
|
this.instance = instance;
|
|
140
131
|
}
|
|
141
132
|
get type() {
|
|
142
|
-
return this.instance.
|
|
133
|
+
return this.instance.type;
|
|
143
134
|
}
|
|
144
135
|
get props() {
|
|
145
|
-
if (this.instance.tag === "CONTAINER") {
|
|
146
|
-
return {};
|
|
147
|
-
}
|
|
148
136
|
const _a = this.instance.props, { children } = _a, restProps = __objRest(_a, ["children"]);
|
|
149
137
|
return restProps;
|
|
150
138
|
}
|
|
151
139
|
get children() {
|
|
152
|
-
const result = this.instance.children.filter((child) => !child.isHidden).map((child) =>
|
|
140
|
+
const result = this.instance.children.filter((child) => !child.isHidden).map((child) => getHostNodeForInstance(child));
|
|
153
141
|
return result;
|
|
154
142
|
}
|
|
155
143
|
get parent() {
|
|
156
144
|
const parentInstance = this.instance.parent;
|
|
157
|
-
if (parentInstance == null) {
|
|
145
|
+
if (parentInstance == null || parentInstance.tag === "CONTAINER") {
|
|
158
146
|
return null;
|
|
159
147
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return _HostElement.fromContainer(parentInstance);
|
|
165
|
-
}
|
|
148
|
+
return _HostElement.fromInstance(parentInstance);
|
|
149
|
+
}
|
|
150
|
+
get unstable_fiber() {
|
|
151
|
+
return this.instance.unstable_fiber;
|
|
166
152
|
}
|
|
167
153
|
get $$typeof() {
|
|
168
|
-
return Symbol.for("react.test.json");
|
|
154
|
+
return /* @__PURE__ */ Symbol.for("react.test.json");
|
|
169
155
|
}
|
|
170
156
|
toJSON() {
|
|
171
157
|
return renderToJson(this.instance);
|
|
172
158
|
}
|
|
173
159
|
/** @internal */
|
|
174
|
-
static
|
|
175
|
-
const hostElement =
|
|
160
|
+
static fromInstance(instance) {
|
|
161
|
+
const hostElement = instanceMap.get(instance);
|
|
176
162
|
if (hostElement) {
|
|
177
163
|
return hostElement;
|
|
178
164
|
}
|
|
179
|
-
const result = new _HostElement(
|
|
180
|
-
|
|
165
|
+
const result = new _HostElement(instance);
|
|
166
|
+
instanceMap.set(instance, result);
|
|
181
167
|
return result;
|
|
182
168
|
}
|
|
183
|
-
/** @internal */
|
|
184
|
-
static fromInstance(instance) {
|
|
185
|
-
switch (instance.tag) {
|
|
186
|
-
case "TEXT":
|
|
187
|
-
return instance.text;
|
|
188
|
-
case "INSTANCE": {
|
|
189
|
-
const hostElement = instanceToHostElementMap.get(instance);
|
|
190
|
-
if (hostElement) {
|
|
191
|
-
return hostElement;
|
|
192
|
-
}
|
|
193
|
-
const result = new _HostElement(instance);
|
|
194
|
-
instanceToHostElementMap.set(instance, result);
|
|
195
|
-
return result;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
169
|
};
|
|
170
|
+
function getHostNodeForInstance(instance) {
|
|
171
|
+
switch (instance.tag) {
|
|
172
|
+
case "TEXT":
|
|
173
|
+
return instance.text;
|
|
174
|
+
case "INSTANCE":
|
|
175
|
+
return HostElement.fromInstance(instance);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
200
178
|
|
|
201
179
|
// src/reconciler.ts
|
|
202
180
|
var import_react_reconciler = __toESM(require("react-reconciler"), 1);
|
|
203
|
-
var
|
|
181
|
+
var import_constants = require("react-reconciler/constants");
|
|
204
182
|
|
|
205
183
|
// src/utils.ts
|
|
206
184
|
function formatComponentList(names) {
|
|
@@ -220,7 +198,7 @@ function formatComponentList(names) {
|
|
|
220
198
|
|
|
221
199
|
// src/reconciler.ts
|
|
222
200
|
var nodeToInstanceMap = /* @__PURE__ */ new WeakMap();
|
|
223
|
-
var currentUpdatePriority =
|
|
201
|
+
var currentUpdatePriority = import_constants.NoEventPriority;
|
|
224
202
|
var hostConfig = {
|
|
225
203
|
/**
|
|
226
204
|
* The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.
|
|
@@ -291,7 +269,7 @@ var hostConfig = {
|
|
|
291
269
|
children: [],
|
|
292
270
|
parent: null,
|
|
293
271
|
rootContainer,
|
|
294
|
-
internalHandle
|
|
272
|
+
unstable_fiber: internalHandle
|
|
295
273
|
};
|
|
296
274
|
},
|
|
297
275
|
/**
|
|
@@ -370,7 +348,7 @@ var hostConfig = {
|
|
|
370
348
|
return currentUpdatePriority;
|
|
371
349
|
},
|
|
372
350
|
resolveUpdatePriority() {
|
|
373
|
-
return currentUpdatePriority ||
|
|
351
|
+
return currentUpdatePriority || import_constants.DefaultEventPriority;
|
|
374
352
|
},
|
|
375
353
|
shouldAttemptEagerTransition() {
|
|
376
354
|
return false;
|
|
@@ -514,7 +492,7 @@ var hostConfig = {
|
|
|
514
492
|
getInstanceFromNode(node) {
|
|
515
493
|
const instance = nodeToInstanceMap.get(node);
|
|
516
494
|
if (instance !== void 0) {
|
|
517
|
-
return instance.
|
|
495
|
+
return instance.unstable_fiber;
|
|
518
496
|
}
|
|
519
497
|
return null;
|
|
520
498
|
},
|
|
@@ -643,7 +621,7 @@ var hostConfig = {
|
|
|
643
621
|
commitUpdate(instance, type, _prevProps, nextProps, internalHandle) {
|
|
644
622
|
instance.type = type;
|
|
645
623
|
instance.props = nextProps;
|
|
646
|
-
instance.
|
|
624
|
+
instance.unstable_fiber = internalHandle;
|
|
647
625
|
},
|
|
648
626
|
/**
|
|
649
627
|
* #### `hideInstance(instance)`
|
|
@@ -786,12 +764,12 @@ function createRoot(options) {
|
|
|
786
764
|
parent: null,
|
|
787
765
|
config: {
|
|
788
766
|
textComponents: options == null ? void 0 : options.textComponents,
|
|
789
|
-
createNodeMock: (_a = options == null ? void 0 : options.createNodeMock) != null ? _a : () => ({})
|
|
767
|
+
createNodeMock: (_a = options == null ? void 0 : options.createNodeMock) != null ? _a : (() => ({}))
|
|
790
768
|
}
|
|
791
769
|
};
|
|
792
770
|
let containerFiber = TestReconciler.createContainer(
|
|
793
771
|
container,
|
|
794
|
-
|
|
772
|
+
import_constants2.ConcurrentRoot,
|
|
795
773
|
null,
|
|
796
774
|
// hydration callbacks
|
|
797
775
|
false,
|
|
@@ -824,33 +802,33 @@ function createRoot(options) {
|
|
|
824
802
|
container = null;
|
|
825
803
|
containerFiber = null;
|
|
826
804
|
};
|
|
805
|
+
const getRoot = () => {
|
|
806
|
+
if (containerFiber == null || container == null) {
|
|
807
|
+
throw new Error("Can't access .root on unmounted test renderer");
|
|
808
|
+
}
|
|
809
|
+
if (container.children.length === 0) {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
const firstChild = container.children[0];
|
|
813
|
+
if (firstChild.tag === "TEXT") {
|
|
814
|
+
throw new Error("Cannot render text as root element");
|
|
815
|
+
}
|
|
816
|
+
return HostElement.fromInstance(firstChild);
|
|
817
|
+
};
|
|
827
818
|
return {
|
|
828
819
|
render,
|
|
829
820
|
unmount,
|
|
830
821
|
get root() {
|
|
831
|
-
|
|
832
|
-
throw new Error("Can't access .root on unmounted test renderer");
|
|
833
|
-
}
|
|
834
|
-
if (container.children.length === 0) {
|
|
835
|
-
return null;
|
|
836
|
-
}
|
|
837
|
-
const root = HostElement.fromInstance(container.children[0]);
|
|
838
|
-
if (typeof root === "string") {
|
|
839
|
-
throw new Error("Cannot render string as root element");
|
|
840
|
-
}
|
|
841
|
-
return root;
|
|
822
|
+
return getRoot();
|
|
842
823
|
},
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}
|
|
847
|
-
return HostElement.fromContainer(container);
|
|
824
|
+
findAll: (predicate, options2) => {
|
|
825
|
+
const root = getRoot();
|
|
826
|
+
return root != null ? findAll(root, predicate, options2) : [];
|
|
848
827
|
}
|
|
849
828
|
};
|
|
850
829
|
}
|
|
851
830
|
// Annotate the CommonJS export names for ESM import in node:
|
|
852
831
|
0 && (module.exports = {
|
|
853
|
-
CONTAINER_TYPE,
|
|
854
832
|
createRoot
|
|
855
833
|
});
|
|
856
834
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/renderer.ts","../src/constants.ts","../src/render-to-json.ts","../src/host-element.ts","../src/reconciler.ts","../src/utils.ts"],"sourcesContent":["export { createRoot } from \"./renderer\";\nexport { CONTAINER_TYPE } from \"./constants\";\n\nexport type { Root, RootOptions } from \"./renderer\";\nexport type { HostElement, HostElementProps, HostNode } from \"./host-element\";\nexport type { JsonElement, JsonNode } from \"./render-to-json\";\n","import type { ReactElement } from \"react\";\nimport type { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot } from \"react-reconciler/constants\";\n\nimport { HostElement } from \"./host-element\";\nimport type { Container} from \"./reconciler\";\nimport { TestReconciler } from \"./reconciler\";\n\n// Refs:\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-noop-renderer/src/createReactNoop.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactNativeHostConfig.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactFabricHostConfig.js\n\nexport type RootOptions = {\n textComponents?: string[];\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Root = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n container: HostElement;\n root: HostElement | null;\n};\n\nexport function createRoot(options?: RootOptions): Root {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n config: {\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n ConcurrentRoot,\n null, // hydration callbacks\n false, // isStrictMode\n null, // concurrentUpdatesByDefaultOverride\n \"id\", // identifierPrefix\n () => {}, // onUncaughtError\n () => {}, // onCaughtError\n // @ts-expect-error missing types\n () => {}, // onRecoverableError\n null, // transitionCallbacks\n );\n\n const render = (element: ReactElement) => {\n TestReconciler.updateContainer(element, containerFiber, null, null);\n };\n\n const unmount = () => {\n if (containerFiber == null || container == null) {\n return;\n }\n\n TestReconciler.updateContainer(null, containerFiber, null, null);\n\n container = null;\n containerFiber = null;\n };\n\n return {\n render,\n unmount,\n get root(): HostElement | null {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .root on unmounted test renderer\");\n }\n\n if (container.children.length === 0) {\n return null;\n }\n\n const root = HostElement.fromInstance(container.children[0]);\n if (typeof root === \"string\") {\n throw new Error(\"Cannot render string as root element\");\n }\n\n return root;\n },\n\n get container(): HostElement {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .container on unmounted test renderer\");\n }\n\n return HostElement.fromContainer(container);\n },\n };\n}\n","export const CONTAINER_TYPE = \"CONTAINER\";\n","import { CONTAINER_TYPE } from \"./constants\";\nimport type { Container, Instance, TextInstance } from \"./reconciler\";\n\nexport type JsonNode = JsonElement | string;\n\nexport type JsonElement = {\n type: string;\n props: object;\n children: Array<JsonNode> | null;\n $$typeof: symbol;\n};\n\nexport function renderToJson(instance: Container | Instance | TextInstance): JsonNode | null {\n if (`isHidden` in instance && instance.isHidden) {\n // Omit timed out children from output entirely. This seems like the least\n // surprising behavior. We could perhaps add a separate API that includes\n // them, if it turns out people need it.\n return null;\n }\n\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\": {\n // We don't include the `children` prop in JSON.\n // Instead, we will include the actual rendered children.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...props } = instance.props;\n\n let renderedChildren = null;\n if (instance.children.length) {\n for (let i = 0; i < instance.children.length; i++) {\n const renderedChild = renderToJson(instance.children[i]);\n if (renderedChild !== null) {\n if (renderedChildren === null) {\n renderedChildren = [renderedChild];\n } else {\n renderedChildren.push(renderedChild);\n }\n }\n }\n }\n\n const result = {\n type: instance.type,\n props: props,\n children: renderedChildren,\n $$typeof: Symbol.for(\"react.test.json\"),\n };\n // This is needed for JEST to format snapshot as JSX.\n Object.defineProperty(result, \"$$typeof\", {\n value: Symbol.for(\"react.test.json\"),\n });\n return result;\n }\n\n case \"CONTAINER\": {\n let renderedChildren = null;\n if (instance.children.length) {\n for (let i = 0; i < instance.children.length; i++) {\n const renderedChild = renderToJson(instance.children[i]);\n if (renderedChild !== null) {\n if (renderedChildren === null) {\n renderedChildren = [renderedChild];\n } else {\n renderedChildren.push(renderedChild);\n }\n }\n }\n }\n\n const result = {\n type: CONTAINER_TYPE,\n props: {},\n children: renderedChildren,\n $$typeof: Symbol.for(\"react.test.json\"),\n };\n // This is needed for JEST to format snapshot as JSX.\n Object.defineProperty(result, \"$$typeof\", {\n value: Symbol.for(\"react.test.json\"),\n });\n return result;\n }\n }\n}\n\nexport function renderChildrenToJson(children: Array<Instance | TextInstance> | null) {\n let result = null;\n if (children?.length) {\n for (let i = 0; i < children.length; i++) {\n const renderedChild = renderToJson(children[i]);\n if (renderedChild !== null) {\n if (result === null) {\n result = [renderedChild];\n } else {\n result.push(renderedChild);\n }\n }\n }\n }\n\n return result;\n}\n","import { CONTAINER_TYPE } from \"./constants\";\nimport type { Container, Instance, TextInstance } from \"./reconciler\";\nimport type { JsonNode} from \"./render-to-json\";\nimport { renderToJson } from \"./render-to-json\";\n\nexport type HostNode = HostElement | string;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type HostElementProps = Record<string, any>;\n\nconst instanceToHostElementMap = new WeakMap<Container | Instance, HostElement>();\n\nexport class HostElement {\n private instance: Instance | Container;\n\n private constructor(instance: Instance | Container) {\n this.instance = instance;\n }\n\n get type(): string {\n return this.instance.tag === \"INSTANCE\" ? this.instance.type : CONTAINER_TYPE;\n }\n\n get props(): HostElementProps {\n if (this.instance.tag === \"CONTAINER\") {\n return {};\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...restProps } = this.instance.props;\n return restProps;\n }\n\n get children(): HostNode[] {\n const result = this.instance.children\n .filter((child) => !child.isHidden)\n .map((child) => HostElement.fromInstance(child));\n return result;\n }\n\n get parent(): HostElement | null {\n const parentInstance = this.instance.parent;\n if (parentInstance == null) {\n return null;\n }\n\n switch (parentInstance.tag) {\n case \"INSTANCE\":\n return HostElement.fromInstance(parentInstance) as HostElement;\n\n case \"CONTAINER\":\n return HostElement.fromContainer(parentInstance);\n }\n }\n\n get $$typeof(): symbol {\n return Symbol.for(\"react.test.json\");\n }\n\n toJSON(): JsonNode | null {\n return renderToJson(this.instance);\n }\n\n /** @internal */\n static fromContainer(container: Container): HostElement {\n const hostElement = instanceToHostElementMap.get(container);\n if (hostElement) {\n return hostElement;\n }\n\n const result = new HostElement(container);\n instanceToHostElementMap.set(container, result);\n return result;\n }\n\n /** @internal */\n static fromInstance(instance: Instance | TextInstance): HostNode {\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\": {\n const hostElement = instanceToHostElementMap.get(instance);\n if (hostElement) {\n return hostElement;\n }\n\n const result = new HostElement(instance);\n instanceToHostElementMap.set(instance, result);\n return result;\n }\n }\n }\n}\n","import type { ReactElement } from \"react\";\nimport type { Fiber } from \"react-reconciler\";\nimport ReactReconciler from \"react-reconciler\";\nimport {\n DefaultEventPriority,\n // @ts-expect-error missing types\n NoEventPriority,\n} from \"react-reconciler/constants\";\n\nimport { formatComponentList } from \"./utils\";\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\nexport type OpaqueHandle = Fiber;\n\ntype ReconcilerConfig = {\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\n};\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n config: ReconcilerConfig;\n};\n\nexport type Instance = {\n tag: \"INSTANCE\";\n type: string;\n props: Props;\n children: Array<Instance | TextInstance>;\n parent: Container | Instance | null;\n rootContainer: Container;\n isHidden: boolean;\n internalHandle: OpaqueHandle;\n};\n\nexport type TextInstance = {\n tag: \"TEXT\";\n text: string;\n parent: Container | Instance | null;\n isHidden: boolean;\n};\n\nexport type SuspenseInstance = object;\nexport type HydratableInstance = object;\nexport type PublicInstance = object | TextInstance;\nexport type UpdatePayload = unknown;\nexport type ChildSet = unknown;\nexport type TimeoutHandle = unknown;\nexport type NoTimeout = unknown;\n\ntype HostContext = {\n type: string;\n isInsideText: boolean;\n config: ReconcilerConfig;\n};\n\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nlet currentUpdatePriority: number = NoEventPriority;\n\nconst hostConfig: ReactReconciler.HostConfig<\n Type,\n Props,\n Container,\n Instance,\n TextInstance,\n SuspenseInstance,\n HydratableInstance,\n PublicInstance,\n HostContext,\n UpdatePayload,\n ChildSet,\n TimeoutHandle,\n NoTimeout\n> = {\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform is similar to the DOM and has methods similar to `appendChild`, `removeChild`,\n * and so on, you'll want to use the **mutation mode**. This is the same mode used by React DOM, React ART,\n * and the classic React Native renderer.\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsMutation: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsMutation: true,\n\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform has immutable trees, you'll want the **persistent mode** instead. In that mode,\n * existing nodes are never mutated, and instead every change clones the parent tree and then replaces\n * the whole parent tree at the root. This is the node used by the new React Native renderer, codenamed \"Fabric\".\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsPersistence: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsPersistence: false,\n\n /**\n * #### `createInstance(type, props, rootContainer, hostContext, internalHandle)`\n *\n * This method should return a newly created node. For example, the DOM renderer would call\n * `document.createElement(type)` here and then set the properties from `props`.\n *\n * You can use `rootContainer` to access the root container associated with that tree. For example,\n * in the DOM renderer, this is useful to get the correct `document` reference that the root belongs to.\n *\n * The `hostContext` parameter lets you keep track of some information about your current place in\n * the tree. To learn more about it, see `getChildHostContext` below.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its\n * internal fields, be aware that it may change significantly between versions. You're taking on additional\n * maintenance risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * This method happens **in the render phase**. It can (and usually should) mutate the node it has\n * just created before returning it, but it must not modify any other nodes. It must not register\n * any event handlers on the parent tree. This is because an instance being created doesn't guarantee\n * it would be placed in the tree — it could be left unused and later collected by GC. If you need to do\n * something when an instance is definitely in the tree, look at `commitMount` instead.\n */\n createInstance(\n type: Type,\n props: Props,\n rootContainer: Container,\n _hostContext: HostContext,\n internalHandle: OpaqueHandle,\n ) {\n return {\n tag: \"INSTANCE\",\n type,\n props,\n isHidden: false,\n children: [],\n parent: null,\n rootContainer,\n internalHandle,\n };\n },\n\n /**\n * #### `createTextInstance(text, rootContainer, hostContext, internalHandle)`\n *\n * Same as `createInstance`, but for text nodes. If your renderer doesn't support text nodes, you can\n * throw here.\n */\n createTextInstance(\n text: string,\n rootContainer: Container,\n hostContext: HostContext,\n _internalHandle: OpaqueHandle,\n ): TextInstance {\n if (rootContainer.config.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.config.textComponents,\n )} component. Detected attempt to render \"${text}\" string within a <${\n hostContext.type\n }> component.`,\n );\n }\n\n return {\n tag: \"TEXT\",\n text,\n parent: null,\n isHidden: false,\n };\n },\n\n /**\n * #### `appendInitialChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children.\n * For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * This method happens **in the render phase**. It can mutate `parentInstance` and `child`, but it\n * must not modify any other nodes. It's called while the tree is still being built up and not connected\n * to the actual tree on the screen.\n */\n appendInitialChild: appendChild,\n\n /**\n * #### `finalizeInitialChildren(instance, type, props, rootContainer, hostContext)`\n *\n * In this method, you can perform some final mutations on the `instance`. Unlike with `createInstance`,\n * by the time `finalizeInitialChildren` is called, all the initial children have already been added to\n * the `instance`, but the instance itself has not yet been connected to the tree on the screen.\n *\n * This method happens **in the render phase**. It can mutate `instance`, but it must not modify any other\n * nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.\n *\n * There is a second purpose to this method. It lets you specify whether there is some work that needs to\n * happen when the node is connected to the tree on the screen. If you return `true`, the instance will\n * receive a `commitMount` call later. See its documentation below.\n *\n * If you don't want to do anything here, you should return `false`.\n */\n finalizeInitialChildren(\n _instance: Instance,\n _type: Type,\n _props: Props,\n _rootContainer: Container,\n _hostContext: HostContext,\n ): boolean {\n return false;\n },\n\n /**\n * #### `shouldSetTextContent(type, props)`\n *\n * Some target platforms support setting an instance's text content without manually creating a text node.\n * For example, in the DOM, you can set `node.textContent` instead of creating a text node and appending it.\n *\n * If you return `true` from this method, React will assume that this node's children are text, and will\n * not create nodes for them. It will instead rely on you to have filled that text during `createInstance`.\n * This is a performance optimization. For example, the DOM renderer returns `true` only if `type` is a\n * known text-only parent (like `'textarea'`) or if `props.children` has a `'string'` type. If you return `true`,\n * you will need to implement `resetTextContent` too.\n *\n * If you don't want to do anything here, you should return `false`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n shouldSetTextContent(_type: Type, _props: Props): boolean {\n return false;\n },\n\n setCurrentUpdatePriority(newPriority: number) {\n currentUpdatePriority = newPriority;\n },\n\n getCurrentUpdatePriority() {\n return currentUpdatePriority;\n },\n\n resolveUpdatePriority(): number {\n return currentUpdatePriority || DefaultEventPriority;\n },\n\n shouldAttemptEagerTransition() {\n return false;\n },\n\n /**\n * #### `getRootHostContext(rootContainer)`\n *\n * This method lets you return the initial host context from the root of the tree. See `getChildHostContext`\n * for the explanation of host context.\n *\n * If you don't intend to use host context, you can return `null`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getRootHostContext(rootContainer: Container): HostContext | null {\n return {\n type: \"ROOT\",\n config: rootContainer.config,\n isInsideText: false,\n };\n },\n\n /**\n * #### `getChildHostContext(parentHostContext, type, rootContainer)`\n *\n * Host context lets you track some information about where you are in the tree so that it's available\n * inside `createInstance` as the `hostContext` parameter. For example, the DOM renderer uses it to track\n * whether it's inside an HTML or an SVG tree, because `createInstance` implementation needs to be\n * different for them.\n *\n * If the node of this `type` does not influence the context you want to pass down, you can return\n * `parentHostContext`. Alternatively, you can return any custom object representing the information\n * you want to pass down.\n *\n * If you don't want to do anything here, return `parentHostContext`.\n *\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getChildHostContext(parentHostContext: HostContext, type: Type): HostContext {\n const isInsideText = Boolean(parentHostContext.config.textComponents?.includes(type));\n return { ...parentHostContext, type: type, isInsideText };\n },\n\n /**\n * #### `getPublicInstance(instance)`\n *\n * Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But\n * in some cases it might make sense to only expose some part of it.\n *\n * If you don't want to do anything here, return `instance`.\n */\n getPublicInstance(instance: Instance | TextInstance): PublicInstance {\n switch (instance.tag) {\n case \"INSTANCE\": {\n const createNodeMock = instance.rootContainer.config.createNodeMock;\n const mockNode = createNodeMock({\n type: instance.type,\n props: instance.props,\n key: null,\n });\n\n //if (typeof mockNode === \"object\" && mockNode !== null) {\n nodeToInstanceMap.set(mockNode, instance);\n //}\n\n return mockNode;\n }\n\n default:\n return instance;\n }\n },\n\n /**\n * #### `prepareForCommit(containerInfo)`\n *\n * This method lets you store some information before React starts making changes to the tree on\n * the screen. For example, the DOM renderer stores the current text selection so that it can later\n * restore it. This method is mirrored by `resetAfterCommit`.\n *\n * Even if you don't want to do anything here, you need to return `null` from it.\n */\n prepareForCommit(_containerInfo: Container) {\n return null; // noop\n },\n\n /**\n * #### `resetAfterCommit(containerInfo)`\n *\n * This method is called right after React has performed the tree mutations. You can use it to restore\n * something you've stored in `prepareForCommit` — for example, text selection.\n *\n * You can leave it empty.\n */\n resetAfterCommit(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `preparePortalMount(containerInfo)`\n *\n * This method is called for a container that's used as a portal target. Usually you can leave it empty.\n */\n preparePortalMount(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `scheduleTimeout(fn, delay)`\n *\n * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n\n /**\n * #### `cancelTimeout(id)`\n *\n * You can proxy this to `clearTimeout` or its equivalent in your environment.\n */\n cancelTimeout: clearTimeout,\n\n /**\n * #### `noTimeout`\n *\n * This is a property (not a function) that should be set to something that can never be a valid timeout ID.\n * For example, you can set it to `-1`.\n */\n noTimeout: -1,\n\n /**\n * #### `supportsMicrotasks`\n *\n * Set this to `true` to indicate that your renderer supports `scheduleMicrotask`. We use microtasks as part\n * of our discrete event implementation in React DOM. If you're not sure if your renderer should support this,\n * you probably should. The option to not implement `scheduleMicrotask` exists so that platforms with more control\n * over user events, like React Native, can choose to use a different mechanism.\n */\n supportsMicrotasks: true,\n\n /**\n * #### `scheduleMicrotask(fn)`\n *\n * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\n /**\n * #### `isPrimaryRenderer`\n *\n * This is a property (not a function) that should be set to `true` if your renderer is the main one on the\n * page. For example, if you're writing a renderer for the Terminal, it makes sense to set it to `true`, but\n * if your renderer is used *on top of* React DOM or some other existing renderer, set it to `false`.\n */\n isPrimaryRenderer: true,\n\n /**\n * Whether the renderer shouldn't trigger missing `act()` warnings\n */\n warnsIfNotActing: true,\n\n getInstanceFromNode(node: object): OpaqueHandle | null | undefined {\n const instance = nodeToInstanceMap.get(node);\n if (instance !== undefined) {\n return instance.internalHandle;\n }\n\n return null;\n },\n\n beforeActiveInstanceBlur(): void {\n // noop\n },\n\n afterActiveInstanceBlur(): void {\n // noop\n },\n\n prepareScopeUpdate(scopeInstance: object, instance: Instance): void {\n nodeToInstanceMap.set(scopeInstance, instance);\n },\n\n getInstanceFromScope(scopeInstance: object): Instance | null {\n return nodeToInstanceMap.get(scopeInstance) ?? null;\n },\n\n detachDeletedInstance(_node: Instance): void {},\n\n /**\n * #### `appendChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree, look at `commitMount`.\n */\n appendChild: appendChild,\n\n /**\n * #### `appendChildToContainer(container, child)`\n *\n * Same as `appendChild`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different\n * type than the rest of the tree.\n */\n appendChildToContainer: appendChild,\n\n /**\n * #### `insertBefore(parentInstance, child, beforeChild)`\n *\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list of\n * its children. For example, in the DOM this would translate to a `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is expected\n * that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts of the tree from it.\n */\n insertBefore: insertBefore,\n\n /**\n * #### `insertInContainerBefore(container, child, beforeChild)\n *\n * Same as `insertBefore`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n insertInContainerBefore: insertBefore,\n\n /**\n * #### `removeChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage collection\n * would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\n removeChild: removeChild,\n\n /**\n * #### `removeChildFromContainer(container, child)`\n *\n * Same as `removeChild`, but for when a node is detached from the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n removeChildFromContainer: removeChild,\n\n /**\n * #### `resetTextContent(instance)`\n *\n * If you returned `true` from `shouldSetTextContent` for the previous props, but returned `false` from\n * `shouldSetTextContent` for the next props, React will call this method so that you can clear the text\n * content you were managing manually. For example, in the DOM you could set `node.textContent = ''`.\n *\n * If you never return `true` from `shouldSetTextContent`, you can leave it empty.\n */\n resetTextContent(_instance: Instance): void {\n // noop\n },\n\n /**\n * #### `commitTextUpdate(textInstance, prevText, nextText)`\n *\n * This method should mutate the `textInstance` and update its text content to `nextText`.\n *\n * Here, `textInstance` is a node created by `createTextInstance`.\n */\n commitTextUpdate(textInstance: TextInstance, _oldText: string, newText: string): void {\n textInstance.text = newText;\n },\n\n /**\n * #### `commitMount(instance, type, props, internalHandle)`\n *\n * This method is only called if you returned `true` from `finalizeInitialChildren` for this instance.\n *\n * It lets you do some additional work after the node is actually attached to the tree on the screen for\n * the first time. For example, the DOM renderer uses it to trigger focus on nodes with the `autoFocus` attribute.\n *\n * Note that `commitMount` does not mirror `removeChild` one to one because `removeChild` is only called for\n * the top-level removed node. This is why ideally `commitMount` should not mutate any nodes other than the\n * `instance` itself. For example, if it registers some events on some node above, it will be your responsibility\n * to traverse the tree in `removeChild` and clean them up, which is not ideal.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal\n * fields, be aware that it may change significantly between versions. You're taking on additional maintenance\n * risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * If you never return `true` from `finalizeInitialChildren`, you can leave it empty.\n */\n commitMount(\n _instance: Instance,\n _type: Type,\n _props: Props,\n _internalHandle: OpaqueHandle,\n ): void {\n // noop\n },\n\n /**\n * #### `commitUpdate(instance, type, prevProps, nextProps, internalHandle)`\n *\n * This method should mutate the `instance` according to the set of changes in `updatePayload`. Here, `updatePayload`\n * is the object that you've returned from `prepareUpdate` and has an arbitrary structure that makes sense for your\n * renderer. For example, the DOM renderer returns an update payload like `[prop1, value1, prop2, value2, ...]` from\n * `prepareUpdate`, and that structure gets passed into `commitUpdate`. Ideally, all the diffing and calculation\n * should happen inside `prepareUpdate` so that `commitUpdate` can be fast and straightforward.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields,\n * be aware that it may change significantly between versions. You're taking on additional maintenance risk by\n * reading from it, and giving up all guarantees if you write something to it.\n */\n // @ts-expect-error types are not updated\n commitUpdate(\n instance: Instance,\n type: Type,\n _prevProps: Props,\n nextProps: Props,\n internalHandle: OpaqueHandle,\n ): void {\n instance.type = type;\n instance.props = nextProps;\n instance.internalHandle = internalHandle;\n },\n\n /**\n * #### `hideInstance(instance)`\n *\n * This method should make the `instance` invisible without removing it from the tree. For example, it can apply\n * visual styling to hide it. It is used by Suspense to hide the tree while the fallback is visible.\n */\n hideInstance(instance: Instance): void {\n instance.isHidden = true;\n },\n\n /**\n * #### `hideTextInstance(textInstance)`\n *\n * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\n /**\n * #### `unhideInstance(instance, props)`\n *\n * This method should make the `instance` visible, undoing what `hideInstance` did.\n */\n unhideInstance(instance: Instance, _props: Props): void {\n instance.isHidden = false;\n },\n\n /**\n * #### `unhideTextInstance(textInstance, text)`\n *\n * Same as `unhideInstance`, but for nodes created by `createTextInstance`.\n */\n unhideTextInstance(textInstance: TextInstance, _text: string): void {\n textInstance.isHidden = false;\n },\n\n /**\n * #### `clearContainer(container)`\n *\n * This method should mutate the `container` root node and remove all children from it.\n */\n clearContainer(container: Container): void {\n container.children.forEach((child) => {\n child.parent = null;\n });\n\n container.children.splice(0);\n },\n\n /**\n * #### `maySuspendCommit(type, props)`\n *\n * This method is called during render to determine if the Host Component type and props require\n * some kind of loading process to complete before committing an update.\n */\n maySuspendCommit(_type: Type, _props: Props): boolean {\n return false;\n },\n\n /**\n * #### `preloadInstance(type, props)`\n *\n * This method may be called during render if the Host Component type and props might suspend a commit.\n * It can be used to initiate any work that might shorten the duration of a suspended commit.\n */\n preloadInstance(_type: Type, _props: Props): boolean {\n return true;\n },\n\n /**\n * #### `startSuspendingCommit()`\n *\n * This method is called just before the commit phase. Use it to set up any necessary state while any Host\n * Components that might suspend this commit are evaluated to determine if the commit must be suspended.\n */\n startSuspendingCommit() {},\n\n /**\n * #### `suspendInstance(type, props)`\n *\n * This method is called after `startSuspendingCommit` for each Host Component that indicated it might\n * suspend a commit.\n */\n suspendInstance() {},\n\n /**\n * #### `waitForCommitToBeReady()`\n *\n * This method is called after all `suspendInstance` calls are complete.\n *\n * Return `null` if the commit can happen immediately.\n * Return `(initiateCommit: Function) => Function` if the commit must be suspended. The argument to this\n * callback will initiate the commit when called. The return value is a cancellation function that the\n * Reconciler can use to abort the commit.\n */\n waitForCommitToBeReady() {\n return null;\n },\n\n // -------------------\n // Hydration Methods\n // (optional)\n // You can optionally implement hydration to \"attach\" to the existing tree during the initial render instead\n // of creating it from scratch. For example, the DOM renderer uses this to attach to an HTML markup.\n //\n // To support hydration, you need to declare `supportsHydration: true` and then implement the methods in\n // the \"Hydration\" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js).\n // File an issue if you need help.\n // -------------------\n supportsHydration: false,\n\n NotPendingTransition: null,\n\n resetFormInstance(_form: Instance) {},\n\n requestPostPaintCallback(_callback: (endTime: number) => void) {},\n};\n\nexport const TestReconciler = ReactReconciler(hostConfig);\n\n/**\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree,\n * look at `commitMount`.\n */\nfunction appendChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n parentInstance.children.push(child);\n}\n\n/**\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list\n * of its children. For example, in the DOM this would translate to a\n * `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is\n * expected that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts\n * of the tree from it.\n */\nfunction insertBefore(\n parentInstance: Container | Instance,\n child: Instance | TextInstance,\n beforeChild: Instance | TextInstance,\n): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n const beforeIndex = parentInstance.children.indexOf(beforeChild);\n parentInstance.children.splice(beforeIndex, 0, child);\n}\n\n/**\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage\n * collection would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\nfunction removeChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n parentInstance.children.splice(index, 1);\n child.parent = null;\n}\n","export function formatComponentList(names: string[]): string {\n if (names.length === 0) {\n return \"\";\n }\n\n if (names.length === 1) {\n return `<${names[0]}>`;\n }\n\n if (names.length === 2) {\n return `<${names[0]}> or <${names[1]}>`;\n }\n\n const allButLast = names.slice(0, -1);\n const last = names[names.length - 1];\n\n return `${allButLast.map((name) => `<${name}>`).join(\", \")}, or <${last}>`;\n}\n"],"mappings":"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","names":["import_constants","import_constants","ReactReconciler"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/renderer.ts","../src/find-all.ts","../src/render-to-json.ts","../src/host-element.ts","../src/reconciler.ts","../src/utils.ts"],"sourcesContent":["export { createRoot } from \"./renderer\";\n\nexport type { Root, RootOptions } from \"./renderer\";\nexport type { HostElement, HostElementProps, HostNode } from \"./host-element\";\nexport type { JsonElement, JsonNode } from \"./render-to-json\";\n","import type { ReactElement } from \"react\";\nimport type { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot } from \"react-reconciler/constants\";\n\nimport { findAll, type FindAllOptions } from \"./find-all\";\nimport { HostElement } from \"./host-element\";\nimport type { Container } from \"./reconciler\";\nimport { TestReconciler } from \"./reconciler\";\n\n// Refs:\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-noop-renderer/src/createReactNoop.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactNativeHostConfig.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactFabricHostConfig.js\n\nexport type RootOptions = {\n textComponents?: string[];\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Root = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n\n root: HostElement | null;\n findAll: (\n predicate: (element: HostElement) => boolean,\n options?: FindAllOptions,\n ) => HostElement[];\n};\n\nexport function createRoot(options?: RootOptions): Root {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n config: {\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n ConcurrentRoot,\n null, // hydration callbacks\n false, // isStrictMode\n null, // concurrentUpdatesByDefaultOverride\n \"id\", // identifierPrefix\n () => {}, // onUncaughtError\n () => {}, // onCaughtError\n // @ts-expect-error missing types\n () => {}, // onRecoverableError\n null, // transitionCallbacks\n );\n\n const render = (element: ReactElement) => {\n TestReconciler.updateContainer(element, containerFiber, null, null);\n };\n\n const unmount = () => {\n if (containerFiber == null || container == null) {\n return;\n }\n\n TestReconciler.updateContainer(null, containerFiber, null, null);\n\n container = null;\n containerFiber = null;\n };\n\n const getRoot = () => {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .root on unmounted test renderer\");\n }\n\n if (container.children.length === 0) {\n return null;\n }\n\n const firstChild = container.children[0];\n if (firstChild.tag === \"TEXT\") {\n throw new Error(\"Cannot render text as root element\");\n }\n\n return HostElement.fromInstance(firstChild);\n };\n\n return {\n render,\n unmount,\n get root(): HostElement | null {\n return getRoot();\n },\n findAll: (predicate: (element: HostElement) => boolean, options?: FindAllOptions) => {\n const root = getRoot();\n return root != null ? findAll(root, predicate, options) : [];\n },\n };\n}\n","import type { HostElement } from \"./host-element\";\n\nexport interface FindAllOptions {\n /* Exclude any ancestors of deepest matched elements even if they match the predicate */\n matchDeepestOnly?: boolean;\n}\n\nexport function findAll(\n root: HostElement,\n predicate: (element: HostElement) => boolean,\n options?: FindAllOptions,\n): HostElement[] {\n const results: HostElement[] = [];\n\n // Match descendants first but do not add them to results yet.\n const matchingDescendants: HostElement[] = [];\n\n root.children.forEach((child) => {\n if (typeof child === \"string\") {\n return;\n }\n\n matchingDescendants.push(...findAll(child, predicate, options));\n });\n\n if (\n // When matchDeepestOnly = true: add current element only if no descendants match\n (!options?.matchDeepestOnly || matchingDescendants.length === 0) &&\n predicate(root)\n ) {\n results.push(root);\n }\n\n // Add matching descendants after element to preserve original tree walk order.\n results.push(...matchingDescendants);\n\n return results;\n}\n","import type { Instance, TextInstance } from \"./reconciler\";\n\nexport type JsonNode = JsonElement | string;\n\nexport type JsonElement = {\n type: string;\n props: object;\n children: Array<JsonNode> | null;\n $$typeof: symbol;\n};\n\nexport function renderToJson(instance: Instance | TextInstance): JsonNode | null {\n if (instance.isHidden) {\n return null;\n }\n\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\": {\n // We don't include the `children` prop in JSON.\n // Instead, we will include the actual rendered children.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...props } = instance.props;\n\n let renderedChildren = null;\n if (instance.children.length) {\n for (let i = 0; i < instance.children.length; i++) {\n const renderedChild = renderToJson(instance.children[i]);\n if (renderedChild !== null) {\n if (renderedChildren === null) {\n renderedChildren = [renderedChild];\n } else {\n renderedChildren.push(renderedChild);\n }\n }\n }\n }\n\n const result = {\n type: instance.type,\n props: props,\n children: renderedChildren,\n $$typeof: Symbol.for(\"react.test.json\"),\n };\n // This is needed for JEST to format snapshot as JSX.\n Object.defineProperty(result, \"$$typeof\", {\n value: Symbol.for(\"react.test.json\"),\n });\n return result;\n }\n }\n}\n\nexport function renderChildrenToJson(children: Array<Instance | TextInstance> | null) {\n let result = null;\n if (children?.length) {\n for (let i = 0; i < children.length; i++) {\n const renderedChild = renderToJson(children[i]);\n if (renderedChild !== null) {\n if (result === null) {\n result = [renderedChild];\n } else {\n result.push(renderedChild);\n }\n }\n }\n }\n\n return result;\n}\n","import type { Fiber } from \"react-reconciler\";\n\nimport type { Instance, TextInstance } from \"./reconciler\";\nimport type { JsonNode } from \"./render-to-json\";\nimport { renderToJson } from \"./render-to-json\";\n\nexport type HostNode = HostElement | string;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type HostElementProps = Record<string, any>;\n\nconst instanceMap = new WeakMap<Instance, HostElement>();\n\nexport class HostElement {\n private instance: Instance;\n\n private constructor(instance: Instance) {\n this.instance = instance;\n }\n\n get type(): string {\n return this.instance.type;\n }\n\n get props(): HostElementProps {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...restProps } = this.instance.props;\n return restProps;\n }\n\n get children(): HostNode[] {\n const result = this.instance.children\n .filter((child) => !child.isHidden)\n .map((child) => getHostNodeForInstance(child));\n return result;\n }\n\n get parent(): HostElement | null {\n const parentInstance = this.instance.parent;\n if (parentInstance == null || parentInstance.tag === \"CONTAINER\") {\n return null;\n }\n\n return HostElement.fromInstance(parentInstance);\n }\n\n get unstable_fiber(): Fiber {\n return this.instance.unstable_fiber;\n }\n\n get $$typeof(): symbol {\n return Symbol.for(\"react.test.json\");\n }\n\n toJSON(): JsonNode | null {\n return renderToJson(this.instance);\n }\n\n /** @internal */\n static fromInstance(instance: Instance): HostElement {\n const hostElement = instanceMap.get(instance);\n if (hostElement) {\n return hostElement;\n }\n\n const result = new HostElement(instance);\n instanceMap.set(instance, result);\n return result;\n }\n}\n\nexport function getHostNodeForInstance(instance: Instance | TextInstance): HostNode {\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\":\n return HostElement.fromInstance(instance);\n }\n}\n","import type { ReactElement } from \"react\";\nimport type { Fiber } from \"react-reconciler\";\nimport ReactReconciler from \"react-reconciler\";\nimport {\n DefaultEventPriority,\n // @ts-expect-error missing types\n NoEventPriority,\n} from \"react-reconciler/constants\";\n\nimport { formatComponentList } from \"./utils\";\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\n\ntype ReconcilerConfig = {\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\n};\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n config: ReconcilerConfig;\n};\n\nexport type Instance = {\n tag: \"INSTANCE\";\n type: string;\n props: Props;\n children: Array<Instance | TextInstance>;\n parent: Container | Instance | null;\n rootContainer: Container;\n isHidden: boolean;\n unstable_fiber: Fiber;\n};\n\nexport type TextInstance = {\n tag: \"TEXT\";\n text: string;\n parent: Container | Instance | null;\n isHidden: boolean;\n};\n\nexport type SuspenseInstance = object;\nexport type HydratableInstance = object;\nexport type PublicInstance = object | TextInstance;\nexport type UpdatePayload = unknown;\nexport type ChildSet = unknown;\nexport type TimeoutHandle = unknown;\nexport type NoTimeout = unknown;\n\ntype HostContext = {\n type: string;\n isInsideText: boolean;\n config: ReconcilerConfig;\n};\n\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nlet currentUpdatePriority: number = NoEventPriority;\n\nconst hostConfig: ReactReconciler.HostConfig<\n Type,\n Props,\n Container,\n Instance,\n TextInstance,\n SuspenseInstance,\n HydratableInstance,\n PublicInstance,\n HostContext,\n UpdatePayload,\n ChildSet,\n TimeoutHandle,\n NoTimeout\n> = {\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform is similar to the DOM and has methods similar to `appendChild`, `removeChild`,\n * and so on, you'll want to use the **mutation mode**. This is the same mode used by React DOM, React ART,\n * and the classic React Native renderer.\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsMutation: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsMutation: true,\n\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform has immutable trees, you'll want the **persistent mode** instead. In that mode,\n * existing nodes are never mutated, and instead every change clones the parent tree and then replaces\n * the whole parent tree at the root. This is the node used by the new React Native renderer, codenamed \"Fabric\".\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsPersistence: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsPersistence: false,\n\n /**\n * #### `createInstance(type, props, rootContainer, hostContext, internalHandle)`\n *\n * This method should return a newly created node. For example, the DOM renderer would call\n * `document.createElement(type)` here and then set the properties from `props`.\n *\n * You can use `rootContainer` to access the root container associated with that tree. For example,\n * in the DOM renderer, this is useful to get the correct `document` reference that the root belongs to.\n *\n * The `hostContext` parameter lets you keep track of some information about your current place in\n * the tree. To learn more about it, see `getChildHostContext` below.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its\n * internal fields, be aware that it may change significantly between versions. You're taking on additional\n * maintenance risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * This method happens **in the render phase**. It can (and usually should) mutate the node it has\n * just created before returning it, but it must not modify any other nodes. It must not register\n * any event handlers on the parent tree. This is because an instance being created doesn't guarantee\n * it would be placed in the tree — it could be left unused and later collected by GC. If you need to do\n * something when an instance is definitely in the tree, look at `commitMount` instead.\n */\n createInstance(\n type: Type,\n props: Props,\n rootContainer: Container,\n _hostContext: HostContext,\n internalHandle: Fiber,\n ) {\n return {\n tag: \"INSTANCE\",\n type,\n props,\n isHidden: false,\n children: [],\n parent: null,\n rootContainer,\n unstable_fiber: internalHandle,\n };\n },\n\n /**\n * #### `createTextInstance(text, rootContainer, hostContext, internalHandle)`\n *\n * Same as `createInstance`, but for text nodes. If your renderer doesn't support text nodes, you can\n * throw here.\n */\n createTextInstance(\n text: string,\n rootContainer: Container,\n hostContext: HostContext,\n _internalHandle: Fiber,\n ): TextInstance {\n if (rootContainer.config.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.config.textComponents,\n )} component. Detected attempt to render \"${text}\" string within a <${\n hostContext.type\n }> component.`,\n );\n }\n\n return {\n tag: \"TEXT\",\n text,\n parent: null,\n isHidden: false,\n };\n },\n\n /**\n * #### `appendInitialChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children.\n * For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * This method happens **in the render phase**. It can mutate `parentInstance` and `child`, but it\n * must not modify any other nodes. It's called while the tree is still being built up and not connected\n * to the actual tree on the screen.\n */\n appendInitialChild: appendChild,\n\n /**\n * #### `finalizeInitialChildren(instance, type, props, rootContainer, hostContext)`\n *\n * In this method, you can perform some final mutations on the `instance`. Unlike with `createInstance`,\n * by the time `finalizeInitialChildren` is called, all the initial children have already been added to\n * the `instance`, but the instance itself has not yet been connected to the tree on the screen.\n *\n * This method happens **in the render phase**. It can mutate `instance`, but it must not modify any other\n * nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.\n *\n * There is a second purpose to this method. It lets you specify whether there is some work that needs to\n * happen when the node is connected to the tree on the screen. If you return `true`, the instance will\n * receive a `commitMount` call later. See its documentation below.\n *\n * If you don't want to do anything here, you should return `false`.\n */\n finalizeInitialChildren(\n _instance: Instance,\n _type: Type,\n _props: Props,\n _rootContainer: Container,\n _hostContext: HostContext,\n ): boolean {\n return false;\n },\n\n /**\n * #### `shouldSetTextContent(type, props)`\n *\n * Some target platforms support setting an instance's text content without manually creating a text node.\n * For example, in the DOM, you can set `node.textContent` instead of creating a text node and appending it.\n *\n * If you return `true` from this method, React will assume that this node's children are text, and will\n * not create nodes for them. It will instead rely on you to have filled that text during `createInstance`.\n * This is a performance optimization. For example, the DOM renderer returns `true` only if `type` is a\n * known text-only parent (like `'textarea'`) or if `props.children` has a `'string'` type. If you return `true`,\n * you will need to implement `resetTextContent` too.\n *\n * If you don't want to do anything here, you should return `false`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n shouldSetTextContent(_type: Type, _props: Props): boolean {\n return false;\n },\n\n setCurrentUpdatePriority(newPriority: number) {\n currentUpdatePriority = newPriority;\n },\n\n getCurrentUpdatePriority() {\n return currentUpdatePriority;\n },\n\n resolveUpdatePriority(): number {\n return currentUpdatePriority || DefaultEventPriority;\n },\n\n shouldAttemptEagerTransition() {\n return false;\n },\n\n /**\n * #### `getRootHostContext(rootContainer)`\n *\n * This method lets you return the initial host context from the root of the tree. See `getChildHostContext`\n * for the explanation of host context.\n *\n * If you don't intend to use host context, you can return `null`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getRootHostContext(rootContainer: Container): HostContext | null {\n return {\n type: \"ROOT\",\n config: rootContainer.config,\n isInsideText: false,\n };\n },\n\n /**\n * #### `getChildHostContext(parentHostContext, type, rootContainer)`\n *\n * Host context lets you track some information about where you are in the tree so that it's available\n * inside `createInstance` as the `hostContext` parameter. For example, the DOM renderer uses it to track\n * whether it's inside an HTML or an SVG tree, because `createInstance` implementation needs to be\n * different for them.\n *\n * If the node of this `type` does not influence the context you want to pass down, you can return\n * `parentHostContext`. Alternatively, you can return any custom object representing the information\n * you want to pass down.\n *\n * If you don't want to do anything here, return `parentHostContext`.\n *\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getChildHostContext(parentHostContext: HostContext, type: Type): HostContext {\n const isInsideText = Boolean(parentHostContext.config.textComponents?.includes(type));\n return { ...parentHostContext, type: type, isInsideText };\n },\n\n /**\n * #### `getPublicInstance(instance)`\n *\n * Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But\n * in some cases it might make sense to only expose some part of it.\n *\n * If you don't want to do anything here, return `instance`.\n */\n getPublicInstance(instance: Instance | TextInstance): PublicInstance {\n switch (instance.tag) {\n case \"INSTANCE\": {\n const createNodeMock = instance.rootContainer.config.createNodeMock;\n const mockNode = createNodeMock({\n type: instance.type,\n props: instance.props,\n key: null,\n });\n\n nodeToInstanceMap.set(mockNode, instance);\n\n return mockNode;\n }\n\n default:\n return instance;\n }\n },\n\n /**\n * #### `prepareForCommit(containerInfo)`\n *\n * This method lets you store some information before React starts making changes to the tree on\n * the screen. For example, the DOM renderer stores the current text selection so that it can later\n * restore it. This method is mirrored by `resetAfterCommit`.\n *\n * Even if you don't want to do anything here, you need to return `null` from it.\n */\n prepareForCommit(_containerInfo: Container) {\n return null; // noop\n },\n\n /**\n * #### `resetAfterCommit(containerInfo)`\n *\n * This method is called right after React has performed the tree mutations. You can use it to restore\n * something you've stored in `prepareForCommit` — for example, text selection.\n *\n * You can leave it empty.\n */\n resetAfterCommit(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `preparePortalMount(containerInfo)`\n *\n * This method is called for a container that's used as a portal target. Usually you can leave it empty.\n */\n preparePortalMount(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `scheduleTimeout(fn, delay)`\n *\n * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n\n /**\n * #### `cancelTimeout(id)`\n *\n * You can proxy this to `clearTimeout` or its equivalent in your environment.\n */\n cancelTimeout: clearTimeout,\n\n /**\n * #### `noTimeout`\n *\n * This is a property (not a function) that should be set to something that can never be a valid timeout ID.\n * For example, you can set it to `-1`.\n */\n noTimeout: -1,\n\n /**\n * #### `supportsMicrotasks`\n *\n * Set this to `true` to indicate that your renderer supports `scheduleMicrotask`. We use microtasks as part\n * of our discrete event implementation in React DOM. If you're not sure if your renderer should support this,\n * you probably should. The option to not implement `scheduleMicrotask` exists so that platforms with more control\n * over user events, like React Native, can choose to use a different mechanism.\n */\n supportsMicrotasks: true,\n\n /**\n * #### `scheduleMicrotask(fn)`\n *\n * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\n /**\n * #### `isPrimaryRenderer`\n *\n * This is a property (not a function) that should be set to `true` if your renderer is the main one on the\n * page. For example, if you're writing a renderer for the Terminal, it makes sense to set it to `true`, but\n * if your renderer is used *on top of* React DOM or some other existing renderer, set it to `false`.\n */\n isPrimaryRenderer: true,\n\n /**\n * Whether the renderer shouldn't trigger missing `act()` warnings\n */\n warnsIfNotActing: true,\n\n getInstanceFromNode(node: object): Fiber | null | undefined {\n const instance = nodeToInstanceMap.get(node);\n if (instance !== undefined) {\n return instance.unstable_fiber;\n }\n\n return null;\n },\n\n beforeActiveInstanceBlur(): void {\n // noop\n },\n\n afterActiveInstanceBlur(): void {\n // noop\n },\n\n prepareScopeUpdate(scopeInstance: object, instance: Instance): void {\n nodeToInstanceMap.set(scopeInstance, instance);\n },\n\n getInstanceFromScope(scopeInstance: object): Instance | null {\n return nodeToInstanceMap.get(scopeInstance) ?? null;\n },\n\n detachDeletedInstance(_node: Instance): void {},\n\n /**\n * #### `appendChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree, look at `commitMount`.\n */\n appendChild: appendChild,\n\n /**\n * #### `appendChildToContainer(container, child)`\n *\n * Same as `appendChild`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different\n * type than the rest of the tree.\n */\n appendChildToContainer: appendChild,\n\n /**\n * #### `insertBefore(parentInstance, child, beforeChild)`\n *\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list of\n * its children. For example, in the DOM this would translate to a `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is expected\n * that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts of the tree from it.\n */\n insertBefore: insertBefore,\n\n /**\n * #### `insertInContainerBefore(container, child, beforeChild)\n *\n * Same as `insertBefore`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n insertInContainerBefore: insertBefore,\n\n /**\n * #### `removeChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage collection\n * would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\n removeChild: removeChild,\n\n /**\n * #### `removeChildFromContainer(container, child)`\n *\n * Same as `removeChild`, but for when a node is detached from the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n removeChildFromContainer: removeChild,\n\n /**\n * #### `resetTextContent(instance)`\n *\n * If you returned `true` from `shouldSetTextContent` for the previous props, but returned `false` from\n * `shouldSetTextContent` for the next props, React will call this method so that you can clear the text\n * content you were managing manually. For example, in the DOM you could set `node.textContent = ''`.\n *\n * If you never return `true` from `shouldSetTextContent`, you can leave it empty.\n */\n resetTextContent(_instance: Instance): void {\n // noop\n },\n\n /**\n * #### `commitTextUpdate(textInstance, prevText, nextText)`\n *\n * This method should mutate the `textInstance` and update its text content to `nextText`.\n *\n * Here, `textInstance` is a node created by `createTextInstance`.\n */\n commitTextUpdate(textInstance: TextInstance, _oldText: string, newText: string): void {\n textInstance.text = newText;\n },\n\n /**\n * #### `commitMount(instance, type, props, internalHandle)`\n *\n * This method is only called if you returned `true` from `finalizeInitialChildren` for this instance.\n *\n * It lets you do some additional work after the node is actually attached to the tree on the screen for\n * the first time. For example, the DOM renderer uses it to trigger focus on nodes with the `autoFocus` attribute.\n *\n * Note that `commitMount` does not mirror `removeChild` one to one because `removeChild` is only called for\n * the top-level removed node. This is why ideally `commitMount` should not mutate any nodes other than the\n * `instance` itself. For example, if it registers some events on some node above, it will be your responsibility\n * to traverse the tree in `removeChild` and clean them up, which is not ideal.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal\n * fields, be aware that it may change significantly between versions. You're taking on additional maintenance\n * risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * If you never return `true` from `finalizeInitialChildren`, you can leave it empty.\n */\n commitMount(_instance: Instance, _type: Type, _props: Props, _internalHandle: Fiber): void {\n // noop\n },\n\n /**\n * #### `commitUpdate(instance, type, prevProps, nextProps, internalHandle)`\n *\n * This method should mutate the `instance` according to the set of changes in `updatePayload`. Here, `updatePayload`\n * is the object that you've returned from `prepareUpdate` and has an arbitrary structure that makes sense for your\n * renderer. For example, the DOM renderer returns an update payload like `[prop1, value1, prop2, value2, ...]` from\n * `prepareUpdate`, and that structure gets passed into `commitUpdate`. Ideally, all the diffing and calculation\n * should happen inside `prepareUpdate` so that `commitUpdate` can be fast and straightforward.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields,\n * be aware that it may change significantly between versions. You're taking on additional maintenance risk by\n * reading from it, and giving up all guarantees if you write something to it.\n */\n // @ts-expect-error types are not updated\n commitUpdate(\n instance: Instance,\n type: Type,\n _prevProps: Props,\n nextProps: Props,\n internalHandle: Fiber,\n ): void {\n instance.type = type;\n instance.props = nextProps;\n instance.unstable_fiber = internalHandle;\n },\n\n /**\n * #### `hideInstance(instance)`\n *\n * This method should make the `instance` invisible without removing it from the tree. For example, it can apply\n * visual styling to hide it. It is used by Suspense to hide the tree while the fallback is visible.\n */\n hideInstance(instance: Instance): void {\n instance.isHidden = true;\n },\n\n /**\n * #### `hideTextInstance(textInstance)`\n *\n * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\n /**\n * #### `unhideInstance(instance, props)`\n *\n * This method should make the `instance` visible, undoing what `hideInstance` did.\n */\n unhideInstance(instance: Instance, _props: Props): void {\n instance.isHidden = false;\n },\n\n /**\n * #### `unhideTextInstance(textInstance, text)`\n *\n * Same as `unhideInstance`, but for nodes created by `createTextInstance`.\n */\n unhideTextInstance(textInstance: TextInstance, _text: string): void {\n textInstance.isHidden = false;\n },\n\n /**\n * #### `clearContainer(container)`\n *\n * This method should mutate the `container` root node and remove all children from it.\n */\n clearContainer(container: Container): void {\n container.children.forEach((child) => {\n child.parent = null;\n });\n\n container.children.splice(0);\n },\n\n /**\n * #### `maySuspendCommit(type, props)`\n *\n * This method is called during render to determine if the Host Component type and props require\n * some kind of loading process to complete before committing an update.\n */\n maySuspendCommit(_type: Type, _props: Props): boolean {\n return false;\n },\n\n /**\n * #### `preloadInstance(type, props)`\n *\n * This method may be called during render if the Host Component type and props might suspend a commit.\n * It can be used to initiate any work that might shorten the duration of a suspended commit.\n */\n preloadInstance(_type: Type, _props: Props): boolean {\n return true;\n },\n\n /**\n * #### `startSuspendingCommit()`\n *\n * This method is called just before the commit phase. Use it to set up any necessary state while any Host\n * Components that might suspend this commit are evaluated to determine if the commit must be suspended.\n */\n startSuspendingCommit() {},\n\n /**\n * #### `suspendInstance(type, props)`\n *\n * This method is called after `startSuspendingCommit` for each Host Component that indicated it might\n * suspend a commit.\n */\n suspendInstance() {},\n\n /**\n * #### `waitForCommitToBeReady()`\n *\n * This method is called after all `suspendInstance` calls are complete.\n *\n * Return `null` if the commit can happen immediately.\n * Return `(initiateCommit: Function) => Function` if the commit must be suspended. The argument to this\n * callback will initiate the commit when called. The return value is a cancellation function that the\n * Reconciler can use to abort the commit.\n */\n waitForCommitToBeReady() {\n return null;\n },\n\n // -------------------\n // Hydration Methods\n // (optional)\n // You can optionally implement hydration to \"attach\" to the existing tree during the initial render instead\n // of creating it from scratch. For example, the DOM renderer uses this to attach to an HTML markup.\n //\n // To support hydration, you need to declare `supportsHydration: true` and then implement the methods in\n // the \"Hydration\" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js).\n // File an issue if you need help.\n // -------------------\n supportsHydration: false,\n\n NotPendingTransition: null,\n\n resetFormInstance(_form: Instance) {},\n\n requestPostPaintCallback(_callback: (endTime: number) => void) {},\n};\n\nexport const TestReconciler = ReactReconciler(hostConfig);\n\n/**\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree,\n * look at `commitMount`.\n */\nfunction appendChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n parentInstance.children.push(child);\n}\n\n/**\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list\n * of its children. For example, in the DOM this would translate to a\n * `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is\n * expected that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts\n * of the tree from it.\n */\nfunction insertBefore(\n parentInstance: Container | Instance,\n child: Instance | TextInstance,\n beforeChild: Instance | TextInstance,\n): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n const beforeIndex = parentInstance.children.indexOf(beforeChild);\n parentInstance.children.splice(beforeIndex, 0, child);\n}\n\n/**\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage\n * collection would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\nfunction removeChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n parentInstance.children.splice(index, 1);\n child.parent = null;\n}\n","export function formatComponentList(names: string[]): string {\n if (names.length === 0) {\n return \"\";\n }\n\n if (names.length === 1) {\n return `<${names[0]}>`;\n }\n\n if (names.length === 2) {\n return `<${names[0]}> or <${names[1]}>`;\n }\n\n const allButLast = names.slice(0, -1);\n const last = names[names.length - 1];\n\n return `${allButLast.map((name) => `<${name}>`).join(\", \")}, or <${last}>`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAAA,oBAA+B;;;ACKxB,SAAS,QACd,MACA,WACA,SACe;AACf,QAAM,UAAyB,CAAC;AAGhC,QAAM,sBAAqC,CAAC;AAE5C,OAAK,SAAS,QAAQ,CAAC,UAAU;AAC/B,QAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,IACF;AAEA,wBAAoB,KAAK,GAAG,QAAQ,OAAO,WAAW,OAAO,CAAC;AAAA,EAChE,CAAC;AAED;AAAA;AAAA,KAEG,EAAC,mCAAS,qBAAoB,oBAAoB,WAAW,MAC9D,UAAU,IAAI;AAAA,IACd;AACA,YAAQ,KAAK,IAAI;AAAA,EACnB;AAGA,UAAQ,KAAK,GAAG,mBAAmB;AAEnC,SAAO;AACT;;;AC1BO,SAAS,aAAa,UAAoD;AAC/E,MAAI,SAAS,UAAU;AACrB,WAAO;AAAA,EACT;AAEA,UAAQ,SAAS,KAAK;AAAA,IACpB,KAAK;AACH,aAAO,SAAS;AAAA,IAElB,KAAK,YAAY;AAIf,YAA+B,cAAS,OAAhC,WAxBd,IAwBqC,IAAV,kBAAU,IAAV,CAAb;AAER,UAAI,mBAAmB;AACvB,UAAI,SAAS,SAAS,QAAQ;AAC5B,iBAAS,IAAI,GAAG,IAAI,SAAS,SAAS,QAAQ,KAAK;AACjD,gBAAM,gBAAgB,aAAa,SAAS,SAAS,CAAC,CAAC;AACvD,cAAI,kBAAkB,MAAM;AAC1B,gBAAI,qBAAqB,MAAM;AAC7B,iCAAmB,CAAC,aAAa;AAAA,YACnC,OAAO;AACL,+BAAiB,KAAK,aAAa;AAAA,YACrC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,YAAM,SAAS;AAAA,QACb,MAAM,SAAS;AAAA,QACf;AAAA,QACA,UAAU;AAAA,QACV,UAAU,uBAAO,IAAI,iBAAiB;AAAA,MACxC;AAEA,aAAO,eAAe,QAAQ,YAAY;AAAA,QACxC,OAAO,uBAAO,IAAI,iBAAiB;AAAA,MACrC,CAAC;AACD,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC1CA,IAAM,cAAc,oBAAI,QAA+B;AAEhD,IAAM,cAAN,MAAM,aAAY;AAAA,EAGf,YAAY,UAAoB;AACtC,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,IAAI,QAA0B;AAE5B,UAAmC,UAAK,SAAS,OAAzC,WA1BZ,IA0BuC,IAAd,sBAAc,IAAd,CAAb;AACR,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,WAAuB;AACzB,UAAM,SAAS,KAAK,SAAS,SAC1B,OAAO,CAAC,UAAU,CAAC,MAAM,QAAQ,EACjC,IAAI,CAAC,UAAU,uBAAuB,KAAK,CAAC;AAC/C,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,SAA6B;AAC/B,UAAM,iBAAiB,KAAK,SAAS;AACrC,QAAI,kBAAkB,QAAQ,eAAe,QAAQ,aAAa;AAChE,aAAO;AAAA,IACT;AAEA,WAAO,aAAY,aAAa,cAAc;AAAA,EAChD;AAAA,EAEA,IAAI,iBAAwB;AAC1B,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,IAAI,WAAmB;AACrB,WAAO,uBAAO,IAAI,iBAAiB;AAAA,EACrC;AAAA,EAEA,SAA0B;AACxB,WAAO,aAAa,KAAK,QAAQ;AAAA,EACnC;AAAA;AAAA,EAGA,OAAO,aAAa,UAAiC;AACnD,UAAM,cAAc,YAAY,IAAI,QAAQ;AAC5C,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,IAAI,aAAY,QAAQ;AACvC,gBAAY,IAAI,UAAU,MAAM;AAChC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,uBAAuB,UAA6C;AAClF,UAAQ,SAAS,KAAK;AAAA,IACpB,KAAK;AACH,aAAO,SAAS;AAAA,IAElB,KAAK;AACH,aAAO,YAAY,aAAa,QAAQ;AAAA,EAC5C;AACF;;;AC7EA,8BAA4B;AAC5B,uBAIO;;;ACPA,SAAS,oBAAoB,OAAyB;AAC3D,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,IAAI,MAAM,CAAC,CAAC;AAAA,EACrB;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,IAAI,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC;AAAA,EACtC;AAEA,QAAM,aAAa,MAAM,MAAM,GAAG,EAAE;AACpC,QAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AAEnC,SAAO,GAAG,WAAW,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,SAAS,IAAI;AACzE;;;ADyCA,IAAM,oBAAoB,oBAAI,QAA0B;AAGxD,IAAI,wBAAgC;AAEpC,IAAM,aAcF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAmBF,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBlB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBrB,eACE,MACA,OACA,eACA,cACA,gBACA;AACA,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU;AAAA,MACV,UAAU,CAAC;AAAA,MACX,QAAQ;AAAA,MACR;AAAA,MACA,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBACE,MACA,eACA,aACA,iBACc;AACd,QAAI,cAAc,OAAO,kBAAkB,CAAC,YAAY,cAAc;AACpE,YAAM,IAAI;AAAA,QACR,+DAA+D;AAAA,UAC7D,cAAc,OAAO;AAAA,QACvB,CAAC,2CAA2C,IAAI,sBAC9C,YAAY,IACd;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBpB,wBACE,WACA,OACA,QACA,gBACA,cACS;AACT,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,qBAAqB,OAAa,QAAwB;AACxD,WAAO;AAAA,EACT;AAAA,EAEA,yBAAyB,aAAqB;AAC5C,4BAAwB;AAAA,EAC1B;AAAA,EAEA,2BAA2B;AACzB,WAAO;AAAA,EACT;AAAA,EAEA,wBAAgC;AAC9B,WAAO,yBAAyB;AAAA,EAClC;AAAA,EAEA,+BAA+B;AAC7B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,mBAAmB,eAA8C;AAC/D,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,cAAc;AAAA,MACtB,cAAc;AAAA,IAChB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,oBAAoB,mBAAgC,MAAyB;AAvS/E;AAwSI,UAAM,eAAe,SAAQ,uBAAkB,OAAO,mBAAzB,mBAAyC,SAAS,KAAK;AACpF,WAAO,iCAAK,oBAAL,EAAwB,MAAY,aAAa;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,kBAAkB,UAAmD;AACnE,YAAQ,SAAS,KAAK;AAAA,MACpB,KAAK,YAAY;AACf,cAAM,iBAAiB,SAAS,cAAc,OAAO;AACrD,cAAM,WAAW,eAAe;AAAA,UAC9B,MAAM,SAAS;AAAA,UACf,OAAO,SAAS;AAAA,UAChB,KAAK;AAAA,QACP,CAAC;AAED,0BAAkB,IAAI,UAAU,QAAQ;AAExC,eAAO;AAAA,MACT;AAAA,MAEA;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,iBAAiB,gBAA2B;AAC1C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,iBAAiB,gBAAiC;AAAA,EAElD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,gBAAiC;AAAA,EAEpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQf,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUX,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASnB,mBAAmB;AAAA;AAAA;AAAA;AAAA,EAKnB,kBAAkB;AAAA,EAElB,oBAAoB,MAAwC;AAC1D,UAAM,WAAW,kBAAkB,IAAI,IAAI;AAC3C,QAAI,aAAa,QAAW;AAC1B,aAAO,SAAS;AAAA,IAClB;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,2BAAiC;AAAA,EAEjC;AAAA,EAEA,0BAAgC;AAAA,EAEhC;AAAA,EAEA,mBAAmB,eAAuB,UAA0B;AAClE,sBAAkB,IAAI,eAAe,QAAQ;AAAA,EAC/C;AAAA,EAEA,qBAAqB,eAAwC;AApb/D;AAqbI,YAAO,uBAAkB,IAAI,aAAa,MAAnC,YAAwC;AAAA,EACjD;AAAA,EAEA,sBAAsB,OAAuB;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAW1B,iBAAiB,WAA2B;AAAA,EAE5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAiB,cAA4B,UAAkB,SAAuB;AACpF,iBAAa,OAAO;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,YAAY,WAAqB,OAAa,QAAe,iBAA8B;AAAA,EAE3F;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aACE,UACA,MACA,YACA,WACA,gBACM;AACN,aAAS,OAAO;AAChB,aAAS,QAAQ;AACjB,aAAS,iBAAiB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,UAA0B;AACrC,aAAS,WAAW;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,iBAAiB,cAAkC;AACjD,iBAAa,WAAW;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,UAAoB,QAAqB;AACtD,aAAS,WAAW;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,cAA4B,OAAqB;AAClE,iBAAa,WAAW;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,WAA4B;AACzC,cAAU,SAAS,QAAQ,CAAC,UAAU;AACpC,YAAM,SAAS;AAAA,IACjB,CAAC;AAED,cAAU,SAAS,OAAO,CAAC;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBAAiB,OAAa,QAAwB;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB,OAAa,QAAwB;AACnD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,wBAAwB;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzB,kBAAkB;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYnB,yBAAyB;AACvB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,mBAAmB;AAAA,EAEnB,sBAAsB;AAAA,EAEtB,kBAAkB,OAAiB;AAAA,EAAC;AAAA,EAEpC,yBAAyB,WAAsC;AAAA,EAAC;AAClE;AAEO,IAAM,qBAAiB,wBAAAC,SAAgB,UAAU;AAUxD,SAAS,YAAY,gBAAsC,OAAsC;AAC/F,QAAM,QAAQ,eAAe,SAAS,QAAQ,KAAK;AACnD,MAAI,UAAU,IAAI;AAChB,mBAAe,SAAS,OAAO,OAAO,CAAC;AAAA,EACzC;AAEA,QAAM,SAAS;AACf,iBAAe,SAAS,KAAK,KAAK;AACpC;AAWA,SAAS,aACP,gBACA,OACA,aACM;AACN,QAAM,QAAQ,eAAe,SAAS,QAAQ,KAAK;AACnD,MAAI,UAAU,IAAI;AAChB,mBAAe,SAAS,OAAO,OAAO,CAAC;AAAA,EACzC;AAEA,QAAM,SAAS;AACf,QAAM,cAAc,eAAe,SAAS,QAAQ,WAAW;AAC/D,iBAAe,SAAS,OAAO,aAAa,GAAG,KAAK;AACtD;AAQA,SAAS,YAAY,gBAAsC,OAAsC;AAC/F,QAAM,QAAQ,eAAe,SAAS,QAAQ,KAAK;AACnD,iBAAe,SAAS,OAAO,OAAO,CAAC;AACvC,QAAM,SAAS;AACjB;;;AJ7sBO,SAAS,WAAW,SAA6B;AA9BxD;AA+BE,MAAI,YAA8B;AAAA,IAChC,KAAK;AAAA,IACL,UAAU,CAAC;AAAA,IACX,QAAQ;AAAA,IACR,QAAQ;AAAA,MACN,gBAAgB,mCAAS;AAAA,MACzB,iBAAgB,wCAAS,mBAAT,aAA4B,OAAO,CAAC;AAAA,IACtD;AAAA,EACF;AAGA,MAAI,iBAA4B,eAAe;AAAA,IAC7C;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA,MAAM;AAAA,IAAC;AAAA;AAAA,IACP,MAAM;AAAA,IAAC;AAAA;AAAA;AAAA,IAEP,MAAM;AAAA,IAAC;AAAA;AAAA,IACP;AAAA;AAAA,EACF;AAEA,QAAM,SAAS,CAAC,YAA0B;AACxC,mBAAe,gBAAgB,SAAS,gBAAgB,MAAM,IAAI;AAAA,EACpE;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,kBAAkB,QAAQ,aAAa,MAAM;AAC/C;AAAA,IACF;AAEA,mBAAe,gBAAgB,MAAM,gBAAgB,MAAM,IAAI;AAE/D,gBAAY;AACZ,qBAAiB;AAAA,EACnB;AAEA,QAAM,UAAU,MAAM;AACpB,QAAI,kBAAkB,QAAQ,aAAa,MAAM;AAC/C,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAEA,QAAI,UAAU,SAAS,WAAW,GAAG;AACnC,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,UAAU,SAAS,CAAC;AACvC,QAAI,WAAW,QAAQ,QAAQ;AAC7B,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AAEA,WAAO,YAAY,aAAa,UAAU;AAAA,EAC5C;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,IAAI,OAA2B;AAC7B,aAAO,QAAQ;AAAA,IACjB;AAAA,IACA,SAAS,CAAC,WAA8CC,aAA6B;AACnF,YAAM,OAAO,QAAQ;AACrB,aAAO,QAAQ,OAAO,QAAQ,MAAM,WAAWA,QAAO,IAAI,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;","names":["import_constants","ReactReconciler","options"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
+
import { Fiber } from 'react-reconciler';
|
|
2
3
|
|
|
3
4
|
type JsonNode = JsonElement | string;
|
|
4
5
|
type JsonElement = {
|
|
@@ -17,10 +18,15 @@ declare class HostElement {
|
|
|
17
18
|
get props(): HostElementProps;
|
|
18
19
|
get children(): HostNode[];
|
|
19
20
|
get parent(): HostElement | null;
|
|
21
|
+
get unstable_fiber(): Fiber;
|
|
20
22
|
get $$typeof(): symbol;
|
|
21
23
|
toJSON(): JsonNode | null;
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
interface FindAllOptions {
|
|
27
|
+
matchDeepestOnly?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
type RootOptions = {
|
|
25
31
|
textComponents?: string[];
|
|
26
32
|
createNodeMock?: (element: ReactElement) => object;
|
|
@@ -28,11 +34,9 @@ type RootOptions = {
|
|
|
28
34
|
type Root = {
|
|
29
35
|
render: (element: ReactElement) => void;
|
|
30
36
|
unmount: () => void;
|
|
31
|
-
container: HostElement;
|
|
32
37
|
root: HostElement | null;
|
|
38
|
+
findAll: (predicate: (element: HostElement) => boolean, options?: FindAllOptions) => HostElement[];
|
|
33
39
|
};
|
|
34
40
|
declare function createRoot(options?: RootOptions): Root;
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
export { CONTAINER_TYPE, HostElement, type HostElementProps, type HostNode, type JsonElement, type JsonNode, type Root, type RootOptions, createRoot };
|
|
42
|
+
export { HostElement, type HostElementProps, type HostNode, type JsonElement, type JsonNode, type Root, type RootOptions, createRoot };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
|
+
import { Fiber } from 'react-reconciler';
|
|
2
3
|
|
|
3
4
|
type JsonNode = JsonElement | string;
|
|
4
5
|
type JsonElement = {
|
|
@@ -17,10 +18,15 @@ declare class HostElement {
|
|
|
17
18
|
get props(): HostElementProps;
|
|
18
19
|
get children(): HostNode[];
|
|
19
20
|
get parent(): HostElement | null;
|
|
21
|
+
get unstable_fiber(): Fiber;
|
|
20
22
|
get $$typeof(): symbol;
|
|
21
23
|
toJSON(): JsonNode | null;
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
interface FindAllOptions {
|
|
27
|
+
matchDeepestOnly?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
24
30
|
type RootOptions = {
|
|
25
31
|
textComponents?: string[];
|
|
26
32
|
createNodeMock?: (element: ReactElement) => object;
|
|
@@ -28,11 +34,9 @@ type RootOptions = {
|
|
|
28
34
|
type Root = {
|
|
29
35
|
render: (element: ReactElement) => void;
|
|
30
36
|
unmount: () => void;
|
|
31
|
-
container: HostElement;
|
|
32
37
|
root: HostElement | null;
|
|
38
|
+
findAll: (predicate: (element: HostElement) => boolean, options?: FindAllOptions) => HostElement[];
|
|
33
39
|
};
|
|
34
40
|
declare function createRoot(options?: RootOptions): Root;
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
export { CONTAINER_TYPE, HostElement, type HostElementProps, type HostNode, type JsonElement, type JsonNode, type Root, type RootOptions, createRoot };
|
|
42
|
+
export { HostElement, type HostElementProps, type HostNode, type JsonElement, type JsonNode, type Root, type RootOptions, createRoot };
|
package/dist/index.js
CHANGED
|
@@ -33,12 +33,29 @@ var __objRest = (source, exclude) => {
|
|
|
33
33
|
// src/renderer.ts
|
|
34
34
|
import { ConcurrentRoot } from "react-reconciler/constants";
|
|
35
35
|
|
|
36
|
-
// src/
|
|
37
|
-
|
|
36
|
+
// src/find-all.ts
|
|
37
|
+
function findAll(root, predicate, options) {
|
|
38
|
+
const results = [];
|
|
39
|
+
const matchingDescendants = [];
|
|
40
|
+
root.children.forEach((child) => {
|
|
41
|
+
if (typeof child === "string") {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
matchingDescendants.push(...findAll(child, predicate, options));
|
|
45
|
+
});
|
|
46
|
+
if (
|
|
47
|
+
// When matchDeepestOnly = true: add current element only if no descendants match
|
|
48
|
+
(!(options == null ? void 0 : options.matchDeepestOnly) || matchingDescendants.length === 0) && predicate(root)
|
|
49
|
+
) {
|
|
50
|
+
results.push(root);
|
|
51
|
+
}
|
|
52
|
+
results.push(...matchingDescendants);
|
|
53
|
+
return results;
|
|
54
|
+
}
|
|
38
55
|
|
|
39
56
|
// src/render-to-json.ts
|
|
40
57
|
function renderToJson(instance) {
|
|
41
|
-
if (
|
|
58
|
+
if (instance.isHidden) {
|
|
42
59
|
return null;
|
|
43
60
|
}
|
|
44
61
|
switch (instance.tag) {
|
|
@@ -63,35 +80,10 @@ function renderToJson(instance) {
|
|
|
63
80
|
type: instance.type,
|
|
64
81
|
props,
|
|
65
82
|
children: renderedChildren,
|
|
66
|
-
$$typeof: Symbol.for("react.test.json")
|
|
67
|
-
};
|
|
68
|
-
Object.defineProperty(result, "$$typeof", {
|
|
69
|
-
value: Symbol.for("react.test.json")
|
|
70
|
-
});
|
|
71
|
-
return result;
|
|
72
|
-
}
|
|
73
|
-
case "CONTAINER": {
|
|
74
|
-
let renderedChildren = null;
|
|
75
|
-
if (instance.children.length) {
|
|
76
|
-
for (let i = 0; i < instance.children.length; i++) {
|
|
77
|
-
const renderedChild = renderToJson(instance.children[i]);
|
|
78
|
-
if (renderedChild !== null) {
|
|
79
|
-
if (renderedChildren === null) {
|
|
80
|
-
renderedChildren = [renderedChild];
|
|
81
|
-
} else {
|
|
82
|
-
renderedChildren.push(renderedChild);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const result = {
|
|
88
|
-
type: CONTAINER_TYPE,
|
|
89
|
-
props: {},
|
|
90
|
-
children: renderedChildren,
|
|
91
|
-
$$typeof: Symbol.for("react.test.json")
|
|
83
|
+
$$typeof: /* @__PURE__ */ Symbol.for("react.test.json")
|
|
92
84
|
};
|
|
93
85
|
Object.defineProperty(result, "$$typeof", {
|
|
94
|
-
value: Symbol.for("react.test.json")
|
|
86
|
+
value: /* @__PURE__ */ Symbol.for("react.test.json")
|
|
95
87
|
});
|
|
96
88
|
return result;
|
|
97
89
|
}
|
|
@@ -99,70 +91,57 @@ function renderToJson(instance) {
|
|
|
99
91
|
}
|
|
100
92
|
|
|
101
93
|
// src/host-element.ts
|
|
102
|
-
var
|
|
94
|
+
var instanceMap = /* @__PURE__ */ new WeakMap();
|
|
103
95
|
var HostElement = class _HostElement {
|
|
104
96
|
constructor(instance) {
|
|
105
97
|
this.instance = instance;
|
|
106
98
|
}
|
|
107
99
|
get type() {
|
|
108
|
-
return this.instance.
|
|
100
|
+
return this.instance.type;
|
|
109
101
|
}
|
|
110
102
|
get props() {
|
|
111
|
-
if (this.instance.tag === "CONTAINER") {
|
|
112
|
-
return {};
|
|
113
|
-
}
|
|
114
103
|
const _a = this.instance.props, { children } = _a, restProps = __objRest(_a, ["children"]);
|
|
115
104
|
return restProps;
|
|
116
105
|
}
|
|
117
106
|
get children() {
|
|
118
|
-
const result = this.instance.children.filter((child) => !child.isHidden).map((child) =>
|
|
107
|
+
const result = this.instance.children.filter((child) => !child.isHidden).map((child) => getHostNodeForInstance(child));
|
|
119
108
|
return result;
|
|
120
109
|
}
|
|
121
110
|
get parent() {
|
|
122
111
|
const parentInstance = this.instance.parent;
|
|
123
|
-
if (parentInstance == null) {
|
|
112
|
+
if (parentInstance == null || parentInstance.tag === "CONTAINER") {
|
|
124
113
|
return null;
|
|
125
114
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return _HostElement.fromContainer(parentInstance);
|
|
131
|
-
}
|
|
115
|
+
return _HostElement.fromInstance(parentInstance);
|
|
116
|
+
}
|
|
117
|
+
get unstable_fiber() {
|
|
118
|
+
return this.instance.unstable_fiber;
|
|
132
119
|
}
|
|
133
120
|
get $$typeof() {
|
|
134
|
-
return Symbol.for("react.test.json");
|
|
121
|
+
return /* @__PURE__ */ Symbol.for("react.test.json");
|
|
135
122
|
}
|
|
136
123
|
toJSON() {
|
|
137
124
|
return renderToJson(this.instance);
|
|
138
125
|
}
|
|
139
126
|
/** @internal */
|
|
140
|
-
static
|
|
141
|
-
const hostElement =
|
|
127
|
+
static fromInstance(instance) {
|
|
128
|
+
const hostElement = instanceMap.get(instance);
|
|
142
129
|
if (hostElement) {
|
|
143
130
|
return hostElement;
|
|
144
131
|
}
|
|
145
|
-
const result = new _HostElement(
|
|
146
|
-
|
|
132
|
+
const result = new _HostElement(instance);
|
|
133
|
+
instanceMap.set(instance, result);
|
|
147
134
|
return result;
|
|
148
135
|
}
|
|
149
|
-
/** @internal */
|
|
150
|
-
static fromInstance(instance) {
|
|
151
|
-
switch (instance.tag) {
|
|
152
|
-
case "TEXT":
|
|
153
|
-
return instance.text;
|
|
154
|
-
case "INSTANCE": {
|
|
155
|
-
const hostElement = instanceToHostElementMap.get(instance);
|
|
156
|
-
if (hostElement) {
|
|
157
|
-
return hostElement;
|
|
158
|
-
}
|
|
159
|
-
const result = new _HostElement(instance);
|
|
160
|
-
instanceToHostElementMap.set(instance, result);
|
|
161
|
-
return result;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
136
|
};
|
|
137
|
+
function getHostNodeForInstance(instance) {
|
|
138
|
+
switch (instance.tag) {
|
|
139
|
+
case "TEXT":
|
|
140
|
+
return instance.text;
|
|
141
|
+
case "INSTANCE":
|
|
142
|
+
return HostElement.fromInstance(instance);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
166
145
|
|
|
167
146
|
// src/reconciler.ts
|
|
168
147
|
import ReactReconciler from "react-reconciler";
|
|
@@ -260,7 +239,7 @@ var hostConfig = {
|
|
|
260
239
|
children: [],
|
|
261
240
|
parent: null,
|
|
262
241
|
rootContainer,
|
|
263
|
-
internalHandle
|
|
242
|
+
unstable_fiber: internalHandle
|
|
264
243
|
};
|
|
265
244
|
},
|
|
266
245
|
/**
|
|
@@ -483,7 +462,7 @@ var hostConfig = {
|
|
|
483
462
|
getInstanceFromNode(node) {
|
|
484
463
|
const instance = nodeToInstanceMap.get(node);
|
|
485
464
|
if (instance !== void 0) {
|
|
486
|
-
return instance.
|
|
465
|
+
return instance.unstable_fiber;
|
|
487
466
|
}
|
|
488
467
|
return null;
|
|
489
468
|
},
|
|
@@ -612,7 +591,7 @@ var hostConfig = {
|
|
|
612
591
|
commitUpdate(instance, type, _prevProps, nextProps, internalHandle) {
|
|
613
592
|
instance.type = type;
|
|
614
593
|
instance.props = nextProps;
|
|
615
|
-
instance.
|
|
594
|
+
instance.unstable_fiber = internalHandle;
|
|
616
595
|
},
|
|
617
596
|
/**
|
|
618
597
|
* #### `hideInstance(instance)`
|
|
@@ -755,7 +734,7 @@ function createRoot(options) {
|
|
|
755
734
|
parent: null,
|
|
756
735
|
config: {
|
|
757
736
|
textComponents: options == null ? void 0 : options.textComponents,
|
|
758
|
-
createNodeMock: (_a = options == null ? void 0 : options.createNodeMock) != null ? _a : () => ({})
|
|
737
|
+
createNodeMock: (_a = options == null ? void 0 : options.createNodeMock) != null ? _a : (() => ({}))
|
|
759
738
|
}
|
|
760
739
|
};
|
|
761
740
|
let containerFiber = TestReconciler.createContainer(
|
|
@@ -793,32 +772,32 @@ function createRoot(options) {
|
|
|
793
772
|
container = null;
|
|
794
773
|
containerFiber = null;
|
|
795
774
|
};
|
|
775
|
+
const getRoot = () => {
|
|
776
|
+
if (containerFiber == null || container == null) {
|
|
777
|
+
throw new Error("Can't access .root on unmounted test renderer");
|
|
778
|
+
}
|
|
779
|
+
if (container.children.length === 0) {
|
|
780
|
+
return null;
|
|
781
|
+
}
|
|
782
|
+
const firstChild = container.children[0];
|
|
783
|
+
if (firstChild.tag === "TEXT") {
|
|
784
|
+
throw new Error("Cannot render text as root element");
|
|
785
|
+
}
|
|
786
|
+
return HostElement.fromInstance(firstChild);
|
|
787
|
+
};
|
|
796
788
|
return {
|
|
797
789
|
render,
|
|
798
790
|
unmount,
|
|
799
791
|
get root() {
|
|
800
|
-
|
|
801
|
-
throw new Error("Can't access .root on unmounted test renderer");
|
|
802
|
-
}
|
|
803
|
-
if (container.children.length === 0) {
|
|
804
|
-
return null;
|
|
805
|
-
}
|
|
806
|
-
const root = HostElement.fromInstance(container.children[0]);
|
|
807
|
-
if (typeof root === "string") {
|
|
808
|
-
throw new Error("Cannot render string as root element");
|
|
809
|
-
}
|
|
810
|
-
return root;
|
|
792
|
+
return getRoot();
|
|
811
793
|
},
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
}
|
|
816
|
-
return HostElement.fromContainer(container);
|
|
794
|
+
findAll: (predicate, options2) => {
|
|
795
|
+
const root = getRoot();
|
|
796
|
+
return root != null ? findAll(root, predicate, options2) : [];
|
|
817
797
|
}
|
|
818
798
|
};
|
|
819
799
|
}
|
|
820
800
|
export {
|
|
821
|
-
CONTAINER_TYPE,
|
|
822
801
|
createRoot
|
|
823
802
|
};
|
|
824
803
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/renderer.ts","../src/constants.ts","../src/render-to-json.ts","../src/host-element.ts","../src/reconciler.ts","../src/utils.ts"],"sourcesContent":["import type { ReactElement } from \"react\";\nimport type { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot } from \"react-reconciler/constants\";\n\nimport { HostElement } from \"./host-element\";\nimport type { Container} from \"./reconciler\";\nimport { TestReconciler } from \"./reconciler\";\n\n// Refs:\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-noop-renderer/src/createReactNoop.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactNativeHostConfig.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactFabricHostConfig.js\n\nexport type RootOptions = {\n textComponents?: string[];\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Root = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n container: HostElement;\n root: HostElement | null;\n};\n\nexport function createRoot(options?: RootOptions): Root {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n config: {\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n ConcurrentRoot,\n null, // hydration callbacks\n false, // isStrictMode\n null, // concurrentUpdatesByDefaultOverride\n \"id\", // identifierPrefix\n () => {}, // onUncaughtError\n () => {}, // onCaughtError\n // @ts-expect-error missing types\n () => {}, // onRecoverableError\n null, // transitionCallbacks\n );\n\n const render = (element: ReactElement) => {\n TestReconciler.updateContainer(element, containerFiber, null, null);\n };\n\n const unmount = () => {\n if (containerFiber == null || container == null) {\n return;\n }\n\n TestReconciler.updateContainer(null, containerFiber, null, null);\n\n container = null;\n containerFiber = null;\n };\n\n return {\n render,\n unmount,\n get root(): HostElement | null {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .root on unmounted test renderer\");\n }\n\n if (container.children.length === 0) {\n return null;\n }\n\n const root = HostElement.fromInstance(container.children[0]);\n if (typeof root === \"string\") {\n throw new Error(\"Cannot render string as root element\");\n }\n\n return root;\n },\n\n get container(): HostElement {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .container on unmounted test renderer\");\n }\n\n return HostElement.fromContainer(container);\n },\n };\n}\n","export const CONTAINER_TYPE = \"CONTAINER\";\n","import { CONTAINER_TYPE } from \"./constants\";\nimport type { Container, Instance, TextInstance } from \"./reconciler\";\n\nexport type JsonNode = JsonElement | string;\n\nexport type JsonElement = {\n type: string;\n props: object;\n children: Array<JsonNode> | null;\n $$typeof: symbol;\n};\n\nexport function renderToJson(instance: Container | Instance | TextInstance): JsonNode | null {\n if (`isHidden` in instance && instance.isHidden) {\n // Omit timed out children from output entirely. This seems like the least\n // surprising behavior. We could perhaps add a separate API that includes\n // them, if it turns out people need it.\n return null;\n }\n\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\": {\n // We don't include the `children` prop in JSON.\n // Instead, we will include the actual rendered children.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...props } = instance.props;\n\n let renderedChildren = null;\n if (instance.children.length) {\n for (let i = 0; i < instance.children.length; i++) {\n const renderedChild = renderToJson(instance.children[i]);\n if (renderedChild !== null) {\n if (renderedChildren === null) {\n renderedChildren = [renderedChild];\n } else {\n renderedChildren.push(renderedChild);\n }\n }\n }\n }\n\n const result = {\n type: instance.type,\n props: props,\n children: renderedChildren,\n $$typeof: Symbol.for(\"react.test.json\"),\n };\n // This is needed for JEST to format snapshot as JSX.\n Object.defineProperty(result, \"$$typeof\", {\n value: Symbol.for(\"react.test.json\"),\n });\n return result;\n }\n\n case \"CONTAINER\": {\n let renderedChildren = null;\n if (instance.children.length) {\n for (let i = 0; i < instance.children.length; i++) {\n const renderedChild = renderToJson(instance.children[i]);\n if (renderedChild !== null) {\n if (renderedChildren === null) {\n renderedChildren = [renderedChild];\n } else {\n renderedChildren.push(renderedChild);\n }\n }\n }\n }\n\n const result = {\n type: CONTAINER_TYPE,\n props: {},\n children: renderedChildren,\n $$typeof: Symbol.for(\"react.test.json\"),\n };\n // This is needed for JEST to format snapshot as JSX.\n Object.defineProperty(result, \"$$typeof\", {\n value: Symbol.for(\"react.test.json\"),\n });\n return result;\n }\n }\n}\n\nexport function renderChildrenToJson(children: Array<Instance | TextInstance> | null) {\n let result = null;\n if (children?.length) {\n for (let i = 0; i < children.length; i++) {\n const renderedChild = renderToJson(children[i]);\n if (renderedChild !== null) {\n if (result === null) {\n result = [renderedChild];\n } else {\n result.push(renderedChild);\n }\n }\n }\n }\n\n return result;\n}\n","import { CONTAINER_TYPE } from \"./constants\";\nimport type { Container, Instance, TextInstance } from \"./reconciler\";\nimport type { JsonNode} from \"./render-to-json\";\nimport { renderToJson } from \"./render-to-json\";\n\nexport type HostNode = HostElement | string;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type HostElementProps = Record<string, any>;\n\nconst instanceToHostElementMap = new WeakMap<Container | Instance, HostElement>();\n\nexport class HostElement {\n private instance: Instance | Container;\n\n private constructor(instance: Instance | Container) {\n this.instance = instance;\n }\n\n get type(): string {\n return this.instance.tag === \"INSTANCE\" ? this.instance.type : CONTAINER_TYPE;\n }\n\n get props(): HostElementProps {\n if (this.instance.tag === \"CONTAINER\") {\n return {};\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...restProps } = this.instance.props;\n return restProps;\n }\n\n get children(): HostNode[] {\n const result = this.instance.children\n .filter((child) => !child.isHidden)\n .map((child) => HostElement.fromInstance(child));\n return result;\n }\n\n get parent(): HostElement | null {\n const parentInstance = this.instance.parent;\n if (parentInstance == null) {\n return null;\n }\n\n switch (parentInstance.tag) {\n case \"INSTANCE\":\n return HostElement.fromInstance(parentInstance) as HostElement;\n\n case \"CONTAINER\":\n return HostElement.fromContainer(parentInstance);\n }\n }\n\n get $$typeof(): symbol {\n return Symbol.for(\"react.test.json\");\n }\n\n toJSON(): JsonNode | null {\n return renderToJson(this.instance);\n }\n\n /** @internal */\n static fromContainer(container: Container): HostElement {\n const hostElement = instanceToHostElementMap.get(container);\n if (hostElement) {\n return hostElement;\n }\n\n const result = new HostElement(container);\n instanceToHostElementMap.set(container, result);\n return result;\n }\n\n /** @internal */\n static fromInstance(instance: Instance | TextInstance): HostNode {\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\": {\n const hostElement = instanceToHostElementMap.get(instance);\n if (hostElement) {\n return hostElement;\n }\n\n const result = new HostElement(instance);\n instanceToHostElementMap.set(instance, result);\n return result;\n }\n }\n }\n}\n","import type { ReactElement } from \"react\";\nimport type { Fiber } from \"react-reconciler\";\nimport ReactReconciler from \"react-reconciler\";\nimport {\n DefaultEventPriority,\n // @ts-expect-error missing types\n NoEventPriority,\n} from \"react-reconciler/constants\";\n\nimport { formatComponentList } from \"./utils\";\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\nexport type OpaqueHandle = Fiber;\n\ntype ReconcilerConfig = {\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\n};\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n config: ReconcilerConfig;\n};\n\nexport type Instance = {\n tag: \"INSTANCE\";\n type: string;\n props: Props;\n children: Array<Instance | TextInstance>;\n parent: Container | Instance | null;\n rootContainer: Container;\n isHidden: boolean;\n internalHandle: OpaqueHandle;\n};\n\nexport type TextInstance = {\n tag: \"TEXT\";\n text: string;\n parent: Container | Instance | null;\n isHidden: boolean;\n};\n\nexport type SuspenseInstance = object;\nexport type HydratableInstance = object;\nexport type PublicInstance = object | TextInstance;\nexport type UpdatePayload = unknown;\nexport type ChildSet = unknown;\nexport type TimeoutHandle = unknown;\nexport type NoTimeout = unknown;\n\ntype HostContext = {\n type: string;\n isInsideText: boolean;\n config: ReconcilerConfig;\n};\n\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nlet currentUpdatePriority: number = NoEventPriority;\n\nconst hostConfig: ReactReconciler.HostConfig<\n Type,\n Props,\n Container,\n Instance,\n TextInstance,\n SuspenseInstance,\n HydratableInstance,\n PublicInstance,\n HostContext,\n UpdatePayload,\n ChildSet,\n TimeoutHandle,\n NoTimeout\n> = {\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform is similar to the DOM and has methods similar to `appendChild`, `removeChild`,\n * and so on, you'll want to use the **mutation mode**. This is the same mode used by React DOM, React ART,\n * and the classic React Native renderer.\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsMutation: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsMutation: true,\n\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform has immutable trees, you'll want the **persistent mode** instead. In that mode,\n * existing nodes are never mutated, and instead every change clones the parent tree and then replaces\n * the whole parent tree at the root. This is the node used by the new React Native renderer, codenamed \"Fabric\".\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsPersistence: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsPersistence: false,\n\n /**\n * #### `createInstance(type, props, rootContainer, hostContext, internalHandle)`\n *\n * This method should return a newly created node. For example, the DOM renderer would call\n * `document.createElement(type)` here and then set the properties from `props`.\n *\n * You can use `rootContainer` to access the root container associated with that tree. For example,\n * in the DOM renderer, this is useful to get the correct `document` reference that the root belongs to.\n *\n * The `hostContext` parameter lets you keep track of some information about your current place in\n * the tree. To learn more about it, see `getChildHostContext` below.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its\n * internal fields, be aware that it may change significantly between versions. You're taking on additional\n * maintenance risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * This method happens **in the render phase**. It can (and usually should) mutate the node it has\n * just created before returning it, but it must not modify any other nodes. It must not register\n * any event handlers on the parent tree. This is because an instance being created doesn't guarantee\n * it would be placed in the tree — it could be left unused and later collected by GC. If you need to do\n * something when an instance is definitely in the tree, look at `commitMount` instead.\n */\n createInstance(\n type: Type,\n props: Props,\n rootContainer: Container,\n _hostContext: HostContext,\n internalHandle: OpaqueHandle,\n ) {\n return {\n tag: \"INSTANCE\",\n type,\n props,\n isHidden: false,\n children: [],\n parent: null,\n rootContainer,\n internalHandle,\n };\n },\n\n /**\n * #### `createTextInstance(text, rootContainer, hostContext, internalHandle)`\n *\n * Same as `createInstance`, but for text nodes. If your renderer doesn't support text nodes, you can\n * throw here.\n */\n createTextInstance(\n text: string,\n rootContainer: Container,\n hostContext: HostContext,\n _internalHandle: OpaqueHandle,\n ): TextInstance {\n if (rootContainer.config.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.config.textComponents,\n )} component. Detected attempt to render \"${text}\" string within a <${\n hostContext.type\n }> component.`,\n );\n }\n\n return {\n tag: \"TEXT\",\n text,\n parent: null,\n isHidden: false,\n };\n },\n\n /**\n * #### `appendInitialChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children.\n * For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * This method happens **in the render phase**. It can mutate `parentInstance` and `child`, but it\n * must not modify any other nodes. It's called while the tree is still being built up and not connected\n * to the actual tree on the screen.\n */\n appendInitialChild: appendChild,\n\n /**\n * #### `finalizeInitialChildren(instance, type, props, rootContainer, hostContext)`\n *\n * In this method, you can perform some final mutations on the `instance`. Unlike with `createInstance`,\n * by the time `finalizeInitialChildren` is called, all the initial children have already been added to\n * the `instance`, but the instance itself has not yet been connected to the tree on the screen.\n *\n * This method happens **in the render phase**. It can mutate `instance`, but it must not modify any other\n * nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.\n *\n * There is a second purpose to this method. It lets you specify whether there is some work that needs to\n * happen when the node is connected to the tree on the screen. If you return `true`, the instance will\n * receive a `commitMount` call later. See its documentation below.\n *\n * If you don't want to do anything here, you should return `false`.\n */\n finalizeInitialChildren(\n _instance: Instance,\n _type: Type,\n _props: Props,\n _rootContainer: Container,\n _hostContext: HostContext,\n ): boolean {\n return false;\n },\n\n /**\n * #### `shouldSetTextContent(type, props)`\n *\n * Some target platforms support setting an instance's text content without manually creating a text node.\n * For example, in the DOM, you can set `node.textContent` instead of creating a text node and appending it.\n *\n * If you return `true` from this method, React will assume that this node's children are text, and will\n * not create nodes for them. It will instead rely on you to have filled that text during `createInstance`.\n * This is a performance optimization. For example, the DOM renderer returns `true` only if `type` is a\n * known text-only parent (like `'textarea'`) or if `props.children` has a `'string'` type. If you return `true`,\n * you will need to implement `resetTextContent` too.\n *\n * If you don't want to do anything here, you should return `false`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n shouldSetTextContent(_type: Type, _props: Props): boolean {\n return false;\n },\n\n setCurrentUpdatePriority(newPriority: number) {\n currentUpdatePriority = newPriority;\n },\n\n getCurrentUpdatePriority() {\n return currentUpdatePriority;\n },\n\n resolveUpdatePriority(): number {\n return currentUpdatePriority || DefaultEventPriority;\n },\n\n shouldAttemptEagerTransition() {\n return false;\n },\n\n /**\n * #### `getRootHostContext(rootContainer)`\n *\n * This method lets you return the initial host context from the root of the tree. See `getChildHostContext`\n * for the explanation of host context.\n *\n * If you don't intend to use host context, you can return `null`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getRootHostContext(rootContainer: Container): HostContext | null {\n return {\n type: \"ROOT\",\n config: rootContainer.config,\n isInsideText: false,\n };\n },\n\n /**\n * #### `getChildHostContext(parentHostContext, type, rootContainer)`\n *\n * Host context lets you track some information about where you are in the tree so that it's available\n * inside `createInstance` as the `hostContext` parameter. For example, the DOM renderer uses it to track\n * whether it's inside an HTML or an SVG tree, because `createInstance` implementation needs to be\n * different for them.\n *\n * If the node of this `type` does not influence the context you want to pass down, you can return\n * `parentHostContext`. Alternatively, you can return any custom object representing the information\n * you want to pass down.\n *\n * If you don't want to do anything here, return `parentHostContext`.\n *\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getChildHostContext(parentHostContext: HostContext, type: Type): HostContext {\n const isInsideText = Boolean(parentHostContext.config.textComponents?.includes(type));\n return { ...parentHostContext, type: type, isInsideText };\n },\n\n /**\n * #### `getPublicInstance(instance)`\n *\n * Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But\n * in some cases it might make sense to only expose some part of it.\n *\n * If you don't want to do anything here, return `instance`.\n */\n getPublicInstance(instance: Instance | TextInstance): PublicInstance {\n switch (instance.tag) {\n case \"INSTANCE\": {\n const createNodeMock = instance.rootContainer.config.createNodeMock;\n const mockNode = createNodeMock({\n type: instance.type,\n props: instance.props,\n key: null,\n });\n\n //if (typeof mockNode === \"object\" && mockNode !== null) {\n nodeToInstanceMap.set(mockNode, instance);\n //}\n\n return mockNode;\n }\n\n default:\n return instance;\n }\n },\n\n /**\n * #### `prepareForCommit(containerInfo)`\n *\n * This method lets you store some information before React starts making changes to the tree on\n * the screen. For example, the DOM renderer stores the current text selection so that it can later\n * restore it. This method is mirrored by `resetAfterCommit`.\n *\n * Even if you don't want to do anything here, you need to return `null` from it.\n */\n prepareForCommit(_containerInfo: Container) {\n return null; // noop\n },\n\n /**\n * #### `resetAfterCommit(containerInfo)`\n *\n * This method is called right after React has performed the tree mutations. You can use it to restore\n * something you've stored in `prepareForCommit` — for example, text selection.\n *\n * You can leave it empty.\n */\n resetAfterCommit(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `preparePortalMount(containerInfo)`\n *\n * This method is called for a container that's used as a portal target. Usually you can leave it empty.\n */\n preparePortalMount(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `scheduleTimeout(fn, delay)`\n *\n * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n\n /**\n * #### `cancelTimeout(id)`\n *\n * You can proxy this to `clearTimeout` or its equivalent in your environment.\n */\n cancelTimeout: clearTimeout,\n\n /**\n * #### `noTimeout`\n *\n * This is a property (not a function) that should be set to something that can never be a valid timeout ID.\n * For example, you can set it to `-1`.\n */\n noTimeout: -1,\n\n /**\n * #### `supportsMicrotasks`\n *\n * Set this to `true` to indicate that your renderer supports `scheduleMicrotask`. We use microtasks as part\n * of our discrete event implementation in React DOM. If you're not sure if your renderer should support this,\n * you probably should. The option to not implement `scheduleMicrotask` exists so that platforms with more control\n * over user events, like React Native, can choose to use a different mechanism.\n */\n supportsMicrotasks: true,\n\n /**\n * #### `scheduleMicrotask(fn)`\n *\n * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\n /**\n * #### `isPrimaryRenderer`\n *\n * This is a property (not a function) that should be set to `true` if your renderer is the main one on the\n * page. For example, if you're writing a renderer for the Terminal, it makes sense to set it to `true`, but\n * if your renderer is used *on top of* React DOM or some other existing renderer, set it to `false`.\n */\n isPrimaryRenderer: true,\n\n /**\n * Whether the renderer shouldn't trigger missing `act()` warnings\n */\n warnsIfNotActing: true,\n\n getInstanceFromNode(node: object): OpaqueHandle | null | undefined {\n const instance = nodeToInstanceMap.get(node);\n if (instance !== undefined) {\n return instance.internalHandle;\n }\n\n return null;\n },\n\n beforeActiveInstanceBlur(): void {\n // noop\n },\n\n afterActiveInstanceBlur(): void {\n // noop\n },\n\n prepareScopeUpdate(scopeInstance: object, instance: Instance): void {\n nodeToInstanceMap.set(scopeInstance, instance);\n },\n\n getInstanceFromScope(scopeInstance: object): Instance | null {\n return nodeToInstanceMap.get(scopeInstance) ?? null;\n },\n\n detachDeletedInstance(_node: Instance): void {},\n\n /**\n * #### `appendChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree, look at `commitMount`.\n */\n appendChild: appendChild,\n\n /**\n * #### `appendChildToContainer(container, child)`\n *\n * Same as `appendChild`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different\n * type than the rest of the tree.\n */\n appendChildToContainer: appendChild,\n\n /**\n * #### `insertBefore(parentInstance, child, beforeChild)`\n *\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list of\n * its children. For example, in the DOM this would translate to a `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is expected\n * that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts of the tree from it.\n */\n insertBefore: insertBefore,\n\n /**\n * #### `insertInContainerBefore(container, child, beforeChild)\n *\n * Same as `insertBefore`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n insertInContainerBefore: insertBefore,\n\n /**\n * #### `removeChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage collection\n * would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\n removeChild: removeChild,\n\n /**\n * #### `removeChildFromContainer(container, child)`\n *\n * Same as `removeChild`, but for when a node is detached from the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n removeChildFromContainer: removeChild,\n\n /**\n * #### `resetTextContent(instance)`\n *\n * If you returned `true` from `shouldSetTextContent` for the previous props, but returned `false` from\n * `shouldSetTextContent` for the next props, React will call this method so that you can clear the text\n * content you were managing manually. For example, in the DOM you could set `node.textContent = ''`.\n *\n * If you never return `true` from `shouldSetTextContent`, you can leave it empty.\n */\n resetTextContent(_instance: Instance): void {\n // noop\n },\n\n /**\n * #### `commitTextUpdate(textInstance, prevText, nextText)`\n *\n * This method should mutate the `textInstance` and update its text content to `nextText`.\n *\n * Here, `textInstance` is a node created by `createTextInstance`.\n */\n commitTextUpdate(textInstance: TextInstance, _oldText: string, newText: string): void {\n textInstance.text = newText;\n },\n\n /**\n * #### `commitMount(instance, type, props, internalHandle)`\n *\n * This method is only called if you returned `true` from `finalizeInitialChildren` for this instance.\n *\n * It lets you do some additional work after the node is actually attached to the tree on the screen for\n * the first time. For example, the DOM renderer uses it to trigger focus on nodes with the `autoFocus` attribute.\n *\n * Note that `commitMount` does not mirror `removeChild` one to one because `removeChild` is only called for\n * the top-level removed node. This is why ideally `commitMount` should not mutate any nodes other than the\n * `instance` itself. For example, if it registers some events on some node above, it will be your responsibility\n * to traverse the tree in `removeChild` and clean them up, which is not ideal.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal\n * fields, be aware that it may change significantly between versions. You're taking on additional maintenance\n * risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * If you never return `true` from `finalizeInitialChildren`, you can leave it empty.\n */\n commitMount(\n _instance: Instance,\n _type: Type,\n _props: Props,\n _internalHandle: OpaqueHandle,\n ): void {\n // noop\n },\n\n /**\n * #### `commitUpdate(instance, type, prevProps, nextProps, internalHandle)`\n *\n * This method should mutate the `instance` according to the set of changes in `updatePayload`. Here, `updatePayload`\n * is the object that you've returned from `prepareUpdate` and has an arbitrary structure that makes sense for your\n * renderer. For example, the DOM renderer returns an update payload like `[prop1, value1, prop2, value2, ...]` from\n * `prepareUpdate`, and that structure gets passed into `commitUpdate`. Ideally, all the diffing and calculation\n * should happen inside `prepareUpdate` so that `commitUpdate` can be fast and straightforward.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields,\n * be aware that it may change significantly between versions. You're taking on additional maintenance risk by\n * reading from it, and giving up all guarantees if you write something to it.\n */\n // @ts-expect-error types are not updated\n commitUpdate(\n instance: Instance,\n type: Type,\n _prevProps: Props,\n nextProps: Props,\n internalHandle: OpaqueHandle,\n ): void {\n instance.type = type;\n instance.props = nextProps;\n instance.internalHandle = internalHandle;\n },\n\n /**\n * #### `hideInstance(instance)`\n *\n * This method should make the `instance` invisible without removing it from the tree. For example, it can apply\n * visual styling to hide it. It is used by Suspense to hide the tree while the fallback is visible.\n */\n hideInstance(instance: Instance): void {\n instance.isHidden = true;\n },\n\n /**\n * #### `hideTextInstance(textInstance)`\n *\n * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\n /**\n * #### `unhideInstance(instance, props)`\n *\n * This method should make the `instance` visible, undoing what `hideInstance` did.\n */\n unhideInstance(instance: Instance, _props: Props): void {\n instance.isHidden = false;\n },\n\n /**\n * #### `unhideTextInstance(textInstance, text)`\n *\n * Same as `unhideInstance`, but for nodes created by `createTextInstance`.\n */\n unhideTextInstance(textInstance: TextInstance, _text: string): void {\n textInstance.isHidden = false;\n },\n\n /**\n * #### `clearContainer(container)`\n *\n * This method should mutate the `container` root node and remove all children from it.\n */\n clearContainer(container: Container): void {\n container.children.forEach((child) => {\n child.parent = null;\n });\n\n container.children.splice(0);\n },\n\n /**\n * #### `maySuspendCommit(type, props)`\n *\n * This method is called during render to determine if the Host Component type and props require\n * some kind of loading process to complete before committing an update.\n */\n maySuspendCommit(_type: Type, _props: Props): boolean {\n return false;\n },\n\n /**\n * #### `preloadInstance(type, props)`\n *\n * This method may be called during render if the Host Component type and props might suspend a commit.\n * It can be used to initiate any work that might shorten the duration of a suspended commit.\n */\n preloadInstance(_type: Type, _props: Props): boolean {\n return true;\n },\n\n /**\n * #### `startSuspendingCommit()`\n *\n * This method is called just before the commit phase. Use it to set up any necessary state while any Host\n * Components that might suspend this commit are evaluated to determine if the commit must be suspended.\n */\n startSuspendingCommit() {},\n\n /**\n * #### `suspendInstance(type, props)`\n *\n * This method is called after `startSuspendingCommit` for each Host Component that indicated it might\n * suspend a commit.\n */\n suspendInstance() {},\n\n /**\n * #### `waitForCommitToBeReady()`\n *\n * This method is called after all `suspendInstance` calls are complete.\n *\n * Return `null` if the commit can happen immediately.\n * Return `(initiateCommit: Function) => Function` if the commit must be suspended. The argument to this\n * callback will initiate the commit when called. The return value is a cancellation function that the\n * Reconciler can use to abort the commit.\n */\n waitForCommitToBeReady() {\n return null;\n },\n\n // -------------------\n // Hydration Methods\n // (optional)\n // You can optionally implement hydration to \"attach\" to the existing tree during the initial render instead\n // of creating it from scratch. For example, the DOM renderer uses this to attach to an HTML markup.\n //\n // To support hydration, you need to declare `supportsHydration: true` and then implement the methods in\n // the \"Hydration\" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js).\n // File an issue if you need help.\n // -------------------\n supportsHydration: false,\n\n NotPendingTransition: null,\n\n resetFormInstance(_form: Instance) {},\n\n requestPostPaintCallback(_callback: (endTime: number) => void) {},\n};\n\nexport const TestReconciler = ReactReconciler(hostConfig);\n\n/**\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree,\n * look at `commitMount`.\n */\nfunction appendChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n parentInstance.children.push(child);\n}\n\n/**\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list\n * of its children. For example, in the DOM this would translate to a\n * `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is\n * expected that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts\n * of the tree from it.\n */\nfunction insertBefore(\n parentInstance: Container | Instance,\n child: Instance | TextInstance,\n beforeChild: Instance | TextInstance,\n): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n const beforeIndex = parentInstance.children.indexOf(beforeChild);\n parentInstance.children.splice(beforeIndex, 0, child);\n}\n\n/**\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage\n * collection would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\nfunction removeChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n parentInstance.children.splice(index, 1);\n child.parent = null;\n}\n","export function formatComponentList(names: string[]): string {\n if (names.length === 0) {\n return \"\";\n }\n\n if (names.length === 1) {\n return `<${names[0]}>`;\n }\n\n if (names.length === 2) {\n return `<${names[0]}> or <${names[1]}>`;\n }\n\n const allButLast = names.slice(0, -1);\n const last = names[names.length - 1];\n\n return `${allButLast.map((name) => `<${name}>`).join(\", \")}, or <${last}>`;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/renderer.ts","../src/find-all.ts","../src/render-to-json.ts","../src/host-element.ts","../src/reconciler.ts","../src/utils.ts"],"sourcesContent":["import type { ReactElement } from \"react\";\nimport type { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot } from \"react-reconciler/constants\";\n\nimport { findAll, type FindAllOptions } from \"./find-all\";\nimport { HostElement } from \"./host-element\";\nimport type { Container } from \"./reconciler\";\nimport { TestReconciler } from \"./reconciler\";\n\n// Refs:\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-noop-renderer/src/createReactNoop.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactNativeHostConfig.js\n// https://github.com/facebook/react/blob/v18.3.1/packages/react-native-renderer/src/ReactFabricHostConfig.js\n\nexport type RootOptions = {\n textComponents?: string[];\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Root = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n\n root: HostElement | null;\n findAll: (\n predicate: (element: HostElement) => boolean,\n options?: FindAllOptions,\n ) => HostElement[];\n};\n\nexport function createRoot(options?: RootOptions): Root {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n config: {\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n ConcurrentRoot,\n null, // hydration callbacks\n false, // isStrictMode\n null, // concurrentUpdatesByDefaultOverride\n \"id\", // identifierPrefix\n () => {}, // onUncaughtError\n () => {}, // onCaughtError\n // @ts-expect-error missing types\n () => {}, // onRecoverableError\n null, // transitionCallbacks\n );\n\n const render = (element: ReactElement) => {\n TestReconciler.updateContainer(element, containerFiber, null, null);\n };\n\n const unmount = () => {\n if (containerFiber == null || container == null) {\n return;\n }\n\n TestReconciler.updateContainer(null, containerFiber, null, null);\n\n container = null;\n containerFiber = null;\n };\n\n const getRoot = () => {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .root on unmounted test renderer\");\n }\n\n if (container.children.length === 0) {\n return null;\n }\n\n const firstChild = container.children[0];\n if (firstChild.tag === \"TEXT\") {\n throw new Error(\"Cannot render text as root element\");\n }\n\n return HostElement.fromInstance(firstChild);\n };\n\n return {\n render,\n unmount,\n get root(): HostElement | null {\n return getRoot();\n },\n findAll: (predicate: (element: HostElement) => boolean, options?: FindAllOptions) => {\n const root = getRoot();\n return root != null ? findAll(root, predicate, options) : [];\n },\n };\n}\n","import type { HostElement } from \"./host-element\";\n\nexport interface FindAllOptions {\n /* Exclude any ancestors of deepest matched elements even if they match the predicate */\n matchDeepestOnly?: boolean;\n}\n\nexport function findAll(\n root: HostElement,\n predicate: (element: HostElement) => boolean,\n options?: FindAllOptions,\n): HostElement[] {\n const results: HostElement[] = [];\n\n // Match descendants first but do not add them to results yet.\n const matchingDescendants: HostElement[] = [];\n\n root.children.forEach((child) => {\n if (typeof child === \"string\") {\n return;\n }\n\n matchingDescendants.push(...findAll(child, predicate, options));\n });\n\n if (\n // When matchDeepestOnly = true: add current element only if no descendants match\n (!options?.matchDeepestOnly || matchingDescendants.length === 0) &&\n predicate(root)\n ) {\n results.push(root);\n }\n\n // Add matching descendants after element to preserve original tree walk order.\n results.push(...matchingDescendants);\n\n return results;\n}\n","import type { Instance, TextInstance } from \"./reconciler\";\n\nexport type JsonNode = JsonElement | string;\n\nexport type JsonElement = {\n type: string;\n props: object;\n children: Array<JsonNode> | null;\n $$typeof: symbol;\n};\n\nexport function renderToJson(instance: Instance | TextInstance): JsonNode | null {\n if (instance.isHidden) {\n return null;\n }\n\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\": {\n // We don't include the `children` prop in JSON.\n // Instead, we will include the actual rendered children.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...props } = instance.props;\n\n let renderedChildren = null;\n if (instance.children.length) {\n for (let i = 0; i < instance.children.length; i++) {\n const renderedChild = renderToJson(instance.children[i]);\n if (renderedChild !== null) {\n if (renderedChildren === null) {\n renderedChildren = [renderedChild];\n } else {\n renderedChildren.push(renderedChild);\n }\n }\n }\n }\n\n const result = {\n type: instance.type,\n props: props,\n children: renderedChildren,\n $$typeof: Symbol.for(\"react.test.json\"),\n };\n // This is needed for JEST to format snapshot as JSX.\n Object.defineProperty(result, \"$$typeof\", {\n value: Symbol.for(\"react.test.json\"),\n });\n return result;\n }\n }\n}\n\nexport function renderChildrenToJson(children: Array<Instance | TextInstance> | null) {\n let result = null;\n if (children?.length) {\n for (let i = 0; i < children.length; i++) {\n const renderedChild = renderToJson(children[i]);\n if (renderedChild !== null) {\n if (result === null) {\n result = [renderedChild];\n } else {\n result.push(renderedChild);\n }\n }\n }\n }\n\n return result;\n}\n","import type { Fiber } from \"react-reconciler\";\n\nimport type { Instance, TextInstance } from \"./reconciler\";\nimport type { JsonNode } from \"./render-to-json\";\nimport { renderToJson } from \"./render-to-json\";\n\nexport type HostNode = HostElement | string;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type HostElementProps = Record<string, any>;\n\nconst instanceMap = new WeakMap<Instance, HostElement>();\n\nexport class HostElement {\n private instance: Instance;\n\n private constructor(instance: Instance) {\n this.instance = instance;\n }\n\n get type(): string {\n return this.instance.type;\n }\n\n get props(): HostElementProps {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { children, ...restProps } = this.instance.props;\n return restProps;\n }\n\n get children(): HostNode[] {\n const result = this.instance.children\n .filter((child) => !child.isHidden)\n .map((child) => getHostNodeForInstance(child));\n return result;\n }\n\n get parent(): HostElement | null {\n const parentInstance = this.instance.parent;\n if (parentInstance == null || parentInstance.tag === \"CONTAINER\") {\n return null;\n }\n\n return HostElement.fromInstance(parentInstance);\n }\n\n get unstable_fiber(): Fiber {\n return this.instance.unstable_fiber;\n }\n\n get $$typeof(): symbol {\n return Symbol.for(\"react.test.json\");\n }\n\n toJSON(): JsonNode | null {\n return renderToJson(this.instance);\n }\n\n /** @internal */\n static fromInstance(instance: Instance): HostElement {\n const hostElement = instanceMap.get(instance);\n if (hostElement) {\n return hostElement;\n }\n\n const result = new HostElement(instance);\n instanceMap.set(instance, result);\n return result;\n }\n}\n\nexport function getHostNodeForInstance(instance: Instance | TextInstance): HostNode {\n switch (instance.tag) {\n case \"TEXT\":\n return instance.text;\n\n case \"INSTANCE\":\n return HostElement.fromInstance(instance);\n }\n}\n","import type { ReactElement } from \"react\";\nimport type { Fiber } from \"react-reconciler\";\nimport ReactReconciler from \"react-reconciler\";\nimport {\n DefaultEventPriority,\n // @ts-expect-error missing types\n NoEventPriority,\n} from \"react-reconciler/constants\";\n\nimport { formatComponentList } from \"./utils\";\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\n\ntype ReconcilerConfig = {\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\n};\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n config: ReconcilerConfig;\n};\n\nexport type Instance = {\n tag: \"INSTANCE\";\n type: string;\n props: Props;\n children: Array<Instance | TextInstance>;\n parent: Container | Instance | null;\n rootContainer: Container;\n isHidden: boolean;\n unstable_fiber: Fiber;\n};\n\nexport type TextInstance = {\n tag: \"TEXT\";\n text: string;\n parent: Container | Instance | null;\n isHidden: boolean;\n};\n\nexport type SuspenseInstance = object;\nexport type HydratableInstance = object;\nexport type PublicInstance = object | TextInstance;\nexport type UpdatePayload = unknown;\nexport type ChildSet = unknown;\nexport type TimeoutHandle = unknown;\nexport type NoTimeout = unknown;\n\ntype HostContext = {\n type: string;\n isInsideText: boolean;\n config: ReconcilerConfig;\n};\n\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\nlet currentUpdatePriority: number = NoEventPriority;\n\nconst hostConfig: ReactReconciler.HostConfig<\n Type,\n Props,\n Container,\n Instance,\n TextInstance,\n SuspenseInstance,\n HydratableInstance,\n PublicInstance,\n HostContext,\n UpdatePayload,\n ChildSet,\n TimeoutHandle,\n NoTimeout\n> = {\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform is similar to the DOM and has methods similar to `appendChild`, `removeChild`,\n * and so on, you'll want to use the **mutation mode**. This is the same mode used by React DOM, React ART,\n * and the classic React Native renderer.\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsMutation: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsMutation: true,\n\n /**\n * The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.\n *\n * If your target platform has immutable trees, you'll want the **persistent mode** instead. In that mode,\n * existing nodes are never mutated, and instead every change clones the parent tree and then replaces\n * the whole parent tree at the root. This is the node used by the new React Native renderer, codenamed \"Fabric\".\n *\n * ```js\n * const HostConfig = {\n * // ...\n * supportsPersistence: true,\n * // ...\n * }\n * ```\n *\n * Depending on the mode, the reconciler will call different methods on your host config.\n * If you're not sure which one you want, you likely need the mutation mode.\n */\n supportsPersistence: false,\n\n /**\n * #### `createInstance(type, props, rootContainer, hostContext, internalHandle)`\n *\n * This method should return a newly created node. For example, the DOM renderer would call\n * `document.createElement(type)` here and then set the properties from `props`.\n *\n * You can use `rootContainer` to access the root container associated with that tree. For example,\n * in the DOM renderer, this is useful to get the correct `document` reference that the root belongs to.\n *\n * The `hostContext` parameter lets you keep track of some information about your current place in\n * the tree. To learn more about it, see `getChildHostContext` below.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its\n * internal fields, be aware that it may change significantly between versions. You're taking on additional\n * maintenance risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * This method happens **in the render phase**. It can (and usually should) mutate the node it has\n * just created before returning it, but it must not modify any other nodes. It must not register\n * any event handlers on the parent tree. This is because an instance being created doesn't guarantee\n * it would be placed in the tree — it could be left unused and later collected by GC. If you need to do\n * something when an instance is definitely in the tree, look at `commitMount` instead.\n */\n createInstance(\n type: Type,\n props: Props,\n rootContainer: Container,\n _hostContext: HostContext,\n internalHandle: Fiber,\n ) {\n return {\n tag: \"INSTANCE\",\n type,\n props,\n isHidden: false,\n children: [],\n parent: null,\n rootContainer,\n unstable_fiber: internalHandle,\n };\n },\n\n /**\n * #### `createTextInstance(text, rootContainer, hostContext, internalHandle)`\n *\n * Same as `createInstance`, but for text nodes. If your renderer doesn't support text nodes, you can\n * throw here.\n */\n createTextInstance(\n text: string,\n rootContainer: Container,\n hostContext: HostContext,\n _internalHandle: Fiber,\n ): TextInstance {\n if (rootContainer.config.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.config.textComponents,\n )} component. Detected attempt to render \"${text}\" string within a <${\n hostContext.type\n }> component.`,\n );\n }\n\n return {\n tag: \"TEXT\",\n text,\n parent: null,\n isHidden: false,\n };\n },\n\n /**\n * #### `appendInitialChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children.\n * For example, in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * This method happens **in the render phase**. It can mutate `parentInstance` and `child`, but it\n * must not modify any other nodes. It's called while the tree is still being built up and not connected\n * to the actual tree on the screen.\n */\n appendInitialChild: appendChild,\n\n /**\n * #### `finalizeInitialChildren(instance, type, props, rootContainer, hostContext)`\n *\n * In this method, you can perform some final mutations on the `instance`. Unlike with `createInstance`,\n * by the time `finalizeInitialChildren` is called, all the initial children have already been added to\n * the `instance`, but the instance itself has not yet been connected to the tree on the screen.\n *\n * This method happens **in the render phase**. It can mutate `instance`, but it must not modify any other\n * nodes. It's called while the tree is still being built up and not connected to the actual tree on the screen.\n *\n * There is a second purpose to this method. It lets you specify whether there is some work that needs to\n * happen when the node is connected to the tree on the screen. If you return `true`, the instance will\n * receive a `commitMount` call later. See its documentation below.\n *\n * If you don't want to do anything here, you should return `false`.\n */\n finalizeInitialChildren(\n _instance: Instance,\n _type: Type,\n _props: Props,\n _rootContainer: Container,\n _hostContext: HostContext,\n ): boolean {\n return false;\n },\n\n /**\n * #### `shouldSetTextContent(type, props)`\n *\n * Some target platforms support setting an instance's text content without manually creating a text node.\n * For example, in the DOM, you can set `node.textContent` instead of creating a text node and appending it.\n *\n * If you return `true` from this method, React will assume that this node's children are text, and will\n * not create nodes for them. It will instead rely on you to have filled that text during `createInstance`.\n * This is a performance optimization. For example, the DOM renderer returns `true` only if `type` is a\n * known text-only parent (like `'textarea'`) or if `props.children` has a `'string'` type. If you return `true`,\n * you will need to implement `resetTextContent` too.\n *\n * If you don't want to do anything here, you should return `false`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n shouldSetTextContent(_type: Type, _props: Props): boolean {\n return false;\n },\n\n setCurrentUpdatePriority(newPriority: number) {\n currentUpdatePriority = newPriority;\n },\n\n getCurrentUpdatePriority() {\n return currentUpdatePriority;\n },\n\n resolveUpdatePriority(): number {\n return currentUpdatePriority || DefaultEventPriority;\n },\n\n shouldAttemptEagerTransition() {\n return false;\n },\n\n /**\n * #### `getRootHostContext(rootContainer)`\n *\n * This method lets you return the initial host context from the root of the tree. See `getChildHostContext`\n * for the explanation of host context.\n *\n * If you don't intend to use host context, you can return `null`.\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getRootHostContext(rootContainer: Container): HostContext | null {\n return {\n type: \"ROOT\",\n config: rootContainer.config,\n isInsideText: false,\n };\n },\n\n /**\n * #### `getChildHostContext(parentHostContext, type, rootContainer)`\n *\n * Host context lets you track some information about where you are in the tree so that it's available\n * inside `createInstance` as the `hostContext` parameter. For example, the DOM renderer uses it to track\n * whether it's inside an HTML or an SVG tree, because `createInstance` implementation needs to be\n * different for them.\n *\n * If the node of this `type` does not influence the context you want to pass down, you can return\n * `parentHostContext`. Alternatively, you can return any custom object representing the information\n * you want to pass down.\n *\n * If you don't want to do anything here, return `parentHostContext`.\n *\n * This method happens **in the render phase**. Do not mutate the tree from it.\n */\n getChildHostContext(parentHostContext: HostContext, type: Type): HostContext {\n const isInsideText = Boolean(parentHostContext.config.textComponents?.includes(type));\n return { ...parentHostContext, type: type, isInsideText };\n },\n\n /**\n * #### `getPublicInstance(instance)`\n *\n * Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But\n * in some cases it might make sense to only expose some part of it.\n *\n * If you don't want to do anything here, return `instance`.\n */\n getPublicInstance(instance: Instance | TextInstance): PublicInstance {\n switch (instance.tag) {\n case \"INSTANCE\": {\n const createNodeMock = instance.rootContainer.config.createNodeMock;\n const mockNode = createNodeMock({\n type: instance.type,\n props: instance.props,\n key: null,\n });\n\n nodeToInstanceMap.set(mockNode, instance);\n\n return mockNode;\n }\n\n default:\n return instance;\n }\n },\n\n /**\n * #### `prepareForCommit(containerInfo)`\n *\n * This method lets you store some information before React starts making changes to the tree on\n * the screen. For example, the DOM renderer stores the current text selection so that it can later\n * restore it. This method is mirrored by `resetAfterCommit`.\n *\n * Even if you don't want to do anything here, you need to return `null` from it.\n */\n prepareForCommit(_containerInfo: Container) {\n return null; // noop\n },\n\n /**\n * #### `resetAfterCommit(containerInfo)`\n *\n * This method is called right after React has performed the tree mutations. You can use it to restore\n * something you've stored in `prepareForCommit` — for example, text selection.\n *\n * You can leave it empty.\n */\n resetAfterCommit(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `preparePortalMount(containerInfo)`\n *\n * This method is called for a container that's used as a portal target. Usually you can leave it empty.\n */\n preparePortalMount(_containerInfo: Container): void {\n // noop\n },\n\n /**\n * #### `scheduleTimeout(fn, delay)`\n *\n * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n\n /**\n * #### `cancelTimeout(id)`\n *\n * You can proxy this to `clearTimeout` or its equivalent in your environment.\n */\n cancelTimeout: clearTimeout,\n\n /**\n * #### `noTimeout`\n *\n * This is a property (not a function) that should be set to something that can never be a valid timeout ID.\n * For example, you can set it to `-1`.\n */\n noTimeout: -1,\n\n /**\n * #### `supportsMicrotasks`\n *\n * Set this to `true` to indicate that your renderer supports `scheduleMicrotask`. We use microtasks as part\n * of our discrete event implementation in React DOM. If you're not sure if your renderer should support this,\n * you probably should. The option to not implement `scheduleMicrotask` exists so that platforms with more control\n * over user events, like React Native, can choose to use a different mechanism.\n */\n supportsMicrotasks: true,\n\n /**\n * #### `scheduleMicrotask(fn)`\n *\n * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\n /**\n * #### `isPrimaryRenderer`\n *\n * This is a property (not a function) that should be set to `true` if your renderer is the main one on the\n * page. For example, if you're writing a renderer for the Terminal, it makes sense to set it to `true`, but\n * if your renderer is used *on top of* React DOM or some other existing renderer, set it to `false`.\n */\n isPrimaryRenderer: true,\n\n /**\n * Whether the renderer shouldn't trigger missing `act()` warnings\n */\n warnsIfNotActing: true,\n\n getInstanceFromNode(node: object): Fiber | null | undefined {\n const instance = nodeToInstanceMap.get(node);\n if (instance !== undefined) {\n return instance.unstable_fiber;\n }\n\n return null;\n },\n\n beforeActiveInstanceBlur(): void {\n // noop\n },\n\n afterActiveInstanceBlur(): void {\n // noop\n },\n\n prepareScopeUpdate(scopeInstance: object, instance: Instance): void {\n nodeToInstanceMap.set(scopeInstance, instance);\n },\n\n getInstanceFromScope(scopeInstance: object): Instance | null {\n return nodeToInstanceMap.get(scopeInstance) ?? null;\n },\n\n detachDeletedInstance(_node: Instance): void {},\n\n /**\n * #### `appendChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree, look at `commitMount`.\n */\n appendChild: appendChild,\n\n /**\n * #### `appendChildToContainer(container, child)`\n *\n * Same as `appendChild`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different\n * type than the rest of the tree.\n */\n appendChildToContainer: appendChild,\n\n /**\n * #### `insertBefore(parentInstance, child, beforeChild)`\n *\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list of\n * its children. For example, in the DOM this would translate to a `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is expected\n * that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts of the tree from it.\n */\n insertBefore: insertBefore,\n\n /**\n * #### `insertInContainerBefore(container, child, beforeChild)\n *\n * Same as `insertBefore`, but for when a node is attached to the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n insertInContainerBefore: insertBefore,\n\n /**\n * #### `removeChild(parentInstance, child)`\n *\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage collection\n * would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\n removeChild: removeChild,\n\n /**\n * #### `removeChildFromContainer(container, child)`\n *\n * Same as `removeChild`, but for when a node is detached from the root container. This is useful if attaching\n * to the root has a slightly different implementation, or if the root container nodes are of a different type\n * than the rest of the tree.\n */\n removeChildFromContainer: removeChild,\n\n /**\n * #### `resetTextContent(instance)`\n *\n * If you returned `true` from `shouldSetTextContent` for the previous props, but returned `false` from\n * `shouldSetTextContent` for the next props, React will call this method so that you can clear the text\n * content you were managing manually. For example, in the DOM you could set `node.textContent = ''`.\n *\n * If you never return `true` from `shouldSetTextContent`, you can leave it empty.\n */\n resetTextContent(_instance: Instance): void {\n // noop\n },\n\n /**\n * #### `commitTextUpdate(textInstance, prevText, nextText)`\n *\n * This method should mutate the `textInstance` and update its text content to `nextText`.\n *\n * Here, `textInstance` is a node created by `createTextInstance`.\n */\n commitTextUpdate(textInstance: TextInstance, _oldText: string, newText: string): void {\n textInstance.text = newText;\n },\n\n /**\n * #### `commitMount(instance, type, props, internalHandle)`\n *\n * This method is only called if you returned `true` from `finalizeInitialChildren` for this instance.\n *\n * It lets you do some additional work after the node is actually attached to the tree on the screen for\n * the first time. For example, the DOM renderer uses it to trigger focus on nodes with the `autoFocus` attribute.\n *\n * Note that `commitMount` does not mirror `removeChild` one to one because `removeChild` is only called for\n * the top-level removed node. This is why ideally `commitMount` should not mutate any nodes other than the\n * `instance` itself. For example, if it registers some events on some node above, it will be your responsibility\n * to traverse the tree in `removeChild` and clean them up, which is not ideal.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal\n * fields, be aware that it may change significantly between versions. You're taking on additional maintenance\n * risk by reading from it, and giving up all guarantees if you write something to it.\n *\n * If you never return `true` from `finalizeInitialChildren`, you can leave it empty.\n */\n commitMount(_instance: Instance, _type: Type, _props: Props, _internalHandle: Fiber): void {\n // noop\n },\n\n /**\n * #### `commitUpdate(instance, type, prevProps, nextProps, internalHandle)`\n *\n * This method should mutate the `instance` according to the set of changes in `updatePayload`. Here, `updatePayload`\n * is the object that you've returned from `prepareUpdate` and has an arbitrary structure that makes sense for your\n * renderer. For example, the DOM renderer returns an update payload like `[prop1, value1, prop2, value2, ...]` from\n * `prepareUpdate`, and that structure gets passed into `commitUpdate`. Ideally, all the diffing and calculation\n * should happen inside `prepareUpdate` so that `commitUpdate` can be fast and straightforward.\n *\n * The `internalHandle` data structure is meant to be opaque. If you bend the rules and rely on its internal fields,\n * be aware that it may change significantly between versions. You're taking on additional maintenance risk by\n * reading from it, and giving up all guarantees if you write something to it.\n */\n // @ts-expect-error types are not updated\n commitUpdate(\n instance: Instance,\n type: Type,\n _prevProps: Props,\n nextProps: Props,\n internalHandle: Fiber,\n ): void {\n instance.type = type;\n instance.props = nextProps;\n instance.unstable_fiber = internalHandle;\n },\n\n /**\n * #### `hideInstance(instance)`\n *\n * This method should make the `instance` invisible without removing it from the tree. For example, it can apply\n * visual styling to hide it. It is used by Suspense to hide the tree while the fallback is visible.\n */\n hideInstance(instance: Instance): void {\n instance.isHidden = true;\n },\n\n /**\n * #### `hideTextInstance(textInstance)`\n *\n * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\n /**\n * #### `unhideInstance(instance, props)`\n *\n * This method should make the `instance` visible, undoing what `hideInstance` did.\n */\n unhideInstance(instance: Instance, _props: Props): void {\n instance.isHidden = false;\n },\n\n /**\n * #### `unhideTextInstance(textInstance, text)`\n *\n * Same as `unhideInstance`, but for nodes created by `createTextInstance`.\n */\n unhideTextInstance(textInstance: TextInstance, _text: string): void {\n textInstance.isHidden = false;\n },\n\n /**\n * #### `clearContainer(container)`\n *\n * This method should mutate the `container` root node and remove all children from it.\n */\n clearContainer(container: Container): void {\n container.children.forEach((child) => {\n child.parent = null;\n });\n\n container.children.splice(0);\n },\n\n /**\n * #### `maySuspendCommit(type, props)`\n *\n * This method is called during render to determine if the Host Component type and props require\n * some kind of loading process to complete before committing an update.\n */\n maySuspendCommit(_type: Type, _props: Props): boolean {\n return false;\n },\n\n /**\n * #### `preloadInstance(type, props)`\n *\n * This method may be called during render if the Host Component type and props might suspend a commit.\n * It can be used to initiate any work that might shorten the duration of a suspended commit.\n */\n preloadInstance(_type: Type, _props: Props): boolean {\n return true;\n },\n\n /**\n * #### `startSuspendingCommit()`\n *\n * This method is called just before the commit phase. Use it to set up any necessary state while any Host\n * Components that might suspend this commit are evaluated to determine if the commit must be suspended.\n */\n startSuspendingCommit() {},\n\n /**\n * #### `suspendInstance(type, props)`\n *\n * This method is called after `startSuspendingCommit` for each Host Component that indicated it might\n * suspend a commit.\n */\n suspendInstance() {},\n\n /**\n * #### `waitForCommitToBeReady()`\n *\n * This method is called after all `suspendInstance` calls are complete.\n *\n * Return `null` if the commit can happen immediately.\n * Return `(initiateCommit: Function) => Function` if the commit must be suspended. The argument to this\n * callback will initiate the commit when called. The return value is a cancellation function that the\n * Reconciler can use to abort the commit.\n */\n waitForCommitToBeReady() {\n return null;\n },\n\n // -------------------\n // Hydration Methods\n // (optional)\n // You can optionally implement hydration to \"attach\" to the existing tree during the initial render instead\n // of creating it from scratch. For example, the DOM renderer uses this to attach to an HTML markup.\n //\n // To support hydration, you need to declare `supportsHydration: true` and then implement the methods in\n // the \"Hydration\" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js).\n // File an issue if you need help.\n // -------------------\n supportsHydration: false,\n\n NotPendingTransition: null,\n\n resetFormInstance(_form: Instance) {},\n\n requestPostPaintCallback(_callback: (endTime: number) => void) {},\n};\n\nexport const TestReconciler = ReactReconciler(hostConfig);\n\n/**\n * This method should mutate the `parentInstance` and add the child to its list of children. For example,\n * in the DOM this would translate to a `parentInstance.appendChild(child)` call.\n *\n * Although this method currently runs in the commit phase, you still should not mutate any other nodes\n * in it. If you need to do some additional work when a node is definitely connected to the visible tree,\n * look at `commitMount`.\n */\nfunction appendChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n parentInstance.children.push(child);\n}\n\n/**\n * This method should mutate the `parentInstance` and place the `child` before `beforeChild` in the list\n * of its children. For example, in the DOM this would translate to a\n * `parentInstance.insertBefore(child, beforeChild)` call.\n *\n * Note that React uses this method both for insertions and for reordering nodes. Similar to DOM, it is\n * expected that you can call `insertBefore` to reposition an existing child. Do not mutate any other parts\n * of the tree from it.\n */\nfunction insertBefore(\n parentInstance: Container | Instance,\n child: Instance | TextInstance,\n beforeChild: Instance | TextInstance,\n): void {\n const index = parentInstance.children.indexOf(child);\n if (index !== -1) {\n parentInstance.children.splice(index, 1);\n }\n\n child.parent = parentInstance;\n const beforeIndex = parentInstance.children.indexOf(beforeChild);\n parentInstance.children.splice(beforeIndex, 0, child);\n}\n\n/**\n * This method should mutate the `parentInstance` to remove the `child` from the list of its children.\n *\n * React will only call it for the top-level node that is being removed. It is expected that garbage\n * collection would take care of the whole subtree. You are not expected to traverse the child tree in it.\n */\nfunction removeChild(parentInstance: Container | Instance, child: Instance | TextInstance): void {\n const index = parentInstance.children.indexOf(child);\n parentInstance.children.splice(index, 1);\n child.parent = null;\n}\n","export function formatComponentList(names: string[]): string {\n if (names.length === 0) {\n return \"\";\n }\n\n if (names.length === 1) {\n return `<${names[0]}>`;\n }\n\n if (names.length === 2) {\n return `<${names[0]}> or <${names[1]}>`;\n }\n\n const allButLast = names.slice(0, -1);\n const last = names[names.length - 1];\n\n return `${allButLast.map((name) => `<${name}>`).join(\", \")}, or <${last}>`;\n}\n"],"mappings":"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","names":["options"]}
|
package/package.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-test-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/mdjastrzebski/universal-test-renderer.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/mdjastrzebski/universal-test-renderer",
|
|
8
13
|
"type": "module",
|
|
9
14
|
"main": "./dist/index.cjs",
|
|
10
15
|
"module": "./dist/index.js",
|
|
@@ -27,7 +32,9 @@
|
|
|
27
32
|
"lint": "eslint .",
|
|
28
33
|
"typecheck": "tsc --noEmit",
|
|
29
34
|
"test:watch": "jest --watch",
|
|
30
|
-
"validate": "
|
|
35
|
+
"validate": "bun run prettier && bun run lint && bun run typecheck && bun run test",
|
|
36
|
+
"prettier": "prettier --check .",
|
|
37
|
+
"prettier:write": "prettier --write .",
|
|
31
38
|
"release": "release-it"
|
|
32
39
|
},
|
|
33
40
|
"dependencies": {
|
|
@@ -38,14 +45,14 @@
|
|
|
38
45
|
},
|
|
39
46
|
"devDependencies": {
|
|
40
47
|
"@eslint/js": "^9.21.0",
|
|
41
|
-
"@jest/globals": "^
|
|
48
|
+
"@jest/globals": "^30.2.0",
|
|
42
49
|
"@release-it/conventional-changelog": "^10.0.0",
|
|
43
|
-
"@types/jest": "^
|
|
50
|
+
"@types/jest": "^30.0.0",
|
|
44
51
|
"@types/react": "^19.0.10",
|
|
45
52
|
"@types/react-reconciler": "^0.28.9",
|
|
46
53
|
"eslint": "^9.21.0",
|
|
47
54
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
48
|
-
"jest": "^
|
|
55
|
+
"jest": "^30.2.0",
|
|
49
56
|
"prettier": "^3.5.2",
|
|
50
57
|
"react": "^19.0.0",
|
|
51
58
|
"release-it": "^18.1.2",
|
|
@@ -53,6 +60,5 @@
|
|
|
53
60
|
"tsup": "^8.4.0",
|
|
54
61
|
"typescript": "~5.7.3",
|
|
55
62
|
"typescript-eslint": "^8.25.0"
|
|
56
|
-
}
|
|
57
|
-
"packageManager": "pnpm@10.5.2+sha512.da9dc28cd3ff40d0592188235ab25d3202add8a207afbedc682220e4a0029ffbff4562102b9e6e46b4e3f9e8bd53e6d05de48544b0c57d4b0179e22c76d1199b"
|
|
63
|
+
}
|
|
58
64
|
}
|