@askrjs/askr 0.0.35 → 0.0.37

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 (202) hide show
  1. package/README.md +17 -9
  2. package/dist/bench/components/benchmark-row.js.map +1 -1
  3. package/dist/bench/components/benchmark-table.js +1 -1
  4. package/dist/bench/components/benchmark-table.js.map +1 -1
  5. package/dist/benchmark.js +3 -3
  6. package/dist/benchmark.js.map +1 -1
  7. package/dist/bin/askr-ssg.js.map +1 -1
  8. package/dist/boot/index.d.ts +1 -7
  9. package/dist/boot/index.d.ts.map +1 -1
  10. package/dist/boot/index.js +31 -42
  11. package/dist/boot/index.js.map +1 -1
  12. package/dist/common/control.js.map +1 -1
  13. package/dist/common/env.js.map +1 -1
  14. package/dist/common/ssr-errors.js.map +1 -1
  15. package/dist/common/vnode.js.map +1 -1
  16. package/dist/components/error-boundary.js.map +1 -1
  17. package/dist/components/index.d.ts +2 -0
  18. package/dist/components/index.js +2 -0
  19. package/dist/components/link.d.ts +4 -5
  20. package/dist/components/link.d.ts.map +1 -1
  21. package/dist/components/link.js +2 -1
  22. package/dist/components/link.js.map +1 -1
  23. package/dist/control/case.js.map +1 -1
  24. package/dist/control/for.js.map +1 -1
  25. package/dist/control/shared.js.map +1 -1
  26. package/dist/control/show.js.map +1 -1
  27. package/dist/data/index.d.ts.map +1 -1
  28. package/dist/data/index.js +165 -23
  29. package/dist/data/index.js.map +1 -1
  30. package/dist/dev/invariant.js.map +1 -1
  31. package/dist/dev/logger.js.map +1 -1
  32. package/dist/foundations/icon/icon.d.ts.map +1 -1
  33. package/dist/foundations/icon/icon.js.map +1 -1
  34. package/dist/foundations/icon/icon.types.d.ts +2 -1
  35. package/dist/foundations/icon/icon.types.d.ts.map +1 -1
  36. package/dist/foundations/icon/index.d.ts +3 -0
  37. package/dist/foundations/icon/index.js +2 -0
  38. package/dist/foundations/index.d.ts +1 -18
  39. package/dist/foundations/index.js +2 -18
  40. package/dist/foundations/interactions/dismissable.js.map +1 -1
  41. package/dist/foundations/interactions/focusable.js.map +1 -1
  42. package/dist/foundations/interactions/hoverable.js.map +1 -1
  43. package/dist/foundations/interactions/index.d.ts +7 -0
  44. package/dist/foundations/interactions/index.js +7 -0
  45. package/dist/foundations/interactions/interaction-policy.js +2 -2
  46. package/dist/foundations/interactions/interaction-policy.js.map +1 -1
  47. package/dist/foundations/interactions/pressable.js.map +1 -1
  48. package/dist/foundations/interactions/roving-focus.js.map +1 -1
  49. package/dist/foundations/state/controllable.js.map +1 -1
  50. package/dist/foundations/state/index.d.ts +2 -0
  51. package/dist/foundations/state/index.js +2 -0
  52. package/dist/foundations/structures/collection.js.map +1 -1
  53. package/dist/foundations/structures/index.d.ts +8 -0
  54. package/dist/foundations/structures/index.js +7 -0
  55. package/dist/foundations/structures/layer.js.map +1 -1
  56. package/dist/foundations/structures/layout.js.map +1 -1
  57. package/dist/foundations/structures/portal.js.map +1 -1
  58. package/dist/foundations/structures/presence.js.map +1 -1
  59. package/dist/foundations/structures/slot.js.map +1 -1
  60. package/dist/foundations/utilities/aria.js.map +1 -1
  61. package/dist/foundations/utilities/compose-handlers.js.map +1 -1
  62. package/dist/foundations/utilities/compose-ref.js.map +1 -1
  63. package/dist/foundations/utilities/index.d.ts +7 -0
  64. package/dist/foundations/utilities/index.js +6 -0
  65. package/dist/foundations/utilities/merge-props.js.map +1 -1
  66. package/dist/foundations/utilities/use-id.js.map +1 -1
  67. package/dist/fx/fx.js.map +1 -1
  68. package/dist/fx/timing.js.map +1 -1
  69. package/dist/index.d.ts +2 -16
  70. package/dist/index.js +1 -17
  71. package/dist/index.js.map +1 -1
  72. package/dist/jsx/utils.js.map +1 -1
  73. package/dist/jsx-dev-runtime.d.ts +1 -1
  74. package/dist/jsx-dev-runtime.js.map +1 -1
  75. package/dist/jsx-runtime.d.ts +1 -1
  76. package/dist/jsx-runtime.js.map +1 -1
  77. package/dist/renderer/children.js.map +1 -1
  78. package/dist/renderer/cleanup.js.map +1 -1
  79. package/dist/renderer/dom.js +92 -357
  80. package/dist/renderer/dom.js.map +1 -1
  81. package/dist/renderer/evaluate.js +7 -0
  82. package/dist/renderer/evaluate.js.map +1 -1
  83. package/dist/renderer/fastpath.js +20 -18
  84. package/dist/renderer/fastpath.js.map +1 -1
  85. package/dist/renderer/for-commit.js +486 -0
  86. package/dist/renderer/for-commit.js.map +1 -0
  87. package/dist/renderer/index.js.map +1 -1
  88. package/dist/renderer/keyed.js +84 -23
  89. package/dist/renderer/keyed.js.map +1 -1
  90. package/dist/renderer/reconcile.js +11 -18
  91. package/dist/renderer/reconcile.js.map +1 -1
  92. package/dist/renderer/utils.js +5 -1
  93. package/dist/renderer/utils.js.map +1 -1
  94. package/dist/resources/index.d.ts +1 -2
  95. package/dist/resources/index.js +1 -2
  96. package/dist/router/index.d.ts +2 -2
  97. package/dist/router/index.js +2 -2
  98. package/dist/router/match.js.map +1 -1
  99. package/dist/router/navigate.d.ts.map +1 -1
  100. package/dist/router/navigate.js +4 -2
  101. package/dist/router/navigate.js.map +1 -1
  102. package/dist/router/policy.js.map +1 -1
  103. package/dist/router/route-context.js.map +1 -1
  104. package/dist/router/route.d.ts +1 -1
  105. package/dist/router/route.d.ts.map +1 -1
  106. package/dist/router/route.js +2 -33
  107. package/dist/router/route.js.map +1 -1
  108. package/dist/runtime/child-scope.d.ts +1 -0
  109. package/dist/runtime/child-scope.d.ts.map +1 -1
  110. package/dist/runtime/child-scope.js +2 -0
  111. package/dist/runtime/child-scope.js.map +1 -1
  112. package/dist/runtime/component.js +1 -1
  113. package/dist/runtime/component.js.map +1 -1
  114. package/dist/runtime/context.js.map +1 -1
  115. package/dist/runtime/control.js.map +1 -1
  116. package/dist/runtime/derive.d.ts +2 -1
  117. package/dist/runtime/derive.d.ts.map +1 -1
  118. package/dist/runtime/derive.js +15 -10
  119. package/dist/runtime/derive.js.map +1 -1
  120. package/dist/runtime/dev-namespace.js.map +1 -1
  121. package/dist/runtime/effect.d.ts.map +1 -1
  122. package/dist/runtime/effect.js +34 -9
  123. package/dist/runtime/effect.js.map +1 -1
  124. package/dist/runtime/events.js.map +1 -1
  125. package/dist/runtime/execution-model.js.map +1 -1
  126. package/dist/runtime/fastlane.js.map +1 -1
  127. package/dist/runtime/for-bench.d.ts +1 -1
  128. package/dist/runtime/for-bench.d.ts.map +1 -1
  129. package/dist/runtime/for-bench.js +15 -14
  130. package/dist/runtime/for-bench.js.map +1 -1
  131. package/dist/runtime/for.d.ts +1 -0
  132. package/dist/runtime/for.d.ts.map +1 -1
  133. package/dist/runtime/for.js +90 -31
  134. package/dist/runtime/for.js.map +1 -1
  135. package/dist/runtime/operations.d.ts.map +1 -1
  136. package/dist/runtime/operations.js +10 -8
  137. package/dist/runtime/operations.js.map +1 -1
  138. package/dist/runtime/perf-metrics.js +8 -2
  139. package/dist/runtime/perf-metrics.js.map +1 -1
  140. package/dist/runtime/readable.js.map +1 -1
  141. package/dist/runtime/resource-cell.js +3 -2
  142. package/dist/runtime/resource-cell.js.map +1 -1
  143. package/dist/runtime/scheduler.d.ts +0 -1
  144. package/dist/runtime/scheduler.d.ts.map +1 -1
  145. package/dist/runtime/scheduler.js +6 -19
  146. package/dist/runtime/scheduler.js.map +1 -1
  147. package/dist/runtime/selector.d.ts.map +1 -1
  148. package/dist/runtime/selector.js +182 -103
  149. package/dist/runtime/selector.js.map +1 -1
  150. package/dist/runtime/snapshot-source.d.ts +10 -0
  151. package/dist/runtime/snapshot-source.d.ts.map +1 -0
  152. package/dist/runtime/snapshot-source.js +17 -0
  153. package/dist/runtime/snapshot-source.js.map +1 -0
  154. package/dist/runtime/ssr-bridge.js.map +1 -1
  155. package/dist/runtime/state.d.ts.map +1 -1
  156. package/dist/runtime/state.js +1 -5
  157. package/dist/runtime/state.js.map +1 -1
  158. package/dist/ssg/batch-render.js.map +1 -1
  159. package/dist/ssg/create-static-gen.js.map +1 -1
  160. package/dist/ssg/generate-metadata.js.map +1 -1
  161. package/dist/ssg/incremental-manifest.js.map +1 -1
  162. package/dist/ssg/index.d.ts +1 -6
  163. package/dist/ssg/index.js +1 -6
  164. package/dist/ssg/resolve-ssg-data.js.map +1 -1
  165. package/dist/ssg/route-utils.js.map +1 -1
  166. package/dist/ssg/write-static-files.js.map +1 -1
  167. package/dist/ssr/attrs.js.map +1 -1
  168. package/dist/ssr/context.d.ts +3 -1
  169. package/dist/ssr/context.d.ts.map +1 -1
  170. package/dist/ssr/context.js +31 -11
  171. package/dist/ssr/context.js.map +1 -1
  172. package/dist/ssr/escape.js +56 -16
  173. package/dist/ssr/escape.js.map +1 -1
  174. package/dist/ssr/index.d.ts +2 -31
  175. package/dist/ssr/index.d.ts.map +1 -1
  176. package/dist/ssr/index.js +19 -49
  177. package/dist/ssr/index.js.map +1 -1
  178. package/dist/ssr/render-keys.js +1 -12
  179. package/dist/ssr/render-keys.js.map +1 -1
  180. package/dist/ssr/sink.js.map +1 -1
  181. package/dist/ssr/verify-hydration.js +25 -0
  182. package/dist/ssr/verify-hydration.js.map +1 -0
  183. package/package.json +44 -19
  184. package/dist/_virtual/_rolldown/runtime.js +0 -7
  185. package/dist/foundations/core.d.ts +0 -15
  186. package/dist/foundations/core.js +0 -13
  187. package/dist/foundations/structures.d.ts +0 -7
  188. package/dist/foundations/structures.js +0 -6
  189. package/dist/ssg/batch-render.d.ts +0 -16
  190. package/dist/ssg/batch-render.d.ts.map +0 -1
  191. package/dist/ssg/generate-metadata.d.ts +0 -24
  192. package/dist/ssg/generate-metadata.d.ts.map +0 -1
  193. package/dist/ssg/resolve-ssg-data.d.ts +0 -23
  194. package/dist/ssg/resolve-ssg-data.d.ts.map +0 -1
  195. package/dist/ssg/route-utils.d.ts +0 -16
  196. package/dist/ssg/route-utils.d.ts.map +0 -1
  197. package/dist/ssg/write-static-files.d.ts +0 -15
  198. package/dist/ssg/write-static-files.d.ts.map +0 -1
  199. package/dist/ssr/render-keys.d.ts +0 -37
  200. package/dist/ssr/render-keys.d.ts.map +0 -1
  201. package/dist/ssr/stream-render.js +0 -76
  202. package/dist/ssr/stream-render.js.map +0 -1
