@craft-ts/component 0.7.0-beta.13

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 (190) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +36 -0
  3. package/src/index.d.ts +40 -0
  4. package/src/index.d.ts.map +1 -0
  5. package/src/index.js +38 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/a11y-control.d.ts +58 -0
  8. package/src/lib/a11y-control.d.ts.map +1 -0
  9. package/src/lib/a11y-control.js +74 -0
  10. package/src/lib/a11y-control.js.map +1 -0
  11. package/src/lib/a11y.d.ts +87 -0
  12. package/src/lib/a11y.d.ts.map +1 -0
  13. package/src/lib/a11y.js +96 -0
  14. package/src/lib/a11y.js.map +1 -0
  15. package/src/lib/ai/ai-context-menu.d.ts +140 -0
  16. package/src/lib/ai/ai-context-menu.d.ts.map +1 -0
  17. package/src/lib/ai/ai-context-menu.js +66 -0
  18. package/src/lib/ai/ai-context-menu.js.map +1 -0
  19. package/src/lib/ai/ai-send-dialog.d.ts +1263 -0
  20. package/src/lib/ai/ai-send-dialog.d.ts.map +1 -0
  21. package/src/lib/ai/ai-send-dialog.js +288 -0
  22. package/src/lib/ai/ai-send-dialog.js.map +1 -0
  23. package/src/lib/ai/send-context-to-ai.d.ts +29 -0
  24. package/src/lib/ai/send-context-to-ai.d.ts.map +1 -0
  25. package/src/lib/ai/send-context-to-ai.js +127 -0
  26. package/src/lib/ai/send-context-to-ai.js.map +1 -0
  27. package/src/lib/assert-defined-input.d.ts +26 -0
  28. package/src/lib/assert-defined-input.d.ts.map +1 -0
  29. package/src/lib/assert-defined-input.js +47 -0
  30. package/src/lib/assert-defined-input.js.map +1 -0
  31. package/src/lib/block.d.ts +36 -0
  32. package/src/lib/block.d.ts.map +1 -0
  33. package/src/lib/block.js +55 -0
  34. package/src/lib/block.js.map +1 -0
  35. package/src/lib/bootstrap.d.ts +32 -0
  36. package/src/lib/bootstrap.d.ts.map +1 -0
  37. package/src/lib/bootstrap.js +60 -0
  38. package/src/lib/bootstrap.js.map +1 -0
  39. package/src/lib/bridge.d.ts +56 -0
  40. package/src/lib/bridge.d.ts.map +1 -0
  41. package/src/lib/bridge.js +81 -0
  42. package/src/lib/bridge.js.map +1 -0
  43. package/src/lib/component.d.ts +46 -0
  44. package/src/lib/component.d.ts.map +1 -0
  45. package/src/lib/component.js +118 -0
  46. package/src/lib/component.js.map +1 -0
  47. package/src/lib/composition.d.ts +17 -0
  48. package/src/lib/composition.d.ts.map +1 -0
  49. package/src/lib/composition.js +28 -0
  50. package/src/lib/composition.js.map +1 -0
  51. package/src/lib/craft-defaults.d.ts +2 -0
  52. package/src/lib/craft-defaults.d.ts.map +1 -0
  53. package/src/lib/craft-defaults.js +41 -0
  54. package/src/lib/craft-defaults.js.map +1 -0
  55. package/src/lib/craft-host-tokens.d.ts +6 -0
  56. package/src/lib/craft-host-tokens.d.ts.map +1 -0
  57. package/src/lib/craft-host-tokens.js +7 -0
  58. package/src/lib/craft-host-tokens.js.map +1 -0
  59. package/src/lib/craft-router-outlet.d.ts +15 -0
  60. package/src/lib/craft-router-outlet.d.ts.map +1 -0
  61. package/src/lib/craft-router-outlet.js +10 -0
  62. package/src/lib/craft-router-outlet.js.map +1 -0
  63. package/src/lib/css-vars.d.ts +31 -0
  64. package/src/lib/css-vars.d.ts.map +1 -0
  65. package/src/lib/css-vars.js +43 -0
  66. package/src/lib/css-vars.js.map +1 -0
  67. package/src/lib/css-vars.type.d.ts +151 -0
  68. package/src/lib/css-vars.type.d.ts.map +1 -0
  69. package/src/lib/css-vars.type.js +1 -0
  70. package/src/lib/css-vars.type.js.map +1 -0
  71. package/src/lib/defer.d.ts +31 -0
  72. package/src/lib/defer.d.ts.map +1 -0
  73. package/src/lib/defer.js +19 -0
  74. package/src/lib/defer.js.map +1 -0
  75. package/src/lib/directive.d.ts +9 -0
  76. package/src/lib/directive.d.ts.map +1 -0
  77. package/src/lib/directive.js +31 -0
  78. package/src/lib/directive.js.map +1 -0
  79. package/src/lib/each-scheduling.d.ts +59 -0
  80. package/src/lib/each-scheduling.d.ts.map +1 -0
  81. package/src/lib/each-scheduling.js +120 -0
  82. package/src/lib/each-scheduling.js.map +1 -0
  83. package/src/lib/each.d.ts +29 -0
  84. package/src/lib/each.d.ts.map +1 -0
  85. package/src/lib/each.js +23 -0
  86. package/src/lib/each.js.map +1 -0
  87. package/src/lib/factory-runtime.d.ts +5 -0
  88. package/src/lib/factory-runtime.d.ts.map +1 -0
  89. package/src/lib/factory-runtime.js +26 -0
  90. package/src/lib/factory-runtime.js.map +1 -0
  91. package/src/lib/field-exception-block.d.ts +96 -0
  92. package/src/lib/field-exception-block.d.ts.map +1 -0
  93. package/src/lib/field-exception-block.js +44 -0
  94. package/src/lib/field-exception-block.js.map +1 -0
  95. package/src/lib/host-runtime.d.ts +60 -0
  96. package/src/lib/host-runtime.d.ts.map +1 -0
  97. package/src/lib/host-runtime.js +16 -0
  98. package/src/lib/host-runtime.js.map +1 -0
  99. package/src/lib/hydrate.d.ts +15 -0
  100. package/src/lib/hydrate.d.ts.map +1 -0
  101. package/src/lib/hydrate.js +79 -0
  102. package/src/lib/hydrate.js.map +1 -0
  103. package/src/lib/hyperscript.d.ts +148 -0
  104. package/src/lib/hyperscript.d.ts.map +1 -0
  105. package/src/lib/hyperscript.js +96 -0
  106. package/src/lib/hyperscript.js.map +1 -0
  107. package/src/lib/if-block.d.ts +8 -0
  108. package/src/lib/if-block.d.ts.map +1 -0
  109. package/src/lib/if-block.js +16 -0
  110. package/src/lib/if-block.js.map +1 -0
  111. package/src/lib/locator.d.ts +170 -0
  112. package/src/lib/locator.d.ts.map +1 -0
  113. package/src/lib/locator.js +151 -0
  114. package/src/lib/locator.js.map +1 -0
  115. package/src/lib/match-block.d.ts +38 -0
  116. package/src/lib/match-block.d.ts.map +1 -0
  117. package/src/lib/match-block.js +29 -0
  118. package/src/lib/match-block.js.map +1 -0
  119. package/src/lib/pending-block.d.ts +125 -0
  120. package/src/lib/pending-block.d.ts.map +1 -0
  121. package/src/lib/pending-block.js +48 -0
  122. package/src/lib/pending-block.js.map +1 -0
  123. package/src/lib/project.d.ts +19 -0
  124. package/src/lib/project.d.ts.map +1 -0
  125. package/src/lib/project.js +56 -0
  126. package/src/lib/project.js.map +1 -0
  127. package/src/lib/render/hydration-metadata.d.ts +3 -0
  128. package/src/lib/render/hydration-metadata.d.ts.map +1 -0
  129. package/src/lib/render/hydration-metadata.js +8 -0
  130. package/src/lib/render/hydration-metadata.js.map +1 -0
  131. package/src/lib/render/hydration.d.ts +24 -0
  132. package/src/lib/render/hydration.d.ts.map +1 -0
  133. package/src/lib/render/hydration.js +181 -0
  134. package/src/lib/render/hydration.js.map +1 -0
  135. package/src/lib/render/interpreter.d.ts +32 -0
  136. package/src/lib/render/interpreter.d.ts.map +1 -0
  137. package/src/lib/render/interpreter.js +3588 -0
  138. package/src/lib/render/interpreter.js.map +1 -0
  139. package/src/lib/render/server-style-collector.d.ts +6 -0
  140. package/src/lib/render/server-style-collector.d.ts.map +1 -0
  141. package/src/lib/render/server-style-collector.js +23 -0
  142. package/src/lib/render/server-style-collector.js.map +1 -0
  143. package/src/lib/render/ssr-coordinator.d.ts +20 -0
  144. package/src/lib/render/ssr-coordinator.d.ts.map +1 -0
  145. package/src/lib/render/ssr-coordinator.js +99 -0
  146. package/src/lib/render/ssr-coordinator.js.map +1 -0
  147. package/src/lib/render/string-dom.d.ts +9 -0
  148. package/src/lib/render/string-dom.d.ts.map +1 -0
  149. package/src/lib/render/string-dom.js +377 -0
  150. package/src/lib/render/string-dom.js.map +1 -0
  151. package/src/lib/render/style-registry.d.ts +14 -0
  152. package/src/lib/render/style-registry.d.ts.map +1 -0
  153. package/src/lib/render/style-registry.js +79 -0
  154. package/src/lib/render/style-registry.js.map +1 -0
  155. package/src/lib/render/style-scope.d.ts +30 -0
  156. package/src/lib/render/style-scope.d.ts.map +1 -0
  157. package/src/lib/render/style-scope.js +261 -0
  158. package/src/lib/render/style-scope.js.map +1 -0
  159. package/src/lib/render/vnode.d.ts +330 -0
  160. package/src/lib/render/vnode.d.ts.map +1 -0
  161. package/src/lib/render/vnode.js +293 -0
  162. package/src/lib/render/vnode.js.map +1 -0
  163. package/src/lib/server-render.d.ts +34 -0
  164. package/src/lib/server-render.d.ts.map +1 -0
  165. package/src/lib/server-render.js +84 -0
  166. package/src/lib/server-render.js.map +1 -0
  167. package/src/lib/start.d.ts +13 -0
  168. package/src/lib/start.d.ts.map +1 -0
  169. package/src/lib/start.js +20 -0
  170. package/src/lib/start.js.map +1 -0
  171. package/src/lib/template-contract.d.ts +347 -0
  172. package/src/lib/template-contract.d.ts.map +1 -0
  173. package/src/lib/template-contract.js +1 -0
  174. package/src/lib/template-contract.js.map +1 -0
  175. package/src/lib/template.d.ts +11 -0
  176. package/src/lib/template.d.ts.map +1 -0
  177. package/src/lib/template.js +21 -0
  178. package/src/lib/template.js.map +1 -0
  179. package/src/lib/testing.d.ts +157 -0
  180. package/src/lib/testing.d.ts.map +1 -0
  181. package/src/lib/testing.js +416 -0
  182. package/src/lib/testing.js.map +1 -0
  183. package/src/lib/types.d.ts +442 -0
  184. package/src/lib/types.d.ts.map +1 -0
  185. package/src/lib/types.js +22 -0
  186. package/src/lib/types.js.map +1 -0
  187. package/testing/public-api.d.ts +3 -0
  188. package/testing/public-api.d.ts.map +1 -0
  189. package/testing/public-api.js +3 -0
  190. package/testing/public-api.js.map +1 -0
