@contember/react-multipass-rendering 1.0.0-rc.1 → 1.0.0-rc.12

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.
Files changed (79) hide show
  1. package/dist/types/BranchNodeList.d.ts +3 -0
  2. package/dist/types/BranchNodeList.d.ts.map +1 -0
  3. package/dist/types/ChildrenAnalyzer.d.ts +15 -0
  4. package/dist/types/ChildrenAnalyzer.d.ts.map +1 -0
  5. package/dist/types/ChildrenAnalyzerError.d.ts +3 -0
  6. package/dist/types/ChildrenAnalyzerError.d.ts.map +1 -0
  7. package/dist/types/ChildrenAnalyzerOptions.d.ts +10 -0
  8. package/dist/types/ChildrenAnalyzerOptions.d.ts.map +1 -0
  9. package/dist/types/ErrorMessageFactory.d.ts +3 -0
  10. package/dist/types/ErrorMessageFactory.d.ts.map +1 -0
  11. package/dist/types/LeafList.d.ts +3 -0
  12. package/dist/types/LeafList.d.ts.map +1 -0
  13. package/dist/types/assertNever.d.ts +2 -0
  14. package/dist/types/assertNever.d.ts.map +1 -0
  15. package/dist/types/helpers/getErrorMessage.d.ts +4 -0
  16. package/dist/types/helpers/getErrorMessage.d.ts.map +1 -0
  17. package/dist/types/helpers/index.d.ts +2 -0
  18. package/dist/types/helpers/index.d.ts.map +1 -0
  19. package/dist/types/index.d.ts +5 -0
  20. package/dist/types/index.d.ts.map +1 -0
  21. package/dist/types/nodeSpecs/BranchNode.d.ts +23 -0
  22. package/dist/types/nodeSpecs/BranchNode.d.ts.map +1 -0
  23. package/dist/types/nodeSpecs/BranchNodeOptions.d.ts +5 -0
  24. package/dist/types/nodeSpecs/BranchNodeOptions.d.ts.map +1 -0
  25. package/dist/types/nodeSpecs/Leaf.d.ts +20 -0
  26. package/dist/types/nodeSpecs/Leaf.d.ts.map +1 -0
  27. package/dist/types/nodeSpecs/RawNodeRepresentation.d.ts +2 -0
  28. package/dist/types/nodeSpecs/RawNodeRepresentation.d.ts.map +1 -0
  29. package/dist/types/nodeSpecs/index.d.ts +6 -0
  30. package/dist/types/nodeSpecs/index.d.ts.map +1 -0
  31. package/dist/types/nodeSpecs/types/ChildrenRepresentationReducer.d.ts +2 -0
  32. package/dist/types/nodeSpecs/types/ChildrenRepresentationReducer.d.ts.map +1 -0
  33. package/dist/types/nodeSpecs/types/ConstrainedLeafRepresentationFactory.d.ts +3 -0
  34. package/dist/types/nodeSpecs/types/ConstrainedLeafRepresentationFactory.d.ts.map +1 -0
  35. package/dist/types/nodeSpecs/types/DeclarationSiteNodeRepresentationFactory.d.ts +2 -0
  36. package/dist/types/nodeSpecs/types/DeclarationSiteNodeRepresentationFactory.d.ts.map +1 -0
  37. package/dist/types/nodeSpecs/types/RepresentationFactorySite.d.ts +2 -0
  38. package/dist/types/nodeSpecs/types/RepresentationFactorySite.d.ts.map +1 -0
  39. package/dist/types/nodeSpecs/types/StaticContextFactory.d.ts +2 -0
  40. package/dist/types/nodeSpecs/types/StaticContextFactory.d.ts.map +1 -0
  41. package/dist/types/nodeSpecs/types/SyntheticChildrenFactory.d.ts +3 -0
  42. package/dist/types/nodeSpecs/types/SyntheticChildrenFactory.d.ts.map +1 -0
  43. package/dist/types/nodeSpecs/types/UnconstrainedLeafRepresentationFactory.d.ts +3 -0
  44. package/dist/types/nodeSpecs/types/UnconstrainedLeafRepresentationFactory.d.ts.map +1 -0
  45. package/dist/types/nodeSpecs/types/UseSiteBranchNodeRepresentationFactory.d.ts +3 -0
  46. package/dist/types/nodeSpecs/types/UseSiteBranchNodeRepresentationFactory.d.ts.map +1 -0
  47. package/dist/types/nodeSpecs/types/ValidFactoryName.d.ts +2 -0
  48. package/dist/types/nodeSpecs/types/ValidFactoryName.d.ts.map +1 -0
  49. package/dist/types/nodeSpecs/types/index.d.ts +10 -0
  50. package/dist/types/nodeSpecs/types/index.d.ts.map +1 -0
  51. package/dist/types/tsconfig.tsbuildinfo +1 -0
  52. package/package.json +4 -5
  53. package/src/BranchNodeList.ts +10 -0
  54. package/src/ChildrenAnalyzer.ts +250 -0
  55. package/src/ChildrenAnalyzerError.ts +1 -0
  56. package/src/ChildrenAnalyzerOptions.ts +12 -0
  57. package/src/ErrorMessageFactory.ts +5 -0
  58. package/src/LeafList.ts +8 -0
  59. package/src/assertNever.ts +3 -0
  60. package/src/helpers/getErrorMessage.ts +10 -0
  61. package/src/helpers/index.ts +1 -0
  62. package/src/index.ts +5 -0
  63. package/src/nodeSpecs/BranchNode.ts +103 -0
  64. package/src/nodeSpecs/BranchNodeOptions.ts +4 -0
  65. package/src/nodeSpecs/Leaf.ts +59 -0
  66. package/src/nodeSpecs/RawNodeRepresentation.ts +5 -0
  67. package/src/nodeSpecs/index.ts +6 -0
  68. package/src/nodeSpecs/types/ChildrenRepresentationReducer.ts +3 -0
  69. package/src/nodeSpecs/types/ConstrainedLeafRepresentationFactory.ts +6 -0
  70. package/src/nodeSpecs/types/DeclarationSiteNodeRepresentationFactory.ts +10 -0
  71. package/src/nodeSpecs/types/RepresentationFactorySite.ts +1 -0
  72. package/src/nodeSpecs/types/StaticContextFactory.ts +4 -0
  73. package/src/nodeSpecs/types/SyntheticChildrenFactory.ts +6 -0
  74. package/src/nodeSpecs/types/UnconstrainedLeafRepresentationFactory.ts +6 -0
  75. package/src/nodeSpecs/types/UseSiteBranchNodeRepresentationFactory.ts +12 -0
  76. package/src/nodeSpecs/types/ValidFactoryName.ts +1 -0
  77. package/src/nodeSpecs/types/index.ts +9 -0
  78. package/src/tsconfig.json +6 -0
  79. package/dist/react-multipass-rendering.d.ts +0 -98