@@ -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":"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"}
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"}
@@ -0,0 +1,2 @@
1
+ import { ErrorBoundary, ErrorBoundaryFallbackRender, ErrorBoundaryProps } from "./error-boundary.js";
2
+ export { ErrorBoundary, type ErrorBoundaryFallbackRender, type ErrorBoundaryProps };
@@ -0,0 +1,2 @@
1
+ import { ErrorBoundary } from "./error-boundary.js";
2
+ export { ErrorBoundary };
@@ -1,8 +1,7 @@
1
+ import { Props } from "../common/props.js";
2
+ import { JSXElement } from "../common/jsx.js";
1
3
  //#region src/components/link.d.ts
2
- /**
3
- * Link component for client-side navigation
4
- */
5
- type LinkProps = Omit<JSX.IntrinsicElements['a'], 'children' | 'href' | 'class' | 'rel' | 'target' | 'aria-current' | 'aria-label'> & {
4
+ type LinkProps = Omit<Props, 'children' | 'href' | 'class' | 'rel' | 'target' | 'aria-current' | 'aria-label'> & {
6
5
  href: string;
7
6
  class?: string;
8
7
  children?: unknown;
@@ -62,7 +61,7 @@ declare function Link({
62
61
  'aria-current': ariaCurrent,
63
62
  'aria-label': ariaLabel,
64
63
  ...rest
65
- }: LinkProps): JSX.Element;
64
+ }: LinkProps): JSXElement;
66
65
  //#endregion
67
66
  export { Link, LinkProps };
68
67
  //# sourceMappingURL=link.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"link.d.ts","names":[],"sources":["../../src/components/link.tsx"],"mappings":";;AAQA;;KAAY,SAAA,GAAY,IAAA,CACtB,GAAA,CAAI,iBAAA;EASJ,IAAA;EACA,KAAA;EACA,QAAA;EAXI;;;;EAgBJ,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,GAAA,CAAI,OAAA"}
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,8 +1,9 @@
1
+ import "../jsx/types.js";
1
2
  import { jsx } from "../jsx-runtime.js";
3
+ import "../jsx-runtime2.js";
2
4
  import { navigate } from "../router/navigate.js";
3
5
  import { mergeProps } from "../foundations/utilities/merge-props.js";
4
6
  import { applyInteractionPolicy } from "../foundations/interactions/interaction-policy.js";
5
- import "../jsx-runtime2.js";
6
7
  //#region src/components/link.tsx