@@ -0,0 +1,170 @@
1
+ import type { CraftComponent, ComponentTemplateOf } from './types';
2
+ import { YIELDABLE_VALUE } from '@craft-ts/core';
3
+ import type { CraftDirectiveNode, ElementNodeBase, CraftNodeChildren } from './render/vnode';
4
+ type IsAny<Value> = 0 extends 1 & Value ? true : false;
5
+ type LiteralString<Value> = Value extends string ? string extends Value ? never : Value : never;
6
+ type ClassTokens<Value> = [Value] extends [string] ? LiteralString<Value> extends infer Text extends string ? Text extends '' ? never : Text extends `${infer Head} ${infer Tail}` ? Head extends '' ? ClassTokens<Tail> : Head | ClassTokens<Tail> : Text : never : [Value] extends [readonly unknown[]] ? ClassTokens<Value[number]> : [Value] extends [Readonly<Record<string, boolean | null | undefined>>] ? string extends keyof Value ? never : Extract<keyof Value, string> : never;
7
+ type StaticAttributeValue<Value> = [Value] extends [string] ? string extends Value ? never : Value : [Value] extends [number] ? number extends Value ? never : Value : [Value] extends [boolean] ? boolean extends Value ? never : Value : never;
8
+ type StaticDirectAttributes<Props> = {
9
+ [Key in keyof Props & string as Key extends `data-${string}` | `aria-${string}` ? StaticAttributeValue<Props[Key]> extends never ? never : Key : never]: StaticAttributeValue<Props[Key]>;
10
+ };
11
+ type StaticNestedAttributes<Props> = Props extends {
12
+ readonly attrs?: infer Attributes;
13
+ } ? Attributes extends object ? {
14
+ [Key in keyof Attributes & string as StaticAttributeValue<Attributes[Key]> extends never ? never : Key]: StaticAttributeValue<Attributes[Key]>;
15
+ } : {} : {};
16
+ export type StaticLocatorCriteria<Props> = (Props extends {
17
+ readonly class?: infer Class;
18
+ } ? [ClassTokens<Class>] extends [never] ? {} : {
19
+ readonly class: ClassTokens<Class>;
20
+ } : {}) & StaticDirectAttributes<Props> & StaticNestedAttributes<Props>;
21
+ type LocatorCandidate<Tag extends keyof HTMLElementTagNameMap, Criteria extends object, Optional extends boolean, Repeated extends boolean> = {
22
+ readonly tag: Tag;
23
+ readonly criteria: Criteria;
24
+ readonly optional: Optional;
25
+ readonly repeated: Repeated;
26
+ };
27
+ type DirectContentNames<Value> = Value extends unknown ? Value extends {
28
+ readonly [YIELDABLE_VALUE]: infer Name extends string;
29
+ } ? LiteralString<Name> : Value extends readonly (infer Item)[] ? DirectContentNames<Item> : never : never;
30
+ type ContentLocatorCandidates<Tag extends keyof HTMLElementTagNameMap, Props, Children, Optional extends boolean, Repeated extends boolean> = DirectContentNames<Children> extends infer Name extends string ? LocatorCandidate<Tag, StaticLocatorCriteria<Props> & {
31
+ readonly content: Name;
32
+ }, Optional, Repeated> : never;
33
+ type VisitContentNode<Node, Optional extends boolean, Repeated extends boolean, Seen extends readonly unknown[] = [], Depth extends readonly unknown[] = []> = Depth['length'] extends 8 ? never : IsAny<Node> extends true ? never : Node extends readonly (infer Child)[] ? VisitContentNode<Child, Optional, Repeated, Seen, [...Depth, unknown]> : Node extends ElementNodeBase<any, infer Tag extends keyof HTMLElementTagNameMap, infer Props, infer Children> ? ContentLocatorCandidates<Tag, Props, Children, Optional, Repeated> | VisitContentNode<Children, Optional, Repeated, Seen, [
34
+ ...Depth,
35
+ unknown
36
+ ]> : Node extends {
37
+ readonly kind: 'component';
38
+ readonly component: infer Component;
39
+ } ? Component extends CraftComponent<any, any> ? Component extends Seen[number] ? never : VisitContentNode<ReturnType<ComponentTemplateOf<Component>>, Optional, Repeated, [
40
+ ...Seen,
41
+ Component
42
+ ], [
43
+ ...Depth,
44
+ unknown
45
+ ]> : never : Node extends CraftDirectiveNode<any> ? VisitContentNode<Node['node'], Optional, Repeated, Seen, [
46
+ ...Depth,
47
+ unknown
48
+ ]> : Node extends {
49
+ readonly kind: 'if';
50
+ readonly whenTrue: () => infer TrueChildren;
51
+ readonly whenFalse?: () => infer FalseChildren;
52
+ } ? VisitContentNode<TrueChildren | FalseChildren, true, Repeated, Seen, [
53
+ ...Depth,
54
+ unknown
55
+ ]> : Node extends {
56
+ readonly kind: 'each';
57
+ readonly itemTemplate: (...args: any[]) => infer ItemChildren;
58
+ readonly empty?: () => infer EmptyChildren;
59
+ } ? VisitContentNode<ItemChildren | EmptyChildren, true, true, Seen, [
60
+ ...Depth,
61
+ unknown
62
+ ]> : Node extends {
63
+ readonly kind: 'defer';
64
+ readonly resolve: (...args: any[]) => infer Resolved;
65
+ } ? VisitContentNode<Resolved, true, Repeated, Seen, [
66
+ ...Depth,
67
+ unknown
68
+ ]> : never;
69
+ type ContentLocatorCandidatesOfTemplate<Template> = VisitContentNode<Template extends (...args: any[]) => infer Output ? Output : never, false, false>;
70
+ type ContentLocatorNames<Template, Tag> = ContentLocatorCandidatesOfTemplate<Template> extends infer Candidate ? Candidate extends LocatorCandidate<any, infer Criteria, any, any> ? Candidate['tag'] extends Tag ? Criteria extends {
71
+ readonly content: infer Name extends string;
72
+ } ? Name : never : never : never : never;
73
+ export type LocatorContentNamesFor<Component extends CraftComponent<any, any>, Tag extends keyof HTMLElementTagNameMap> = ContentLocatorNames<ComponentTemplateOf<Component>, Tag>;
74
+ type VisitOptionalTag<Node, Tag extends keyof HTMLElementTagNameMap, Optional extends boolean = false, Seen extends readonly unknown[] = [], Depth extends readonly unknown[] = []> = Depth['length'] extends 8 ? false : IsAny<Node> extends true ? false : Node extends readonly (infer Child)[] ? VisitOptionalTag<Child, Tag, Optional, Seen, [...Depth, unknown]> : Node extends ElementNodeBase<any, infer ActualTag extends keyof HTMLElementTagNameMap, any, infer Children> ? (ActualTag extends Tag ? Optional : false) | VisitOptionalTag<Children, Tag, Optional, Seen, [...Depth, unknown]> : Node extends {
75
+ readonly kind: 'component';
76
+ readonly component: infer Component;
77
+ } ? Component extends CraftComponent<any, any> ? Component extends Seen[number] ? false : VisitOptionalTag<ReturnType<ComponentTemplateOf<Component>>, Tag, Optional, [
78
+ ...Seen,
79
+ Component
80
+ ], [
81
+ ...Depth,
82
+ unknown
83
+ ]> : false : Node extends CraftDirectiveNode<any> ? VisitOptionalTag<Node['node'], Tag, Optional, Seen, [
84
+ ...Depth,
85
+ unknown
86
+ ]> : Node extends {
87
+ readonly kind: 'if';
88
+ readonly whenTrue: () => infer TrueChildren;
89
+ readonly whenFalse?: () => infer FalseChildren;
90
+ } ? VisitOptionalTag<TrueChildren | FalseChildren, Tag, true, Seen, [
91
+ ...Depth,
92
+ unknown
93
+ ]> : Node extends {
94
+ readonly kind: 'each';
95
+ readonly itemTemplate: (...args: any[]) => infer ItemChildren;
96
+ readonly empty?: () => infer EmptyChildren;
97
+ } ? VisitOptionalTag<ItemChildren | EmptyChildren, Tag, true, Seen, [
98
+ ...Depth,
99
+ unknown
100
+ ]> : Node extends {
101
+ readonly kind: 'defer';
102
+ readonly resolve: (...args: any[]) => infer Resolved;
103
+ } ? VisitOptionalTag<Resolved, Tag, true, Seen, [
104
+ ...Depth,
105
+ unknown
106
+ ]> : false;
107
+ type TemplateHasOptionalTag<Template, Tag extends keyof HTMLElementTagNameMap> = true extends VisitOptionalTag<Template extends (...args: any[]) => infer Output ? Output : never, Tag> ? true : false;
108
+ type NextDepth<Depth extends readonly unknown[]> = [...Depth, unknown];
109
+ type VisitChildren<Children, Depth extends readonly unknown[], Optional extends boolean, Repeated extends boolean, Seen extends readonly unknown[]> = Children extends readonly (infer Child)[] ? VisitNode<Child, NextDepth<Depth>, Optional, Repeated, Seen> : VisitNode<Children, Depth, Optional, Repeated, Seen>;
110
+ type VisitComponent<Component, Depth extends readonly unknown[], Optional extends boolean, Repeated extends boolean, Seen extends readonly unknown[]> = IsAny<Component> extends true ? never : Component extends CraftComponent<any, any> ? VisitChildren<ReturnType<ComponentTemplateOf<Component>>, NextDepth<Depth>, Optional, Repeated, Seen> : never;
111
+ type VisitNode<Node, Depth extends readonly unknown[], Optional extends boolean, Repeated extends boolean, Seen extends readonly unknown[]> = Depth['length'] extends 2 ? never : IsAny<Node> extends true ? never : Node extends ElementNodeBase<any, infer Tag extends keyof HTMLElementTagNameMap, infer Props, infer Children> ? LocatorCandidate<Tag, StaticLocatorCriteria<Props>, Optional, Repeated> | VisitChildren<Children, NextDepth<Depth>, Optional, Repeated, Seen> : Node extends {
112
+ readonly kind: 'component';
113
+ readonly component: infer Component;
114
+ } ? VisitComponent<Component, Depth, Optional, Repeated, Seen> : Node extends CraftDirectiveNode<any> ? VisitNode<Node['node'], NextDepth<Depth>, Optional, Repeated, Seen> : Node extends {
115
+ readonly kind: 'if';
116
+ readonly whenTrue: () => infer TrueChildren;
117
+ readonly whenFalse?: () => infer FalseChildren;
118
+ } ? VisitChildren<TrueChildren | FalseChildren, NextDepth<Depth>, true, Repeated, Seen> : Node extends {
119
+ readonly kind: 'each';
120
+ readonly itemTemplate: (...args: any[]) => infer ItemChildren;
121
+ readonly empty?: () => infer EmptyChildren;
122
+ } ? VisitChildren<ItemChildren | EmptyChildren, NextDepth<Depth>, true, true, Seen> : Node extends {
123
+ readonly kind: 'defer';
124
+ readonly resolve: (...args: any[]) => infer Resolved;
125
+ } ? VisitChildren<Resolved, NextDepth<Depth>, true, Repeated, Seen> : never;
126
+ export type TemplateLocatorCandidates<Component extends CraftComponent<any, any>> = VisitNode<ReturnType<ComponentTemplateOf<Component>>, [
127
+ ], false, false, [
128
+ ]>;
129
+ export type LocatorCriteriaFor<Component extends CraftComponent<any, any>, Tag extends keyof HTMLElementTagNameMap> = LocatorCriteria & {
130
+ readonly content?: ContentLocatorNames<ComponentTemplateOf<Component>, Tag>;
131
+ };
132
+ type CriteriaMatches<Available, Wanted> = Wanted extends Partial<Available> ? true : false;
133
+ type MatchingCandidates<Candidates, Tag, Criteria> = Candidates extends LocatorCandidate<infer CandidateTag, infer Available, any, any> ? CandidateTag extends Tag ? CriteriaMatches<Available, Criteria> extends true ? Candidates : never : never : never;
134
+ type IsUnion<Value, Whole = Value> = Value extends any ? [Whole] extends [Value] ? false : true : never;
135
+ type HasRepeated<Candidates> = Extract<Candidates, {
136
+ readonly repeated: true;
137
+ }> extends never ? false : true;
138
+ type HasMultiple<Candidates> = IsUnion<Candidates> extends true ? true : false;
139
+ type LocatorIsValid<Candidates> = [Candidates] extends [never] ? false : HasRepeated<Candidates> extends true ? false : HasMultiple<Candidates> extends true ? false : true;
140
+ type LocatorOptional<Candidates> = Extract<Candidates, {
141
+ readonly optional: true;
142
+ }> extends never ? false : true;
143
+ export type CraftLocatorResult<Tag extends keyof HTMLElementTagNameMap, Candidates> = MaybeDefined<HTMLElementTagNameMap[Tag], LocatorOptional<Candidates>>;
144
+ export type MaybeDefined<Value, Optional extends boolean = true> = Optional extends true ? Value | undefined : Value;
145
+ export type LocatorCriteriaValidation<Component extends CraftComponent<any, any>, Tag extends keyof HTMLElementTagNameMap, Criteria> = MatchingCandidates<TemplateLocatorCandidates<Component> | ContentLocatorCandidatesOfTemplate<ComponentTemplateOf<Component>>, Tag, Criteria> extends infer Candidates ? LocatorIsValid<Candidates> extends true ? unknown : {
146
+ readonly 'locator must identify exactly one static element': never;
147
+ } : never;
148
+ export type LocatorCriteria = {
149
+ readonly class?: string;
150
+ readonly [dataAttribute: `data-${string}`]: string | undefined;
151
+ readonly [ariaAttribute: `aria-${string}`]: string | undefined;
152
+ };
153
+ type CraftTemplateLocatorApiForTemplate<Template> = {
154
+ locator<const Tag extends keyof HTMLElementTagNameMap, const Criteria extends LocatorCriteria>(tag: Tag, criteria: Criteria extends {
155
+ readonly content: unknown;
156
+ } ? never : Criteria): MaybeDefined<HTMLElementTagNameMap[Tag], TemplateHasOptionalTag<Template, Tag>>;
157
+ locator<const Tag extends keyof HTMLElementTagNameMap, const Content extends string>(tag: Tag, criteria: LocatorCriteria & {
158
+ readonly content: Content;
159
+ } & (Content extends ContentLocatorNames<Template, Tag> ? unknown : {
160
+ readonly 'content brand is not rendered by this template': never;
161
+ })): MaybeDefined<HTMLElementTagNameMap[Tag], TemplateHasOptionalTag<Template, Tag>>;
162
+ };
163
+ export type CraftTemplateLocatorApi<Component extends CraftComponent<any, any>> = CraftTemplateLocatorApiForTemplate<ComponentTemplateOf<Component>>;
164
+ export type RuntimeLocatorCriteria = Readonly<Record<string, unknown>>;
165
+ /** Runtime marker for branded values rendered directly as element children. */
166
+ export declare const CRAFT_LOCATOR_CONTENT_NAMES: unique symbol;
167
+ export declare function directCraftContentNames(children: CraftNodeChildren): readonly string[];
168
+ export declare function findCraftTemplateLocator(host: Element, template: CraftNodeChildren, tag: string, criteria: RuntimeLocatorCriteria): Element | undefined;
169
+ export {};
170
+ //# sourceMappingURL=locator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locator.d.ts","sourceRoot":"","sources":["../../../../../libs/component/src/lib/locator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,151 @@
1
+ import { YIELDABLE_VALUE } from '@craft-ts/core';
2
+ /** Runtime marker for branded values rendered directly as element children. */
3
+ export const CRAFT_LOCATOR_CONTENT_NAMES = Symbol('craft-locator-content-names');
4
+ export function directCraftContentNames(children) {
5
+ const names = new Set();
6
+ const visit = (child) => {
7
+ if (Array.isArray(child)) {
8
+ child.forEach(visit);
9
+ return;
10
+ }
11
+ if ((typeof child === 'function' ||
12
+ (typeof child === 'object' && child !== null)) &&
13
+ YIELDABLE_VALUE in child) {
14
+ const name = child[YIELDABLE_VALUE];
15
+ if (typeof name === 'string')
16
+ names.add(name);
17
+ }
18
+ };
19
+ visit(children);
20
+ return [...names];
21
+ }
22
+ function runtimeChildren(children) {
23
+ const result = [];
24
+ const visit = (child) => {
25
+ if (Array.isArray(child)) {
26
+ child.forEach(visit);
27
+ }
28
+ else if (child !== null &&
29
+ child !== undefined &&
30
+ typeof child === 'object' &&
31
+ 'kind' in child) {
32
+ result.push(child);
33
+ }
34
+ };
35
+ visit(children);
36
+ return result;
37
+ }
38
+ function runtimeClassTokens(value) {
39
+ if (typeof value === 'string')
40
+ return value.split(/\s+/).filter(Boolean);
41
+ if (Array.isArray(value))
42
+ return value.flatMap(runtimeClassTokens);
43
+ if (typeof value === 'object' && value !== null) {
44
+ return Object.entries(value)
45
+ .filter(([, enabled]) => enabled)
46
+ .map(([name]) => name);
47
+ }
48
+ return [];
49
+ }
50
+ function runtimeAttributeValue(props, key) {
51
+ if (key in props && key !== 'attrs')
52
+ return props[key];
53
+ const attrs = props['attrs'];
54
+ return typeof attrs === 'object' && attrs !== null
55
+ ? attrs[key]
56
+ : undefined;
57
+ }
58
+ function runtimeCriteriaMatch(props, criteria, children) {
59
+ return Object.entries(criteria).every(([key, expected]) => {
60
+ if (key === 'class') {
61
+ return runtimeClassTokens(props[key]).includes(String(expected));
62
+ }
63
+ if (key === 'content') {
64
+ return directCraftContentNames(children ?? []).includes(String(expected));
65
+ }
66
+ const actual = runtimeAttributeValue(props, key);
67
+ if (actual === null || actual === undefined || actual === false) {
68
+ return false;
69
+ }
70
+ return (actual === true ? '' : String(actual)) === String(expected);
71
+ });
72
+ }
73
+ function runtimeTemplateMatches(children, tag, criteria, optional = false, repeated = false, seen = new Set()) {
74
+ const matches = [];
75
+ for (const node of runtimeChildren(children)) {
76
+ if (seen.has(node))
77
+ continue;
78
+ seen.add(node);
79
+ switch (node.kind) {
80
+ case 'element':
81
+ if (node.tag === tag &&
82
+ runtimeCriteriaMatch(node.props, criteria, node.children)) {
83
+ matches.push({ optional, repeated });
84
+ }
85
+ matches.push(...runtimeTemplateMatches(node.children, tag, criteria, optional, repeated, seen));
86
+ break;
87
+ case 'component':
88
+ // Child component DOM is searched by the caller. Its internal VNode
89
+ // contract is available to the type-level walker, while a runtime
90
+ // absence is handled conservatively by the DOM query below.
91
+ break;
92
+ case 'directive':
93
+ matches.push(...runtimeTemplateMatches(node.node, tag, criteria, optional, repeated, seen));
94
+ break;
95
+ case 'if':
96
+ matches.push(...runtimeTemplateMatches(node.whenTrue(), tag, criteria, true, repeated, seen), ...(node.whenFalse
97
+ ? runtimeTemplateMatches(node.whenFalse(), tag, criteria, true, repeated, seen)
98
+ : []));
99
+ break;
100
+ case 'each':
101
+ matches.push(...runtimeTemplateMatches(node.itemTemplate(undefined, 0), tag, criteria, true, true, seen));
102
+ if (node.empty) {
103
+ matches.push(...runtimeTemplateMatches(node.empty(), tag, criteria, true, true, seen));
104
+ }
105
+ break;
106
+ case 'defer':
107
+ if (node.placeholder) {
108
+ matches.push(...runtimeTemplateMatches(node.placeholder(), tag, criteria, true, repeated, seen));
109
+ }
110
+ if (node.loading) {
111
+ matches.push(...runtimeTemplateMatches(node.loading(), tag, criteria, true, repeated, seen));
112
+ }
113
+ if (node.error) {
114
+ matches.push(...runtimeTemplateMatches(node.error(undefined), tag, criteria, true, repeated, seen));
115
+ }
116
+ break;
117
+ }
118
+ }
119
+ return matches;
120
+ }
121
+ export function findCraftTemplateLocator(host, template, tag, criteria) {
122
+ const matches = Array.from(host.querySelectorAll(tag)).filter((element) => {
123
+ if (criteria['content'] !== undefined) {
124
+ const names = element[CRAFT_LOCATOR_CONTENT_NAMES];
125
+ if (!names?.includes(String(criteria['content'])))
126
+ return false;
127
+ }
128
+ if (criteria['class'] !== undefined) {
129
+ if (!element.classList.contains(String(criteria['class'])))
130
+ return false;
131
+ }
132
+ return Object.entries(criteria)
133
+ .filter(([key]) => key !== 'class' && key !== 'content')
134
+ .every(([key, expected]) => {
135
+ const actual = element.getAttribute(key);
136
+ return actual !== null && actual === (expected === true ? '' : String(expected));
137
+ });
138
+ });
139
+ const runtimeMatches = runtimeTemplateMatches(template, tag, criteria);
140
+ const optional = runtimeMatches.some((match) => match.optional);
141
+ if (matches.length === 0) {
142
+ if (optional)
143
+ return undefined;
144
+ throw new Error(`Craft locator "${tag}" found no matching element for ${JSON.stringify(criteria)}.`);
145
+ }
146
+ if (matches.length !== 1) {
147
+ throw new Error(`Craft locator "${tag}" expected exactly one matching element, found ${matches.length}.`);
148
+ }
149
+ return matches[0];
150
+ }
151
+ //# sourceMappingURL=locator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locator.js","sourceRoot":"","sources":["../../../../../libs/component/src/lib/locator.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n CraftComponent,\n ComponentTemplateOf,\n} from './types';\nimport { YIELDABLE_VALUE } from '@craft-ts/core';\nimport type {\n CraftDirectiveNode,\n ElementNodeBase,\n CraftNode,\n CraftNodeChild,\n CraftNodeChildren,\n} from './render/vnode';\n\ntype IsAny<Value> = 0 extends 1 & Value ? true : false;\n\ntype LiteralString<Value> = Value extends string\n ? string extends Value\n ? never\n : Value\n : never;\n\ntype ClassTokens<Value> = [Value] extends [string]\n ? LiteralString<Value> extends infer Text extends string\n ? Text extends ''\n ? never\n : Text extends `${infer Head} ${infer Tail}`\n ? Head extends ''\n ? ClassTokens<Tail>\n : Head | ClassTokens<Tail>\n : Text\n : never\n : [Value] extends [readonly unknown[]]\n ? ClassTokens<Value[number]>\n : [Value] extends [Readonly<Record<string, boolean | null | undefined>>]\n ? string extends keyof Value\n ? never\n : Extract<keyof Value, string>\n : never;\n\ntype StaticAttributeValue<Value> = [Value] extends [string]\n ? string extends Value\n ? never\n : Value\n : [Value] extends [number]\n ? number extends Value\n ? never\n : Value\n : [Value] extends [boolean]\n ? boolean extends Value\n ? never\n : Value\n : never;\n\ntype StaticDirectAttributes<Props> = {\n [Key in keyof Props & string as Key extends `data-${string}` | `aria-${string}`\n ? StaticAttributeValue<Props[Key]> extends never\n ? never\n : Key\n : never]: StaticAttributeValue<Props[Key]>;\n};\n\ntype StaticNestedAttributes<Props> = Props extends {\n readonly attrs?: infer Attributes;\n}\n ? Attributes extends object\n ? {\n [Key in keyof Attributes & string as StaticAttributeValue<\n Attributes[Key]\n > extends never\n ? never\n : Key]: StaticAttributeValue<Attributes[Key]>;\n }\n : {}\n : {};\n\nexport type StaticLocatorCriteria<Props> = (Props extends {\n readonly class?: infer Class;\n}\n ? [ClassTokens<Class>] extends [never]\n ? {}\n : { readonly class: ClassTokens<Class> }\n : {}) &\n StaticDirectAttributes<Props> &\n StaticNestedAttributes<Props>;\n\ntype LocatorCandidate<\n Tag extends keyof HTMLElementTagNameMap,\n Criteria extends object,\n Optional extends boolean,\n Repeated extends boolean,\n> = {\n readonly tag: Tag;\n readonly criteria: Criteria;\n readonly optional: Optional;\n readonly repeated: Repeated;\n};\n\ntype DirectContentNames<Value> = Value extends unknown\n ? Value extends { readonly [YIELDABLE_VALUE]: infer Name extends string }\n ? LiteralString<Name>\n : Value extends readonly (infer Item)[]\n ? DirectContentNames<Item>\n : never\n : never;\n\ntype ContentLocatorCandidates<\n Tag extends keyof HTMLElementTagNameMap,\n Props,\n Children,\n Optional extends boolean,\n Repeated extends boolean,\n> = DirectContentNames<Children> extends infer Name extends string\n ? LocatorCandidate<\n Tag,\n StaticLocatorCriteria<Props> & { readonly content: Name },\n Optional,\n Repeated\n >\n : never;\n\ntype VisitContentNode<\n Node,\n Optional extends boolean,\n Repeated extends boolean,\n Seen extends readonly unknown[] = [],\n Depth extends readonly unknown[] = [],\n> = Depth['length'] extends 8\n ? never\n : IsAny<Node> extends true\n ? never\n : Node extends readonly (infer Child)[]\n ? VisitContentNode<Child, Optional, Repeated, Seen, [...Depth, unknown]>\n : Node extends ElementNodeBase<\n any,\n infer Tag extends keyof HTMLElementTagNameMap,\n infer Props,\n infer Children\n >\n ?\n | ContentLocatorCandidates<\n Tag,\n Props,\n Children,\n Optional,\n Repeated\n >\n | VisitContentNode<\n Children,\n Optional,\n Repeated,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'component';\n readonly component: infer Component;\n }\n ? Component extends CraftComponent<any, any>\n ? Component extends Seen[number]\n ? never\n : VisitContentNode<\n ReturnType<ComponentTemplateOf<Component>>,\n Optional,\n Repeated,\n [...Seen, Component],\n [...Depth, unknown]\n >\n : never\n : Node extends CraftDirectiveNode<any>\n ? VisitContentNode<\n Node['node'],\n Optional,\n Repeated,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'if';\n readonly whenTrue: () => infer TrueChildren;\n readonly whenFalse?: () => infer FalseChildren;\n }\n ? VisitContentNode<\n TrueChildren | FalseChildren,\n true,\n Repeated,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'each';\n readonly itemTemplate: (...args: any[]) => infer ItemChildren;\n readonly empty?: () => infer EmptyChildren;\n }\n ? VisitContentNode<\n ItemChildren | EmptyChildren,\n true,\n true,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'defer';\n readonly resolve: (...args: any[]) => infer Resolved;\n }\n ? VisitContentNode<\n Resolved,\n true,\n Repeated,\n Seen,\n [...Depth, unknown]\n >\n : never;\n\ntype ContentLocatorCandidatesOfTemplate<Template> = VisitContentNode<\n Template extends (...args: any[]) => infer Output ? Output : never,\n false,\n false\n>;\n\ntype ContentLocatorNames<Template, Tag> =\n ContentLocatorCandidatesOfTemplate<Template> extends infer Candidate\n ? Candidate extends LocatorCandidate<any, infer Criteria, any, any>\n ? Candidate['tag'] extends Tag\n ? Criteria extends { readonly content: infer Name extends string }\n ? Name\n : never\n : never\n : never\n : never;\n\nexport type LocatorContentNamesFor<\n Component extends CraftComponent<any, any>,\n Tag extends keyof HTMLElementTagNameMap,\n> = ContentLocatorNames<ComponentTemplateOf<Component>, Tag>;\n\ntype VisitOptionalTag<\n Node,\n Tag extends keyof HTMLElementTagNameMap,\n Optional extends boolean = false,\n Seen extends readonly unknown[] = [],\n Depth extends readonly unknown[] = [],\n> = Depth['length'] extends 8\n ? false\n : IsAny<Node> extends true\n ? false\n : Node extends readonly (infer Child)[]\n ? VisitOptionalTag<Child, Tag, Optional, Seen, [...Depth, unknown]>\n : Node extends ElementNodeBase<\n any,\n infer ActualTag extends keyof HTMLElementTagNameMap,\n any,\n infer Children\n >\n ? (ActualTag extends Tag ? Optional : false) |\n VisitOptionalTag<Children, Tag, Optional, Seen, [...Depth, unknown]>\n : Node extends {\n readonly kind: 'component';\n readonly component: infer Component;\n }\n ? Component extends CraftComponent<any, any>\n ? Component extends Seen[number]\n ? false\n : VisitOptionalTag<\n ReturnType<ComponentTemplateOf<Component>>,\n Tag,\n Optional,\n [...Seen, Component],\n [...Depth, unknown]\n >\n : false\n : Node extends CraftDirectiveNode<any>\n ? VisitOptionalTag<\n Node['node'],\n Tag,\n Optional,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'if';\n readonly whenTrue: () => infer TrueChildren;\n readonly whenFalse?: () => infer FalseChildren;\n }\n ? VisitOptionalTag<\n TrueChildren | FalseChildren,\n Tag,\n true,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'each';\n readonly itemTemplate: (...args: any[]) => infer ItemChildren;\n readonly empty?: () => infer EmptyChildren;\n }\n ? VisitOptionalTag<\n ItemChildren | EmptyChildren,\n Tag,\n true,\n Seen,\n [...Depth, unknown]\n >\n : Node extends {\n readonly kind: 'defer';\n readonly resolve: (...args: any[]) => infer Resolved;\n }\n ? VisitOptionalTag<\n Resolved,\n Tag,\n true,\n Seen,\n [...Depth, unknown]\n >\n : false;\n\ntype TemplateHasOptionalTag<Template, Tag extends keyof HTMLElementTagNameMap> =\n true extends VisitOptionalTag<\n Template extends (...args: any[]) => infer Output ? Output : never,\n Tag\n >\n ? true\n : false;\n\ntype NextDepth<Depth extends readonly unknown[]> = [...Depth, unknown];\n\ntype VisitChildren<\n Children,\n Depth extends readonly unknown[],\n Optional extends boolean,\n Repeated extends boolean,\n Seen extends readonly unknown[],\n> = Children extends readonly (infer Child)[]\n ? VisitNode<Child, NextDepth<Depth>, Optional, Repeated, Seen>\n : VisitNode<Children, Depth, Optional, Repeated, Seen>;\n\ntype VisitComponent<\n Component,\n Depth extends readonly unknown[],\n Optional extends boolean,\n Repeated extends boolean,\n Seen extends readonly unknown[],\n> = IsAny<Component> extends true\n ? never\n : Component extends CraftComponent<any, any>\n ? VisitChildren<\n ReturnType<ComponentTemplateOf<Component>>,\n NextDepth<Depth>,\n Optional,\n Repeated,\n Seen\n >\n : never;\n\ntype VisitNode<\n Node,\n Depth extends readonly unknown[],\n Optional extends boolean,\n Repeated extends boolean,\n Seen extends readonly unknown[],\n> = Depth['length'] extends 2\n ? never\n : IsAny<Node> extends true\n ? never\n : Node extends ElementNodeBase<\n any,\n infer Tag extends keyof HTMLElementTagNameMap,\n infer Props,\n infer Children\n >\n ?\n | LocatorCandidate<\n Tag,\n StaticLocatorCriteria<Props>,\n Optional,\n Repeated\n >\n | VisitChildren<Children, NextDepth<Depth>, Optional, Repeated, Seen>\n : Node extends {\n readonly kind: 'component';\n readonly component: infer Component;\n }\n ? VisitComponent<Component, Depth, Optional, Repeated, Seen>\n : Node extends CraftDirectiveNode<any>\n ? VisitNode<Node['node'], NextDepth<Depth>, Optional, Repeated, Seen>\n : Node extends {\n readonly kind: 'if';\n readonly whenTrue: () => infer TrueChildren;\n readonly whenFalse?: () => infer FalseChildren;\n }\n ? VisitChildren<\n TrueChildren | FalseChildren,\n NextDepth<Depth>,\n true,\n Repeated,\n Seen\n >\n : Node extends {\n readonly kind: 'each';\n readonly itemTemplate: (...args: any[]) => infer ItemChildren;\n readonly empty?: () => infer EmptyChildren;\n }\n ? VisitChildren<\n ItemChildren | EmptyChildren,\n NextDepth<Depth>,\n true,\n true,\n Seen\n >\n : Node extends {\n readonly kind: 'defer';\n readonly resolve: (...args: any[]) => infer Resolved;\n }\n ? VisitChildren<\n Resolved,\n NextDepth<Depth>,\n true,\n Repeated,\n Seen\n >\n : never;\n\nexport type TemplateLocatorCandidates<\n Component extends CraftComponent<any, any>,\n> = VisitNode<\n ReturnType<ComponentTemplateOf<Component>>,\n [],\n false,\n false,\n []\n>;\n\nexport type LocatorCriteriaFor<\n Component extends CraftComponent<any, any>,\n Tag extends keyof HTMLElementTagNameMap,\n> = LocatorCriteria & {\n readonly content?: ContentLocatorNames<ComponentTemplateOf<Component>, Tag>;\n};\n\ntype CriteriaMatches<Available, Wanted> = Wanted extends Partial<Available>\n ? true\n : false;\n\ntype MatchingCandidates<\n Candidates,\n Tag,\n Criteria,\n> = Candidates extends LocatorCandidate<\n infer CandidateTag,\n infer Available,\n any,\n any\n>\n ? CandidateTag extends Tag\n ? CriteriaMatches<Available, Criteria> extends true\n ? Candidates\n : never\n : never\n : never;\n\ntype IsUnion<Value, Whole = Value> = Value extends any\n ? [Whole] extends [Value]\n ? false\n : true\n : never;\n\ntype HasRepeated<Candidates> = Extract<\n Candidates,\n { readonly repeated: true }\n> extends never\n ? false\n : true;\n\ntype HasMultiple<Candidates> = IsUnion<Candidates> extends true ? true : false;\n\ntype LocatorIsValid<Candidates> = [Candidates] extends [never]\n ? false\n : HasRepeated<Candidates> extends true\n ? false\n : HasMultiple<Candidates> extends true\n ? false\n : true;\n\ntype LocatorOptional<Candidates> = Extract<\n Candidates,\n { readonly optional: true }\n> extends never\n ? false\n : true;\n\nexport type CraftLocatorResult<\n Tag extends keyof HTMLElementTagNameMap,\n Candidates,\n> = MaybeDefined<\n HTMLElementTagNameMap[Tag],\n LocatorOptional<Candidates>\n>;\n\nexport type MaybeDefined<Value, Optional extends boolean = true> = Optional extends true\n ? Value | undefined\n : Value;\n\nexport type LocatorCriteriaValidation<\n Component extends CraftComponent<any, any>,\n Tag extends keyof HTMLElementTagNameMap,\n Criteria,\n> = MatchingCandidates<\n TemplateLocatorCandidates<Component> |\n ContentLocatorCandidatesOfTemplate<ComponentTemplateOf<Component>>,\n Tag,\n Criteria\n> extends infer Candidates\n ? LocatorIsValid<Candidates> extends true\n ? unknown\n : {\n readonly 'locator must identify exactly one static element': never;\n }\n : never;\n\nexport type LocatorCriteria = {\n readonly class?: string;\n readonly [dataAttribute: `data-${string}`]: string | undefined;\n readonly [ariaAttribute: `aria-${string}`]: string | undefined;\n};\n\ntype CraftTemplateLocatorApiForTemplate<\n Template,\n> = {\n locator<\n const Tag extends keyof HTMLElementTagNameMap,\n const Criteria extends LocatorCriteria,\n >(\n tag: Tag,\n criteria: Criteria extends { readonly content: unknown } ? never : Criteria,\n ): MaybeDefined<\n HTMLElementTagNameMap[Tag],\n TemplateHasOptionalTag<Template, Tag>\n >;\n locator<\n const Tag extends keyof HTMLElementTagNameMap,\n const Content extends string,\n >(\n tag: Tag,\n criteria: LocatorCriteria &\n { readonly content: Content } &\n (Content extends ContentLocatorNames<Template, Tag>\n ? unknown\n : {\n readonly 'content brand is not rendered by this template': never;\n }),\n ): MaybeDefined<\n HTMLElementTagNameMap[Tag],\n TemplateHasOptionalTag<Template, Tag>\n >;\n};\n\nexport type CraftTemplateLocatorApi<\n Component extends CraftComponent<any, any>,\n> = CraftTemplateLocatorApiForTemplate<ComponentTemplateOf<Component>>;\n\nexport type RuntimeLocatorCriteria = Readonly<Record<string, unknown>>;\n\n/** Runtime marker for branded values rendered directly as element children. */\nexport const CRAFT_LOCATOR_CONTENT_NAMES = Symbol(\n 'craft-locator-content-names',\n);\n\ntype LocatorContentMarkedElement = Element & {\n readonly [CRAFT_LOCATOR_CONTENT_NAMES]?: readonly string[];\n};\n\nexport function directCraftContentNames(\n children: CraftNodeChildren,\n): readonly string[] {\n const names = new Set<string>();\n const visit = (child: CraftNodeChild): void => {\n if (Array.isArray(child)) {\n child.forEach(visit);\n return;\n }\n if (\n (typeof child === 'function' ||\n (typeof child === 'object' && child !== null)) &&\n YIELDABLE_VALUE in child\n ) {\n const name = (child as { readonly [YIELDABLE_VALUE]?: unknown })[\n YIELDABLE_VALUE\n ];\n if (typeof name === 'string') names.add(name);\n }\n };\n visit(children);\n return [...names];\n}\n\ntype RuntimeLocatorMatch = {\n readonly optional: boolean;\n readonly repeated: boolean;\n};\n\nfunction runtimeChildren(children: CraftNodeChildren): readonly CraftNode[] {\n const result: CraftNode[] = [];\n const visit = (child: CraftNodeChild): void => {\n if (Array.isArray(child)) {\n child.forEach(visit);\n } else if (\n child !== null &&\n child !== undefined &&\n typeof child === 'object' &&\n 'kind' in child\n ) {\n result.push(child as CraftNode);\n }\n };\n visit(children);\n return result;\n}\n\nfunction runtimeClassTokens(value: unknown): readonly string[] {\n if (typeof value === 'string') return value.split(/\\s+/).filter(Boolean);\n if (Array.isArray(value)) return value.flatMap(runtimeClassTokens);\n if (typeof value === 'object' && value !== null) {\n return Object.entries(value)\n .filter(([, enabled]) => enabled)\n .map(([name]) => name);\n }\n return [];\n}\n\nfunction runtimeAttributeValue(\n props: Readonly<Record<string, unknown>>,\n key: string,\n): unknown {\n if (key in props && key !== 'attrs') return props[key];\n const attrs = props['attrs'];\n return typeof attrs === 'object' && attrs !== null\n ? (attrs as Record<string, unknown>)[key]\n : undefined;\n}\n\nfunction runtimeCriteriaMatch(\n props: Readonly<Record<string, unknown>>,\n criteria: RuntimeLocatorCriteria,\n children?: CraftNodeChildren,\n): boolean {\n return Object.entries(criteria).every(([key, expected]) => {\n if (key === 'class') {\n return runtimeClassTokens(props[key]).includes(String(expected));\n }\n if (key === 'content') {\n return directCraftContentNames(children ?? []).includes(String(expected));\n }\n const actual = runtimeAttributeValue(props, key);\n if (actual === null || actual === undefined || actual === false) {\n return false;\n }\n return (actual === true ? '' : String(actual)) === String(expected);\n });\n}\n\nfunction runtimeTemplateMatches(\n children: CraftNodeChildren,\n tag: string,\n criteria: RuntimeLocatorCriteria,\n optional = false,\n repeated = false,\n seen = new Set<unknown>(),\n): RuntimeLocatorMatch[] {\n const matches: RuntimeLocatorMatch[] = [];\n for (const node of runtimeChildren(children)) {\n if (seen.has(node)) continue;\n seen.add(node);\n\n switch (node.kind) {\n case 'element':\n if (\n node.tag === tag &&\n runtimeCriteriaMatch(node.props, criteria, node.children)\n ) {\n matches.push({ optional, repeated });\n }\n matches.push(\n ...runtimeTemplateMatches(\n node.children,\n tag,\n criteria,\n optional,\n repeated,\n seen,\n ),\n );\n break;\n case 'component':\n // Child component DOM is searched by the caller. Its internal VNode\n // contract is available to the type-level walker, while a runtime\n // absence is handled conservatively by the DOM query below.\n break;\n case 'directive':\n matches.push(\n ...runtimeTemplateMatches(\n node.node as CraftNodeChildren,\n tag,\n criteria,\n optional,\n repeated,\n seen,\n ),\n );\n break;\n case 'if':\n matches.push(\n ...runtimeTemplateMatches(\n node.whenTrue(),\n tag,\n criteria,\n true,\n repeated,\n seen,\n ),\n ...(node.whenFalse\n ? runtimeTemplateMatches(\n node.whenFalse(),\n tag,\n criteria,\n true,\n repeated,\n seen,\n )\n : []),\n );\n break;\n case 'each':\n matches.push(\n ...runtimeTemplateMatches(\n node.itemTemplate(undefined as never, 0),\n tag,\n criteria,\n true,\n true,\n seen,\n ),\n );\n if (node.empty) {\n matches.push(\n ...runtimeTemplateMatches(\n node.empty(),\n tag,\n criteria,\n true,\n true,\n seen,\n ),\n );\n }\n break;\n case 'defer':\n if (node.placeholder) {\n matches.push(\n ...runtimeTemplateMatches(\n node.placeholder(),\n tag,\n criteria,\n true,\n repeated,\n seen,\n ),\n );\n }\n if (node.loading) {\n matches.push(\n ...runtimeTemplateMatches(\n node.loading(),\n tag,\n criteria,\n true,\n repeated,\n seen,\n ),\n );\n }\n if (node.error) {\n matches.push(\n ...runtimeTemplateMatches(\n node.error(undefined),\n tag,\n criteria,\n true,\n repeated,\n seen,\n ),\n );\n }\n break;\n }\n }\n return matches;\n}\n\nexport function findCraftTemplateLocator(\n host: Element,\n template: CraftNodeChildren,\n tag: string,\n criteria: RuntimeLocatorCriteria,\n): Element | undefined {\n const matches = Array.from(host.querySelectorAll(tag)).filter((element) => {\n if (criteria['content'] !== undefined) {\n const names = (element as LocatorContentMarkedElement)[\n CRAFT_LOCATOR_CONTENT_NAMES\n ];\n if (!names?.includes(String(criteria['content']))) return false;\n }\n if (criteria['class'] !== undefined) {\n if (!element.classList.contains(String(criteria['class']))) return false;\n }\n return Object.entries(criteria)\n .filter(([key]) => key !== 'class' && key !== 'content')\n .every(([key, expected]) => {\n const actual = element.getAttribute(key);\n return actual !== null && actual === (expected === true ? '' : String(expected));\n });\n });\n const runtimeMatches = runtimeTemplateMatches(template, tag, criteria);\n const optional = runtimeMatches.some((match) => match.optional);\n if (matches.length === 0) {\n if (optional) return undefined;\n throw new Error(\n `Craft locator \"${tag}\" found no matching element for ${JSON.stringify(criteria)}.`,\n );\n }\n if (matches.length !== 1) {\n throw new Error(\n `Craft locator \"${tag}\" expected exactly one matching element, found ${matches.length}.`,\n );\n }\n return matches[0];\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import type { YieldableReactiveValue } from '@craft-ts/core';
2
+ import type { CraftNodeChildren, CraftNodeChildrenDependencies, MatchBlockNode } from './render/vnode';
3
+ type ExceptionCode<Value extends object, Key extends keyof Value> = Extract<Value[Key], string | number>;
4
+ type ExceptionHandlerMap<Value extends object, Key extends keyof Value> = {
5
+ [Code in ExceptionCode<Value, Key>]: (exception: Extract<Value, Record<Key, Code>>) => CraftNodeChildren;
6
+ };
7
+ type MatchBlockDependencies<Handlers> = Handlers extends Record<string, (...args: any[]) => infer Output> ? CraftNodeChildrenDependencies<Output> : Record<never, never>;
8
+ type ExceptionKey<Value extends object> = {
9
+ [K in keyof Value]-?: Value[K] extends string | number ? K : never;
10
+ }[keyof Value];
11
+ type ScalarValue = string | number;
12
+ type ScalarHandlerMap<Value extends ScalarValue> = {
13
+ [Code in Extract<Value, string | number>]: () => CraftNodeChildren;
14
+ };
15
+ type GeneratorSourceValue<Source> = Source extends (...args: any[]) => Generator<any, infer Value, any> ? Exclude<Value, undefined> extends infer ObjectValue extends object ? ObjectValue : never : never;
16
+ /**
17
+ * Template-projected deep readers are generator callbacks rather than the
18
+ * original `YieldableReactiveValue` type. Keep their result type available to
19
+ * discriminated-union matching without importing the component template
20
+ * layer into core's component primitives.
21
+ */
22
+ declare function exhaustive<Source extends ((...args: any[]) => Generator<any, any, any>) | undefined, Value extends object = GeneratorSourceValue<Source>, Key extends ExceptionKey<Value> = ExceptionKey<Value>, Handlers extends ExceptionHandlerMap<Value, Key> = ExceptionHandlerMap<Value, Key>>(source: Source, key: Key, handlers: Handlers): MatchBlockNode<MatchBlockDependencies<Handlers>, NonNullable<Source>, ReturnType<Handlers[ExceptionCode<Value, Key>]>, Extract<ExceptionCode<Value, Key>, string>>;
23
+ declare function exhaustive<Value extends object, Key extends ExceptionKey<Value>, Handlers extends ExceptionHandlerMap<Value, Key>>(source: YieldableReactiveValue<Value>, key: Key, handlers: Handlers): MatchBlockNode<MatchBlockDependencies<Handlers>, YieldableReactiveValue<Value>, ReturnType<Handlers[ExceptionCode<Value, Key>]>, Extract<ExceptionCode<Value, Key>, string>>;
24
+ declare function exhaustive<Value extends object, Key extends ExceptionKey<Value>, Handlers extends ExceptionHandlerMap<Value, Key>>(source: (() => Value | undefined) | Value, key: Key, handlers: Handlers): MatchBlockNode<MatchBlockDependencies<Handlers>, (() => Value | undefined) | Value, ReturnType<Handlers[ExceptionCode<Value, Key>]>, Extract<ExceptionCode<Value, Key>, string>>;
25
+ declare function exhaustive<Value extends ScalarValue, Handlers extends ScalarHandlerMap<Value>>(source: YieldableReactiveValue<Value>, handlers: Handlers): MatchBlockNode<MatchBlockDependencies<Handlers>, YieldableReactiveValue<{
26
+ value: Value;
27
+ }>, ReturnType<Handlers[Extract<Value, string | number>]>, Extract<Value, string>>;
28
+ declare function exhaustive<Value extends ScalarValue, Handlers extends ScalarHandlerMap<Value>>(source: (() => Value | Generator<unknown, Value, unknown>) | Value, handlers: Handlers): MatchBlockNode<MatchBlockDependencies<Handlers>, (() => {
29
+ value: Value;
30
+ }) | {
31
+ value: Value;
32
+ }, ReturnType<Handlers[Extract<Value, string | number>]>, Extract<Value, string>>;
33
+ /** Reactive template counterpart of discriminated-union matching. */
34
+ export declare const matchBlock: {
35
+ exhaustive: typeof exhaustive;
36
+ };
37
+ export {};
38
+ //# sourceMappingURL=match-block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match-block.d.ts","sourceRoot":"","sources":["../../../../../libs/component/src/lib/match-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,sBAAsB,EACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EACV,iBAAiB,EACjB,6BAA6B,EAC7B,cAAc,EACf,MAAM,gBAAgB,CAAC;AAExB,KAAK,aAAa,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,KAAK,IAAI,OAAO,CACzE,KAAK,CAAC,GAAG,CAAC,EACV,MAAM,GAAG,MAAM,CAChB,CAAC;AAEF,KAAK,mBAAmB,CAAC,KAAK,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,KAAK,IAAI;KACvE,IAAI,IAAI,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CACnC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,KACzC,iBAAiB;CACvB,CAAC;AAEF,KAAK,sBAAsB,CAAC,QAAQ,IAClC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,MAAM,MAAM,CAAC,GAC7D,6BAA6B,CAAC,MAAM,CAAC,GACrC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE3B,KAAK,YAAY,CAAC,KAAK,SAAS,MAAM,IAAI;KACvC,CAAC,IAAI,MAAM,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,KAAK;CACnE,CAAC,MAAM,KAAK,CAAC,CAAC;AAEf,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnC,KAAK,gBAAgB,CAAC,KAAK,SAAS,WAAW,IAAI;KAChD,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,iBAAiB;CACnE,CAAC;AAEF,KAAK,oBAAoB,CAAC,MAAM,IAAI,MAAM,SAAS,CACjD,GAAG,IAAI,EAAE,GAAG,EAAE,KACX,SAAS,CAAC,GAAG,EAAE,MAAM,KAAK,EAAE,GAAG,CAAC,GACjC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,MAAM,WAAW,SAAS,MAAM,GAChE,WAAW,GACX,KAAK,GACP,KAAK,CAAC;AAEV;;;;;GAKG;AACH,iBAAS,UAAU,CACjB,MAAM,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,SAAS,EACzE,KAAK,SAAS,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,EACnD,GAAG,SAAS,YAAY,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,EACrD,QAAQ,SAAS,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,mBAAmB,CACpE,KAAK,EACL,GAAG,CACJ,EAED,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,GACjB,cAAc,CACf,sBAAsB,CAAC,QAAQ,CAAC,EAChC,WAAW,CAAC,MAAM,CAAC,EACnB,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAC/C,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAC3C,CAAC;AAEF,iBAAS,UAAU,CACjB,KAAK,SAAS,MAAM,EACpB,GAAG,SAAS,YAAY,CAAC,KAAK,CAAC,EAC/B,QAAQ,SAAS,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,EAEhD,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,EACrC,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,GACjB,cAAc,CACf,sBAAsB,CAAC,QAAQ,CAAC,EAChC,sBAAsB,CAAC,KAAK,CAAC,EAC7B,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAC/C,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAC3C,CAAC;AACF,iBAAS,UAAU,CACjB,KAAK,SAAS,MAAM,EACpB,GAAG,SAAS,YAAY,CAAC,KAAK,CAAC,EAC/B,QAAQ,SAAS,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,EAEhD,MAAM,EAAE,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,KAAK,EACzC,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,GACjB,cAAc,CACf,sBAAsB,CAAC,QAAQ,CAAC,EAChC,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,KAAK,EACjC,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAC/C,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAC3C,CAAC;AACF,iBAAS,UAAU,CACjB,KAAK,SAAS,WAAW,EACzB,QAAQ,SAAS,gBAAgB,CAAC,KAAK,CAAC,EAExC,MAAM,EAAE,sBAAsB,CAAC,KAAK,CAAC,EACrC,QAAQ,EAAE,QAAQ,GACjB,cAAc,CACf,sBAAsB,CAAC,QAAQ,CAAC,EAChC,sBAAsB,CAAC;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,EACxC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,EACrD,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CACvB,CAAC;AACF,iBAAS,UAAU,CACjB,KAAK,SAAS,WAAW,EACzB,QAAQ,SAAS,gBAAgB,CAAC,KAAK,CAAC,EAExC,MAAM,EAAE,CAAC,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,KAAK,EAClE,QAAQ,EAAE,QAAQ,GACjB,cAAc,CACf,sBAAsB,CAAC,QAAQ,CAAC,EAChC,CAAC,MAAM;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,GAAG;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,EAC3C,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,EACrD,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CACvB,CAAC;AA0CF,qEAAqE;AACrE,eAAO,MAAM,UAAU;;CAAiB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { craftUse } from '@craft-ts/core';
2
+ function exhaustive(source, keyOrHandlers, maybeHandlers) {
3
+ if (maybeHandlers === undefined) {
4
+ const handlers = keyOrHandlers;
5
+ const scalarSource = typeof source === 'function'
6
+ ? () => ({
7
+ value: craftUse(source()),
8
+ })
9
+ : { value: source };
10
+ return {
11
+ kind: 'match-block',
12
+ source: scalarSource,
13
+ key: 'value',
14
+ handlers: Object.fromEntries(Object.entries(handlers).map(([code, handler]) => [
15
+ code,
16
+ () => handler(),
17
+ ])),
18
+ };
19
+ }
20
+ return {
21
+ kind: 'match-block',
22
+ source,
23
+ key: keyOrHandlers,
24
+ handlers: maybeHandlers,
25
+ };
26
+ }
27
+ /** Reactive template counterpart of discriminated-union matching. */
28
+ export const matchBlock = { exhaustive };
29
+ //# sourceMappingURL=match-block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match-block.js","sourceRoot":"","sources":["../../../../../libs/component/src/lib/match-block.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAsH1C,SAAS,UAAU,CACjB,MAAe,EACf,aAAoE,EACpE,aAGC;IAED,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,aAGhB,CAAC;QACF,MAAM,YAAY,GAChB,OAAO,MAAM,KAAK,UAAU;YAC1B,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBACL,KAAK,EAAE,QAAQ,CAAE,MAAwB,EAAE,CAAgB;aAC5D,CAAC;YACJ,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAExB,OAAO;YACL,IAAI,EAAE,aAAsB;YAC5B,MAAM,EAAE,YAAY;YACpB,GAAG,EAAE,OAAO;YACZ,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC1B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;gBAChD,IAAI;gBACJ,GAAG,EAAE,CAAC,OAAO,EAAE;aAChB,CAAC,CACH;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,aAAsB;QAC5B,MAAM;QACN,GAAG,EAAE,aAAa;QAClB,QAAQ,EAAE,aAAa;KACxB,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,UAAU,EAAE,CAAC","sourcesContent":["import type {\n AnyCraftException,\n YieldableReactiveValue,\n} from '@craft-ts/core';\nimport { craftUse } from '@craft-ts/core';\nimport type {\n CraftNodeChildren,\n CraftNodeChildrenDependencies,\n MatchBlockNode,\n} from './render/vnode';\n\ntype ExceptionCode<Value extends object, Key extends keyof Value> = Extract<\n Value[Key],\n string | number\n>;\n\ntype ExceptionHandlerMap<Value extends object, Key extends keyof Value> = {\n [Code in ExceptionCode<Value, Key>]: (\n exception: Extract<Value, Record<Key, Code>>,\n ) => CraftNodeChildren;\n};\n\ntype MatchBlockDependencies<Handlers> =\n Handlers extends Record<string, (...args: any[]) => infer Output>\n ? CraftNodeChildrenDependencies<Output>\n : Record<never, never>;\n\ntype ExceptionKey<Value extends object> = {\n [K in keyof Value]-?: Value[K] extends string | number ? K : never;\n}[keyof Value];\n\ntype ScalarValue = string | number;\n\ntype ScalarHandlerMap<Value extends ScalarValue> = {\n [Code in Extract<Value, string | number>]: () => CraftNodeChildren;\n};\n\ntype GeneratorSourceValue<Source> = Source extends (\n ...args: any[]\n) => Generator<any, infer Value, any>\n ? Exclude<Value, undefined> extends infer ObjectValue extends object\n ? ObjectValue\n : never\n : never;\n\n/**\n * Template-projected deep readers are generator callbacks rather than the\n * original `YieldableReactiveValue` type. Keep their result type available to\n * discriminated-union matching without importing the component template\n * layer into core's component primitives.\n */\nfunction exhaustive<\n Source extends ((...args: any[]) => Generator<any, any, any>) | undefined,\n Value extends object = GeneratorSourceValue<Source>,\n Key extends ExceptionKey<Value> = ExceptionKey<Value>,\n Handlers extends ExceptionHandlerMap<Value, Key> = ExceptionHandlerMap<\n Value,\n Key\n >,\n>(\n source: Source,\n key: Key,\n handlers: Handlers,\n): MatchBlockNode<\n MatchBlockDependencies<Handlers>,\n NonNullable<Source>,\n ReturnType<Handlers[ExceptionCode<Value, Key>]>,\n Extract<ExceptionCode<Value, Key>, string>\n>;\n\nfunction exhaustive<\n Value extends object,\n Key extends ExceptionKey<Value>,\n Handlers extends ExceptionHandlerMap<Value, Key>,\n>(\n source: YieldableReactiveValue<Value>,\n key: Key,\n handlers: Handlers,\n): MatchBlockNode<\n MatchBlockDependencies<Handlers>,\n YieldableReactiveValue<Value>,\n ReturnType<Handlers[ExceptionCode<Value, Key>]>,\n Extract<ExceptionCode<Value, Key>, string>\n>;\nfunction exhaustive<\n Value extends object,\n Key extends ExceptionKey<Value>,\n Handlers extends ExceptionHandlerMap<Value, Key>,\n>(\n source: (() => Value | undefined) | Value,\n key: Key,\n handlers: Handlers,\n): MatchBlockNode<\n MatchBlockDependencies<Handlers>,\n (() => Value | undefined) | Value,\n ReturnType<Handlers[ExceptionCode<Value, Key>]>,\n Extract<ExceptionCode<Value, Key>, string>\n>;\nfunction exhaustive<\n Value extends ScalarValue,\n Handlers extends ScalarHandlerMap<Value>,\n>(\n source: YieldableReactiveValue<Value>,\n handlers: Handlers,\n): MatchBlockNode<\n MatchBlockDependencies<Handlers>,\n YieldableReactiveValue<{ value: Value }>,\n ReturnType<Handlers[Extract<Value, string | number>]>,\n Extract<Value, string>\n>;\nfunction exhaustive<\n Value extends ScalarValue,\n Handlers extends ScalarHandlerMap<Value>,\n>(\n source: (() => Value | Generator<unknown, Value, unknown>) | Value,\n handlers: Handlers,\n): MatchBlockNode<\n MatchBlockDependencies<Handlers>,\n (() => { value: Value }) | { value: Value },\n ReturnType<Handlers[Extract<Value, string | number>]>,\n Extract<Value, string>\n>;\nfunction exhaustive(\n source: unknown,\n keyOrHandlers: PropertyKey | Record<string, () => CraftNodeChildren>,\n maybeHandlers?: Record<\n string,\n (exception: AnyCraftException) => CraftNodeChildren\n >,\n) {\n if (maybeHandlers === undefined) {\n const handlers = keyOrHandlers as Record<\n string,\n () => CraftNodeChildren\n >;\n const scalarSource =\n typeof source === 'function'\n ? () => ({\n value: craftUse((source as () => unknown)()) as ScalarValue,\n })\n : { value: source };\n\n return {\n kind: 'match-block' as const,\n source: scalarSource,\n key: 'value',\n handlers: Object.fromEntries(\n Object.entries(handlers).map(([code, handler]) => [\n code,\n () => handler(),\n ]),\n ),\n };\n }\n\n return {\n kind: 'match-block' as const,\n source,\n key: keyOrHandlers,\n handlers: maybeHandlers,\n };\n}\n\n/** Reactive template counterpart of discriminated-union matching. */\nexport const matchBlock = { exhaustive };\n"]}