import { raise } from "@reacord/helpers/raise.js" import type { HostConfig } from "react-reconciler" import ReactReconciler from "react-reconciler" import { DefaultEventPriority } from "react-reconciler/constants.js" import { Node } from "./node.js" import type { Renderer } from "./renderers/renderer" import { TextNode } from "./text-node.js" const config: HostConfig< string, // Type, Record, // Props, Renderer, // Container, Node, // Instance, TextNode, // TextInstance, never, // SuspenseInstance, never, // HydratableInstance, never, // PublicInstance, never, // HostContext, true, // UpdatePayload, never, // ChildSet, number, // TimeoutHandle, number // NoTimeout, > = { supportsMutation: true, supportsPersistence: false, supportsHydration: false, isPrimaryRenderer: true, scheduleTimeout: global.setTimeout, cancelTimeout: global.clearTimeout, noTimeout: -1, getRootHostContext: () => null, getChildHostContext: (parentContext) => parentContext, createInstance: (type, props) => { if (type !== "reacord-element") { raise(`Unknown element type: ${type}`) } if (typeof props.createNode !== "function") { raise(`Missing createNode function`) } const node: unknown = props.createNode(props.props) if (!(node instanceof Node)) { raise(`createNode function did not return a Node`) } return node }, createTextInstance: (text) => new TextNode(text), shouldSetTextContent: () => false, detachDeletedInstance: (_instance) => {}, beforeActiveInstanceBlur: () => {}, afterActiveInstanceBlur: () => {}, getInstanceFromNode: (_node: unknown) => null, getInstanceFromScope: (_scopeInstance: unknown) => null, clearContainer: (renderer) => { renderer.nodes.clear() }, appendChildToContainer: (renderer, child) => { renderer.nodes.add(child) }, removeChildFromContainer: (renderer, child) => { renderer.nodes.remove(child) }, insertInContainerBefore: (renderer, child, before) => { renderer.nodes.addBefore(child, before) }, appendInitialChild: (parent, child) => { parent.children.add(child) }, appendChild: (parent, child) => { parent.children.add(child) }, removeChild: (parent, child) => { parent.children.remove(child) }, insertBefore: (parent, child, before) => { parent.children.addBefore(child, before) }, prepareUpdate: () => true, commitUpdate: (node, payload, type, oldProps, newProps) => { node.props = newProps.props }, commitTextUpdate: (node, oldText, newText) => { node.props = newText }, prepareForCommit: () => null, resetAfterCommit: (renderer) => { renderer.render() }, prepareScopeUpdate: (_scopeInstance: unknown, _instance: unknown) => {}, preparePortalMount: () => raise("Portals are not supported"), getPublicInstance: () => raise("Refs are currently not supported"), finalizeInitialChildren: () => false, getCurrentEventPriority: () => DefaultEventPriority, } export const reconciler = ReactReconciler(config)