@depup/svelte 5.53.3-depup.0
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/LICENSE.md +7 -0
- package/README.md +41 -0
- package/action.d.ts +1 -0
- package/animate.d.ts +1 -0
- package/compiler/index.js +1 -0
- package/compiler/package.json +3 -0
- package/compiler.d.ts +1 -0
- package/easing.d.ts +1 -0
- package/elements.d.ts +2078 -0
- package/index.d.ts +1 -0
- package/legacy.d.ts +1 -0
- package/motion.d.ts +1 -0
- package/package.json +185 -0
- package/src/animate/index.js +78 -0
- package/src/attachments/index.js +113 -0
- package/src/compiler/errors.js +1719 -0
- package/src/compiler/index.js +198 -0
- package/src/compiler/legacy.js +637 -0
- package/src/compiler/migrate/index.js +1996 -0
- package/src/compiler/phases/1-parse/acorn.js +198 -0
- package/src/compiler/phases/1-parse/index.js +326 -0
- package/src/compiler/phases/1-parse/read/context.js +116 -0
- package/src/compiler/phases/1-parse/read/expression.js +93 -0
- package/src/compiler/phases/1-parse/read/options.js +263 -0
- package/src/compiler/phases/1-parse/read/script.js +97 -0
- package/src/compiler/phases/1-parse/read/style.js +637 -0
- package/src/compiler/phases/1-parse/remove_typescript_nodes.js +180 -0
- package/src/compiler/phases/1-parse/state/element.js +937 -0
- package/src/compiler/phases/1-parse/state/fragment.js +17 -0
- package/src/compiler/phases/1-parse/state/tag.js +751 -0
- package/src/compiler/phases/1-parse/state/text.js +23 -0
- package/src/compiler/phases/1-parse/utils/bracket.js +213 -0
- package/src/compiler/phases/1-parse/utils/create.js +16 -0
- package/src/compiler/phases/1-parse/utils/entities.js +2234 -0
- package/src/compiler/phases/1-parse/utils/fuzzymatch.js +281 -0
- package/src/compiler/phases/1-parse/utils/html.js +127 -0
- package/src/compiler/phases/2-analyze/css/css-analyze.js +331 -0
- package/src/compiler/phases/2-analyze/css/css-prune.js +1206 -0
- package/src/compiler/phases/2-analyze/css/css-warn.js +47 -0
- package/src/compiler/phases/2-analyze/css/utils.js +177 -0
- package/src/compiler/phases/2-analyze/index.js +1300 -0
- package/src/compiler/phases/2-analyze/utils/check_graph_for_cycles.js +47 -0
- package/src/compiler/phases/2-analyze/visitors/AnimateDirective.js +15 -0
- package/src/compiler/phases/2-analyze/visitors/ArrowFunctionExpression.js +11 -0
- package/src/compiler/phases/2-analyze/visitors/AssignmentExpression.js +31 -0
- package/src/compiler/phases/2-analyze/visitors/AttachTag.js +17 -0
- package/src/compiler/phases/2-analyze/visitors/Attribute.js +66 -0
- package/src/compiler/phases/2-analyze/visitors/AwaitBlock.js +48 -0
- package/src/compiler/phases/2-analyze/visitors/AwaitExpression.js +150 -0
- package/src/compiler/phases/2-analyze/visitors/BindDirective.js +280 -0
- package/src/compiler/phases/2-analyze/visitors/CallExpression.js +339 -0
- package/src/compiler/phases/2-analyze/visitors/ClassBody.js +156 -0
- package/src/compiler/phases/2-analyze/visitors/ClassDeclaration.js +25 -0
- package/src/compiler/phases/2-analyze/visitors/ClassDirective.js +13 -0
- package/src/compiler/phases/2-analyze/visitors/Component.js +26 -0
- package/src/compiler/phases/2-analyze/visitors/ConstTag.js +45 -0
- package/src/compiler/phases/2-analyze/visitors/DebugTag.js +15 -0
- package/src/compiler/phases/2-analyze/visitors/EachBlock.js +97 -0
- package/src/compiler/phases/2-analyze/visitors/ExportDefaultDeclaration.js +20 -0
- package/src/compiler/phases/2-analyze/visitors/ExportNamedDeclaration.js +70 -0
- package/src/compiler/phases/2-analyze/visitors/ExportSpecifier.js +30 -0
- package/src/compiler/phases/2-analyze/visitors/ExpressionStatement.js +38 -0
- package/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +26 -0
- package/src/compiler/phases/2-analyze/visitors/Fragment.js +10 -0
- package/src/compiler/phases/2-analyze/visitors/FunctionDeclaration.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/FunctionExpression.js +11 -0
- package/src/compiler/phases/2-analyze/visitors/HtmlTag.js +19 -0
- package/src/compiler/phases/2-analyze/visitors/Identifier.js +194 -0
- package/src/compiler/phases/2-analyze/visitors/IfBlock.js +46 -0
- package/src/compiler/phases/2-analyze/visitors/ImportDeclaration.js +31 -0
- package/src/compiler/phases/2-analyze/visitors/KeyBlock.js +21 -0
- package/src/compiler/phases/2-analyze/visitors/LabeledStatement.js +95 -0
- package/src/compiler/phases/2-analyze/visitors/LetDirective.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/Literal.js +14 -0
- package/src/compiler/phases/2-analyze/visitors/MemberExpression.js +28 -0
- package/src/compiler/phases/2-analyze/visitors/NewExpression.js +17 -0
- package/src/compiler/phases/2-analyze/visitors/OnDirective.js +28 -0
- package/src/compiler/phases/2-analyze/visitors/PropertyDefinition.js +21 -0
- package/src/compiler/phases/2-analyze/visitors/RegularElement.js +240 -0
- package/src/compiler/phases/2-analyze/visitors/RenderTag.js +68 -0
- package/src/compiler/phases/2-analyze/visitors/SlotElement.js +42 -0
- package/src/compiler/phases/2-analyze/visitors/SnippetBlock.js +113 -0
- package/src/compiler/phases/2-analyze/visitors/SpreadAttribute.js +13 -0
- package/src/compiler/phases/2-analyze/visitors/SpreadElement.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/StyleDirective.js +39 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteBody.js +22 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteBoundary.js +30 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteComponent.js +18 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteDocument.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteElement.js +78 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteFragment.js +27 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteHead.js +18 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteSelf.js +36 -0
- package/src/compiler/phases/2-analyze/visitors/SvelteWindow.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/TaggedTemplateExpression.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/TemplateElement.js +12 -0
- package/src/compiler/phases/2-analyze/visitors/Text.js +52 -0
- package/src/compiler/phases/2-analyze/visitors/TitleElement.js +21 -0
- package/src/compiler/phases/2-analyze/visitors/TransitionDirective.js +19 -0
- package/src/compiler/phases/2-analyze/visitors/UpdateExpression.js +29 -0
- package/src/compiler/phases/2-analyze/visitors/UseDirective.js +18 -0
- package/src/compiler/phases/2-analyze/visitors/VariableDeclarator.js +160 -0
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/constants.js +334 -0
- package/src/compiler/phases/2-analyze/visitors/shared/a11y/index.js +981 -0
- package/src/compiler/phases/2-analyze/visitors/shared/attribute.js +125 -0
- package/src/compiler/phases/2-analyze/visitors/shared/component.js +177 -0
- package/src/compiler/phases/2-analyze/visitors/shared/element.js +160 -0
- package/src/compiler/phases/2-analyze/visitors/shared/fragment.js +15 -0
- package/src/compiler/phases/2-analyze/visitors/shared/function.js +24 -0
- package/src/compiler/phases/2-analyze/visitors/shared/snippets.js +17 -0
- package/src/compiler/phases/2-analyze/visitors/shared/special-element.js +16 -0
- package/src/compiler/phases/2-analyze/visitors/shared/utils.js +301 -0
- package/src/compiler/phases/3-transform/client/transform-client.js +719 -0
- package/src/compiler/phases/3-transform/client/transform-template/fix-attribute-casing.js +18 -0
- package/src/compiler/phases/3-transform/client/transform-template/index.js +67 -0
- package/src/compiler/phases/3-transform/client/transform-template/template.js +164 -0
- package/src/compiler/phases/3-transform/client/utils.js +181 -0
- package/src/compiler/phases/3-transform/client/visitors/AnimateDirective.js +38 -0
- package/src/compiler/phases/3-transform/client/visitors/ArrowFunctionExpression.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/AssignmentExpression.js +247 -0
- package/src/compiler/phases/3-transform/client/visitors/AttachTag.js +26 -0
- package/src/compiler/phases/3-transform/client/visitors/Attribute.js +14 -0
- package/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +124 -0
- package/src/compiler/phases/3-transform/client/visitors/AwaitExpression.js +25 -0
- package/src/compiler/phases/3-transform/client/visitors/BinaryExpression.js +34 -0
- package/src/compiler/phases/3-transform/client/visitors/BindDirective.js +290 -0
- package/src/compiler/phases/3-transform/client/visitors/BlockStatement.js +32 -0
- package/src/compiler/phases/3-transform/client/visitors/BreakStatement.js +20 -0
- package/src/compiler/phases/3-transform/client/visitors/CallExpression.js +136 -0
- package/src/compiler/phases/3-transform/client/visitors/ClassBody.js +111 -0
- package/src/compiler/phases/3-transform/client/visitors/Comment.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/Component.js +12 -0
- package/src/compiler/phases/3-transform/client/visitors/ConstTag.js +134 -0
- package/src/compiler/phases/3-transform/client/visitors/DebugTag.js +28 -0
- package/src/compiler/phases/3-transform/client/visitors/EachBlock.js +362 -0
- package/src/compiler/phases/3-transform/client/visitors/ExportNamedDeclaration.js +19 -0
- package/src/compiler/phases/3-transform/client/visitors/ExpressionStatement.js +20 -0
- package/src/compiler/phases/3-transform/client/visitors/ForOfStatement.js +25 -0
- package/src/compiler/phases/3-transform/client/visitors/Fragment.js +186 -0
- package/src/compiler/phases/3-transform/client/visitors/FunctionDeclaration.js +12 -0
- package/src/compiler/phases/3-transform/client/visitors/FunctionExpression.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/HtmlTag.js +53 -0
- package/src/compiler/phases/3-transform/client/visitors/Identifier.js +45 -0
- package/src/compiler/phases/3-transform/client/visitors/IfBlock.js +131 -0
- package/src/compiler/phases/3-transform/client/visitors/KeyBlock.js +45 -0
- package/src/compiler/phases/3-transform/client/visitors/LabeledStatement.js +64 -0
- package/src/compiler/phases/3-transform/client/visitors/LetDirective.js +55 -0
- package/src/compiler/phases/3-transform/client/visitors/MemberExpression.js +23 -0
- package/src/compiler/phases/3-transform/client/visitors/OnDirective.js +38 -0
- package/src/compiler/phases/3-transform/client/visitors/Program.js +153 -0
- package/src/compiler/phases/3-transform/client/visitors/RegularElement.js +725 -0
- package/src/compiler/phases/3-transform/client/visitors/RenderTag.js +95 -0
- package/src/compiler/phases/3-transform/client/visitors/SlotElement.js +94 -0
- package/src/compiler/phases/3-transform/client/visitors/SnippetBlock.js +94 -0
- package/src/compiler/phases/3-transform/client/visitors/SpreadAttribute.js +10 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteBody.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteBoundary.js +126 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteComponent.js +13 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteDocument.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteElement.js +161 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteFragment.js +17 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteHead.js +23 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteSelf.js +13 -0
- package/src/compiler/phases/3-transform/client/visitors/SvelteWindow.js +11 -0
- package/src/compiler/phases/3-transform/client/visitors/TitleElement.js +48 -0
- package/src/compiler/phases/3-transform/client/visitors/TransitionDirective.js +41 -0
- package/src/compiler/phases/3-transform/client/visitors/UpdateExpression.js +55 -0
- package/src/compiler/phases/3-transform/client/visitors/UseDirective.js +49 -0
- package/src/compiler/phases/3-transform/client/visitors/VariableDeclaration.js +422 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/component.js +536 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/declarations.js +53 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/element.js +263 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/events.js +180 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/fragment.js +185 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/function.js +17 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/special_element.js +22 -0
- package/src/compiler/phases/3-transform/client/visitors/shared/utils.js +513 -0
- package/src/compiler/phases/3-transform/css/index.js +479 -0
- package/src/compiler/phases/3-transform/index.js +118 -0
- package/src/compiler/phases/3-transform/server/transform-server.js +428 -0
- package/src/compiler/phases/3-transform/server/visitors/AssignmentExpression.js +124 -0
- package/src/compiler/phases/3-transform/server/visitors/AwaitBlock.js +36 -0
- package/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js +40 -0
- package/src/compiler/phases/3-transform/server/visitors/CallExpression.js +71 -0
- package/src/compiler/phases/3-transform/server/visitors/ClassBody.js +81 -0
- package/src/compiler/phases/3-transform/server/visitors/Component.js +13 -0
- package/src/compiler/phases/3-transform/server/visitors/ConstTag.js +49 -0
- package/src/compiler/phases/3-transform/server/visitors/DebugTag.js +24 -0
- package/src/compiler/phases/3-transform/server/visitors/EachBlock.js +76 -0
- package/src/compiler/phases/3-transform/server/visitors/ExpressionStatement.js +23 -0
- package/src/compiler/phases/3-transform/server/visitors/Fragment.js +53 -0
- package/src/compiler/phases/3-transform/server/visitors/HtmlTag.js +25 -0
- package/src/compiler/phases/3-transform/server/visitors/Identifier.js +24 -0
- package/src/compiler/phases/3-transform/server/visitors/IfBlock.js +48 -0
- package/src/compiler/phases/3-transform/server/visitors/KeyBlock.js +22 -0
- package/src/compiler/phases/3-transform/server/visitors/LabeledStatement.js +24 -0
- package/src/compiler/phases/3-transform/server/visitors/MemberExpression.js +19 -0
- package/src/compiler/phases/3-transform/server/visitors/Program.js +25 -0
- package/src/compiler/phases/3-transform/server/visitors/PropertyDefinition.js +37 -0
- package/src/compiler/phases/3-transform/server/visitors/RegularElement.js +216 -0
- package/src/compiler/phases/3-transform/server/visitors/RenderTag.js +45 -0
- package/src/compiler/phases/3-transform/server/visitors/SlotElement.js +68 -0
- package/src/compiler/phases/3-transform/server/visitors/SnippetBlock.js +29 -0
- package/src/compiler/phases/3-transform/server/visitors/SpreadAttribute.js +10 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteBoundary.js +139 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteComponent.js +12 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteElement.js +89 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteFragment.js +11 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteHead.js +25 -0
- package/src/compiler/phases/3-transform/server/visitors/SvelteSelf.js +12 -0
- package/src/compiler/phases/3-transform/server/visitors/TitleElement.js +21 -0
- package/src/compiler/phases/3-transform/server/visitors/UpdateExpression.js +35 -0
- package/src/compiler/phases/3-transform/server/visitors/VariableDeclaration.js +247 -0
- package/src/compiler/phases/3-transform/server/visitors/shared/component.js +359 -0
- package/src/compiler/phases/3-transform/server/visitors/shared/element.js +557 -0
- package/src/compiler/phases/3-transform/server/visitors/shared/utils.js +408 -0
- package/src/compiler/phases/3-transform/shared/assignments.js +92 -0
- package/src/compiler/phases/3-transform/shared/transform-async.js +114 -0
- package/src/compiler/phases/3-transform/utils.js +451 -0
- package/src/compiler/phases/bindings.js +227 -0
- package/src/compiler/phases/css.js +14 -0
- package/src/compiler/phases/nodes.js +258 -0
- package/src/compiler/phases/patterns.js +27 -0
- package/src/compiler/phases/scope.js +1432 -0
- package/src/compiler/preprocess/decode_sourcemap.js +96 -0
- package/src/compiler/preprocess/index.js +368 -0
- package/src/compiler/preprocess/replace_in_code.js +72 -0
- package/src/compiler/print/index.js +911 -0
- package/src/compiler/state.js +144 -0
- package/src/compiler/utils/assert.js +9 -0
- package/src/compiler/utils/ast.js +639 -0
- package/src/compiler/utils/builders.js +698 -0
- package/src/compiler/utils/compile_diagnostic.js +107 -0
- package/src/compiler/utils/extract_svelte_ignore.js +104 -0
- package/src/compiler/utils/mapped_code.js +454 -0
- package/src/compiler/utils/push_array.js +13 -0
- package/src/compiler/utils/sanitize_template_string.js +7 -0
- package/src/compiler/utils/slot.js +20 -0
- package/src/compiler/utils/string.js +9 -0
- package/src/compiler/validate-options.js +324 -0
- package/src/compiler/warnings.js +845 -0
- package/src/constants.js +66 -0
- package/src/easing/index.js +286 -0
- package/src/escaping.js +26 -0
- package/src/events/index.js +1 -0
- package/src/html-tree-validation.js +238 -0
- package/src/index-client.js +255 -0
- package/src/index-server.js +56 -0
- package/src/internal/client/constants.js +77 -0
- package/src/internal/client/context.js +258 -0
- package/src/internal/client/dev/assign.js +79 -0
- package/src/internal/client/dev/console-log.js +37 -0
- package/src/internal/client/dev/css.js +31 -0
- package/src/internal/client/dev/debug.js +500 -0
- package/src/internal/client/dev/elements.js +63 -0
- package/src/internal/client/dev/equality.js +101 -0
- package/src/internal/client/dev/hmr.js +89 -0
- package/src/internal/client/dev/inspect.js +72 -0
- package/src/internal/client/dev/legacy.js +25 -0
- package/src/internal/client/dev/ownership.js +81 -0
- package/src/internal/client/dev/tracing.js +162 -0
- package/src/internal/client/dev/validation.js +16 -0
- package/src/internal/client/dom/blocks/async.js +71 -0
- package/src/internal/client/dom/blocks/await.js +142 -0
- package/src/internal/client/dom/blocks/boundary.js +534 -0
- package/src/internal/client/dom/blocks/branches.js +227 -0
- package/src/internal/client/dom/blocks/css-props.js +28 -0
- package/src/internal/client/dom/blocks/each.js +723 -0
- package/src/internal/client/dom/blocks/html.js +128 -0
- package/src/internal/client/dom/blocks/if.js +82 -0
- package/src/internal/client/dom/blocks/key.js +40 -0
- package/src/internal/client/dom/blocks/slot.js +44 -0
- package/src/internal/client/dom/blocks/snippet.js +103 -0
- package/src/internal/client/dom/blocks/svelte-component.js +61 -0
- package/src/internal/client/dom/blocks/svelte-element.js +152 -0
- package/src/internal/client/dom/blocks/svelte-head.js +61 -0
- package/src/internal/client/dom/css.js +33 -0
- package/src/internal/client/dom/elements/actions.js +43 -0
- package/src/internal/client/dom/elements/attachments.js +33 -0
- package/src/internal/client/dom/elements/attributes.js +657 -0
- package/src/internal/client/dom/elements/bindings/document.js +17 -0
- package/src/internal/client/dom/elements/bindings/input.js +312 -0
- package/src/internal/client/dom/elements/bindings/media.js +233 -0
- package/src/internal/client/dom/elements/bindings/navigator.js +11 -0
- package/src/internal/client/dom/elements/bindings/props.js +22 -0
- package/src/internal/client/dom/elements/bindings/select.js +159 -0
- package/src/internal/client/dom/elements/bindings/shared.js +76 -0
- package/src/internal/client/dom/elements/bindings/size.js +107 -0
- package/src/internal/client/dom/elements/bindings/this.js +61 -0
- package/src/internal/client/dom/elements/bindings/universal.js +75 -0
- package/src/internal/client/dom/elements/bindings/window.js +66 -0
- package/src/internal/client/dom/elements/class.js +51 -0
- package/src/internal/client/dom/elements/custom-element.js +344 -0
- package/src/internal/client/dom/elements/customizable-select.js +99 -0
- package/src/internal/client/dom/elements/events.js +355 -0
- package/src/internal/client/dom/elements/misc.js +58 -0
- package/src/internal/client/dom/elements/style.js +57 -0
- package/src/internal/client/dom/elements/transitions.js +471 -0
- package/src/internal/client/dom/hydration.js +125 -0
- package/src/internal/client/dom/legacy/event-modifiers.js +127 -0
- package/src/internal/client/dom/legacy/lifecycle.js +82 -0
- package/src/internal/client/dom/legacy/misc.js +68 -0
- package/src/internal/client/dom/operations.js +293 -0
- package/src/internal/client/dom/reconciler.js +25 -0
- package/src/internal/client/dom/task.js +42 -0
- package/src/internal/client/dom/template.js +401 -0
- package/src/internal/client/error-handling.js +118 -0
- package/src/internal/client/errors.js +510 -0
- package/src/internal/client/hydratable.js +33 -0
- package/src/internal/client/index.js +183 -0
- package/src/internal/client/legacy.js +46 -0
- package/src/internal/client/loop.js +48 -0
- package/src/internal/client/proxy.js +432 -0
- package/src/internal/client/reactivity/async.js +306 -0
- package/src/internal/client/reactivity/batch.js +1057 -0
- package/src/internal/client/reactivity/deriveds.js +426 -0
- package/src/internal/client/reactivity/effects.js +718 -0
- package/src/internal/client/reactivity/equality.js +31 -0
- package/src/internal/client/reactivity/props.js +430 -0
- package/src/internal/client/reactivity/sources.js +370 -0
- package/src/internal/client/reactivity/status.js +25 -0
- package/src/internal/client/reactivity/store.js +203 -0
- package/src/internal/client/reactivity/utils.js +40 -0
- package/src/internal/client/render.js +335 -0
- package/src/internal/client/runtime.js +827 -0
- package/src/internal/client/timing.js +16 -0
- package/src/internal/client/validate.js +54 -0
- package/src/internal/client/warnings.js +271 -0
- package/src/internal/disclose-version.js +6 -0
- package/src/internal/flags/async.js +3 -0
- package/src/internal/flags/index.js +23 -0
- package/src/internal/flags/legacy.js +3 -0
- package/src/internal/flags/tracing.js +3 -0
- package/src/internal/index.js +5 -0
- package/src/internal/server/abort-signal.js +13 -0
- package/src/internal/server/blocks/html.js +11 -0
- package/src/internal/server/blocks/snippet.js +24 -0
- package/src/internal/server/context.js +132 -0
- package/src/internal/server/crypto.js +45 -0
- package/src/internal/server/dev.js +115 -0
- package/src/internal/server/errors.js +131 -0
- package/src/internal/server/hydratable.js +142 -0
- package/src/internal/server/hydration.js +6 -0
- package/src/internal/server/index.js +544 -0
- package/src/internal/server/render-context.js +86 -0
- package/src/internal/server/renderer.js +923 -0
- package/src/internal/server/warnings.js +29 -0
- package/src/internal/shared/attributes.js +225 -0
- package/src/internal/shared/clone.js +137 -0
- package/src/internal/shared/dev.js +65 -0
- package/src/internal/shared/errors.js +134 -0
- package/src/internal/shared/utils.js +144 -0
- package/src/internal/shared/validate.js +47 -0
- package/src/internal/shared/warnings.js +40 -0
- package/src/legacy/legacy-client.js +281 -0
- package/src/legacy/legacy-server.js +112 -0
- package/src/motion/index.js +32 -0
- package/src/motion/spring.js +369 -0
- package/src/motion/tweened.js +306 -0
- package/src/motion/utils.js +7 -0
- package/src/reactivity/create-subscriber.js +95 -0
- package/src/reactivity/date.js +118 -0
- package/src/reactivity/index-client.js +7 -0
- package/src/reactivity/index-server.js +23 -0
- package/src/reactivity/map.js +273 -0
- package/src/reactivity/media-query.js +55 -0
- package/src/reactivity/reactive-value.js +24 -0
- package/src/reactivity/set.js +213 -0
- package/src/reactivity/url-search-params.js +174 -0
- package/src/reactivity/url.js +205 -0
- package/src/reactivity/window/index.js +161 -0
- package/src/server/index.js +1 -0
- package/src/store/index-client.js +169 -0
- package/src/store/index-server.js +101 -0
- package/src/store/shared/index.js +209 -0
- package/src/store/utils.js +36 -0
- package/src/transition/index.js +300 -0
- package/src/utils.js +504 -0
- package/src/version.js +8 -0
- package/store.d.ts +1 -0
- package/svelte-html.d.ts +245 -0
- package/transition.d.ts +1 -0
- package/types/compiler/interfaces.d.ts +1 -0
- package/types/compiler/preprocess.d.ts +1 -0
- package/types/index.d.ts +3744 -0
- package/types/index.d.ts.map +280 -0
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
/** @import { Component } from 'svelte' */
|
|
2
|
+
/** @import { Csp, HydratableContext, RenderOutput, SSRContext, SyncRenderOutput, Sha256Source } from './types.js' */
|
|
3
|
+
/** @import { MaybePromise } from '#shared' */
|
|
4
|
+
import { async_mode_flag } from '../flags/index.js';
|
|
5
|
+
import { abort } from './abort-signal.js';
|
|
6
|
+
import { pop, push, set_ssr_context, ssr_context } from './context.js';
|
|
7
|
+
import * as e from './errors.js';
|
|
8
|
+
import * as w from './warnings.js';
|
|
9
|
+
import { BLOCK_CLOSE, BLOCK_OPEN } from './hydration.js';
|
|
10
|
+
import { HYDRATION_START_FAILED } from '../../constants.js';
|
|
11
|
+
import { attributes } from './index.js';
|
|
12
|
+
import { get_render_context, with_render_context, init_render_context } from './render-context.js';
|
|
13
|
+
import { sha256 } from './crypto.js';
|
|
14
|
+
import * as devalue from 'devalue';
|
|
15
|
+
import { has_own_property, noop } from '../shared/utils.js';
|
|
16
|
+
import { escape_html } from '../../escaping.js';
|
|
17
|
+
|
|
18
|
+
/** @typedef {'head' | 'body'} RendererType */
|
|
19
|
+
/** @typedef {{ [key in RendererType]: string }} AccumulatedContent */
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {string | Renderer} RendererItem
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Renderers are basically a tree of `string | Renderer`s, where each `Renderer` in the tree represents
|
|
27
|
+
* work that may or may not have completed. A renderer can be {@link collect}ed to aggregate the
|
|
28
|
+
* content from itself and all of its children, but this will throw if any of the children are
|
|
29
|
+
* performing asynchronous work. To asynchronously collect a renderer, just `await` it.
|
|
30
|
+
*
|
|
31
|
+
* The `string` values within a renderer are always associated with the {@link type} of that renderer. To switch types,
|
|
32
|
+
* call {@link child} with a different `type` argument.
|
|
33
|
+
*/
|
|
34
|
+
export class Renderer {
|
|
35
|
+
/**
|
|
36
|
+
* The contents of the renderer.
|
|
37
|
+
* @type {RendererItem[]}
|
|
38
|
+
*/
|
|
39
|
+
#out = [];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Any `onDestroy` callbacks registered during execution of this renderer.
|
|
43
|
+
* @type {(() => void)[] | undefined}
|
|
44
|
+
*/
|
|
45
|
+
#on_destroy = undefined;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Whether this renderer is a component body.
|
|
49
|
+
* @type {boolean}
|
|
50
|
+
*/
|
|
51
|
+
#is_component_body = false;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* If set, this renderer is an error boundary. When async collection
|
|
55
|
+
* of the children fails, the failed snippet is rendered instead.
|
|
56
|
+
* @type {{
|
|
57
|
+
* failed: (renderer: Renderer, error: unknown, reset: () => void) => void;
|
|
58
|
+
* transformError: (error: unknown) => unknown;
|
|
59
|
+
* context: SSRContext | null;
|
|
60
|
+
* } | null}
|
|
61
|
+
*/
|
|
62
|
+
#boundary = null;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The type of string content that this renderer is accumulating.
|
|
66
|
+
* @type {RendererType}
|
|
67
|
+
*/
|
|
68
|
+
type;
|
|
69
|
+
|
|
70
|
+
/** @type {Renderer | undefined} */
|
|
71
|
+
#parent;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Asynchronous work associated with this renderer
|
|
75
|
+
* @type {Promise<void> | undefined}
|
|
76
|
+
*/
|
|
77
|
+
promise = undefined;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* State which is associated with the content tree as a whole.
|
|
81
|
+
* It will be re-exposed, uncopied, on all children.
|
|
82
|
+
* @type {SSRState}
|
|
83
|
+
* @readonly
|
|
84
|
+
*/
|
|
85
|
+
global;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* State that is local to the branch it is declared in.
|
|
89
|
+
* It will be shallow-copied to all children.
|
|
90
|
+
*
|
|
91
|
+
* @type {{ select_value: string | undefined }}
|
|
92
|
+
*/
|
|
93
|
+
local;
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {SSRState} global
|
|
97
|
+
* @param {Renderer | undefined} [parent]
|
|
98
|
+
*/
|
|
99
|
+
constructor(global, parent) {
|
|
100
|
+
this.#parent = parent;
|
|
101
|
+
|
|
102
|
+
this.global = global;
|
|
103
|
+
this.local = parent ? { ...parent.local } : { select_value: undefined };
|
|
104
|
+
this.type = parent ? parent.type : 'body';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @param {(renderer: Renderer) => void} fn
|
|
109
|
+
*/
|
|
110
|
+
head(fn) {
|
|
111
|
+
const head = new Renderer(this.global, this);
|
|
112
|
+
head.type = 'head';
|
|
113
|
+
|
|
114
|
+
this.#out.push(head);
|
|
115
|
+
head.child(fn);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {Array<Promise<void>>} blockers
|
|
120
|
+
* @param {(renderer: Renderer) => void} fn
|
|
121
|
+
*/
|
|
122
|
+
async_block(blockers, fn) {
|
|
123
|
+
this.#out.push(BLOCK_OPEN);
|
|
124
|
+
this.async(blockers, fn);
|
|
125
|
+
this.#out.push(BLOCK_CLOSE);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @param {Array<Promise<void>>} blockers
|
|
130
|
+
* @param {(renderer: Renderer) => void} fn
|
|
131
|
+
*/
|
|
132
|
+
async(blockers, fn) {
|
|
133
|
+
let callback = fn;
|
|
134
|
+
|
|
135
|
+
if (blockers.length > 0) {
|
|
136
|
+
const context = ssr_context;
|
|
137
|
+
|
|
138
|
+
callback = (renderer) => {
|
|
139
|
+
return Promise.all(blockers).then(() => {
|
|
140
|
+
const previous_context = ssr_context;
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
set_ssr_context(context);
|
|
144
|
+
return fn(renderer);
|
|
145
|
+
} finally {
|
|
146
|
+
set_ssr_context(previous_context);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.child(callback);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @param {Array<() => void>} thunks
|
|
157
|
+
*/
|
|
158
|
+
run(thunks) {
|
|
159
|
+
const context = ssr_context;
|
|
160
|
+
|
|
161
|
+
let promise = Promise.resolve(thunks[0]());
|
|
162
|
+
const promises = [promise];
|
|
163
|
+
|
|
164
|
+
for (const fn of thunks.slice(1)) {
|
|
165
|
+
promise = promise.then(() => {
|
|
166
|
+
const previous_context = ssr_context;
|
|
167
|
+
set_ssr_context(context);
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
return fn();
|
|
171
|
+
} finally {
|
|
172
|
+
set_ssr_context(previous_context);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
promises.push(promise);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// prevent unhandled rejections, and attach the promise to the renderer instance
|
|
180
|
+
// so that rejections correctly cause rendering to fail
|
|
181
|
+
promise.catch(noop);
|
|
182
|
+
this.promise = promise;
|
|
183
|
+
|
|
184
|
+
return promises;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @param {(renderer: Renderer) => MaybePromise<void>} fn
|
|
189
|
+
*/
|
|
190
|
+
child_block(fn) {
|
|
191
|
+
this.#out.push(BLOCK_OPEN);
|
|
192
|
+
this.child(fn);
|
|
193
|
+
this.#out.push(BLOCK_CLOSE);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Create a child renderer. The child renderer inherits the state from the parent,
|
|
198
|
+
* but has its own content.
|
|
199
|
+
* @param {(renderer: Renderer) => MaybePromise<void>} fn
|
|
200
|
+
*/
|
|
201
|
+
child(fn) {
|
|
202
|
+
const child = new Renderer(this.global, this);
|
|
203
|
+
this.#out.push(child);
|
|
204
|
+
|
|
205
|
+
const parent = ssr_context;
|
|
206
|
+
|
|
207
|
+
set_ssr_context({
|
|
208
|
+
...ssr_context,
|
|
209
|
+
p: parent,
|
|
210
|
+
c: null,
|
|
211
|
+
r: child
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const result = fn(child);
|
|
215
|
+
|
|
216
|
+
set_ssr_context(parent);
|
|
217
|
+
|
|
218
|
+
if (result instanceof Promise) {
|
|
219
|
+
// catch to avoid unhandled promise rejections - we'll end up throwing in `collect_async` if something fails
|
|
220
|
+
result.catch(noop);
|
|
221
|
+
result.finally(() => set_ssr_context(null)).catch(noop);
|
|
222
|
+
|
|
223
|
+
if (child.global.mode === 'sync') {
|
|
224
|
+
e.await_invalid();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
child.promise = result;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return child;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Render children inside an error boundary. If the children throw and the API-level
|
|
235
|
+
* `transformError` transform handles the error (doesn't re-throw), the `failed` snippet is
|
|
236
|
+
* rendered instead. Otherwise the error propagates.
|
|
237
|
+
*
|
|
238
|
+
* @param {{ failed?: (renderer: Renderer, error: unknown, reset: () => void) => void }} props
|
|
239
|
+
* @param {(renderer: Renderer) => MaybePromise<void>} children_fn
|
|
240
|
+
*/
|
|
241
|
+
boundary(props, children_fn) {
|
|
242
|
+
// Create a child renderer for the boundary content.
|
|
243
|
+
// Mark it as a boundary so that #collect_content_async can catch
|
|
244
|
+
// errors from nested async children and render the failed snippet.
|
|
245
|
+
const child = new Renderer(this.global, this);
|
|
246
|
+
this.#out.push(child);
|
|
247
|
+
|
|
248
|
+
const parent_context = ssr_context;
|
|
249
|
+
|
|
250
|
+
if (props.failed) {
|
|
251
|
+
child.#boundary = {
|
|
252
|
+
failed: props.failed,
|
|
253
|
+
transformError: this.global.transformError,
|
|
254
|
+
context: parent_context
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
set_ssr_context({
|
|
259
|
+
...ssr_context,
|
|
260
|
+
p: parent_context,
|
|
261
|
+
c: null,
|
|
262
|
+
r: child
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
try {
|
|
266
|
+
const result = children_fn(child);
|
|
267
|
+
|
|
268
|
+
set_ssr_context(parent_context);
|
|
269
|
+
|
|
270
|
+
if (result instanceof Promise) {
|
|
271
|
+
if (child.global.mode === 'sync') {
|
|
272
|
+
e.await_invalid();
|
|
273
|
+
}
|
|
274
|
+
result.catch(noop);
|
|
275
|
+
child.promise = result;
|
|
276
|
+
}
|
|
277
|
+
} catch (error) {
|
|
278
|
+
// synchronous errors are handled here, async errors will be handled in #collect_content_async
|
|
279
|
+
set_ssr_context(parent_context);
|
|
280
|
+
|
|
281
|
+
const failed_snippet = props.failed;
|
|
282
|
+
|
|
283
|
+
if (!failed_snippet) throw error;
|
|
284
|
+
|
|
285
|
+
const result = this.global.transformError(error);
|
|
286
|
+
|
|
287
|
+
child.#out.length = 0;
|
|
288
|
+
child.#boundary = null;
|
|
289
|
+
|
|
290
|
+
if (result instanceof Promise) {
|
|
291
|
+
if (this.global.mode === 'sync') {
|
|
292
|
+
e.await_invalid();
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
child.promise = /** @type {Promise<unknown>} */ (result).then((transformed) => {
|
|
296
|
+
child.#out.push(`<!--${HYDRATION_START_FAILED}${JSON.stringify(transformed)}-->`);
|
|
297
|
+
failed_snippet(child, transformed, noop);
|
|
298
|
+
child.#out.push(BLOCK_CLOSE);
|
|
299
|
+
});
|
|
300
|
+
child.promise.catch(noop);
|
|
301
|
+
} else {
|
|
302
|
+
child.#out.push(`<!--${HYDRATION_START_FAILED}${JSON.stringify(result)}-->`);
|
|
303
|
+
failed_snippet(child, result, noop);
|
|
304
|
+
child.#out.push(BLOCK_CLOSE);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Create a component renderer. The component renderer inherits the state from the parent,
|
|
311
|
+
* but has its own content. It is treated as an ordering boundary for ondestroy callbacks.
|
|
312
|
+
* @param {(renderer: Renderer) => MaybePromise<void>} fn
|
|
313
|
+
* @param {Function} [component_fn]
|
|
314
|
+
* @returns {void}
|
|
315
|
+
*/
|
|
316
|
+
component(fn, component_fn) {
|
|
317
|
+
push(component_fn);
|
|
318
|
+
const child = this.child(fn);
|
|
319
|
+
child.#is_component_body = true;
|
|
320
|
+
pop();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* @param {Record<string, any>} attrs
|
|
325
|
+
* @param {(renderer: Renderer) => void} fn
|
|
326
|
+
* @param {string | undefined} [css_hash]
|
|
327
|
+
* @param {Record<string, boolean> | undefined} [classes]
|
|
328
|
+
* @param {Record<string, string> | undefined} [styles]
|
|
329
|
+
* @param {number | undefined} [flags]
|
|
330
|
+
* @param {boolean | undefined} [is_rich]
|
|
331
|
+
* @returns {void}
|
|
332
|
+
*/
|
|
333
|
+
select(attrs, fn, css_hash, classes, styles, flags, is_rich) {
|
|
334
|
+
const { value, ...select_attrs } = attrs;
|
|
335
|
+
|
|
336
|
+
this.push(`<select${attributes(select_attrs, css_hash, classes, styles, flags)}>`);
|
|
337
|
+
this.child((renderer) => {
|
|
338
|
+
renderer.local.select_value = value;
|
|
339
|
+
fn(renderer);
|
|
340
|
+
});
|
|
341
|
+
this.push(`${is_rich ? '<!>' : ''}</select>`);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* @param {Record<string, any>} attrs
|
|
346
|
+
* @param {string | number | boolean | ((renderer: Renderer) => void)} body
|
|
347
|
+
* @param {string | undefined} [css_hash]
|
|
348
|
+
* @param {Record<string, boolean> | undefined} [classes]
|
|
349
|
+
* @param {Record<string, string> | undefined} [styles]
|
|
350
|
+
* @param {number | undefined} [flags]
|
|
351
|
+
* @param {boolean | undefined} [is_rich]
|
|
352
|
+
*/
|
|
353
|
+
option(attrs, body, css_hash, classes, styles, flags, is_rich) {
|
|
354
|
+
this.#out.push(`<option${attributes(attrs, css_hash, classes, styles, flags)}`);
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* @param {Renderer} renderer
|
|
358
|
+
* @param {any} value
|
|
359
|
+
* @param {{ head?: string, body: any }} content
|
|
360
|
+
*/
|
|
361
|
+
const close = (renderer, value, { head, body }) => {
|
|
362
|
+
if (has_own_property.call(attrs, 'value')) {
|
|
363
|
+
value = attrs.value;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (value === this.local.select_value) {
|
|
367
|
+
renderer.#out.push(' selected=""');
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
renderer.#out.push(`>${body}${is_rich ? '<!>' : ''}</option>`);
|
|
371
|
+
|
|
372
|
+
// super edge case, but may as well handle it
|
|
373
|
+
if (head) {
|
|
374
|
+
renderer.head((child) => child.push(head));
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
if (typeof body === 'function') {
|
|
379
|
+
this.child((renderer) => {
|
|
380
|
+
const r = new Renderer(this.global, this);
|
|
381
|
+
body(r);
|
|
382
|
+
|
|
383
|
+
if (this.global.mode === 'async') {
|
|
384
|
+
return r.#collect_content_async().then((content) => {
|
|
385
|
+
close(renderer, content.body.replaceAll('<!---->', ''), content);
|
|
386
|
+
});
|
|
387
|
+
} else {
|
|
388
|
+
const content = r.#collect_content();
|
|
389
|
+
close(renderer, content.body.replaceAll('<!---->', ''), content);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
} else {
|
|
393
|
+
close(this, body, { body: escape_html(body) });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @param {(renderer: Renderer) => void} fn
|
|
399
|
+
*/
|
|
400
|
+
title(fn) {
|
|
401
|
+
const path = this.get_path();
|
|
402
|
+
|
|
403
|
+
/** @param {string} head */
|
|
404
|
+
const close = (head) => {
|
|
405
|
+
this.global.set_title(head, path);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
this.child((renderer) => {
|
|
409
|
+
const r = new Renderer(renderer.global, renderer);
|
|
410
|
+
fn(r);
|
|
411
|
+
|
|
412
|
+
if (renderer.global.mode === 'async') {
|
|
413
|
+
return r.#collect_content_async().then((content) => {
|
|
414
|
+
close(content.head);
|
|
415
|
+
});
|
|
416
|
+
} else {
|
|
417
|
+
const content = r.#collect_content();
|
|
418
|
+
close(content.head);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* @param {string | (() => Promise<string>)} content
|
|
425
|
+
*/
|
|
426
|
+
push(content) {
|
|
427
|
+
if (typeof content === 'function') {
|
|
428
|
+
this.child(async (renderer) => renderer.push(await content()));
|
|
429
|
+
} else {
|
|
430
|
+
this.#out.push(content);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* @param {() => void} fn
|
|
436
|
+
*/
|
|
437
|
+
on_destroy(fn) {
|
|
438
|
+
(this.#on_destroy ??= []).push(fn);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* @returns {number[]}
|
|
443
|
+
*/
|
|
444
|
+
get_path() {
|
|
445
|
+
return this.#parent ? [...this.#parent.get_path(), this.#parent.#out.indexOf(this)] : [];
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* @deprecated this is needed for legacy component bindings
|
|
450
|
+
*/
|
|
451
|
+
copy() {
|
|
452
|
+
const copy = new Renderer(this.global, this.#parent);
|
|
453
|
+
copy.#out = this.#out.map((item) => (item instanceof Renderer ? item.copy() : item));
|
|
454
|
+
copy.promise = this.promise;
|
|
455
|
+
return copy;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* @param {Renderer} other
|
|
460
|
+
* @deprecated this is needed for legacy component bindings
|
|
461
|
+
*/
|
|
462
|
+
subsume(other) {
|
|
463
|
+
if (this.global.mode !== other.global.mode) {
|
|
464
|
+
throw new Error(
|
|
465
|
+
"invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
this.local = other.local;
|
|
470
|
+
this.#out = other.#out.map((item) => {
|
|
471
|
+
if (item instanceof Renderer) {
|
|
472
|
+
item.subsume(item);
|
|
473
|
+
}
|
|
474
|
+
return item;
|
|
475
|
+
});
|
|
476
|
+
this.promise = other.promise;
|
|
477
|
+
this.type = other.type;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
get length() {
|
|
481
|
+
return this.#out.length;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Only available on the server and when compiling with the `server` option.
|
|
486
|
+
* Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.
|
|
487
|
+
* @template {Record<string, any>} Props
|
|
488
|
+
* @param {Component<Props>} component
|
|
489
|
+
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} [options]
|
|
490
|
+
* @returns {RenderOutput}
|
|
491
|
+
*/
|
|
492
|
+
static render(component, options = {}) {
|
|
493
|
+
/** @type {AccumulatedContent | undefined} */
|
|
494
|
+
let sync;
|
|
495
|
+
/** @type {Promise<AccumulatedContent & { hashes: { script: Sha256Source[] } }> | undefined} */
|
|
496
|
+
let async;
|
|
497
|
+
|
|
498
|
+
const result = /** @type {RenderOutput} */ ({});
|
|
499
|
+
// making these properties non-enumerable so that console.logging
|
|
500
|
+
// doesn't trigger a sync render
|
|
501
|
+
Object.defineProperties(result, {
|
|
502
|
+
html: {
|
|
503
|
+
get: () => {
|
|
504
|
+
return (sync ??= Renderer.#render(component, options)).body;
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
head: {
|
|
508
|
+
get: () => {
|
|
509
|
+
return (sync ??= Renderer.#render(component, options)).head;
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
body: {
|
|
513
|
+
get: () => {
|
|
514
|
+
return (sync ??= Renderer.#render(component, options)).body;
|
|
515
|
+
}
|
|
516
|
+
},
|
|
517
|
+
hashes: {
|
|
518
|
+
value: {
|
|
519
|
+
script: ''
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
then: {
|
|
523
|
+
value:
|
|
524
|
+
/**
|
|
525
|
+
* this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
|
|
526
|
+
*
|
|
527
|
+
* @template TResult1
|
|
528
|
+
* @template [TResult2=never]
|
|
529
|
+
* @param { (value: SyncRenderOutput) => TResult1 } onfulfilled
|
|
530
|
+
* @param { (reason: unknown) => TResult2 } onrejected
|
|
531
|
+
*/
|
|
532
|
+
(onfulfilled, onrejected) => {
|
|
533
|
+
if (!async_mode_flag) {
|
|
534
|
+
const result = (sync ??= Renderer.#render(component, options));
|
|
535
|
+
const user_result = onfulfilled({
|
|
536
|
+
head: result.head,
|
|
537
|
+
body: result.body,
|
|
538
|
+
html: result.body,
|
|
539
|
+
hashes: { script: [] }
|
|
540
|
+
});
|
|
541
|
+
return Promise.resolve(user_result);
|
|
542
|
+
}
|
|
543
|
+
async ??= init_render_context().then(() =>
|
|
544
|
+
with_render_context(() => Renderer.#render_async(component, options))
|
|
545
|
+
);
|
|
546
|
+
return async.then((result) => {
|
|
547
|
+
Object.defineProperty(result, 'html', {
|
|
548
|
+
// eslint-disable-next-line getter-return
|
|
549
|
+
get: () => {
|
|
550
|
+
e.html_deprecated();
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
return onfulfilled(/** @type {SyncRenderOutput} */ (result));
|
|
554
|
+
}, onrejected);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
return result;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Collect all of the `onDestroy` callbacks registered during rendering. In an async context, this is only safe to call
|
|
564
|
+
* after awaiting `collect_async`.
|
|
565
|
+
*
|
|
566
|
+
* Child renderers are "porous" and don't affect execution order, but component body renderers
|
|
567
|
+
* create ordering boundaries. Within a renderer, callbacks run in order until hitting a component boundary.
|
|
568
|
+
* @returns {Iterable<() => void>}
|
|
569
|
+
*/
|
|
570
|
+
*#collect_on_destroy() {
|
|
571
|
+
for (const component of this.#traverse_components()) {
|
|
572
|
+
yield* component.#collect_ondestroy();
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Performs a depth-first search of renderers, yielding the deepest components first, then additional components as we backtrack up the tree.
|
|
578
|
+
* @returns {Iterable<Renderer>}
|
|
579
|
+
*/
|
|
580
|
+
*#traverse_components() {
|
|
581
|
+
for (const child of this.#out) {
|
|
582
|
+
if (typeof child !== 'string') {
|
|
583
|
+
yield* child.#traverse_components();
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
if (this.#is_component_body) {
|
|
587
|
+
yield this;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* @returns {Iterable<() => void>}
|
|
593
|
+
*/
|
|
594
|
+
*#collect_ondestroy() {
|
|
595
|
+
if (this.#on_destroy) {
|
|
596
|
+
for (const fn of this.#on_destroy) {
|
|
597
|
+
yield fn;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
for (const child of this.#out) {
|
|
601
|
+
if (child instanceof Renderer && !child.#is_component_body) {
|
|
602
|
+
yield* child.#collect_ondestroy();
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Render a component. Throws if any of the children are performing asynchronous work.
|
|
609
|
+
*
|
|
610
|
+
* @template {Record<string, any>} Props
|
|
611
|
+
* @param {Component<Props>} component
|
|
612
|
+
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
|
|
613
|
+
* @returns {AccumulatedContent}
|
|
614
|
+
*/
|
|
615
|
+
static #render(component, options) {
|
|
616
|
+
var previous_context = ssr_context;
|
|
617
|
+
try {
|
|
618
|
+
const renderer = Renderer.#open_render('sync', component, options);
|
|
619
|
+
|
|
620
|
+
const content = renderer.#collect_content();
|
|
621
|
+
return Renderer.#close_render(content, renderer);
|
|
622
|
+
} finally {
|
|
623
|
+
abort();
|
|
624
|
+
set_ssr_context(previous_context);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Render a component.
|
|
630
|
+
*
|
|
631
|
+
* @template {Record<string, any>} Props
|
|
632
|
+
* @param {Component<Props>} component
|
|
633
|
+
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} options
|
|
634
|
+
* @returns {Promise<AccumulatedContent & { hashes: { script: Sha256Source[] } }>}
|
|
635
|
+
*/
|
|
636
|
+
static async #render_async(component, options) {
|
|
637
|
+
const previous_context = ssr_context;
|
|
638
|
+
|
|
639
|
+
try {
|
|
640
|
+
const renderer = Renderer.#open_render('async', component, options);
|
|
641
|
+
const content = await renderer.#collect_content_async();
|
|
642
|
+
const hydratables = await renderer.#collect_hydratables();
|
|
643
|
+
if (hydratables !== null) {
|
|
644
|
+
content.head = hydratables + content.head;
|
|
645
|
+
}
|
|
646
|
+
return Renderer.#close_render(content, renderer);
|
|
647
|
+
} finally {
|
|
648
|
+
set_ssr_context(previous_context);
|
|
649
|
+
abort();
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Collect all of the code from the `out` array and return it as a string, or a promise resolving to a string.
|
|
655
|
+
* @param {AccumulatedContent} content
|
|
656
|
+
* @returns {AccumulatedContent}
|
|
657
|
+
*/
|
|
658
|
+
#collect_content(content = { head: '', body: '' }) {
|
|
659
|
+
for (const item of this.#out) {
|
|
660
|
+
if (typeof item === 'string') {
|
|
661
|
+
content[this.type] += item;
|
|
662
|
+
} else if (item instanceof Renderer) {
|
|
663
|
+
item.#collect_content(content);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
return content;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Collect all of the code from the `out` array and return it as a string.
|
|
672
|
+
* @param {AccumulatedContent} content
|
|
673
|
+
* @returns {Promise<AccumulatedContent>}
|
|
674
|
+
*/
|
|
675
|
+
async #collect_content_async(content = { head: '', body: '' }) {
|
|
676
|
+
await this.promise;
|
|
677
|
+
|
|
678
|
+
// no danger to sequentially awaiting stuff in here; all of the work is already kicked off
|
|
679
|
+
for (const item of this.#out) {
|
|
680
|
+
if (typeof item === 'string') {
|
|
681
|
+
content[this.type] += item;
|
|
682
|
+
} else if (item instanceof Renderer) {
|
|
683
|
+
if (item.#boundary) {
|
|
684
|
+
// This renderer is an error boundary - collect into a separate
|
|
685
|
+
// accumulator so we can discard partial content on error
|
|
686
|
+
/** @type {AccumulatedContent} */
|
|
687
|
+
const boundary_content = { head: '', body: '' };
|
|
688
|
+
|
|
689
|
+
try {
|
|
690
|
+
await item.#collect_content_async(boundary_content);
|
|
691
|
+
// Success - merge into the main content
|
|
692
|
+
content.head += boundary_content.head;
|
|
693
|
+
content.body += boundary_content.body;
|
|
694
|
+
} catch (error) {
|
|
695
|
+
const { context, failed, transformError } = item.#boundary;
|
|
696
|
+
|
|
697
|
+
set_ssr_context(context);
|
|
698
|
+
let transformed = await transformError(error);
|
|
699
|
+
|
|
700
|
+
// Render the failed snippet instead of the partial children content
|
|
701
|
+
const failed_renderer = new Renderer(item.global, item);
|
|
702
|
+
failed_renderer.type = item.type;
|
|
703
|
+
failed_renderer.#out.push(
|
|
704
|
+
`<!--${HYDRATION_START_FAILED}${JSON.stringify(transformed)}-->`
|
|
705
|
+
);
|
|
706
|
+
failed(failed_renderer, transformed, noop);
|
|
707
|
+
failed_renderer.#out.push(BLOCK_CLOSE);
|
|
708
|
+
await failed_renderer.#collect_content_async(content);
|
|
709
|
+
}
|
|
710
|
+
} else {
|
|
711
|
+
await item.#collect_content_async(content);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
return content;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
async #collect_hydratables() {
|
|
720
|
+
const ctx = get_render_context().hydratable;
|
|
721
|
+
|
|
722
|
+
for (const [_, key] of ctx.unresolved_promises) {
|
|
723
|
+
// this is a problem -- it means we've finished the render but we're still waiting on a promise to resolve so we can
|
|
724
|
+
// serialize it, so we're blocking the response on useless content.
|
|
725
|
+
w.unresolved_hydratable(key, ctx.lookup.get(key)?.stack ?? '<missing stack trace>');
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
for (const comparison of ctx.comparisons) {
|
|
729
|
+
// these reject if there's a mismatch
|
|
730
|
+
await comparison;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
return await this.#hydratable_block(ctx);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* @template {Record<string, any>} Props
|
|
738
|
+
* @param {'sync' | 'async'} mode
|
|
739
|
+
* @param {import('svelte').Component<Props>} component
|
|
740
|
+
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp; transformError?: (error: unknown) => unknown }} options
|
|
741
|
+
* @returns {Renderer}
|
|
742
|
+
*/
|
|
743
|
+
static #open_render(mode, component, options) {
|
|
744
|
+
var previous_context = ssr_context;
|
|
745
|
+
|
|
746
|
+
try {
|
|
747
|
+
const renderer = new Renderer(
|
|
748
|
+
new SSRState(
|
|
749
|
+
mode,
|
|
750
|
+
options.idPrefix ? options.idPrefix + '-' : '',
|
|
751
|
+
options.csp,
|
|
752
|
+
options.transformError
|
|
753
|
+
)
|
|
754
|
+
);
|
|
755
|
+
|
|
756
|
+
/** @type {SSRContext} */
|
|
757
|
+
const context = { p: null, c: options.context ?? null, r: renderer };
|
|
758
|
+
set_ssr_context(context);
|
|
759
|
+
|
|
760
|
+
renderer.push(BLOCK_OPEN);
|
|
761
|
+
// @ts-expect-error
|
|
762
|
+
component(renderer, options.props ?? {});
|
|
763
|
+
renderer.push(BLOCK_CLOSE);
|
|
764
|
+
|
|
765
|
+
return renderer;
|
|
766
|
+
} finally {
|
|
767
|
+
set_ssr_context(previous_context);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* @param {AccumulatedContent} content
|
|
773
|
+
* @param {Renderer} renderer
|
|
774
|
+
* @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }}
|
|
775
|
+
*/
|
|
776
|
+
static #close_render(content, renderer) {
|
|
777
|
+
for (const cleanup of renderer.#collect_on_destroy()) {
|
|
778
|
+
cleanup();
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
let head = content.head + renderer.global.get_title();
|
|
782
|
+
let body = content.body;
|
|
783
|
+
|
|
784
|
+
for (const { hash, code } of renderer.global.css) {
|
|
785
|
+
head += `<style id="${hash}">${code}</style>`;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
return {
|
|
789
|
+
head,
|
|
790
|
+
body,
|
|
791
|
+
hashes: {
|
|
792
|
+
script: renderer.global.csp.script_hashes
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* @param {HydratableContext} ctx
|
|
799
|
+
*/
|
|
800
|
+
async #hydratable_block(ctx) {
|
|
801
|
+
if (ctx.lookup.size === 0) {
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
let entries = [];
|
|
806
|
+
let has_promises = false;
|
|
807
|
+
|
|
808
|
+
for (const [k, v] of ctx.lookup) {
|
|
809
|
+
if (v.promises) {
|
|
810
|
+
has_promises = true;
|
|
811
|
+
for (const p of v.promises) await p;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
entries.push(`[${devalue.uneval(k)},${v.serialized}]`);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
let prelude = `const h = (window.__svelte ??= {}).h ??= new Map();`;
|
|
818
|
+
|
|
819
|
+
if (has_promises) {
|
|
820
|
+
prelude = `const r = (v) => Promise.resolve(v);
|
|
821
|
+
${prelude}`;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
const body = `
|
|
825
|
+
{
|
|
826
|
+
${prelude}
|
|
827
|
+
|
|
828
|
+
for (const [k, v] of [
|
|
829
|
+
${entries.join(',\n\t\t\t\t\t')}
|
|
830
|
+
]) {
|
|
831
|
+
h.set(k, v);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
`;
|
|
835
|
+
|
|
836
|
+
let csp_attr = '';
|
|
837
|
+
if (this.global.csp.nonce) {
|
|
838
|
+
csp_attr = ` nonce="${this.global.csp.nonce}"`;
|
|
839
|
+
} else if (this.global.csp.hash) {
|
|
840
|
+
// note to future selves: this doesn't need to be optimized with a Map<body, hash>
|
|
841
|
+
// because the it's impossible for identical data to occur multiple times in a single render
|
|
842
|
+
// (this would require the same hydratable key:value pair to be serialized multiple times)
|
|
843
|
+
const hash = await sha256(body);
|
|
844
|
+
this.global.csp.script_hashes.push(`sha256-${hash}`);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
return `\n\t\t<script${csp_attr}>${body}</script>`;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
export class SSRState {
|
|
852
|
+
/** @readonly @type {Csp & { script_hashes: Sha256Source[] }} */
|
|
853
|
+
csp;
|
|
854
|
+
|
|
855
|
+
/** @readonly @type {'sync' | 'async'} */
|
|
856
|
+
mode;
|
|
857
|
+
|
|
858
|
+
/** @readonly @type {() => string} */
|
|
859
|
+
uid;
|
|
860
|
+
|
|
861
|
+
/** @readonly @type {Set<{ hash: string; code: string }>} */
|
|
862
|
+
css = new Set();
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* `transformError` passed to `render`. Called when an error boundary catches an error.
|
|
866
|
+
* Throws by default if unset in `render`.
|
|
867
|
+
* @type {(error: unknown) => unknown}
|
|
868
|
+
*/
|
|
869
|
+
transformError;
|
|
870
|
+
|
|
871
|
+
/** @type {{ path: number[], value: string }} */
|
|
872
|
+
#title = { path: [], value: '' };
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* @param {'sync' | 'async'} mode
|
|
876
|
+
* @param {string} id_prefix
|
|
877
|
+
* @param {Csp} csp
|
|
878
|
+
* @param {((error: unknown) => unknown) | undefined} [transformError]
|
|
879
|
+
*/
|
|
880
|
+
constructor(mode, id_prefix = '', csp = { hash: false }, transformError) {
|
|
881
|
+
this.mode = mode;
|
|
882
|
+
this.csp = { ...csp, script_hashes: [] };
|
|
883
|
+
|
|
884
|
+
this.transformError =
|
|
885
|
+
transformError ??
|
|
886
|
+
((error) => {
|
|
887
|
+
throw error;
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
let uid = 1;
|
|
891
|
+
this.uid = () => `${id_prefix}s${uid++}`;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
get_title() {
|
|
895
|
+
return this.#title.value;
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* Performs a depth-first (lexicographic) comparison using the path. Rejects sets
|
|
900
|
+
* from earlier than or equal to the current value.
|
|
901
|
+
* @param {string} value
|
|
902
|
+
* @param {number[]} path
|
|
903
|
+
*/
|
|
904
|
+
set_title(value, path) {
|
|
905
|
+
const current = this.#title.path;
|
|
906
|
+
|
|
907
|
+
let i = 0;
|
|
908
|
+
let l = Math.min(path.length, current.length);
|
|
909
|
+
|
|
910
|
+
// skip identical prefixes - [1, 2, 3, ...] === [1, 2, 3, ...]
|
|
911
|
+
while (i < l && path[i] === current[i]) i += 1;
|
|
912
|
+
|
|
913
|
+
if (path[i] === undefined) return;
|
|
914
|
+
|
|
915
|
+
// replace title if
|
|
916
|
+
// - incoming path is longer - [7, 8, 9] > [7, 8]
|
|
917
|
+
// - incoming path is later - [7, 8, 9] > [7, 8, 8]
|
|
918
|
+
if (current[i] === undefined || path[i] > current[i]) {
|
|
919
|
+
this.#title.path = path;
|
|
920
|
+
this.#title.value = value;
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|