@askrjs/askr 0.0.27 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -147
- package/dist/_virtual/_rolldown/runtime.js +7 -0
- package/dist/bench/components/benchmark-row.d.ts +20 -0
- package/dist/bench/components/benchmark-row.d.ts.map +1 -0
- package/dist/bench/components/benchmark-row.js +42 -0
- package/dist/bench/components/benchmark-row.js.map +1 -0
- package/dist/bench/components/benchmark-table.js +25 -0
- package/dist/bench/components/benchmark-table.js.map +1 -0
- package/dist/benchmark.d.ts +22 -0
- package/dist/benchmark.d.ts.map +1 -0
- package/dist/benchmark.js +64 -1
- package/dist/benchmark.js.map +1 -0
- package/dist/bin/askr-ssg.d.ts +28 -0
- package/dist/bin/askr-ssg.d.ts.map +1 -0
- package/dist/bin/askr-ssg.js +171 -0
- package/dist/bin/askr-ssg.js.map +1 -0
- package/dist/boot/index.d.ts +64 -42
- package/dist/boot/index.d.ts.map +1 -1
- package/dist/boot/index.js +416 -2
- package/dist/boot/index.js.map +1 -0
- package/dist/common/component.d.ts +14 -13
- package/dist/common/component.d.ts.map +1 -1
- package/dist/common/control.d.ts +13 -0
- package/dist/common/control.d.ts.map +1 -0
- package/dist/common/control.js +14 -0
- package/dist/common/control.js.map +1 -0
- package/dist/common/env.js +47 -0
- package/dist/common/env.js.map +1 -0
- package/dist/common/jsx.d.ts +17 -15
- package/dist/common/jsx.d.ts.map +1 -1
- package/dist/common/jsx.js +8 -1
- package/dist/common/jsx.js.map +1 -0
- package/dist/common/props.d.ts +14 -11
- package/dist/common/props.d.ts.map +1 -1
- package/dist/common/router.d.ts +190 -32
- package/dist/common/router.d.ts.map +1 -1
- package/dist/common/ssr-errors.d.ts +6 -3
- package/dist/common/ssr-errors.d.ts.map +1 -1
- package/dist/common/ssr-errors.js +16 -1
- package/dist/common/ssr-errors.js.map +1 -0
- package/dist/common/ssr.d.ts +12 -9
- package/dist/common/ssr.d.ts.map +1 -1
- package/dist/common/vnode.d.ts +17 -15
- package/dist/common/vnode.d.ts.map +1 -1
- package/dist/common/vnode.js +10 -1
- package/dist/common/vnode.js.map +1 -0
- package/dist/components/link.d.ts +37 -25
- package/dist/components/link.d.ts.map +1 -1
- package/dist/components/link.js +64 -1
- package/dist/components/link.js.map +1 -0
- package/dist/control/case.d.ts +17 -0
- package/dist/control/case.d.ts.map +1 -0
- package/dist/control/case.js +69 -0
- package/dist/control/case.js.map +1 -0
- package/dist/control/for.d.ts +23 -0
- package/dist/control/for.d.ts.map +1 -0
- package/dist/control/for.js +62 -0
- package/dist/control/for.js.map +1 -0
- package/dist/control/index.d.ts +4 -0
- package/dist/control/index.js +4 -0
- package/dist/control/shared.js +20 -0
- package/dist/control/shared.js.map +1 -0
- package/dist/control/show.d.ts +14 -0
- package/dist/control/show.d.ts.map +1 -0
- package/dist/control/show.js +33 -0
- package/dist/control/show.js.map +1 -0
- package/dist/dev/invariant.js +29 -2
- package/dist/dev/invariant.js.map +1 -0
- package/dist/dev/logger.js +37 -1
- package/dist/dev/logger.js.map +1 -0
- package/dist/foundations/icon/icon.d.ts +53 -0
- package/dist/foundations/icon/icon.d.ts.map +1 -0
- package/dist/foundations/icon/icon.js +88 -0
- package/dist/foundations/icon/icon.js.map +1 -0
- package/dist/foundations/icon/icon.types.d.ts +21 -0
- package/dist/foundations/icon/icon.types.d.ts.map +1 -0
- package/dist/foundations/index.d.ts +10 -3
- package/dist/foundations/index.js +9 -1
- package/dist/foundations/interactions/interaction-policy.js +93 -1
- package/dist/foundations/interactions/interaction-policy.js.map +1 -0
- package/dist/foundations/interactions/pressable.js +51 -1
- package/dist/foundations/interactions/pressable.js.map +1 -0
- package/dist/foundations/structures/collection.d.ts +25 -40
- package/dist/foundations/structures/collection.d.ts.map +1 -1
- package/dist/foundations/structures/collection.js +51 -1
- package/dist/foundations/structures/collection.js.map +1 -0
- package/dist/foundations/structures/layer.d.ts +47 -68
- package/dist/foundations/structures/layer.d.ts.map +1 -1
- package/dist/foundations/structures/layer.js +81 -1
- package/dist/foundations/structures/layer.js.map +1 -0
- package/dist/foundations/structures/layout.d.ts +6 -3
- package/dist/foundations/structures/layout.d.ts.map +1 -1
- package/dist/foundations/structures/layout.js +13 -1
- package/dist/foundations/structures/layout.js.map +1 -0
- package/dist/foundations/structures/portal.d.ts +17 -10
- package/dist/foundations/structures/portal.d.ts.map +1 -1
- package/dist/foundations/structures/portal.js +105 -1
- package/dist/foundations/structures/portal.js.map +1 -0
- package/dist/foundations/structures/presence.d.ts +11 -5
- package/dist/foundations/structures/presence.d.ts.map +1 -1
- package/dist/foundations/structures/presence.js +39 -1
- package/dist/foundations/structures/presence.js.map +1 -0
- package/dist/foundations/structures/slot.d.ts +11 -8
- package/dist/foundations/structures/slot.d.ts.map +1 -1
- package/dist/foundations/structures/slot.js +41 -1
- package/dist/foundations/structures/slot.js.map +1 -0
- package/dist/foundations/structures.d.ts +7 -14
- package/dist/foundations/structures.js +6 -1
- package/dist/foundations/utilities/aria.js +11 -1
- package/dist/foundations/utilities/aria.js.map +1 -0
- package/dist/foundations/utilities/compose-handlers.js +20 -1
- package/dist/foundations/utilities/compose-handlers.js.map +1 -0
- package/dist/foundations/utilities/compose-ref.d.ts +7 -4
- package/dist/foundations/utilities/compose-ref.d.ts.map +1 -1
- package/dist/foundations/utilities/compose-ref.js +18 -1
- package/dist/foundations/utilities/compose-ref.js.map +1 -0
- package/dist/foundations/utilities/merge-props.js +49 -1
- package/dist/foundations/utilities/merge-props.js.map +1 -0
- package/dist/fx/fx.d.ts +24 -21
- package/dist/fx/fx.d.ts.map +1 -1
- package/dist/fx/fx.js +212 -1
- package/dist/fx/fx.js.map +1 -0
- package/dist/fx/index.d.ts +4 -7
- package/dist/fx/index.js +4 -1
- package/dist/fx/noop.js +9 -1
- package/dist/fx/noop.js.map +1 -0
- package/dist/fx/timing.d.ts +24 -21
- package/dist/fx/timing.d.ts.map +1 -1
- package/dist/fx/timing.js +236 -1
- package/dist/fx/timing.js.map +1 -0
- package/dist/index.d.ts +21 -20
- package/dist/index.js +34 -1
- package/dist/index.js.map +1 -0
- package/dist/jsx/index.d.ts +1 -4
- package/dist/jsx/index.js +3 -1
- package/dist/jsx/types.d.ts +18 -25
- package/dist/jsx/types.d.ts.map +1 -1
- package/dist/jsx/types.js +1 -1
- package/dist/jsx/utils.d.ts +4 -3
- package/dist/jsx/utils.d.ts.map +1 -1
- package/dist/jsx/utils.js +19 -1
- package/dist/jsx/utils.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +8 -0
- package/dist/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/jsx-dev-runtime.js +32 -1
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.d.ts +12 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +45 -1
- package/dist/jsx-runtime.js.map +1 -0
- package/dist/jsx-runtime2.d.ts +2 -0
- package/dist/jsx-runtime2.js +3 -0
- package/dist/renderer/children.js +293 -0
- package/dist/renderer/children.js.map +1 -0
- package/dist/renderer/cleanup.js +150 -1
- package/dist/renderer/cleanup.js.map +1 -0
- package/dist/renderer/dom.js +2439 -1
- package/dist/renderer/dom.js.map +1 -0
- package/dist/renderer/env.js +1 -0
- package/dist/renderer/evaluate.js +450 -1
- package/dist/renderer/evaluate.js.map +1 -0
- package/dist/renderer/fastpath.js +145 -1
- package/dist/renderer/fastpath.js.map +1 -0
- package/dist/renderer/index.js +24 -1
- package/dist/renderer/index.js.map +1 -0
- package/dist/renderer/keyed.js +119 -1
- package/dist/renderer/keyed.js.map +1 -0
- package/dist/renderer/reconcile.js +359 -1
- package/dist/renderer/reconcile.js.map +1 -0
- package/dist/renderer/types.js +1 -1
- package/dist/renderer/utils.js +220 -1
- package/dist/renderer/utils.js.map +1 -0
- package/dist/resources/index.d.ts +3 -9
- package/dist/resources/index.js +3 -1
- package/dist/router/index.d.ts +6 -10
- package/dist/router/index.js +5 -1
- package/dist/router/match.js +83 -1
- package/dist/router/match.js.map +1 -0
- package/dist/router/navigate.d.ts +20 -8
- package/dist/router/navigate.d.ts.map +1 -1
- package/dist/router/navigate.js +288 -1
- package/dist/router/navigate.js.map +1 -0
- package/dist/router/policy.d.ts +22 -0
- package/dist/router/policy.d.ts.map +1 -0
- package/dist/router/policy.js +116 -0
- package/dist/router/policy.js.map +1 -0
- package/dist/router/route-context.js +79 -0
- package/dist/router/route-context.js.map +1 -0
- package/dist/router/route.d.ts +101 -33
- package/dist/router/route.d.ts.map +1 -1
- package/dist/router/route.js +599 -1
- package/dist/router/route.js.map +1 -0
- package/dist/runtime/child-scope.d.ts +21 -0
- package/dist/runtime/child-scope.d.ts.map +1 -0
- package/dist/runtime/child-scope.js +77 -0
- package/dist/runtime/child-scope.js.map +1 -0
- package/dist/runtime/component.d.ts +67 -53
- package/dist/runtime/component.d.ts.map +1 -1
- package/dist/runtime/component.js +462 -1
- package/dist/runtime/component.js.map +1 -0
- package/dist/runtime/context.d.ts +28 -42
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/context.js +205 -1
- package/dist/runtime/context.js.map +1 -0
- package/dist/runtime/control.d.ts +43 -0
- package/dist/runtime/control.d.ts.map +1 -0
- package/dist/runtime/control.js +125 -0
- package/dist/runtime/control.js.map +1 -0
- package/dist/runtime/derive.d.ts +15 -6
- package/dist/runtime/derive.d.ts.map +1 -1
- package/dist/runtime/derive.js +134 -1
- package/dist/runtime/derive.js.map +1 -0
- package/dist/runtime/dev-namespace.js +57 -1
- package/dist/runtime/dev-namespace.js.map +1 -0
- package/dist/runtime/effect.d.ts +32 -0
- package/dist/runtime/effect.d.ts.map +1 -0
- package/dist/runtime/effect.js +146 -0
- package/dist/runtime/effect.js.map +1 -0
- package/dist/runtime/events.js +162 -1
- package/dist/runtime/events.js.map +1 -0
- package/dist/runtime/execution-model.js +15 -1
- package/dist/runtime/execution-model.js.map +1 -0
- package/dist/runtime/fastlane.js +204 -1
- package/dist/runtime/fastlane.js.map +1 -0
- package/dist/runtime/for-bench.d.ts +41 -0
- package/dist/runtime/for-bench.d.ts.map +1 -0
- package/dist/runtime/for-bench.js +173 -0
- package/dist/runtime/for-bench.js.map +1 -0
- package/dist/runtime/for.d.ts +62 -49
- package/dist/runtime/for.d.ts.map +1 -1
- package/dist/runtime/for.js +668 -1
- package/dist/runtime/for.js.map +1 -0
- package/dist/runtime/operations.d.ts +18 -15
- package/dist/runtime/operations.d.ts.map +1 -1
- package/dist/runtime/operations.js +209 -1
- package/dist/runtime/operations.js.map +1 -0
- package/dist/runtime/perf-metrics.js +64 -0
- package/dist/runtime/perf-metrics.js.map +1 -0
- package/dist/runtime/readable.d.ts +27 -0
- package/dist/runtime/readable.d.ts.map +1 -0
- package/dist/runtime/readable.js +118 -0
- package/dist/runtime/readable.js.map +1 -0
- package/dist/runtime/resource-cell.js +102 -1
- package/dist/runtime/resource-cell.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +51 -35
- package/dist/runtime/scheduler.d.ts.map +1 -1
- package/dist/runtime/scheduler.js +328 -1
- package/dist/runtime/scheduler.js.map +1 -0
- package/dist/runtime/selector.d.ts +11 -0
- package/dist/runtime/selector.d.ts.map +1 -0
- package/dist/runtime/selector.js +188 -0
- package/dist/runtime/selector.js.map +1 -0
- package/dist/runtime/ssr-bridge.js +24 -1
- package/dist/runtime/ssr-bridge.js.map +1 -0
- package/dist/runtime/state.d.ts +11 -21
- package/dist/runtime/state.d.ts.map +1 -1
- package/dist/runtime/state.js +99 -1
- package/dist/runtime/state.js.map +1 -0
- package/dist/ssg/batch-render.d.ts +16 -0
- package/dist/ssg/batch-render.d.ts.map +1 -0
- package/dist/ssg/batch-render.js +84 -0
- package/dist/ssg/batch-render.js.map +1 -0
- package/dist/ssg/create-static-gen.d.ts +50 -0
- package/dist/ssg/create-static-gen.d.ts.map +1 -0
- package/dist/ssg/create-static-gen.js +282 -0
- package/dist/ssg/create-static-gen.js.map +1 -0
- package/dist/ssg/generate-metadata.d.ts +24 -0
- package/dist/ssg/generate-metadata.d.ts.map +1 -0
- package/dist/ssg/generate-metadata.js +94 -0
- package/dist/ssg/generate-metadata.js.map +1 -0
- package/dist/ssg/incremental-manifest.js +56 -0
- package/dist/ssg/incremental-manifest.js.map +1 -0
- package/dist/ssg/index.d.ts +8 -0
- package/dist/ssg/index.js +7 -0
- package/dist/ssg/resolve-ssg-data.d.ts +23 -0
- package/dist/ssg/resolve-ssg-data.d.ts.map +1 -0
- package/dist/ssg/resolve-ssg-data.js +46 -0
- package/dist/ssg/resolve-ssg-data.js.map +1 -0
- package/dist/ssg/route-utils.d.ts +16 -0
- package/dist/ssg/route-utils.d.ts.map +1 -0
- package/dist/ssg/route-utils.js +24 -0
- package/dist/ssg/route-utils.js.map +1 -0
- package/dist/ssg/types.d.ts +177 -0
- package/dist/ssg/types.d.ts.map +1 -0
- package/dist/ssg/write-static-files.d.ts +15 -0
- package/dist/ssg/write-static-files.d.ts.map +1 -0
- package/dist/ssg/write-static-files.js +73 -0
- package/dist/ssg/write-static-files.js.map +1 -0
- package/dist/ssr/attrs.js +93 -1
- package/dist/ssr/attrs.js.map +1 -0
- package/dist/ssr/context.d.ts +31 -32
- package/dist/ssr/context.d.ts.map +1 -1
- package/dist/ssr/context.js +63 -1
- package/dist/ssr/context.js.map +1 -0
- package/dist/ssr/errors.d.ts +6 -4
- package/dist/ssr/errors.d.ts.map +1 -1
- package/dist/ssr/errors.js +4 -1
- package/dist/ssr/errors.js.map +1 -0
- package/dist/ssr/escape.js +153 -1
- package/dist/ssr/escape.js.map +1 -0
- package/dist/ssr/index.d.ts +75 -46
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/index.js +543 -1
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/render-keys.d.ts +27 -29
- package/dist/ssr/render-keys.d.ts.map +1 -1
- package/dist/ssr/render-keys.js +39 -1
- package/dist/ssr/render-keys.js.map +1 -0
- package/dist/ssr/sink.js +86 -1
- package/dist/ssr/sink.js.map +1 -0
- package/dist/ssr/stream-render.js +76 -1
- package/dist/ssr/stream-render.js.map +1 -0
- package/dist/ssr/types.d.ts +14 -13
- package/dist/ssr/types.d.ts.map +1 -1
- package/package.json +53 -48
- package/dist/_virtual/___vite-browser-external.js +0 -1
- package/dist/_virtual/__vite-browser-external.js +0 -1
- package/dist/_virtual/_commonjsHelpers.js +0 -1
- package/dist/_virtual/main.js +0 -1
- package/dist/_virtual/preload-helper.js +0 -1
- package/dist/bench/benchmark-entry.d.ts +0 -14
- package/dist/bench/benchmark-entry.d.ts.map +0 -1
- package/dist/common/errors.d.ts +0 -53
- package/dist/common/errors.d.ts.map +0 -1
- package/dist/common/index.d.ts +0 -14
- package/dist/common/index.d.ts.map +0 -1
- package/dist/dev/invariant.d.ts +0 -83
- package/dist/dev/invariant.d.ts.map +0 -1
- package/dist/dev/logger.d.ts +0 -13
- package/dist/dev/logger.d.ts.map +0 -1
- package/dist/dev/vite-plugin-askr.d.ts +0 -18
- package/dist/dev/vite-plugin-askr.d.ts.map +0 -1
- package/dist/dev/warnings.d.ts +0 -5
- package/dist/dev/warnings.d.ts.map +0 -1
- package/dist/for/for.d.ts +0 -16
- package/dist/for/for.d.ts.map +0 -1
- package/dist/for/for.js +0 -1
- package/dist/for/index.d.ts +0 -2
- package/dist/for/index.d.ts.map +0 -1
- package/dist/for/index.js +0 -1
- package/dist/foundations/core.d.ts +0 -23
- package/dist/foundations/core.d.ts.map +0 -1
- package/dist/foundations/core.js +0 -1
- package/dist/foundations/index.d.ts.map +0 -1
- package/dist/foundations/interactions/dismissable.d.ts +0 -58
- package/dist/foundations/interactions/dismissable.d.ts.map +0 -1
- package/dist/foundations/interactions/dismissable.js +0 -1
- package/dist/foundations/interactions/focusable.d.ts +0 -16
- package/dist/foundations/interactions/focusable.d.ts.map +0 -1
- package/dist/foundations/interactions/focusable.js +0 -1
- package/dist/foundations/interactions/hoverable.d.ts +0 -19
- package/dist/foundations/interactions/hoverable.d.ts.map +0 -1
- package/dist/foundations/interactions/hoverable.js +0 -1
- package/dist/foundations/interactions/index.d.ts +0 -5
- package/dist/foundations/interactions/index.d.ts.map +0 -1
- package/dist/foundations/interactions/interaction-policy.d.ts +0 -96
- package/dist/foundations/interactions/interaction-policy.d.ts.map +0 -1
- package/dist/foundations/interactions/pressable.d.ts +0 -54
- package/dist/foundations/interactions/pressable.d.ts.map +0 -1
- package/dist/foundations/interactions/roving-focus.d.ts +0 -117
- package/dist/foundations/interactions/roving-focus.d.ts.map +0 -1
- package/dist/foundations/interactions/roving-focus.js +0 -1
- package/dist/foundations/state/controllable.d.ts +0 -53
- package/dist/foundations/state/controllable.d.ts.map +0 -1
- package/dist/foundations/state/controllable.js +0 -1
- package/dist/foundations/state/index.d.ts +0 -2
- package/dist/foundations/state/index.d.ts.map +0 -1
- package/dist/foundations/structures/index.d.ts +0 -5
- package/dist/foundations/structures/index.d.ts.map +0 -1
- package/dist/foundations/structures.d.ts.map +0 -1
- package/dist/foundations/utilities/aria.d.ts +0 -13
- package/dist/foundations/utilities/aria.d.ts.map +0 -1
- package/dist/foundations/utilities/compose-handlers.d.ts +0 -34
- package/dist/foundations/utilities/compose-handlers.d.ts.map +0 -1
- package/dist/foundations/utilities/event-types.d.ts +0 -17
- package/dist/foundations/utilities/event-types.d.ts.map +0 -1
- package/dist/foundations/utilities/index.d.ts +0 -7
- package/dist/foundations/utilities/index.d.ts.map +0 -1
- package/dist/foundations/utilities/merge-props.d.ts +0 -2
- package/dist/foundations/utilities/merge-props.d.ts.map +0 -1
- package/dist/foundations/utilities/use-id.d.ts +0 -29
- package/dist/foundations/utilities/use-id.d.ts.map +0 -1
- package/dist/foundations/utilities/use-id.js +0 -1
- package/dist/fx/index.d.ts.map +0 -1
- package/dist/fx/noop.d.ts +0 -12
- package/dist/fx/noop.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/jsx/index.d.ts.map +0 -1
- package/dist/jsx/jsx-dev-runtime.d.ts +0 -4
- package/dist/jsx/jsx-dev-runtime.d.ts.map +0 -1
- package/dist/jsx/jsx-runtime.d.ts +0 -10
- package/dist/jsx/jsx-runtime.d.ts.map +0 -1
- package/dist/node_modules/esbuild/lib/main.js +0 -65
- package/dist/renderer/cleanup.d.ts +0 -25
- package/dist/renderer/cleanup.d.ts.map +0 -1
- package/dist/renderer/dom.d.ts +0 -62
- package/dist/renderer/dom.d.ts.map +0 -1
- package/dist/renderer/evaluate.d.ts +0 -4
- package/dist/renderer/evaluate.d.ts.map +0 -1
- package/dist/renderer/fastpath.d.ts +0 -7
- package/dist/renderer/fastpath.d.ts.map +0 -1
- package/dist/renderer/index.d.ts +0 -6
- package/dist/renderer/index.d.ts.map +0 -1
- package/dist/renderer/keyed.d.ts +0 -23
- package/dist/renderer/keyed.d.ts.map +0 -1
- package/dist/renderer/reconcile.d.ts +0 -88
- package/dist/renderer/reconcile.d.ts.map +0 -1
- package/dist/renderer/types.d.ts +0 -3
- package/dist/renderer/types.d.ts.map +0 -1
- package/dist/renderer/utils.d.ts +0 -63
- package/dist/renderer/utils.d.ts.map +0 -1
- package/dist/resources/index.d.ts.map +0 -1
- package/dist/router/index.d.ts.map +0 -1
- package/dist/router/match.d.ts +0 -22
- package/dist/router/match.d.ts.map +0 -1
- package/dist/runtime/dev-namespace.d.ts +0 -31
- package/dist/runtime/dev-namespace.d.ts.map +0 -1
- package/dist/runtime/events.d.ts +0 -52
- package/dist/runtime/events.d.ts.map +0 -1
- package/dist/runtime/execution-model.d.ts +0 -4
- package/dist/runtime/execution-model.d.ts.map +0 -1
- package/dist/runtime/fastlane.d.ts +0 -27
- package/dist/runtime/fastlane.d.ts.map +0 -1
- package/dist/runtime/hydration.d.ts +0 -25
- package/dist/runtime/hydration.d.ts.map +0 -1
- package/dist/runtime/resource-cell.d.ts +0 -35
- package/dist/runtime/resource-cell.d.ts.map +0 -1
- package/dist/runtime/snapshot.d.ts +0 -25
- package/dist/runtime/snapshot.d.ts.map +0 -1
- package/dist/runtime/ssr-bridge.d.ts +0 -10
- package/dist/runtime/ssr-bridge.d.ts.map +0 -1
- package/dist/ssr/attrs.d.ts +0 -26
- package/dist/ssr/attrs.d.ts.map +0 -1
- package/dist/ssr/create-ssr.d.ts +0 -19
- package/dist/ssr/create-ssr.d.ts.map +0 -1
- package/dist/ssr/escape.d.ts +0 -38
- package/dist/ssr/escape.d.ts.map +0 -1
- package/dist/ssr/sink.d.ts +0 -23
- package/dist/ssr/sink.d.ts.map +0 -1
- package/dist/ssr/stream-render.d.ts +0 -7
- package/dist/ssr/stream-render.d.ts.map +0 -1
- package/dist/vite/index.js +0 -3
|
@@ -1 +1,328 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import { isDevelopmentEnvironment } from "../common/env.js";
|
|
2
|
+
import { assertSchedulingPrecondition, invariant } from "../dev/invariant.js";
|
|
3
|
+
import { logger } from "../dev/logger.js";
|
|
4
|
+
import { recordSchedulerFlushTaskCount } from "./perf-metrics.js";
|
|
5
|
+
//#region src/runtime/scheduler.ts
|
|
6
|
+
/**
|
|
7
|
+
* Serialized update scheduler — safer design (no inline execution, explicit flush)
|
|
8
|
+
*
|
|
9
|
+
* Key ideas:
|
|
10
|
+
* - Never execute a task inline from `enqueue`.
|
|
11
|
+
* - `flush()` is explicit and non-reentrant.
|
|
12
|
+
* - `runWithSyncProgress()` allows enqueues temporarily but does not run tasks
|
|
13
|
+
* inline; it runs `fn` and then does an explicit `flush()`.
|
|
14
|
+
* - `waitForFlush()` is race-free with a monotonic `flushVersion`.
|
|
15
|
+
*/
|
|
16
|
+
const MAX_FLUSH_DEPTH = 50;
|
|
17
|
+
const SCHEDULER_LANES = [
|
|
18
|
+
"derived",
|
|
19
|
+
"component",
|
|
20
|
+
"reactive",
|
|
21
|
+
"post"
|
|
22
|
+
];
|
|
23
|
+
function isBulkCommitActive() {
|
|
24
|
+
try {
|
|
25
|
+
const fb = globalThis.__ASKR_FASTLANE;
|
|
26
|
+
return typeof fb?.isBulkCommitActive === "function" ? !!fb.isBulkCommitActive() : false;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
var Scheduler = class {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.lanes = {
|
|
34
|
+
derived: {
|
|
35
|
+
tasks: [],
|
|
36
|
+
head: 0
|
|
37
|
+
},
|
|
38
|
+
component: {
|
|
39
|
+
tasks: [],
|
|
40
|
+
head: 0
|
|
41
|
+
},
|
|
42
|
+
reactive: {
|
|
43
|
+
tasks: [],
|
|
44
|
+
head: 0
|
|
45
|
+
},
|
|
46
|
+
post: {
|
|
47
|
+
tasks: [],
|
|
48
|
+
head: 0
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
this.running = false;
|
|
52
|
+
this.inHandler = false;
|
|
53
|
+
this.depth = 0;
|
|
54
|
+
this.executionDepth = 0;
|
|
55
|
+
this.flushVersion = 0;
|
|
56
|
+
this.kickScheduled = false;
|
|
57
|
+
this.allowSyncProgress = false;
|
|
58
|
+
this.waiters = [];
|
|
59
|
+
this.taskCount = 0;
|
|
60
|
+
}
|
|
61
|
+
hasPendingTasks() {
|
|
62
|
+
for (const lane of SCHEDULER_LANES) {
|
|
63
|
+
const queue = this.lanes[lane];
|
|
64
|
+
if (queue.head < queue.tasks.length) return true;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
getPendingTaskCount() {
|
|
69
|
+
let total = 0;
|
|
70
|
+
for (const lane of SCHEDULER_LANES) {
|
|
71
|
+
const queue = this.lanes[lane];
|
|
72
|
+
total += queue.tasks.length - queue.head;
|
|
73
|
+
}
|
|
74
|
+
return total;
|
|
75
|
+
}
|
|
76
|
+
compactLane(queue) {
|
|
77
|
+
if (queue.head >= queue.tasks.length) {
|
|
78
|
+
queue.tasks.length = 0;
|
|
79
|
+
queue.head = 0;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (queue.head <= 0) return;
|
|
83
|
+
const remaining = queue.tasks.length - queue.head;
|
|
84
|
+
for (let i = 0; i < remaining; i++) queue.tasks[i] = queue.tasks[queue.head + i];
|
|
85
|
+
queue.tasks.length = remaining;
|
|
86
|
+
queue.head = 0;
|
|
87
|
+
}
|
|
88
|
+
scheduleFlushKick() {
|
|
89
|
+
if (this.running || this.kickScheduled || this.inHandler || isBulkCommitActive() || !this.hasPendingTasks()) return;
|
|
90
|
+
this.kickScheduled = true;
|
|
91
|
+
queueMicrotask(() => {
|
|
92
|
+
this.kickScheduled = false;
|
|
93
|
+
if (this.running || isBulkCommitActive() || !this.hasPendingTasks()) return;
|
|
94
|
+
try {
|
|
95
|
+
this.flush();
|
|
96
|
+
} catch (err) {
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
throw err;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
enqueue(task) {
|
|
104
|
+
this.enqueueInLane("component", task);
|
|
105
|
+
}
|
|
106
|
+
enqueueInLane(lane, task) {
|
|
107
|
+
assertSchedulingPrecondition(typeof task === "function", "enqueue() requires a function");
|
|
108
|
+
if (isBulkCommitActive() && !this.allowSyncProgress) {
|
|
109
|
+
if (isDevelopmentEnvironment()) throw new Error("[Scheduler] enqueue() during bulk commit (not allowed)");
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
this.lanes[lane].tasks.push(task);
|
|
113
|
+
this.taskCount++;
|
|
114
|
+
this.scheduleFlushKick();
|
|
115
|
+
}
|
|
116
|
+
flush() {
|
|
117
|
+
invariant(!this.running, "[Scheduler] flush() called while already running");
|
|
118
|
+
if (isDevelopmentEnvironment()) {
|
|
119
|
+
if (isBulkCommitActive() && !this.allowSyncProgress) throw new Error("[Scheduler] flush() started during bulk commit (not allowed)");
|
|
120
|
+
}
|
|
121
|
+
this.running = true;
|
|
122
|
+
this.depth = 0;
|
|
123
|
+
let fatal = null;
|
|
124
|
+
let executedTaskCount = 0;
|
|
125
|
+
const checkFlushDepth = isDevelopmentEnvironment();
|
|
126
|
+
try {
|
|
127
|
+
while (fatal === null) {
|
|
128
|
+
let didRunTask = false;
|
|
129
|
+
for (const lane of SCHEDULER_LANES) {
|
|
130
|
+
const laneQueue = this.lanes[lane];
|
|
131
|
+
let executedInLane = 0;
|
|
132
|
+
while (laneQueue.head < laneQueue.tasks.length) {
|
|
133
|
+
this.depth++;
|
|
134
|
+
if (checkFlushDepth && this.depth > MAX_FLUSH_DEPTH) throw new Error(`[Scheduler] exceeded MAX_FLUSH_DEPTH (${MAX_FLUSH_DEPTH}). Likely infinite update loop.`);
|
|
135
|
+
const task = laneQueue.tasks[laneQueue.head++];
|
|
136
|
+
try {
|
|
137
|
+
this.executionDepth++;
|
|
138
|
+
task();
|
|
139
|
+
this.executionDepth--;
|
|
140
|
+
executedTaskCount++;
|
|
141
|
+
executedInLane++;
|
|
142
|
+
didRunTask = true;
|
|
143
|
+
} catch (err) {
|
|
144
|
+
if (this.executionDepth > 0) this.executionDepth = 0;
|
|
145
|
+
fatal = err;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (executedInLane > 0) this.taskCount = Math.max(0, this.taskCount - executedInLane);
|
|
150
|
+
if (fatal !== null) break;
|
|
151
|
+
}
|
|
152
|
+
if (!didRunTask) break;
|
|
153
|
+
}
|
|
154
|
+
} finally {
|
|
155
|
+
this.running = false;
|
|
156
|
+
this.depth = 0;
|
|
157
|
+
this.executionDepth = 0;
|
|
158
|
+
for (const lane of SCHEDULER_LANES) this.compactLane(this.lanes[lane]);
|
|
159
|
+
this.flushVersion++;
|
|
160
|
+
this.resolveWaiters();
|
|
161
|
+
recordSchedulerFlushTaskCount(executedTaskCount);
|
|
162
|
+
}
|
|
163
|
+
if (fatal) throw fatal;
|
|
164
|
+
}
|
|
165
|
+
finalizeFlush() {}
|
|
166
|
+
runWithSyncProgress(fn) {
|
|
167
|
+
const prev = this.allowSyncProgress;
|
|
168
|
+
this.allowSyncProgress = true;
|
|
169
|
+
const g = globalThis;
|
|
170
|
+
const origQueueMicrotask = g.queueMicrotask;
|
|
171
|
+
const origSetTimeout = g.setTimeout;
|
|
172
|
+
if (isDevelopmentEnvironment()) {
|
|
173
|
+
g.queueMicrotask = () => {
|
|
174
|
+
throw new Error("[Scheduler] queueMicrotask not allowed during runWithSyncProgress");
|
|
175
|
+
};
|
|
176
|
+
g.setTimeout = () => {
|
|
177
|
+
throw new Error("[Scheduler] setTimeout not allowed during runWithSyncProgress");
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
const startVersion = this.flushVersion;
|
|
181
|
+
try {
|
|
182
|
+
const res = fn();
|
|
183
|
+
if (!this.running && this.hasPendingTasks()) this.flush();
|
|
184
|
+
if (isDevelopmentEnvironment()) {
|
|
185
|
+
if (this.hasPendingTasks()) throw new Error("[Scheduler] tasks remain after runWithSyncProgress flush");
|
|
186
|
+
}
|
|
187
|
+
return res;
|
|
188
|
+
} finally {
|
|
189
|
+
if (isDevelopmentEnvironment()) {
|
|
190
|
+
g.queueMicrotask = origQueueMicrotask;
|
|
191
|
+
g.setTimeout = origSetTimeout;
|
|
192
|
+
}
|
|
193
|
+
try {
|
|
194
|
+
if (this.flushVersion === startVersion) {
|
|
195
|
+
this.flushVersion++;
|
|
196
|
+
this.resolveWaiters();
|
|
197
|
+
}
|
|
198
|
+
} catch (e) {}
|
|
199
|
+
this.allowSyncProgress = prev;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
waitForFlush(targetVersion, timeoutMs = 2e3) {
|
|
203
|
+
const target = typeof targetVersion === "number" ? targetVersion : this.flushVersion + 1;
|
|
204
|
+
if (this.flushVersion >= target) return Promise.resolve();
|
|
205
|
+
return new Promise((resolve, reject) => {
|
|
206
|
+
const timer = setTimeout(() => {
|
|
207
|
+
const ns = globalThis.__ASKR__ || {};
|
|
208
|
+
const diag = {
|
|
209
|
+
flushVersion: this.flushVersion,
|
|
210
|
+
queueLen: this.getPendingTaskCount(),
|
|
211
|
+
running: this.running,
|
|
212
|
+
inHandler: this.inHandler,
|
|
213
|
+
bulk: isBulkCommitActive(),
|
|
214
|
+
namespace: ns
|
|
215
|
+
};
|
|
216
|
+
reject(/* @__PURE__ */ new Error(`waitForFlush timeout ${timeoutMs}ms: ${JSON.stringify(diag)}`));
|
|
217
|
+
}, timeoutMs);
|
|
218
|
+
this.waiters.push({
|
|
219
|
+
target,
|
|
220
|
+
resolve,
|
|
221
|
+
reject,
|
|
222
|
+
timer
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
getState() {
|
|
227
|
+
return {
|
|
228
|
+
queueLength: this.getPendingTaskCount(),
|
|
229
|
+
running: this.running,
|
|
230
|
+
depth: this.depth,
|
|
231
|
+
executionDepth: this.executionDepth,
|
|
232
|
+
taskCount: this.taskCount,
|
|
233
|
+
flushVersion: this.flushVersion,
|
|
234
|
+
laneQueues: {
|
|
235
|
+
derived: this.lanes.derived.tasks.length - this.lanes.derived.head,
|
|
236
|
+
component: this.lanes.component.tasks.length - this.lanes.component.head,
|
|
237
|
+
reactive: this.lanes.reactive.tasks.length - this.lanes.reactive.head,
|
|
238
|
+
post: this.lanes.post.tasks.length - this.lanes.post.head
|
|
239
|
+
},
|
|
240
|
+
inHandler: this.inHandler,
|
|
241
|
+
allowSyncProgress: this.allowSyncProgress
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
getFlushVersion() {
|
|
245
|
+
return this.flushVersion;
|
|
246
|
+
}
|
|
247
|
+
flushIfQueued() {
|
|
248
|
+
if (!this.running && this.hasPendingTasks()) this.flush();
|
|
249
|
+
}
|
|
250
|
+
runInHandlerScope(fn, flushMode = "defer") {
|
|
251
|
+
const prevInHandler = this.inHandler;
|
|
252
|
+
this.inHandler = true;
|
|
253
|
+
try {
|
|
254
|
+
return fn();
|
|
255
|
+
} finally {
|
|
256
|
+
this.inHandler = prevInHandler;
|
|
257
|
+
if (!this.inHandler) if (flushMode === "sync") this.flushIfQueued();
|
|
258
|
+
else this.scheduleFlushKick();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
setInHandler(v) {
|
|
262
|
+
this.inHandler = v;
|
|
263
|
+
if (!v) this.scheduleFlushKick();
|
|
264
|
+
}
|
|
265
|
+
isInHandler() {
|
|
266
|
+
return this.inHandler;
|
|
267
|
+
}
|
|
268
|
+
isExecuting() {
|
|
269
|
+
return this.running || this.executionDepth > 0;
|
|
270
|
+
}
|
|
271
|
+
clearPendingSyncTasks() {
|
|
272
|
+
const remaining = this.getPendingTaskCount();
|
|
273
|
+
if (remaining <= 0) return 0;
|
|
274
|
+
if (this.running) {
|
|
275
|
+
for (const lane of SCHEDULER_LANES) {
|
|
276
|
+
const queue = this.lanes[lane];
|
|
277
|
+
queue.tasks.length = queue.head;
|
|
278
|
+
}
|
|
279
|
+
this.taskCount = Math.max(0, this.taskCount - remaining);
|
|
280
|
+
queueMicrotask(() => {
|
|
281
|
+
try {
|
|
282
|
+
this.flushVersion++;
|
|
283
|
+
this.resolveWaiters();
|
|
284
|
+
} catch (e) {}
|
|
285
|
+
});
|
|
286
|
+
return remaining;
|
|
287
|
+
}
|
|
288
|
+
for (const lane of SCHEDULER_LANES) {
|
|
289
|
+
const queue = this.lanes[lane];
|
|
290
|
+
queue.tasks.length = 0;
|
|
291
|
+
queue.head = 0;
|
|
292
|
+
}
|
|
293
|
+
this.taskCount = Math.max(0, this.taskCount - remaining);
|
|
294
|
+
this.flushVersion++;
|
|
295
|
+
this.resolveWaiters();
|
|
296
|
+
return remaining;
|
|
297
|
+
}
|
|
298
|
+
resolveWaiters() {
|
|
299
|
+
if (this.waiters.length === 0) return;
|
|
300
|
+
const ready = [];
|
|
301
|
+
const remaining = [];
|
|
302
|
+
for (const w of this.waiters) if (this.flushVersion >= w.target) {
|
|
303
|
+
if (w.timer) clearTimeout(w.timer);
|
|
304
|
+
ready.push(w.resolve);
|
|
305
|
+
} else remaining.push(w);
|
|
306
|
+
this.waiters = remaining;
|
|
307
|
+
for (const r of ready) r();
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
const globalScheduler = new Scheduler();
|
|
311
|
+
function isSchedulerExecuting() {
|
|
312
|
+
return globalScheduler.isExecuting();
|
|
313
|
+
}
|
|
314
|
+
function scheduleEventHandler(handler) {
|
|
315
|
+
return (event) => {
|
|
316
|
+
try {
|
|
317
|
+
globalScheduler.runInHandlerScope(() => {
|
|
318
|
+
handler.call(null, event);
|
|
319
|
+
});
|
|
320
|
+
} catch (error) {
|
|
321
|
+
logger.error("[Askr] Event handler error:", error);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
//#endregion
|
|
326
|
+
export { globalScheduler, isSchedulerExecuting, scheduleEventHandler };
|
|
327
|
+
|
|
328
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","names":[],"sources":["../../src/runtime/scheduler.ts"],"sourcesContent":["/**\n * Serialized update scheduler — safer design (no inline execution, explicit flush)\n *\n * Key ideas:\n * - Never execute a task inline from `enqueue`.\n * - `flush()` is explicit and non-reentrant.\n * - `runWithSyncProgress()` allows enqueues temporarily but does not run tasks\n * inline; it runs `fn` and then does an explicit `flush()`.\n * - `waitForFlush()` is race-free with a monotonic `flushVersion`.\n */\n\nimport { isDevelopmentEnvironment } from '../common/env';\nimport { assertSchedulingPrecondition, invariant } from '../dev/invariant';\nimport { logger } from '../dev/logger';\nimport { recordSchedulerFlushTaskCount } from './perf-metrics';\n\nconst MAX_FLUSH_DEPTH = 50;\n\ntype Task = () => void;\nexport type SchedulerLane = 'derived' | 'component' | 'reactive' | 'post';\n\nconst SCHEDULER_LANES: SchedulerLane[] = [\n 'derived',\n 'component',\n 'reactive',\n 'post',\n];\n\ninterface LaneQueue {\n tasks: Task[];\n head: number;\n}\n\nfunction isBulkCommitActive(): boolean {\n try {\n const fb = (\n globalThis as {\n __ASKR_FASTLANE?: { isBulkCommitActive?: () => boolean };\n }\n ).__ASKR_FASTLANE;\n return typeof fb?.isBulkCommitActive === 'function'\n ? !!fb.isBulkCommitActive()\n : false;\n } catch (e) {\n void e;\n return false;\n }\n}\n\nexport class Scheduler {\n private lanes: Record<SchedulerLane, LaneQueue> = {\n derived: { tasks: [], head: 0 },\n component: { tasks: [], head: 0 },\n reactive: { tasks: [], head: 0 },\n post: { tasks: [], head: 0 },\n };\n\n private running = false;\n private inHandler = false;\n private depth = 0;\n private executionDepth = 0; // for compat with existing diagnostics\n\n // Monotonic flush version increments at end of each flush\n private flushVersion = 0;\n\n // Best-effort microtask kick scheduling\n private kickScheduled = false;\n\n // Escape hatch flag for runWithSyncProgress\n private allowSyncProgress = false;\n\n // Waiters waiting for flushVersion >= target\n private waiters: Array<{\n target: number;\n resolve: () => void;\n reject: (err: unknown) => void;\n timer?: ReturnType<typeof setTimeout>;\n }> = [];\n\n // Keep a lightweight taskCount for compatibility/diagnostics\n private taskCount = 0;\n\n private hasPendingTasks(): boolean {\n for (const lane of SCHEDULER_LANES) {\n const queue = this.lanes[lane];\n if (queue.head < queue.tasks.length) {\n return true;\n }\n }\n return false;\n }\n\n private getPendingTaskCount(): number {\n let total = 0;\n for (const lane of SCHEDULER_LANES) {\n const queue = this.lanes[lane];\n total += queue.tasks.length - queue.head;\n }\n return total;\n }\n\n private compactLane(queue: LaneQueue): void {\n if (queue.head >= queue.tasks.length) {\n queue.tasks.length = 0;\n queue.head = 0;\n return;\n }\n\n if (queue.head <= 0) {\n return;\n }\n\n const remaining = queue.tasks.length - queue.head;\n for (let i = 0; i < remaining; i++) {\n queue.tasks[i] = queue.tasks[queue.head + i];\n }\n queue.tasks.length = remaining;\n queue.head = 0;\n }\n\n private scheduleFlushKick(): void {\n if (\n this.running ||\n this.kickScheduled ||\n this.inHandler ||\n isBulkCommitActive() ||\n !this.hasPendingTasks()\n ) {\n return;\n }\n\n this.kickScheduled = true;\n queueMicrotask(() => {\n this.kickScheduled = false;\n if (this.running || isBulkCommitActive() || !this.hasPendingTasks()) {\n return;\n }\n try {\n this.flush();\n } catch (err) {\n setTimeout(() => {\n throw err;\n });\n }\n });\n }\n\n enqueue(task: Task): void {\n this.enqueueInLane('component', task);\n }\n\n enqueueInLane(lane: SchedulerLane, task: Task): void {\n assertSchedulingPrecondition(\n typeof task === 'function',\n 'enqueue() requires a function'\n );\n\n // Strict rule: during bulk commit, only allow enqueues if runWithSyncProgress enabled\n if (isBulkCommitActive() && !this.allowSyncProgress) {\n if (isDevelopmentEnvironment()) {\n throw new Error(\n '[Scheduler] enqueue() during bulk commit (not allowed)'\n );\n }\n return;\n }\n\n // Enqueue task and account counts\n this.lanes[lane].tasks.push(task);\n this.taskCount++;\n\n this.scheduleFlushKick();\n }\n\n flush(): void {\n invariant(\n !this.running,\n '[Scheduler] flush() called while already running'\n );\n\n // Dev-only guard: disallow flush during bulk commit unless allowed\n if (isDevelopmentEnvironment()) {\n if (isBulkCommitActive() && !this.allowSyncProgress) {\n throw new Error(\n '[Scheduler] flush() started during bulk commit (not allowed)'\n );\n }\n }\n\n this.running = true;\n this.depth = 0;\n let fatal: unknown = null;\n let executedTaskCount = 0;\n const checkFlushDepth = isDevelopmentEnvironment();\n\n try {\n while (fatal === null) {\n let didRunTask = false;\n\n for (const lane of SCHEDULER_LANES) {\n const laneQueue = this.lanes[lane];\n let executedInLane = 0;\n\n while (laneQueue.head < laneQueue.tasks.length) {\n this.depth++;\n if (checkFlushDepth && this.depth > MAX_FLUSH_DEPTH) {\n throw new Error(\n `[Scheduler] exceeded MAX_FLUSH_DEPTH (${MAX_FLUSH_DEPTH}). Likely infinite update loop.`\n );\n }\n\n const task = laneQueue.tasks[laneQueue.head++];\n try {\n this.executionDepth++;\n task();\n this.executionDepth--;\n executedTaskCount++;\n executedInLane++;\n didRunTask = true;\n } catch (err) {\n // ensure executionDepth stays balanced\n if (this.executionDepth > 0) this.executionDepth = 0;\n fatal = err;\n break;\n }\n }\n\n if (executedInLane > 0) {\n this.taskCount = Math.max(0, this.taskCount - executedInLane);\n }\n\n if (fatal !== null) {\n break;\n }\n }\n\n if (!didRunTask) {\n break;\n }\n }\n } finally {\n this.running = false;\n this.depth = 0;\n this.executionDepth = 0;\n\n for (const lane of SCHEDULER_LANES) {\n this.compactLane(this.lanes[lane]);\n }\n\n // Advance flush epoch and resolve waiters\n this.flushVersion++;\n this.resolveWaiters();\n recordSchedulerFlushTaskCount(executedTaskCount);\n }\n\n if (fatal) throw fatal;\n }\n\n private finalizeFlush(): void {\n // Not used - finalize happens in finally block above\n }\n\n runWithSyncProgress<T>(fn: () => T): T {\n const prev = this.allowSyncProgress;\n this.allowSyncProgress = true;\n\n const g = globalThis as {\n queueMicrotask?: (...args: unknown[]) => void;\n setTimeout?: (...args: unknown[]) => unknown;\n };\n const origQueueMicrotask = g.queueMicrotask;\n const origSetTimeout = g.setTimeout;\n\n if (isDevelopmentEnvironment()) {\n g.queueMicrotask = () => {\n throw new Error(\n '[Scheduler] queueMicrotask not allowed during runWithSyncProgress'\n );\n };\n g.setTimeout = () => {\n throw new Error(\n '[Scheduler] setTimeout not allowed during runWithSyncProgress'\n );\n };\n }\n\n // Snapshot flushVersion so we can ensure we always complete an epoch\n const startVersion = this.flushVersion;\n\n try {\n const res = fn();\n\n // Flush deterministically if tasks were enqueued (and we're not already running)\n if (!this.running && this.hasPendingTasks()) {\n this.flush();\n }\n\n if (isDevelopmentEnvironment()) {\n if (this.hasPendingTasks()) {\n throw new Error(\n '[Scheduler] tasks remain after runWithSyncProgress flush'\n );\n }\n }\n\n return res;\n } finally {\n // Restore guarded globals\n if (isDevelopmentEnvironment()) {\n g.queueMicrotask = origQueueMicrotask;\n g.setTimeout = origSetTimeout;\n }\n\n // If no flush happened during the protected window, complete an epoch so\n // observers (tests) see progress even when fast-lane did synchronous work\n // without enqueuing tasks.\n try {\n if (this.flushVersion === startVersion) {\n this.flushVersion++;\n this.resolveWaiters();\n }\n } catch (e) {\n void e;\n }\n\n this.allowSyncProgress = prev;\n }\n }\n\n waitForFlush(targetVersion?: number, timeoutMs = 2000): Promise<void> {\n const target =\n typeof targetVersion === 'number' ? targetVersion : this.flushVersion + 1;\n if (this.flushVersion >= target) return Promise.resolve();\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n const ns =\n (\n globalThis as unknown as Record<string, unknown> & {\n __ASKR__?: Record<string, unknown>;\n }\n ).__ASKR__ || {};\n const diag = {\n flushVersion: this.flushVersion,\n queueLen: this.getPendingTaskCount(),\n running: this.running,\n inHandler: this.inHandler,\n bulk: isBulkCommitActive(),\n namespace: ns,\n };\n reject(\n new Error(\n `waitForFlush timeout ${timeoutMs}ms: ${JSON.stringify(diag)}`\n )\n );\n }, timeoutMs);\n\n this.waiters.push({ target, resolve, reject, timer });\n });\n }\n\n getState() {\n // Provide the compatibility shape expected by diagnostics/tests\n return {\n queueLength: this.getPendingTaskCount(),\n running: this.running,\n depth: this.depth,\n executionDepth: this.executionDepth,\n taskCount: this.taskCount,\n flushVersion: this.flushVersion,\n laneQueues: {\n derived: this.lanes.derived.tasks.length - this.lanes.derived.head,\n component:\n this.lanes.component.tasks.length - this.lanes.component.head,\n reactive: this.lanes.reactive.tasks.length - this.lanes.reactive.head,\n post: this.lanes.post.tasks.length - this.lanes.post.head,\n },\n // New fields for optional inspection\n inHandler: this.inHandler,\n allowSyncProgress: this.allowSyncProgress,\n };\n }\n\n getFlushVersion(): number {\n return this.flushVersion;\n }\n\n flushIfQueued(): void {\n if (!this.running && this.hasPendingTasks()) {\n this.flush();\n }\n }\n\n runInHandlerScope<T>(fn: () => T, flushMode: 'defer' | 'sync' = 'defer'): T {\n const prevInHandler = this.inHandler;\n this.inHandler = true;\n\n try {\n return fn();\n } finally {\n this.inHandler = prevInHandler;\n\n if (!this.inHandler) {\n if (flushMode === 'sync') {\n this.flushIfQueued();\n } else {\n this.scheduleFlushKick();\n }\n }\n }\n }\n\n setInHandler(v: boolean) {\n this.inHandler = v;\n if (!v) {\n this.scheduleFlushKick();\n }\n }\n\n isInHandler(): boolean {\n return this.inHandler;\n }\n\n isExecuting(): boolean {\n return this.running || this.executionDepth > 0;\n }\n\n // Clear pending synchronous tasks (used by fastlane enter/exit)\n clearPendingSyncTasks(): number {\n const remaining = this.getPendingTaskCount();\n if (remaining <= 0) return 0;\n\n if (this.running) {\n for (const lane of SCHEDULER_LANES) {\n const queue = this.lanes[lane];\n queue.tasks.length = queue.head;\n }\n this.taskCount = Math.max(0, this.taskCount - remaining);\n queueMicrotask(() => {\n try {\n this.flushVersion++;\n this.resolveWaiters();\n } catch (e) {\n void e;\n }\n });\n return remaining;\n }\n\n for (const lane of SCHEDULER_LANES) {\n const queue = this.lanes[lane];\n queue.tasks.length = 0;\n queue.head = 0;\n }\n this.taskCount = Math.max(0, this.taskCount - remaining);\n this.flushVersion++;\n this.resolveWaiters();\n return remaining;\n }\n\n private resolveWaiters() {\n if (this.waiters.length === 0) return;\n const ready: Array<() => void> = [];\n const remaining: typeof this.waiters = [];\n\n for (const w of this.waiters) {\n if (this.flushVersion >= w.target) {\n if (w.timer) clearTimeout(w.timer);\n ready.push(w.resolve);\n } else {\n remaining.push(w);\n }\n }\n\n this.waiters = remaining;\n for (const r of ready) r();\n }\n}\n\nexport const globalScheduler = new Scheduler();\n\nexport function isSchedulerExecuting(): boolean {\n return globalScheduler.isExecuting();\n}\n\nexport function scheduleEventHandler(handler: EventListener): EventListener {\n return (event: Event) => {\n try {\n globalScheduler.runInHandlerScope(() => {\n handler.call(null, event);\n });\n } catch (error) {\n logger.error('[Askr] Event handler error:', error);\n }\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/runtime/selector.d.ts
|
|
2
|
+
interface Selector<T> {
|
|
3
|
+
(candidate: T): boolean;
|
|
4
|
+
}
|
|
5
|
+
type SelectorEquals<T> = {
|
|
6
|
+
bivarianceHack(a: T, b: T): boolean;
|
|
7
|
+
}['bivarianceHack'];
|
|
8
|
+
declare function selector<T>(source: () => T, equals?: SelectorEquals<T>): Selector<T>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { Selector, selector };
|
|
11
|
+
//# sourceMappingURL=selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.d.ts","names":[],"sources":["../../src/runtime/selector.ts"],"mappings":";UA6BiB,QAAA;EAAA,CACd,SAAA,EAAW,CAAA;AAAA;AAAA,KAOT,cAAA;EACH,cAAA,CAAe,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA;AAAA,iBAwRV,QAAA,GAAA,CACd,MAAA,QAAc,CAAA,EACd,MAAA,GAAQ,cAAA,CAAe,CAAA,IACtB,QAAA,CAAS,CAAA"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { incrementPerfMetric } from "./perf-metrics.js";
|
|
2
|
+
import { globalScheduler } from "./scheduler.js";
|
|
3
|
+
import { clearDerivedDependencySubscriptions, markReactivePropsDirtySource, markReadableDerivedSubscribersDirty, markReadableUsage, notifyReadableReaders, recordReadableRead, syncDerivedDependencySubscriptions, withDerivedReadTracking } from "./readable.js";
|
|
4
|
+
import { claimHookIndex, getCurrentInstance } from "./component.js";
|
|
5
|
+
//#region src/runtime/selector.ts
|
|
6
|
+
const selectorCells = /* @__PURE__ */ new WeakMap();
|
|
7
|
+
const dirtySelectorCells = /* @__PURE__ */ new Set();
|
|
8
|
+
let hasPendingSelectorFlush = false;
|
|
9
|
+
function getSelectorStore(instance) {
|
|
10
|
+
let store = selectorCells.get(instance);
|
|
11
|
+
if (!store) {
|
|
12
|
+
store = /* @__PURE__ */ new Map();
|
|
13
|
+
selectorCells.set(instance, store);
|
|
14
|
+
}
|
|
15
|
+
return store;
|
|
16
|
+
}
|
|
17
|
+
function scheduleSelectorFlush() {
|
|
18
|
+
if (hasPendingSelectorFlush) return;
|
|
19
|
+
hasPendingSelectorFlush = true;
|
|
20
|
+
globalScheduler.enqueueInLane("derived", flushDirtySelectorCells);
|
|
21
|
+
}
|
|
22
|
+
function markSelectorCellDirty(cell) {
|
|
23
|
+
cell._dirty = true;
|
|
24
|
+
if (cell._scheduled) return;
|
|
25
|
+
cell._scheduled = true;
|
|
26
|
+
dirtySelectorCells.add(cell);
|
|
27
|
+
scheduleSelectorFlush();
|
|
28
|
+
}
|
|
29
|
+
function flushDirtySelectorCells() {
|
|
30
|
+
hasPendingSelectorFlush = false;
|
|
31
|
+
if (dirtySelectorCells.size === 0) return;
|
|
32
|
+
const pending = Array.from(dirtySelectorCells);
|
|
33
|
+
dirtySelectorCells.clear();
|
|
34
|
+
for (const cell of pending) {
|
|
35
|
+
cell._scheduled = false;
|
|
36
|
+
if (!cell._dirty) continue;
|
|
37
|
+
recomputeSelectorCell(cell, true);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function isObjectCandidate(value) {
|
|
41
|
+
return typeof value === "object" && value !== null || typeof value === "function";
|
|
42
|
+
}
|
|
43
|
+
function isDefaultSelectorEquals(equals) {
|
|
44
|
+
return equals === Object.is;
|
|
45
|
+
}
|
|
46
|
+
function createCandidateSource(candidate) {
|
|
47
|
+
const source = (() => false);
|
|
48
|
+
source._candidate = candidate;
|
|
49
|
+
return source;
|
|
50
|
+
}
|
|
51
|
+
function getCandidateSource(cell, candidate) {
|
|
52
|
+
if (isObjectCandidate(candidate)) {
|
|
53
|
+
const cached = cell._objectCandidates.get(candidate);
|
|
54
|
+
if (cached) return cached;
|
|
55
|
+
const created = createCandidateSource(candidate);
|
|
56
|
+
created._candidate = candidate;
|
|
57
|
+
cell._objectCandidates.set(candidate, created);
|
|
58
|
+
cell._objectCandidateSources.add(created);
|
|
59
|
+
return created;
|
|
60
|
+
}
|
|
61
|
+
const key = candidate;
|
|
62
|
+
const cached = cell._primitiveCandidates.get(key);
|
|
63
|
+
if (cached) return cached;
|
|
64
|
+
const created = createCandidateSource(candidate);
|
|
65
|
+
created._candidate = candidate;
|
|
66
|
+
cell._primitiveCandidates.set(key, created);
|
|
67
|
+
return created;
|
|
68
|
+
}
|
|
69
|
+
function notifySelectorSource(source) {
|
|
70
|
+
incrementPerfMetric("selectorInvalidations");
|
|
71
|
+
markReadableDerivedSubscribersDirty(source);
|
|
72
|
+
markReactivePropsDirtySource(source);
|
|
73
|
+
notifyReadableReaders(source);
|
|
74
|
+
}
|
|
75
|
+
function notifyAllSelectorSources(cell) {
|
|
76
|
+
for (const source of cell._primitiveCandidates.values()) notifySelectorSource(source);
|
|
77
|
+
for (const source of cell._objectCandidateSources) notifySelectorSource(source);
|
|
78
|
+
}
|
|
79
|
+
function notifySelectorValueChange(cell, prevValue, nextValue) {
|
|
80
|
+
if (!isDefaultSelectorEquals(cell._equals)) {
|
|
81
|
+
notifyAllSelectorSources(cell);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (!Object.is(prevValue, nextValue)) {
|
|
85
|
+
notifySelectorSource(getCandidateSource(cell, prevValue));
|
|
86
|
+
notifySelectorSource(getCandidateSource(cell, nextValue));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function recomputeSelectorCell(cell, notifyDownstream) {
|
|
90
|
+
if (!cell._dirty && cell._hasValue) return cell._value;
|
|
91
|
+
if (cell._evaluating) throw new Error("selector() cannot read itself recursively");
|
|
92
|
+
cell._evaluating = true;
|
|
93
|
+
cell._dirty = false;
|
|
94
|
+
cell._pendingDependencySources = /* @__PURE__ */ new Set();
|
|
95
|
+
const prevSources = cell._sources;
|
|
96
|
+
const hadValue = cell._hasValue;
|
|
97
|
+
const prevValue = cell._value;
|
|
98
|
+
let nextValue;
|
|
99
|
+
try {
|
|
100
|
+
nextValue = withDerivedReadTracking(cell, cell._source);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
cell._dirty = true;
|
|
103
|
+
cell._pendingDependencySources = void 0;
|
|
104
|
+
throw error;
|
|
105
|
+
} finally {
|
|
106
|
+
cell._evaluating = false;
|
|
107
|
+
}
|
|
108
|
+
const nextSources = cell._pendingDependencySources ?? /* @__PURE__ */ new Set();
|
|
109
|
+
cell._pendingDependencySources = void 0;
|
|
110
|
+
syncDerivedDependencySubscriptions(cell, prevSources, nextSources);
|
|
111
|
+
cell._sources = nextSources;
|
|
112
|
+
const valueChanged = !cell._hasValue || !cell._equals(prevValue, nextValue);
|
|
113
|
+
cell._hasValue = true;
|
|
114
|
+
cell._value = nextValue;
|
|
115
|
+
if (valueChanged && notifyDownstream && hadValue) notifySelectorValueChange(cell, prevValue, nextValue);
|
|
116
|
+
return cell._value;
|
|
117
|
+
}
|
|
118
|
+
function createSelectorCell(instance, hookIndex, source, equals) {
|
|
119
|
+
const cell = function selectorPredicate(candidate) {
|
|
120
|
+
recordReadableRead(getCandidateSource(cell, candidate));
|
|
121
|
+
incrementPerfMetric("selectorCandidateReads");
|
|
122
|
+
const current = recomputeSelectorCell(cell, cell._scheduled);
|
|
123
|
+
return cell._equals(current, candidate);
|
|
124
|
+
};
|
|
125
|
+
cell._owner = instance;
|
|
126
|
+
cell._hookIndex = hookIndex;
|
|
127
|
+
cell._source = source;
|
|
128
|
+
cell._equals = equals;
|
|
129
|
+
cell._value = void 0;
|
|
130
|
+
cell._hasValue = false;
|
|
131
|
+
cell._dirty = true;
|
|
132
|
+
cell._scheduled = false;
|
|
133
|
+
cell._evaluating = false;
|
|
134
|
+
cell._sources = /* @__PURE__ */ new Set();
|
|
135
|
+
cell._primitiveCandidates = /* @__PURE__ */ new Map();
|
|
136
|
+
cell._objectCandidates = /* @__PURE__ */ new WeakMap();
|
|
137
|
+
cell._objectCandidateSources = /* @__PURE__ */ new Set();
|
|
138
|
+
cell._markDirty = () => {
|
|
139
|
+
markSelectorCellDirty(cell);
|
|
140
|
+
};
|
|
141
|
+
cell._cleanup = () => {
|
|
142
|
+
cell._scheduled = false;
|
|
143
|
+
cell._dirty = false;
|
|
144
|
+
cell._hasValue = false;
|
|
145
|
+
dirtySelectorCells.delete(cell);
|
|
146
|
+
clearDerivedDependencySubscriptions(cell, cell._sources);
|
|
147
|
+
for (const sourceRef of cell._primitiveCandidates.values()) {
|
|
148
|
+
sourceRef._readers?.clear();
|
|
149
|
+
sourceRef._derivedSubscribers?.clear();
|
|
150
|
+
}
|
|
151
|
+
for (const sourceRef of cell._objectCandidateSources) {
|
|
152
|
+
sourceRef._readers?.clear();
|
|
153
|
+
sourceRef._derivedSubscribers?.clear();
|
|
154
|
+
}
|
|
155
|
+
cell._primitiveCandidates.clear();
|
|
156
|
+
cell._objectCandidateSources.clear();
|
|
157
|
+
};
|
|
158
|
+
(instance.cleanupFns ??= []).push(() => {
|
|
159
|
+
cell._cleanup();
|
|
160
|
+
selectorCells.get(instance)?.delete(hookIndex);
|
|
161
|
+
});
|
|
162
|
+
return cell;
|
|
163
|
+
}
|
|
164
|
+
function getOrCreateSelectorCell(instance, hookIndex, source, equals) {
|
|
165
|
+
const store = getSelectorStore(instance);
|
|
166
|
+
const existing = store.get(hookIndex);
|
|
167
|
+
if (existing) {
|
|
168
|
+
existing._source = source;
|
|
169
|
+
existing._equals = equals;
|
|
170
|
+
existing._dirty = true;
|
|
171
|
+
return existing;
|
|
172
|
+
}
|
|
173
|
+
const created = createSelectorCell(instance, hookIndex, source, equals);
|
|
174
|
+
store.set(hookIndex, created);
|
|
175
|
+
return created;
|
|
176
|
+
}
|
|
177
|
+
function selector(source, equals = Object.is) {
|
|
178
|
+
markReadableUsage(source);
|
|
179
|
+
const instance = getCurrentInstance();
|
|
180
|
+
if (!instance) throw new Error("selector() can only be called during component render execution. Move selector() calls to the top level of your component function.");
|
|
181
|
+
const cell = getOrCreateSelectorCell(instance, claimHookIndex(instance, "selector"), source, equals);
|
|
182
|
+
recomputeSelectorCell(cell, false);
|
|
183
|
+
return cell;
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
186
|
+
export { selector };
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.js","names":[],"sources":["../../src/runtime/selector.ts"],"sourcesContent":["import {\n claimHookIndex,\n getCurrentInstance,\n type ComponentInstance,\n} from './component';\nimport { globalScheduler } from './scheduler';\nimport {\n clearDerivedDependencySubscriptions,\n markReadableDerivedSubscribersDirty,\n markReadableUsage,\n markReactivePropsDirtySource,\n notifyReadableReaders,\n recordReadableRead,\n syncDerivedDependencySubscriptions,\n withDerivedReadTracking,\n type DerivedSubscriber,\n type ReadableSource,\n} from './readable';\nimport { incrementPerfMetric } from './perf-metrics';\n\ntype PrimitiveKey =\n | string\n | number\n | boolean\n | symbol\n | bigint\n | null\n | undefined;\n\nexport interface Selector<T> {\n (candidate: T): boolean;\n}\n\ninterface SelectorCandidateSource<T> extends ReadableSource<boolean> {\n _candidate: T;\n}\n\ntype SelectorEquals<T> = {\n bivarianceHack(a: T, b: T): boolean;\n}['bivarianceHack'];\n\ninterface SelectorCell<T> extends Selector<T>, DerivedSubscriber {\n _owner: ComponentInstance;\n _hookIndex: number;\n _source: () => T;\n _equals: SelectorEquals<T>;\n _value: T;\n _hasValue: boolean;\n _dirty: boolean;\n _scheduled: boolean;\n _evaluating: boolean;\n _sources: Set<ReadableSource<unknown>>;\n _pendingDependencySources?: Set<ReadableSource<unknown>>;\n _primitiveCandidates: Map<PrimitiveKey, SelectorCandidateSource<T>>;\n _objectCandidates: WeakMap<object, SelectorCandidateSource<T>>;\n _objectCandidateSources: Set<SelectorCandidateSource<T>>;\n _cleanup(): void;\n}\n\nconst selectorCells = new WeakMap<\n ComponentInstance,\n Map<number, SelectorCell<unknown>>\n>();\nconst dirtySelectorCells = new Set<SelectorCell<unknown>>();\nlet hasPendingSelectorFlush = false;\n\nfunction getSelectorStore(\n instance: ComponentInstance\n): Map<number, SelectorCell<unknown>> {\n let store = selectorCells.get(instance);\n if (!store) {\n store = new Map();\n selectorCells.set(instance, store);\n }\n return store;\n}\n\nfunction scheduleSelectorFlush(): void {\n if (hasPendingSelectorFlush) {\n return;\n }\n hasPendingSelectorFlush = true;\n globalScheduler.enqueueInLane('derived', flushDirtySelectorCells);\n}\n\nfunction markSelectorCellDirty(cell: SelectorCell<unknown>): void {\n cell._dirty = true;\n if (cell._scheduled) {\n return;\n }\n\n cell._scheduled = true;\n dirtySelectorCells.add(cell);\n scheduleSelectorFlush();\n}\n\nfunction flushDirtySelectorCells(): void {\n hasPendingSelectorFlush = false;\n\n if (dirtySelectorCells.size === 0) {\n return;\n }\n\n const pending = Array.from(dirtySelectorCells);\n dirtySelectorCells.clear();\n\n for (const cell of pending) {\n cell._scheduled = false;\n if (!cell._dirty) {\n continue;\n }\n recomputeSelectorCell(cell, true);\n }\n}\n\nfunction isObjectCandidate(value: unknown): value is object {\n return (\n (typeof value === 'object' && value !== null) || typeof value === 'function'\n );\n}\n\nfunction isDefaultSelectorEquals<T>(equals: SelectorEquals<T>): boolean {\n return equals === Object.is;\n}\n\nfunction createCandidateSource<T>(candidate: T): SelectorCandidateSource<T> {\n const source = (() => false) as SelectorCandidateSource<T>;\n source._candidate = candidate;\n return source;\n}\n\nfunction getCandidateSource<T>(\n cell: SelectorCell<T>,\n candidate: T\n): SelectorCandidateSource<T> {\n if (isObjectCandidate(candidate)) {\n const cached = cell._objectCandidates.get(candidate);\n if (cached) {\n return cached;\n }\n\n const created = createCandidateSource(candidate);\n created._candidate = candidate;\n cell._objectCandidates.set(candidate, created);\n cell._objectCandidateSources.add(created);\n return created;\n }\n\n const key = candidate as PrimitiveKey;\n const cached = cell._primitiveCandidates.get(key);\n if (cached) {\n return cached;\n }\n\n const created = createCandidateSource(candidate);\n created._candidate = candidate;\n cell._primitiveCandidates.set(key, created);\n return created;\n}\n\nfunction notifySelectorSource(source: SelectorCandidateSource<unknown>): void {\n incrementPerfMetric('selectorInvalidations');\n markReadableDerivedSubscribersDirty(source);\n markReactivePropsDirtySource(source);\n notifyReadableReaders(source);\n}\n\nfunction notifyAllSelectorSources<T>(cell: SelectorCell<T>): void {\n for (const source of cell._primitiveCandidates.values()) {\n notifySelectorSource(source);\n }\n for (const source of cell._objectCandidateSources) {\n notifySelectorSource(source);\n }\n}\n\nfunction notifySelectorValueChange<T>(\n cell: SelectorCell<T>,\n prevValue: T,\n nextValue: T\n): void {\n if (!isDefaultSelectorEquals(cell._equals)) {\n notifyAllSelectorSources(cell);\n return;\n }\n\n if (!Object.is(prevValue, nextValue)) {\n notifySelectorSource(getCandidateSource(cell, prevValue));\n notifySelectorSource(getCandidateSource(cell, nextValue));\n }\n}\n\nfunction recomputeSelectorCell<T>(\n cell: SelectorCell<T>,\n notifyDownstream: boolean\n): T {\n if (!cell._dirty && cell._hasValue) {\n return cell._value;\n }\n\n if (cell._evaluating) {\n throw new Error('selector() cannot read itself recursively');\n }\n\n cell._evaluating = true;\n cell._dirty = false;\n cell._pendingDependencySources = new Set();\n\n const prevSources = cell._sources;\n const hadValue = cell._hasValue;\n const prevValue = cell._value;\n let nextValue: T;\n\n try {\n nextValue = withDerivedReadTracking(cell, cell._source);\n } catch (error) {\n cell._dirty = true;\n cell._pendingDependencySources = undefined;\n throw error;\n } finally {\n cell._evaluating = false;\n }\n\n const nextSources = cell._pendingDependencySources ?? new Set();\n cell._pendingDependencySources = undefined;\n syncDerivedDependencySubscriptions(cell, prevSources, nextSources);\n cell._sources = nextSources;\n\n const valueChanged = !cell._hasValue || !cell._equals(prevValue, nextValue);\n cell._hasValue = true;\n cell._value = nextValue;\n\n if (valueChanged && notifyDownstream && hadValue) {\n notifySelectorValueChange(cell, prevValue, nextValue);\n }\n\n return cell._value;\n}\n\nfunction createSelectorCell<T>(\n instance: ComponentInstance,\n hookIndex: number,\n source: () => T,\n equals: SelectorEquals<T>\n): SelectorCell<T> {\n const cell = function selectorPredicate(candidate: T): boolean {\n const sourceRef = getCandidateSource(cell as SelectorCell<T>, candidate);\n recordReadableRead(sourceRef);\n incrementPerfMetric('selectorCandidateReads');\n const current = recomputeSelectorCell(\n cell as SelectorCell<T>,\n (cell as SelectorCell<T>)._scheduled\n );\n return (cell as SelectorCell<T>)._equals(current, candidate);\n } as SelectorCell<T>;\n\n cell._owner = instance;\n cell._hookIndex = hookIndex;\n cell._source = source;\n cell._equals = equals;\n cell._value = undefined as T;\n cell._hasValue = false;\n cell._dirty = true;\n cell._scheduled = false;\n cell._evaluating = false;\n cell._sources = new Set();\n cell._primitiveCandidates = new Map();\n cell._objectCandidates = new WeakMap();\n cell._objectCandidateSources = new Set();\n cell._markDirty = () => {\n markSelectorCellDirty(cell as unknown as SelectorCell<unknown>);\n };\n cell._cleanup = () => {\n cell._scheduled = false;\n cell._dirty = false;\n cell._hasValue = false;\n dirtySelectorCells.delete(cell as unknown as SelectorCell<unknown>);\n clearDerivedDependencySubscriptions(cell, cell._sources);\n for (const sourceRef of cell._primitiveCandidates.values()) {\n sourceRef._readers?.clear();\n sourceRef._derivedSubscribers?.clear();\n }\n for (const sourceRef of cell._objectCandidateSources) {\n sourceRef._readers?.clear();\n sourceRef._derivedSubscribers?.clear();\n }\n cell._primitiveCandidates.clear();\n cell._objectCandidateSources.clear();\n };\n\n (instance.cleanupFns ??= []).push(() => {\n cell._cleanup();\n selectorCells.get(instance)?.delete(hookIndex);\n });\n\n return cell;\n}\n\nfunction getOrCreateSelectorCell<T>(\n instance: ComponentInstance,\n hookIndex: number,\n source: () => T,\n equals: SelectorEquals<T>\n): SelectorCell<T> {\n const store = getSelectorStore(instance);\n const existing = store.get(hookIndex) as SelectorCell<T> | undefined;\n if (existing) {\n existing._source = source;\n existing._equals = equals;\n existing._dirty = true;\n return existing;\n }\n\n const created = createSelectorCell(instance, hookIndex, source, equals);\n store.set(hookIndex, created as unknown as SelectorCell<unknown>);\n return created;\n}\n\nexport function selector<T>(\n source: () => T,\n equals: SelectorEquals<T> = Object.is\n): Selector<T> {\n markReadableUsage(source);\n\n const instance = getCurrentInstance();\n if (!instance) {\n throw new Error(\n 'selector() can only be called during component render execution. ' +\n 'Move selector() calls to the top level of your component function.'\n );\n }\n\n const hookIndex = claimHookIndex(instance, 'selector');\n const cell = getOrCreateSelectorCell(instance, hookIndex, source, equals);\n recomputeSelectorCell(cell, false);\n return cell;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
let bridge = {
|
|
2
|
+
getCurrentSSRContext() {
|
|
3
|
+
return null;
|
|
4
|
+
},
|
|
5
|
+
throwSSRDataMissing() {
|
|
6
|
+
throw new Error("[Askr] SSR data missing (SSR bridge not installed). If you are rendering on the server, ensure you are using the askr SSR entrypoints.");
|
|
7
|
+
},
|
|
8
|
+
getCurrentRenderData() {
|
|
9
|
+
return null;
|
|
10
|
+
},
|
|
11
|
+
getNextKey() {
|
|
12
|
+
throw new Error("[Askr] getNextKey() called outside SSR render phase (SSR bridge not installed).");
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
function installSSRBridge(next) {
|
|
16
|
+
bridge = next;
|
|
17
|
+
}
|
|
18
|
+
function getSSRBridge() {
|
|
19
|
+
return bridge;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { getSSRBridge, installSSRBridge };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=ssr-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssr-bridge.js","names":[],"sources":["../../src/runtime/ssr-bridge.ts"],"sourcesContent":["import type { RenderContext } from '../common/ssr';\n\nexport type SSRBridge = {\n getCurrentSSRContext(): RenderContext | null;\n throwSSRDataMissing(): never;\n\n // Deterministic SSR render-phase data lookup\n getCurrentRenderData(): Record<string, unknown> | null;\n getNextKey(): string;\n};\n\nconst defaultBridge: SSRBridge = {\n getCurrentSSRContext() {\n return null;\n },\n throwSSRDataMissing() {\n throw new Error(\n '[Askr] SSR data missing (SSR bridge not installed). ' +\n 'If you are rendering on the server, ensure you are using the askr SSR entrypoints.'\n );\n },\n getCurrentRenderData() {\n return null;\n },\n getNextKey() {\n throw new Error(\n '[Askr] getNextKey() called outside SSR render phase (SSR bridge not installed).'\n );\n },\n};\n\nlet bridge: SSRBridge = defaultBridge;\n\nexport function installSSRBridge(next: SSRBridge): void {\n bridge = next;\n}\n\nexport function getSSRBridge(): SSRBridge {\n return bridge;\n}\n"],"mappings":"AA+BA,IAAI,SAAoB;CAnBtB,uBAAuB;AACrB,SAAO;;CAET,sBAAsB;AACpB,QAAM,IAAI,MACR,yIAED;;CAEH,uBAAuB;AACrB,SAAO;;CAET,aAAa;AACX,QAAM,IAAI,MACR,kFACD;;CAImB;AAExB,SAAgB,iBAAiB,MAAuB;AACtD,UAAS;;AAGX,SAAgB,eAA0B;AACxC,QAAO"}
|