@askrjs/askr 0.0.38 → 0.0.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.
Files changed (250) hide show
  1. package/dist/bench/components/benchmark-row.d.ts.map +1 -1
  2. package/dist/bench/components/benchmark-row.js.map +1 -1
  3. package/dist/bench/components/benchmark-table.js.map +1 -1
  4. package/dist/benchmark.d.ts.map +1 -1
  5. package/dist/benchmark.js +2 -2
  6. package/dist/benchmark.js.map +1 -1
  7. package/dist/bin/askr-ssg.d.ts.map +1 -1
  8. package/dist/bin/askr-ssg.js.map +1 -1
  9. package/dist/boot/index.d.ts +9 -6
  10. package/dist/boot/index.d.ts.map +1 -1
  11. package/dist/boot/index.js +210 -75
  12. package/dist/boot/index.js.map +1 -1
  13. package/dist/common/attr-names.js +17 -0
  14. package/dist/common/attr-names.js.map +1 -0
  15. package/dist/common/component.d.ts.map +1 -1
  16. package/dist/common/control.d.ts.map +1 -1
  17. package/dist/common/control.js.map +1 -1
  18. package/dist/common/env.js.map +1 -1
  19. package/dist/common/jsx.d.ts.map +1 -1
  20. package/dist/common/jsx.js.map +1 -1
  21. package/dist/common/promise.js +8 -0
  22. package/dist/common/promise.js.map +1 -0
  23. package/dist/common/props.d.ts +286 -1
  24. package/dist/common/props.d.ts.map +1 -1
  25. package/dist/common/router-internal.js +6 -0
  26. package/dist/common/router-internal.js.map +1 -0
  27. package/dist/common/router.d.ts +45 -36
  28. package/dist/common/router.d.ts.map +1 -1
  29. package/dist/common/ssr-errors.d.ts.map +1 -1
  30. package/dist/common/ssr-errors.js.map +1 -1
  31. package/dist/common/ssr.d.ts +1 -0
  32. package/dist/common/ssr.d.ts.map +1 -1
  33. package/dist/common/ssr.js +6 -0
  34. package/dist/common/ssr.js.map +1 -0
  35. package/dist/common/vnode.d.ts +2 -1
  36. package/dist/common/vnode.d.ts.map +1 -1
  37. package/dist/common/vnode.js.map +1 -1
  38. package/dist/components/error-boundary.d.ts +7 -4
  39. package/dist/components/error-boundary.d.ts.map +1 -1
  40. package/dist/components/error-boundary.js.map +1 -1
  41. package/dist/components/link.d.ts +2 -1
  42. package/dist/components/link.d.ts.map +1 -1
  43. package/dist/components/link.js +10 -1
  44. package/dist/components/link.js.map +1 -1
  45. package/dist/control/case.d.ts +4 -2
  46. package/dist/control/case.d.ts.map +1 -1
  47. package/dist/control/case.js.map +1 -1
  48. package/dist/control/for.d.ts +2 -1
  49. package/dist/control/for.d.ts.map +1 -1
  50. package/dist/control/for.js.map +1 -1
  51. package/dist/control/shared.d.ts +9 -0
  52. package/dist/control/shared.d.ts.map +1 -0
  53. package/dist/control/shared.js.map +1 -1
  54. package/dist/control/show.d.ts +4 -3
  55. package/dist/control/show.d.ts.map +1 -1
  56. package/dist/control/show.js.map +1 -1
  57. package/dist/data/index.d.ts +94 -14
  58. package/dist/data/index.d.ts.map +1 -1
  59. package/dist/data/index.js +65 -14
  60. package/dist/data/index.js.map +1 -1
  61. package/dist/dev/invariant.js.map +1 -1
  62. package/dist/dev/logger.js.map +1 -1
  63. package/dist/foundations/icon/icon.d.ts.map +1 -1
  64. package/dist/foundations/icon/icon.js.map +1 -1
  65. package/dist/foundations/icon/icon.types.d.ts.map +1 -1
  66. package/dist/foundations/interactions/dismissable.d.ts +9 -3
  67. package/dist/foundations/interactions/dismissable.d.ts.map +1 -1
  68. package/dist/foundations/interactions/dismissable.js.map +1 -1
  69. package/dist/foundations/interactions/focusable.d.ts.map +1 -1
  70. package/dist/foundations/interactions/focusable.js.map +1 -1
  71. package/dist/foundations/interactions/hoverable.d.ts.map +1 -1
  72. package/dist/foundations/interactions/hoverable.js.map +1 -1
  73. package/dist/foundations/interactions/interaction-policy.d.ts +1 -1
  74. package/dist/foundations/interactions/interaction-policy.d.ts.map +1 -1
  75. package/dist/foundations/interactions/interaction-policy.js +3 -3
  76. package/dist/foundations/interactions/interaction-policy.js.map +1 -1
  77. package/dist/foundations/interactions/pressable.d.ts.map +1 -1
  78. package/dist/foundations/interactions/pressable.js.map +1 -1
  79. package/dist/foundations/interactions/roving-focus.d.ts.map +1 -1
  80. package/dist/foundations/interactions/roving-focus.js +8 -8
  81. package/dist/foundations/interactions/roving-focus.js.map +1 -1
  82. package/dist/foundations/state/controllable.d.ts.map +1 -1
  83. package/dist/foundations/state/controllable.js.map +1 -1
  84. package/dist/foundations/structures/collection.d.ts.map +1 -1
  85. package/dist/foundations/structures/collection.js.map +1 -1
  86. package/dist/foundations/structures/layer.d.ts.map +1 -1
  87. package/dist/foundations/structures/layer.js.map +1 -1
  88. package/dist/foundations/structures/layout.d.ts +4 -2
  89. package/dist/foundations/structures/layout.d.ts.map +1 -1
  90. package/dist/foundations/structures/layout.js.map +1 -1
  91. package/dist/foundations/structures/portal.d.ts +9 -25
  92. package/dist/foundations/structures/portal.d.ts.map +1 -1
  93. package/dist/foundations/structures/portal.js +98 -17
  94. package/dist/foundations/structures/portal.js.map +1 -1
  95. package/dist/foundations/structures/presence.d.ts +4 -3
  96. package/dist/foundations/structures/presence.d.ts.map +1 -1
  97. package/dist/foundations/structures/presence.js +2 -2
  98. package/dist/foundations/structures/presence.js.map +1 -1
  99. package/dist/foundations/structures/slot.d.ts +2 -1
  100. package/dist/foundations/structures/slot.d.ts.map +1 -1
  101. package/dist/foundations/structures/slot.js.map +1 -1
  102. package/dist/foundations/utilities/aria.d.ts.map +1 -1
  103. package/dist/foundations/utilities/aria.js.map +1 -1
  104. package/dist/foundations/utilities/compose-handlers.d.ts.map +1 -1
  105. package/dist/foundations/utilities/compose-handlers.js.map +1 -1
  106. package/dist/foundations/utilities/compose-ref.d.ts.map +1 -1
  107. package/dist/foundations/utilities/compose-ref.js.map +1 -1
  108. package/dist/foundations/utilities/event-types.d.ts.map +1 -1
  109. package/dist/foundations/utilities/merge-props.js.map +1 -1
  110. package/dist/foundations/utilities/use-id.d.ts.map +1 -1
  111. package/dist/foundations/utilities/use-id.js.map +1 -1
  112. package/dist/fx/fx.d.ts.map +1 -1
  113. package/dist/fx/fx.js.map +1 -1
  114. package/dist/fx/noop.js.map +1 -1
  115. package/dist/fx/timing.d.ts +5 -4
  116. package/dist/fx/timing.d.ts.map +1 -1
  117. package/dist/fx/timing.js +7 -4
  118. package/dist/fx/timing.js.map +1 -1
  119. package/dist/index.js.map +1 -1
  120. package/dist/jsx/types.d.ts +3 -3
  121. package/dist/jsx/types.d.ts.map +1 -1
  122. package/dist/jsx/utils.d.ts.map +1 -1
  123. package/dist/jsx/utils.js.map +1 -1
  124. package/dist/jsx-dev-runtime.d.ts +6 -2
  125. package/dist/jsx-dev-runtime.d.ts.map +1 -1
  126. package/dist/jsx-dev-runtime.js.map +1 -1
  127. package/dist/jsx-runtime.d.ts +16 -6
  128. package/dist/jsx-runtime.d.ts.map +1 -1
  129. package/dist/jsx-runtime.js.map +1 -1
  130. package/dist/renderer/children.js.map +1 -1
  131. package/dist/renderer/cleanup.js +40 -13
  132. package/dist/renderer/cleanup.js.map +1 -1
  133. package/dist/renderer/dom.js +163 -63
  134. package/dist/renderer/dom.js.map +1 -1
  135. package/dist/renderer/evaluate.js +9 -6
  136. package/dist/renderer/evaluate.js.map +1 -1
  137. package/dist/renderer/fastpath.js.map +1 -1
  138. package/dist/renderer/for-commit.js +1 -0
  139. package/dist/renderer/for-commit.js.map +1 -1
  140. package/dist/renderer/index.js.map +1 -1
  141. package/dist/renderer/keyed.js.map +1 -1
  142. package/dist/renderer/reconcile.js +34 -0
  143. package/dist/renderer/reconcile.js.map +1 -1
  144. package/dist/renderer/utils.js +34 -3
  145. package/dist/renderer/utils.js.map +1 -1
  146. package/dist/router/index.d.ts +2 -2
  147. package/dist/router/match.js +16 -2
  148. package/dist/router/match.js.map +1 -1
  149. package/dist/router/navigate.d.ts +9 -1
  150. package/dist/router/navigate.d.ts.map +1 -1
  151. package/dist/router/navigate.js +235 -81
  152. package/dist/router/navigate.js.map +1 -1
  153. package/dist/router/policy.d.ts +7 -7
  154. package/dist/router/policy.d.ts.map +1 -1
  155. package/dist/router/policy.js +5 -7
  156. package/dist/router/policy.js.map +1 -1
  157. package/dist/router/route-context.js.map +1 -1
  158. package/dist/router/route.d.ts +20 -9
  159. package/dist/router/route.d.ts.map +1 -1
  160. package/dist/router/route.js +95 -29
  161. package/dist/router/route.js.map +1 -1
  162. package/dist/runtime/child-scope.d.ts.map +1 -1
  163. package/dist/runtime/child-scope.js +5 -1
  164. package/dist/runtime/child-scope.js.map +1 -1
  165. package/dist/runtime/component.d.ts +5 -2
  166. package/dist/runtime/component.d.ts.map +1 -1
  167. package/dist/runtime/component.js +85 -25
  168. package/dist/runtime/component.js.map +1 -1
  169. package/dist/runtime/context.d.ts +5 -2
  170. package/dist/runtime/context.d.ts.map +1 -1
  171. package/dist/runtime/context.js +5 -2
  172. package/dist/runtime/context.js.map +1 -1
  173. package/dist/runtime/control.d.ts.map +1 -1
  174. package/dist/runtime/control.js.map +1 -1
  175. package/dist/runtime/derive.d.ts.map +1 -1
  176. package/dist/runtime/derive.js +3 -1
  177. package/dist/runtime/derive.js.map +1 -1
  178. package/dist/runtime/dev-namespace.js.map +1 -1
  179. package/dist/runtime/effect.d.ts.map +1 -1
  180. package/dist/runtime/effect.js +17 -11
  181. package/dist/runtime/effect.js.map +1 -1
  182. package/dist/runtime/events.js +43 -1
  183. package/dist/runtime/events.js.map +1 -1
  184. package/dist/runtime/execution-model.js.map +1 -1
  185. package/dist/runtime/fastlane.js +2 -23
  186. package/dist/runtime/fastlane.js.map +1 -1
  187. package/dist/runtime/for-bench.d.ts.map +1 -1
  188. package/dist/runtime/for-bench.js.map +1 -1
  189. package/dist/runtime/for.d.ts +1 -1
  190. package/dist/runtime/for.d.ts.map +1 -1
  191. package/dist/runtime/for.js +36 -12
  192. package/dist/runtime/for.js.map +1 -1
  193. package/dist/runtime/operations.d.ts +3 -13
  194. package/dist/runtime/operations.d.ts.map +1 -1
  195. package/dist/runtime/operations.js +47 -39
  196. package/dist/runtime/operations.js.map +1 -1
  197. package/dist/runtime/perf-metrics.js.map +1 -1
  198. package/dist/runtime/readable.d.ts +1 -0
  199. package/dist/runtime/readable.d.ts.map +1 -1
  200. package/dist/runtime/readable.js +6 -1
  201. package/dist/runtime/readable.js.map +1 -1
  202. package/dist/runtime/resource-cell.js +13 -2
  203. package/dist/runtime/resource-cell.js.map +1 -1
  204. package/dist/runtime/scheduler.d.ts.map +1 -1
  205. package/dist/runtime/scheduler.js +8 -4
  206. package/dist/runtime/scheduler.js.map +1 -1
  207. package/dist/runtime/selector.d.ts.map +1 -1
  208. package/dist/runtime/selector.js +8 -2
  209. package/dist/runtime/selector.js.map +1 -1
  210. package/dist/runtime/snapshot-source.d.ts.map +1 -1
  211. package/dist/runtime/snapshot-source.js.map +1 -1
  212. package/dist/runtime/ssr-bridge.js.map +1 -1
  213. package/dist/runtime/state.d.ts +4 -3
  214. package/dist/runtime/state.d.ts.map +1 -1
  215. package/dist/runtime/state.js.map +1 -1
  216. package/dist/ssg/batch-render.js +4 -8
  217. package/dist/ssg/batch-render.js.map +1 -1
  218. package/dist/ssg/create-static-gen.d.ts +10 -2
  219. package/dist/ssg/create-static-gen.d.ts.map +1 -1
  220. package/dist/ssg/create-static-gen.js +5 -4
  221. package/dist/ssg/create-static-gen.js.map +1 -1
  222. package/dist/ssg/generate-metadata.js.map +1 -1
  223. package/dist/ssg/incremental-manifest.js.map +1 -1
  224. package/dist/ssg/resolve-ssg-data.js +54 -12
  225. package/dist/ssg/resolve-ssg-data.js.map +1 -1
  226. package/dist/ssg/route-utils.js.map +1 -1
  227. package/dist/ssg/types.d.ts +8 -7
  228. package/dist/ssg/types.d.ts.map +1 -1
  229. package/dist/ssg/write-static-files.js.map +1 -1
  230. package/dist/ssr/attrs.js +3 -2
  231. package/dist/ssr/attrs.js.map +1 -1
  232. package/dist/ssr/context.d.ts +1 -0
  233. package/dist/ssr/context.d.ts.map +1 -1
  234. package/dist/ssr/context.js +1 -0
  235. package/dist/ssr/context.js.map +1 -1
  236. package/dist/ssr/errors.d.ts.map +1 -1
  237. package/dist/ssr/escape.js.map +1 -1
  238. package/dist/ssr/index.d.ts +8 -12
  239. package/dist/ssr/index.d.ts.map +1 -1
  240. package/dist/ssr/index.js +55 -30
  241. package/dist/ssr/index.js.map +1 -1
  242. package/dist/ssr/render-keys.js +15 -4
  243. package/dist/ssr/render-keys.js.map +1 -1
  244. package/dist/ssr/render-resolved.js +33 -0
  245. package/dist/ssr/render-resolved.js.map +1 -0
  246. package/dist/ssr/sink.js.map +1 -1
  247. package/dist/ssr/types.d.ts.map +1 -1
  248. package/dist/ssr/verify-hydration.js +5 -6
  249. package/dist/ssr/verify-hydration.js.map +1 -1
  250. package/package.json +13 -5
