@kubb/renderer-jsx 5.0.0-beta.16 → 5.0.0-beta.18

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.
@@ -1,6 +1,6 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { h as KubbReactNode, m as KubbReactElement } from "./types-nAFMiWFw.js";
3
- import { t as JSX } from "./jsx-namespace-CNp0arTN.js";
2
+ import { h as KubbReactNode, m as KubbReactElement } from "./types-Dk7A1Y5U.js";
3
+ import { t as JSX } from "./jsx-namespace-BLGeMDcR.js";
4
4
  import * as _$react from "react";
5
5
  import * as React$1 from "react/jsx-runtime";
6
6
 
@@ -1,5 +1,5 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { _ as KubbTextProps, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, l as KubbExportProps, m as KubbReactElement, p as KubbJsxProps, s as KubbArrowFunctionProps, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-nAFMiWFw.js";
2
+ import { _ as KubbTextProps, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, l as KubbExportProps, m as KubbReactElement, p as KubbJsxProps, s as KubbArrowFunctionProps, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-Dk7A1Y5U.js";
3
3
  import React from "react";
4
4
 
5
5
  //#region src/jsx-namespace.d.ts
@@ -36,4 +36,4 @@ declare namespace JSX$1 {
36
36
  }
37
37
  //#endregion
38
38
  export { JSX$1 as t };
39
- //# sourceMappingURL=jsx-namespace-CNp0arTN.d.ts.map
39
+ //# sourceMappingURL=jsx-namespace-BLGeMDcR.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { n as __name } from "./chunk-Bb7HlUDG.js";
2
- import { h as KubbReactNode, m as KubbReactElement } from "./types-nAFMiWFw.js";
3
- import { t as JSX } from "./jsx-namespace-CNp0arTN.js";
2
+ import { h as KubbReactNode, m as KubbReactElement } from "./types-Dk7A1Y5U.js";
3
+ import { t as JSX } from "./jsx-namespace-BLGeMDcR.js";
4
4
  import * as _$react from "react";
5
5
  import * as React$1 from "react/jsx-runtime";
6
6
 
@@ -46,7 +46,7 @@ type DOMElement = {
46
46
  /**
47
47
  * Key/value attributes passed as JSX props to this element.
48
48
  */
49
- attributes: Map<string, DOMNodeAttribute>;
49
+ attributes: Record<string, DOMNodeAttribute>;
50
50
  /**
51
51
  * Ordered list of child nodes attached to this element.
52
52
  */
@@ -165,4 +165,4 @@ type JSDoc = {
165
165
  };
166
166
  //#endregion
167
167
  export { KubbTextProps as _, JSDoc as a, TextNode as b, KubbConstProps as c, KubbFunctionProps as d, KubbImportProps as f, KubbSourceProps as g, KubbReactNode as h, ElementNames as i, KubbExportProps as l, KubbReactElement as m, DOMNode as n, Key as o, KubbJsxProps as p, DOMNodeAttribute as r, KubbArrowFunctionProps as s, DOMElement as t, KubbFileProps as u, KubbTypeProps as v, LineBreakProps as y };
168
- //# sourceMappingURL=types-nAFMiWFw.d.ts.map
168
+ //# sourceMappingURL=types-Dk7A1Y5U.d.ts.map
package/dist/types.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as KubbTextProps, a as JSDoc, b as TextNode, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, i as ElementNames, l as KubbExportProps, m as KubbReactElement, n as DOMNode, o as Key, p as KubbJsxProps, r as DOMNodeAttribute, s as KubbArrowFunctionProps, t as DOMElement, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-nAFMiWFw.js";
1
+ import { _ as KubbTextProps, a as JSDoc, b as TextNode, c as KubbConstProps, d as KubbFunctionProps, f as KubbImportProps, g as KubbSourceProps, h as KubbReactNode, i as ElementNames, l as KubbExportProps, m as KubbReactElement, n as DOMNode, o as Key, p as KubbJsxProps, r as DOMNodeAttribute, s as KubbArrowFunctionProps, t as DOMElement, u as KubbFileProps, v as KubbTypeProps, y as LineBreakProps } from "./types-Dk7A1Y5U.js";
2
2
  export { DOMElement, DOMNode, DOMNodeAttribute, ElementNames, JSDoc, Key, KubbArrowFunctionProps, KubbConstProps, KubbExportProps, KubbFileProps, KubbFunctionProps, KubbImportProps, KubbJsxProps, KubbReactElement, KubbReactNode, KubbSourceProps, KubbTextProps, KubbTypeProps, LineBreakProps, TextNode };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/renderer-jsx",
3
- "version": "5.0.0-beta.16",
3
+ "version": "5.0.0-beta.18",
4
4
  "description": "JSX-based renderer for Kubb. Provides a custom React runtime, reconciler, and built-in components (File, Function, Type, Const) for component-based, type-safe code generation.",
5
5
  "keywords": [
6
6
  "codegen",
@@ -75,7 +75,7 @@
75
75
  "registry": "https://registry.npmjs.org/"
76
76
  },
77
77
  "dependencies": {
78
- "@kubb/ast": "5.0.0-beta.16"
78
+ "@kubb/ast": "5.0.0-beta.18"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/react": "^19.2.14",
package/src/Renderer.ts CHANGED
@@ -105,7 +105,7 @@ export const Renderer = Reconciler({
105
105
  return false
106
106
  },
107
107
  supportsMutation: true,
108
- isPrimaryRenderer: true,
108
+ isPrimaryRenderer: false,
109
109
  supportsPersistence: false,
110
110
  supportsHydration: false,
111
111
  scheduleTimeout: setTimeout,
package/src/Runtime.tsx CHANGED
@@ -1,12 +1,12 @@
1
1
  import { onProcessExit } from '@internals/utils'
2
2
  import type { FileNode } from '@kubb/ast'
3
- import { ConcurrentRoot } from 'react-reconciler/constants.js'
3
+ import { LegacyRoot } from 'react-reconciler/constants.js'
4
4
  import { Root } from './components/Root.tsx'
5
5
  import { createNode } from './dom.ts'
6
6
  import type { FiberRoot } from 'react-reconciler'
7
7
  import { Renderer } from './Renderer.ts'
8
8
  import type { DOMElement, KubbReactElement } from './types.ts'
9
- import { processFiles } from './utils.ts'
9
+ import { collectFiles } from './utils.ts'
10
10
 
11
11
  type Options = {
12
12
  /**
@@ -51,7 +51,7 @@ export class Runtime {
51
51
 
52
52
  const logRecoverableError = typeof reportError === 'function' ? reportError : console.error
53
53
 
54
- const rootTag = ConcurrentRoot
54
+ const rootTag = LegacyRoot
55
55
  this.#container = Renderer.createContainer(
56
56
  this.#rootNode,
57
57
  rootTag,
@@ -86,7 +86,7 @@ export class Runtime {
86
86
  return
87
87
  }
88
88
 
89
- const files = processFiles(this.#rootNode)
89
+ const files = collectFiles(this.#rootNode)
90
90
 
91
91
  this.nodes.push(...files)
92
92
 
@@ -0,0 +1,285 @@
1
+ import type { ArrowFunctionNode, CodeNode, ExportNode, FileNode, ImportNode, JSDocNode, SourceNode } from '@kubb/ast'
2
+ import {
3
+ createArrowFunction,
4
+ createBreak,
5
+ createConst,
6
+ createExport,
7
+ createFunction,
8
+ createImport,
9
+ createJsx,
10
+ createSource,
11
+ createText,
12
+ createType,
13
+ } from '@kubb/ast'
14
+ import React from 'react'
15
+ import { KUBB_ARROW_FUNCTION, KUBB_CONST, KUBB_EXPORT, KUBB_FILE, KUBB_FUNCTION, KUBB_IMPORT, KUBB_JSX, KUBB_SOURCE, KUBB_TYPE } from './constants.ts'
16
+ import type { KubbReactElement } from './types.ts'
17
+
18
+ type OnText = (text: string) => void
19
+ type OnHost = (type: string, props: Record<string, unknown>) => void
20
+
21
+ /**
22
+ * Walks `element`, resolving arrays, Fragments, and function components
23
+ * transparently, then calls `onText` for primitive values and `onHost` for
24
+ * every host element encountered. Pure function components are called
25
+ * synchronously; hooks and class components are not supported.
26
+ */
27
+ function walkElement(element: unknown, onText: OnText, onHost: OnHost): void {
28
+ if (element == null || typeof element === 'boolean') return
29
+
30
+ if (typeof element === 'string' || typeof element === 'number' || typeof element === 'bigint') {
31
+ onText(String(element))
32
+ return
33
+ }
34
+
35
+ if (Array.isArray(element)) {
36
+ for (const child of element) walkElement(child, onText, onHost)
37
+ return
38
+ }
39
+
40
+ if (typeof element === 'object' && '$$typeof' in element) {
41
+ const el = element as unknown as React.ReactElement
42
+ const { type } = el
43
+ const props = el.props as Record<string, unknown>
44
+
45
+ if (type === React.Fragment) {
46
+ walkElement(props['children'], onText, onHost)
47
+ } else if (typeof type === 'function') {
48
+ walkElement((type as (p: unknown) => unknown)(props), onText, onHost)
49
+ } else if (typeof type === 'string') {
50
+ onHost(type, props)
51
+ }
52
+ }
53
+ }
54
+
55
+ function toBool(val: unknown): boolean {
56
+ return (val ?? false) as boolean
57
+ }
58
+
59
+ function collectCodeNodes(props: Record<string, unknown>): CodeNode[] {
60
+ const nodes: CodeNode[] = []
61
+ collectCode(props['children'], nodes)
62
+ return nodes
63
+ }
64
+
65
+ function collectCode(element: unknown, nodes: CodeNode[]): void {
66
+ walkElement(
67
+ element,
68
+ (text) => {
69
+ if (text.trim()) nodes.push(createText(text))
70
+ },
71
+ (type, props) => resolveCodeNode(type, props, nodes),
72
+ )
73
+ }
74
+
75
+ function resolveCodeNode(type: string, props: Record<string, unknown>, nodes: CodeNode[]): void {
76
+ if (type === 'br') {
77
+ nodes.push(createBreak())
78
+ return
79
+ }
80
+
81
+ if (type === KUBB_JSX) {
82
+ let value = ''
83
+ walkElement(
84
+ props['children'],
85
+ (t) => {
86
+ value += t
87
+ },
88
+ () => {},
89
+ )
90
+ if (value) nodes.push(createJsx(value))
91
+ return
92
+ }
93
+
94
+ if (type === KUBB_FUNCTION) {
95
+ nodes.push(
96
+ createFunction({
97
+ name: props['name'] as string,
98
+ params: props['params'] as string | undefined,
99
+ export: props['export'] as boolean | undefined,
100
+ default: props['default'] as boolean | undefined,
101
+ async: props['async'] as boolean | undefined,
102
+ generics: props['generics'] as string | undefined,
103
+ returnType: props['returnType'] as string | undefined,
104
+ JSDoc: props['JSDoc'] as JSDocNode | undefined,
105
+ nodes: collectCodeNodes(props),
106
+ }),
107
+ )
108
+ return
109
+ }
110
+
111
+ if (type === KUBB_ARROW_FUNCTION) {
112
+ nodes.push(
113
+ createArrowFunction({
114
+ name: props['name'] as string,
115
+ params: props['params'] as string | undefined,
116
+ export: props['export'] as boolean | undefined,
117
+ default: props['default'] as boolean | undefined,
118
+ async: props['async'] as boolean | undefined,
119
+ generics: props['generics'] as string | undefined,
120
+ returnType: props['returnType'] as string | undefined,
121
+ singleLine: props['singleLine'] as boolean | undefined,
122
+ JSDoc: props['JSDoc'] as JSDocNode | undefined,
123
+ nodes: collectCodeNodes(props),
124
+ } as Omit<ArrowFunctionNode, 'kind'>),
125
+ )
126
+ return
127
+ }
128
+
129
+ if (type === KUBB_CONST) {
130
+ nodes.push(
131
+ createConst({
132
+ name: props['name'] as string,
133
+ type: props['type'] as string | undefined,
134
+ export: props['export'] as boolean | undefined,
135
+ asConst: props['asConst'] as boolean | undefined,
136
+ JSDoc: props['JSDoc'] as JSDocNode | undefined,
137
+ nodes: collectCodeNodes(props),
138
+ }),
139
+ )
140
+ return
141
+ }
142
+
143
+ if (type === KUBB_TYPE) {
144
+ nodes.push(
145
+ createType({
146
+ name: props['name'] as string,
147
+ export: props['export'] as boolean | undefined,
148
+ JSDoc: props['JSDoc'] as JSDocNode | undefined,
149
+ nodes: collectCodeNodes(props),
150
+ }),
151
+ )
152
+ return
153
+ }
154
+ }
155
+
156
+ type FileChildren = { sources: SourceNode[]; exports: ExportNode[]; imports: ImportNode[] }
157
+
158
+ function collectFileChildren(element: unknown): FileChildren {
159
+ const sources: SourceNode[] = []
160
+ const exports: ExportNode[] = []
161
+ const imports: ImportNode[] = []
162
+
163
+ walkElement(
164
+ element,
165
+ (text) => {
166
+ if (text.trim()) {
167
+ throw new Error(`[react] '${text}' should be part of <File.Source> component when using the <File/> component`)
168
+ }
169
+ },
170
+ (type, props) => {
171
+ if (type === KUBB_SOURCE) {
172
+ sources.push(
173
+ createSource({
174
+ name: props['name']?.toString(),
175
+ isTypeOnly: toBool(props['isTypeOnly']),
176
+ isExportable: toBool(props['isExportable']),
177
+ isIndexable: toBool(props['isIndexable']),
178
+ nodes: collectCodeNodes(props),
179
+ }),
180
+ )
181
+ return
182
+ }
183
+
184
+ if (type === KUBB_EXPORT) {
185
+ exports.push(
186
+ createExport({
187
+ name: props['name'] as ExportNode['name'],
188
+ path: props['path'] as string,
189
+ isTypeOnly: toBool(props['isTypeOnly']),
190
+ asAlias: toBool(props['asAlias']),
191
+ }),
192
+ )
193
+ return
194
+ }
195
+
196
+ if (type === KUBB_IMPORT) {
197
+ imports.push(
198
+ createImport({
199
+ name: props['name'] as ImportNode['name'],
200
+ path: props['path'] as string,
201
+ root: props['root'] as string | undefined,
202
+ isTypeOnly: toBool(props['isTypeOnly']),
203
+ isNameSpace: toBool(props['isNameSpace']),
204
+ }),
205
+ )
206
+ return
207
+ }
208
+
209
+ const nested = collectFileChildren(props['children'])
210
+ sources.push(...nested.sources)
211
+ exports.push(...nested.exports)
212
+ imports.push(...nested.imports)
213
+ },
214
+ )
215
+
216
+ return { sources, exports, imports }
217
+ }
218
+
219
+ function* walkFiles(element: unknown): Generator<FileNode> {
220
+ const files: FileNode[] = []
221
+
222
+ function onHost(type: string, props: Record<string, unknown>): void {
223
+ if (type === KUBB_FILE && props['baseName'] !== undefined && props['path'] !== undefined) {
224
+ const { sources, exports, imports } = collectFileChildren(props['children'])
225
+ files.push({
226
+ baseName: props['baseName'],
227
+ path: props['path'],
228
+ meta: props['meta'] || {},
229
+ footer: props['footer'],
230
+ banner: props['banner'],
231
+ sources,
232
+ exports,
233
+ imports,
234
+ } as FileNode)
235
+ } else {
236
+ walkElement(props['children'], () => {}, onHost)
237
+ }
238
+ }
239
+
240
+ walkElement(element, () => {}, onHost)
241
+ yield* files
242
+ }
243
+
244
+ /**
245
+ * Synchronous JSX renderer that walks the element tree in a single pass,
246
+ * producing {@link FileNode} objects directly without an intermediate virtual
247
+ * DOM. No React fiber, scheduler, or work loop is involved.
248
+ *
249
+ * All components must be pure functions; hooks and class components are not
250
+ * supported. Produces identical output to the React-backed {@link Runtime} at
251
+ * approximately 2–4× the speed and a fraction of the allocations.
252
+ */
253
+ export class SyncRuntime {
254
+ /**
255
+ * Accumulated {@link FileNode} results from every {@link render} call.
256
+ */
257
+ nodes: FileNode[] = []
258
+
259
+ /**
260
+ * Walks `element` synchronously, converts every `<kubb-file>` subtree into
261
+ * a {@link FileNode} with no intermediate virtual DOM, and appends the results
262
+ * to {@link nodes}.
263
+ */
264
+ render(element: KubbReactElement): void {
265
+ for (const file of walkFiles(element)) {
266
+ this.nodes.push(file)
267
+ }
268
+ }
269
+
270
+ /**
271
+ * Walks `element` synchronously and yields each {@link FileNode} as it is
272
+ * produced, without buffering into an intermediate array first. Callers can
273
+ * begin processing each file before the rest of the element tree is traversed.
274
+ *
275
+ * @example
276
+ * ```ts
277
+ * for (const file of runtime.stream(element)) {
278
+ * await writeFile(file)
279
+ * }
280
+ * ```
281
+ */
282
+ *stream(element: KubbReactElement): Generator<FileNode> {
283
+ yield* walkFiles(element)
284
+ }
285
+ }
package/src/constants.ts CHANGED
@@ -5,20 +5,30 @@ import type { ElementNames } from './types.ts'
5
5
  */
6
6
  export const TEXT_NODE_NAME = '#text' as const
7
7
 
8
+ export const KUBB_FILE = 'kubb-file' as const
9
+ export const KUBB_SOURCE = 'kubb-source' as const
10
+ export const KUBB_EXPORT = 'kubb-export' as const
11
+ export const KUBB_IMPORT = 'kubb-import' as const
12
+ export const KUBB_FUNCTION = 'kubb-function' as const
13
+ export const KUBB_ARROW_FUNCTION = 'kubb-arrow-function' as const
14
+ export const KUBB_CONST = 'kubb-const' as const
15
+ export const KUBB_TYPE = 'kubb-type' as const
16
+ export const KUBB_JSX = 'kubb-jsx' as const
17
+
8
18
  /**
9
19
  * Set of all element names recognized by the Kubb renderer.
10
20
  * Used to distinguish Kubb-owned elements from unrecognized or text nodes during tree traversal.
11
21
  */
12
22
  export const nodeNames = new Set<ElementNames>([
13
- 'kubb-export',
14
- 'kubb-file',
15
- 'kubb-source',
16
- 'kubb-import',
17
- 'kubb-function',
18
- 'kubb-arrow-function',
19
- 'kubb-const',
20
- 'kubb-type',
21
- 'kubb-jsx',
23
+ KUBB_EXPORT,
24
+ KUBB_FILE,
25
+ KUBB_SOURCE,
26
+ KUBB_IMPORT,
27
+ KUBB_FUNCTION,
28
+ KUBB_ARROW_FUNCTION,
29
+ KUBB_CONST,
30
+ KUBB_TYPE,
31
+ KUBB_JSX,
22
32
  'kubb-text',
23
33
  'kubb-root',
24
34
  'kubb-app',
@@ -1,20 +1,19 @@
1
+ import type { FileNode } from '@kubb/ast'
1
2
  import { Runtime } from './Runtime.tsx'
3
+ import { SyncRuntime } from './SyncRuntime.tsx'
2
4
  import type { KubbReactElement } from './types.ts'
3
5
 
4
6
  /**
5
- * A renderer factory for generators that produce JSX output.
7
+ * Renderer factory for generators that produce JSX output.
6
8
  *
7
- * Pass this as the `renderer` property of a `defineGenerator` call so that
8
- * core can render the JSX element tree returned by your generator methods
9
+ * Pass as the `renderer` property of `defineGenerator`. Core drives rendering
9
10
  * without a hard dependency on `@kubb/renderer-jsx`.
10
11
  *
11
12
  * @example
12
13
  * ```ts
13
14
  * import { jsxRenderer } from '@kubb/renderer-jsx'
14
- * import { defineGenerator } from '@kubb/core'
15
15
  *
16
16
  * export const myGenerator = defineGenerator<PluginTs>({
17
- * name: 'my-generator',
18
17
  * renderer: jsxRenderer,
19
18
  * schema(node, options) {
20
19
  * return <File baseName="output.ts" path="src/output.ts">...</File>
@@ -36,3 +35,45 @@ export const jsxRenderer = () => {
36
35
  },
37
36
  }
38
37
  }
38
+
39
+ /**
40
+ * Lightweight renderer factory with no React fiber, scheduler, or work loop.
41
+ *
42
+ * Walks the JSX element tree in a single recursive pass. All components must be
43
+ * pure functions; hooks and class components are not supported. Drop-in
44
+ * replacement for {@link jsxRenderer} at approximately 2–4× the speed.
45
+ *
46
+ * @example Drop-in replacement
47
+ * ```ts
48
+ * import { jsxRendererSync } from '@kubb/renderer-jsx'
49
+ *
50
+ * export const myGenerator = defineGenerator<PluginTs>({
51
+ * renderer: jsxRendererSync,
52
+ * schema(node, options) {
53
+ * return <File baseName="output.ts" path="src/output.ts">...</File>
54
+ * },
55
+ * })
56
+ * ```
57
+ *
58
+ * @example Stream files as they are produced
59
+ * ```ts
60
+ * for await (const file of jsxRendererSync().stream(element)) {
61
+ * await writeFile(file)
62
+ * }
63
+ * ```
64
+ */
65
+ export const jsxRendererSync = () => {
66
+ const runtime = new SyncRuntime()
67
+ return {
68
+ async render(element: KubbReactElement): Promise<void> {
69
+ runtime.render(element)
70
+ },
71
+ get files() {
72
+ return runtime.nodes
73
+ },
74
+ async *stream(element: KubbReactElement): AsyncGenerator<FileNode> {
75
+ yield* runtime.stream(element)
76
+ },
77
+ unmount(_error?: Error | number | null) {},
78
+ }
79
+ }
package/src/dom.ts CHANGED
@@ -8,7 +8,7 @@ import type { DOMElement, DOMNode, DOMNodeAttribute, TextNode } from './types.ts
8
8
  export const createNode = (nodeName: string): DOMElement => {
9
9
  return {
10
10
  nodeName: nodeName as DOMElement['nodeName'],
11
- attributes: new Map(),
11
+ attributes: Object.create(null) as Record<string, DOMNodeAttribute>,
12
12
  childNodes: [],
13
13
  parentNode: undefined,
14
14
  }
@@ -48,7 +48,6 @@ export const insertBeforeNode = (node: DOMElement, newChildNode: DOMNode, before
48
48
  const index = node.childNodes.indexOf(beforeChildNode)
49
49
  if (index >= 0) {
50
50
  node.childNodes.splice(index, 0, newChildNode)
51
-
52
51
  return
53
52
  }
54
53
 
@@ -72,32 +71,23 @@ export const removeChildNode = (node: DOMElement, removeNode: DOMNode): void =>
72
71
  * Set an attribute on `node`, storing it in the node's `attributes` map.
73
72
  */
74
73
  export const setAttribute = (node: DOMElement, key: string, value: DOMNodeAttribute): void => {
75
- node.attributes.set(key, value)
74
+ node.attributes[key] = value
76
75
  }
77
76
 
78
77
  /**
79
78
  * Create a new {@link TextNode} with the given text value.
80
79
  */
81
80
  export const createTextNode = (text: string): TextNode => {
82
- const node: TextNode = {
81
+ return {
83
82
  nodeName: TEXT_NODE_NAME,
84
83
  nodeValue: text,
85
84
  parentNode: undefined,
86
85
  }
87
-
88
- setTextNodeValue(node, text)
89
-
90
- return node
91
86
  }
92
87
 
93
88
  /**
94
89
  * Update the `nodeValue` of an existing {@link TextNode}.
95
- * Non-string values are coerced to strings via `String(text)`.
96
90
  */
97
91
  export const setTextNodeValue = (node: TextNode, text: string): void => {
98
- if (typeof text !== 'string') {
99
- text = String(text)
100
- }
101
-
102
92
  node.nodeValue = text
103
93
  }
package/src/index.ts CHANGED
@@ -5,4 +5,4 @@ export { Function } from './components/Function.tsx'
5
5
  export { Jsx } from './components/Jsx.tsx'
6
6
  export { Root } from './components/Root.tsx'
7
7
  export { Type } from './components/Type.tsx'
8
- export { jsxRenderer } from './createRenderer.tsx'
8
+ export { jsxRenderer, jsxRendererSync } from './createRenderer.tsx'
package/src/types.ts CHANGED
@@ -71,7 +71,7 @@ export type DOMElement = {
71
71
  /**
72
72
  * Key/value attributes passed as JSX props to this element.
73
73
  */
74
- attributes: Map<string, DOMNodeAttribute>
74
+ attributes: Record<string, DOMNodeAttribute>
75
75
  /**
76
76
  * Ordered list of child nodes attached to this element.
77
77
  */