universal-test-renderer 0.1.2 → 0.3.0-react19.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/dist/index.cjs +105 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +106 -28
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
package/dist/index.cjs
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __defProps = Object.defineProperties;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
7
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
8
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
9
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
10
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
11
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
12
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
|
+
var __spreadValues = (a, b) => {
|
|
14
|
+
for (var prop in b || (b = {}))
|
|
15
|
+
if (__hasOwnProp.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
if (__getOwnPropSymbols)
|
|
18
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
19
|
+
if (__propIsEnum.call(b, prop))
|
|
20
|
+
__defNormalProp(a, prop, b[prop]);
|
|
21
|
+
}
|
|
22
|
+
return a;
|
|
23
|
+
};
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
10
25
|
var __objRest = (source, exclude) => {
|
|
11
26
|
var target = {};
|
|
12
27
|
for (var prop in source)
|
|
@@ -70,8 +85,10 @@ function formatComponentList(names) {
|
|
|
70
85
|
}
|
|
71
86
|
|
|
72
87
|
// src/reconciler.ts
|
|
88
|
+
var NoEventPriority = 0;
|
|
73
89
|
var UPDATE_SIGNAL = {};
|
|
74
90
|
var nodeToInstanceMap = /* @__PURE__ */ new WeakMap();
|
|
91
|
+
var currentUpdatePriority = NoEventPriority;
|
|
75
92
|
var hostConfig = {
|
|
76
93
|
/**
|
|
77
94
|
* The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.
|
|
@@ -219,8 +236,12 @@ var hostConfig = {
|
|
|
219
236
|
* If you don't intend to use host context, you can return `null`.
|
|
220
237
|
* This method happens **in the render phase**. Do not mutate the tree from it.
|
|
221
238
|
*/
|
|
222
|
-
getRootHostContext(
|
|
223
|
-
return {
|
|
239
|
+
getRootHostContext(rootContainer) {
|
|
240
|
+
return {
|
|
241
|
+
type: "ROOT",
|
|
242
|
+
isInsideText: false,
|
|
243
|
+
textComponents: rootContainer.textComponents
|
|
244
|
+
};
|
|
224
245
|
},
|
|
225
246
|
/**
|
|
226
247
|
* Host context lets you track some information about where you are in the tree so that it's available
|
|
@@ -236,10 +257,12 @@ var hostConfig = {
|
|
|
236
257
|
*
|
|
237
258
|
* This method happens **in the render phase**. Do not mutate the tree from it.
|
|
238
259
|
*/
|
|
239
|
-
getChildHostContext(parentHostContext, type
|
|
260
|
+
getChildHostContext(parentHostContext, type) {
|
|
240
261
|
var _a;
|
|
241
|
-
const isInsideText = Boolean(
|
|
242
|
-
|
|
262
|
+
const isInsideText = Boolean(
|
|
263
|
+
(_a = parentHostContext.textComponents) == null ? void 0 : _a.includes(type)
|
|
264
|
+
);
|
|
265
|
+
return __spreadProps(__spreadValues({}, parentHostContext), { type, isInsideText });
|
|
243
266
|
},
|
|
244
267
|
/**
|
|
245
268
|
* Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But
|
|
@@ -354,9 +377,10 @@ var hostConfig = {
|
|
|
354
377
|
*
|
|
355
378
|
* You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.
|
|
356
379
|
*/
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
380
|
+
// Removed in React 19
|
|
381
|
+
// getCurrentEventPriority() {
|
|
382
|
+
// return DefaultEventPriority;
|
|
383
|
+
// },
|
|
360
384
|
getInstanceFromNode(node) {
|
|
361
385
|
const instance = nodeToInstanceMap.get(node);
|
|
362
386
|
if (instance !== void 0) {
|
|
@@ -514,7 +538,53 @@ var hostConfig = {
|
|
|
514
538
|
// the "Hydration" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js).
|
|
515
539
|
// File an issue if you need help.
|
|
516
540
|
// -------------------
|
|
517
|
-
supportsHydration: false
|
|
541
|
+
supportsHydration: false,
|
|
542
|
+
// React 19
|
|
543
|
+
// @ts-expect-error missing types
|
|
544
|
+
setCurrentUpdatePriority(newPriority) {
|
|
545
|
+
currentUpdatePriority = newPriority;
|
|
546
|
+
},
|
|
547
|
+
getCurrentUpdatePriority() {
|
|
548
|
+
return currentUpdatePriority;
|
|
549
|
+
},
|
|
550
|
+
resolveUpdatePriority() {
|
|
551
|
+
return currentUpdatePriority || import_constants.DefaultEventPriority;
|
|
552
|
+
},
|
|
553
|
+
shouldAttemptEagerTransition() {
|
|
554
|
+
return false;
|
|
555
|
+
},
|
|
556
|
+
// #### `maySuspendCommit(type, props)`
|
|
557
|
+
// This method is called during render to determine if the Host Component type and props require
|
|
558
|
+
// some kind of loading process to complete before committing an update.
|
|
559
|
+
maySuspendCommit() {
|
|
560
|
+
return false;
|
|
561
|
+
},
|
|
562
|
+
// #### `preloadInstance(type, props)`
|
|
563
|
+
// This method may be called during render if the Host Component type and props might suspend a commit.
|
|
564
|
+
// It can be used to initiate any work that might shorten the duration of a suspended commit.
|
|
565
|
+
preloadInstance() {
|
|
566
|
+
return true;
|
|
567
|
+
},
|
|
568
|
+
// #### `startSuspendingCommit()`
|
|
569
|
+
// This method is called just before the commit phase. Use it to set up any necessary state while any Host
|
|
570
|
+
// Components that might suspend this commit are evaluated to determine if the commit must be suspended.
|
|
571
|
+
startSuspendingCommit() {
|
|
572
|
+
},
|
|
573
|
+
// #### `suspendInstance(type, props)`
|
|
574
|
+
// This method is called after `startSuspendingCommit` for each Host Component that indicated it might
|
|
575
|
+
// suspend a commit.
|
|
576
|
+
suspendInstance() {
|
|
577
|
+
},
|
|
578
|
+
// #### `waitForCommitToBeReady()`
|
|
579
|
+
// This method is called after all `suspendInstance` calls are complete.
|
|
580
|
+
waitForCommitToBeReady() {
|
|
581
|
+
return null;
|
|
582
|
+
},
|
|
583
|
+
NotPendingTransition: null,
|
|
584
|
+
resetFormInstance() {
|
|
585
|
+
},
|
|
586
|
+
requestPostPaintCallback() {
|
|
587
|
+
}
|
|
518
588
|
};
|
|
519
589
|
var TestReconciler = (0, import_react_reconciler.default)(hostConfig);
|
|
520
590
|
function appendChild(parentInstance, child) {
|
|
@@ -605,9 +675,9 @@ function renderToJson(instance) {
|
|
|
605
675
|
}
|
|
606
676
|
}
|
|
607
677
|
|
|
608
|
-
// src/host-
|
|
609
|
-
var
|
|
610
|
-
var
|
|
678
|
+
// src/host-element.ts
|
|
679
|
+
var instanceToHostElementMap = /* @__PURE__ */ new WeakMap();
|
|
680
|
+
var HostElement = class _HostElement {
|
|
611
681
|
constructor(instance) {
|
|
612
682
|
this.instance = instance;
|
|
613
683
|
}
|
|
@@ -622,7 +692,7 @@ var HostComponent = class _HostComponent {
|
|
|
622
692
|
return restProps;
|
|
623
693
|
}
|
|
624
694
|
get children() {
|
|
625
|
-
const result = this.instance.children.filter((child) => !child.isHidden).map((child) =>
|
|
695
|
+
const result = this.instance.children.filter((child) => !child.isHidden).map((child) => _HostElement.fromInstance(child));
|
|
626
696
|
return result;
|
|
627
697
|
}
|
|
628
698
|
get parent() {
|
|
@@ -632,9 +702,9 @@ var HostComponent = class _HostComponent {
|
|
|
632
702
|
}
|
|
633
703
|
switch (parentInstance.tag) {
|
|
634
704
|
case "INSTANCE":
|
|
635
|
-
return
|
|
705
|
+
return _HostElement.fromInstance(parentInstance);
|
|
636
706
|
case "CONTAINER":
|
|
637
|
-
return
|
|
707
|
+
return _HostElement.fromContainer(parentInstance);
|
|
638
708
|
}
|
|
639
709
|
}
|
|
640
710
|
get $$typeof() {
|
|
@@ -645,12 +715,12 @@ var HostComponent = class _HostComponent {
|
|
|
645
715
|
}
|
|
646
716
|
/** @internal */
|
|
647
717
|
static fromContainer(container) {
|
|
648
|
-
const
|
|
649
|
-
if (
|
|
650
|
-
return
|
|
718
|
+
const hostElement = instanceToHostElementMap.get(container);
|
|
719
|
+
if (hostElement) {
|
|
720
|
+
return hostElement;
|
|
651
721
|
}
|
|
652
|
-
const result = new
|
|
653
|
-
|
|
722
|
+
const result = new _HostElement(container);
|
|
723
|
+
instanceToHostElementMap.set(container, result);
|
|
654
724
|
return result;
|
|
655
725
|
}
|
|
656
726
|
/** @internal */
|
|
@@ -659,12 +729,12 @@ var HostComponent = class _HostComponent {
|
|
|
659
729
|
case "TEXT":
|
|
660
730
|
return instance.text;
|
|
661
731
|
case "INSTANCE": {
|
|
662
|
-
const
|
|
663
|
-
if (
|
|
664
|
-
return
|
|
732
|
+
const hostElement = instanceToHostElementMap.get(instance);
|
|
733
|
+
if (hostElement) {
|
|
734
|
+
return hostElement;
|
|
665
735
|
}
|
|
666
|
-
const result = new
|
|
667
|
-
|
|
736
|
+
const result = new _HostElement(instance);
|
|
737
|
+
instanceToHostElementMap.set(instance, result);
|
|
668
738
|
return result;
|
|
669
739
|
}
|
|
670
740
|
}
|
|
@@ -686,7 +756,7 @@ function createRenderer(options) {
|
|
|
686
756
|
container,
|
|
687
757
|
(options == null ? void 0 : options.isConcurrent) ? import_constants4.ConcurrentRoot : import_constants4.LegacyRoot,
|
|
688
758
|
null,
|
|
689
|
-
//
|
|
759
|
+
// hydration callbacks
|
|
690
760
|
false,
|
|
691
761
|
// isStrictMode
|
|
692
762
|
null,
|
|
@@ -695,6 +765,13 @@ function createRenderer(options) {
|
|
|
695
765
|
// identifierPrefix
|
|
696
766
|
() => {
|
|
697
767
|
},
|
|
768
|
+
// onUncaughtError
|
|
769
|
+
() => {
|
|
770
|
+
},
|
|
771
|
+
// onCaughtError
|
|
772
|
+
// @ts-expect-error missing types
|
|
773
|
+
() => {
|
|
774
|
+
},
|
|
698
775
|
// onRecoverableError
|
|
699
776
|
null
|
|
700
777
|
// transitionCallbacks
|
|
@@ -720,7 +797,7 @@ function createRenderer(options) {
|
|
|
720
797
|
if (container.children.length === 0) {
|
|
721
798
|
return null;
|
|
722
799
|
}
|
|
723
|
-
const root =
|
|
800
|
+
const root = HostElement.fromInstance(container.children[0]);
|
|
724
801
|
if (typeof root === "string") {
|
|
725
802
|
throw new Error("Cannot render string as root element");
|
|
726
803
|
}
|
|
@@ -730,7 +807,7 @@ function createRenderer(options) {
|
|
|
730
807
|
if (containerFiber == null || container == null) {
|
|
731
808
|
throw new Error("Can't access .container on unmounted test renderer");
|
|
732
809
|
}
|
|
733
|
-
return
|
|
810
|
+
return HostElement.fromContainer(container);
|
|
734
811
|
}
|
|
735
812
|
};
|
|
736
813
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/reconciler.ts","../src/utils.ts","../src/constants.ts","../src/render-to-json.ts","../src/host-component.ts","../src/renderer.ts"],"sourcesContent":["export { createRenderer } from \"./renderer\";\nexport { CONTAINER_TYPE } from \"./constants\";\n\nexport type { Renderer, RendererOptions } from \"./renderer\";\nexport type { HostComponent, HostNode, Props } from \"./host-component\";\nexport type { JsonNode, JsonElement } from \"./render-to-json\";\n","import { ReactElement } from \"react\";\nimport ReactReconciler, { Fiber } from \"react-reconciler\";\nimport { DefaultEventPriority } from \"react-reconciler/constants\";\nimport { formatComponentList } from \"./utils\";\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\nexport type OpaqueHandle = Fiber;\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n\n // Access to key options passed to createRenderer\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\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};\n\nconst UPDATE_SIGNAL = {};\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\n// if (__DEV__) {\n// Object.freeze(UPDATE_SIGNAL);\n// }\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 * 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 * 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.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.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 appendInitialChild: appendChild,\n\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 * React calls this method so that you can compare the previous and the next props, and decide whether you\n * need to update the underlying instance or not. If you don't need to update it, return `null`. If you\n * need to update it, you can return an arbitrary object representing the changes that need to happen.\n * Then in `commitUpdate` you would need to apply those changes to the instance.\n *\n * This method happens **in the render phase**. It should only *calculate* the update — but not apply it!\n * For example, the DOM renderer returns an array that looks like `[prop1, value1, prop2, value2, ...]`\n * for all props that have actually changed. And only in `commitUpdate` it applies those changes. You should\n * calculate as much as you can in `prepareUpdate` so that `commitUpdate` can be very fast and straightforward.\n *\n * See the meaning of `rootContainer` and `hostContext` in the `createInstance` documentation.\n */\n prepareUpdate(\n _instance: Instance,\n _type: Type,\n _oldProps: Props,\n _newProps: Props,\n _rootContainer: Container,\n _hostContext: HostContext\n ) {\n return UPDATE_SIGNAL;\n },\n\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 /**\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 { type: \"ROOT\", isInsideText: false };\n },\n\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(\n parentHostContext: HostContext,\n type: Type,\n rootContainer: Container\n ): HostContext {\n const isInsideText = Boolean(rootContainer.textComponents?.includes(type));\n return { type: type, isInsideText };\n },\n\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.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 * 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 * 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 * 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 * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n cancelTimeout: clearTimeout,\n\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 * 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 * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\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 /**\n * To implement this method, you'll need some constants available on the special `react-reconciler/constants` entry point:\n *\n * ```\n * import {\n * DiscreteEventPriority,\n * ContinuousEventPriority,\n * DefaultEventPriority,\n * } from 'react-reconciler/constants';\n *\n * const HostConfig = {\n * // ...\n * getCurrentEventPriority() {\n * return DefaultEventPriority;\n * },\n * // ...\n * }\n *\n * const MyRenderer = Reconciler(HostConfig);\n * ```\n *\n * The constant you return depends on which event, if any, is being handled right now. (In the browser, you can\n * check this using `window.event && window.event.type`).\n *\n * - **Discrete events**: If the active event is directly caused by the user (such as mouse and keyboard events)\n * and each event in a sequence is intentional (e.g. click), return DiscreteEventPriority. This tells React that\n * they should interrupt any background work and cannot be batched across time.\n *\n * - **Continuous events**: If the active event is directly caused by the user but the user can't distinguish between\n * individual events in a sequence (e.g. mouseover), return ContinuousEventPriority. This tells React they\n * should interrupt any background work but can be batched across time.\n *\n * - **Other events / No active event**: In all other cases, return DefaultEventPriority. This tells React that\n * this event is considered background work, and interactive events will be prioritized over it.\n *\n * You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.\n */\n getCurrentEventPriority() {\n return DefaultEventPriority;\n },\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 // noop\n },\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, look at `commitMount`.\n */\n appendChild: appendChild,\n\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 * 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 * 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 * 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 * 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 * 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 * 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(\n textInstance: TextInstance,\n _oldText: string,\n newText: string\n ): void {\n textInstance.text = newText;\n },\n\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 * 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 commitUpdate(\n instance: Instance,\n _updatePayload: UpdatePayload,\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 * 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 * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\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 * 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 * 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 // 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\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(\n parentInstance: Container | Instance,\n child: 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 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(\n parentInstance: Container | Instance,\n child: Instance | TextInstance\n): 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","export const CONTAINER_TYPE = \"CONTAINER\";\n","import { CONTAINER_TYPE } from \"./constants\";\nimport { 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(\n instance: Container | Instance | TextInstance\n): 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(\n children: Array<Instance | TextInstance> | null\n) {\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 { Container, Instance, TextInstance } from \"./reconciler\";\nimport { JsonNode, renderToJson } from \"./render-to-json\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Props = Record<string, any>;\n\nexport type HostNode = HostComponent | string;\n\nconst instanceToHostComponentInstanceMap = new WeakMap<\n Container | Instance,\n HostComponent\n>();\n\nexport class HostComponent {\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\"\n ? this.instance.type\n : CONTAINER_TYPE;\n }\n\n get props(): Props {\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) => HostComponent.fromInstance(child));\n return result;\n }\n\n get parent(): HostComponent | 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 HostComponent.fromInstance(parentInstance) as HostComponent;\n\n case \"CONTAINER\":\n return HostComponent.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): HostComponent {\n const hostComponentInstance =\n instanceToHostComponentInstanceMap.get(container);\n if (hostComponentInstance) {\n return hostComponentInstance;\n }\n\n const result = new HostComponent(container);\n instanceToHostComponentInstanceMap.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 hostComponentInstance =\n instanceToHostComponentInstanceMap.get(instance);\n if (hostComponentInstance) {\n return hostComponentInstance;\n }\n\n const result = new HostComponent(instance);\n instanceToHostComponentInstanceMap.set(instance, result);\n return result;\n }\n }\n }\n}\n","import { ReactElement } from \"react\";\nimport { Container, TestReconciler } from \"./reconciler\";\nimport { HostComponent } from \"./host-component\";\nimport { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot, LegacyRoot } from \"react-reconciler/constants\";\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 RendererOptions = {\n textComponents?: string[];\n isConcurrent?: boolean;\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Renderer = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n container: HostComponent;\n root: HostComponent | null;\n};\n\nexport function createRenderer(options?: RendererOptions): Renderer {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n options?.isConcurrent ? ConcurrentRoot : LegacyRoot,\n null, // no hydration callback\n false, // isStrictMode\n null, // concurrentUpdatesByDefaultOverride\n \"id\", // identifierPrefix\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(): HostComponent | 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 = HostComponent.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(): HostComponent {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .container on unmounted test renderer\");\n }\n\n return HostComponent.fromContainer(container);\n },\n };\n}\n"],"mappings":"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","names":["ReactReconciler","import_constants"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/reconciler.ts","../src/utils.ts","../src/constants.ts","../src/render-to-json.ts","../src/host-element.ts","../src/renderer.ts"],"sourcesContent":["export { createRenderer } from \"./renderer\";\nexport { CONTAINER_TYPE } from \"./constants\";\n\nexport type { Renderer, RendererOptions } from \"./renderer\";\nexport type { HostElement, HostElementProps, HostNode } from \"./host-element\";\nexport type { JsonElement, JsonNode } from \"./render-to-json\";\n","import { ReactElement } from \"react\";\nimport ReactReconciler, { Fiber } from \"react-reconciler\";\nimport { DefaultEventPriority } from \"react-reconciler/constants\";\nimport { formatComponentList } from \"./utils\";\n\n// Taken from NoEventPriority in react-reconciler/constants.js\nconst NoEventPriority: number = 0;\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\nexport type OpaqueHandle = Fiber;\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n\n // Access to key options passed to createRenderer\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\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 textComponents?: string[];\n};\n\nconst UPDATE_SIGNAL = {};\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\nlet currentUpdatePriority: number = NoEventPriority;\n\n// if (__DEV__) {\n// Object.freeze(UPDATE_SIGNAL);\n// }\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 * 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 * 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.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.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 appendInitialChild: appendChild,\n\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 * React calls this method so that you can compare the previous and the next props, and decide whether you\n * need to update the underlying instance or not. If you don't need to update it, return `null`. If you\n * need to update it, you can return an arbitrary object representing the changes that need to happen.\n * Then in `commitUpdate` you would need to apply those changes to the instance.\n *\n * This method happens **in the render phase**. It should only *calculate* the update — but not apply it!\n * For example, the DOM renderer returns an array that looks like `[prop1, value1, prop2, value2, ...]`\n * for all props that have actually changed. And only in `commitUpdate` it applies those changes. You should\n * calculate as much as you can in `prepareUpdate` so that `commitUpdate` can be very fast and straightforward.\n *\n * See the meaning of `rootContainer` and `hostContext` in the `createInstance` documentation.\n */\n prepareUpdate(\n _instance: Instance,\n _type: Type,\n _oldProps: Props,\n _newProps: Props,\n _rootContainer: Container,\n _hostContext: HostContext\n ) {\n return UPDATE_SIGNAL;\n },\n\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 /**\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 isInsideText: false,\n textComponents: rootContainer.textComponents,\n };\n },\n\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(\n parentHostContext.textComponents?.includes(type)\n );\n return { ...parentHostContext, type: type, isInsideText };\n },\n\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.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 * 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 * 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 * 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 * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n cancelTimeout: clearTimeout,\n\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 * 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 * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\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 /**\n * To implement this method, you'll need some constants available on the special `react-reconciler/constants` entry point:\n *\n * ```\n * import {\n * DiscreteEventPriority,\n * ContinuousEventPriority,\n * DefaultEventPriority,\n * } from 'react-reconciler/constants';\n *\n * const HostConfig = {\n * // ...\n * getCurrentEventPriority() {\n * return DefaultEventPriority;\n * },\n * // ...\n * }\n *\n * const MyRenderer = Reconciler(HostConfig);\n * ```\n *\n * The constant you return depends on which event, if any, is being handled right now. (In the browser, you can\n * check this using `window.event && window.event.type`).\n *\n * - **Discrete events**: If the active event is directly caused by the user (such as mouse and keyboard events)\n * and each event in a sequence is intentional (e.g. click), return DiscreteEventPriority. This tells React that\n * they should interrupt any background work and cannot be batched across time.\n *\n * - **Continuous events**: If the active event is directly caused by the user but the user can't distinguish between\n * individual events in a sequence (e.g. mouseover), return ContinuousEventPriority. This tells React they\n * should interrupt any background work but can be batched across time.\n *\n * - **Other events / No active event**: In all other cases, return DefaultEventPriority. This tells React that\n * this event is considered background work, and interactive events will be prioritized over it.\n *\n * You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.\n */\n // Removed in React 19\n // getCurrentEventPriority() {\n // return DefaultEventPriority;\n // },\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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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(\n textInstance: TextInstance,\n _oldText: string,\n newText: string\n ): void {\n textInstance.text = newText;\n },\n\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 * 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 commitUpdate(\n instance: Instance,\n _updatePayload: UpdatePayload,\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 * 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 * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\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 * 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 * 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 // 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 // React 19\n // @ts-expect-error missing types\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 // #### `maySuspendCommit(type, props)`\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 maySuspendCommit(): boolean {\n return false;\n },\n\n // #### `preloadInstance(type, props)`\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 preloadInstance() {\n return true;\n },\n\n // #### `startSuspendingCommit()`\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 startSuspendingCommit() {},\n\n // #### `suspendInstance(type, props)`\n // This method is called after `startSuspendingCommit` for each Host Component that indicated it might\n // suspend a commit.\n suspendInstance() {},\n\n // #### `waitForCommitToBeReady()`\n // This method is called after all `suspendInstance` calls are complete.\n waitForCommitToBeReady() {\n return null;\n },\n\n NotPendingTransition: null,\n\n resetFormInstance() {},\n\n requestPostPaintCallback() {},\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(\n parentInstance: Container | Instance,\n child: 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 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(\n parentInstance: Container | Instance,\n child: Instance | TextInstance\n): 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","export const CONTAINER_TYPE = \"CONTAINER\";\n","import { CONTAINER_TYPE } from \"./constants\";\nimport { 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(\n instance: Container | Instance | TextInstance\n): 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(\n children: Array<Instance | TextInstance> | null\n) {\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 { Container, Instance, TextInstance } from \"./reconciler\";\nimport { JsonNode, 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<\n Container | Instance,\n HostElement\n>();\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\"\n ? this.instance.type\n : 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 { ReactElement } from \"react\";\nimport { Container, TestReconciler } from \"./reconciler\";\nimport { HostElement } from \"./host-element\";\nimport { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot, LegacyRoot } from \"react-reconciler/constants\";\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 RendererOptions = {\n textComponents?: string[];\n isConcurrent?: boolean;\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Renderer = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n container: HostElement;\n root: HostElement | null;\n};\n\nexport function createRenderer(options?: RendererOptions): Renderer {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n options?.isConcurrent ? ConcurrentRoot : LegacyRoot,\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"],"mappings":"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","names":["ReactReconciler","import_constants"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -8,15 +8,15 @@ type JsonElement = {
|
|
|
8
8
|
$$typeof: symbol;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
type
|
|
12
|
-
type
|
|
13
|
-
declare class
|
|
11
|
+
type HostNode = HostElement | string;
|
|
12
|
+
type HostElementProps = Record<string, any>;
|
|
13
|
+
declare class HostElement {
|
|
14
14
|
private instance;
|
|
15
15
|
private constructor();
|
|
16
16
|
get type(): string;
|
|
17
|
-
get props():
|
|
17
|
+
get props(): HostElementProps;
|
|
18
18
|
get children(): HostNode[];
|
|
19
|
-
get parent():
|
|
19
|
+
get parent(): HostElement | null;
|
|
20
20
|
get $$typeof(): symbol;
|
|
21
21
|
toJSON(): JsonNode | null;
|
|
22
22
|
}
|
|
@@ -29,11 +29,11 @@ type RendererOptions = {
|
|
|
29
29
|
type Renderer = {
|
|
30
30
|
render: (element: ReactElement) => void;
|
|
31
31
|
unmount: () => void;
|
|
32
|
-
container:
|
|
33
|
-
root:
|
|
32
|
+
container: HostElement;
|
|
33
|
+
root: HostElement | null;
|
|
34
34
|
};
|
|
35
35
|
declare function createRenderer(options?: RendererOptions): Renderer;
|
|
36
36
|
|
|
37
37
|
declare const CONTAINER_TYPE = "CONTAINER";
|
|
38
38
|
|
|
39
|
-
export { CONTAINER_TYPE,
|
|
39
|
+
export { CONTAINER_TYPE, HostElement, type HostElementProps, type HostNode, type JsonElement, type JsonNode, type Renderer, type RendererOptions, createRenderer };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,15 +8,15 @@ type JsonElement = {
|
|
|
8
8
|
$$typeof: symbol;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
type
|
|
12
|
-
type
|
|
13
|
-
declare class
|
|
11
|
+
type HostNode = HostElement | string;
|
|
12
|
+
type HostElementProps = Record<string, any>;
|
|
13
|
+
declare class HostElement {
|
|
14
14
|
private instance;
|
|
15
15
|
private constructor();
|
|
16
16
|
get type(): string;
|
|
17
|
-
get props():
|
|
17
|
+
get props(): HostElementProps;
|
|
18
18
|
get children(): HostNode[];
|
|
19
|
-
get parent():
|
|
19
|
+
get parent(): HostElement | null;
|
|
20
20
|
get $$typeof(): symbol;
|
|
21
21
|
toJSON(): JsonNode | null;
|
|
22
22
|
}
|
|
@@ -29,11 +29,11 @@ type RendererOptions = {
|
|
|
29
29
|
type Renderer = {
|
|
30
30
|
render: (element: ReactElement) => void;
|
|
31
31
|
unmount: () => void;
|
|
32
|
-
container:
|
|
33
|
-
root:
|
|
32
|
+
container: HostElement;
|
|
33
|
+
root: HostElement | null;
|
|
34
34
|
};
|
|
35
35
|
declare function createRenderer(options?: RendererOptions): Renderer;
|
|
36
36
|
|
|
37
37
|
declare const CONTAINER_TYPE = "CONTAINER";
|
|
38
38
|
|
|
39
|
-
export { CONTAINER_TYPE,
|
|
39
|
+
export { CONTAINER_TYPE, HostElement, type HostElementProps, type HostNode, type JsonElement, type JsonNode, type Renderer, type RendererOptions, createRenderer };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
1
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
2
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
3
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
4
20
|
var __objRest = (source, exclude) => {
|
|
5
21
|
var target = {};
|
|
6
22
|
for (var prop in source)
|
|
@@ -35,8 +51,10 @@ function formatComponentList(names) {
|
|
|
35
51
|
}
|
|
36
52
|
|
|
37
53
|
// src/reconciler.ts
|
|
54
|
+
var NoEventPriority = 0;
|
|
38
55
|
var UPDATE_SIGNAL = {};
|
|
39
56
|
var nodeToInstanceMap = /* @__PURE__ */ new WeakMap();
|
|
57
|
+
var currentUpdatePriority = NoEventPriority;
|
|
40
58
|
var hostConfig = {
|
|
41
59
|
/**
|
|
42
60
|
* The reconciler has two modes: mutation mode and persistent mode. You must specify one of them.
|
|
@@ -184,8 +202,12 @@ var hostConfig = {
|
|
|
184
202
|
* If you don't intend to use host context, you can return `null`.
|
|
185
203
|
* This method happens **in the render phase**. Do not mutate the tree from it.
|
|
186
204
|
*/
|
|
187
|
-
getRootHostContext(
|
|
188
|
-
return {
|
|
205
|
+
getRootHostContext(rootContainer) {
|
|
206
|
+
return {
|
|
207
|
+
type: "ROOT",
|
|
208
|
+
isInsideText: false,
|
|
209
|
+
textComponents: rootContainer.textComponents
|
|
210
|
+
};
|
|
189
211
|
},
|
|
190
212
|
/**
|
|
191
213
|
* Host context lets you track some information about where you are in the tree so that it's available
|
|
@@ -201,10 +223,12 @@ var hostConfig = {
|
|
|
201
223
|
*
|
|
202
224
|
* This method happens **in the render phase**. Do not mutate the tree from it.
|
|
203
225
|
*/
|
|
204
|
-
getChildHostContext(parentHostContext, type
|
|
226
|
+
getChildHostContext(parentHostContext, type) {
|
|
205
227
|
var _a;
|
|
206
|
-
const isInsideText = Boolean(
|
|
207
|
-
|
|
228
|
+
const isInsideText = Boolean(
|
|
229
|
+
(_a = parentHostContext.textComponents) == null ? void 0 : _a.includes(type)
|
|
230
|
+
);
|
|
231
|
+
return __spreadProps(__spreadValues({}, parentHostContext), { type, isInsideText });
|
|
208
232
|
},
|
|
209
233
|
/**
|
|
210
234
|
* Determines what object gets exposed as a ref. You'll likely want to return the `instance` itself. But
|
|
@@ -319,9 +343,10 @@ var hostConfig = {
|
|
|
319
343
|
*
|
|
320
344
|
* You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.
|
|
321
345
|
*/
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
346
|
+
// Removed in React 19
|
|
347
|
+
// getCurrentEventPriority() {
|
|
348
|
+
// return DefaultEventPriority;
|
|
349
|
+
// },
|
|
325
350
|
getInstanceFromNode(node) {
|
|
326
351
|
const instance = nodeToInstanceMap.get(node);
|
|
327
352
|
if (instance !== void 0) {
|
|
@@ -479,7 +504,53 @@ var hostConfig = {
|
|
|
479
504
|
// the "Hydration" section [listed in this file](https://github.com/facebook/react/blob/master/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js).
|
|
480
505
|
// File an issue if you need help.
|
|
481
506
|
// -------------------
|
|
482
|
-
supportsHydration: false
|
|
507
|
+
supportsHydration: false,
|
|
508
|
+
// React 19
|
|
509
|
+
// @ts-expect-error missing types
|
|
510
|
+
setCurrentUpdatePriority(newPriority) {
|
|
511
|
+
currentUpdatePriority = newPriority;
|
|
512
|
+
},
|
|
513
|
+
getCurrentUpdatePriority() {
|
|
514
|
+
return currentUpdatePriority;
|
|
515
|
+
},
|
|
516
|
+
resolveUpdatePriority() {
|
|
517
|
+
return currentUpdatePriority || DefaultEventPriority;
|
|
518
|
+
},
|
|
519
|
+
shouldAttemptEagerTransition() {
|
|
520
|
+
return false;
|
|
521
|
+
},
|
|
522
|
+
// #### `maySuspendCommit(type, props)`
|
|
523
|
+
// This method is called during render to determine if the Host Component type and props require
|
|
524
|
+
// some kind of loading process to complete before committing an update.
|
|
525
|
+
maySuspendCommit() {
|
|
526
|
+
return false;
|
|
527
|
+
},
|
|
528
|
+
// #### `preloadInstance(type, props)`
|
|
529
|
+
// This method may be called during render if the Host Component type and props might suspend a commit.
|
|
530
|
+
// It can be used to initiate any work that might shorten the duration of a suspended commit.
|
|
531
|
+
preloadInstance() {
|
|
532
|
+
return true;
|
|
533
|
+
},
|
|
534
|
+
// #### `startSuspendingCommit()`
|
|
535
|
+
// This method is called just before the commit phase. Use it to set up any necessary state while any Host
|
|
536
|
+
// Components that might suspend this commit are evaluated to determine if the commit must be suspended.
|
|
537
|
+
startSuspendingCommit() {
|
|
538
|
+
},
|
|
539
|
+
// #### `suspendInstance(type, props)`
|
|
540
|
+
// This method is called after `startSuspendingCommit` for each Host Component that indicated it might
|
|
541
|
+
// suspend a commit.
|
|
542
|
+
suspendInstance() {
|
|
543
|
+
},
|
|
544
|
+
// #### `waitForCommitToBeReady()`
|
|
545
|
+
// This method is called after all `suspendInstance` calls are complete.
|
|
546
|
+
waitForCommitToBeReady() {
|
|
547
|
+
return null;
|
|
548
|
+
},
|
|
549
|
+
NotPendingTransition: null,
|
|
550
|
+
resetFormInstance() {
|
|
551
|
+
},
|
|
552
|
+
requestPostPaintCallback() {
|
|
553
|
+
}
|
|
483
554
|
};
|
|
484
555
|
var TestReconciler = ReactReconciler(hostConfig);
|
|
485
556
|
function appendChild(parentInstance, child) {
|
|
@@ -570,9 +641,9 @@ function renderToJson(instance) {
|
|
|
570
641
|
}
|
|
571
642
|
}
|
|
572
643
|
|
|
573
|
-
// src/host-
|
|
574
|
-
var
|
|
575
|
-
var
|
|
644
|
+
// src/host-element.ts
|
|
645
|
+
var instanceToHostElementMap = /* @__PURE__ */ new WeakMap();
|
|
646
|
+
var HostElement = class _HostElement {
|
|
576
647
|
constructor(instance) {
|
|
577
648
|
this.instance = instance;
|
|
578
649
|
}
|
|
@@ -587,7 +658,7 @@ var HostComponent = class _HostComponent {
|
|
|
587
658
|
return restProps;
|
|
588
659
|
}
|
|
589
660
|
get children() {
|
|
590
|
-
const result = this.instance.children.filter((child) => !child.isHidden).map((child) =>
|
|
661
|
+
const result = this.instance.children.filter((child) => !child.isHidden).map((child) => _HostElement.fromInstance(child));
|
|
591
662
|
return result;
|
|
592
663
|
}
|
|
593
664
|
get parent() {
|
|
@@ -597,9 +668,9 @@ var HostComponent = class _HostComponent {
|
|
|
597
668
|
}
|
|
598
669
|
switch (parentInstance.tag) {
|
|
599
670
|
case "INSTANCE":
|
|
600
|
-
return
|
|
671
|
+
return _HostElement.fromInstance(parentInstance);
|
|
601
672
|
case "CONTAINER":
|
|
602
|
-
return
|
|
673
|
+
return _HostElement.fromContainer(parentInstance);
|
|
603
674
|
}
|
|
604
675
|
}
|
|
605
676
|
get $$typeof() {
|
|
@@ -610,12 +681,12 @@ var HostComponent = class _HostComponent {
|
|
|
610
681
|
}
|
|
611
682
|
/** @internal */
|
|
612
683
|
static fromContainer(container) {
|
|
613
|
-
const
|
|
614
|
-
if (
|
|
615
|
-
return
|
|
684
|
+
const hostElement = instanceToHostElementMap.get(container);
|
|
685
|
+
if (hostElement) {
|
|
686
|
+
return hostElement;
|
|
616
687
|
}
|
|
617
|
-
const result = new
|
|
618
|
-
|
|
688
|
+
const result = new _HostElement(container);
|
|
689
|
+
instanceToHostElementMap.set(container, result);
|
|
619
690
|
return result;
|
|
620
691
|
}
|
|
621
692
|
/** @internal */
|
|
@@ -624,12 +695,12 @@ var HostComponent = class _HostComponent {
|
|
|
624
695
|
case "TEXT":
|
|
625
696
|
return instance.text;
|
|
626
697
|
case "INSTANCE": {
|
|
627
|
-
const
|
|
628
|
-
if (
|
|
629
|
-
return
|
|
698
|
+
const hostElement = instanceToHostElementMap.get(instance);
|
|
699
|
+
if (hostElement) {
|
|
700
|
+
return hostElement;
|
|
630
701
|
}
|
|
631
|
-
const result = new
|
|
632
|
-
|
|
702
|
+
const result = new _HostElement(instance);
|
|
703
|
+
instanceToHostElementMap.set(instance, result);
|
|
633
704
|
return result;
|
|
634
705
|
}
|
|
635
706
|
}
|
|
@@ -651,7 +722,7 @@ function createRenderer(options) {
|
|
|
651
722
|
container,
|
|
652
723
|
(options == null ? void 0 : options.isConcurrent) ? ConcurrentRoot : LegacyRoot,
|
|
653
724
|
null,
|
|
654
|
-
//
|
|
725
|
+
// hydration callbacks
|
|
655
726
|
false,
|
|
656
727
|
// isStrictMode
|
|
657
728
|
null,
|
|
@@ -660,6 +731,13 @@ function createRenderer(options) {
|
|
|
660
731
|
// identifierPrefix
|
|
661
732
|
() => {
|
|
662
733
|
},
|
|
734
|
+
// onUncaughtError
|
|
735
|
+
() => {
|
|
736
|
+
},
|
|
737
|
+
// onCaughtError
|
|
738
|
+
// @ts-expect-error missing types
|
|
739
|
+
() => {
|
|
740
|
+
},
|
|
663
741
|
// onRecoverableError
|
|
664
742
|
null
|
|
665
743
|
// transitionCallbacks
|
|
@@ -685,7 +763,7 @@ function createRenderer(options) {
|
|
|
685
763
|
if (container.children.length === 0) {
|
|
686
764
|
return null;
|
|
687
765
|
}
|
|
688
|
-
const root =
|
|
766
|
+
const root = HostElement.fromInstance(container.children[0]);
|
|
689
767
|
if (typeof root === "string") {
|
|
690
768
|
throw new Error("Cannot render string as root element");
|
|
691
769
|
}
|
|
@@ -695,7 +773,7 @@ function createRenderer(options) {
|
|
|
695
773
|
if (containerFiber == null || container == null) {
|
|
696
774
|
throw new Error("Can't access .container on unmounted test renderer");
|
|
697
775
|
}
|
|
698
|
-
return
|
|
776
|
+
return HostElement.fromContainer(container);
|
|
699
777
|
}
|
|
700
778
|
};
|
|
701
779
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/reconciler.ts","../src/utils.ts","../src/constants.ts","../src/render-to-json.ts","../src/host-component.ts","../src/renderer.ts"],"sourcesContent":["import { ReactElement } from \"react\";\nimport ReactReconciler, { Fiber } from \"react-reconciler\";\nimport { DefaultEventPriority } from \"react-reconciler/constants\";\nimport { formatComponentList } from \"./utils\";\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\nexport type OpaqueHandle = Fiber;\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n\n // Access to key options passed to createRenderer\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\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};\n\nconst UPDATE_SIGNAL = {};\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\n// if (__DEV__) {\n// Object.freeze(UPDATE_SIGNAL);\n// }\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 * 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 * 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.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.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 appendInitialChild: appendChild,\n\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 * React calls this method so that you can compare the previous and the next props, and decide whether you\n * need to update the underlying instance or not. If you don't need to update it, return `null`. If you\n * need to update it, you can return an arbitrary object representing the changes that need to happen.\n * Then in `commitUpdate` you would need to apply those changes to the instance.\n *\n * This method happens **in the render phase**. It should only *calculate* the update — but not apply it!\n * For example, the DOM renderer returns an array that looks like `[prop1, value1, prop2, value2, ...]`\n * for all props that have actually changed. And only in `commitUpdate` it applies those changes. You should\n * calculate as much as you can in `prepareUpdate` so that `commitUpdate` can be very fast and straightforward.\n *\n * See the meaning of `rootContainer` and `hostContext` in the `createInstance` documentation.\n */\n prepareUpdate(\n _instance: Instance,\n _type: Type,\n _oldProps: Props,\n _newProps: Props,\n _rootContainer: Container,\n _hostContext: HostContext\n ) {\n return UPDATE_SIGNAL;\n },\n\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 /**\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 { type: \"ROOT\", isInsideText: false };\n },\n\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(\n parentHostContext: HostContext,\n type: Type,\n rootContainer: Container\n ): HostContext {\n const isInsideText = Boolean(rootContainer.textComponents?.includes(type));\n return { type: type, isInsideText };\n },\n\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.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 * 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 * 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 * 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 * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n cancelTimeout: clearTimeout,\n\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 * 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 * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\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 /**\n * To implement this method, you'll need some constants available on the special `react-reconciler/constants` entry point:\n *\n * ```\n * import {\n * DiscreteEventPriority,\n * ContinuousEventPriority,\n * DefaultEventPriority,\n * } from 'react-reconciler/constants';\n *\n * const HostConfig = {\n * // ...\n * getCurrentEventPriority() {\n * return DefaultEventPriority;\n * },\n * // ...\n * }\n *\n * const MyRenderer = Reconciler(HostConfig);\n * ```\n *\n * The constant you return depends on which event, if any, is being handled right now. (In the browser, you can\n * check this using `window.event && window.event.type`).\n *\n * - **Discrete events**: If the active event is directly caused by the user (such as mouse and keyboard events)\n * and each event in a sequence is intentional (e.g. click), return DiscreteEventPriority. This tells React that\n * they should interrupt any background work and cannot be batched across time.\n *\n * - **Continuous events**: If the active event is directly caused by the user but the user can't distinguish between\n * individual events in a sequence (e.g. mouseover), return ContinuousEventPriority. This tells React they\n * should interrupt any background work but can be batched across time.\n *\n * - **Other events / No active event**: In all other cases, return DefaultEventPriority. This tells React that\n * this event is considered background work, and interactive events will be prioritized over it.\n *\n * You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.\n */\n getCurrentEventPriority() {\n return DefaultEventPriority;\n },\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 // noop\n },\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, look at `commitMount`.\n */\n appendChild: appendChild,\n\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 * 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 * 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 * 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 * 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 * 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 * 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(\n textInstance: TextInstance,\n _oldText: string,\n newText: string\n ): void {\n textInstance.text = newText;\n },\n\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 * 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 commitUpdate(\n instance: Instance,\n _updatePayload: UpdatePayload,\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 * 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 * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\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 * 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 * 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 // 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\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(\n parentInstance: Container | Instance,\n child: 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 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(\n parentInstance: Container | Instance,\n child: Instance | TextInstance\n): 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","export const CONTAINER_TYPE = \"CONTAINER\";\n","import { CONTAINER_TYPE } from \"./constants\";\nimport { 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(\n instance: Container | Instance | TextInstance\n): 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(\n children: Array<Instance | TextInstance> | null\n) {\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 { Container, Instance, TextInstance } from \"./reconciler\";\nimport { JsonNode, renderToJson } from \"./render-to-json\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Props = Record<string, any>;\n\nexport type HostNode = HostComponent | string;\n\nconst instanceToHostComponentInstanceMap = new WeakMap<\n Container | Instance,\n HostComponent\n>();\n\nexport class HostComponent {\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\"\n ? this.instance.type\n : CONTAINER_TYPE;\n }\n\n get props(): Props {\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) => HostComponent.fromInstance(child));\n return result;\n }\n\n get parent(): HostComponent | 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 HostComponent.fromInstance(parentInstance) as HostComponent;\n\n case \"CONTAINER\":\n return HostComponent.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): HostComponent {\n const hostComponentInstance =\n instanceToHostComponentInstanceMap.get(container);\n if (hostComponentInstance) {\n return hostComponentInstance;\n }\n\n const result = new HostComponent(container);\n instanceToHostComponentInstanceMap.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 hostComponentInstance =\n instanceToHostComponentInstanceMap.get(instance);\n if (hostComponentInstance) {\n return hostComponentInstance;\n }\n\n const result = new HostComponent(instance);\n instanceToHostComponentInstanceMap.set(instance, result);\n return result;\n }\n }\n }\n}\n","import { ReactElement } from \"react\";\nimport { Container, TestReconciler } from \"./reconciler\";\nimport { HostComponent } from \"./host-component\";\nimport { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot, LegacyRoot } from \"react-reconciler/constants\";\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 RendererOptions = {\n textComponents?: string[];\n isConcurrent?: boolean;\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Renderer = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n container: HostComponent;\n root: HostComponent | null;\n};\n\nexport function createRenderer(options?: RendererOptions): Renderer {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n options?.isConcurrent ? ConcurrentRoot : LegacyRoot,\n null, // no hydration callback\n false, // isStrictMode\n null, // concurrentUpdatesByDefaultOverride\n \"id\", // identifierPrefix\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(): HostComponent | 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 = HostComponent.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(): HostComponent {\n if (containerFiber == null || container == null) {\n throw new Error(\"Can't access .container on unmounted test renderer\");\n }\n\n return HostComponent.fromContainer(container);\n },\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/reconciler.ts","../src/utils.ts","../src/constants.ts","../src/render-to-json.ts","../src/host-element.ts","../src/renderer.ts"],"sourcesContent":["import { ReactElement } from \"react\";\nimport ReactReconciler, { Fiber } from \"react-reconciler\";\nimport { DefaultEventPriority } from \"react-reconciler/constants\";\nimport { formatComponentList } from \"./utils\";\n\n// Taken from NoEventPriority in react-reconciler/constants.js\nconst NoEventPriority: number = 0;\n\nexport type Type = string;\nexport type Props = Record<string, unknown>;\nexport type OpaqueHandle = Fiber;\n\nexport type Container = {\n tag: \"CONTAINER\";\n children: Array<Instance | TextInstance>;\n parent: null;\n\n // Access to key options passed to createRenderer\n textComponents?: string[];\n createNodeMock: (element: ReactElement) => object;\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 textComponents?: string[];\n};\n\nconst UPDATE_SIGNAL = {};\nconst nodeToInstanceMap = new WeakMap<object, Instance>();\n\nlet currentUpdatePriority: number = NoEventPriority;\n\n// if (__DEV__) {\n// Object.freeze(UPDATE_SIGNAL);\n// }\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 * 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 * 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.textComponents && !hostContext.isInsideText) {\n throw new Error(\n `Invariant Violation: Text strings must be rendered within a ${formatComponentList(\n rootContainer.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 appendInitialChild: appendChild,\n\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 * React calls this method so that you can compare the previous and the next props, and decide whether you\n * need to update the underlying instance or not. If you don't need to update it, return `null`. If you\n * need to update it, you can return an arbitrary object representing the changes that need to happen.\n * Then in `commitUpdate` you would need to apply those changes to the instance.\n *\n * This method happens **in the render phase**. It should only *calculate* the update — but not apply it!\n * For example, the DOM renderer returns an array that looks like `[prop1, value1, prop2, value2, ...]`\n * for all props that have actually changed. And only in `commitUpdate` it applies those changes. You should\n * calculate as much as you can in `prepareUpdate` so that `commitUpdate` can be very fast and straightforward.\n *\n * See the meaning of `rootContainer` and `hostContext` in the `createInstance` documentation.\n */\n prepareUpdate(\n _instance: Instance,\n _type: Type,\n _oldProps: Props,\n _newProps: Props,\n _rootContainer: Container,\n _hostContext: HostContext\n ) {\n return UPDATE_SIGNAL;\n },\n\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 /**\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 isInsideText: false,\n textComponents: rootContainer.textComponents,\n };\n },\n\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(\n parentHostContext.textComponents?.includes(type)\n );\n return { ...parentHostContext, type: type, isInsideText };\n },\n\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.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 * 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 * 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 * 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 * You can proxy this to `setTimeout` or its equivalent in your environment.\n */\n scheduleTimeout: setTimeout,\n cancelTimeout: clearTimeout,\n\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 * 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 * Optional. You can proxy this to `queueMicrotask` or its equivalent in your environment.\n */\n scheduleMicrotask: queueMicrotask,\n\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 /**\n * To implement this method, you'll need some constants available on the special `react-reconciler/constants` entry point:\n *\n * ```\n * import {\n * DiscreteEventPriority,\n * ContinuousEventPriority,\n * DefaultEventPriority,\n * } from 'react-reconciler/constants';\n *\n * const HostConfig = {\n * // ...\n * getCurrentEventPriority() {\n * return DefaultEventPriority;\n * },\n * // ...\n * }\n *\n * const MyRenderer = Reconciler(HostConfig);\n * ```\n *\n * The constant you return depends on which event, if any, is being handled right now. (In the browser, you can\n * check this using `window.event && window.event.type`).\n *\n * - **Discrete events**: If the active event is directly caused by the user (such as mouse and keyboard events)\n * and each event in a sequence is intentional (e.g. click), return DiscreteEventPriority. This tells React that\n * they should interrupt any background work and cannot be batched across time.\n *\n * - **Continuous events**: If the active event is directly caused by the user but the user can't distinguish between\n * individual events in a sequence (e.g. mouseover), return ContinuousEventPriority. This tells React they\n * should interrupt any background work but can be batched across time.\n *\n * - **Other events / No active event**: In all other cases, return DefaultEventPriority. This tells React that\n * this event is considered background work, and interactive events will be prioritized over it.\n *\n * You can consult the `getCurrentEventPriority()` implementation in `ReactDOMHostConfig.js` for a reference implementation.\n */\n // Removed in React 19\n // getCurrentEventPriority() {\n // return DefaultEventPriority;\n // },\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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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(\n textInstance: TextInstance,\n _oldText: string,\n newText: string\n ): void {\n textInstance.text = newText;\n },\n\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 * 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 commitUpdate(\n instance: Instance,\n _updatePayload: UpdatePayload,\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 * 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 * Same as `hideInstance`, but for nodes created by `createTextInstance`.\n */\n hideTextInstance(textInstance: TextInstance): void {\n textInstance.isHidden = true;\n },\n\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 * 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 * 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 // 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 // React 19\n // @ts-expect-error missing types\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 // #### `maySuspendCommit(type, props)`\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 maySuspendCommit(): boolean {\n return false;\n },\n\n // #### `preloadInstance(type, props)`\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 preloadInstance() {\n return true;\n },\n\n // #### `startSuspendingCommit()`\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 startSuspendingCommit() {},\n\n // #### `suspendInstance(type, props)`\n // This method is called after `startSuspendingCommit` for each Host Component that indicated it might\n // suspend a commit.\n suspendInstance() {},\n\n // #### `waitForCommitToBeReady()`\n // This method is called after all `suspendInstance` calls are complete.\n waitForCommitToBeReady() {\n return null;\n },\n\n NotPendingTransition: null,\n\n resetFormInstance() {},\n\n requestPostPaintCallback() {},\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(\n parentInstance: Container | Instance,\n child: 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 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(\n parentInstance: Container | Instance,\n child: Instance | TextInstance\n): 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","export const CONTAINER_TYPE = \"CONTAINER\";\n","import { CONTAINER_TYPE } from \"./constants\";\nimport { 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(\n instance: Container | Instance | TextInstance\n): 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(\n children: Array<Instance | TextInstance> | null\n) {\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 { Container, Instance, TextInstance } from \"./reconciler\";\nimport { JsonNode, 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<\n Container | Instance,\n HostElement\n>();\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\"\n ? this.instance.type\n : 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 { ReactElement } from \"react\";\nimport { Container, TestReconciler } from \"./reconciler\";\nimport { HostElement } from \"./host-element\";\nimport { FiberRoot } from \"react-reconciler\";\nimport { ConcurrentRoot, LegacyRoot } from \"react-reconciler/constants\";\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 RendererOptions = {\n textComponents?: string[];\n isConcurrent?: boolean;\n createNodeMock?: (element: ReactElement) => object;\n};\n\nexport type Renderer = {\n render: (element: ReactElement) => void;\n unmount: () => void;\n container: HostElement;\n root: HostElement | null;\n};\n\nexport function createRenderer(options?: RendererOptions): Renderer {\n let container: Container | null = {\n tag: \"CONTAINER\",\n children: [],\n parent: null,\n textComponents: options?.textComponents,\n createNodeMock: options?.createNodeMock ?? (() => ({})),\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n let containerFiber: FiberRoot = TestReconciler.createContainer(\n container,\n options?.isConcurrent ? ConcurrentRoot : LegacyRoot,\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"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "universal-test-renderer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-react19.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "",
|
|
@@ -16,17 +16,19 @@
|
|
|
16
16
|
"build": "tsup",
|
|
17
17
|
"dev": "tsup --watch",
|
|
18
18
|
"test": "jest",
|
|
19
|
+
"test:ci": "jest --coverage",
|
|
19
20
|
"lint": "eslint .",
|
|
20
21
|
"typecheck": "tsc --noEmit",
|
|
21
22
|
"test:watch": "jest --watch",
|
|
22
23
|
"validate": "pnpm lint && pnpm typecheck && pnpm test",
|
|
23
|
-
"release": "release-it"
|
|
24
|
+
"release": "release-it",
|
|
25
|
+
"release:react19": "release-it --preRelease=react19"
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|
|
26
|
-
"react-reconciler": "^0.
|
|
28
|
+
"react-reconciler": "^0.31.0-rc-fb9a90fa48-20240614"
|
|
27
29
|
},
|
|
28
30
|
"peerDependencies": {
|
|
29
|
-
"react": "^
|
|
31
|
+
"react": "^19.0.0-rc-fb9a90fa48-20240614"
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"@jest/globals": "^29.7.0",
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
"@types/react-reconciler": "^0.28.8",
|
|
37
39
|
"eslint": "^9.13.0",
|
|
38
40
|
"jest": "^29.7.0",
|
|
39
|
-
"react": "^
|
|
41
|
+
"react": "^19.0.0-rc-fb9a90fa48-20240614",
|
|
40
42
|
"release-it": "^17.10.0",
|
|
41
43
|
"ts-jest": "^29.2.5",
|
|
42
44
|
"tsup": "^8.3.5",
|