@@ -1,14 +1,23 @@
1
+ import { RenderableChild } from "./vnode.js";
2
+
1
3
  //#region src/common/router.d.ts
2
4
  /**
3
5
  * Common call contracts: Router types
4
6
  */
7
+ type RouteParams = Record<string, string>;
8
+ type StripRoutePathSuffix<Path extends string> = Path extends `${infer Base}?${string}` ? StripRoutePathSuffix<Base> : Path extends `${infer Base}#${string}` ? StripRoutePathSuffix<Base> : Path;
9
+ type TrimRoutePathSlashes<Path extends string> = Path extends `/${infer Rest}` ? TrimRoutePathSlashes<Rest> : Path extends `${infer Rest}/` ? TrimRoutePathSlashes<Rest> : Path;
10
+ type ExtractRouteSegmentParam<Segment extends string> = Segment extends `{${infer Param}}` ? Param : Segment extends '*' ? '*' : never;
11
+ type ExtractRoutePathParamNames<Path extends string> = TrimRoutePathSlashes<StripRoutePathSuffix<Path>> extends `${infer Segment}/${infer Rest}` ? ExtractRouteSegmentParam<Segment> | ExtractRoutePathParamNames<Rest> : ExtractRouteSegmentParam<TrimRoutePathSlashes<StripRoutePathSuffix<Path>>>;
12
+ type RoutePathParams<Path extends string> = [ExtractRoutePathParamNames<Path>] extends [never] ? Record<never, string> : { [Key in ExtractRoutePathParamNames<Path>]: string };
5
13
  /**
6
14
  * A route page component: a regular component that receives route params as
7
- * props (always `Record<string, string>` derived from the URL pattern).
15
+ * props derived from the URL pattern.
8
16
  *
9
- * Components may accept no params at all — `() => unknown` is assignable.
17
+ * Components may accept no params at all — zero-argument components are still
18
+ * assignable.
10
19
  */
11
- type RouteComponent = (props: Record<string, string>) => unknown;
20
+ type RouteComponent<TParams extends RouteParams = RouteParams> = (props: TParams) => RenderableChild;
12
21
  type RouteMode = 'spa' | 'ssr' | 'ssg';
13
22
  type RouteAuthMode = true | 'guest';
14
23
  type AccessRedirectStatus = 301 | 302 | 303 | 307 | 308;
@@ -27,9 +36,9 @@ interface AccessDenyDecision {
27
36
  status: AccessDenyStatus;
28
37
  }
29
38
  type AccessDecision = AccessAllowDecision | AccessRedirectDecision | AccessDenyDecision;