@@ -0,0 +1,250 @@
1
+ import type { ElementType, ReactNode } from 'react'
2
+ import { assertNever } from './assertNever'
3
+ import type { BranchNodeList } from './BranchNodeList'
4
+ import { ChildrenAnalyzerError } from './ChildrenAnalyzerError'
5
+ import type { ChildrenAnalyzerOptions } from './ChildrenAnalyzerOptions'
6
+ import { getErrorMessage } from './helpers'
7
+ import type { LeafList } from './LeafList'
8
+ import type {
9
+ DeclarationSiteNodeRepresentationFactory,
10
+ RawNodeRepresentation,
11
+ RepresentationFactorySite,
12
+ StaticContextFactory,
13
+ SyntheticChildrenFactory,
14
+ UnconstrainedLeafRepresentationFactory,
15
+ ValidFactoryName,
16
+ } from './nodeSpecs'
17
+
18
+ export class ChildrenAnalyzer<
19
+ AllLeavesRepresentation = any,
20
+ AllBranchNodesRepresentation = never,
21
+ StaticContext = undefined,
22
+ > {
23
+ private static defaultOptions: ChildrenAnalyzerOptions = {
24
+ ignoreRenderProps: true,
25
+ renderPropsErrorMessage: 'Render props (functions as React component children) are not supported.',
26
+
27
+ ignoreUnhandledNodes: true,
28
+ unhandledNodeErrorMessage: 'Encountered an unknown child.',
29
+
30
+ staticContextFactoryName: 'getStaticContext',
31
+ staticRenderFactoryName: 'staticRender',
32
+ }
33
+
34
+ private readonly leaves: LeafList<AllLeavesRepresentation, StaticContext>
35
+ private readonly branchNodes: BranchNodeList<AllLeavesRepresentation, AllBranchNodesRepresentation, StaticContext>
36
+ private readonly options: ChildrenAnalyzerOptions<StaticContext>
37
+
38
+ public constructor(
39
+ leaves: LeafList<AllLeavesRepresentation, StaticContext>,
40
+ options?: Partial<ChildrenAnalyzerOptions>,
41
+ )
42
+ public constructor(
43
+ leaves: LeafList<AllLeavesRepresentation, StaticContext>,
44
+ branchNodes: BranchNodeList<AllLeavesRepresentation, AllBranchNodesRepresentation, StaticContext>,
45
+ options?: Partial<ChildrenAnalyzerOptions>,
46
+ )
47
+ public constructor(
48
+ leaves: LeafList<AllLeavesRepresentation, StaticContext>,
49
+ decider:
50
+ | Partial<ChildrenAnalyzerOptions>
51
+ | BranchNodeList<AllLeavesRepresentation, AllBranchNodesRepresentation, StaticContext> = [],
52
+ options: Partial<ChildrenAnalyzerOptions> = {},
53
+ ) {
54
+ this.leaves = leaves
55
+
56
+ if (Array.isArray(decider)) {
57
+ this.branchNodes = decider
58
+ } else {
59
+ this.branchNodes = []
60
+ options = decider
61
+ }
62
+ this.options = { ...ChildrenAnalyzer.defaultOptions, ...options }
63
+ }
64
+
65
+ public processChildren(
66
+ children: ReactNode,
67
+ initialStaticContext: StaticContext,
68
+ ): Array<AllLeavesRepresentation | AllBranchNodesRepresentation> {
69
+ const processed = this.processNode(children, initialStaticContext)
70
+
71
+ const rawResult: Array<AllLeavesRepresentation | AllBranchNodesRepresentation | undefined> = Array.isArray(
72
+ processed,
73
+ )
74
+ ? processed
75
+ : [processed]
76
+
77
+ return rawResult.filter(
78
+ (item): item is AllLeavesRepresentation | AllBranchNodesRepresentation => item !== undefined,
79
+ )
80
+ }
81
+
82
+ private processNode(
83
+ node: ReactNode | Function,
84
+ staticContext: StaticContext,
85
+ ): RawNodeRepresentation<AllLeavesRepresentation, AllBranchNodesRepresentation> {
86
+ if (!node || typeof node === 'string' || typeof node === 'number' || typeof node === 'boolean') {
87
+ for (const leaf of this.leaves) {
88
+ const specification = leaf.specification
89
+ if (specification.type === 'useSite') {
90
+ const { ComponentType, factory } = specification
91
+ if (ComponentType === undefined) {
92
+ return factory(node, staticContext)
93
+ }
94
+ }
95
+ }
96
+ if (node === false || node === undefined || node === null) {
97
+ // This adds seamless support for conditionals and such.
98
+ return undefined
99
+ }
100
+ if (!this.options.ignoreUnhandledNodes) {
101
+ throw new ChildrenAnalyzerError(getErrorMessage(this.options.unhandledNodeErrorMessage, node, staticContext))
102
+ }
103
+ return undefined
104
+ }
105
+
106
+ if (typeof node === 'function') {
107
+ if (this.options.ignoreRenderProps) {
108
+ return undefined
109
+ }
110
+ throw new ChildrenAnalyzerError(getErrorMessage(this.options.renderPropsErrorMessage, node, staticContext))
111
+ }
112
+
113
+ if (Array.isArray(node)) {
114
+ let mapped: Array<AllLeavesRepresentation | AllBranchNodesRepresentation> = []
115
+
116
+ for (const subNode of node) {
117
+ const processed = this.processNode(subNode, staticContext)
118
+
119
+ if (processed !== undefined) {
120
+ if (Array.isArray(processed)) {
121
+ mapped = mapped.concat(processed)
122
+ } else {
123
+ mapped.push(processed)
124
+ }
125
+ }
126
+ }
127
+
128
+ return mapped
129
+ }
130
+
131
+ let children: ReactNode = undefined
132
+
133
+ if (!('type' in node)) {
134
+ return this.processNode(children, staticContext)
135
+ }
136
+ children = node.props.children
137
+
138
+ if (typeof node.type === 'symbol') {
139
+ // Fragment, Portal or other non-component
140
+ return this.processNode(children, staticContext)
141
+ }
142
+ // if (typeof node.type === 'string') {
143
+ // // Typically a host component
144
+ // if (!this.options.ignoreUnhandledNodes) {
145
+ // throw new ChildrenAnalyzerError(getErrorMessage(this.options.unhandledNodeErrorMessage, node, staticContext))
146
+ // }
147
+ // return this.processNode(children, staticContext)
148
+ // }
149
+
150
+ // Component, PureComponent, FunctionComponent
151
+
152
+ const treeNode = node.type as ElementType &
153
+ {
154
+ [staticMethod in ValidFactoryName]:
155
+ | StaticContextFactory<any, StaticContext>
156
+ | SyntheticChildrenFactory<any, StaticContext>
157
+ | UnconstrainedLeafRepresentationFactory<any, AllLeavesRepresentation, StaticContext>
158
+ | DeclarationSiteNodeRepresentationFactory<any, unknown, AllBranchNodesRepresentation, StaticContext>
159
+ }
160
+
161
+ if (typeof treeNode !== 'string') {
162
+ if (this.options.staticContextFactoryName in treeNode) {
163
+ const staticContextFactory = treeNode[this.options.staticContextFactoryName] as StaticContextFactory<
164
+ any,
165
+ StaticContext
166
+ >
167
+ staticContext = staticContextFactory(node.props, staticContext)
168
+ }
169
+
170
+ if (this.options.staticRenderFactoryName in treeNode) {
171
+ const factory = treeNode[this.options.staticRenderFactoryName] as SyntheticChildrenFactory<any, StaticContext>
172
+ children = factory(node.props, staticContext)
173
+ }
174
+ }
175
+
176
+ for (const leaf of this.leaves) {
177
+ const specification = leaf.specification
178
+ switch (specification.type) {
179
+ case 'declarationSite': {
180
+ const { factoryMethodName } = specification
181
+
182
+ if (typeof treeNode !== 'string' && factoryMethodName in treeNode) {
183
+ const factory = treeNode[factoryMethodName] as UnconstrainedLeafRepresentationFactory<
184
+ any,
185
+ AllBranchNodesRepresentation | AllLeavesRepresentation,
186
+ StaticContext
187
+ >
188
+ return factory(node.props, staticContext)
189
+ }
190
+ break
191
+ }
192
+ case 'useSite': {
193
+ const { ComponentType, factory } = specification
194
+ if (ComponentType === undefined || node.type === ComponentType) {
195
+ return factory(node, staticContext)
196
+ }
197
+ break
198
+ }
199
+ default:
200
+ return assertNever(specification)
201
+ }
202
+ }
203
+
204
+ const processedChildren = this.processNode(children, staticContext)
205
+
206
+ for (const branchNode of this.branchNodes) {
207
+ const specification = branchNode.specification
208
+ switch (specification.type) {
209
+ case 'declarationSite': {
210
+ const { factoryMethodName, childrenRepresentationReducer } = specification
211
+
212
+ if (typeof treeNode !== 'string' && factoryMethodName in treeNode) {
213
+ if (processedChildren === undefined && !branchNode.options.childrenAreOptional) {
214
+ throw new ChildrenAnalyzerError(branchNode.options.childrenAbsentErrorMessage)
215
+ }
216
+ const factory = treeNode[factoryMethodName] as DeclarationSiteNodeRepresentationFactory<
217
+ any,
218
+ unknown,
219
+ AllBranchNodesRepresentation | AllLeavesRepresentation,
220
+ StaticContext
221
+ >
222
+ return factory(node.props, childrenRepresentationReducer(processedChildren), staticContext)
223
+ }
224
+ break
225
+ }
226
+ case 'useSite': {
227
+ const { factory, ComponentType } = specification
228
+ if (ComponentType === undefined || node.type === ComponentType) {
229
+ if (processedChildren === undefined && !branchNode.options.childrenAreOptional) {
230
+ throw new ChildrenAnalyzerError(branchNode.options.childrenAbsentErrorMessage)
231
+ }
232
+ return factory(node, processedChildren, staticContext)
233
+ }
234
+ break
235
+ }
236
+ default:
237
+ return assertNever(specification)
238
+ }
239
+ }
240
+
241
+ if (
242
+ !this.options.ignoreUnhandledNodes &&
243
+ !(typeof treeNode !== 'string' && this.options.staticRenderFactoryName in treeNode)
244
+ ) {
245
+ throw new ChildrenAnalyzerError(getErrorMessage(this.options.unhandledNodeErrorMessage, node, staticContext))
246
+ }
247
+
248
+ return processedChildren
249
+ }
250
+ }
@@ -0,0 +1 @@
1
+ export class ChildrenAnalyzerError extends Error {}
@@ -0,0 +1,12 @@
1
+ import type { ErrorMessageFactory } from './ErrorMessageFactory'
2
+
3
+ export interface ChildrenAnalyzerOptions<StaticContext = any> {
4
+ ignoreRenderProps: boolean
5
+ renderPropsErrorMessage: ErrorMessageFactory<StaticContext>
6
+
7
+ ignoreUnhandledNodes: boolean
8
+ unhandledNodeErrorMessage: ErrorMessageFactory<StaticContext>
9
+
10
+ staticContextFactoryName: string
11
+ staticRenderFactoryName: string
12
+ }
@@ -0,0 +1,5 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ export type ErrorMessageFactory<StaticContext = any> =
4
+ | string
5
+ | ((node: ReactNode, staticContext: StaticContext) => string)
@@ -0,0 +1,8 @@
1
+ import type { Leaf, ValidFactoryName } from './nodeSpecs'
2
+
3
+ export type LeafList<RepresentationUnion, StaticContext> = Leaf<
4
+ any,
5
+ StaticContext,
6
+ ValidFactoryName,
7
+ RepresentationUnion
8
+ >[]
@@ -0,0 +1,3 @@
1
+ export const assertNever = (_: never): never => {
2
+ throw new Error()
3
+ }
@@ -0,0 +1,10 @@
1
+ import type { ReactNode } from 'react'
2
+ import type { ErrorMessageFactory } from '../ErrorMessageFactory'
3
+
4
+ export const getErrorMessage = <StaticContext>(
5
+ factory: ErrorMessageFactory<StaticContext>,
6
+ node: ReactNode,
7
+ staticContext: StaticContext,
8
+ ): string => {
9
+ return typeof factory === 'string' ? factory : factory(node, staticContext)
10
+ }
@@ -0,0 +1 @@
1
+ export * from './getErrorMessage'
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './nodeSpecs'
2
+
3
+ export * from './ChildrenAnalyzer'
4
+ export * from './ChildrenAnalyzerError'
5
+ export * from './ChildrenAnalyzerOptions'
@@ -0,0 +1,103 @@
1
+ import type { ElementType } from 'react'
2
+ import { ChildrenAnalyzerError } from '../ChildrenAnalyzerError'
3
+ import type { BranchNodeOptions } from './BranchNodeOptions'
4
+ import type { ChildrenRepresentationReducer, UseSiteBranchNodeRepresentationFactory, ValidFactoryName } from './types'
5
+
6
+ class BranchNode<
7
+ Props extends {} = {},
8
+ StaticContext = undefined,
9
+ FactoryMethodName extends ValidFactoryName = string,
10
+ ChildrenRepresentation = any,
11
+ ReducedChildrenRepresentation = any,
12
+ Representation = any,
13
+ > {
14
+ private static defaultOptions: BranchNodeOptions = {
15
+ childrenAreOptional: false,
16
+ childrenAbsentErrorMessage: 'Component must have children!',
17
+ }
18
+
19
+ public readonly specification: BranchNode.Specification<
20
+ Props,
21
+ StaticContext,
22
+ FactoryMethodName,
23
+ ChildrenRepresentation,
24
+ ReducedChildrenRepresentation,
25
+ Representation
26
+ >
27
+
28
+ public readonly options: BranchNodeOptions
29
+
30
+ public constructor(
31
+ factoryMethodName: FactoryMethodName,
32
+ childrenRepresentationReducer: ChildrenRepresentationReducer<ChildrenRepresentation, ReducedChildrenRepresentation>,
33
+ options?: Partial<BranchNodeOptions>,
34
+ )
35
+ public constructor(
36
+ useSiteFactory: UseSiteBranchNodeRepresentationFactory<
37
+ Props,
38
+ ChildrenRepresentation,
39
+ Representation,
40
+ StaticContext
41
+ >,
42
+ ComponentType?: ElementType<Props>,
43
+ options?: Partial<BranchNodeOptions>,
44
+ )
45
+ public constructor(
46
+ factory:
47
+ | FactoryMethodName
48
+ | UseSiteBranchNodeRepresentationFactory<Props, ChildrenRepresentation, Representation, StaticContext>,
49
+ componentOrReducer?:
50
+ | ChildrenRepresentationReducer<ChildrenRepresentation, ReducedChildrenRepresentation>
51
+ | ElementType<Props>,
52
+ options?: Partial<BranchNodeOptions>,
53
+ ) {
54
+ if (typeof factory !== 'function') {
55
+ this.specification = {
56
+ type: 'declarationSite',
57
+ factoryMethodName: factory,
58
+ childrenRepresentationReducer: componentOrReducer as ChildrenRepresentationReducer<
59
+ ChildrenRepresentation,
60
+ ReducedChildrenRepresentation
61
+ >,
62
+ }
63
+ } else if (typeof factory === 'function') {
64
+ this.specification = {
65
+ type: 'useSite',
66
+ factory,
67
+ ComponentType: componentOrReducer as ElementType<Props>,
68
+ }
69
+ } else {
70
+ throw new ChildrenAnalyzerError('Invalid arguments')
71
+ }
72
+ this.options = {
73
+ ...BranchNode.defaultOptions,
74
+ ...options,
75
+ }
76
+ }
77
+ }
78
+
79
+ namespace BranchNode {
80
+ export type Specification<
81
+ Props extends {} = {},
82
+ StaticContext = any,
83
+ FactoryMethodName extends ValidFactoryName = string,
84
+ ChildrenRepresentation = any,
85
+ ReducedChildrenRepresentation = any,
86
+ Representation = any,
87
+ > =
88
+ | {
89
+ type: 'declarationSite'
90
+ factoryMethodName: FactoryMethodName
91
+ childrenRepresentationReducer: ChildrenRepresentationReducer<
92
+ ChildrenRepresentation,
93
+ ReducedChildrenRepresentation
94
+ >
95
+ }
96
+ | {
97
+ type: 'useSite'
98
+ factory: UseSiteBranchNodeRepresentationFactory<Props, ChildrenRepresentation, Representation, StaticContext>
99
+ ComponentType?: ElementType<Props>
100
+ }
101
+ }
102
+
103
+ export { BranchNode }
@@ -0,0 +1,4 @@
1
+ export interface BranchNodeOptions {
2
+ childrenAreOptional: boolean
3
+ childrenAbsentErrorMessage: string
4
+ }
@@ -0,0 +1,59 @@
1
+ import type { ElementType } from 'react'
2
+ import type {
3
+ ConstrainedLeafRepresentationFactory,
4
+ UnconstrainedLeafRepresentationFactory,
5
+ ValidFactoryName,
6
+ } from './types'
7
+
8
+ class Leaf<
9
+ Props extends {} = {},
10
+ StaticContext = any,
11
+ FactoryMethodName extends ValidFactoryName = string,
12
+ Representation = any,
13
+ > {
14
+ public readonly specification: Leaf.Specification<FactoryMethodName, Representation, Props, StaticContext>
15
+
16
+ public constructor(factoryMethodName: FactoryMethodName)
17
+ public constructor(staticFactory: UnconstrainedLeafRepresentationFactory<Props, Representation, StaticContext>)
18
+ public constructor(
19
+ staticFactory: ConstrainedLeafRepresentationFactory<Props, Representation, StaticContext>,
20
+ ComponentType: ElementType<Props>,
21
+ )
22
+ public constructor(
23
+ factory: FactoryMethodName | UnconstrainedLeafRepresentationFactory<Props, Representation, StaticContext>,
24
+ ComponentType?: ElementType<Props>,
25
+ ) {
26
+ if (typeof factory === 'function') {
27
+ this.specification = {
28
+ type: 'useSite',
29
+ ComponentType,
30
+ factory,
31
+ }
32
+ } else {
33
+ this.specification = {
34
+ type: 'declarationSite',
35
+ factoryMethodName: factory,
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ namespace Leaf {
42
+ export type Specification<
43
+ FactoryMethodName extends ValidFactoryName,
44
+ Representation,
45
+ Props extends {},
46
+ StaticContext,
47
+ > =
48
+ | {
49
+ type: 'declarationSite'
50
+ factoryMethodName: FactoryMethodName
51
+ }
52
+ | {
53
+ type: 'useSite'
54
+ factory: UnconstrainedLeafRepresentationFactory<Props, Representation, StaticContext>
55
+ ComponentType?: ElementType<Props>
56
+ }
57
+ }
58
+
59
+ export { Leaf }
@@ -0,0 +1,5 @@
1
+ export type RawNodeRepresentation<AllLeavesRepresentation, AllBranchNodesRepresentation = AllLeavesRepresentation> =
2
+ | AllLeavesRepresentation
3
+ | AllBranchNodesRepresentation
4
+ | Array<AllLeavesRepresentation | AllBranchNodesRepresentation>
5
+ | undefined
@@ -0,0 +1,6 @@
1
+ export * from './types'
2
+
3
+ export * from './BranchNode'
4
+ export * from './BranchNodeOptions'
5
+ export * from './Leaf'
6
+ export * from './RawNodeRepresentation'
@@ -0,0 +1,3 @@
1
+ export type ChildrenRepresentationReducer<ChildrenRepresentation, ReducedChildrenRepresentation> = (
2
+ childrenRepresentations: ChildrenRepresentation,
3
+ ) => ReducedChildrenRepresentation
@@ -0,0 +1,6 @@
1
+ import type { ReactElement } from 'react'
2
+
3
+ export type ConstrainedLeafRepresentationFactory<Props extends {}, Representation, StaticContext> = (
4
+ node: ReactElement<Props, any>,
5
+ staticContext: StaticContext,
6
+ ) => Representation
@@ -0,0 +1,10 @@
1
+ export type DeclarationSiteNodeRepresentationFactory<
2
+ Props extends {},
3
+ ReducedChildrenRepresentation,
4
+ Representation,
5
+ StaticContext,
6
+ > = (
7
+ props: Props,
8
+ reducedChildrenRepresentation: ReducedChildrenRepresentation,
9
+ staticContext: StaticContext,
10
+ ) => Representation
@@ -0,0 +1 @@
1
+ export type RepresentationFactorySite = 'declarationSite' | 'useSite'
@@ -0,0 +1,4 @@
1
+ export type StaticContextFactory<Props extends {}, StaticContext> = (
2
+ props: Props,
3
+ staticContext: StaticContext,
4
+ ) => StaticContext
@@ -0,0 +1,6 @@
1
+ import type { ReactNode } from 'react'
2
+
3
+ export type SyntheticChildrenFactory<Props extends {}, StaticContext> = (
4
+ props: Props,
5
+ staticContext: StaticContext,
6
+ ) => ReactNode
@@ -0,0 +1,6 @@
1
+ import type { ReactElement, ReactText } from 'react'
2
+
3
+ export type UnconstrainedLeafRepresentationFactory<Props extends {}, Representation, StaticContext> = (
4
+ node: ReactText | ReactElement<Props, any> | boolean | null | undefined | {},
5
+ staticContext: StaticContext,
6
+ ) => Representation
@@ -0,0 +1,12 @@
1
+ import type { ReactElement } from 'react'
2
+
3
+ export type UseSiteBranchNodeRepresentationFactory<
4
+ Props extends {},
5
+ ChildrenRepresentation,
6
+ Representation,
7
+ StaticContext,
8
+ > = (
9
+ node: ReactElement<Props, any>,
10
+ childrenRepresentation: ChildrenRepresentation,
11
+ staticContext: StaticContext,
12
+ ) => Representation
@@ -0,0 +1 @@
1
+ export type ValidFactoryName = string | number
@@ -0,0 +1,9 @@
1
+ export * from './ChildrenRepresentationReducer'
2
+ export * from './ConstrainedLeafRepresentationFactory'
3
+ export * from './DeclarationSiteNodeRepresentationFactory'
4
+ export * from './RepresentationFactorySite'
5
+ export * from './StaticContextFactory'
6
+ export * from './SyntheticChildrenFactory'
7
+ export * from './UnconstrainedLeafRepresentationFactory'
8
+ export * from './UseSiteBranchNodeRepresentationFactory'
9
+ export * from './ValidFactoryName'
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "../tsconfig.settings.json",
3
+ "compilerOptions": {
4
+ "outDir": "../dist/types"
5
+ }
6
+ }