@askrjs/askr 0.0.47 → 0.0.49
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/dist/benchmark.js +6 -6
- package/dist/benchmark.js.map +1 -1
- package/dist/boot/hydration.js +140 -0
- package/dist/boot/hydration.js.map +1 -0
- package/dist/boot/index.d.ts +3 -56
- package/dist/boot/index.d.ts.map +1 -1
- package/dist/boot/index.js +62 -410
- package/dist/boot/index.js.map +1 -1
- package/dist/boot/root-lifecycle.d.ts +15 -0
- package/dist/boot/root-lifecycle.d.ts.map +1 -0
- package/dist/boot/root-lifecycle.js +205 -0
- package/dist/boot/root-lifecycle.js.map +1 -0
- package/dist/boot/route-startup.js +45 -0
- package/dist/boot/route-startup.js.map +1 -0
- package/dist/boot/types.d.ts +62 -0
- package/dist/boot/types.d.ts.map +1 -0
- package/dist/common/component.d.ts +3 -1
- package/dist/common/component.d.ts.map +1 -1
- package/dist/common/jsx.d.ts +1 -1
- package/dist/common/jsx.d.ts.map +1 -1
- package/dist/common/jsx.js.map +1 -1
- package/dist/common/props.d.ts +1 -1
- package/dist/common/render-context.js +55 -0
- package/dist/common/render-context.js.map +1 -0
- package/dist/common/router.d.ts +5 -1
- package/dist/common/router.d.ts.map +1 -1
- package/dist/common/ssr.d.ts +1 -1
- package/dist/common/ssr.js.map +1 -1
- package/dist/common/vnode.d.ts +5 -4
- package/dist/common/vnode.d.ts.map +1 -1
- package/dist/common/vnode.js.map +1 -1
- package/dist/components/error-boundary.d.ts +1 -1
- package/dist/components/error-boundary.js +2 -1
- package/dist/components/error-boundary.js.map +1 -1
- package/dist/components/link.js.map +1 -1
- package/dist/control/for.js +2 -1
- package/dist/control/for.js.map +1 -1
- package/dist/data/data-runtime.d.ts +28 -0
- package/dist/data/data-runtime.d.ts.map +1 -0
- package/dist/data/data-runtime.js +114 -0
- package/dist/data/data-runtime.js.map +1 -0
- package/dist/data/index.d.ts +6 -142
- package/dist/data/index.js +5 -539
- package/dist/data/invalidation.d.ts +9 -0
- package/dist/data/invalidation.d.ts.map +1 -0
- package/dist/data/invalidation.js +27 -0
- package/dist/data/invalidation.js.map +1 -0
- package/dist/data/mutation-cell.d.ts +28 -0
- package/dist/data/mutation-cell.d.ts.map +1 -0
- package/dist/data/mutation-cell.js +132 -0
- package/dist/data/mutation-cell.js.map +1 -0
- package/dist/data/query-cell.d.ts +46 -0
- package/dist/data/query-cell.d.ts.map +1 -0
- package/dist/data/query-cell.js +290 -0
- package/dist/data/query-cell.js.map +1 -0
- package/dist/data/query-key.js +42 -0
- package/dist/data/query-key.js.map +1 -0
- package/dist/data/shared.js +20 -0
- package/dist/data/shared.js.map +1 -0
- package/dist/data/types.d.ts +161 -0
- package/dist/data/types.d.ts.map +1 -0
- package/dist/foundations/icon/icon.d.ts.map +1 -1
- package/dist/foundations/icon/icon.js.map +1 -1
- package/dist/foundations/structures/portal.d.ts +1 -1
- package/dist/foundations/structures/portal.d.ts.map +1 -1
- package/dist/foundations/structures/portal.js +2 -1
- package/dist/foundations/structures/portal.js.map +1 -1
- package/dist/fx/fx.d.ts +1 -1
- package/dist/fx/fx.js +5 -4
- package/dist/fx/fx.js.map +1 -1
- package/dist/fx/timing.d.ts.map +1 -1
- package/dist/fx/timing.js +10 -6
- package/dist/fx/timing.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/jsx/index.d.ts +2 -1
- package/dist/jsx/index.js +3 -2
- package/dist/jsx/types.d.ts +2 -0
- package/dist/jsx/types.js +2 -1
- package/dist/jsx-runtime2.d.ts +2 -1
- package/dist/jsx-runtime2.js +3 -2
- package/dist/renderer/attributes.js +231 -0
- package/dist/renderer/attributes.js.map +1 -0
- package/dist/renderer/boundaries.js +266 -0
- package/dist/renderer/boundaries.js.map +1 -0
- package/dist/renderer/child-shape.js +85 -0
- package/dist/renderer/child-shape.js.map +1 -0
- package/dist/renderer/children.js +3 -2
- package/dist/renderer/children.js.map +1 -1
- package/dist/renderer/cleanup.js +2 -1
- package/dist/renderer/cleanup.js.map +1 -1
- package/dist/renderer/component-host-cleanup.js +68 -0
- package/dist/renderer/component-host-cleanup.js.map +1 -0
- package/dist/renderer/component-host-instances.js +65 -0
- package/dist/renderer/component-host-instances.js.map +1 -0
- package/dist/renderer/component-host.js +247 -0
- package/dist/renderer/component-host.js.map +1 -0
- package/dist/renderer/dom-host.js +13 -0
- package/dist/renderer/dom-host.js.map +1 -0
- package/dist/renderer/dom-internal.js +185 -0
- package/dist/renderer/dom-internal.js.map +1 -0
- package/dist/renderer/dom.js +9 -2356
- package/dist/renderer/element-children.js +279 -0
- package/dist/renderer/element-children.js.map +1 -0
- package/dist/renderer/env.js +2 -1
- package/dist/renderer/error-boundary-dom.js +29 -0
- package/dist/renderer/error-boundary-dom.js.map +1 -0
- package/dist/renderer/evaluate-dom-range.js +85 -0
- package/dist/renderer/evaluate-dom-range.js.map +1 -0
- package/dist/renderer/evaluate-reconcile.js +281 -0
- package/dist/renderer/evaluate-reconcile.js.map +1 -0
- package/dist/renderer/evaluate.js +13 -399
- package/dist/renderer/evaluate.js.map +1 -1
- package/dist/renderer/fastpath.js +6 -5
- package/dist/renderer/fastpath.js.map +1 -1
- package/dist/renderer/for-commit-dom-map.js +83 -0
- package/dist/renderer/for-commit-dom-map.js.map +1 -0
- package/dist/renderer/for-commit-removal.js +36 -0
- package/dist/renderer/for-commit-removal.js.map +1 -0
- package/dist/renderer/for-commit-reorder.js +89 -0
- package/dist/renderer/for-commit-reorder.js.map +1 -0
- package/dist/renderer/for-commit.js +6 -188
- package/dist/renderer/for-commit.js.map +1 -1
- package/dist/renderer/index.js +28 -16
- package/dist/renderer/index.js.map +1 -1
- package/dist/renderer/keyed-children.js +32 -0
- package/dist/renderer/keyed-children.js.map +1 -0
- package/dist/renderer/keyed.js +2 -15
- package/dist/renderer/keyed.js.map +1 -1
- package/dist/renderer/namespaces.js +23 -0
- package/dist/renderer/namespaces.js.map +1 -0
- package/dist/renderer/prop-bindings.js +280 -0
- package/dist/renderer/prop-bindings.js.map +1 -0
- package/dist/renderer/reactive-child-dom.js +133 -0
- package/dist/renderer/reactive-child-dom.js.map +1 -0
- package/dist/renderer/reactive-child-sources.js +184 -0
- package/dist/renderer/reactive-child-sources.js.map +1 -0
- package/dist/renderer/reactive-children.js +294 -0
- package/dist/renderer/reactive-children.js.map +1 -0
- package/dist/renderer/reconcile-commit.js +38 -0
- package/dist/renderer/reconcile-commit.js.map +1 -0
- package/dist/renderer/reconcile-fastpaths.js +106 -0
- package/dist/renderer/reconcile-fastpaths.js.map +1 -0
- package/dist/renderer/reconcile-resolution.js +187 -0
- package/dist/renderer/reconcile-resolution.js.map +1 -0
- package/dist/renderer/reconcile.js +9 -371
- package/dist/renderer/reconcile.js.map +1 -1
- package/dist/renderer/retained-element-rollback.js +276 -0
- package/dist/renderer/retained-element-rollback.js.map +1 -0
- package/dist/renderer/stable-patch.js +82 -0
- package/dist/renderer/stable-patch.js.map +1 -0
- package/dist/renderer/static-reuse.js +96 -0
- package/dist/renderer/static-reuse.js.map +1 -0
- package/dist/renderer/types.js +2 -1
- package/dist/renderer/utils.js +4 -4
- package/dist/renderer/utils.js.map +1 -1
- package/dist/resources/index.d.ts +3 -2
- package/dist/resources/index.js +5 -2
- package/dist/router/access.js +36 -0
- package/dist/router/access.js.map +1 -0
- package/dist/router/activity.d.ts +10 -0
- package/dist/router/activity.d.ts.map +1 -0
- package/dist/router/activity.js +89 -0
- package/dist/router/activity.js.map +1 -0
- package/dist/router/authoring.d.ts +22 -0
- package/dist/router/authoring.d.ts.map +1 -0
- package/dist/router/authoring.js +198 -0
- package/dist/router/authoring.js.map +1 -0
- package/dist/router/index.d.ts +12 -4
- package/dist/router/index.js +9 -2
- package/dist/router/internal-types.d.ts +31 -0
- package/dist/router/internal-types.d.ts.map +1 -0
- package/dist/router/lazy.d.ts +19 -0
- package/dist/router/lazy.d.ts.map +1 -0
- package/dist/router/lazy.js +52 -0
- package/dist/router/lazy.js.map +1 -0
- package/dist/router/manifest.d.ts +10 -0
- package/dist/router/manifest.d.ts.map +1 -0
- package/dist/router/manifest.js +49 -0
- package/dist/router/manifest.js.map +1 -0
- package/dist/router/navigate.d.ts +4 -33
- package/dist/router/navigate.d.ts.map +1 -1
- package/dist/router/navigate.js +17 -414
- package/dist/router/navigate.js.map +1 -1
- package/dist/router/navigation-registry.d.ts +32 -0
- package/dist/router/navigation-registry.d.ts.map +1 -0
- package/dist/router/navigation-registry.js +105 -0
- package/dist/router/navigation-registry.js.map +1 -0
- package/dist/router/navigation-scroll.d.ts +14 -0
- package/dist/router/navigation-scroll.d.ts.map +1 -0
- package/dist/router/navigation-scroll.js +93 -0
- package/dist/router/navigation-scroll.js.map +1 -0
- package/dist/router/navigation-targets.d.ts +31 -0
- package/dist/router/navigation-targets.d.ts.map +1 -0
- package/dist/router/navigation-targets.js +253 -0
- package/dist/router/navigation-targets.js.map +1 -0
- package/dist/router/policy.d.ts +7 -1
- package/dist/router/policy.d.ts.map +1 -1
- package/dist/router/policy.js +27 -9
- package/dist/router/policy.js.map +1 -1
- package/dist/router/rendering.d.ts +10 -0
- package/dist/router/rendering.d.ts.map +1 -0
- package/dist/router/rendering.js +45 -0
- package/dist/router/rendering.js.map +1 -0
- package/dist/router/resolution.d.ts +17 -0
- package/dist/router/resolution.d.ts.map +1 -0
- package/dist/router/resolution.js +253 -0
- package/dist/router/resolution.js.map +1 -0
- package/dist/router/route-query.d.ts +17 -0
- package/dist/router/route-query.d.ts.map +1 -0
- package/dist/router/route-query.js +47 -0
- package/dist/router/route-query.js.map +1 -0
- package/dist/router/route.d.ts +8 -149
- package/dist/router/route.js +8 -854
- package/dist/router/store.d.ts +50 -0
- package/dist/router/store.d.ts.map +1 -0
- package/dist/router/store.js +171 -0
- package/dist/router/store.js.map +1 -0
- package/dist/runtime/access.js +45 -0
- package/dist/runtime/access.js.map +1 -0
- package/dist/runtime/child-scope.d.ts +1 -1
- package/dist/runtime/child-scope.js +4 -1
- package/dist/runtime/child-scope.js.map +1 -1
- package/dist/runtime/component-cleanup.d.ts +16 -0
- package/dist/runtime/component-cleanup.d.ts.map +1 -0
- package/dist/runtime/component-cleanup.js +70 -0
- package/dist/runtime/component-cleanup.js.map +1 -0
- package/dist/runtime/component-commit.js +165 -0
- package/dist/runtime/component-commit.js.map +1 -0
- package/dist/runtime/component-contracts.js +5 -0
- package/dist/runtime/component-facade.d.ts +5 -0
- package/dist/runtime/component-facade.js +4 -0
- package/dist/runtime/component-internal.d.ts +100 -0
- package/dist/runtime/component-internal.d.ts.map +1 -0
- package/dist/runtime/component-internal.js +219 -0
- package/dist/runtime/component-internal.js.map +1 -0
- package/dist/runtime/component-lifecycle.d.ts +49 -0
- package/dist/runtime/component-lifecycle.d.ts.map +1 -0
- package/dist/runtime/component-lifecycle.js +176 -0
- package/dist/runtime/component-lifecycle.js.map +1 -0
- package/dist/runtime/component-scope.d.ts +55 -0
- package/dist/runtime/component-scope.d.ts.map +1 -0
- package/dist/runtime/component-scope.js +154 -0
- package/dist/runtime/component-scope.js.map +1 -0
- package/dist/runtime/component.d.ts +4 -152
- package/dist/runtime/component.js +4 -692
- package/dist/runtime/context.d.ts +1 -1
- package/dist/runtime/context.js +6 -4
- package/dist/runtime/context.js.map +1 -1
- package/dist/runtime/control.d.ts +3 -3
- package/dist/runtime/control.js +2 -1
- package/dist/runtime/control.js.map +1 -1
- package/dist/runtime/derive.d.ts.map +1 -1
- package/dist/runtime/derive.js +6 -5
- package/dist/runtime/derive.js.map +1 -1
- package/dist/runtime/effect.d.ts +1 -1
- package/dist/runtime/effect.d.ts.map +1 -1
- package/dist/runtime/effect.js +2 -2
- package/dist/runtime/effect.js.map +1 -1
- package/dist/runtime/events.js +3 -3
- package/dist/runtime/events.js.map +1 -1
- package/dist/runtime/fastlane.js +13 -27
- package/dist/runtime/fastlane.js.map +1 -1
- package/dist/runtime/for-bench.d.ts +1 -1
- package/dist/runtime/for-bench.js +1 -4
- package/dist/runtime/for-bench.js.map +1 -1
- package/dist/runtime/for-internal.d.ts +43 -0
- package/dist/runtime/for-internal.d.ts.map +1 -0
- package/dist/runtime/for-internal.js +98 -0
- package/dist/runtime/for-internal.js.map +1 -0
- package/dist/runtime/for-reconcile.d.ts +8 -0
- package/dist/runtime/for-reconcile.d.ts.map +1 -0
- package/dist/runtime/for-reconcile.js +389 -0
- package/dist/runtime/for-reconcile.js.map +1 -0
- package/dist/runtime/for-scopes.d.ts +26 -0
- package/dist/runtime/for-scopes.d.ts.map +1 -0
- package/dist/runtime/for-scopes.js +160 -0
- package/dist/runtime/for-scopes.js.map +1 -0
- package/dist/runtime/for-signals.d.ts +30 -0
- package/dist/runtime/for-signals.d.ts.map +1 -0
- package/dist/runtime/for-signals.js +139 -0
- package/dist/runtime/for-signals.js.map +1 -0
- package/dist/runtime/for.d.ts +4 -66
- package/dist/runtime/for.js +5 -773
- package/dist/runtime/lifecycle-operations.d.ts +31 -0
- package/dist/runtime/lifecycle-operations.d.ts.map +1 -0
- package/dist/runtime/lifecycle-operations.js +195 -0
- package/dist/runtime/lifecycle-operations.js.map +1 -0
- package/dist/runtime/operations.d.ts +3 -40
- package/dist/runtime/operations.js +2 -357
- package/dist/runtime/readable.d.ts +2 -3
- package/dist/runtime/readable.d.ts.map +1 -1
- package/dist/runtime/readable.js +6 -5
- package/dist/runtime/readable.js.map +1 -1
- package/dist/runtime/resource-cell.js +2 -2
- package/dist/runtime/resource-cell.js.map +1 -1
- package/dist/runtime/resource-operation.d.ts +13 -0
- package/dist/runtime/resource-operation.d.ts.map +1 -0
- package/dist/runtime/resource-operation.js +170 -0
- package/dist/runtime/resource-operation.js.map +1 -0
- package/dist/runtime/runtime.d.ts +42 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +59 -0
- package/dist/runtime/runtime.js.map +1 -0
- package/dist/runtime/scheduler.d.ts +5 -1
- package/dist/runtime/scheduler.d.ts.map +1 -1
- package/dist/runtime/scheduler.js +17 -17
- package/dist/runtime/scheduler.js.map +1 -1
- package/dist/runtime/selector.js +4 -3
- package/dist/runtime/selector.js.map +1 -1
- package/dist/runtime/snapshot-source.d.ts +1 -1
- package/dist/runtime/snapshot-source.js +1 -1
- package/dist/runtime/state.js +2 -1
- package/dist/runtime/state.js.map +1 -1
- package/dist/ssg/batch-render.js +2 -1
- package/dist/ssg/batch-render.js.map +1 -1
- package/dist/ssg/create-static-gen.d.ts +9 -3
- package/dist/ssg/create-static-gen.d.ts.map +1 -1
- package/dist/ssg/create-static-gen.js +12 -99
- package/dist/ssg/create-static-gen.js.map +1 -1
- package/dist/ssg/generation-plan.js +70 -0
- package/dist/ssg/generation-plan.js.map +1 -0
- package/dist/ssg/incremental-manifest.js +1 -1
- package/dist/ssg/static-routes.js +101 -0
- package/dist/ssg/static-routes.js.map +1 -0
- package/dist/ssg/types.d.ts +15 -7
- package/dist/ssg/types.d.ts.map +1 -1
- package/dist/ssr/boundaries.js +113 -0
- package/dist/ssr/boundaries.js.map +1 -0
- package/dist/ssr/component-runtime.js +111 -0
- package/dist/ssr/component-runtime.js.map +1 -0
- package/dist/ssr/context.d.ts +3 -1
- package/dist/ssr/context.d.ts.map +1 -1
- package/dist/ssr/context.js +9 -2
- package/dist/ssr/context.js.map +1 -1
- package/dist/ssr/errors.d.ts +2 -0
- package/dist/ssr/errors.js +11 -1
- package/dist/ssr/errors.js.map +1 -1
- package/dist/ssr/escape.js +3 -3
- package/dist/ssr/escape.js.map +1 -1
- package/dist/ssr/hydration-data.js +10 -0
- package/dist/ssr/hydration-data.js.map +1 -0
- package/dist/ssr/hydration-verify.d.ts +12 -0
- package/dist/ssr/hydration-verify.d.ts.map +1 -0
- package/dist/ssr/hydration-verify.js +144 -0
- package/dist/ssr/hydration-verify.js.map +1 -0
- package/dist/ssr/index-internal.d.ts +15 -0
- package/dist/ssr/index-internal.d.ts.map +1 -0
- package/dist/ssr/index-internal.js +19 -0
- package/dist/ssr/index-internal.js.map +1 -0
- package/dist/ssr/index.d.ts +5 -57
- package/dist/ssr/index.js +3 -738
- package/dist/ssr/render-keys.js +9 -32
- package/dist/ssr/render-keys.js.map +1 -1
- package/dist/ssr/render-resolved.d.ts +1 -1
- package/dist/ssr/render-resolved.d.ts.map +1 -1
- package/dist/ssr/render-resolved.js +4 -2
- package/dist/ssr/render-resolved.js.map +1 -1
- package/dist/ssr/render-sync.d.ts +21 -0
- package/dist/ssr/render-sync.d.ts.map +1 -0
- package/dist/ssr/render-sync.js +275 -0
- package/dist/ssr/render-sync.js.map +1 -0
- package/dist/ssr/route-policy-resolution.js +77 -0
- package/dist/ssr/route-policy-resolution.js.map +1 -0
- package/dist/ssr/route-render.d.ts +77 -0
- package/dist/ssr/route-render.d.ts.map +1 -0
- package/dist/ssr/route-render.js +119 -0
- package/dist/ssr/route-render.js.map +1 -0
- package/dist/ssr/sink.d.ts +26 -0
- package/dist/ssr/sink.d.ts.map +1 -0
- package/dist/ssr/types.d.ts +1 -0
- package/dist/ssr/types.d.ts.map +1 -1
- package/dist/ssr/verify-hydration.js.map +1 -1
- package/dist/testing/index.d.ts +1 -2
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/index.js.map +1 -1
- package/package.json +4 -3
- package/dist/data/index.d.ts.map +0 -1
- package/dist/data/index.js.map +0 -1
- package/dist/renderer/dom.js.map +0 -1
- package/dist/router/route.d.ts.map +0 -1
- package/dist/router/route.js.map +0 -1
- package/dist/runtime/component.d.ts.map +0 -1
- package/dist/runtime/component.js.map +0 -1
- package/dist/runtime/for.d.ts.map +0 -1
- package/dist/runtime/for.js.map +0 -1
- package/dist/runtime/operations.d.ts.map +0 -1
- package/dist/runtime/operations.js.map +0 -1
- package/dist/runtime/ssr-bridge.js +0 -24
- package/dist/runtime/ssr-bridge.js.map +0 -1
- package/dist/ssr/index.d.ts.map +0 -1
- package/dist/ssr/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive-child-dom.js","names":[],"sources":["../../src/renderer/reactive-child-dom.ts"],"sourcesContent":["import type { ChildScope } from '../runtime/child-scope';\nimport { syncControlBoundaryScopeDom } from './boundaries';\nimport { teardownNodeSubtree } from './cleanup';\nimport {\n createElementForNamespace,\n getParentNamespace,\n SVG_NAMESPACE,\n} from './namespaces';\nimport {\n collectReactiveChildBoundaryVNodes,\n isSingleRootReactiveChildBoundaryValue,\n} from './reactive-child-sources';\nimport type { VNode } from './types';\n\nexport interface ReactiveChildDOMHost {\n createDOMNode(node: unknown, parentNamespace?: string): Node | null;\n updateElementChildren(\n el: Element,\n children: VNode | VNode[] | undefined,\n forceUpdate?: boolean\n ): void;\n}\n\nexport type ReactiveChildBoundarySequenceEntry =\n | { kind: 'static'; nodes: Node[] }\n | { kind: 'dynamic'; scope: ChildScope; nodes: Node[] };\n\nexport function materializeReactiveChildBoundaryNodes(\n value: unknown,\n parentNamespace: string | undefined,\n host: ReactiveChildDOMHost\n): Node[] {\n const nodes: Node[] = [];\n const dom = host.createDOMNode(value, parentNamespace);\n if (!dom) {\n return nodes;\n }\n\n if (dom instanceof DocumentFragment) {\n for (let child = dom.firstChild; child; child = dom.firstChild) {\n nodes.push(child);\n dom.removeChild(child);\n }\n return nodes;\n }\n\n nodes.push(dom);\n return nodes;\n}\n\nexport function createReactiveChildBoundaryHost(el: Element): Element {\n const ownerDocument = el.ownerDocument;\n const parentNamespace = getParentNamespace(el);\n return parentNamespace === SVG_NAMESPACE\n ? createElementForNamespace('g', parentNamespace, ownerDocument)\n : createElementForNamespace('div', parentNamespace, ownerDocument);\n}\n\nexport function disposeReactiveChildBoundaryNodes(nodes: Node[]): void {\n for (const node of nodes) {\n if (node.parentNode) {\n node.parentNode.removeChild(node);\n }\n\n teardownNodeSubtree(node);\n }\n}\n\nexport function syncReactiveChildExpectedNodes(\n el: Element,\n expectedNodes: Node[]\n): void {\n const expectedNodeSet = new Set(expectedNodes);\n\n for (let node = el.firstChild; node; ) {\n const next = node.nextSibling;\n if (!expectedNodeSet.has(node)) {\n teardownNodeSubtree(node);\n el.removeChild(node);\n }\n node = next;\n }\n\n let anchor = el.firstChild;\n for (const node of expectedNodes) {\n if (node === anchor) {\n anchor = anchor.nextSibling;\n continue;\n }\n\n el.insertBefore(node, anchor);\n anchor = node.nextSibling;\n }\n}\n\nexport function commitReactiveChildBoundaryEntryNodes(\n el: Element,\n entry: { scope: ChildScope; nodes: Node[] },\n host: ReactiveChildDOMHost\n): Node[] {\n if (!entry.scope.needsDomUpdate) {\n return entry.nodes;\n }\n\n if (\n entry.scope.vnode === null ||\n entry.scope.vnode === undefined ||\n entry.scope.vnode === false\n ) {\n if (entry.nodes.length > 0) {\n disposeReactiveChildBoundaryNodes(entry.nodes);\n entry.nodes = [];\n }\n\n const dom = entry.scope.dom;\n if (dom?.parentNode === el) {\n teardownNodeSubtree(dom);\n el.removeChild(dom);\n }\n\n entry.scope.dom = undefined;\n entry.scope.needsDomUpdate = false;\n return entry.nodes;\n }\n\n if (!isSingleRootReactiveChildBoundaryValue(entry.scope.vnode)) {\n const nextChildren: VNode[] = [];\n collectReactiveChildBoundaryVNodes(entry.scope.vnode, nextChildren);\n\n const boundaryHost = createReactiveChildBoundaryHost(el);\n for (const node of entry.nodes) {\n boundaryHost.appendChild(node);\n }\n\n host.updateElementChildren(boundaryHost, nextChildren);\n\n const nextNodes = Array.from(boundaryHost.childNodes);\n\n entry.scope.dom = undefined;\n entry.scope.needsDomUpdate = false;\n entry.nodes = nextNodes;\n return nextNodes;\n }\n\n if (entry.nodes.length > 1) {\n disposeReactiveChildBoundaryNodes(entry.nodes);\n entry.nodes = [];\n entry.scope.dom = undefined;\n }\n\n const nextDom = syncControlBoundaryScopeDom(\n el,\n entry.scope,\n entry.scope.vnode ?? null\n );\n if (!nextDom) {\n entry.nodes = [];\n entry.scope.needsDomUpdate = false;\n return entry.nodes;\n }\n\n entry.nodes = [nextDom];\n entry.scope.needsDomUpdate = false;\n return entry.nodes;\n}\n\nexport function syncReactiveChildSequenceNodes(\n el: Element,\n entries: ReactiveChildBoundarySequenceEntry[],\n host: ReactiveChildDOMHost\n): void {\n const expectedNodes: Node[] = [];\n\n for (const entry of entries) {\n if (entry.kind === 'static') {\n expectedNodes.push(...entry.nodes);\n continue;\n }\n\n expectedNodes.push(\n ...commitReactiveChildBoundaryEntryNodes(el, entry, host)\n );\n }\n\n syncReactiveChildExpectedNodes(el, expectedNodes);\n}\n\nexport function syncReactiveScalarTextNodes(\n el: Element,\n slotValues: unknown[],\n values: string[],\n host: ReactiveChildDOMHost\n): void {\n const childNodes = el.childNodes;\n const canPatchInPlace = childNodes.length === values.length;\n\n if (canPatchInPlace) {\n let allText = true;\n for (let index = 0; index < childNodes.length; index += 1) {\n if (childNodes[index]?.nodeType !== Node.TEXT_NODE) {\n allText = false;\n break;\n }\n }\n\n if (allText) {\n for (let index = 0; index < values.length; index += 1) {\n const textNode = childNodes[index] as Text;\n if (textNode.data !== values[index]) {\n textNode.data = values[index];\n }\n }\n return;\n }\n }\n\n const boundaryHost = createReactiveChildBoundaryHost(el);\n for (let node = el.firstChild; node; ) {\n const next = node.nextSibling;\n boundaryHost.appendChild(node);\n node = next;\n }\n\n host.updateElementChildren(boundaryHost, slotValues as VNode[]);\n syncReactiveChildExpectedNodes(el, Array.from(boundaryHost.childNodes));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { _isDOMElement } from "../common/vnode.js";
|
|
2
|
+
import "./types.js";
|
|
3
|
+
import { isFragmentVNode, normalizeComponentChildren } from "./child-shape.js";
|
|
4
|
+
//#region src/renderer/reactive-child-sources.ts
|
|
5
|
+
function collectReactiveScalarSequenceValue(value, normalized) {
|
|
6
|
+
if (isFragmentVNode(value)) return collectReactiveScalarSequenceValue(value.props?.children ?? value.children, normalized);
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
for (const child of value) if (!collectReactiveScalarSequenceValue(child, normalized)) return false;
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
if (value === null || value === void 0 || value === false) return true;
|
|
12
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
13
|
+
normalized.push(String(value));
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
function collectReactiveScalarChildSource(children, slots, state) {
|
|
19
|
+
if (isFragmentVNode(children)) return collectReactiveScalarChildSource(children.props?.children ?? children.children, slots, state);
|
|
20
|
+
if (Array.isArray(children)) {
|
|
21
|
+
for (const child of children) if (!collectReactiveScalarChildSource(child, slots, state)) return false;
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
if (children === null || children === void 0 || children === false) return true;
|
|
25
|
+
if (typeof children === "function") {
|
|
26
|
+
slots.push({
|
|
27
|
+
kind: "dynamic",
|
|
28
|
+
compute: children
|
|
29
|
+
});
|
|
30
|
+
state.hasDynamic = true;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
if (typeof children === "string" || typeof children === "number") {
|
|
34
|
+
slots.push({
|
|
35
|
+
kind: "static",
|
|
36
|
+
value: String(children)
|
|
37
|
+
});
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
function getReactiveScalarChildSource(children) {
|
|
43
|
+
const slots = [];
|
|
44
|
+
const state = { hasDynamic: false };
|
|
45
|
+
if (!collectReactiveScalarChildSource(children, slots, state)) return null;
|
|
46
|
+
return state.hasDynamic ? slots : null;
|
|
47
|
+
}
|
|
48
|
+
function getSingleReactiveChildBoundarySource(children) {
|
|
49
|
+
if (isFragmentVNode(children)) return getSingleReactiveChildBoundarySource(children.props?.children ?? children.children);
|
|
50
|
+
if (Array.isArray(children)) {
|
|
51
|
+
if (children.length !== 1) return null;
|
|
52
|
+
return getSingleReactiveChildBoundarySource(children[0]);
|
|
53
|
+
}
|
|
54
|
+
if (typeof children === "function") return children;
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
function collectReactiveChildBoundarySequenceSource(children, slots, state) {
|
|
58
|
+
if (isFragmentVNode(children)) return collectReactiveChildBoundarySequenceSource(children.props?.children ?? children.children, slots, state);
|
|
59
|
+
if (Array.isArray(children)) {
|
|
60
|
+
for (const child of children) if (!collectReactiveChildBoundarySequenceSource(child, slots, state)) return false;
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
if (children === null || children === void 0 || children === false) return true;
|
|
64
|
+
if (typeof children === "function") {
|
|
65
|
+
slots.push({
|
|
66
|
+
kind: "dynamic",
|
|
67
|
+
compute: children
|
|
68
|
+
});
|
|
69
|
+
state.dynamicCount += 1;
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
if (typeof children === "string" || typeof children === "number") {
|
|
73
|
+
slots.push({
|
|
74
|
+
kind: "static-text",
|
|
75
|
+
value: String(children)
|
|
76
|
+
});
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (_isDOMElement(children)) {
|
|
80
|
+
slots.push({
|
|
81
|
+
kind: "static-node",
|
|
82
|
+
value: children
|
|
83
|
+
});
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
function getReactiveChildBoundarySequenceSource(children) {
|
|
89
|
+
const slots = [];
|
|
90
|
+
const state = { dynamicCount: 0 };
|
|
91
|
+
if (!collectReactiveChildBoundarySequenceSource(children, slots, state)) return null;
|
|
92
|
+
return state.dynamicCount >= 1 && slots.length > 1 ? slots : null;
|
|
93
|
+
}
|
|
94
|
+
function areReactiveChildBoundarySequenceSourcesEqual(previousSource, nextSource) {
|
|
95
|
+
if (!Array.isArray(previousSource) || previousSource.length !== nextSource.length) return false;
|
|
96
|
+
for (let index = 0; index < nextSource.length; index += 1) {
|
|
97
|
+
const previousSlot = previousSource[index];
|
|
98
|
+
const nextSlot = nextSource[index];
|
|
99
|
+
if (!previousSlot || previousSlot.kind !== nextSlot.kind) return false;
|
|
100
|
+
if (nextSlot.kind === "static-text") {
|
|
101
|
+
if (previousSlot.kind !== "static-text" || previousSlot.value !== nextSlot.value) return false;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (nextSlot.kind === "static-node") {
|
|
105
|
+
if (previousSlot.kind !== "static-node" || previousSlot.value !== nextSlot.value) return false;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (previousSlot.kind !== "dynamic" || previousSlot.compute !== nextSlot.compute) return false;
|
|
109
|
+
}
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
function canUpdateReactiveChildBoundarySequenceSource(previousSource, nextSource) {
|
|
113
|
+
if (!Array.isArray(previousSource) || previousSource.length !== nextSource.length) return false;
|
|
114
|
+
for (let index = 0; index < nextSource.length; index += 1) {
|
|
115
|
+
const previousSlot = previousSource[index];
|
|
116
|
+
const nextSlot = nextSource[index];
|
|
117
|
+
if (!previousSlot || previousSlot.kind !== nextSlot.kind) return false;
|
|
118
|
+
if (nextSlot.kind === "static-text") {
|
|
119
|
+
if (previousSlot.kind !== "static-text" || previousSlot.value !== nextSlot.value) return false;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (nextSlot.kind === "static-node") {
|
|
123
|
+
if (previousSlot.kind !== "static-node" || previousSlot.value !== nextSlot.value) return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
function areReactiveScalarChildSourcesEqual(previousSource, nextSource) {
|
|
129
|
+
if (!Array.isArray(previousSource) || previousSource.length !== nextSource.length) return false;
|
|
130
|
+
for (let index = 0; index < nextSource.length; index += 1) {
|
|
131
|
+
const previousSlot = previousSource[index];
|
|
132
|
+
const nextSlot = nextSource[index];
|
|
133
|
+
if (!previousSlot || previousSlot.kind !== nextSlot.kind) return false;
|
|
134
|
+
if (nextSlot.kind === "static") {
|
|
135
|
+
if (previousSlot.kind !== "static" || previousSlot.value !== nextSlot.value) return false;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (previousSlot.kind !== "dynamic" || previousSlot.compute !== nextSlot.compute) return false;
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
function normalizeReactiveScalarSequenceValues(values) {
|
|
143
|
+
const normalized = [];
|
|
144
|
+
for (const value of values) if (!collectReactiveScalarSequenceValue(value, normalized)) return null;
|
|
145
|
+
return normalized;
|
|
146
|
+
}
|
|
147
|
+
function normalizeOwnedReactiveTextValue(value) {
|
|
148
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
function collectReactiveChildValuesAsVNodes(values, children) {
|
|
152
|
+
for (const value of values) collectReactiveChildBoundaryVNodes(value, children);
|
|
153
|
+
}
|
|
154
|
+
function normalizeReactiveChildBoundaryVNode(value) {
|
|
155
|
+
if (!isFragmentVNode(value)) return value;
|
|
156
|
+
const children = normalizeComponentChildren(value);
|
|
157
|
+
if (children.length !== 1) return value;
|
|
158
|
+
return normalizeReactiveChildBoundaryVNode(children[0]);
|
|
159
|
+
}
|
|
160
|
+
function isSingleRootReactiveChildBoundaryValue(value) {
|
|
161
|
+
if (value === null || value === void 0 || value === false) return true;
|
|
162
|
+
if (Array.isArray(value)) return value.length === 1 && isSingleRootReactiveChildBoundaryValue(value[0]);
|
|
163
|
+
if (isFragmentVNode(value)) {
|
|
164
|
+
const children = normalizeComponentChildren(value);
|
|
165
|
+
return children.length === 1 && isSingleRootReactiveChildBoundaryValue(children[0]);
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
function collectReactiveChildBoundaryVNodes(value, children) {
|
|
170
|
+
if (value === null || value === void 0 || value === false) return;
|
|
171
|
+
if (Array.isArray(value)) {
|
|
172
|
+
for (const child of value) collectReactiveChildBoundaryVNodes(child, children);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (isFragmentVNode(value)) {
|
|
176
|
+
collectReactiveChildBoundaryVNodes(value.props?.children ?? value.children, children);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
children.push(value);
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
export { areReactiveChildBoundarySequenceSourcesEqual, areReactiveScalarChildSourcesEqual, canUpdateReactiveChildBoundarySequenceSource, collectReactiveChildBoundaryVNodes, collectReactiveChildValuesAsVNodes, getReactiveChildBoundarySequenceSource, getReactiveScalarChildSource, getSingleReactiveChildBoundarySource, isSingleRootReactiveChildBoundaryValue, normalizeOwnedReactiveTextValue, normalizeReactiveChildBoundaryVNode, normalizeReactiveScalarSequenceValues };
|
|
183
|
+
|
|
184
|
+
//# sourceMappingURL=reactive-child-sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive-child-sources.js","names":[],"sources":["../../src/renderer/reactive-child-sources.ts"],"sourcesContent":["import { _isDOMElement, type VNode } from './types';\nimport { isFragmentVNode, normalizeComponentChildren } from './child-shape';\n\nexport type ReactiveScalarChildSourceSlot =\n | { kind: 'static'; value: string }\n | { kind: 'dynamic'; compute: () => unknown };\n\nexport type ReactiveScalarChildSource = ReactiveScalarChildSourceSlot[];\n\nexport type ReactiveChildBoundarySequenceSource = Array<\n | { kind: 'static-text'; value: string }\n | { kind: 'static-node'; value: VNode }\n | { kind: 'dynamic'; compute: () => VNode }\n>;\n\nfunction collectReactiveScalarSequenceValue(\n value: unknown,\n normalized: string[]\n): boolean {\n if (isFragmentVNode(value)) {\n const fragmentChildren = value.props?.children ?? value.children;\n return collectReactiveScalarSequenceValue(fragmentChildren, normalized);\n }\n\n if (Array.isArray(value)) {\n for (const child of value) {\n if (!collectReactiveScalarSequenceValue(child, normalized)) {\n return false;\n }\n }\n return true;\n }\n\n if (value === null || value === undefined || value === false) {\n return true;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n normalized.push(String(value));\n return true;\n }\n\n return false;\n}\n\nfunction collectReactiveScalarChildSource(\n children: unknown,\n slots: ReactiveScalarChildSource,\n state: { hasDynamic: boolean }\n): boolean {\n if (isFragmentVNode(children)) {\n const fragmentChildren = children.props?.children ?? children.children;\n return collectReactiveScalarChildSource(fragmentChildren, slots, state);\n }\n\n if (Array.isArray(children)) {\n for (const child of children) {\n if (!collectReactiveScalarChildSource(child, slots, state)) {\n return false;\n }\n }\n return true;\n }\n\n if (children === null || children === undefined || children === false) {\n return true;\n }\n\n if (typeof children === 'function') {\n slots.push({ kind: 'dynamic', compute: children as () => unknown });\n state.hasDynamic = true;\n return true;\n }\n\n if (typeof children === 'string' || typeof children === 'number') {\n slots.push({ kind: 'static', value: String(children) });\n return true;\n }\n\n return false;\n}\n\nexport function getReactiveScalarChildSource(\n children: unknown\n): ReactiveScalarChildSource | null {\n const slots: ReactiveScalarChildSource = [];\n const state = { hasDynamic: false };\n\n if (!collectReactiveScalarChildSource(children, slots, state)) {\n return null;\n }\n\n return state.hasDynamic ? slots : null;\n}\n\nexport function getSingleReactiveChildBoundarySource(\n children: unknown\n): (() => VNode) | null {\n if (isFragmentVNode(children)) {\n const fragmentChildren = children.props?.children ?? children.children;\n return getSingleReactiveChildBoundarySource(fragmentChildren);\n }\n\n if (Array.isArray(children)) {\n if (children.length !== 1) {\n return null;\n }\n return getSingleReactiveChildBoundarySource(children[0]);\n }\n\n if (typeof children === 'function') {\n return children as () => VNode;\n }\n\n return null;\n}\n\nfunction collectReactiveChildBoundarySequenceSource(\n children: unknown,\n slots: ReactiveChildBoundarySequenceSource,\n state: { dynamicCount: number }\n): boolean {\n if (isFragmentVNode(children)) {\n const fragmentChildren = children.props?.children ?? children.children;\n return collectReactiveChildBoundarySequenceSource(\n fragmentChildren,\n slots,\n state\n );\n }\n\n if (Array.isArray(children)) {\n for (const child of children) {\n if (!collectReactiveChildBoundarySequenceSource(child, slots, state)) {\n return false;\n }\n }\n return true;\n }\n\n if (children === null || children === undefined || children === false) {\n return true;\n }\n\n if (typeof children === 'function') {\n slots.push({ kind: 'dynamic', compute: children as () => VNode });\n state.dynamicCount += 1;\n return true;\n }\n\n if (typeof children === 'string' || typeof children === 'number') {\n slots.push({ kind: 'static-text', value: String(children) });\n return true;\n }\n\n if (_isDOMElement(children)) {\n slots.push({ kind: 'static-node', value: children as VNode });\n return true;\n }\n\n return false;\n}\n\nexport function getReactiveChildBoundarySequenceSource(\n children: unknown\n): ReactiveChildBoundarySequenceSource | null {\n const slots: ReactiveChildBoundarySequenceSource = [];\n const state = { dynamicCount: 0 };\n\n if (!collectReactiveChildBoundarySequenceSource(children, slots, state)) {\n return null;\n }\n\n return state.dynamicCount >= 1 && slots.length > 1 ? slots : null;\n}\n\nexport function areReactiveChildBoundarySequenceSourcesEqual(\n previousSource: unknown,\n nextSource: ReactiveChildBoundarySequenceSource\n): boolean {\n if (\n !Array.isArray(previousSource) ||\n previousSource.length !== nextSource.length\n ) {\n return false;\n }\n\n for (let index = 0; index < nextSource.length; index += 1) {\n const previousSlot = previousSource[index] as\n | ReactiveChildBoundarySequenceSource[number]\n | undefined;\n const nextSlot = nextSource[index];\n\n if (!previousSlot || previousSlot.kind !== nextSlot.kind) {\n return false;\n }\n\n if (nextSlot.kind === 'static-text') {\n if (\n previousSlot.kind !== 'static-text' ||\n previousSlot.value !== nextSlot.value\n ) {\n return false;\n }\n continue;\n }\n\n if (nextSlot.kind === 'static-node') {\n if (\n previousSlot.kind !== 'static-node' ||\n previousSlot.value !== nextSlot.value\n ) {\n return false;\n }\n continue;\n }\n\n if (\n previousSlot.kind !== 'dynamic' ||\n previousSlot.compute !== nextSlot.compute\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function canUpdateReactiveChildBoundarySequenceSource(\n previousSource: unknown,\n nextSource: ReactiveChildBoundarySequenceSource\n): boolean {\n if (\n !Array.isArray(previousSource) ||\n previousSource.length !== nextSource.length\n ) {\n return false;\n }\n\n for (let index = 0; index < nextSource.length; index += 1) {\n const previousSlot = previousSource[index] as\n | ReactiveChildBoundarySequenceSource[number]\n | undefined;\n const nextSlot = nextSource[index];\n\n if (!previousSlot || previousSlot.kind !== nextSlot.kind) {\n return false;\n }\n\n if (nextSlot.kind === 'static-text') {\n if (\n previousSlot.kind !== 'static-text' ||\n previousSlot.value !== nextSlot.value\n ) {\n return false;\n }\n continue;\n }\n\n if (nextSlot.kind === 'static-node') {\n if (\n previousSlot.kind !== 'static-node' ||\n previousSlot.value !== nextSlot.value\n ) {\n return false;\n }\n }\n }\n\n return true;\n}\n\nexport function areReactiveScalarChildSourcesEqual(\n previousSource: unknown,\n nextSource: ReactiveScalarChildSource\n): boolean {\n if (\n !Array.isArray(previousSource) ||\n previousSource.length !== nextSource.length\n ) {\n return false;\n }\n\n for (let index = 0; index < nextSource.length; index += 1) {\n const previousSlot = previousSource[index] as\n | ReactiveScalarChildSourceSlot\n | undefined;\n const nextSlot = nextSource[index];\n\n if (!previousSlot || previousSlot.kind !== nextSlot.kind) {\n return false;\n }\n\n if (nextSlot.kind === 'static') {\n if (\n previousSlot.kind !== 'static' ||\n previousSlot.value !== nextSlot.value\n ) {\n return false;\n }\n continue;\n }\n\n if (\n previousSlot.kind !== 'dynamic' ||\n previousSlot.compute !== nextSlot.compute\n ) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function normalizeReactiveScalarSequenceValues(\n values: unknown[]\n): string[] | null {\n const normalized: string[] = [];\n\n for (const value of values) {\n if (!collectReactiveScalarSequenceValue(value, normalized)) {\n return null;\n }\n }\n\n return normalized;\n}\n\nexport function normalizeOwnedReactiveTextValue(value: unknown): string | null {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n\n return null;\n}\n\nexport function collectReactiveChildValuesAsVNodes(\n values: unknown[],\n children: VNode[]\n): void {\n for (const value of values) {\n collectReactiveChildBoundaryVNodes(value, children);\n }\n}\n\nexport function normalizeReactiveChildBoundaryVNode(value: VNode): VNode {\n if (!isFragmentVNode(value)) {\n return value;\n }\n\n const children = normalizeComponentChildren(value);\n if (children.length !== 1) {\n return value;\n }\n\n return normalizeReactiveChildBoundaryVNode(children[0] as VNode);\n}\n\nexport function isSingleRootReactiveChildBoundaryValue(\n value: unknown\n): boolean {\n if (value === null || value === undefined || value === false) {\n return true;\n }\n\n if (Array.isArray(value)) {\n return (\n value.length === 1 && isSingleRootReactiveChildBoundaryValue(value[0])\n );\n }\n\n if (isFragmentVNode(value)) {\n const children = normalizeComponentChildren(value);\n return (\n children.length === 1 &&\n isSingleRootReactiveChildBoundaryValue(children[0])\n );\n }\n\n return true;\n}\n\nexport function collectReactiveChildBoundaryVNodes(\n value: unknown,\n children: VNode[]\n): void {\n if (value === null || value === undefined || value === false) {\n return;\n }\n\n if (Array.isArray(value)) {\n for (const child of value) {\n collectReactiveChildBoundaryVNodes(child, children);\n }\n return;\n }\n\n if (isFragmentVNode(value)) {\n const fragmentChildren = value.props?.children ?? value.children;\n collectReactiveChildBoundaryVNodes(fragmentChildren, children);\n return;\n }\n\n children.push(value as VNode);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { getRuntimeEnv } from "../common/env.js";
|
|
2
|
+
import { logger } from "../dev/logger.js";
|
|
3
|
+
import { incDevCounter } from "../runtime/dev-namespace.js";
|
|
4
|
+
import { getCurrentInstance } from "../runtime/component-scope.js";
|
|
5
|
+
import "../runtime/component-contracts.js";
|
|
6
|
+
import { REACTIVE_CHILDREN_KEY, elementReactivePropsCleanup, teardownNodeSubtree } from "./cleanup.js";
|
|
7
|
+
import "./env.js";
|
|
8
|
+
import { createChildScope, disposeChildScope, rerenderChildScope } from "../runtime/child-scope.js";
|
|
9
|
+
import { getParentNamespace } from "./namespaces.js";
|
|
10
|
+
import { createFineGrainedEffect } from "../runtime/effect.js";
|
|
11
|
+
import { areReactiveChildBoundarySequenceSourcesEqual, areReactiveScalarChildSourcesEqual, canUpdateReactiveChildBoundarySequenceSource, collectReactiveChildValuesAsVNodes, getReactiveChildBoundarySequenceSource, getReactiveScalarChildSource, getSingleReactiveChildBoundarySource, normalizeOwnedReactiveTextValue, normalizeReactiveChildBoundaryVNode, normalizeReactiveScalarSequenceValues } from "./reactive-child-sources.js";
|
|
12
|
+
import { commitReactiveChildBoundaryEntryNodes, createReactiveChildBoundaryHost, disposeReactiveChildBoundaryNodes, materializeReactiveChildBoundaryNodes, syncReactiveChildExpectedNodes, syncReactiveChildSequenceNodes, syncReactiveScalarTextNodes } from "./reactive-child-dom.js";
|
|
13
|
+
//#region src/renderer/reactive-children.ts
|
|
14
|
+
let reactiveChildScopeId = 0;
|
|
15
|
+
function getOrCreateElementReactiveCleanupMap(el) {
|
|
16
|
+
let cleanupMap = elementReactivePropsCleanup.get(el);
|
|
17
|
+
if (!cleanupMap) {
|
|
18
|
+
cleanupMap = /* @__PURE__ */ new Map();
|
|
19
|
+
elementReactivePropsCleanup.set(el, cleanupMap);
|
|
20
|
+
}
|
|
21
|
+
return cleanupMap;
|
|
22
|
+
}
|
|
23
|
+
function trySyncScalarChildSequenceInPlace(el, children, host) {
|
|
24
|
+
const normalized = normalizeReactiveScalarSequenceValues(children);
|
|
25
|
+
if (!normalized) return false;
|
|
26
|
+
if (el.childNodes.length !== normalized.length) return false;
|
|
27
|
+
for (let index = 0; index < el.childNodes.length; index += 1) if (el.childNodes[index]?.nodeType !== Node.TEXT_NODE) return false;
|
|
28
|
+
syncReactiveScalarTextNodes(el, children, normalized, host);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function setupReactiveScalarChild(el, source, host) {
|
|
32
|
+
let currentSource = source;
|
|
33
|
+
if (source.length === 1 && source[0]?.kind === "dynamic") {
|
|
34
|
+
let ownedTextNode = el.childNodes.length === 1 && el.firstChild?.nodeType === Node.TEXT_NODE ? el.firstChild : null;
|
|
35
|
+
let effectHandle = createFineGrainedEffect({
|
|
36
|
+
lane: "reactive",
|
|
37
|
+
compute: () => {
|
|
38
|
+
const currentSlot = currentSource[0];
|
|
39
|
+
if (!currentSlot || currentSlot.kind !== "dynamic") throw new Error("[Askr] Direct reactive text bindings require a single dynamic slot.");
|
|
40
|
+
const rawValue = currentSlot.compute();
|
|
41
|
+
return normalizeOwnedReactiveTextValue(rawValue) ?? rawValue;
|
|
42
|
+
},
|
|
43
|
+
commit: (value) => {
|
|
44
|
+
const normalized = normalizeOwnedReactiveTextValue(value);
|
|
45
|
+
if (normalized === null) {
|
|
46
|
+
ownedTextNode = null;
|
|
47
|
+
host.updateElementChildren(el, value);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!ownedTextNode || el.childNodes.length !== 1 || el.firstChild !== ownedTextNode) {
|
|
51
|
+
host.updateElementChildren(el, normalized);
|
|
52
|
+
ownedTextNode = el.childNodes.length === 1 && el.firstChild?.nodeType === Node.TEXT_NODE ? el.firstChild : null;
|
|
53
|
+
}
|
|
54
|
+
if (!ownedTextNode) return;
|
|
55
|
+
if (ownedTextNode.data !== normalized) {
|
|
56
|
+
ownedTextNode.data = normalized;
|
|
57
|
+
incDevCounter("textNodeWrites");
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
onError: (err) => {
|
|
61
|
+
if (getRuntimeEnv().NODE_ENV !== "production") logger.warn("[Askr] Reactive child update failed:", err);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
cleanup: () => {
|
|
66
|
+
effectHandle?.cleanup();
|
|
67
|
+
effectHandle = null;
|
|
68
|
+
},
|
|
69
|
+
updateFn: (nextSource) => {
|
|
70
|
+
if (!effectHandle) return;
|
|
71
|
+
currentSource = nextSource;
|
|
72
|
+
effectHandle.updateCompute(() => {
|
|
73
|
+
const currentSlot = currentSource[0];
|
|
74
|
+
if (!currentSlot || currentSlot.kind !== "dynamic") throw new Error("[Askr] Direct reactive text bindings require a single dynamic slot.");
|
|
75
|
+
const rawValue = currentSlot.compute();
|
|
76
|
+
return normalizeOwnedReactiveTextValue(rawValue) ?? rawValue;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
let effectHandle = createFineGrainedEffect({
|
|
82
|
+
lane: "reactive",
|
|
83
|
+
compute: () => currentSource.map((slot) => slot.kind === "static" ? slot.value : slot.compute()),
|
|
84
|
+
commit: (values) => {
|
|
85
|
+
if (!Array.isArray(values)) throw new Error("[Askr] Reactive scalar children must evaluate to a slot array.");
|
|
86
|
+
const normalized = normalizeReactiveScalarSequenceValues(values);
|
|
87
|
+
if (normalized) {
|
|
88
|
+
syncReactiveScalarTextNodes(el, values, normalized, host);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const nextChildren = [];
|
|
92
|
+
collectReactiveChildValuesAsVNodes(values, nextChildren);
|
|
93
|
+
const boundaryHost = createReactiveChildBoundaryHost(el);
|
|
94
|
+
for (let node = el.firstChild; node;) {
|
|
95
|
+
const next = node.nextSibling;
|
|
96
|
+
boundaryHost.appendChild(node);
|
|
97
|
+
node = next;
|
|
98
|
+
}
|
|
99
|
+
host.updateElementChildren(boundaryHost, nextChildren);
|
|
100
|
+
syncReactiveChildExpectedNodes(el, Array.from(boundaryHost.childNodes));
|
|
101
|
+
},
|
|
102
|
+
equals: (previousValue, nextValue) => {
|
|
103
|
+
if (!Array.isArray(previousValue) || !Array.isArray(nextValue)) return false;
|
|
104
|
+
const previousNormalized = normalizeReactiveScalarSequenceValues(previousValue);
|
|
105
|
+
const nextNormalized = normalizeReactiveScalarSequenceValues(nextValue);
|
|
106
|
+
if (!previousNormalized || !nextNormalized) return false;
|
|
107
|
+
if (previousNormalized.length !== nextNormalized.length) return false;
|
|
108
|
+
for (let index = 0; index < previousNormalized.length; index += 1) if (previousNormalized[index] !== nextNormalized[index]) return false;
|
|
109
|
+
return true;
|
|
110
|
+
},
|
|
111
|
+
onError: (err) => {
|
|
112
|
+
if (getRuntimeEnv().NODE_ENV !== "production") logger.warn("[Askr] Reactive child update failed:", err);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return {
|
|
116
|
+
cleanup: () => {
|
|
117
|
+
effectHandle?.cleanup();
|
|
118
|
+
effectHandle = null;
|
|
119
|
+
},
|
|
120
|
+
updateFn: (nextSource) => {
|
|
121
|
+
if (!effectHandle) return;
|
|
122
|
+
currentSource = nextSource;
|
|
123
|
+
effectHandle.updateCompute(() => currentSource.map((slot) => slot.kind === "static" ? slot.value : slot.compute()));
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function setupReactiveChildBoundary(el, childFn, host) {
|
|
128
|
+
let currentChildFn = childFn;
|
|
129
|
+
const entry = {
|
|
130
|
+
scope: createChildScope(getCurrentInstance(), `__reactive-child__:${reactiveChildScopeId += 1}`, () => {
|
|
131
|
+
syncReactiveChildExpectedNodes(el, commitReactiveChildBoundaryEntryNodes(el, entry, host));
|
|
132
|
+
}),
|
|
133
|
+
nodes: []
|
|
134
|
+
};
|
|
135
|
+
entry.scope.render(() => normalizeReactiveChildBoundaryVNode(currentChildFn()));
|
|
136
|
+
syncReactiveChildExpectedNodes(el, commitReactiveChildBoundaryEntryNodes(el, entry, host));
|
|
137
|
+
return {
|
|
138
|
+
cleanup: () => {
|
|
139
|
+
const dom = entry.scope.dom;
|
|
140
|
+
const nodes = entry.nodes;
|
|
141
|
+
disposeChildScope(entry.scope);
|
|
142
|
+
entry.nodes = [];
|
|
143
|
+
if (nodes.length > 0) {
|
|
144
|
+
disposeReactiveChildBoundaryNodes(nodes);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (dom?.parentNode === el) {
|
|
148
|
+
teardownNodeSubtree(dom);
|
|
149
|
+
el.removeChild(dom);
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
updateFn: (nextValue) => {
|
|
153
|
+
currentChildFn = nextValue;
|
|
154
|
+
rerenderChildScope(entry.scope);
|
|
155
|
+
syncReactiveChildExpectedNodes(el, commitReactiveChildBoundaryEntryNodes(el, entry, host));
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function setupReactiveChildBoundarySequence(el, source, host) {
|
|
160
|
+
let currentSource = source;
|
|
161
|
+
const parentInstance = getCurrentInstance();
|
|
162
|
+
const entries = [];
|
|
163
|
+
const dynamicEntries = [];
|
|
164
|
+
if (!currentSource.some((slot) => slot.kind === "dynamic")) throw new Error("[Askr] Reactive child boundary sequence requires at least one dynamic slot.");
|
|
165
|
+
const syncSequence = () => {
|
|
166
|
+
syncReactiveChildSequenceNodes(el, entries, host);
|
|
167
|
+
};
|
|
168
|
+
const parentNamespace = getParentNamespace(el);
|
|
169
|
+
for (let index = 0; index < currentSource.length; index += 1) {
|
|
170
|
+
const slot = currentSource[index];
|
|
171
|
+
if (!slot) continue;
|
|
172
|
+
if (slot.kind === "static-text") {
|
|
173
|
+
entries.push({
|
|
174
|
+
kind: "static",
|
|
175
|
+
nodes: [document.createTextNode(slot.value)]
|
|
176
|
+
});
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (slot.kind === "static-node") {
|
|
180
|
+
entries.push({
|
|
181
|
+
kind: "static",
|
|
182
|
+
nodes: materializeReactiveChildBoundaryNodes(slot.value, parentNamespace, host)
|
|
183
|
+
});
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const dynamicEntry = {
|
|
187
|
+
kind: "dynamic",
|
|
188
|
+
scope: createChildScope(parentInstance, `__reactive-child-seq__:${reactiveChildScopeId += 1}`, syncSequence),
|
|
189
|
+
nodes: []
|
|
190
|
+
};
|
|
191
|
+
entries.push(dynamicEntry);
|
|
192
|
+
dynamicEntries.push({
|
|
193
|
+
index,
|
|
194
|
+
entry: dynamicEntry
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
for (const dynamicEntry of dynamicEntries) dynamicEntry.entry.scope.render(() => normalizeReactiveChildBoundaryVNode(currentSource[dynamicEntry.index].compute()));
|
|
198
|
+
syncSequence();
|
|
199
|
+
return {
|
|
200
|
+
cleanup: () => {
|
|
201
|
+
for (const dynamicEntry of dynamicEntries) {
|
|
202
|
+
const dom = dynamicEntry.entry.scope.dom;
|
|
203
|
+
const nodes = dynamicEntry.entry.nodes;
|
|
204
|
+
disposeChildScope(dynamicEntry.entry.scope);
|
|
205
|
+
if (nodes.length > 0) {
|
|
206
|
+
disposeReactiveChildBoundaryNodes(nodes);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (dom?.parentNode === el) {
|
|
210
|
+
teardownNodeSubtree(dom);
|
|
211
|
+
el.removeChild(dom);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
for (const entry of entries) if (entry.kind === "static") disposeReactiveChildBoundaryNodes(entry.nodes);
|
|
215
|
+
},
|
|
216
|
+
updateFn: (nextValue) => {
|
|
217
|
+
currentSource = nextValue;
|
|
218
|
+
for (const dynamicEntry of dynamicEntries) rerenderChildScope(dynamicEntry.entry.scope);
|
|
219
|
+
syncSequence();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function syncReactiveScalarChild(el, children, host) {
|
|
224
|
+
const reactiveChildSource = getReactiveScalarChildSource(children);
|
|
225
|
+
const reactiveChildBoundary = getSingleReactiveChildBoundarySource(children);
|
|
226
|
+
const reactiveChildBoundarySequence = getReactiveChildBoundarySequenceSource(children);
|
|
227
|
+
const existingReactiveEntry = elementReactivePropsCleanup.get(el)?.get(REACTIVE_CHILDREN_KEY);
|
|
228
|
+
if (!reactiveChildSource && !reactiveChildBoundary && !reactiveChildBoundarySequence) {
|
|
229
|
+
if (existingReactiveEntry) {
|
|
230
|
+
existingReactiveEntry.cleanup();
|
|
231
|
+
const cleanupMap = elementReactivePropsCleanup.get(el);
|
|
232
|
+
cleanupMap?.delete(REACTIVE_CHILDREN_KEY);
|
|
233
|
+
if (cleanupMap && cleanupMap.size === 0) elementReactivePropsCleanup.delete(el);
|
|
234
|
+
}
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
if (reactiveChildSource && !reactiveChildBoundarySequence) {
|
|
238
|
+
if (existingReactiveEntry && Array.isArray(existingReactiveEntry.fnRef) && areReactiveScalarChildSourcesEqual(existingReactiveEntry.fnRef, reactiveChildSource)) return true;
|
|
239
|
+
if (existingReactiveEntry?.updateFn && Array.isArray(existingReactiveEntry.fnRef)) {
|
|
240
|
+
existingReactiveEntry.updateFn(reactiveChildSource);
|
|
241
|
+
existingReactiveEntry.fnRef = reactiveChildSource;
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
existingReactiveEntry?.cleanup();
|
|
245
|
+
try {
|
|
246
|
+
const reactive = setupReactiveScalarChild(el, reactiveChildSource, host);
|
|
247
|
+
getOrCreateElementReactiveCleanupMap(el).set(REACTIVE_CHILDREN_KEY, {
|
|
248
|
+
cleanup: reactive.cleanup,
|
|
249
|
+
updateFn: (nextValue) => {
|
|
250
|
+
reactive.updateFn(nextValue);
|
|
251
|
+
},
|
|
252
|
+
fnRef: reactiveChildSource
|
|
253
|
+
});
|
|
254
|
+
return true;
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (!reactiveChildBoundary && !reactiveChildBoundarySequence) throw error;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (reactiveChildBoundarySequence) {
|
|
260
|
+
if (existingReactiveEntry && Array.isArray(existingReactiveEntry.fnRef) && areReactiveChildBoundarySequenceSourcesEqual(existingReactiveEntry.fnRef, reactiveChildBoundarySequence)) return true;
|
|
261
|
+
if (existingReactiveEntry?.updateFn && Array.isArray(existingReactiveEntry.fnRef) && canUpdateReactiveChildBoundarySequenceSource(existingReactiveEntry.fnRef, reactiveChildBoundarySequence)) {
|
|
262
|
+
existingReactiveEntry.updateFn(reactiveChildBoundarySequence);
|
|
263
|
+
existingReactiveEntry.fnRef = reactiveChildBoundarySequence;
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
existingReactiveEntry?.cleanup();
|
|
267
|
+
const reactive = setupReactiveChildBoundarySequence(el, reactiveChildBoundarySequence, host);
|
|
268
|
+
getOrCreateElementReactiveCleanupMap(el).set(REACTIVE_CHILDREN_KEY, {
|
|
269
|
+
cleanup: reactive.cleanup,
|
|
270
|
+
updateFn: reactive.updateFn,
|
|
271
|
+
fnRef: reactiveChildBoundarySequence
|
|
272
|
+
});
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
if (existingReactiveEntry?.fnRef === reactiveChildBoundary) return true;
|
|
276
|
+
if (existingReactiveEntry?.updateFn && !Array.isArray(existingReactiveEntry.fnRef)) {
|
|
277
|
+
existingReactiveEntry.updateFn(reactiveChildBoundary);
|
|
278
|
+
existingReactiveEntry.fnRef = reactiveChildBoundary;
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
existingReactiveEntry?.cleanup();
|
|
282
|
+
if (!reactiveChildBoundary) return false;
|
|
283
|
+
const reactive = setupReactiveChildBoundary(el, reactiveChildBoundary, host);
|
|
284
|
+
getOrCreateElementReactiveCleanupMap(el).set(REACTIVE_CHILDREN_KEY, {
|
|
285
|
+
cleanup: reactive.cleanup,
|
|
286
|
+
updateFn: reactive.updateFn,
|
|
287
|
+
fnRef: reactiveChildBoundary
|
|
288
|
+
});
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
export { syncReactiveScalarChild, trySyncScalarChildSequenceInPlace };
|
|
293
|
+
|
|
294
|
+
//# sourceMappingURL=reactive-children.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive-children.js","names":[],"sources":["../../src/renderer/reactive-children.ts"],"sourcesContent":["import { logger } from '../dev/logger';\nimport {\n createChildScope,\n disposeChildScope,\n rerenderChildScope,\n type ChildScope,\n} from '../runtime/child-scope';\nimport { getCurrentInstance } from '../runtime/component-contracts';\nimport { incDevCounter } from '../runtime/dev-namespace';\nimport {\n createFineGrainedEffect,\n type FineGrainedEffectHandle,\n} from '../runtime/effect';\nimport {\n elementReactivePropsCleanup,\n REACTIVE_CHILDREN_KEY,\n teardownNodeSubtree,\n type ReactivePropCleanupEntry,\n} from './cleanup';\nimport { getRuntimeEnv } from './env';\nimport { getParentNamespace } from './namespaces';\nimport type { VNode } from './types';\nimport {\n commitReactiveChildBoundaryEntryNodes,\n createReactiveChildBoundaryHost,\n disposeReactiveChildBoundaryNodes,\n materializeReactiveChildBoundaryNodes,\n syncReactiveChildExpectedNodes,\n syncReactiveChildSequenceNodes,\n syncReactiveScalarTextNodes,\n type ReactiveChildBoundarySequenceEntry,\n type ReactiveChildDOMHost,\n} from './reactive-child-dom';\nimport {\n areReactiveChildBoundarySequenceSourcesEqual,\n areReactiveScalarChildSourcesEqual,\n canUpdateReactiveChildBoundarySequenceSource,\n collectReactiveChildValuesAsVNodes,\n getReactiveChildBoundarySequenceSource,\n getReactiveScalarChildSource,\n getSingleReactiveChildBoundarySource,\n normalizeOwnedReactiveTextValue,\n normalizeReactiveChildBoundaryVNode,\n normalizeReactiveScalarSequenceValues,\n type ReactiveChildBoundarySequenceSource,\n type ReactiveScalarChildSource,\n} from './reactive-child-sources';\n\nexport type { ReactiveChildDOMHost } from './reactive-child-dom';\n\nlet reactiveChildScopeId = 0;\n\nfunction getOrCreateElementReactiveCleanupMap(\n el: Element\n): Map<string, ReactivePropCleanupEntry> {\n let cleanupMap = elementReactivePropsCleanup.get(el);\n if (!cleanupMap) {\n cleanupMap = new Map();\n elementReactivePropsCleanup.set(el, cleanupMap);\n }\n\n return cleanupMap;\n}\n\nexport function trySyncScalarChildSequenceInPlace(\n el: Element,\n children: unknown[],\n host: ReactiveChildDOMHost\n): boolean {\n const normalized = normalizeReactiveScalarSequenceValues(children);\n if (!normalized) {\n return false;\n }\n\n if (el.childNodes.length !== normalized.length) {\n return false;\n }\n\n for (let index = 0; index < el.childNodes.length; index += 1) {\n if (el.childNodes[index]?.nodeType !== Node.TEXT_NODE) {\n return false;\n }\n }\n\n syncReactiveScalarTextNodes(el, children, normalized, host);\n return true;\n}\n\nfunction setupReactiveScalarChild(\n el: Element,\n source: ReactiveScalarChildSource,\n host: ReactiveChildDOMHost\n): {\n cleanup: () => void;\n updateFn: (nextSource: ReactiveScalarChildSource) => void;\n} {\n let currentSource = source;\n\n if (source.length === 1 && source[0]?.kind === 'dynamic') {\n let ownedTextNode =\n el.childNodes.length === 1 && el.firstChild?.nodeType === Node.TEXT_NODE\n ? (el.firstChild as Text)\n : null;\n\n let effectHandle: FineGrainedEffectHandle<string> | null =\n createFineGrainedEffect({\n lane: 'reactive',\n compute: () => {\n const currentSlot = currentSource[0];\n if (!currentSlot || currentSlot.kind !== 'dynamic') {\n throw new Error(\n '[Askr] Direct reactive text bindings require a single dynamic slot.'\n );\n }\n\n const rawValue = currentSlot.compute();\n const normalized = normalizeOwnedReactiveTextValue(rawValue);\n return normalized ?? (rawValue as string);\n },\n commit: (value) => {\n const normalized = normalizeOwnedReactiveTextValue(value);\n\n if (normalized === null) {\n ownedTextNode = null;\n host.updateElementChildren(\n el,\n value as unknown as VNode | VNode[] | undefined\n );\n return;\n }\n\n if (\n !ownedTextNode ||\n el.childNodes.length !== 1 ||\n el.firstChild !== ownedTextNode\n ) {\n host.updateElementChildren(el, normalized);\n ownedTextNode =\n el.childNodes.length === 1 &&\n el.firstChild?.nodeType === Node.TEXT_NODE\n ? (el.firstChild as Text)\n : null;\n }\n\n if (!ownedTextNode) {\n return;\n }\n\n if (ownedTextNode.data !== normalized) {\n ownedTextNode.data = normalized;\n incDevCounter('textNodeWrites');\n }\n },\n onError: (err) => {\n if (getRuntimeEnv().NODE_ENV !== 'production') {\n logger.warn('[Askr] Reactive child update failed:', err);\n }\n },\n });\n\n return {\n cleanup: () => {\n effectHandle?.cleanup();\n effectHandle = null;\n },\n updateFn: (nextSource: ReactiveScalarChildSource) => {\n if (!effectHandle) {\n return;\n }\n\n currentSource = nextSource;\n effectHandle.updateCompute(() => {\n const currentSlot = currentSource[0];\n if (!currentSlot || currentSlot.kind !== 'dynamic') {\n throw new Error(\n '[Askr] Direct reactive text bindings require a single dynamic slot.'\n );\n }\n\n const rawValue = currentSlot.compute();\n const normalized = normalizeOwnedReactiveTextValue(rawValue);\n return normalized ?? (rawValue as string);\n });\n },\n };\n }\n\n let effectHandle: FineGrainedEffectHandle<unknown> | null =\n createFineGrainedEffect({\n lane: 'reactive',\n compute: () =>\n currentSource.map((slot) =>\n slot.kind === 'static' ? slot.value : slot.compute()\n ),\n commit: (values) => {\n if (!Array.isArray(values)) {\n throw new Error(\n '[Askr] Reactive scalar children must evaluate to a slot array.'\n );\n }\n\n const normalized = normalizeReactiveScalarSequenceValues(values);\n if (normalized) {\n syncReactiveScalarTextNodes(el, values, normalized, host);\n return;\n }\n\n const nextChildren: VNode[] = [];\n collectReactiveChildValuesAsVNodes(values, nextChildren);\n\n const boundaryHost = createReactiveChildBoundaryHost(el);\n for (let node = el.firstChild; node; ) {\n const next = node.nextSibling;\n boundaryHost.appendChild(node);\n node = next;\n }\n\n host.updateElementChildren(boundaryHost, nextChildren);\n syncReactiveChildExpectedNodes(el, Array.from(boundaryHost.childNodes));\n },\n equals: (previousValue, nextValue) => {\n if (!Array.isArray(previousValue) || !Array.isArray(nextValue)) {\n return false;\n }\n\n const previousNormalized =\n normalizeReactiveScalarSequenceValues(previousValue);\n const nextNormalized = normalizeReactiveScalarSequenceValues(nextValue);\n\n if (!previousNormalized || !nextNormalized) {\n return false;\n }\n\n if (previousNormalized.length !== nextNormalized.length) {\n return false;\n }\n\n for (let index = 0; index < previousNormalized.length; index += 1) {\n if (previousNormalized[index] !== nextNormalized[index]) {\n return false;\n }\n }\n\n return true;\n },\n onError: (err) => {\n if (getRuntimeEnv().NODE_ENV !== 'production') {\n logger.warn('[Askr] Reactive child update failed:', err);\n }\n },\n });\n\n return {\n cleanup: () => {\n effectHandle?.cleanup();\n effectHandle = null;\n },\n updateFn: (nextSource: ReactiveScalarChildSource) => {\n if (!effectHandle) {\n return;\n }\n\n currentSource = nextSource;\n effectHandle.updateCompute(() =>\n currentSource.map((slot) =>\n slot.kind === 'static' ? slot.value : slot.compute()\n )\n );\n },\n };\n}\n\nfunction setupReactiveChildBoundary(\n el: Element,\n childFn: () => VNode,\n host: ReactiveChildDOMHost\n): { cleanup: () => void; updateFn: (nextValue: unknown) => void } {\n let currentChildFn = childFn;\n const parentInstance = getCurrentInstance();\n const entry: { scope: ChildScope; nodes: Node[] } = {\n scope: createChildScope(\n parentInstance,\n `__reactive-child__:${(reactiveChildScopeId += 1)}`,\n () => {\n const expectedNodes = commitReactiveChildBoundaryEntryNodes(\n el,\n entry,\n host\n );\n syncReactiveChildExpectedNodes(el, expectedNodes);\n }\n ),\n nodes: [],\n };\n\n entry.scope.render(() =>\n normalizeReactiveChildBoundaryVNode(currentChildFn())\n );\n syncReactiveChildExpectedNodes(\n el,\n commitReactiveChildBoundaryEntryNodes(el, entry, host)\n );\n\n return {\n cleanup: () => {\n const dom = entry.scope.dom;\n const nodes = entry.nodes;\n disposeChildScope(entry.scope);\n entry.nodes = [];\n\n if (nodes.length > 0) {\n disposeReactiveChildBoundaryNodes(nodes);\n return;\n }\n\n if (dom?.parentNode === el) {\n teardownNodeSubtree(dom);\n el.removeChild(dom);\n }\n },\n updateFn: (nextValue: unknown) => {\n currentChildFn = nextValue as () => VNode;\n rerenderChildScope(entry.scope);\n const expectedNodes = commitReactiveChildBoundaryEntryNodes(\n el,\n entry,\n host\n );\n syncReactiveChildExpectedNodes(el, expectedNodes);\n },\n };\n}\n\nfunction setupReactiveChildBoundarySequence(\n el: Element,\n source: ReactiveChildBoundarySequenceSource,\n host: ReactiveChildDOMHost\n): { cleanup: () => void; updateFn: (nextValue: unknown) => void } {\n let currentSource = source;\n const parentInstance = getCurrentInstance();\n const entries: ReactiveChildBoundarySequenceEntry[] = [];\n const dynamicEntries: Array<{\n index: number;\n entry: Extract<ReactiveChildBoundarySequenceEntry, { kind: 'dynamic' }>;\n }> = [];\n\n if (!currentSource.some((slot) => slot.kind === 'dynamic')) {\n throw new Error(\n '[Askr] Reactive child boundary sequence requires at least one dynamic slot.'\n );\n }\n\n const syncSequence = () => {\n syncReactiveChildSequenceNodes(el, entries, host);\n };\n\n const parentNamespace = getParentNamespace(el);\n\n for (let index = 0; index < currentSource.length; index += 1) {\n const slot = currentSource[index];\n if (!slot) {\n continue;\n }\n\n if (slot.kind === 'static-text') {\n entries.push({\n kind: 'static',\n nodes: [document.createTextNode(slot.value)],\n });\n continue;\n }\n\n if (slot.kind === 'static-node') {\n entries.push({\n kind: 'static',\n nodes: materializeReactiveChildBoundaryNodes(\n slot.value,\n parentNamespace,\n host\n ),\n });\n continue;\n }\n\n const scope = createChildScope(\n parentInstance,\n `__reactive-child-seq__:${(reactiveChildScopeId += 1)}`,\n syncSequence\n );\n\n const dynamicEntry: Extract<\n ReactiveChildBoundarySequenceEntry,\n { kind: 'dynamic' }\n > = {\n kind: 'dynamic',\n scope,\n nodes: [],\n };\n entries.push(dynamicEntry);\n dynamicEntries.push({ index, entry: dynamicEntry });\n }\n\n for (const dynamicEntry of dynamicEntries) {\n dynamicEntry.entry.scope.render(() =>\n normalizeReactiveChildBoundaryVNode(\n (\n currentSource[dynamicEntry.index] as {\n kind: 'dynamic';\n compute: () => VNode;\n }\n ).compute()\n )\n );\n }\n\n syncSequence();\n\n return {\n cleanup: () => {\n for (const dynamicEntry of dynamicEntries) {\n const dom = dynamicEntry.entry.scope.dom;\n const nodes = dynamicEntry.entry.nodes;\n disposeChildScope(dynamicEntry.entry.scope);\n\n if (nodes.length > 0) {\n disposeReactiveChildBoundaryNodes(nodes);\n continue;\n }\n\n if (dom?.parentNode === el) {\n teardownNodeSubtree(dom);\n el.removeChild(dom);\n }\n }\n\n for (const entry of entries) {\n if (entry.kind === 'static') {\n disposeReactiveChildBoundaryNodes(entry.nodes);\n }\n }\n },\n updateFn: (nextValue: unknown) => {\n currentSource = nextValue as ReactiveChildBoundarySequenceSource;\n for (const dynamicEntry of dynamicEntries) {\n rerenderChildScope(dynamicEntry.entry.scope);\n }\n syncSequence();\n },\n };\n}\n\nexport function syncReactiveScalarChild(\n el: Element,\n children: unknown,\n host: ReactiveChildDOMHost\n): boolean {\n const reactiveChildSource = getReactiveScalarChildSource(children);\n const reactiveChildBoundary = getSingleReactiveChildBoundarySource(children);\n const reactiveChildBoundarySequence =\n getReactiveChildBoundarySequenceSource(children);\n const existingReactiveEntry = elementReactivePropsCleanup\n .get(el)\n ?.get(REACTIVE_CHILDREN_KEY);\n\n if (\n !reactiveChildSource &&\n !reactiveChildBoundary &&\n !reactiveChildBoundarySequence\n ) {\n if (existingReactiveEntry) {\n existingReactiveEntry.cleanup();\n const cleanupMap = elementReactivePropsCleanup.get(el);\n cleanupMap?.delete(REACTIVE_CHILDREN_KEY);\n if (cleanupMap && cleanupMap.size === 0) {\n elementReactivePropsCleanup.delete(el);\n }\n }\n\n return false;\n }\n\n if (reactiveChildSource && !reactiveChildBoundarySequence) {\n if (\n existingReactiveEntry &&\n Array.isArray(existingReactiveEntry.fnRef) &&\n areReactiveScalarChildSourcesEqual(\n existingReactiveEntry.fnRef,\n reactiveChildSource\n )\n ) {\n return true;\n }\n\n if (\n existingReactiveEntry?.updateFn &&\n Array.isArray(existingReactiveEntry.fnRef)\n ) {\n existingReactiveEntry.updateFn(reactiveChildSource);\n existingReactiveEntry.fnRef = reactiveChildSource;\n return true;\n }\n\n existingReactiveEntry?.cleanup();\n\n try {\n const reactive = setupReactiveScalarChild(el, reactiveChildSource, host);\n getOrCreateElementReactiveCleanupMap(el).set(REACTIVE_CHILDREN_KEY, {\n cleanup: reactive.cleanup,\n updateFn: (nextValue) => {\n reactive.updateFn(nextValue as ReactiveScalarChildSource);\n },\n fnRef: reactiveChildSource,\n });\n return true;\n } catch (error) {\n if (!reactiveChildBoundary && !reactiveChildBoundarySequence) {\n throw error;\n }\n }\n }\n\n if (reactiveChildBoundarySequence) {\n if (\n existingReactiveEntry &&\n Array.isArray(existingReactiveEntry.fnRef) &&\n areReactiveChildBoundarySequenceSourcesEqual(\n existingReactiveEntry.fnRef,\n reactiveChildBoundarySequence\n )\n ) {\n return true;\n }\n\n if (\n existingReactiveEntry?.updateFn &&\n Array.isArray(existingReactiveEntry.fnRef) &&\n canUpdateReactiveChildBoundarySequenceSource(\n existingReactiveEntry.fnRef,\n reactiveChildBoundarySequence\n )\n ) {\n existingReactiveEntry.updateFn(reactiveChildBoundarySequence);\n existingReactiveEntry.fnRef = reactiveChildBoundarySequence;\n return true;\n }\n\n existingReactiveEntry?.cleanup();\n\n const reactive = setupReactiveChildBoundarySequence(\n el,\n reactiveChildBoundarySequence,\n host\n );\n getOrCreateElementReactiveCleanupMap(el).set(REACTIVE_CHILDREN_KEY, {\n cleanup: reactive.cleanup,\n updateFn: reactive.updateFn,\n fnRef: reactiveChildBoundarySequence,\n });\n return true;\n }\n\n if (existingReactiveEntry?.fnRef === reactiveChildBoundary) {\n return true;\n }\n\n if (\n existingReactiveEntry?.updateFn &&\n !Array.isArray(existingReactiveEntry.fnRef)\n ) {\n existingReactiveEntry.updateFn(reactiveChildBoundary);\n existingReactiveEntry.fnRef = reactiveChildBoundary;\n return true;\n }\n\n existingReactiveEntry?.cleanup();\n\n if (!reactiveChildBoundary) {\n return false;\n }\n\n const reactive = setupReactiveChildBoundary(el, reactiveChildBoundary, host);\n getOrCreateElementReactiveCleanupMap(el).set(REACTIVE_CHILDREN_KEY, {\n cleanup: reactive.cleanup,\n updateFn: reactive.updateFn,\n fnRef: reactiveChildBoundary,\n });\n return true;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { teardownNodeSubtree } from "./cleanup.js";
|
|
2
|
+
import { recordDOMReplace } from "./utils.js";
|
|
3
|
+
//#region src/renderer/reconcile-commit.ts
|
|
4
|
+
function commitReconciliation(parent, finalNodes) {
|
|
5
|
+
try {
|
|
6
|
+
const finalSet = new Set(finalNodes);
|
|
7
|
+
for (let n = parent.firstChild; n;) {
|
|
8
|
+
const next = n.nextSibling;
|
|
9
|
+
if (!finalSet.has(n)) {
|
|
10
|
+
teardownNodeSubtree(n);
|
|
11
|
+
parent.removeChild(n);
|
|
12
|
+
}
|
|
13
|
+
n = next;
|
|
14
|
+
}
|
|
15
|
+
for (let i = 0; i < finalNodes.length; i++) {
|
|
16
|
+
const desiredNode = finalNodes[i];
|
|
17
|
+
const anchor = parent.childNodes[i] ?? null;
|
|
18
|
+
if (desiredNode !== anchor) parent.insertBefore(desiredNode, anchor);
|
|
19
|
+
}
|
|
20
|
+
} catch {
|
|
21
|
+
const fragment = document.createDocumentFragment();
|
|
22
|
+
for (let i = 0; i < finalNodes.length; i++) fragment.appendChild(finalNodes[i]);
|
|
23
|
+
try {
|
|
24
|
+
for (let n = parent.firstChild; n;) {
|
|
25
|
+
const next = n.nextSibling;
|
|
26
|
+
teardownNodeSubtree(n);
|
|
27
|
+
n = next;
|
|
28
|
+
}
|
|
29
|
+
} catch {}
|
|
30
|
+
recordDOMReplace("reconcile");
|
|
31
|
+
parent.replaceChildren(fragment);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { commitReconciliation };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=reconcile-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile-commit.js","names":[],"sources":["../../src/renderer/reconcile-commit.ts"],"sourcesContent":["import { teardownNodeSubtree } from './cleanup';\nimport { recordDOMReplace } from './utils';\n\nexport function commitReconciliation(\n parent: Element,\n finalNodes: Node[]\n): void {\n try {\n const finalSet = new Set<Node>(finalNodes);\n\n for (let n = parent.firstChild; n; ) {\n const next = n.nextSibling;\n if (!finalSet.has(n)) {\n teardownNodeSubtree(n);\n parent.removeChild(n);\n }\n n = next;\n }\n\n for (let i = 0; i < finalNodes.length; i++) {\n const desiredNode = finalNodes[i];\n const anchor = parent.childNodes[i] ?? null;\n if (desiredNode !== anchor) {\n parent.insertBefore(desiredNode, anchor);\n }\n }\n } catch {\n const fragment = document.createDocumentFragment();\n for (let i = 0; i < finalNodes.length; i++) {\n fragment.appendChild(finalNodes[i]);\n }\n\n try {\n for (let n = parent.firstChild; n; ) {\n const next = n.nextSibling;\n teardownNodeSubtree(n);\n n = next;\n }\n } catch {\n // Ignore fallback cleanup failures.\n }\n\n recordDOMReplace('reconcile');\n parent.replaceChildren(fragment);\n return;\n }\n}\n"],"mappings":";;;AAGA,SAAgB,qBACd,QACA,YACM;CACN,IAAI;EACF,MAAM,WAAW,IAAI,IAAU,UAAU;EAEzC,KAAK,IAAI,IAAI,OAAO,YAAY,IAAK;GACnC,MAAM,OAAO,EAAE;GACf,IAAI,CAAC,SAAS,IAAI,CAAC,GAAG;IACpB,oBAAoB,CAAC;IACrB,OAAO,YAAY,CAAC;GACtB;GACA,IAAI;EACN;EAEA,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;GAC1C,MAAM,cAAc,WAAW;GAC/B,MAAM,SAAS,OAAO,WAAW,MAAM;GACvC,IAAI,gBAAgB,QAClB,OAAO,aAAa,aAAa,MAAM;EAE3C;CACF,QAAQ;EACN,MAAM,WAAW,SAAS,uBAAuB;EACjD,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KACrC,SAAS,YAAY,WAAW,EAAE;EAGpC,IAAI;GACF,KAAK,IAAI,IAAI,OAAO,YAAY,IAAK;IACnC,MAAM,OAAO,EAAE;IACf,oBAAoB,CAAC;IACrB,IAAI;GACN;EACF,QAAQ,CAER;EAEA,iBAAiB,WAAW;EAC5B,OAAO,gBAAgB,QAAQ;EAC/B;CACF;AACF"}
|