30
- interface RouteContext<Session = unknown, User = unknown> {
39
+ interface RouteContext<Session = unknown, User = unknown, TParams extends RouteParams = RouteParams> {
31
40
  mode: RouteMode;
32
- params: Record<string, string>;
41
+ params: TParams;
33
42
  pathname: string;
34
43
  search: string;
35
44
  hash: string;
@@ -38,18 +47,18 @@ interface RouteContext<Session = unknown, User = unknown> {
38
47
  user: User | null;
39
48
  signal: AbortSignal;
40
49
  }
41
- type RoutePolicy = (context: RouteContext) => AccessDecision | Promise<AccessDecision>;
50
+ type RoutePolicy = (context: RouteContext) => AccessDecision | PromiseLike<AccessDecision>;
42
51
  interface RouteAuthState<Session = unknown, User = unknown> {
43
52
  session: Session | null;
44
53
  user: User | null;
45
54
  }
46
- type RouteAuthResolver<Session = unknown, User = unknown> = (context: Omit<RouteContext<Session, User>, 'session' | 'user'>) => RouteAuthState<Session, User> | Promise<RouteAuthState<Session, User>>;
55
+ type RouteAuthResolver<Session = unknown, User = unknown> = (context: Omit<RouteContext<Session, User>, 'session' | 'user'>) => RouteAuthState<Session, User> | PromiseLike<RouteAuthState<Session, User>>;
47
56
  interface RouteAuthOptions<Session = unknown, User = unknown> {
48
57
  resolve: RouteAuthResolver<Session, User>;
49
- loginPath?: string | ((context: RouteContext<Session, User>) => string | Promise<string>);
50
- guestRedirectTo?: string | ((context: RouteContext<Session, User>) => string | Promise<string>);
51
- hasRole?: (user: User, role: string, context: RouteContext<Session, User>) => boolean | Promise<boolean>;
52
- hasPermission?: (user: User, permission: string, context: RouteContext<Session, User>) => boolean | Promise<boolean>;
58
+ loginPath?: string | ((context: RouteContext<Session, User>) => string | PromiseLike<string>);
59
+ guestRedirectTo?: string | ((context: RouteContext<Session, User>) => string | PromiseLike<string>);
60
+ hasRole?: (user: User, role: string, context: RouteContext<Session, User>) => boolean | PromiseLike<boolean>;
61
+ hasPermission?: (user: User, permission: string, context: RouteContext<Session, User>) => boolean | PromiseLike<boolean>;
53
62
  }
54
63
  interface CommonAccessOptions {
55
64
  auth?: RouteAuthMode;
@@ -65,11 +74,11 @@ interface CommonAccessOptions {
65
74
  * - `title`: page title hint used by SSG and document-meta integrations
66
75
  * - `namespace`: MFE namespace key for grouped route management
67
76
  */
68
- interface RouteOptions extends CommonAccessOptions {
77
+ interface RouteOptions<TParams extends RouteParams = RouteParams> extends CommonAccessOptions {
69
78
  loader?: (context: {
70
- params: Record<string, string>;
79
+ params: TParams;
71
80
  }) => unknown;
72
- entries?: () => Array<Record<string, string>> | Promise<Array<Record<string, string>>>;
81
+ entries?: () => Array<TParams> | Promise<Array<TParams>>;
73
82
  title?: string;
74
83
  namespace?: string;
75
84
  }
@@ -90,8 +99,8 @@ interface ParsedSegment {
90
99
  /** Resolved layout component as stored in a route record's layout chain. */
91
100
  interface LayoutScopeRecord {
92
101
  component: (props: {
93
- children?: unknown;
94
- }) => unknown;
102
+ children?: RenderableChild;
103
+ }) => RenderableChild;
95
104
  }
96
105
  /** Resolved page host component as stored in a route record's page chain. */
97
106
  interface PageScopeRecord {
@@ -107,16 +116,16 @@ interface RouteRequestOptions {
107
116
  auth?: RouteAuthOptions;
108
117
  signal?: AbortSignal;
109
118
  }
110
- interface RouteRenderResult {
119
+ interface RouteRenderResult<TParams extends RouteParams = RouteParams> {
111
120
  kind: 'render';
112
- handler: RouteHandler;
113
- params: Record<string, string>;
121
+ handler: RouteHandler<TParams>;
122
+ params: TParams;
114
123
  }
115
- type RouteRequestResult = RouteRenderResult | AccessRedirectDecision | AccessDenyDecision | null;
124
+ type RouteRequestResult<TParams extends RouteParams = RouteParams> = RouteRenderResult<TParams> | AccessRedirectDecision | AccessDenyDecision | null;
116
125
  interface GroupHelperOptions extends CommonAccessOptions {
117
126
  layout?: (props: {
118
- children?: unknown;
119
- }) => unknown;
127
+ children?: RenderableChild;
128
+ }) => RenderableChild;
120
129
  }
121
130
  /**
122
131
  * A fully normalized route record produced by `route(path, Component, options?)`.
@@ -164,23 +173,23 @@ interface RouteManifest {
164
173
  records: RouteRecord[];
165
174
  auth?: RouteAuthOptions;
166
175
  }
167
- interface RouteHandler {
168
- (params: Record<string, string>, context?: {
176
+ interface RouteHandler<TParams extends RouteParams = RouteParams> {
177
+ (params: TParams, context?: {
169
178
  signal: AbortSignal;
170
- }): unknown;
179
+ }): RenderableChild;
171
180
  }
172
- interface Route {
181
+ interface Route<TParams extends RouteParams = RouteParams> {
173
182
  path: string;
174
- handler: RouteHandler;
183
+ handler: RouteHandler<TParams>;
175
184
  namespace?: string;
176
185
  }
177
- interface ResolvedRoute {
178
- handler: RouteHandler;
179
- params: Record<string, string>;
186
+ interface ResolvedRoute<TParams extends RouteParams = RouteParams> {
187
+ handler: RouteHandler<TParams>;
188
+ params: TParams;
180
189
  }
181
- interface RouteMatch {
190
+ interface RouteMatch<TParams extends RouteParams = RouteParams> {
182
191
  path: string;
183
- params: Readonly<Record<string, string>>;
192
+ params: Readonly<TParams>;
184
193
  name?: string;
185
194
  namespace?: string;
186
195
  }
@@ -190,15 +199,15 @@ interface RouteQuery {
190
199
  has(key: string): boolean;
191
200
  toJSON(): Record<string, string | string[]>;
192
201
  }
193
- interface RouteSnapshot {
202
+ interface RouteSnapshot<TParams extends RouteParams = RouteParams> {
194
203
  path: string;
195
- params: Readonly<Record<string, string>>;
204
+ params: Readonly<TParams>;
196
205
  query: Readonly<RouteQuery>;
197
206
  hash: string | null;
198
207
  name?: string;
199
208
  namespace?: string;
200
- matches: readonly RouteMatch[];
209
+ matches: readonly RouteMatch<TParams>[];
201
210
  }
202
211
  //#endregion
203
- export { AccessDecision, AccessDenyDecision, AccessDenyStatus, AccessRedirectDecision, AccessRedirectStatus, GroupHelperOptions, LayoutScopeRecord, PageHelperOptions, PageScopeRecord, ParsedSegment, RegisterRoutesOptions, ResolvedRoute, Route, RouteAuthMode, RouteAuthOptions, RouteAuthResolver, RouteAuthState, RouteComponent, RouteContext, RouteDefinition, RouteHandler, RouteManifest, RouteMatch, RouteMode, RouteOptions, RoutePolicy, RouteQuery, RouteRecord, RouteRenderResult, RouteRequestOptions, RouteRequestResult, RouteSnapshot };
212
+ export { AccessAllowDecision, AccessDecision, AccessDenyDecision, AccessDenyStatus, AccessRedirectDecision, AccessRedirectStatus, GroupHelperOptions, LayoutScopeRecord, PageHelperOptions, PageScopeRecord, ParsedSegment, RegisterRoutesOptions, ResolvedRoute, Route, RouteAuthMode, RouteAuthOptions, RouteAuthResolver, RouteAuthState, RouteComponent, RouteContext, RouteDefinition, RouteHandler, RouteManifest, RouteMatch, RouteMode, RouteOptions, RouteParams, RoutePathParams, RoutePolicy, RouteQuery, RouteRecord, RouteRenderResult, RouteRequestOptions, RouteRequestResult, RouteSnapshot };
204
213
  //# sourceMappingURL=router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","names":[],"sources":["../../src/common/router.ts"],"mappings":"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"}
1
+ {"version":3,"file":"router.d.ts","names":[],"sources":["../../src/common/router.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-errors.d.ts","names":[],"sources":["../../src/common/ssr-errors.ts"],"mappings":";;AAIA;;cAAa,mBAAA,SAA4B,KAAA;EAAA,SAC9B,IAAA;cAEP,OAAA;AAAA"}
1
+ {"version":3,"file":"ssr-errors.d.ts","names":[],"sources":["../../src/common/ssr-errors.ts"],"mappings":";;AAIA;;cAAa,mBAAA,SAA4B,KAAK;EAAA,SACnC,IAAA;cAEP,OAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssr-errors.js","names":[],"sources":["../../src/common/ssr-errors.ts"],"sourcesContent":["/**\n * Common call contracts: SSR error types\n */\n\nexport class SSRDataMissingError extends Error {\n readonly code = 'SSR_DATA_MISSING';\n constructor(\n message = 'Server-side rendering requires all data to be available synchronously. This component attempted to use async data during SSR.'\n ) {\n super(message);\n this.name = 'SSRDataMissingError';\n Object.setPrototypeOf(this, SSRDataMissingError.prototype);\n }\n}\n"],"mappings":";;;;AAIA,IAAa,sBAAb,MAAa,4BAA4B,MAAM;CAE7C,YACE,UAAU,iIACV;EACA,MAAM,QAAQ;cAJA;EAKd,KAAK,OAAO;EACZ,OAAO,eAAe,MAAM,oBAAoB,UAAU"}
1
+ {"version":3,"file":"ssr-errors.js","names":[],"sources":["../../src/common/ssr-errors.ts"],"sourcesContent":["/**\n * Common call contracts: SSR error types\n */\n\nexport class SSRDataMissingError extends Error {\n readonly code = 'SSR_DATA_MISSING';\n constructor(\n message = 'Server-side rendering requires all data to be available synchronously. This component attempted to use async data during SSR.'\n ) {\n super(message);\n this.name = 'SSRDataMissingError';\n Object.setPrototypeOf(this, SSRDataMissingError.prototype);\n }\n}\n"],"mappings":";;;;AAIA,IAAa,sBAAb,MAAa,4BAA4B,MAAM;CAE7C,YACE,UAAU,iIACV;EACA,MAAM,OAAO;cAJC;EAKd,KAAK,OAAO;EACZ,OAAO,eAAe,MAAM,oBAAoB,SAAS;CAC3D;AACF"}
@@ -3,6 +3,7 @@
3
3
  * Common call contracts: SSR types
4
4
  */
5
5
  type SSRData = Record<string, unknown>;
6
+ declare const SSR_RENDER_DATA_ATTR = "data-askr-render-data";
6
7
  /** Full context for sink-based streaming SSR */
7
8
  type SSRContext = {
8
9
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ssr.d.ts","names":[],"sources":["../../src/common/ssr.ts"],"mappings":";;AAIA;;KAAY,OAAA,GAAU,MAAA;;KAGV,UAAA;EACV,GAAA;EACA,IAAA;EACA,IAAA,GAAO,OAAA;EACP,MAAA,GAAS,MAAA;EACT,MAAA,GAAS,WAAA;AAAA;;KAIC,aAAA;EACV,IAAA;AAAA"}
1
+ {"version":3,"file":"ssr.d.ts","names":[],"sources":["../../src/common/ssr.ts"],"mappings":";;AAIA;;KAAY,OAAA,GAAU,MAAM;AAAA,cAEf,oBAAA;AAFe;AAAA,KAKhB,UAAA;EACV,GAAA;EACA,IAAA;EACA,IAAA,GAAO,OAAA;EACP,MAAA,GAAS,MAAA;EACT,MAAA,GAAS,WAAA;AAAA;;KAIC,aAAA;EACV,IAAI;AAAA"}
@@ -0,0 +1,6 @@
1
+ //#region src/common/ssr.ts
2
+ const SSR_RENDER_DATA_ATTR = "data-askr-render-data";
3
+ //#endregion
4
+ export { SSR_RENDER_DATA_ATTR };
5
+
6
+ //# sourceMappingURL=ssr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssr.js","names":[],"sources":["../../src/common/ssr.ts"],"sourcesContent":["/**\n * Common call contracts: SSR types\n */\n\nexport type SSRData = Record<string, unknown>;\n\nexport const SSR_RENDER_DATA_ATTR = 'data-askr-render-data';\n\n/** Full context for sink-based streaming SSR */\nexport type SSRContext = {\n url: string;\n seed: number;\n data?: SSRData;\n params?: Record<string, string>;\n signal?: AbortSignal;\n};\n\n/** Lightweight context for synchronous render passes */\nexport type RenderContext = {\n seed: number;\n};\n"],"mappings":";AAMA,MAAa,uBAAuB"}
@@ -13,8 +13,9 @@ interface DOMElement {
13
13
  _forState?: ForState<unknown>;
14
14
  }
15
15
  type VNode = DOMElement | string | number | boolean | null | undefined;
16
+ type RenderableChild = VNode | readonly VNode[];
16
17
  declare const __FOR_BOUNDARY__: symbol;
17
18
  declare function _isDOMElement(node: unknown): node is DOMElement;
18
19
  //#endregion
19
- export { VNode };
20
+ export { RenderableChild, VNode };
20
21
  //# sourceMappingURL=vnode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vnode.d.ts","names":[],"sources":["../../src/common/vnode.ts"],"mappings":";;;;cAUa,kBAAA;AAAA,UAEI,UAAA;EAKf,IAAA,aAAiB,KAAA,EAAO,KAAA;EACxB,KAAA,GAAQ,KAAA;EACR,QAAA,GAAW,KAAA;EACX,GAAA;EAAA,CACC,MAAA,CAAO,QAAA;EACR,aAAA,GAAgB,oBAAA;EAChB,SAAA,GAAY,QAAA;AAAA;AAAA,KAIF,KAAA,GAAQ,UAAA;AAAA,cAIP,gBAAA;AAAA,iBAEG,aAAA,CAAc,IAAA,YAAgB,IAAA,IAAQ,UAAA"}
1
+ {"version":3,"file":"vnode.d.ts","names":[],"sources":["../../src/common/vnode.ts"],"mappings":";;;;cAUa,kBAAA;AAAA,UAEI,UAAA;EAKf,IAAA,aAAiB,KAAA,EAAO,KAAA;EACxB,KAAA,GAAQ,KAAA;EACR,QAAA,GAAW,KAAA;EACX,GAAA;EAAA,CACC,MAAA,CAAO,QAAA;EACR,aAAA,GAAgB,oBAAA;EAChB,SAAA,GAAY,QAAA;AAAA;AAAA,KAIF,KAAA,GAAQ,UAAU;AAAA,KAClB,eAAA,GAAkB,KAAA,YAAiB,KAAK;AAAA,cAIvC,gBAAA;AAAA,iBAEG,aAAA,CAAc,IAAA,YAAgB,IAAA,IAAQ,UAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"vnode.js","names":[],"sources":["../../src/common/vnode.ts"],"sourcesContent":["/**\n * Common call contracts: VNode / virtual DOM shapes\n */\n\nimport type { Props } from './props';\nimport type { ControlBoundaryState } from '../runtime/control';\nimport type { ForState } from '../runtime/for';\nexport { __CONTROL_BOUNDARY__ } from './control';\nimport { __CONTROL_BOUNDARY__ } from './control';\n\nexport const __ERROR_BOUNDARY__ = Symbol.for('askr.error-boundary');\n\nexport interface DOMElement {\n // Element `type` can be an intrinsic tag name, a component function, or\n // a special symbol (e.g. `Fragment`). Include `symbol` in the type union\n // so runtime comparisons against `Fragment` are type-safe.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n type: string | ((props: Props) => any) | symbol;\n props?: Props;\n children?: VNode[];\n key?: string | number | null;\n [Symbol.iterator]?: never;\n _controlState?: ControlBoundaryState; // Internal: control boundary state\n _forState?: ForState<unknown>; // Deprecated internal alias during migration\n}\n\n// Type for virtual DOM nodes\nexport type VNode = DOMElement | string | number | boolean | null | undefined;\n\n// Backward-compatible internal alias while renderer/runtime migrates away from\n// the old For-only boundary naming.\nexport const __FOR_BOUNDARY__ = __CONTROL_BOUNDARY__;\n\nexport function _isDOMElement(node: unknown): node is DOMElement {\n return typeof node === 'object' && node !== null && 'type' in node;\n}\n"],"mappings":";;AAUA,MAAa,qBAAqB,OAAO,IAAI,sBAAsB;AAqBnE,MAAa,mBAAmB;AAEhC,SAAgB,cAAc,MAAmC;CAC/D,OAAO,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU"}
1
+ {"version":3,"file":"vnode.js","names":[],"sources":["../../src/common/vnode.ts"],"sourcesContent":["/**\n * Common call contracts: VNode / virtual DOM shapes\n */\n\nimport type { Props } from './props';\nimport type { ControlBoundaryState } from '../runtime/control';\nimport type { ForState } from '../runtime/for';\nexport { __CONTROL_BOUNDARY__ } from './control';\nimport { __CONTROL_BOUNDARY__ } from './control';\n\nexport const __ERROR_BOUNDARY__ = Symbol.for('askr.error-boundary');\n\nexport interface DOMElement {\n // Element `type` can be an intrinsic tag name, a component function, or\n // a special symbol (e.g. `Fragment`). Include `symbol` in the type union\n // so runtime comparisons against `Fragment` are type-safe.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n type: string | ((props: Props) => any) | symbol;\n props?: Props;\n children?: VNode[];\n key?: string | number | null;\n [Symbol.iterator]?: never;\n _controlState?: ControlBoundaryState; // Internal: control boundary state\n _forState?: ForState<unknown>; // Deprecated internal alias during migration\n}\n\n// Type for virtual DOM nodes\nexport type VNode = DOMElement | string | number | boolean | null | undefined;\nexport type RenderableChild = VNode | readonly VNode[];\n\n// Backward-compatible internal alias while renderer/runtime migrates away from\n// the old For-only boundary naming.\nexport const __FOR_BOUNDARY__ = __CONTROL_BOUNDARY__;\n\nexport function _isDOMElement(node: unknown): node is DOMElement {\n return typeof node === 'object' && node !== null && 'type' in node;\n}\n"],"mappings":";;AAUA,MAAa,qBAAqB,OAAO,IAAI,qBAAqB;AAsBlE,MAAa,mBAAmB;AAEhC,SAAgB,cAAc,MAAmC;CAC/D,OAAO,OAAO,SAAS,YAAY,SAAS,QAAQ,UAAU;AAChE"}
@@ -1,12 +1,15 @@
1
1
  import { Props } from "../common/props.js";
2
2
  import { JSXElement } from "../common/jsx.js";
3
3
  import { ComponentInstance } from "../runtime/component.js";
4
+ import { VNode } from "../common/vnode.js";
4
5
 
5
6
  //#region src/components/error-boundary.d.ts
6
- type ErrorBoundaryFallbackRender = (error: unknown, reset: () => void) => unknown;
7
+ type ErrorBoundaryContent = VNode | readonly VNode[];
8
+ type ErrorBoundaryFallbackValue = ErrorBoundaryContent | Node;
9
+ type ErrorBoundaryFallbackRender = (error: unknown, reset: () => void) => ErrorBoundaryFallbackValue;
7
10
  interface ErrorBoundaryProps extends Props {
8
- children?: unknown;
9
- fallback?: unknown | ErrorBoundaryFallbackRender;
11
+ children?: ErrorBoundaryContent;
12
+ fallback?: ErrorBoundaryFallbackValue | ErrorBoundaryFallbackRender;
10
13
  onError?: (error: unknown) => void;
11
14
  resetKey?: unknown;
12
15
  }
@@ -17,7 +20,7 @@ type ErrorBoundaryVNode = JSXElement & {
17
20
  declare function ErrorBoundary(props: ErrorBoundaryProps): JSXElement;
18
21
  declare function isErrorBoundaryVNode(value: unknown): value is ErrorBoundaryVNode;
19
22
  declare function resolveErrorBoundaryState(vnode: ErrorBoundaryVNode): ErrorBoundaryState | null;
20
- declare function resolveErrorBoundaryFallback(fallback: ErrorBoundaryProps['fallback'], error: unknown, reset: () => void): unknown;
23
+ declare function resolveErrorBoundaryFallback(fallback: ErrorBoundaryProps['fallback'], error: unknown, reset: () => void): ErrorBoundaryFallbackValue;
21
24
  declare function createBoundaryReset(instance: ComponentInstance): () => void;
22
25
  declare function reportBoundaryError(instance: ComponentInstance, error: unknown, onError?: (error: unknown) => void): void;
23
26
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"error-boundary.d.ts","names":[],"sources":["../../src/components/error-boundary.tsx"],"mappings":";;;;;KAUY,2BAAA,IACV,KAAA,WACA,KAAA;AAAA,UAGe,kBAAA,SAA2B,KAAA;EAC1C,QAAA;EACA,QAAA,aAAqB,2BAAA;EACrB,OAAA,IAAW,KAAA;EACX,QAAA;AAAA;AAAA,KAGG,kBAAA,GAAqB,WAAA,CAAY,iBAAA;AAAA,KAEjC,kBAAA,GAAqB,UAAA;EACxB,UAAA,GAAa,iBAAA;AAAA;AAAA,iBA+DC,aAAA,CAAc,KAAA,EAAO,kBAAA,GAAqB,UAAA;AAAA,iBAY1C,oBAAA,CACd,KAAA,YACC,KAAA,IAAS,kBAAA;AAAA,iBAQI,yBAAA,CACd,KAAA,EAAO,kBAAA,GACN,kBAAA;AAAA,iBAIa,4BAAA,CACd,QAAA,EAAU,kBAAA,cACV,KAAA,WACA,KAAA;AAAA,iBAoDc,mBAAA,CAAoB,QAAA,EAAU,iBAAA;AAAA,iBAc9B,mBAAA,CACd,QAAA,EAAU,iBAAA,EACV,KAAA,WACA,OAAA,IAAW,KAAA"}
1
+ {"version":3,"file":"error-boundary.d.ts","names":[],"sources":["../../src/components/error-boundary.tsx"],"mappings":";;;;;;KAWK,oBAAA,GAAuB,KAAA,YAAiB,KAAK;AAAA,KAC7C,0BAAA,GAA6B,oBAAA,GAAuB,IAAI;AAAA,KAEjD,2BAAA,IACV,KAAA,WACA,KAAA,iBACG,0BAA0B;AAAA,UAEd,kBAAA,SAA2B,KAAA;EAC1C,QAAA,GAAW,oBAAA;EACX,QAAA,GAAW,0BAAA,GAA6B,2BAAA;EACxC,OAAA,IAAW,KAAA;EACX,QAAA;AAAA;AAAA,KAGG,kBAAA,GAAqB,WAAW,CAAC,iBAAA;AAAA,KAEjC,kBAAA,GAAqB,UAAA;EACxB,UAAA,GAAa,iBAAiB;AAAA;AAAA,iBA+DhB,aAAA,CAAc,KAAA,EAAO,kBAAA,GAAqB,UAAU;AAAA,iBAYpD,oBAAA,CACd,KAAA,YACC,KAAA,IAAS,kBAAkB;AAAA,iBAQd,yBAAA,CACd,KAAA,EAAO,kBAAA,GACN,kBAAkB;AAAA,iBAIL,4BAAA,CACd,QAAA,EAAU,kBAAA,cACV,KAAA,WACA,KAAA,eACC,0BAA0B;AAAA,iBAmDb,mBAAA,CAAoB,QAA2B,EAAjB,iBAAiB;AAAA,iBAc/C,mBAAA,CACd,QAAA,EAAU,iBAAiB,EAC3B,KAAA,WACA,OAAA,IAAW,KAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"error-boundary.js","names":[],"sources":["../../src/components/error-boundary.tsx"],"sourcesContent":["import type { Props } from '../common/props';\nimport { ELEMENT_TYPE, type JSXElement } from '../common/jsx';\nimport { __ERROR_BOUNDARY__ } from '../common/vnode';\nimport {\n getCurrentComponentInstance,\n type ComponentInstance,\n} from '../runtime/component';\nimport { logger } from '../dev/logger';\nimport { isDevelopmentEnvironment } from '../common/env';\n\nexport type ErrorBoundaryFallbackRender = (\n error: unknown,\n reset: () => void\n) => unknown;\n\nexport interface ErrorBoundaryProps extends Props {\n children?: unknown;\n fallback?: unknown | ErrorBoundaryFallbackRender;\n onError?: (error: unknown) => void;\n resetKey?: unknown;\n}\n\ntype ErrorBoundaryState = NonNullable<ComponentInstance['errorBoundaryState']>;\n\ntype ErrorBoundaryVNode = JSXElement & {\n __instance?: ComponentInstance;\n};\n\nfunction getBoundaryMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message || error.name || 'Unknown error';\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n}\n\nfunction ensureBoundaryState(\n instance: ComponentInstance,\n resetKey: unknown\n): ErrorBoundaryState {\n const boundaryState =\n instance.errorBoundaryState ??\n (instance.errorBoundaryState = {\n error: null,\n resetKey,\n notified: false,\n });\n\n if (!Object.is(boundaryState.resetKey, resetKey)) {\n boundaryState.error = null;\n boundaryState.resetKey = resetKey;\n boundaryState.notified = false;\n }\n\n return boundaryState;\n}\n\nfunction createBoundaryVNode(\n instance: ComponentInstance,\n props: ErrorBoundaryProps\n): ErrorBoundaryVNode {\n const key =\n typeof props.key === 'symbol'\n ? null\n : ((props.key ?? null) as string | number | null);\n\n return {\n $$typeof: ELEMENT_TYPE,\n type: __ERROR_BOUNDARY__,\n props: {\n children: props.children,\n fallback: props.fallback,\n onError: props.onError,\n resetKey: props.resetKey,\n },\n key,\n __instance: instance,\n };\n}\n\nexport function ErrorBoundary(props: ErrorBoundaryProps): JSXElement {\n const instance = getCurrentComponentInstance();\n if (!instance) {\n throw new Error(\n '[Askr] ErrorBoundary() can only be used during component render execution.'\n );\n }\n\n ensureBoundaryState(instance, props.resetKey);\n return createBoundaryVNode(instance, props);\n}\n\nexport function isErrorBoundaryVNode(\n value: unknown\n): value is ErrorBoundaryVNode {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as ErrorBoundaryVNode).type === __ERROR_BOUNDARY__\n );\n}\n\nexport function resolveErrorBoundaryState(\n vnode: ErrorBoundaryVNode\n): ErrorBoundaryState | null {\n return vnode.__instance?.errorBoundaryState ?? null;\n}\n\nexport function resolveErrorBoundaryFallback(\n fallback: ErrorBoundaryProps['fallback'],\n error: unknown,\n reset: () => void\n): unknown {\n if (typeof fallback === 'function') {\n return fallback(error, reset);\n }\n\n if (fallback !== undefined) {\n return fallback;\n }\n\n const message = getBoundaryMessage(error);\n const wrapper = document.createElement('div');\n wrapper.setAttribute('role', 'alert');\n wrapper.setAttribute('data-askr-error-boundary', 'true');\n wrapper.style.boxSizing = 'border-box';\n wrapper.style.padding = '1rem';\n wrapper.style.border = '1px solid currentColor';\n wrapper.style.borderRadius = '0.75rem';\n wrapper.style.display = 'grid';\n wrapper.style.gap = '0.75rem';\n wrapper.style.maxWidth = '100%';\n\n const title = document.createElement('strong');\n title.textContent = 'Something went wrong while rendering this view.';\n\n const summary = document.createElement('p');\n summary.textContent =\n 'The app recovered into a visible fallback so the error is not hidden in the console.';\n summary.style.margin = '0';\n\n const details = document.createElement('details');\n details.open = isDevelopmentEnvironment();\n\n const detailsSummary = document.createElement('summary');\n detailsSummary.textContent = 'Error details';\n\n const pre = document.createElement('pre');\n pre.textContent = message;\n pre.style.margin = '0';\n pre.style.whiteSpace = 'pre-wrap';\n pre.style.wordBreak = 'break-word';\n\n const button = document.createElement('button');\n button.type = 'button';\n button.textContent = 'Try again';\n button.addEventListener('click', () => reset());\n\n details.append(detailsSummary, pre);\n wrapper.append(title, summary, details, button);\n return wrapper;\n}\n\nexport function createBoundaryReset(instance: ComponentInstance): () => void {\n return () => {\n const boundaryState = instance.errorBoundaryState;\n if (!boundaryState) {\n return;\n }\n boundaryState.error = null;\n boundaryState.notified = false;\n queueMicrotask(() => {\n instance._enqueueRun?.();\n });\n };\n}\n\nexport function reportBoundaryError(\n instance: ComponentInstance,\n error: unknown,\n onError?: (error: unknown) => void\n): void {\n const boundaryState = instance.errorBoundaryState;\n if (\n boundaryState &&\n Object.is(boundaryState.error, error) &&\n boundaryState.notified\n ) {\n return;\n }\n\n if (boundaryState) {\n boundaryState.error = error;\n boundaryState.notified = true;\n }\n\n try {\n onError?.(error);\n } catch (hookError) {\n logger.error('[Askr] ErrorBoundary onError handler threw:', hookError);\n }\n\n logger.error('[Askr] ErrorBoundary caught render error:', error);\n}\n"],"mappings":";;;;;;AA4BA,SAAS,mBAAmB,OAAwB;CAClD,IAAI,iBAAiB,OACnB,OAAO,MAAM,WAAW,MAAM,QAAQ;CAGxC,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,IAAI;EACF,OAAO,KAAK,UAAU,MAAM;SACtB;EACN,OAAO,OAAO,MAAM;;;AAIxB,SAAS,oBACP,UACA,UACoB;CACpB,MAAM,gBACJ,SAAS,uBACR,SAAS,qBAAqB;EAC7B,OAAO;EACP;EACA,UAAU;EACX;CAEH,IAAI,CAAC,OAAO,GAAG,cAAc,UAAU,SAAS,EAAE;EAChD,cAAc,QAAQ;EACtB,cAAc,WAAW;EACzB,cAAc,WAAW;;CAG3B,OAAO;;AAGT,SAAS,oBACP,UACA,OACoB;CACpB,MAAM,MACJ,OAAO,MAAM,QAAQ,WACjB,OACE,MAAM,OAAO;CAErB,OAAO;EACL,UAAU;EACV,MAAM;EACN,OAAO;GACL,UAAU,MAAM;GAChB,UAAU,MAAM;GAChB,SAAS,MAAM;GACf,UAAU,MAAM;GACjB;EACD;EACA,YAAY;EACb;;AAGH,SAAgB,cAAc,OAAuC;CACnE,MAAM,WAAW,6BAA6B;CAC9C,IAAI,CAAC,UACH,MAAM,IAAI,MACR,6EACD;CAGH,oBAAoB,UAAU,MAAM,SAAS;CAC7C,OAAO,oBAAoB,UAAU,MAAM;;AAmB7C,SAAgB,6BACd,UACA,OACA,OACS;CACT,IAAI,OAAO,aAAa,YACtB,OAAO,SAAS,OAAO,MAAM;CAG/B,IAAI,aAAa,QACf,OAAO;CAGT,MAAM,UAAU,mBAAmB,MAAM;CACzC,MAAM,UAAU,SAAS,cAAc,MAAM;CAC7C,QAAQ,aAAa,QAAQ,QAAQ;CACrC,QAAQ,aAAa,4BAA4B,OAAO;CACxD,QAAQ,MAAM,YAAY;CAC1B,QAAQ,MAAM,UAAU;CACxB,QAAQ,MAAM,SAAS;CACvB,QAAQ,MAAM,eAAe;CAC7B,QAAQ,MAAM,UAAU;CACxB,QAAQ,MAAM,MAAM;CACpB,QAAQ,MAAM,WAAW;CAEzB,MAAM,QAAQ,SAAS,cAAc,SAAS;CAC9C,MAAM,cAAc;CAEpB,MAAM,UAAU,SAAS,cAAc,IAAI;CAC3C,QAAQ,cACN;CACF,QAAQ,MAAM,SAAS;CAEvB,MAAM,UAAU,SAAS,cAAc,UAAU;CACjD,QAAQ,OAAO,0BAA0B;CAEzC,MAAM,iBAAiB,SAAS,cAAc,UAAU;CACxD,eAAe,cAAc;CAE7B,MAAM,MAAM,SAAS,cAAc,MAAM;CACzC,IAAI,cAAc;CAClB,IAAI,MAAM,SAAS;CACnB,IAAI,MAAM,aAAa;CACvB,IAAI,MAAM,YAAY;CAEtB,MAAM,SAAS,SAAS,cAAc,SAAS;CAC/C,OAAO,OAAO;CACd,OAAO,cAAc;CACrB,OAAO,iBAAiB,eAAe,OAAO,CAAC;CAE/C,QAAQ,OAAO,gBAAgB,IAAI;CACnC,QAAQ,OAAO,OAAO,SAAS,SAAS,OAAO;CAC/C,OAAO;;AAGT,SAAgB,oBAAoB,UAAyC;CAC3E,aAAa;EACX,MAAM,gBAAgB,SAAS;EAC/B,IAAI,CAAC,eACH;EAEF,cAAc,QAAQ;EACtB,cAAc,WAAW;EACzB,qBAAqB;GACnB,SAAS,eAAe;IACxB;;;AAIN,SAAgB,oBACd,UACA,OACA,SACM;CACN,MAAM,gBAAgB,SAAS;CAC/B,IACE,iBACA,OAAO,GAAG,cAAc,OAAO,MAAM,IACrC,cAAc,UAEd;CAGF,IAAI,eAAe;EACjB,cAAc,QAAQ;EACtB,cAAc,WAAW;;CAG3B,IAAI;EACF,UAAU,MAAM;UACT,WAAW;EAClB,OAAO,MAAM,+CAA+C,UAAU;;CAGxE,OAAO,MAAM,6CAA6C,MAAM"}
1
+ {"version":3,"file":"error-boundary.js","names":[],"sources":["../../src/components/error-boundary.tsx"],"sourcesContent":["import type { Props } from '../common/props';\nimport { ELEMENT_TYPE, type JSXElement } from '../common/jsx';\nimport type { VNode } from '../common/vnode';\nimport { __ERROR_BOUNDARY__ } from '../common/vnode';\nimport {\n getCurrentComponentInstance,\n type ComponentInstance,\n} from '../runtime/component';\nimport { logger } from '../dev/logger';\nimport { isDevelopmentEnvironment } from '../common/env';\n\ntype ErrorBoundaryContent = VNode | readonly VNode[];\ntype ErrorBoundaryFallbackValue = ErrorBoundaryContent | Node;\n\nexport type ErrorBoundaryFallbackRender = (\n error: unknown,\n reset: () => void\n) => ErrorBoundaryFallbackValue;\n\nexport interface ErrorBoundaryProps extends Props {\n children?: ErrorBoundaryContent;\n fallback?: ErrorBoundaryFallbackValue | ErrorBoundaryFallbackRender;\n onError?: (error: unknown) => void;\n resetKey?: unknown;\n}\n\ntype ErrorBoundaryState = NonNullable<ComponentInstance['errorBoundaryState']>;\n\ntype ErrorBoundaryVNode = JSXElement & {\n __instance?: ComponentInstance;\n};\n\nfunction getBoundaryMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message || error.name || 'Unknown error';\n }\n\n if (typeof error === 'string') {\n return error;\n }\n\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n}\n\nfunction ensureBoundaryState(\n instance: ComponentInstance,\n resetKey: unknown\n): ErrorBoundaryState {\n const boundaryState =\n instance.errorBoundaryState ??\n (instance.errorBoundaryState = {\n error: null,\n resetKey,\n notified: false,\n });\n\n if (!Object.is(boundaryState.resetKey, resetKey)) {\n boundaryState.error = null;\n boundaryState.resetKey = resetKey;\n boundaryState.notified = false;\n }\n\n return boundaryState;\n}\n\nfunction createBoundaryVNode(\n instance: ComponentInstance,\n props: ErrorBoundaryProps\n): ErrorBoundaryVNode {\n const key =\n typeof props.key === 'symbol'\n ? null\n : ((props.key ?? null) as string | number | null);\n\n return {\n $$typeof: ELEMENT_TYPE,\n type: __ERROR_BOUNDARY__,\n props: {\n children: props.children,\n fallback: props.fallback,\n onError: props.onError,\n resetKey: props.resetKey,\n },\n key,\n __instance: instance,\n };\n}\n\nexport function ErrorBoundary(props: ErrorBoundaryProps): JSXElement {\n const instance = getCurrentComponentInstance();\n if (!instance) {\n throw new Error(\n '[Askr] ErrorBoundary() can only be used during component render execution.'\n );\n }\n\n ensureBoundaryState(instance, props.resetKey);\n return createBoundaryVNode(instance, props);\n}\n\nexport function isErrorBoundaryVNode(\n value: unknown\n): value is ErrorBoundaryVNode {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as ErrorBoundaryVNode).type === __ERROR_BOUNDARY__\n );\n}\n\nexport function resolveErrorBoundaryState(\n vnode: ErrorBoundaryVNode\n): ErrorBoundaryState | null {\n return vnode.__instance?.errorBoundaryState ?? null;\n}\n\nexport function resolveErrorBoundaryFallback(\n fallback: ErrorBoundaryProps['fallback'],\n error: unknown,\n reset: () => void\n): ErrorBoundaryFallbackValue {\n if (typeof fallback === 'function') {\n return fallback(error, reset);\n }\n\n if (fallback !== undefined) {\n return fallback;\n }\n\n const message = getBoundaryMessage(error);\n const wrapper = document.createElement('div');\n wrapper.setAttribute('role', 'alert');\n wrapper.setAttribute('data-askr-error-boundary', 'true');\n wrapper.style.boxSizing = 'border-box';\n wrapper.style.padding = '1rem';\n wrapper.style.border = '1px solid currentColor';\n wrapper.style.borderRadius = '0.75rem';\n wrapper.style.display = 'grid';\n wrapper.style.gap = '0.75rem';\n wrapper.style.maxWidth = '100%';\n\n const title = document.createElement('strong');\n title.textContent = 'Something went wrong while rendering this view.';\n\n const summary = document.createElement('p');\n summary.textContent =\n 'The app recovered into a visible fallback so the error is not hidden in the console.';\n summary.style.margin = '0';\n\n const details = document.createElement('details');\n details.open = isDevelopmentEnvironment();\n\n const detailsSummary = document.createElement('summary');\n detailsSummary.textContent = 'Error details';\n\n const pre = document.createElement('pre');\n pre.textContent = message;\n pre.style.margin = '0';\n pre.style.whiteSpace = 'pre-wrap';\n pre.style.wordBreak = 'break-word';\n\n const button = document.createElement('button');\n button.type = 'button';\n button.textContent = 'Try again';\n button.addEventListener('click', () => reset());\n\n details.append(detailsSummary, pre);\n wrapper.append(title, summary, details, button);\n return wrapper;\n}\n\nexport function createBoundaryReset(instance: ComponentInstance): () => void {\n return () => {\n const boundaryState = instance.errorBoundaryState;\n if (!boundaryState) {\n return;\n }\n boundaryState.error = null;\n boundaryState.notified = false;\n queueMicrotask(() => {\n instance._enqueueRun?.();\n });\n };\n}\n\nexport function reportBoundaryError(\n instance: ComponentInstance,\n error: unknown,\n onError?: (error: unknown) => void\n): void {\n const boundaryState = instance.errorBoundaryState;\n if (\n boundaryState &&\n Object.is(boundaryState.error, error) &&\n boundaryState.notified\n ) {\n return;\n }\n\n if (boundaryState) {\n boundaryState.error = error;\n boundaryState.notified = true;\n }\n\n try {\n onError?.(error);\n } catch (hookError) {\n logger.error('[Askr] ErrorBoundary onError handler threw:', hookError);\n }\n\n logger.error('[Askr] ErrorBoundary caught render error:', error);\n}\n"],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { Props } from "../common/props.js";
2
2
  import { JSXElement } from "../common/jsx.js";
3
+ import { RenderableChild } from "../common/vnode.js";
3
4
  //#region src/components/link.d.ts
4
5
  type LinkProps = Omit<Props, 'children' | 'href' | 'class' | 'rel' | 'target' | 'aria-current' | 'aria-label'> & {
5
6
  href: string;
6
7
  class?: string;
7
- children?: unknown;
8
+ children?: RenderableChild;
8
9
  /**
9
10
  * Optional rel attribute for link relationships.
10
11
  * Common values: "noopener", "noreferrer", "nofollow"
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","names":[],"sources":["../../src/components/link.tsx"],"mappings":";;;KAWY,SAAA,GAAY,IAAA,CACtB,KAAA;EASA,IAAA;EACA,KAAA;EACA,QAAA;EAXA;;;;EAgBA,GAAA;EAKA;;;;EAAA,MAAA;EA8Cc;;;;EAzCd,cAAA;EA4CA;;;EAjCA,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8Bc,IAAA,CAAA;EACd,IAAA;EACA,KAAA,EAAO,SAAA;EACP,QAAA;EACA,GAAA;EACA,MAAA;EAAA,gBACgB,WAAA;EAAA,cACF,SAAA;EAAA,GACX;AAAA,GACF,SAAA,GAAY,UAAA"}
1
+ {"version":3,"file":"link.d.ts","names":[],"sources":["../../src/components/link.tsx"],"mappings":";;;;KAYY,SAAA,GAAY,IAAA,CACtB,KAAA;EASA,IAAA;EACA,KAAA;EACA,QAAA,GAAW,eAAA;EAAA;;;;EAKX,GAAA;EAPA;;;;EAYA,MAAA;EAAA;;;;EAKA,cAAA;EAyDc;;;EA9Cd,YAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDuB;;iBATT,IAAA,CAAA;EACd,IAAA;EACA,KAAA,EAAO,SAAA;EACP,QAAA;EACA,GAAA;EACA,MAAA;EAAA,gBACgB,WAAA;EAAA,cACF,SAAA;EAAA,GACX;AAAA,GACF,SAAA,GAAY,UAAA"}
@@ -8,6 +8,15 @@ import { applyInteractionPolicy } from "../foundations/interactions/interaction-
8
8
  /**
9
9
  * Link component for client-side navigation
10
10
  */
11
+ function isSameOriginNavigableHref(href) {
12
+ if (typeof window === "undefined") return true;
13
+ try {
14
+ const target = new URL(href, window.location.href);
15
+ return target.origin === window.location.origin && (target.protocol === "http:" || target.protocol === "https:");
16
+ } catch {
17
+ return false;
18
+ }
19
+ }
11
20
  /**
12
21
  * Link component that prevents default navigation and uses navigate()
13
22
  * Provides declarative way to navigate between routes
@@ -44,7 +53,7 @@ function Link({ href, class: className, children, rel, target, "aria-current": a
44
53
  onPress: (e) => {
45
54
  const event = e;
46
55
  if ((event.button ?? 0) !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
47
- if (target) return;
56
+ if (target || !isSameOriginNavigableHref(href)) return;
48
57
  event.preventDefault();
49
58
  navigate(href);
50
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"link.js","names":[],"sources":["../../src/components/link.tsx"],"sourcesContent":["/**\n * Link component for client-side navigation\n */\n\nimport '../jsx/types';\nimport type { JSXElement } from '../common/jsx';\nimport type { Props } from '../common/props';\nimport { navigate } from '../router/navigate';\nimport { applyInteractionPolicy } from '../foundations/interactions/interaction-policy';\nimport { mergeProps } from '../foundations/utilities/merge-props';\n\nexport type LinkProps = Omit<\n Props,\n | 'children'\n | 'href'\n | 'class'\n | 'rel'\n | 'target'\n | 'aria-current'\n | 'aria-label'\n> & {\n href: string;\n class?: string;\n children?: unknown;\n /**\n * Optional rel attribute for link relationships.\n * Common values: \"noopener\", \"noreferrer\", \"nofollow\"\n */\n rel?: string;\n /**\n * Optional target attribute.\n * Use \"_blank\" for new tab/window.\n */\n target?: string;\n /**\n * Optional aria-current attribute for indicating current page/location.\n * Use \"page\" for the current page in navigation.\n */\n 'aria-current'?:\n | 'page'\n | 'step'\n | 'location'\n | 'date'\n | 'time'\n | 'true'\n | 'false';\n /**\n * Optional aria-label for accessibility when link text isn't descriptive enough.\n */\n 'aria-label'?: string;\n};\n\n/**\n * Link component that prevents default navigation and uses navigate()\n * Provides declarative way to navigate between routes\n *\n * Accessibility features:\n * - Proper semantic <a> element (not a button)\n * - Supports aria-current for indicating active page\n * - Supports aria-label for descriptive labels\n * - Keyboard accessible (Enter key handled by native <a> element)\n *\n * Respects native browser behaviors:\n * - Middle-click (opens in new tab)\n * - Ctrl/Cmd+click (opens in new tab)\n * - Shift+click (opens in new window)\n * - Alt+click (downloads link)\n * - Right-click context menu\n *\n * Best practices:\n * - Use target=\"_blank\" with rel=\"noopener noreferrer\" for external links\n * - Use aria-current=\"page\" for the current page in navigation\n * - Provide descriptive link text or aria-label\n *\n * Uses applyInteractionPolicy to enforce pit-of-success principles:\n * - Interaction behavior centralized in foundations\n * - Keyboard handling automatic\n * - Composable via mergeProps\n */\nexport function Link({\n href,\n class: className,\n children,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n ...rest\n}: LinkProps): JSXElement {\n const interaction = applyInteractionPolicy({\n isNative: true,\n disabled: false,\n onPress: (e: Event) => {\n const event = e as MouseEvent;\n\n // Only intercept left-click without modifiers\n // Default button to 0 if undefined (for mock events in tests)\n const button = event.button ?? 0;\n if (\n button !== 0 || // not left-click\n event.ctrlKey || // Ctrl/Cmd+click\n event.metaKey || // Cmd on Mac\n event.shiftKey || // Shift+click\n event.altKey // Alt+click\n ) {\n return; // Let browser handle it (new tab, etc.)\n }\n\n // Don't intercept external links or explicit target\n if (target) {\n return; // Let browser handle it\n }\n\n event.preventDefault();\n navigate(href);\n },\n });\n\n const props = mergeProps(rest, {\n ...interaction,\n href,\n class: className,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n });\n\n return <a {...props}>{children}</a>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,SAAgB,KAAK,EACnB,MACA,OAAO,WACP,UACA,KACA,QACA,gBAAgB,aAChB,cAAc,WACd,GAAG,QACqB;CAwCxB,OAAO,oBAAC,KAAD;EAAG,GAVI,WAAW,MAAM;GAC7B,GA9BkB,uBAAuB;IACzC,UAAU;IACV,UAAU;IACV,UAAU,MAAa;KACrB,MAAM,QAAQ;KAKd,KADe,MAAM,UAAU,OAElB,KACX,MAAM,WACN,MAAM,WACN,MAAM,YACN,MAAM,QAEN;KAIF,IAAI,QACF;KAGF,MAAM,gBAAgB;KACtB,SAAS,KAAK;;IAEjB,CAGI;GACH;GACA,OAAO;GACP;GACA;GACA,gBAAgB;GAChB,cAAc;GACf,CAEa;EAAQ;EAAa,CAAA"}
1
+ {"version":3,"file":"link.js","names":[],"sources":["../../src/components/link.tsx"],"sourcesContent":["/**\n * Link component for client-side navigation\n */\n\nimport '../jsx/types';\nimport type { JSXElement } from '../common/jsx';\nimport type { Props } from '../common/props';\nimport type { RenderableChild } from '../common/vnode';\nimport { navigate } from '../router/navigate';\nimport { applyInteractionPolicy } from '../foundations/interactions/interaction-policy';\nimport { mergeProps } from '../foundations/utilities/merge-props';\n\nexport type LinkProps = Omit<\n Props,\n | 'children'\n | 'href'\n | 'class'\n | 'rel'\n | 'target'\n | 'aria-current'\n | 'aria-label'\n> & {\n href: string;\n class?: string;\n children?: RenderableChild;\n /**\n * Optional rel attribute for link relationships.\n * Common values: \"noopener\", \"noreferrer\", \"nofollow\"\n */\n rel?: string;\n /**\n * Optional target attribute.\n * Use \"_blank\" for new tab/window.\n */\n target?: string;\n /**\n * Optional aria-current attribute for indicating current page/location.\n * Use \"page\" for the current page in navigation.\n */\n 'aria-current'?:\n | 'page'\n | 'step'\n | 'location'\n | 'date'\n | 'time'\n | 'true'\n | 'false';\n /**\n * Optional aria-label for accessibility when link text isn't descriptive enough.\n */\n 'aria-label'?: string;\n};\n\nfunction isSameOriginNavigableHref(href: string): boolean {\n if (typeof window === 'undefined') {\n return true;\n }\n\n try {\n const target = new URL(href, window.location.href);\n return (\n target.origin === window.location.origin &&\n (target.protocol === 'http:' || target.protocol === 'https:')\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Link component that prevents default navigation and uses navigate()\n * Provides declarative way to navigate between routes\n *\n * Accessibility features:\n * - Proper semantic <a> element (not a button)\n * - Supports aria-current for indicating active page\n * - Supports aria-label for descriptive labels\n * - Keyboard accessible (Enter key handled by native <a> element)\n *\n * Respects native browser behaviors:\n * - Middle-click (opens in new tab)\n * - Ctrl/Cmd+click (opens in new tab)\n * - Shift+click (opens in new window)\n * - Alt+click (downloads link)\n * - Right-click context menu\n *\n * Best practices:\n * - Use target=\"_blank\" with rel=\"noopener noreferrer\" for external links\n * - Use aria-current=\"page\" for the current page in navigation\n * - Provide descriptive link text or aria-label\n *\n * Uses applyInteractionPolicy to enforce pit-of-success principles:\n * - Interaction behavior centralized in foundations\n * - Keyboard handling automatic\n * - Composable via mergeProps\n */\nexport function Link({\n href,\n class: className,\n children,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n ...rest\n}: LinkProps): JSXElement {\n const interaction = applyInteractionPolicy({\n isNative: true,\n disabled: false,\n onPress: (e: Event) => {\n const event = e as MouseEvent;\n\n // Only intercept left-click without modifiers\n // Default button to 0 if undefined (for mock events in tests)\n const button = event.button ?? 0;\n if (\n button !== 0 || // not left-click\n event.ctrlKey || // Ctrl/Cmd+click\n event.metaKey || // Cmd on Mac\n event.shiftKey || // Shift+click\n event.altKey // Alt+click\n ) {\n return; // Let browser handle it (new tab, etc.)\n }\n\n // Don't intercept external links or explicit target.\n if (target || !isSameOriginNavigableHref(href)) {\n return; // Let browser handle it\n }\n\n event.preventDefault();\n navigate(href);\n },\n });\n\n const props = mergeProps(rest, {\n ...interaction,\n href,\n class: className,\n rel,\n target,\n 'aria-current': ariaCurrent,\n 'aria-label': ariaLabel,\n });\n\n return <a {...props}>{children}</a>;\n}\n"],"mappings":";;;;;;;;;;AAqDA,SAAS,0BAA0B,MAAuB;CACxD,IAAI,OAAO,WAAW,aACpB,OAAO;CAGT,IAAI;EACF,MAAM,SAAS,IAAI,IAAI,MAAM,OAAO,SAAS,IAAI;EACjD,OACE,OAAO,WAAW,OAAO,SAAS,WACjC,OAAO,aAAa,WAAW,OAAO,aAAa;CAExD,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,KAAK,EACnB,MACA,OAAO,WACP,UACA,KACA,QACA,gBAAgB,aAChB,cAAc,WACd,GAAG,QACqB;CAwCxB,OAAO,oBAAC,KAAD;EAAG,GAVI,WAAW,MAAM;GAC7B,GA9BkB,uBAAuB;IACzC,UAAU;IACV,UAAU;IACV,UAAU,MAAa;KACrB,MAAM,QAAQ;KAKd,KADe,MAAM,UAAU,OAElB,KACX,MAAM,WACN,MAAM,WACN,MAAM,YACN,MAAM,QAEN;KAIF,IAAI,UAAU,CAAC,0BAA0B,IAAI,GAC3C;KAGF,MAAM,eAAe;KACrB,SAAS,IAAI;IACf;GACF,CAGK;GACH;GACA,OAAO;GACP;GACA;GACA,gBAAgB;GAChB,cAAc;EAChB,CAEc;EAAQ;CAAY,CAAA;AACpC"}
@@ -1,13 +1,15 @@
1
1
  import { JSXElement } from "../common/jsx.js";
2
+ import { BoundaryChild } from "./shared.js";
2
3
 
3
4
  //#region src/control/case.d.ts
5
+ type MatchChild = BoundaryChild | (() => BoundaryChild);
4
6
  type MatchProps = {
5
7
  key?: string | number | null;
6
8
  when: unknown;
7
- children: unknown;
9
+ children: MatchChild;
8
10
  };
9
11
  type CaseProps = {
10
- fallback?: unknown;
12
+ fallback?: BoundaryChild;
11
13
  children?: unknown;
12
14
  };
13
15
  declare function Match(_props: MatchProps): null;
@@ -1 +1 @@
1
- {"version":3,"file":"case.d.ts","names":[],"sources":["../../src/control/case.ts"],"mappings":";;;KAeY,UAAA;EACV,GAAA;EACA,IAAA;EACA,QAAA;AAAA;AAAA,KAGU,SAAA;EACV,QAAA;EACA,QAAA;AAAA;AAAA,iBAmBc,KAAA,CAAM,MAAA,EAAQ,UAAA;AAAA,cAqFjB,IAAA,GAEP,KAAA,EAAO,SAAA,KAAc,UAAA"}
1
+ {"version":3,"file":"case.d.ts","names":[],"sources":["../../src/control/case.ts"],"mappings":";;;;KAeK,UAAA,GAAa,aAAA,UAAuB,aAAa;AAAA,KAE1C,UAAA;EACV,GAAA;EACA,IAAA;EACA,QAAA,EAAU,UAAU;AAAA;AAAA,KAGV,SAAA;EACV,QAAA,GAAW,aAAa;EACxB,QAAA;AAAA;AAAA,iBAmBc,KAAA,CAAM,MAAkB,EAAV,UAAU;AAAA,cAyF3B,IAAA,GAEP,KAAA,EAAO,SAAA,KAAc,UAAU"}
@@ -1 +1 @@
1
- {"version":3,"file":"case.js","names":[],"sources":["../../src/control/case.ts"],"sourcesContent":["import {\n __CONTROL_BOUNDARY__,\n markEagerControlPrimitive,\n} from '../common/control';\nimport type { JSXElement } from '../common/jsx';\nimport type { VNode } from '../common/vnode';\nimport { isDevelopmentEnvironment } from '../common/env';\nimport {\n createCaseState,\n type CaseState,\n type MatchBranch,\n} from '../runtime/control';\nimport { state } from '../runtime/state';\nimport { normalizeBoundaryChild } from './shared';\n\nexport type MatchProps = {\n key?: string | number | null;\n when: unknown;\n children: unknown;\n};\n\nexport type CaseProps = {\n fallback?: unknown;\n children?: unknown;\n};\n\nfunction flattenChildren(children: unknown): unknown[] {\n if (!Array.isArray(children)) {\n return children == null || children === false ? [] : [children];\n }\n\n const result: unknown[] = [];\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child));\n continue;\n }\n result.push(child);\n }\n return result;\n}\n\nexport function Match(_props: MatchProps): null {\n if (isDevelopmentEnvironment()) {\n throw new Error(\n '[askr] <Match> may only be used as a direct child of <Case>.'\n );\n }\n return null;\n}\n\nfunction createCaseFallbackRenderer(fallback: unknown): (() => VNode) | null {\n const normalizedFallback = normalizeBoundaryChild(fallback);\n if (normalizedFallback == null || normalizedFallback === false) {\n return null;\n }\n return () => normalizedFallback;\n}\n\nfunction createMatchBranchKey(\n key: string | number | null | undefined,\n index: number\n): string | number {\n if (key == null) {\n return index;\n }\n return `match:${index}:${typeof key}:${String(key)}`;\n}\n\nfunction readMatchBranches(children: unknown): MatchBranch[] {\n const branches: MatchBranch[] = [];\n const flatChildren = flattenChildren(children);\n\n for (let index = 0; index < flatChildren.length; index += 1) {\n const child = flatChildren[index];\n if (child == null || child === false) {\n continue;\n }\n\n if (\n typeof child === 'object' &&\n child !== null &&\n 'type' in child &&\n (child as JSXElement).type === Match\n ) {\n const element = child as JSXElement;\n const props = (element.props ?? {}) as MatchProps;\n const key = createMatchBranchKey(element.key, index);\n const render =\n typeof props.children === 'function'\n ? () =>\n normalizeBoundaryChild((props.children as () => VNode)()) as VNode\n : () => normalizeBoundaryChild(props.children) as VNode;\n branches.push({\n key,\n render,\n when: props.when,\n });\n continue;\n }\n\n if (isDevelopmentEnvironment()) {\n throw new Error('[askr] <Case> only accepts <Match> children.');\n }\n }\n\n return branches;\n}\n\nfunction CasePrimitive(props: CaseProps): JSXElement {\n const matches = readMatchBranches(props.children);\n const fallback = createCaseFallbackRenderer(props.fallback);\n\n const caseStateContainer = state<CaseState>(\n createCaseState(matches, fallback)\n );\n const caseState = caseStateContainer();\n\n caseState.matches = matches;\n caseState.fallback = fallback;\n\n return {\n type: __CONTROL_BOUNDARY__,\n _controlState: caseState,\n } as unknown as JSXElement;\n}\n\nexport const Case = markEagerControlPrimitive(\n CasePrimitive as (props: CaseProps) => JSXElement\n) as (props: CaseProps) => JSXElement;\n"],"mappings":";;;;;;AA0BA,SAAS,gBAAgB,UAA8B;CACrD,IAAI,CAAC,MAAM,QAAQ,SAAS,EAC1B,OAAO,YAAY,QAAQ,aAAa,QAAQ,EAAE,GAAG,CAAC,SAAS;CAGjE,MAAM,SAAoB,EAAE;CAC5B,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,MAAM,QAAQ,MAAM,EAAE;GACxB,OAAO,KAAK,GAAG,gBAAgB,MAAM,CAAC;GACtC;;EAEF,OAAO,KAAK,MAAM;;CAEpB,OAAO;;AAGT,SAAgB,MAAM,QAA0B;CAC9C,IAAI,0BAA0B,EAC5B,MAAM,IAAI,MACR,+DACD;CAEH,OAAO;;AAGT,SAAS,2BAA2B,UAAyC;CAC3E,MAAM,qBAAqB,uBAAuB,SAAS;CAC3D,IAAI,sBAAsB,QAAQ,uBAAuB,OACvD,OAAO;CAET,aAAa;;AAGf,SAAS,qBACP,KACA,OACiB;CACjB,IAAI,OAAO,MACT,OAAO;CAET,OAAO,SAAS,MAAM,GAAG,OAAO,IAAI,GAAG,OAAO,IAAI;;AAGpD,SAAS,kBAAkB,UAAkC;CAC3D,MAAM,WAA0B,EAAE;CAClC,MAAM,eAAe,gBAAgB,SAAS;CAE9C,KAAK,IAAI,QAAQ,GAAG,QAAQ,aAAa,QAAQ,SAAS,GAAG;EAC3D,MAAM,QAAQ,aAAa;EAC3B,IAAI,SAAS,QAAQ,UAAU,OAC7B;EAGF,IACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAqB,SAAS,OAC/B;GACA,MAAM,UAAU;GAChB,MAAM,QAAS,QAAQ,SAAS,EAAE;GAClC,MAAM,MAAM,qBAAqB,QAAQ,KAAK,MAAM;GACpD,MAAM,SACJ,OAAO,MAAM,aAAa,mBAEpB,uBAAwB,MAAM,UAA0B,CAAC,SACrD,uBAAuB,MAAM,SAAS;GAClD,SAAS,KAAK;IACZ;IACA;IACA,MAAM,MAAM;IACb,CAAC;GACF;;EAGF,IAAI,0BAA0B,EAC5B,MAAM,IAAI,MAAM,+CAA+C;;CAInE,OAAO;;AAGT,SAAS,cAAc,OAA8B;CACnD,MAAM,UAAU,kBAAkB,MAAM,SAAS;CACjD,MAAM,WAAW,2BAA2B,MAAM,SAAS;CAK3D,MAAM,YAHqB,MACzB,gBAAgB,SAAS,SAAS,CAElB,EAAoB;CAEtC,UAAU,UAAU;CACpB,UAAU,WAAW;CAErB,OAAO;EACL,MAAM;EACN,eAAe;EAChB;;AAGH,MAAa,OAAO,0BAClB,cACD"}
1
+ {"version":3,"file":"case.js","names":[],"sources":["../../src/control/case.ts"],"sourcesContent":["import {\n __CONTROL_BOUNDARY__,\n markEagerControlPrimitive,\n} from '../common/control';\nimport type { JSXElement } from '../common/jsx';\nimport type { VNode } from '../common/vnode';\nimport { isDevelopmentEnvironment } from '../common/env';\nimport {\n createCaseState,\n type CaseState,\n type MatchBranch,\n} from '../runtime/control';\nimport { state } from '../runtime/state';\nimport { type BoundaryChild, normalizeBoundaryChild } from './shared';\n\ntype MatchChild = BoundaryChild | (() => BoundaryChild);\n\nexport type MatchProps = {\n key?: string | number | null;\n when: unknown;\n children: MatchChild;\n};\n\nexport type CaseProps = {\n fallback?: BoundaryChild;\n children?: unknown;\n};\n\nfunction flattenChildren(children: unknown): unknown[] {\n if (!Array.isArray(children)) {\n return children == null || children === false ? [] : [children];\n }\n\n const result: unknown[] = [];\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child));\n continue;\n }\n result.push(child);\n }\n return result;\n}\n\nexport function Match(_props: MatchProps): null {\n if (isDevelopmentEnvironment()) {\n throw new Error(\n '[askr] <Match> may only be used as a direct child of <Case>.'\n );\n }\n return null;\n}\n\nfunction createCaseFallbackRenderer(\n fallback: BoundaryChild | undefined\n): (() => VNode) | null {\n const normalizedFallback = normalizeBoundaryChild(fallback);\n if (normalizedFallback == null || normalizedFallback === false) {\n return null;\n }\n return () => normalizedFallback;\n}\n\nfunction createMatchBranchKey(\n key: string | number | null | undefined,\n index: number\n): string | number {\n if (key == null) {\n return index;\n }\n return `match:${index}:${typeof key}:${String(key)}`;\n}\n\nfunction readMatchBranches(children: unknown): MatchBranch[] {\n const branches: MatchBranch[] = [];\n const flatChildren = flattenChildren(children);\n\n for (let index = 0; index < flatChildren.length; index += 1) {\n const child = flatChildren[index];\n if (child == null || child === false) {\n continue;\n }\n\n if (\n typeof child === 'object' &&\n child !== null &&\n 'type' in child &&\n (child as JSXElement).type === Match\n ) {\n const element = child as JSXElement;\n const props = (element.props ?? {}) as MatchProps;\n const key = createMatchBranchKey(element.key, index);\n const render =\n typeof props.children === 'function'\n ? () =>\n normalizeBoundaryChild(\n (props.children as () => BoundaryChild)()\n ) as VNode\n : () => normalizeBoundaryChild(props.children) as VNode;\n branches.push({\n key,\n render,\n when: props.when,\n });\n continue;\n }\n\n if (isDevelopmentEnvironment()) {\n throw new Error('[askr] <Case> only accepts <Match> children.');\n }\n }\n\n return branches;\n}\n\nfunction CasePrimitive(props: CaseProps): JSXElement {\n const matches = readMatchBranches(props.children);\n const fallback = createCaseFallbackRenderer(props.fallback);\n\n const caseStateContainer = state<CaseState>(\n createCaseState(matches, fallback)\n );\n const caseState = caseStateContainer();\n\n caseState.matches = matches;\n caseState.fallback = fallback;\n\n return {\n type: __CONTROL_BOUNDARY__,\n _controlState: caseState,\n } as unknown as JSXElement;\n}\n\nexport const Case = markEagerControlPrimitive(\n CasePrimitive as (props: CaseProps) => JSXElement\n) as (props: CaseProps) => JSXElement;\n"],"mappings":";;;;;;AA4BA,SAAS,gBAAgB,UAA8B;CACrD,IAAI,CAAC,MAAM,QAAQ,QAAQ,GACzB,OAAO,YAAY,QAAQ,aAAa,QAAQ,CAAC,IAAI,CAAC,QAAQ;CAGhE,MAAM,SAAoB,CAAC;CAC3B,KAAK,MAAM,SAAS,UAAU;EAC5B,IAAI,MAAM,QAAQ,KAAK,GAAG;GACxB,OAAO,KAAK,GAAG,gBAAgB,KAAK,CAAC;GACrC;EACF;EACA,OAAO,KAAK,KAAK;CACnB;CACA,OAAO;AACT;AAEA,SAAgB,MAAM,QAA0B;CAC9C,IAAI,yBAAyB,GAC3B,MAAM,IAAI,MACR,8DACF;CAEF,OAAO;AACT;AAEA,SAAS,2BACP,UACsB;CACtB,MAAM,qBAAqB,uBAAuB,QAAQ;CAC1D,IAAI,sBAAsB,QAAQ,uBAAuB,OACvD,OAAO;CAET,aAAa;AACf;AAEA,SAAS,qBACP,KACA,OACiB;CACjB,IAAI,OAAO,MACT,OAAO;CAET,OAAO,SAAS,MAAM,GAAG,OAAO,IAAI,GAAG,OAAO,GAAG;AACnD;AAEA,SAAS,kBAAkB,UAAkC;CAC3D,MAAM,WAA0B,CAAC;CACjC,MAAM,eAAe,gBAAgB,QAAQ;CAE7C,KAAK,IAAI,QAAQ,GAAG,QAAQ,aAAa,QAAQ,SAAS,GAAG;EAC3D,MAAM,QAAQ,aAAa;EAC3B,IAAI,SAAS,QAAQ,UAAU,OAC7B;EAGF,IACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACT,MAAqB,SAAS,OAC/B;GACA,MAAM,UAAU;GAChB,MAAM,QAAS,QAAQ,SAAS,CAAC;GACjC,MAAM,MAAM,qBAAqB,QAAQ,KAAK,KAAK;GACnD,MAAM,SACJ,OAAO,MAAM,aAAa,mBAEpB,uBACG,MAAM,SAAiC,CAC1C,UACI,uBAAuB,MAAM,QAAQ;GACjD,SAAS,KAAK;IACZ;IACA;IACA,MAAM,MAAM;GACd,CAAC;GACD;EACF;EAEA,IAAI,yBAAyB,GAC3B,MAAM,IAAI,MAAM,8CAA8C;CAElE;CAEA,OAAO;AACT;AAEA,SAAS,cAAc,OAA8B;CACnD,MAAM,UAAU,kBAAkB,MAAM,QAAQ;CAChD,MAAM,WAAW,2BAA2B,MAAM,QAAQ;CAK1D,MAAM,YAHqB,MACzB,gBAAgB,SAAS,QAAQ,CAEjB,EAAmB;CAErC,UAAU,UAAU;CACpB,UAAU,WAAW;CAErB,OAAO;EACL,MAAM;EACN,eAAe;CACjB;AACF;AAEA,MAAa,OAAO,0BAClB,aACF"}
@@ -1,11 +1,12 @@
1
1
  import { JSXElement } from "../common/jsx.js";
2
+ import { BoundaryChild } from "./shared.js";
2
3
  import { VNode } from "../common/vnode.js";
3
4
 
4
5
  //#region src/control/for.d.ts
5
6
  type ForEachSource<T> = T[] | (() => T[]);
6
7
  type ForBaseProps<T> = {
7
8
  each: ForEachSource<T>;
8
- fallback?: unknown;
9
+ fallback?: BoundaryChild;
9
10
  children: (item: T, index: () => number) => VNode;
10
11
  };
11
12
  type KeyedForProps<T, K extends string | number> = ForBaseProps<T> & {
@@ -1 +1 @@
1
- {"version":3,"file":"for.d.ts","names":[],"sources":["../../src/control/for.ts"],"mappings":";;;;KAgBY,aAAA,MAAmB,CAAA,YAAa,CAAA;AAAA,KAEvC,YAAA;EACH,IAAA,EAAM,aAAA,CAAc,CAAA;EACpB,QAAA;EACA,QAAA,GAAW,IAAA,EAAM,CAAA,EAAG,KAAA,mBAAwB,KAAA;AAAA;AAAA,KAGzC,aAAA,iCAA8C,YAAA,CAAa,CAAA;EAC9D,EAAA,GAAK,IAAA,EAAM,CAAA,EAAG,KAAA,aAAkB,CAAA;EAChC,OAAA;AAAA;AAAA,KAGG,eAAA,MAAqB,YAAA,CAAa,CAAA;EACrC,EAAA;EACA,OAAA;AAAA;AAAA,KAGU,QAAA,mDACR,aAAA,CAAc,CAAA,EAAG,CAAA,IACjB,eAAA,CAAgB,CAAA;AAAA,cA0EP,GAAA,mDAKX,KAAA,EAAO,QAAA,CAAS,CAAA,EAAG,CAAA,MAChB,UAAA"}
1
+ {"version":3,"file":"for.d.ts","names":[],"sources":["../../src/control/for.ts"],"mappings":";;;;;KAgBY,aAAA,MAAmB,CAAA,YAAa,CAAC;AAAA,KAExC,YAAA;EACH,IAAA,EAAM,aAAA,CAAc,CAAA;EACpB,QAAA,GAAW,aAAA;EACX,QAAA,GAAW,IAAA,EAAM,CAAA,EAAG,KAAA,mBAAwB,KAAA;AAAA;AAAA,KAGzC,aAAA,iCAA8C,YAAA,CAAa,CAAA;EAC9D,EAAA,GAAK,IAAA,EAAM,CAAA,EAAG,KAAA,aAAkB,CAAA;EAChC,OAAA;AAAA;AAAA,KAGG,eAAA,MAAqB,YAAY,CAAC,CAAA;EACrC,EAAA;EACA,OAAA;AAAA;AAAA,KAGU,QAAA,mDACR,aAAA,CAAc,CAAA,EAAG,CAAA,IACjB,eAAA,CAAgB,CAAA;AAAA,cA0EP,GAAA,mDAKX,KAAA,EAAO,QAAA,CAAS,CAAA,EAAG,CAAA,MAChB,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"for.js","names":[],"sources":["../../src/control/for.ts"],"sourcesContent":["/**\n * For JSX primitive\n *\n * Creates a keyed child-scope boundary for efficient list rendering.\n */\n\nimport {\n __CONTROL_BOUNDARY__,\n markEagerControlPrimitive,\n} from '../common/control';\nimport type { JSXElement } from '../common/jsx';\nimport type { DOMElement, VNode } from '../common/vnode';\nimport { createFineGrainedEffect } from '../runtime/effect';\nimport { type ForState, useForState } from '../runtime/for';\nimport { normalizeBoundaryChild } from './shared';\n\nexport type ForEachSource<T> = T[] | (() => T[]);\n\ntype ForBaseProps<T> = {\n each: ForEachSource<T>;\n fallback?: unknown;\n children: (item: T, index: () => number) => VNode;\n};\n\ntype KeyedForProps<T, K extends string | number> = ForBaseProps<T> & {\n by: (item: T, index: number) => K;\n byIndex?: never;\n};\n\ntype IndexedForProps<T> = ForBaseProps<T> & {\n by?: never;\n byIndex: true;\n};\n\nexport type ForProps<T, K extends string | number = string | number> =\n | KeyedForProps<T, K>\n | IndexedForProps<T>;\n\nfunction resolveEach<T>(each: ForEachSource<T>): T[] {\n const resolved = typeof each === 'function' ? each() : each;\n if (!Array.isArray(resolved)) {\n throw new Error('For each must resolve to an array.');\n }\n return resolved;\n}\n\nfunction resolveKeyFn<T>(\n props: ForProps<T>\n): (item: T, index: number) => string | number {\n if ('by' in props && typeof props.by === 'function') {\n return props.by;\n }\n if ('byIndex' in props && props.byIndex === true) {\n return (_item, index) => index;\n }\n throw new Error(\n '[askr] <For> requires a stable `by` key function. Use `byIndex` only as an explicit positional escape hatch.'\n );\n}\n\nfunction createForBoundary<T>(props: ForProps<T>): DOMElement {\n if ('by' in props && typeof props.by === 'function' && 'byIndex' in props) {\n throw new Error('[askr] <For> accepts either `by` or `byIndex`, not both.');\n }\n\n const byFn = resolveKeyFn(props);\n const fallback = normalizeBoundaryChild(props.fallback);\n const forState = useForState(props.each, byFn, props.children, fallback);\n\n const computeItems = () => resolveEach(forState.eachSource);\n if (!forState._sourceEffect) {\n forState._suspendSourceCommit = true;\n forState._sourceEffect = createFineGrainedEffect({\n lane: 'reactive',\n compute: computeItems,\n commit: (items) => {\n forState.currentItems = items;\n\n if (forState._suspendSourceCommit) {\n return;\n }\n\n forState._needsSourceReconcile = true;\n\n if (forState._enqueueBoundaryCommit) {\n forState._enqueueBoundaryCommit();\n return;\n }\n\n forState.parentInstance?._enqueueRun?.();\n },\n });\n forState._suspendSourceCommit = false;\n } else {\n forState._suspendSourceCommit = true;\n forState._sourceEffect.updateCompute(computeItems);\n forState._suspendSourceCommit = false;\n }\n\n return {\n type: __CONTROL_BOUNDARY__,\n _controlState: forState as unknown as ForState<unknown>,\n _forState: forState as unknown as ForState<unknown>,\n };\n}\n\nfunction ForPrimitive<T>(props: ForProps<T>): JSXElement {\n return createForBoundary(props) as unknown as JSXElement;\n}\n\nexport const For = markEagerControlPrimitive(\n ForPrimitive as <T, K extends string | number = string | number>(\n props: ForProps<T, K>\n ) => JSXElement\n) as <T, K extends string | number = string | number>(\n props: ForProps<T, K>\n) => JSXElement;\n"],"mappings":";;;;;;;;;;AAsCA,SAAS,YAAe,MAA6B;CACnD,MAAM,WAAW,OAAO,SAAS,aAAa,MAAM,GAAG;CACvD,IAAI,CAAC,MAAM,QAAQ,SAAS,EAC1B,MAAM,IAAI,MAAM,qCAAqC;CAEvD,OAAO;;AAGT,SAAS,aACP,OAC6C;CAC7C,IAAI,QAAQ,SAAS,OAAO,MAAM,OAAO,YACvC,OAAO,MAAM;CAEf,IAAI,aAAa,SAAS,MAAM,YAAY,MAC1C,QAAQ,OAAO,UAAU;CAE3B,MAAM,IAAI,MACR,+GACD;;AAGH,SAAS,kBAAqB,OAAgC;CAC5D,IAAI,QAAQ,SAAS,OAAO,MAAM,OAAO,cAAc,aAAa,OAClE,MAAM,IAAI,MAAM,2DAA2D;CAG7E,MAAM,OAAO,aAAa,MAAM;CAChC,MAAM,WAAW,uBAAuB,MAAM,SAAS;CACvD,MAAM,WAAW,YAAY,MAAM,MAAM,MAAM,MAAM,UAAU,SAAS;CAExE,MAAM,qBAAqB,YAAY,SAAS,WAAW;CAC3D,IAAI,CAAC,SAAS,eAAe;EAC3B,SAAS,uBAAuB;EAChC,SAAS,gBAAgB,wBAAwB;GAC/C,MAAM;GACN,SAAS;GACT,SAAS,UAAU;IACjB,SAAS,eAAe;IAExB,IAAI,SAAS,sBACX;IAGF,SAAS,wBAAwB;IAEjC,IAAI,SAAS,wBAAwB;KACnC,SAAS,wBAAwB;KACjC;;IAGF,SAAS,gBAAgB,eAAe;;GAE3C,CAAC;EACF,SAAS,uBAAuB;QAC3B;EACL,SAAS,uBAAuB;EAChC,SAAS,cAAc,cAAc,aAAa;EAClD,SAAS,uBAAuB;;CAGlC,OAAO;EACL,MAAM;EACN,eAAe;EACf,WAAW;EACZ;;AAGH,SAAS,aAAgB,OAAgC;CACvD,OAAO,kBAAkB,MAAM;;AAGjC,MAAa,MAAM,0BACjB,aAGD"}
1
+ {"version":3,"file":"for.js","names":[],"sources":["../../src/control/for.ts"],"sourcesContent":["/**\n * For JSX primitive\n *\n * Creates a keyed child-scope boundary for efficient list rendering.\n */\n\nimport {\n __CONTROL_BOUNDARY__,\n markEagerControlPrimitive,\n} from '../common/control';\nimport type { JSXElement } from '../common/jsx';\nimport type { DOMElement, VNode } from '../common/vnode';\nimport { createFineGrainedEffect } from '../runtime/effect';\nimport { type ForState, useForState } from '../runtime/for';\nimport { type BoundaryChild, normalizeBoundaryChild } from './shared';\n\nexport type ForEachSource<T> = T[] | (() => T[]);\n\ntype ForBaseProps<T> = {\n each: ForEachSource<T>;\n fallback?: BoundaryChild;\n children: (item: T, index: () => number) => VNode;\n};\n\ntype KeyedForProps<T, K extends string | number> = ForBaseProps<T> & {\n by: (item: T, index: number) => K;\n byIndex?: never;\n};\n\ntype IndexedForProps<T> = ForBaseProps<T> & {\n by?: never;\n byIndex: true;\n};\n\nexport type ForProps<T, K extends string | number = string | number> =\n | KeyedForProps<T, K>\n | IndexedForProps<T>;\n\nfunction resolveEach<T>(each: ForEachSource<T>): T[] {\n const resolved = typeof each === 'function' ? each() : each;\n if (!Array.isArray(resolved)) {\n throw new Error('For each must resolve to an array.');\n }\n return resolved;\n}\n\nfunction resolveKeyFn<T>(\n props: ForProps<T>\n): (item: T, index: number) => string | number {\n if ('by' in props && typeof props.by === 'function') {\n return props.by;\n }\n if ('byIndex' in props && props.byIndex === true) {\n return (_item, index) => index;\n }\n throw new Error(\n '[askr] <For> requires a stable `by` key function. Use `byIndex` only as an explicit positional escape hatch.'\n );\n}\n\nfunction createForBoundary<T>(props: ForProps<T>): DOMElement {\n if ('by' in props && typeof props.by === 'function' && 'byIndex' in props) {\n throw new Error('[askr] <For> accepts either `by` or `byIndex`, not both.');\n }\n\n const byFn = resolveKeyFn(props);\n const fallback = normalizeBoundaryChild(props.fallback);\n const forState = useForState(props.each, byFn, props.children, fallback);\n\n const computeItems = () => resolveEach(forState.eachSource);\n if (!forState._sourceEffect) {\n forState._suspendSourceCommit = true;\n forState._sourceEffect = createFineGrainedEffect({\n lane: 'reactive',\n compute: computeItems,\n commit: (items) => {\n forState.currentItems = items;\n\n if (forState._suspendSourceCommit) {\n return;\n }\n\n forState._needsSourceReconcile = true;\n\n if (forState._enqueueBoundaryCommit) {\n forState._enqueueBoundaryCommit();\n return;\n }\n\n forState.parentInstance?._enqueueRun?.();\n },\n });\n forState._suspendSourceCommit = false;\n } else {\n forState._suspendSourceCommit = true;\n forState._sourceEffect.updateCompute(computeItems);\n forState._suspendSourceCommit = false;\n }\n\n return {\n type: __CONTROL_BOUNDARY__,\n _controlState: forState as unknown as ForState<unknown>,\n _forState: forState as unknown as ForState<unknown>,\n };\n}\n\nfunction ForPrimitive<T>(props: ForProps<T>): JSXElement {\n return createForBoundary(props) as unknown as JSXElement;\n}\n\nexport const For = markEagerControlPrimitive(\n ForPrimitive as <T, K extends string | number = string | number>(\n props: ForProps<T, K>\n ) => JSXElement\n) as <T, K extends string | number = string | number>(\n props: ForProps<T, K>\n) => JSXElement;\n"],"mappings":";;;;;;;;;;AAsCA,SAAS,YAAe,MAA6B;CACnD,MAAM,WAAW,OAAO,SAAS,aAAa,KAAK,IAAI;CACvD,IAAI,CAAC,MAAM,QAAQ,QAAQ,GACzB,MAAM,IAAI,MAAM,oCAAoC;CAEtD,OAAO;AACT;AAEA,SAAS,aACP,OAC6C;CAC7C,IAAI,QAAQ,SAAS,OAAO,MAAM,OAAO,YACvC,OAAO,MAAM;CAEf,IAAI,aAAa,SAAS,MAAM,YAAY,MAC1C,QAAQ,OAAO,UAAU;CAE3B,MAAM,IAAI,MACR,8GACF;AACF;AAEA,SAAS,kBAAqB,OAAgC;CAC5D,IAAI,QAAQ,SAAS,OAAO,MAAM,OAAO,cAAc,aAAa,OAClE,MAAM,IAAI,MAAM,0DAA0D;CAG5E,MAAM,OAAO,aAAa,KAAK;CAC/B,MAAM,WAAW,uBAAuB,MAAM,QAAQ;CACtD,MAAM,WAAW,YAAY,MAAM,MAAM,MAAM,MAAM,UAAU,QAAQ;CAEvE,MAAM,qBAAqB,YAAY,SAAS,UAAU;CAC1D,IAAI,CAAC,SAAS,eAAe;EAC3B,SAAS,uBAAuB;EAChC,SAAS,gBAAgB,wBAAwB;GAC/C,MAAM;GACN,SAAS;GACT,SAAS,UAAU;IACjB,SAAS,eAAe;IAExB,IAAI,SAAS,sBACX;IAGF,SAAS,wBAAwB;IAEjC,IAAI,SAAS,wBAAwB;KACnC,SAAS,uBAAuB;KAChC;IACF;IAEA,SAAS,gBAAgB,cAAc;GACzC;EACF,CAAC;EACD,SAAS,uBAAuB;CAClC,OAAO;EACL,SAAS,uBAAuB;EAChC,SAAS,cAAc,cAAc,YAAY;EACjD,SAAS,uBAAuB;CAClC;CAEA,OAAO;EACL,MAAM;EACN,eAAe;EACf,WAAW;CACb;AACF;AAEA,SAAS,aAAgB,OAAgC;CACvD,OAAO,kBAAkB,KAAK;AAChC;AAEA,MAAa,MAAM,0BACjB,YAGF"}
@@ -0,0 +1,9 @@
1
+ import { RenderableChild, VNode } from "../common/vnode.js";
2
+
3
+ //#region src/control/shared.d.ts
4
+ type BoundaryChild = RenderableChild;
5
+ declare function normalizeBoundaryChild(value: unknown): VNode | null;
6
+ declare function resolveMaybeAccessor<T>(value: T | (() => T)): T;
7
+ //#endregion
8
+ export { BoundaryChild };
9
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","names":[],"sources":["../../src/control/shared.ts"],"mappings":";;;KAGY,aAAA,GAAgB,eAAe;AAAA,iBAE3B,sBAAA,CAAuB,KAAA,YAAiB,KAAK;AAAA,iBAmB7C,oBAAA,GAAA,CAAwB,KAAA,EAAO,CAAA,UAAW,CAAA,IAAK,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","names":[],"sources":["../../src/control/shared.ts"],"sourcesContent":["import { Fragment } from '../common/jsx';\nimport type { DOMElement, VNode } from '../common/vnode';\n\nexport function normalizeBoundaryChild(value: unknown): VNode | null {\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return null;\n }\n if (value.length === 1) {\n return normalizeBoundaryChild(value[0]);\n }\n return {\n type: Fragment,\n props: {\n children: value,\n },\n } as DOMElement;\n }\n\n return (value ?? null) as VNode | null;\n}\n\nexport function resolveMaybeAccessor<T>(value: T | (() => T)): T {\n return typeof value === 'function' ? (value as () => T)() : value;\n}\n"],"mappings":";;AAGA,SAAgB,uBAAuB,OAA8B;CACnE,IAAI,MAAM,QAAQ,MAAM,EAAE;EACxB,IAAI,MAAM,WAAW,GACnB,OAAO;EAET,IAAI,MAAM,WAAW,GACnB,OAAO,uBAAuB,MAAM,GAAG;EAEzC,OAAO;GACL,MAAM;GACN,OAAO,EACL,UAAU,OACX;GACF;;CAGH,OAAQ,SAAS;;AAGnB,SAAgB,qBAAwB,OAAyB;CAC/D,OAAO,OAAO,UAAU,aAAc,OAAmB,GAAG"}
1
+ {"version":3,"file":"shared.js","names":[],"sources":["../../src/control/shared.ts"],"sourcesContent":["import { Fragment } from '../common/jsx';\nimport type { DOMElement, RenderableChild, VNode } from '../common/vnode';\n\nexport type BoundaryChild = RenderableChild;\n\nexport function normalizeBoundaryChild(value: unknown): VNode | null {\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return null;\n }\n if (value.length === 1) {\n return normalizeBoundaryChild(value[0]);\n }\n return {\n type: Fragment,\n props: {\n children: value,\n },\n } as DOMElement;\n }\n\n return (value ?? null) as VNode | null;\n}\n\nexport function resolveMaybeAccessor<T>(value: T | (() => T)): T {\n return typeof value === 'function' ? (value as () => T)() : value;\n}\n"],"mappings":";;AAKA,SAAgB,uBAAuB,OAA8B;CACnE,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,MAAM,WAAW,GACnB,OAAO;EAET,IAAI,MAAM,WAAW,GACnB,OAAO,uBAAuB,MAAM,EAAE;EAExC,OAAO;GACL,MAAM;GACN,OAAO,EACL,UAAU,MACZ;EACF;CACF;CAEA,OAAQ,SAAS;AACnB;AAEA,SAAgB,qBAAwB,OAAyB;CAC/D,OAAO,OAAO,UAAU,aAAc,MAAkB,IAAI;AAC9D"}
@@ -1,12 +1,13 @@
1
1
  import { JSXElement } from "../common/jsx.js";
2
- import { VNode } from "../common/vnode.js";
2
+ import { BoundaryChild } from "./shared.js";
3
3
 
4
4
  //#region src/control/show.d.ts
5
5
  type ShowSource<T> = T | (() => T);
6
+ type Truthy<T> = T extends false | '' | 0 | 0n | null | undefined ? never : T;
6
7
  type ShowProps<T> = {
7
8
  when: ShowSource<T>;
8
- fallback?: unknown;
9
- children: unknown | ((value: NonNullable<T>) => VNode);
9
+ fallback?: BoundaryChild;
10
+ children: BoundaryChild | ((value: Truthy<T>) => BoundaryChild);
10
11
  };
11
12
  declare const Show: <T>(props: ShowProps<T>) => JSXElement;
12
13
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"show.d.ts","names":[],"sources":["../../src/control/show.ts"],"mappings":";;;;KAUK,UAAA,MAAgB,CAAA,UAAW,CAAA;AAAA,KAEpB,SAAA;EACV,IAAA,EAAM,UAAA,CAAW,CAAA;EACjB,QAAA;EACA,QAAA,cAAsB,KAAA,EAAO,WAAA,CAAY,CAAA,MAAO,KAAA;AAAA;AAAA,cA+CrC,IAAA,MAEJ,KAAA,EAAO,SAAA,CAAU,CAAA,MAAO,UAAA"}
1
+ {"version":3,"file":"show.d.ts","names":[],"sources":["../../src/control/show.ts"],"mappings":";;;;KAcK,UAAA,MAAgB,CAAA,UAAW,CAAC;AAAA,KAC5B,MAAA,MAAY,CAAA,0DAA2D,CAAC;AAAA,KAEjE,SAAA;EACV,IAAA,EAAM,UAAA,CAAW,CAAA;EACjB,QAAA,GAAW,aAAA;EACX,QAAA,EAAU,aAAA,KAAkB,KAAA,EAAO,MAAA,CAAO,CAAA,MAAO,aAAA;AAAA;AAAA,cA+CtC,IAAA,MAEJ,KAAA,EAAO,SAAA,CAAU,CAAA,MAAO,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"show.js","names":[],"sources":["../../src/control/show.ts"],"sourcesContent":["import {\n __CONTROL_BOUNDARY__,\n markEagerControlPrimitive,\n} from '../common/control';\nimport type { JSXElement } from '../common/jsx';\nimport type { VNode } from '../common/vnode';\nimport { createShowState, type ShowState } from '../runtime/control';\nimport { state } from '../runtime/state';\nimport { normalizeBoundaryChild, resolveMaybeAccessor } from './shared';\n\ntype ShowSource<T> = T | (() => T);\n\nexport type ShowProps<T> = {\n when: ShowSource<T>;\n fallback?: unknown;\n children: unknown | ((value: NonNullable<T>) => VNode);\n};\n\nfunction createTruthyRenderer<T>(\n props: ShowProps<T>\n): ShowState['renderTruthy'] {\n if (typeof props.children === 'function') {\n return (value: unknown) =>\n normalizeBoundaryChild(\n (props.children as (resolved: NonNullable<T>) => VNode)(\n value as NonNullable<T>\n )\n ) as VNode;\n }\n\n const staticChild = normalizeBoundaryChild(props.children);\n return () => staticChild as VNode;\n}\n\nfunction createFallbackRenderer(fallback: unknown): (() => VNode) | null {\n const normalizedFallback = normalizeBoundaryChild(fallback);\n if (normalizedFallback == null || normalizedFallback === false) {\n return null;\n }\n return () => normalizedFallback;\n}\n\nfunction ShowPrimitive<T>(props: ShowProps<T>): JSXElement {\n const selectedValue = resolveMaybeAccessor(props.when);\n const renderTruthy = createTruthyRenderer(props);\n const renderFallback = createFallbackRenderer(props.fallback);\n\n const showStateContainer = state<ShowState>(\n createShowState(selectedValue, renderTruthy, renderFallback)\n );\n const showState = showStateContainer();\n\n showState.selectedValue = selectedValue;\n showState.renderTruthy = renderTruthy;\n showState.renderFallback = renderFallback;\n\n return {\n type: __CONTROL_BOUNDARY__,\n _controlState: showState,\n } as unknown as JSXElement;\n}\n\nexport const Show = markEagerControlPrimitive(\n ShowPrimitive as <T>(props: ShowProps<T>) => JSXElement\n) as <T>(props: ShowProps<T>) => JSXElement;\n"],"mappings":";;;;;AAkBA,SAAS,qBACP,OAC2B;CAC3B,IAAI,OAAO,MAAM,aAAa,YAC5B,QAAQ,UACN,uBACG,MAAM,SACL,MACD,CACF;CAGL,MAAM,cAAc,uBAAuB,MAAM,SAAS;CAC1D,aAAa;;AAGf,SAAS,uBAAuB,UAAyC;CACvE,MAAM,qBAAqB,uBAAuB,SAAS;CAC3D,IAAI,sBAAsB,QAAQ,uBAAuB,OACvD,OAAO;CAET,aAAa;;AAGf,SAAS,cAAiB,OAAiC;CACzD,MAAM,gBAAgB,qBAAqB,MAAM,KAAK;CACtD,MAAM,eAAe,qBAAqB,MAAM;CAChD,MAAM,iBAAiB,uBAAuB,MAAM,SAAS;CAK7D,MAAM,YAHqB,MACzB,gBAAgB,eAAe,cAAc,eAAe,CAE5C,EAAoB;CAEtC,UAAU,gBAAgB;CAC1B,UAAU,eAAe;CACzB,UAAU,iBAAiB;CAE3B,OAAO;EACL,MAAM;EACN,eAAe;EAChB;;AAGH,MAAa,OAAO,0BAClB,cACD"}
1
+ {"version":3,"file":"show.js","names":[],"sources":["../../src/control/show.ts"],"sourcesContent":["import {\n __CONTROL_BOUNDARY__,\n markEagerControlPrimitive,\n} from '../common/control';\nimport type { JSXElement } from '../common/jsx';\nimport type { VNode } from '../common/vnode';\nimport { createShowState, type ShowState } from '../runtime/control';\nimport { state } from '../runtime/state';\nimport {\n type BoundaryChild,\n normalizeBoundaryChild,\n resolveMaybeAccessor,\n} from './shared';\n\ntype ShowSource<T> = T | (() => T);\ntype Truthy<T> = T extends false | '' | 0 | 0n | null | undefined ? never : T;\n\nexport type ShowProps<T> = {\n when: ShowSource<T>;\n fallback?: BoundaryChild;\n children: BoundaryChild | ((value: Truthy<T>) => BoundaryChild);\n};\n\nfunction createTruthyRenderer<T>(\n props: ShowProps<T>\n): ShowState['renderTruthy'] {\n if (typeof props.children === 'function') {\n return (value: unknown) =>\n normalizeBoundaryChild(\n (props.children as (resolved: Truthy<T>) => VNode)(value as Truthy<T>)\n ) as VNode;\n }\n\n const staticChild = normalizeBoundaryChild(props.children);\n return () => staticChild as VNode;\n}\n\nfunction createFallbackRenderer(\n fallback: BoundaryChild | undefined\n): (() => VNode) | null {\n const normalizedFallback = normalizeBoundaryChild(fallback);\n if (normalizedFallback == null || normalizedFallback === false) {\n return null;\n }\n return () => normalizedFallback;\n}\n\nfunction ShowPrimitive<T>(props: ShowProps<T>): JSXElement {\n const selectedValue = resolveMaybeAccessor(props.when);\n const renderTruthy = createTruthyRenderer(props);\n const renderFallback = createFallbackRenderer(props.fallback);\n\n const showStateContainer = state<ShowState>(\n createShowState(selectedValue, renderTruthy, renderFallback)\n );\n const showState = showStateContainer();\n\n showState.selectedValue = selectedValue;\n showState.renderTruthy = renderTruthy;\n showState.renderFallback = renderFallback;\n\n return {\n type: __CONTROL_BOUNDARY__,\n _controlState: showState,\n } as unknown as JSXElement;\n}\n\nexport const Show = markEagerControlPrimitive(\n ShowPrimitive as <T>(props: ShowProps<T>) => JSXElement\n) as <T>(props: ShowProps<T>) => JSXElement;\n"],"mappings":";;;;;AAuBA,SAAS,qBACP,OAC2B;CAC3B,IAAI,OAAO,MAAM,aAAa,YAC5B,QAAQ,UACN,uBACG,MAAM,SAA4C,KAAkB,CACvE;CAGJ,MAAM,cAAc,uBAAuB,MAAM,QAAQ;CACzD,aAAa;AACf;AAEA,SAAS,uBACP,UACsB;CACtB,MAAM,qBAAqB,uBAAuB,QAAQ;CAC1D,IAAI,sBAAsB,QAAQ,uBAAuB,OACvD,OAAO;CAET,aAAa;AACf;AAEA,SAAS,cAAiB,OAAiC;CACzD,MAAM,gBAAgB,qBAAqB,MAAM,IAAI;CACrD,MAAM,eAAe,qBAAqB,KAAK;CAC/C,MAAM,iBAAiB,uBAAuB,MAAM,QAAQ;CAK5D,MAAM,YAHqB,MACzB,gBAAgB,eAAe,cAAc,cAAc,CAE3C,EAAmB;CAErC,UAAU,gBAAgB;CAC1B,UAAU,eAAe;CACzB,UAAU,iBAAiB;CAE3B,OAAO;EACL,MAAM;EACN,eAAe;CACjB;AACF;AAEA,MAAa,OAAO,0BAClB,aACF"}