7
8
  /**
8
9
  * Link component for client-side navigation
@@ -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 { navigate } from '../router/navigate';\nimport { applyInteractionPolicy } from '../foundations/interactions/interaction-policy';\nimport { mergeProps } from '../foundations/utilities/merge-props';\n\nexport type LinkProps = Omit<\n JSX.IntrinsicElements['a'],\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): JSX.Element {\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4EA,SAAgB,KAAK,EACnB,MACA,OAAO,WACP,UACA,KACA,QACA,gBAAgB,aAChB,cAAc,WACd,GAAG,QACsB;AAwCzB,QAAO,oBAAC,KAAD;EAAG,GAVI,WAAW,MAAM;GAC7B,GA9BkB,uBAAuB;IACzC,UAAU;IACV,UAAU;IACV,UAAU,MAAa;KACrB,MAAM,QAAQ;AAKd,UADe,MAAM,UAAU,OAElB,KACX,MAAM,WACN,MAAM,WACN,MAAM,YACN,MAAM,OAEN;AAIF,SAAI,OACF;AAGF,WAAM,gBAAgB;AACtB,cAAS,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 { 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 +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;AACrD,KAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,QAAO,YAAY,QAAQ,aAAa,QAAQ,EAAE,GAAG,CAAC,SAAS;CAGjE,MAAM,SAAoB,EAAE;AAC5B,MAAK,MAAM,SAAS,UAAU;AAC5B,MAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,UAAO,KAAK,GAAG,gBAAgB,MAAM,CAAC;AACtC;;AAEF,SAAO,KAAK,MAAM;;AAEpB,QAAO;;AAGT,SAAgB,MAAM,QAA0B;AAC9C,KAAI,0BAA0B,CAC5B,OAAM,IAAI,MACR,+DACD;AAEH,QAAO;;AAGT,SAAS,2BAA2B,UAAyC;CAC3E,MAAM,qBAAqB,uBAAuB,SAAS;AAC3D,KAAI,sBAAsB,QAAQ,uBAAuB,MACvD,QAAO;AAET,cAAa;;AAGf,SAAS,qBACP,KACA,OACiB;AACjB,KAAI,OAAO,KACT,QAAO;AAET,QAAO,SAAS,MAAM,GAAG,OAAO,IAAI,GAAG,OAAO,IAAI;;AAGpD,SAAS,kBAAkB,UAAkC;CAC3D,MAAM,WAA0B,EAAE;CAClC,MAAM,eAAe,gBAAgB,SAAS;AAE9C,MAAK,IAAI,QAAQ,GAAG,QAAQ,aAAa,QAAQ,SAAS,GAAG;EAC3D,MAAM,QAAQ,aAAa;AAC3B,MAAI,SAAS,QAAQ,UAAU,MAC7B;AAGF,MACE,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;AAClD,YAAS,KAAK;IACZ;IACA;IACA,MAAM,MAAM;IACb,CAAC;AACF;;AAGF,MAAI,0BAA0B,CAC5B,OAAM,IAAI,MAAM,+CAA+C;;AAInE,QAAO;;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;AAEtC,WAAU,UAAU;AACpB,WAAU,WAAW;AAErB,QAAO;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 { 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 +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;AACvD,KAAI,CAAC,MAAM,QAAQ,SAAS,CAC1B,OAAM,IAAI,MAAM,qCAAqC;AAEvD,QAAO;;AAGT,SAAS,aACP,OAC6C;AAC7C,KAAI,QAAQ,SAAS,OAAO,MAAM,OAAO,WACvC,QAAO,MAAM;AAEf,KAAI,aAAa,SAAS,MAAM,YAAY,KAC1C,SAAQ,OAAO,UAAU;AAE3B,OAAM,IAAI,MACR,+GACD;;AAGH,SAAS,kBAAqB,OAAgC;AAC5D,KAAI,QAAQ,SAAS,OAAO,MAAM,OAAO,cAAc,aAAa,MAClE,OAAM,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;AAC3D,KAAI,CAAC,SAAS,eAAe;AAC3B,WAAS,uBAAuB;AAChC,WAAS,gBAAgB,wBAAwB;GAC/C,MAAM;GACN,SAAS;GACT,SAAS,UAAU;AACjB,aAAS,eAAe;AAExB,QAAI,SAAS,qBACX;AAGF,aAAS,wBAAwB;AAEjC,QAAI,SAAS,wBAAwB;AACnC,cAAS,wBAAwB;AACjC;;AAGF,aAAS,gBAAgB,eAAe;;GAE3C,CAAC;AACF,WAAS,uBAAuB;QAC3B;AACL,WAAS,uBAAuB;AAChC,WAAS,cAAc,cAAc,aAAa;AAClD,WAAS,uBAAuB;;AAGlC,QAAO;EACL,MAAM;EACN,eAAe;EACf,WAAW;EACZ;;AAGH,SAAS,aAAgB,OAAgC;AACvD,QAAO,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 { 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 +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;AACnE,KAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,MAAI,MAAM,WAAW,EACnB,QAAO;AAET,MAAI,MAAM,WAAW,EACnB,QAAO,uBAAuB,MAAM,GAAG;AAEzC,SAAO;GACL,MAAM;GACN,OAAO,EACL,UAAU,OACX;GACF;;AAGH,QAAQ,SAAS;;AAGnB,SAAgB,qBAAwB,OAAyB;AAC/D,QAAO,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, 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 +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;AAC3B,KAAI,OAAO,MAAM,aAAa,WAC5B,SAAQ,UACN,uBACG,MAAM,SACL,MACD,CACF;CAGL,MAAM,cAAc,uBAAuB,MAAM,SAAS;AAC1D,cAAa;;AAGf,SAAS,uBAAuB,UAAyC;CACvE,MAAM,qBAAqB,uBAAuB,SAAS;AAC3D,KAAI,sBAAsB,QAAQ,uBAAuB,MACvD,QAAO;AAET,cAAa;;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;AAEtC,WAAU,gBAAgB;AAC1B,WAAU,eAAe;AACzB,WAAU,iBAAiB;AAE3B,QAAO;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 { 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 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/data/index.ts"],"mappings":";KASY,gBAAA;AAAA,KAMA,KAAA;EACV,IAAA,EAAM,CAAA;EACN,KAAA;EACA,OAAA;EACA,UAAA;EACA,KAAA;EACA,WAAA,EAAa,gBAAA;EAEb,OAAA,IAAW,OAAA;AAAA;AAAA,KAGD,QAAA;EACV,MAAA;EACA,OAAA;EACA,KAAA;EACA,MAAA,EAAQ,OAAA;EAER,OAAA,CAAQ,KAAA,EAAO,MAAA,GAAS,OAAA,CAAQ,OAAA;EAChC,KAAA;EACA,KAAA;AAAA;AAAA,KAGG,YAAA;EACH,GAAA;EACA,KAAA,GAAQ,GAAA;IAAO,MAAA,EAAQ,WAAA;EAAA,MAAkB,OAAA,CAAQ,CAAA;EACjD,YAAA,IAAgB,IAAA,EAAM,CAAA;EACtB,SAAA,IAAa,IAAA,EAAM,CAAA,EAAG,GAAA;IAAO,GAAA;EAAA,MAAkB,OAAA;AAAA;AAAA,KAG5C,eAAA;EACH,MAAA,GAAS,KAAA,EAAO,MAAA,EAAQ,GAAA;IAAO,MAAA,EAAQ,WAAA;EAAA,MAAkB,OAAA,CAAQ,OAAA;EACjE,OAAA,IAAW,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,OAAA;EAClC,YAAA;AAAA;AAAA,iBA6Wc,WAAA,GAAA,CAAe,OAAA,EAAS,YAAA,CAAa,CAAA,IAAK,KAAA,CAAM,CAAA;AAAA,iBAahD,UAAA,CAAW,MAAA;AAAA,iBAIX,cAAA,iBAAA,CACd,OAAA,EAAS,eAAA,CAAgB,MAAA,EAAQ,OAAA,IAChC,QAAA,CAAS,MAAA,EAAQ,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/data/index.ts"],"mappings":";KAeY,gBAAA;AAAA,KAMA,KAAA;EACV,IAAA,EAAM,CAAA;EACN,KAAA;EACA,OAAA;EACA,UAAA;EACA,KAAA;EACA,WAAA,EAAa,gBAAA;EAEb,OAAA,IAAW,OAAA;AAAA;AAAA,KAGD,QAAA;EACV,MAAA;EACA,OAAA;EACA,KAAA;EACA,MAAA,EAAQ,OAAA;EAER,OAAA,CAAQ,KAAA,EAAO,MAAA,GAAS,OAAA,CAAQ,OAAA;EAChC,KAAA;EACA,KAAA;AAAA;AAAA,KAGG,YAAA;EACH,GAAA;EACA,KAAA,GAAQ,GAAA;IAAO,MAAA,EAAQ,WAAA;EAAA,MAAkB,OAAA,CAAQ,CAAA;EACjD,YAAA,IAAgB,IAAA,EAAM,CAAA;EACtB,SAAA,IAAa,IAAA,EAAM,CAAA,EAAG,GAAA;IAAO,GAAA;EAAA,MAAkB,OAAA;AAAA;AAAA,KAG5C,eAAA;EACH,MAAA,GAAS,KAAA,EAAO,MAAA,EAAQ,GAAA;IAAO,MAAA,EAAQ,WAAA;EAAA,MAAkB,OAAA,CAAQ,OAAA;EACjE,OAAA,IAAW,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAQ,OAAA;EAClC,YAAA;AAAA;AAAA,iBAqjBc,WAAA,GAAA,CAAe,OAAA,EAAS,YAAA,CAAa,CAAA,IAAK,KAAA,CAAM,CAAA;AAAA,iBAyChD,UAAA,CAAW,MAAA;AAAA,iBAIX,cAAA,iBAAA,CACd,OAAA,EAAS,eAAA,CAAgB,MAAA,EAAQ,OAAA,IAChC,QAAA,CAAS,MAAA,EAAQ,OAAA"}
@@ -1,9 +1,67 @@
1
1
  import { globalScheduler } from "../runtime/scheduler.js";
2
2
  import { markReactivePropsDirtySource, markReadableDerivedSubscribersDirty, notifyReadableReaders, recordReadableRead } from "../runtime/readable.js";
3
+ import { claimHookIndex, getCurrentComponentInstance } from "../runtime/component.js";
4
+ import { getRenderContext } from "../ssr/context.js";
3
5
  //#region src/data/index.ts
6
+ const RECONCILE_MAX_ATTEMPTS = 3;
7
+ const RECONCILE_RETRY_DELAY_MS = 25;
8
+ const globalQueryCache = /* @__PURE__ */ new Map();
9
+ const querySlotsByInstance = /* @__PURE__ */ new WeakMap();
10
+ const mutationSlotsByInstance = /* @__PURE__ */ new WeakMap();
11
+ const queryCleanupRegistered = /* @__PURE__ */ new WeakSet();
12
+ const mutationCleanupRegistered = /* @__PURE__ */ new WeakSet();
4
13
  function createReadableSource() {
5
14
  return (() => void 0);
6
15
  }
