@kubb/renderer-jsx 5.0.0-beta.4 → 5.0.0-beta.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -0
- package/dist/index.cjs +621 -193
- package/dist/index.d.ts +326 -90
- package/dist/index.js +615 -193
- package/dist/jsx-dev-runtime.cjs +1 -1
- package/dist/jsx-dev-runtime.d.ts +7 -8
- package/dist/jsx-dev-runtime.js +2 -2
- package/dist/{jsx-namespace-CNp0arTN.d.ts → jsx-namespace-dmStM1a2.d.ts} +3 -3
- package/dist/{jsx-runtime-DdmO3p0U.cjs → jsx-runtime-4M1bV6ub.cjs} +9 -9
- package/dist/{jsx-runtime-Cvu_ZYgL.js → jsx-runtime-CQ6-_gue.js} +10 -10
- package/dist/jsx-runtime.cjs +1 -1
- package/dist/jsx-runtime.d.ts +9 -10
- package/dist/jsx-runtime.js +2 -2
- package/dist/{types-nAFMiWFw.d.ts → types-B5VGpHs0.d.ts} +11 -10
- package/dist/types.d.ts +1 -1
- package/package.json +8 -12
- package/src/Renderer.ts +1 -5
- package/src/Runtime.tsx +7 -18
- package/src/SyncRuntime.tsx +309 -0
- package/src/components/Callout.tsx +59 -0
- package/src/components/CodeBlock.tsx +37 -0
- package/src/components/Const.tsx +4 -4
- package/src/components/File.tsx +7 -5
- package/src/components/Frontmatter.tsx +38 -0
- package/src/components/Function.tsx +8 -8
- package/src/components/Heading.tsx +34 -0
- package/src/components/Jsx.tsx +1 -1
- package/src/components/List.tsx +40 -0
- package/src/components/Paragraph.tsx +28 -0
- package/src/components/Type.tsx +3 -3
- package/src/constants.ts +19 -9
- package/src/createRenderer.tsx +81 -62
- package/src/dom.ts +7 -19
- package/src/index.ts +7 -1
- package/src/types.ts +9 -8
- package/src/utils.ts +153 -174
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jsx-dev-runtime.cjs.map +0 -1
- package/dist/jsx-dev-runtime.js.map +0 -1
- package/dist/jsx-runtime-Cvu_ZYgL.js.map +0 -1
- package/dist/jsx-runtime-DdmO3p0U.cjs.map +0 -1
- package/dist/jsx-runtime.cjs.map +0 -1
- package/dist/jsx-runtime.js.map +0 -1
- /package/dist/{chunk-Bb7HlUDG.js → chunk-DoukXa0m.js} +0 -0
package/src/components/Type.tsx
CHANGED
|
@@ -16,12 +16,12 @@ type TypeProps = {
|
|
|
16
16
|
* - `false` generates `type Name = …`
|
|
17
17
|
* @default false
|
|
18
18
|
*/
|
|
19
|
-
export?: boolean
|
|
19
|
+
export?: boolean | null
|
|
20
20
|
/**
|
|
21
21
|
* JSDoc block to prepend to the type alias declaration.
|
|
22
22
|
* Each entry in `comments` becomes one line inside the emitted `/** … *\/` block.
|
|
23
23
|
*/
|
|
24
|
-
JSDoc?: JSDoc
|
|
24
|
+
JSDoc?: JSDoc | null
|
|
25
25
|
/**
|
|
26
26
|
* Child nodes rendered as the type expression on the right-hand side of the alias.
|
|
27
27
|
*/
|
|
@@ -31,7 +31,7 @@ type TypeProps = {
|
|
|
31
31
|
/**
|
|
32
32
|
* Generates a TypeScript type alias declaration.
|
|
33
33
|
*
|
|
34
|
-
* Throws if `name` does not start with an uppercase letter
|
|
34
|
+
* Throws if `name` does not start with an uppercase letter. TypeScript type aliases
|
|
35
35
|
* should follow PascalCase naming conventions.
|
|
36
36
|
*
|
|
37
37
|
* @example Simple exported type alias
|
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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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',
|
package/src/createRenderer.tsx
CHANGED
|
@@ -1,93 +1,112 @@
|
|
|
1
1
|
import type { FileNode } from '@kubb/ast'
|
|
2
2
|
import { Runtime } from './Runtime.tsx'
|
|
3
|
+
import { SyncRuntime } from './SyncRuntime.tsx'
|
|
3
4
|
import type { KubbReactElement } from './types.ts'
|
|
4
5
|
|
|
5
|
-
type Options = {
|
|
6
|
-
/**
|
|
7
|
-
* Print each render result to the console for debugging.
|
|
8
|
-
* Useful when diagnosing output differences between renders.
|
|
9
|
-
* @default false
|
|
10
|
-
*/
|
|
11
|
-
debug?: boolean
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The renderer instance returned by {@link createRenderer}.
|
|
16
|
-
*/
|
|
17
|
-
type Renderer = {
|
|
18
|
-
/**
|
|
19
|
-
* Render a JSX element tree and collect the resulting {@link FileNode} entries.
|
|
20
|
-
* Resolves once all synchronous render work (including React's flush) is done.
|
|
21
|
-
*/
|
|
22
|
-
render(Element: KubbReactElement): Promise<void>
|
|
23
|
-
/**
|
|
24
|
-
* Tear down the renderer and release all React resources.
|
|
25
|
-
* Pass an `Error` to signal an abnormal shutdown.
|
|
26
|
-
*/
|
|
27
|
-
unmount(error?: Error | number | null): void
|
|
28
|
-
/**
|
|
29
|
-
* The {@link FileNode} entries collected from the most recent `render` call.
|
|
30
|
-
*/
|
|
31
|
-
files: Array<FileNode>
|
|
32
|
-
}
|
|
33
|
-
|
|
34
6
|
/**
|
|
35
|
-
*
|
|
7
|
+
* Renderer factory that turns the JSX produced by a generator into
|
|
8
|
+
* `FileNode`s using React's reconciler under the hood. Pass as the `renderer`
|
|
9
|
+
* property on `defineGenerator`. Kubb core stays generic, with no hard
|
|
10
|
+
* dependency on `@kubb/renderer-jsx`.
|
|
36
11
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
12
|
+
* Use this when generators rely on React features (hooks, suspense, context).
|
|
13
|
+
* For pure-function components, see {@link jsxRendererSync} for ~2-4× faster
|
|
14
|
+
* rendering.
|
|
39
15
|
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```
|
|
42
|
-
* import {
|
|
16
|
+
* @example Wire up a JSX generator
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { defineGenerator } from '@kubb/core'
|
|
19
|
+
* import { jsxRenderer } from '@kubb/renderer-jsx'
|
|
43
20
|
*
|
|
44
|
-
* const
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
21
|
+
* export const myGenerator = defineGenerator<PluginTs>({
|
|
22
|
+
* name: 'types',
|
|
23
|
+
* renderer: jsxRenderer,
|
|
24
|
+
* schema(node, ctx) {
|
|
25
|
+
* return (
|
|
26
|
+
* <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
|
|
27
|
+
* <Type node={node} resolver={ctx.resolver} />
|
|
28
|
+
* </File>
|
|
29
|
+
* )
|
|
30
|
+
* },
|
|
31
|
+
* })
|
|
54
32
|
* ```
|
|
55
33
|
*/
|
|
56
|
-
export
|
|
57
|
-
const runtime = new Runtime(
|
|
34
|
+
export const jsxRenderer = () => {
|
|
35
|
+
const runtime = new Runtime()
|
|
58
36
|
|
|
59
37
|
return {
|
|
60
|
-
async render(
|
|
61
|
-
await runtime.render(
|
|
38
|
+
async render(element: KubbReactElement) {
|
|
39
|
+
await runtime.render(element)
|
|
62
40
|
},
|
|
63
41
|
get files() {
|
|
64
42
|
return runtime.nodes
|
|
65
43
|
},
|
|
66
|
-
|
|
44
|
+
dispose() {
|
|
45
|
+
runtime.unmount()
|
|
46
|
+
},
|
|
47
|
+
unmount(error?: Error | number | null) {
|
|
67
48
|
runtime.unmount(error)
|
|
68
49
|
},
|
|
50
|
+
[Symbol.dispose]() {
|
|
51
|
+
this.dispose()
|
|
52
|
+
},
|
|
69
53
|
}
|
|
70
54
|
}
|
|
71
55
|
|
|
72
56
|
/**
|
|
73
|
-
*
|
|
57
|
+
* Lightweight renderer that walks the JSX tree in a single recursive pass, * no React reconciler, no scheduler. Drop-in replacement for
|
|
58
|
+
* {@link jsxRenderer} at roughly 2, 4× the throughput.
|
|
74
59
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* without a hard dependency on `@kubb/renderer-jsx`.
|
|
60
|
+
* Constraints: every component must be a pure function. Hooks, suspense, and
|
|
61
|
+
* class components are not supported.
|
|
78
62
|
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
63
|
+
* Use this for generators that produce large amounts of output and do not need
|
|
64
|
+
* React's runtime features. It also exposes `stream()` for incremental file
|
|
65
|
+
* emission.
|
|
66
|
+
*
|
|
67
|
+
* @example Drop-in faster renderer
|
|
68
|
+
* ```tsx
|
|
82
69
|
* import { defineGenerator } from '@kubb/core'
|
|
70
|
+
* import { jsxRendererSync } from '@kubb/renderer-jsx'
|
|
83
71
|
*
|
|
84
72
|
* export const myGenerator = defineGenerator<PluginTs>({
|
|
85
|
-
* name: '
|
|
86
|
-
* renderer:
|
|
87
|
-
* schema(node,
|
|
88
|
-
* return
|
|
73
|
+
* name: 'types',
|
|
74
|
+
* renderer: jsxRendererSync,
|
|
75
|
+
* schema(node, ctx) {
|
|
76
|
+
* return (
|
|
77
|
+
* <File baseName="output.ts" path={`${ctx.root}/output.ts`}>
|
|
78
|
+
* <Type node={node} resolver={ctx.resolver} />
|
|
79
|
+
* </File>
|
|
80
|
+
* )
|
|
89
81
|
* },
|
|
90
82
|
* })
|
|
91
83
|
* ```
|
|
84
|
+
*
|
|
85
|
+
* @example Stream files as they are produced
|
|
86
|
+
* ```tsx
|
|
87
|
+
* const renderer = jsxRendererSync()
|
|
88
|
+
* for (const file of renderer.stream(element)) {
|
|
89
|
+
* await writeFile(file.path, file.sources[0])
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
92
|
*/
|
|
93
|
-
export const
|
|
93
|
+
export const jsxRendererSync = () => {
|
|
94
|
+
const runtime = new SyncRuntime()
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
async render(element: KubbReactElement): Promise<void> {
|
|
98
|
+
runtime.render(element)
|
|
99
|
+
},
|
|
100
|
+
get files() {
|
|
101
|
+
return runtime.nodes
|
|
102
|
+
},
|
|
103
|
+
stream(element: KubbReactElement): Generator<FileNode> {
|
|
104
|
+
return runtime.stream(element)
|
|
105
|
+
},
|
|
106
|
+
dispose() {},
|
|
107
|
+
unmount(_error?: Error | number | null) {},
|
|
108
|
+
[Symbol.dispose]() {
|
|
109
|
+
this.dispose()
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
}
|
package/src/dom.ts
CHANGED
|
@@ -6,14 +6,12 @@ import type { DOMElement, DOMNode, DOMNodeAttribute, TextNode } from './types.ts
|
|
|
6
6
|
* The element has no attributes, no children, and no parent.
|
|
7
7
|
*/
|
|
8
8
|
export const createNode = (nodeName: string): DOMElement => {
|
|
9
|
-
|
|
9
|
+
return {
|
|
10
10
|
nodeName: nodeName as DOMElement['nodeName'],
|
|
11
|
-
attributes:
|
|
11
|
+
attributes: Object.create(null) as Record<string, DOMNodeAttribute>,
|
|
12
12
|
childNodes: [],
|
|
13
|
-
parentNode:
|
|
13
|
+
parentNode: null,
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
return node
|
|
17
15
|
}
|
|
18
16
|
|
|
19
17
|
/**
|
|
@@ -50,7 +48,6 @@ export const insertBeforeNode = (node: DOMElement, newChildNode: DOMNode, before
|
|
|
50
48
|
const index = node.childNodes.indexOf(beforeChildNode)
|
|
51
49
|
if (index >= 0) {
|
|
52
50
|
node.childNodes.splice(index, 0, newChildNode)
|
|
53
|
-
|
|
54
51
|
return
|
|
55
52
|
}
|
|
56
53
|
|
|
@@ -62,7 +59,7 @@ export const insertBeforeNode = (node: DOMElement, newChildNode: DOMNode, before
|
|
|
62
59
|
* Does nothing if `removeNode` is not a direct child of `node`.
|
|
63
60
|
*/
|
|
64
61
|
export const removeChildNode = (node: DOMElement, removeNode: DOMNode): void => {
|
|
65
|
-
removeNode.parentNode =
|
|
62
|
+
removeNode.parentNode = null
|
|
66
63
|
|
|
67
64
|
const index = node.childNodes.indexOf(removeNode)
|
|
68
65
|
if (index >= 0) {
|
|
@@ -74,32 +71,23 @@ export const removeChildNode = (node: DOMElement, removeNode: DOMNode): void =>
|
|
|
74
71
|
* Set an attribute on `node`, storing it in the node's `attributes` map.
|
|
75
72
|
*/
|
|
76
73
|
export const setAttribute = (node: DOMElement, key: string, value: DOMNodeAttribute): void => {
|
|
77
|
-
node.attributes
|
|
74
|
+
node.attributes[key] = value
|
|
78
75
|
}
|
|
79
76
|
|
|
80
77
|
/**
|
|
81
78
|
* Create a new {@link TextNode} with the given text value.
|
|
82
79
|
*/
|
|
83
80
|
export const createTextNode = (text: string): TextNode => {
|
|
84
|
-
|
|
81
|
+
return {
|
|
85
82
|
nodeName: TEXT_NODE_NAME,
|
|
86
83
|
nodeValue: text,
|
|
87
|
-
parentNode:
|
|
84
|
+
parentNode: null,
|
|
88
85
|
}
|
|
89
|
-
|
|
90
|
-
setTextNodeValue(node, text)
|
|
91
|
-
|
|
92
|
-
return node
|
|
93
86
|
}
|
|
94
87
|
|
|
95
88
|
/**
|
|
96
89
|
* Update the `nodeValue` of an existing {@link TextNode}.
|
|
97
|
-
* Non-string values are coerced to strings via `String(text)`.
|
|
98
90
|
*/
|
|
99
91
|
export const setTextNodeValue = (node: TextNode, text: string): void => {
|
|
100
|
-
if (typeof text !== 'string') {
|
|
101
|
-
text = String(text)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
92
|
node.nodeValue = text
|
|
105
93
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
export { createContext, inject, provide, unprovide } from '@internals/utils'
|
|
2
|
+
export { Callout } from './components/Callout.tsx'
|
|
3
|
+
export { CodeBlock } from './components/CodeBlock.tsx'
|
|
2
4
|
export { Const } from './components/Const.tsx'
|
|
3
5
|
export { File } from './components/File.tsx'
|
|
6
|
+
export { Frontmatter } from './components/Frontmatter.tsx'
|
|
4
7
|
export { Function } from './components/Function.tsx'
|
|
8
|
+
export { Heading } from './components/Heading.tsx'
|
|
5
9
|
export { Jsx } from './components/Jsx.tsx'
|
|
10
|
+
export { List } from './components/List.tsx'
|
|
11
|
+
export { Paragraph } from './components/Paragraph.tsx'
|
|
6
12
|
export { Root } from './components/Root.tsx'
|
|
7
13
|
export { Type } from './components/Type.tsx'
|
|
8
|
-
export {
|
|
14
|
+
export { jsxRenderer, jsxRendererSync } from './createRenderer.tsx'
|
package/src/types.ts
CHANGED
|
@@ -30,14 +30,15 @@ export type ElementNames =
|
|
|
30
30
|
| 'kubb-app'
|
|
31
31
|
|
|
32
32
|
type Node = {
|
|
33
|
-
parentNode: DOMElement |
|
|
33
|
+
parentNode: DOMElement | null
|
|
34
34
|
internal_static?: boolean
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Allowed attribute value types for DOM elements.
|
|
39
|
+
* `null` signals intentionally empty, the prop was explicitly cleared.
|
|
39
40
|
*/
|
|
40
|
-
export type DOMNodeAttribute = boolean | string | number | Record<string, unknown> | Array<unknown>
|
|
41
|
+
export type DOMNodeAttribute = boolean | string | number | null | Record<string, unknown> | Array<unknown>
|
|
41
42
|
|
|
42
43
|
type TextName = '#text'
|
|
43
44
|
|
|
@@ -50,7 +51,7 @@ export type TextNode = {
|
|
|
50
51
|
} & Node
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
|
-
* Virtual DOM node
|
|
54
|
+
* Virtual DOM node, either a text node or a named element.
|
|
54
55
|
*/
|
|
55
56
|
export type DOMNode<T = { nodeName: NodeNames }> = T extends {
|
|
56
57
|
nodeName: infer U
|
|
@@ -71,11 +72,11 @@ export type DOMElement = {
|
|
|
71
72
|
/**
|
|
72
73
|
* Key/value attributes passed as JSX props to this element.
|
|
73
74
|
*/
|
|
74
|
-
attributes:
|
|
75
|
+
attributes: Record<string, DOMNodeAttribute>
|
|
75
76
|
/**
|
|
76
77
|
* Ordered list of child nodes attached to this element.
|
|
77
78
|
*/
|
|
78
|
-
childNodes: DOMNode
|
|
79
|
+
childNodes: Array<DOMNode>
|
|
79
80
|
internal_transform?: OutputTransformer
|
|
80
81
|
|
|
81
82
|
// Internal properties
|
|
@@ -119,12 +120,12 @@ export type KubbTextProps = {
|
|
|
119
120
|
* Represents a generated file.
|
|
120
121
|
*/
|
|
121
122
|
export type KubbFileProps = {
|
|
122
|
-
id?: string
|
|
123
|
+
id?: string | null
|
|
123
124
|
children?: KubbReactNode
|
|
124
125
|
baseName: string
|
|
125
126
|
path: string
|
|
126
|
-
override?: boolean
|
|
127
|
-
meta?: FileNode['meta']
|
|
127
|
+
override?: boolean | null
|
|
128
|
+
meta?: FileNode['meta'] | null
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
/**
|