16
+ function getQueryCache() {
17
+ return getRenderContext()?.queryCache ?? globalQueryCache;
18
+ }
19
+ function getQuerySlotStore(instance) {
20
+ let store = querySlotsByInstance.get(instance);
21
+ if (!store) {
22
+ store = /* @__PURE__ */ new Map();
23
+ querySlotsByInstance.set(instance, store);
24
+ }
25
+ return store;
26
+ }
27
+ function getMutationSlotStore(instance) {
28
+ let store = mutationSlotsByInstance.get(instance);
29
+ if (!store) {
30
+ store = /* @__PURE__ */ new Map();
31
+ mutationSlotsByInstance.set(instance, store);
32
+ }
33
+ return store;
34
+ }
35
+ function ensureQueryCleanup(instance) {
36
+ if (queryCleanupRegistered.has(instance)) return;
37
+ queryCleanupRegistered.add(instance);
38
+ instance.cleanupFns.push(() => {
39
+ const slots = querySlotsByInstance.get(instance);
40
+ if (!slots) {
41
+ queryCleanupRegistered.delete(instance);
42
+ return;
43
+ }
44
+ for (const [hookIndex, slot] of slots) slot.cell.detach(instance, hookIndex);
45
+ slots.clear();
46
+ querySlotsByInstance.delete(instance);
47
+ queryCleanupRegistered.delete(instance);
48
+ });
49
+ }
50
+ function ensureMutationCleanup(instance) {
51
+ if (mutationCleanupRegistered.has(instance)) return;
52
+ mutationCleanupRegistered.add(instance);
53
+ instance.cleanupFns.push(() => {
54
+ const slots = mutationSlotsByInstance.get(instance);
55
+ if (!slots) {
56
+ mutationCleanupRegistered.delete(instance);
57
+ return;
58
+ }
59
+ for (const cell of slots.values()) cell.abort();
60
+ slots.clear();
61
+ mutationSlotsByInstance.delete(instance);
62
+ mutationCleanupRegistered.delete(instance);
63
+ });
64
+ }
7
65
  function notifySource(source) {
8
66
  markReadableDerivedSubscribersDirty(source);
9
67
  markReactivePropsDirtySource(source);
@@ -12,22 +70,26 @@ function notifySource(source) {
12
70
  function isAbortError(error, signal) {
13
71
  return signal.aborted || error instanceof Error && error.name === "AbortError" || typeof DOMException !== "undefined" && error instanceof DOMException && error.name === "AbortError";
14
72
  }
15
- const queryCache = /* @__PURE__ */ new Map();
16
73
  function invalidateQueries(prefix, markPendingWrite) {
17
- for (const [key, query] of queryCache) {
74
+ const cache = getQueryCache();
75
+ for (const [key, query] of cache) {
18
76
  if (!key.startsWith(prefix)) continue;
19
77
  if (markPendingWrite) query.markPendingWrite();
20
78
  query.refresh();
21
79
  }
22
80
  }
23
81
  var QueryCell = class {
24
- constructor(options) {
82
+ constructor(options, key, cache) {
25
83
  this.source = createReadableSource();
26
84
  this.controller = null;
27
85
  this.generation = 0;
28
86
  this.startQueued = false;
29
87
  this.pendingRefresh = null;
88
+ this.pendingRefreshResolve = null;
30
89
  this.reconcileAttemptCount = 0;
90
+ this.destroyed = false;
91
+ this.ownerCount = 0;
92
+ this.owners = /* @__PURE__ */ new Map();
31
93
  this.state = {
32
94
  data: null,
33
95
  error: null,
@@ -37,9 +99,37 @@ var QueryCell = class {
37
99
  consistency: "fresh"
38
100
  };
39
101
  this.options = options;
102
+ this.key = key;
103
+ this.cache = cache;
40
104
  }
41
- setOptions(options) {
42
- this.options = options;
105
+ attach(instance, hookIndex) {
106
+ let hooks = this.owners.get(instance);
107
+ if (!hooks) {
108
+ hooks = /* @__PURE__ */ new Set();
109
+ this.owners.set(instance, hooks);
110
+ }
111
+ if (hooks.has(hookIndex)) return;
112
+ hooks.add(hookIndex);
113
+ this.ownerCount += 1;
114
+ }
115
+ detach(instance, hookIndex) {
116
+ const hooks = this.owners.get(instance);
117
+ if (!hooks || !hooks.delete(hookIndex)) return;
118
+ this.ownerCount -= 1;
119
+ if (hooks.size === 0) this.owners.delete(instance);
120
+ if (this.ownerCount <= 0) this.destroy();
121
+ }
122
+ destroy() {
123
+ if (this.destroyed) return;
124
+ this.destroyed = true;
125
+ this.controller?.abort();
126
+ this.controller = null;
127
+ this.startQueued = false;
128
+ this.reconcileAttemptCount = 0;
129
+ this.ownerCount = 0;
130
+ this.owners.clear();
131
+ this.cache.delete(this.key);
132
+ this.finishPendingRefresh();
43
133
  }
44
134
  get data() {
45
135
  recordReadableRead(this.source);
@@ -66,15 +156,17 @@ var QueryCell = class {
66
156
  return this.state.consistency;
67
157
  }
68
158
  ensureStarted() {
69
- if (this.state.data !== null || this.pendingRefresh || this.startQueued) return;
159
+ if (this.destroyed || this.state.data !== null || this.pendingRefresh || this.startQueued) return;
70
160
  this.queueStart("initial");
71
161
  }
72
162
  refresh() {
163
+ if (this.destroyed) return Promise.resolve();
73
164
  if (this.pendingRefresh) return this.pendingRefresh;
74
165
  this.queueStart("manual");
75
166
  return this.pendingRefresh ?? Promise.resolve();
76
167
  }
77
168
  markPendingWrite() {
169
+ if (this.destroyed) return;
78
170
  this.setState({
79
171
  refreshing: true,
80
172
  stale: true,
@@ -82,18 +174,30 @@ var QueryCell = class {
82
174
  });
83
175
  }
84
176
  queueStart(reason) {
177
+ if (this.destroyed) return;
85
178
  this.startQueued = true;
86
179
  this.pendingRefresh = new Promise((resolve) => {
180
+ this.pendingRefreshResolve = resolve;
87
181
  globalScheduler.enqueue(() => {
88
182
  this.startQueued = false;
183
+ if (this.destroyed) {
184
+ this.finishPendingRefresh();
185
+ return;
186
+ }
89
187
  this.start(reason).finally(() => {
90
- this.pendingRefresh = null;
91
- resolve();
188
+ this.finishPendingRefresh();
92
189
  });
93
190
  });
94
191
  });
95
192
  }
193
+ finishPendingRefresh() {
194
+ const resolve = this.pendingRefreshResolve;
195
+ this.pendingRefresh = null;
196
+ this.pendingRefreshResolve = null;
197
+ resolve?.();
198
+ }
96
199
  setState(next) {
200
+ if (this.destroyed) return;
97
201
  this.state = {
98
202
  ...this.state,
99
203
  ...next
@@ -101,6 +205,7 @@ var QueryCell = class {
101
205
  notifySource(this.source);
102
206
  }
103
207
  async start(reason) {
208
+ if (this.destroyed) return;
104
209
  this.generation += 1;
105
210
  const generation = this.generation;
106
211
  this.controller?.abort();
@@ -118,7 +223,7 @@ var QueryCell = class {
118
223
  try {
119
224
  nextData = await this.options.fetch({ signal: controller.signal });
120
225
  } catch (error) {
121
- if (this.generation !== generation || this.controller !== controller) return;
226
+ if (this.destroyed || this.generation !== generation || this.controller !== controller) return;
122
227
  if (isAbortError(error, controller.signal)) {
123
228
  this.setState({
124
229
  loading: false,
@@ -135,7 +240,7 @@ var QueryCell = class {
135
240
  });
136
241
  return;
137
242
  }
138
- if (this.generation !== generation || this.controller !== controller) return;
243
+ if (this.destroyed || this.generation !== generation || this.controller !== controller) return;
139
244
  if (!(this.options.isConsistent?.(nextData) ?? true)) {
140
245
  this.setState({
141
246
  data: nextData,
@@ -158,17 +263,17 @@ var QueryCell = class {
158
263
  });
159
264
  }
160
265
  async reconcile(data) {
161
- if (!(this.options.reconcile?.(data, { key: this.options.key }) ?? false)) return;
266
+ if (!(this.options.reconcile?.(data, { key: this.options.key }) ?? false) || this.destroyed) return;
162
267
  this.reconcileAttemptCount += 1;
163
- if (this.reconcileAttemptCount > 3) {
268
+ if (this.reconcileAttemptCount > RECONCILE_MAX_ATTEMPTS) {
164
269
  this.setState({
165
270
  consistency: "stale",
166
271
  refreshing: false
167
272
  });
168
273
  return;
169
274
  }
170
- await new Promise((resolve) => setTimeout(resolve, 25));
171
- if (this.state.consistency === "fresh") return;
275
+ await new Promise((resolve) => setTimeout(resolve, RECONCILE_RETRY_DELAY_MS));
276
+ if (this.destroyed || this.state.consistency === "fresh") return;
172
277
  await this.refresh();
173
278
  }
174
279
  };
@@ -186,6 +291,11 @@ var MutationCell = class {
186
291
  this.affects = options.affects;
187
292
  this.afterSuccess = options.afterSuccess;
188
293
  }
294
+ setOptions(options) {
295
+ this.action = options.action;
296
+ this.affects = options.affects;
297
+ this.afterSuccess = options.afterSuccess;
298
+ }
189
299
  get status() {
190
300
  recordReadableRead(this.source);
191
301
  return this.state.status;
@@ -271,21 +381,53 @@ var MutationCell = class {
271
381
  }
272
382
  };
273
383
  function createQuery(options) {
274
- const existing = queryCache.get(options.key);
275
- if (existing) {
276
- existing.setOptions(options);
277
- return existing;
384
+ const instance = getCurrentComponentInstance();
385
+ const cache = getQueryCache();
386
+ if (!instance) {
387
+ let cell = cache.get(options.key);
388
+ if (!cell) {
389
+ cell = new QueryCell(options, options.key, cache);
390
+ cache.set(options.key, cell);
391
+ cell.ensureStarted();
392
+ }
393
+ return cell;
278
394
  }
279
- const created = new QueryCell(options);
280
- queryCache.set(options.key, created);
281
- created.ensureStarted();
282
- return created;
395
+ const hookIndex = claimHookIndex(instance, "query");
396
+ ensureQueryCleanup(instance);
397
+ const slotStore = getQuerySlotStore(instance);
398
+ const existingSlot = slotStore.get(hookIndex);
399
+ if (existingSlot && existingSlot.key === options.key) return existingSlot.cell;
400
+ if (existingSlot) existingSlot.cell.detach(instance, hookIndex);
401
+ let cell = cache.get(options.key);
402
+ if (!cell) {
403
+ cell = new QueryCell(options, options.key, cache);
404
+ cache.set(options.key, cell);
405
+ cell.ensureStarted();
406
+ }
407
+ slotStore.set(hookIndex, {
408
+ key: options.key,
409
+ cell
410
+ });
411
+ cell.attach(instance, hookIndex);
412
+ return cell;
283
413
  }
284
414
  function invalidate(prefix) {
285
415
  invalidateQueries(prefix, false);
286
416
  }
287
417
  function createMutation(options) {
288
- return new MutationCell(options);
418
+ const instance = getCurrentComponentInstance();
419
+ if (!instance) return new MutationCell(options);
420
+ const hookIndex = claimHookIndex(instance, "mutation");
421
+ ensureMutationCleanup(instance);
422
+ const slotStore = getMutationSlotStore(instance);
423
+ const existing = slotStore.get(hookIndex);
424
+ if (existing) {
425
+ existing.setOptions(options);
426
+ return existing;
427
+ }
428
+ const created = new MutationCell(options);
429
+ slotStore.set(hookIndex, created);
430
+ return created;
289
431
  }
290
432
  //#endregion
291
433
  export { createMutation, createQuery, invalidate };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/data/index.ts"],"sourcesContent":["import { globalScheduler } from '../runtime/scheduler';\nimport {\n markReadableDerivedSubscribersDirty,\n markReactivePropsDirtySource,\n notifyReadableReaders,\n recordReadableRead,\n type ReadableSource,\n} from '../runtime/readable';\n\nexport type QueryConsistency =\n | 'fresh'\n | 'stale'\n | 'refreshing'\n | 'pending-write';\n\nexport type Query<T> = {\n data: T | null;\n error: unknown | null;\n loading: boolean;\n refreshing: boolean;\n stale: boolean;\n consistency: QueryConsistency;\n\n refresh(): Promise<void>;\n};\n\nexport type Mutation<TInput, TResult> = {\n status: 'idle' | 'pending' | 'success' | 'error';\n pending: boolean;\n error: unknown | null;\n result: TResult | null;\n\n execute(input: TInput): Promise<TResult>;\n abort(): void;\n reset(): void;\n};\n\ntype QueryOptions<T> = {\n key: string;\n fetch: (ctx: { signal: AbortSignal }) => Promise<T>;\n isConsistent?: (data: T) => boolean;\n reconcile?: (data: T, ctx: { key: string }) => Promise<boolean> | boolean;\n};\n\ntype MutationOptions<TInput, TResult> = {\n action: (input: TInput, ctx: { signal: AbortSignal }) => Promise<TResult>;\n affects?: (input: TInput, result: TResult) => string[];\n afterSuccess?: 'invalidate';\n};\n\ntype QueryState<T> = {\n data: T | null;\n error: unknown | null;\n loading: boolean;\n refreshing: boolean;\n stale: boolean;\n consistency: QueryConsistency;\n};\n\ntype MutationState<TResult> = {\n status: 'idle' | 'pending' | 'success' | 'error';\n error: unknown | null;\n result: TResult | null;\n};\n\nfunction createReadableSource(): ReadableSource<unknown> {\n return (() => undefined) as ReadableSource<unknown>;\n}\n\nfunction notifySource(source: ReadableSource<unknown>): void {\n markReadableDerivedSubscribersDirty(source);\n markReactivePropsDirtySource(source);\n notifyReadableReaders(source);\n}\n\nfunction isAbortError(error: unknown, signal: AbortSignal): boolean {\n return (\n signal.aborted ||\n (error instanceof Error && error.name === 'AbortError') ||\n (typeof DOMException !== 'undefined' &&\n error instanceof DOMException &&\n error.name === 'AbortError')\n );\n}\n\nconst queryCache = new Map<string, QueryCell<unknown>>();\n\nfunction invalidateQueries(prefix: string, markPendingWrite: boolean): void {\n for (const [key, query] of queryCache) {\n if (!key.startsWith(prefix)) {\n continue;\n }\n\n if (markPendingWrite) {\n query.markPendingWrite();\n }\n\n void query.refresh();\n }\n}\n\nclass QueryCell<T> implements Query<T> {\n private readonly source = createReadableSource();\n private options: QueryOptions<T>;\n private controller: AbortController | null = null;\n private generation = 0;\n private startQueued = false;\n private pendingRefresh: Promise<void> | null = null;\n private reconcileAttemptCount = 0;\n\n private state: QueryState<T> = {\n data: null,\n error: null,\n loading: true,\n refreshing: false,\n stale: false,\n consistency: 'fresh',\n };\n\n constructor(options: QueryOptions<T>) {\n this.options = options;\n }\n\n setOptions(options: QueryOptions<T>): void {\n this.options = options;\n }\n\n get data(): T | null {\n recordReadableRead(this.source);\n return this.state.data;\n }\n\n get error(): unknown | null {\n recordReadableRead(this.source);\n return this.state.error;\n }\n\n get loading(): boolean {\n recordReadableRead(this.source);\n return this.state.loading;\n }\n\n get refreshing(): boolean {\n recordReadableRead(this.source);\n return this.state.refreshing;\n }\n\n get stale(): boolean {\n recordReadableRead(this.source);\n return this.state.stale;\n }\n\n get consistency(): QueryConsistency {\n recordReadableRead(this.source);\n return this.state.consistency;\n }\n\n ensureStarted(): void {\n if (this.state.data !== null || this.pendingRefresh || this.startQueued) {\n return;\n }\n\n this.queueStart('initial');\n }\n\n refresh(): Promise<void> {\n if (this.pendingRefresh) {\n return this.pendingRefresh;\n }\n\n this.queueStart('manual');\n return this.pendingRefresh ?? Promise.resolve();\n }\n\n markPendingWrite(): void {\n this.setState({\n refreshing: true,\n stale: true,\n consistency: 'pending-write',\n });\n }\n\n private queueStart(\n reason: 'initial' | 'manual' | 'invalidate' | 'pending-write'\n ): void {\n this.startQueued = true;\n this.pendingRefresh = new Promise<void>((resolve) => {\n globalScheduler.enqueue(() => {\n this.startQueued = false;\n void this.start(reason).finally(() => {\n this.pendingRefresh = null;\n resolve();\n });\n });\n });\n }\n\n private setState(next: Partial<QueryState<T>>): void {\n this.state = {\n ...this.state,\n ...next,\n };\n notifySource(this.source);\n }\n\n private async start(\n reason: 'initial' | 'manual' | 'invalidate' | 'pending-write'\n ): Promise<void> {\n this.generation += 1;\n const generation = this.generation;\n\n this.controller?.abort();\n const controller = new AbortController();\n this.controller = controller;\n\n const hasData = this.state.data !== null;\n this.setState({\n loading: !hasData,\n refreshing: hasData,\n stale: hasData,\n consistency:\n reason === 'pending-write'\n ? 'pending-write'\n : hasData\n ? 'refreshing'\n : 'fresh',\n error: null,\n });\n\n let nextData: T;\n try {\n nextData = await this.options.fetch({ signal: controller.signal });\n } catch (error) {\n if (this.generation !== generation || this.controller !== controller) {\n return;\n }\n\n if (isAbortError(error, controller.signal)) {\n this.setState({ loading: false, refreshing: false });\n return;\n }\n\n this.setState({\n loading: false,\n refreshing: false,\n stale: true,\n consistency: 'stale',\n error,\n });\n return;\n }\n\n if (this.generation !== generation || this.controller !== controller) {\n return;\n }\n\n const isConsistent = this.options.isConsistent?.(nextData) ?? true;\n if (!isConsistent) {\n this.setState({\n data: nextData,\n loading: false,\n refreshing: false,\n stale: true,\n consistency: 'stale',\n });\n await this.reconcile(nextData);\n return;\n }\n\n this.reconcileAttemptCount = 0;\n this.setState({\n data: nextData,\n loading: false,\n refreshing: false,\n stale: false,\n consistency: 'fresh',\n error: null,\n });\n }\n\n private async reconcile(data: T): Promise<void> {\n const shouldRetry =\n this.options.reconcile?.(data, { key: this.options.key }) ?? false;\n\n if (!shouldRetry) {\n return;\n }\n\n this.reconcileAttemptCount += 1;\n if (this.reconcileAttemptCount > 3) {\n this.setState({ consistency: 'stale', refreshing: false });\n return;\n }\n\n await new Promise<void>((resolve) => setTimeout(resolve, 25));\n if (this.state.consistency === 'fresh') {\n return;\n }\n\n await this.refresh();\n }\n}\n\nclass MutationCell<TInput, TResult> implements Mutation<TInput, TResult> {\n private readonly source = createReadableSource();\n private readonly action: MutationOptions<TInput, TResult>['action'];\n private readonly affects?: MutationOptions<TInput, TResult>['affects'];\n private readonly afterSuccess?: MutationOptions<\n TInput,\n TResult\n >['afterSuccess'];\n private controller: AbortController | null = null;\n private generation = 0;\n\n private state: MutationState<TResult> = {\n status: 'idle',\n error: null,\n result: null,\n };\n\n constructor(options: MutationOptions<TInput, TResult>) {\n this.action = options.action;\n this.affects = options.affects;\n this.afterSuccess = options.afterSuccess;\n }\n\n get status(): 'idle' | 'pending' | 'success' | 'error' {\n recordReadableRead(this.source);\n return this.state.status;\n }\n\n get pending(): boolean {\n recordReadableRead(this.source);\n return this.state.status === 'pending';\n }\n\n get error(): unknown | null {\n recordReadableRead(this.source);\n return this.state.error;\n }\n\n get result(): TResult | null {\n recordReadableRead(this.source);\n return this.state.result;\n }\n\n private setState(next: Partial<MutationState<TResult>>): void {\n this.state = {\n ...this.state,\n ...next,\n };\n notifySource(this.source);\n }\n\n async execute(input: TInput): Promise<TResult> {\n this.generation += 1;\n const generation = this.generation;\n\n this.controller?.abort();\n const controller = new AbortController();\n this.controller = controller;\n\n this.setState({ status: 'pending', error: null, result: null });\n\n let result: TResult;\n try {\n result = await this.action(input, { signal: controller.signal });\n } catch (error) {\n if (this.generation !== generation || this.controller !== controller) {\n throw error;\n }\n\n if (isAbortError(error, controller.signal)) {\n this.setState({ status: 'idle', error: null });\n throw error;\n }\n\n this.setState({ status: 'error', error });\n throw error;\n }\n\n if (this.generation !== generation || this.controller !== controller) {\n return result;\n }\n\n this.setState({ status: 'success', error: null, result });\n\n if (this.afterSuccess === 'invalidate') {\n const prefixes = this.affects?.(input, result) ?? [];\n for (const prefix of new Set(prefixes)) {\n invalidateQueries(prefix, true);\n }\n }\n\n return result;\n }\n\n abort(): void {\n this.generation += 1;\n this.controller?.abort();\n this.controller = null;\n this.setState({ status: 'idle', error: null });\n }\n\n reset(): void {\n this.generation += 1;\n this.controller?.abort();\n this.controller = null;\n this.setState({ status: 'idle', error: null, result: null });\n }\n}\n\nexport function createQuery<T>(options: QueryOptions<T>): Query<T> {\n const existing = queryCache.get(options.key) as QueryCell<T> | undefined;\n if (existing) {\n existing.setOptions(options);\n return existing;\n }\n\n const created = new QueryCell(options);\n queryCache.set(options.key, created as QueryCell<unknown>);\n created.ensureStarted();\n return created;\n}\n\nexport function invalidate(prefix: string): void {\n invalidateQueries(prefix, false);\n}\n\nexport function createMutation<TInput, TResult>(\n options: MutationOptions<TInput, TResult>\n): Mutation<TInput, TResult> {\n return new MutationCell(options);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/data/index.ts"],"sourcesContent":["import { globalScheduler } from '../runtime/scheduler';\nimport {\n claimHookIndex,\n getCurrentComponentInstance,\n type ComponentInstance,\n} from '../runtime/component';\nimport {\n markReadableDerivedSubscribersDirty,\n markReactivePropsDirtySource,\n notifyReadableReaders,\n recordReadableRead,\n type ReadableSource,\n} from '../runtime/readable';\nimport { getRenderContext } from '../ssr/context';\n\nexport type QueryConsistency =\n | 'fresh'\n | 'stale'\n | 'refreshing'\n | 'pending-write';\n\nexport type Query<T> = {\n data: T | null;\n error: unknown | null;\n loading: boolean;\n refreshing: boolean;\n stale: boolean;\n consistency: QueryConsistency;\n\n refresh(): Promise<void>;\n};\n\nexport type Mutation<TInput, TResult> = {\n status: 'idle' | 'pending' | 'success' | 'error';\n pending: boolean;\n error: unknown | null;\n result: TResult | null;\n\n execute(input: TInput): Promise<TResult>;\n abort(): void;\n reset(): void;\n};\n\ntype QueryOptions<T> = {\n key: string;\n fetch: (ctx: { signal: AbortSignal }) => Promise<T>;\n isConsistent?: (data: T) => boolean;\n reconcile?: (data: T, ctx: { key: string }) => Promise<boolean> | boolean;\n};\n\ntype MutationOptions<TInput, TResult> = {\n action: (input: TInput, ctx: { signal: AbortSignal }) => Promise<TResult>;\n affects?: (input: TInput, result: TResult) => string[];\n afterSuccess?: 'invalidate';\n};\n\ntype QueryState<T> = {\n data: T | null;\n error: unknown | null;\n loading: boolean;\n refreshing: boolean;\n stale: boolean;\n consistency: QueryConsistency;\n};\n\ntype MutationState<TResult> = {\n status: 'idle' | 'pending' | 'success' | 'error';\n error: unknown | null;\n result: TResult | null;\n};\n\ntype QuerySlot = {\n key: string;\n cell: QueryCell<unknown>;\n};\n\nconst RECONCILE_MAX_ATTEMPTS = 3;\nconst RECONCILE_RETRY_DELAY_MS = 25;\nconst globalQueryCache = new Map<string, QueryCell<unknown>>();\nconst querySlotsByInstance = new WeakMap<\n ComponentInstance,\n Map<number, QuerySlot>\n>();\nconst mutationSlotsByInstance = new WeakMap<\n ComponentInstance,\n Map<number, MutationCell<unknown, unknown>>\n>();\nconst queryCleanupRegistered = new WeakSet<ComponentInstance>();\nconst mutationCleanupRegistered = new WeakSet<ComponentInstance>();\n\nfunction createReadableSource(): ReadableSource<unknown> {\n return (() => undefined) as ReadableSource<unknown>;\n}\n\nfunction getQueryCache(): Map<string, QueryCell<unknown>> {\n return (\n (getRenderContext()?.queryCache as Map<\n string,\n QueryCell<unknown>\n > | null) ?? globalQueryCache\n );\n}\n\nfunction getQuerySlotStore(\n instance: ComponentInstance\n): Map<number, QuerySlot> {\n let store = querySlotsByInstance.get(instance);\n if (!store) {\n store = new Map();\n querySlotsByInstance.set(instance, store);\n }\n return store;\n}\n\nfunction getMutationSlotStore(\n instance: ComponentInstance\n): Map<number, MutationCell<unknown, unknown>> {\n let store = mutationSlotsByInstance.get(instance);\n if (!store) {\n store = new Map();\n mutationSlotsByInstance.set(instance, store);\n }\n return store;\n}\n\nfunction ensureQueryCleanup(instance: ComponentInstance): void {\n if (queryCleanupRegistered.has(instance)) {\n return;\n }\n\n queryCleanupRegistered.add(instance);\n instance.cleanupFns.push(() => {\n const slots = querySlotsByInstance.get(instance);\n if (!slots) {\n queryCleanupRegistered.delete(instance);\n return;\n }\n\n for (const [hookIndex, slot] of slots) {\n slot.cell.detach(instance, hookIndex);\n }\n\n slots.clear();\n querySlotsByInstance.delete(instance);\n queryCleanupRegistered.delete(instance);\n });\n}\n\nfunction ensureMutationCleanup(instance: ComponentInstance): void {\n if (mutationCleanupRegistered.has(instance)) {\n return;\n }\n\n mutationCleanupRegistered.add(instance);\n instance.cleanupFns.push(() => {\n const slots = mutationSlotsByInstance.get(instance);\n if (!slots) {\n mutationCleanupRegistered.delete(instance);\n return;\n }\n\n for (const cell of slots.values()) {\n cell.abort();\n }\n\n slots.clear();\n mutationSlotsByInstance.delete(instance);\n mutationCleanupRegistered.delete(instance);\n });\n}\n\nfunction notifySource(source: ReadableSource<unknown>): void {\n markReadableDerivedSubscribersDirty(source);\n markReactivePropsDirtySource(source);\n notifyReadableReaders(source);\n}\n\nfunction isAbortError(error: unknown, signal: AbortSignal): boolean {\n return (\n signal.aborted ||\n (error instanceof Error && error.name === 'AbortError') ||\n (typeof DOMException !== 'undefined' &&\n error instanceof DOMException &&\n error.name === 'AbortError')\n );\n}\n\nfunction invalidateQueries(prefix: string, markPendingWrite: boolean): void {\n const cache = getQueryCache();\n\n for (const [key, query] of cache) {\n if (!key.startsWith(prefix)) {\n continue;\n }\n\n if (markPendingWrite) {\n query.markPendingWrite();\n }\n\n void query.refresh();\n }\n}\n\nclass QueryCell<T> implements Query<T> {\n private readonly source = createReadableSource();\n private readonly key: string;\n private readonly cache: Map<string, QueryCell<unknown>>;\n private options: QueryOptions<T>;\n private controller: AbortController | null = null;\n private generation = 0;\n private startQueued = false;\n private pendingRefresh: Promise<void> | null = null;\n private pendingRefreshResolve: (() => void) | null = null;\n private reconcileAttemptCount = 0;\n private destroyed = false;\n private ownerCount = 0;\n private readonly owners = new Map<ComponentInstance, Set<number>>();\n\n private state: QueryState<T> = {\n data: null,\n error: null,\n loading: true,\n refreshing: false,\n stale: false,\n consistency: 'fresh',\n };\n\n constructor(\n options: QueryOptions<T>,\n key: string,\n cache: Map<string, QueryCell<unknown>>\n ) {\n this.options = options;\n this.key = key;\n this.cache = cache;\n }\n\n attach(instance: ComponentInstance, hookIndex: number): void {\n let hooks = this.owners.get(instance);\n if (!hooks) {\n hooks = new Set();\n this.owners.set(instance, hooks);\n }\n\n if (hooks.has(hookIndex)) {\n return;\n }\n\n hooks.add(hookIndex);\n this.ownerCount += 1;\n }\n\n detach(instance: ComponentInstance, hookIndex: number): void {\n const hooks = this.owners.get(instance);\n if (!hooks || !hooks.delete(hookIndex)) {\n return;\n }\n\n this.ownerCount -= 1;\n if (hooks.size === 0) {\n this.owners.delete(instance);\n }\n\n if (this.ownerCount <= 0) {\n this.destroy();\n }\n }\n\n private destroy(): void {\n if (this.destroyed) {\n return;\n }\n\n this.destroyed = true;\n this.controller?.abort();\n this.controller = null;\n this.startQueued = false;\n this.reconcileAttemptCount = 0;\n this.ownerCount = 0;\n this.owners.clear();\n this.cache.delete(this.key);\n this.finishPendingRefresh();\n }\n\n get data(): T | null {\n recordReadableRead(this.source);\n return this.state.data;\n }\n\n get error(): unknown | null {\n recordReadableRead(this.source);\n return this.state.error;\n }\n\n get loading(): boolean {\n recordReadableRead(this.source);\n return this.state.loading;\n }\n\n get refreshing(): boolean {\n recordReadableRead(this.source);\n return this.state.refreshing;\n }\n\n get stale(): boolean {\n recordReadableRead(this.source);\n return this.state.stale;\n }\n\n get consistency(): QueryConsistency {\n recordReadableRead(this.source);\n return this.state.consistency;\n }\n\n ensureStarted(): void {\n if (\n this.destroyed ||\n this.state.data !== null ||\n this.pendingRefresh ||\n this.startQueued\n ) {\n return;\n }\n\n this.queueStart('initial');\n }\n\n refresh(): Promise<void> {\n if (this.destroyed) {\n return Promise.resolve();\n }\n\n if (this.pendingRefresh) {\n return this.pendingRefresh;\n }\n\n this.queueStart('manual');\n return this.pendingRefresh ?? Promise.resolve();\n }\n\n markPendingWrite(): void {\n if (this.destroyed) {\n return;\n }\n\n this.setState({\n refreshing: true,\n stale: true,\n consistency: 'pending-write',\n });\n }\n\n private queueStart(\n reason: 'initial' | 'manual' | 'invalidate' | 'pending-write'\n ): void {\n if (this.destroyed) {\n return;\n }\n\n this.startQueued = true;\n this.pendingRefresh = new Promise<void>((resolve) => {\n this.pendingRefreshResolve = resolve;\n globalScheduler.enqueue(() => {\n this.startQueued = false;\n if (this.destroyed) {\n this.finishPendingRefresh();\n return;\n }\n void this.start(reason).finally(() => {\n this.finishPendingRefresh();\n });\n });\n });\n }\n\n private finishPendingRefresh(): void {\n const resolve = this.pendingRefreshResolve;\n this.pendingRefresh = null;\n this.pendingRefreshResolve = null;\n resolve?.();\n }\n\n private setState(next: Partial<QueryState<T>>): void {\n if (this.destroyed) {\n return;\n }\n\n this.state = {\n ...this.state,\n ...next,\n };\n notifySource(this.source);\n }\n\n private async start(\n reason: 'initial' | 'manual' | 'invalidate' | 'pending-write'\n ): Promise<void> {\n if (this.destroyed) {\n return;\n }\n\n this.generation += 1;\n const generation = this.generation;\n\n this.controller?.abort();\n const controller = new AbortController();\n this.controller = controller;\n\n const hasData = this.state.data !== null;\n this.setState({\n loading: !hasData,\n refreshing: hasData,\n stale: hasData,\n consistency:\n reason === 'pending-write'\n ? 'pending-write'\n : hasData\n ? 'refreshing'\n : 'fresh',\n error: null,\n });\n\n let nextData: T;\n try {\n nextData = await this.options.fetch({ signal: controller.signal });\n } catch (error) {\n if (\n this.destroyed ||\n this.generation !== generation ||\n this.controller !== controller\n ) {\n return;\n }\n\n if (isAbortError(error, controller.signal)) {\n this.setState({ loading: false, refreshing: false });\n return;\n }\n\n this.setState({\n loading: false,\n refreshing: false,\n stale: true,\n consistency: 'stale',\n error,\n });\n return;\n }\n\n if (\n this.destroyed ||\n this.generation !== generation ||\n this.controller !== controller\n ) {\n return;\n }\n\n const isConsistent = this.options.isConsistent?.(nextData) ?? true;\n if (!isConsistent) {\n this.setState({\n data: nextData,\n loading: false,\n refreshing: false,\n stale: true,\n consistency: 'stale',\n });\n await this.reconcile(nextData);\n return;\n }\n\n this.reconcileAttemptCount = 0;\n this.setState({\n data: nextData,\n loading: false,\n refreshing: false,\n stale: false,\n consistency: 'fresh',\n error: null,\n });\n }\n\n private async reconcile(data: T): Promise<void> {\n const shouldRetry =\n this.options.reconcile?.(data, { key: this.options.key }) ?? false;\n\n if (!shouldRetry || this.destroyed) {\n return;\n }\n\n this.reconcileAttemptCount += 1;\n if (this.reconcileAttemptCount > RECONCILE_MAX_ATTEMPTS) {\n this.setState({ consistency: 'stale', refreshing: false });\n return;\n }\n\n await new Promise<void>((resolve) =>\n setTimeout(resolve, RECONCILE_RETRY_DELAY_MS)\n );\n if (this.destroyed || this.state.consistency === 'fresh') {\n return;\n }\n\n await this.refresh();\n }\n}\n\nclass MutationCell<TInput, TResult> implements Mutation<TInput, TResult> {\n private readonly source = createReadableSource();\n private action: MutationOptions<TInput, TResult>['action'];\n private affects?: MutationOptions<TInput, TResult>['affects'];\n private afterSuccess?: MutationOptions<TInput, TResult>['afterSuccess'];\n private controller: AbortController | null = null;\n private generation = 0;\n\n private state: MutationState<TResult> = {\n status: 'idle',\n error: null,\n result: null,\n };\n\n constructor(options: MutationOptions<TInput, TResult>) {\n this.action = options.action;\n this.affects = options.affects;\n this.afterSuccess = options.afterSuccess;\n }\n\n setOptions(options: MutationOptions<TInput, TResult>): void {\n this.action = options.action;\n this.affects = options.affects;\n this.afterSuccess = options.afterSuccess;\n }\n\n get status(): 'idle' | 'pending' | 'success' | 'error' {\n recordReadableRead(this.source);\n return this.state.status;\n }\n\n get pending(): boolean {\n recordReadableRead(this.source);\n return this.state.status === 'pending';\n }\n\n get error(): unknown | null {\n recordReadableRead(this.source);\n return this.state.error;\n }\n\n get result(): TResult | null {\n recordReadableRead(this.source);\n return this.state.result;\n }\n\n private setState(next: Partial<MutationState<TResult>>): void {\n this.state = {\n ...this.state,\n ...next,\n };\n notifySource(this.source);\n }\n\n async execute(input: TInput): Promise<TResult> {\n this.generation += 1;\n const generation = this.generation;\n\n this.controller?.abort();\n const controller = new AbortController();\n this.controller = controller;\n\n this.setState({ status: 'pending', error: null, result: null });\n\n let result: TResult;\n try {\n result = await this.action(input, { signal: controller.signal });\n } catch (error) {\n if (this.generation !== generation || this.controller !== controller) {\n throw error;\n }\n\n if (isAbortError(error, controller.signal)) {\n this.setState({ status: 'idle', error: null });\n throw error;\n }\n\n this.setState({ status: 'error', error });\n throw error;\n }\n\n if (this.generation !== generation || this.controller !== controller) {\n return result;\n }\n\n this.setState({ status: 'success', error: null, result });\n\n if (this.afterSuccess === 'invalidate') {\n const prefixes = this.affects?.(input, result) ?? [];\n for (const prefix of new Set(prefixes)) {\n invalidateQueries(prefix, true);\n }\n }\n\n return result;\n }\n\n abort(): void {\n this.generation += 1;\n this.controller?.abort();\n this.controller = null;\n this.setState({ status: 'idle', error: null });\n }\n\n reset(): void {\n this.generation += 1;\n this.controller?.abort();\n this.controller = null;\n this.setState({ status: 'idle', error: null, result: null });\n }\n}\n\nexport function createQuery<T>(options: QueryOptions<T>): Query<T> {\n const instance = getCurrentComponentInstance();\n const cache = getQueryCache();\n if (!instance) {\n let cell = cache.get(options.key) as QueryCell<T> | undefined;\n if (!cell) {\n cell = new QueryCell(options, options.key, cache);\n cache.set(options.key, cell as QueryCell<unknown>);\n cell.ensureStarted();\n }\n return cell;\n }\n\n const hookIndex = claimHookIndex(instance, 'query');\n ensureQueryCleanup(instance);\n\n const slotStore = getQuerySlotStore(instance);\n const existingSlot = slotStore.get(hookIndex);\n if (existingSlot && existingSlot.key === options.key) {\n return existingSlot.cell as QueryCell<T>;\n }\n\n if (existingSlot) {\n existingSlot.cell.detach(instance, hookIndex);\n }\n\n let cell = cache.get(options.key) as QueryCell<T> | undefined;\n if (!cell) {\n cell = new QueryCell(options, options.key, cache);\n cache.set(options.key, cell as QueryCell<unknown>);\n cell.ensureStarted();\n }\n\n slotStore.set(hookIndex, {\n key: options.key,\n cell: cell as QueryCell<unknown>,\n });\n cell.attach(instance, hookIndex);\n return cell;\n}\n\nexport function invalidate(prefix: string): void {\n invalidateQueries(prefix, false);\n}\n\nexport function createMutation<TInput, TResult>(\n options: MutationOptions<TInput, TResult>\n): Mutation<TInput, TResult> {\n const instance = getCurrentComponentInstance();\n\n if (!instance) {\n return new MutationCell(options);\n }\n\n const hookIndex = claimHookIndex(instance, 'mutation');\n ensureMutationCleanup(instance);\n\n const slotStore = getMutationSlotStore(instance);\n const existing = slotStore.get(hookIndex) as\n | MutationCell<TInput, TResult>\n | undefined;\n if (existing) {\n existing.setOptions(options);\n return existing;\n }\n\n const created = new MutationCell(options);\n slotStore.set(hookIndex, created as MutationCell<unknown, unknown>);\n return created;\n}\n"],"mappings":"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"}