@gyral/core 0.2.0 → 0.3.1
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/CHANGELOG.md +129 -0
- package/NOTICE +19 -0
- package/README.md +35 -8
- package/dist/call.d.ts +32 -0
- package/dist/call.js +63 -0
- package/dist/call.js.map +1 -0
- package/dist/children.d.ts +30 -5
- package/dist/children.js +26 -4
- package/dist/children.js.map +1 -1
- package/dist/cli/gyral-types.d.ts +2 -0
- package/dist/cli/gyral-types.js +23 -0
- package/dist/cli/gyral-types.js.map +1 -0
- package/dist/command.d.ts +54 -12
- package/dist/command.js +31 -11
- package/dist/command.js.map +1 -1
- package/dist/compiler/ast.d.ts +23 -0
- package/dist/compiler/ast.js +149 -0
- package/dist/compiler/ast.js.map +1 -0
- package/dist/compiler/compile.d.ts +41 -0
- package/dist/compiler/compile.js +148 -0
- package/dist/compiler/compile.js.map +1 -0
- package/dist/compiler/component-entries.d.ts +7 -0
- package/dist/compiler/component-entries.js +42 -0
- package/dist/compiler/component-entries.js.map +1 -0
- package/dist/compiler/components.d.ts +4 -0
- package/dist/compiler/components.js +182 -0
- package/dist/compiler/components.js.map +1 -0
- package/dist/compiler/facts.d.ts +31 -0
- package/dist/compiler/facts.js +285 -0
- package/dist/compiler/facts.js.map +1 -0
- package/dist/compiler/features.d.ts +34 -0
- package/dist/compiler/features.js +158 -0
- package/dist/compiler/features.js.map +1 -0
- package/dist/compiler/hooks.d.ts +22 -0
- package/dist/compiler/hooks.js +241 -0
- package/dist/compiler/hooks.js.map +1 -0
- package/dist/compiler/loader-source.d.ts +14 -0
- package/dist/compiler/loader-source.js +86 -0
- package/dist/compiler/loader-source.js.map +1 -0
- package/dist/compiler/locate.d.ts +14 -0
- package/dist/compiler/locate.js +78 -0
- package/dist/compiler/locate.js.map +1 -0
- package/dist/compiler/parse5-check.d.ts +21 -0
- package/dist/compiler/parse5-check.js +60 -0
- package/dist/compiler/parse5-check.js.map +1 -0
- package/dist/compiler/prop-schemas.d.ts +4 -0
- package/dist/compiler/prop-schemas.js +108 -0
- package/dist/compiler/prop-schemas.js.map +1 -0
- package/dist/compiler/scan.d.ts +41 -0
- package/dist/compiler/scan.js +160 -0
- package/dist/compiler/scan.js.map +1 -0
- package/dist/compiler/scope.d.ts +8 -0
- package/dist/compiler/scope.js +116 -0
- package/dist/compiler/scope.js.map +1 -0
- package/dist/compiler/source.d.ts +34 -0
- package/dist/compiler/source.js +114 -0
- package/dist/compiler/source.js.map +1 -0
- package/dist/compiler/tag-map.d.ts +41 -0
- package/dist/compiler/tag-map.js +126 -0
- package/dist/compiler/tag-map.js.map +1 -0
- package/dist/components-ready.d.ts +7 -0
- package/dist/components-ready.js +19 -0
- package/dist/components-ready.js.map +1 -0
- package/dist/define.d.ts +13 -4
- package/dist/define.js +35 -331
- package/dist/define.js.map +1 -1
- package/dist/devtools-events.d.ts +13 -0
- package/dist/devtools-events.js.map +1 -1
- package/dist/devtools-off.d.ts +2 -0
- package/dist/devtools-off.js +2 -0
- package/dist/devtools-off.js.map +1 -1
- package/dist/devtools.d.ts +4 -0
- package/dist/devtools.js +17 -2
- package/dist/devtools.js.map +1 -1
- package/dist/drivers-scope.d.ts +1 -1
- package/dist/drivers-scope.js +1 -8
- package/dist/drivers-scope.js.map +1 -1
- package/dist/element-internals.d.ts +1 -0
- package/dist/element-internals.js +11 -0
- package/dist/element-internals.js.map +1 -0
- package/dist/element-types.d.ts +11 -5
- package/dist/element-types.js.map +1 -1
- package/dist/element.d.ts +3 -0
- package/dist/element.js +322 -0
- package/dist/element.js.map +1 -0
- package/dist/error-view.d.ts +10 -0
- package/dist/error-view.js +30 -0
- package/dist/error-view.js.map +1 -0
- package/dist/errors.d.ts +21 -0
- package/dist/errors.js +47 -0
- package/dist/errors.js.map +1 -0
- package/dist/errors.json +289 -0
- package/dist/eslint/imports.d.ts +26 -0
- package/dist/eslint/imports.js +78 -0
- package/dist/eslint/imports.js.map +1 -0
- package/dist/eslint/index.d.ts +16 -0
- package/dist/eslint/index.js +23 -0
- package/dist/eslint/index.js.map +1 -0
- package/dist/eslint/locate.d.ts +33 -0
- package/dist/eslint/locate.js +132 -0
- package/dist/eslint/locate.js.map +1 -0
- package/dist/eslint/row-purity-rule.d.ts +2 -0
- package/dist/eslint/row-purity-rule.js +103 -0
- package/dist/eslint/row-purity-rule.js.map +1 -0
- package/dist/eslint/template-rule.d.ts +6 -0
- package/dist/eslint/template-rule.js +76 -0
- package/dist/eslint/template-rule.js.map +1 -0
- package/dist/eslint/unused-intent-rule.d.ts +2 -0
- package/dist/eslint/unused-intent-rule.js +186 -0
- package/dist/eslint/unused-intent-rule.js.map +1 -0
- package/dist/features.d.ts +39 -0
- package/dist/features.js +2 -0
- package/dist/features.js.map +1 -0
- package/dist/focus.d.ts +13 -12
- package/dist/focus.js +44 -11
- package/dist/focus.js.map +1 -1
- package/dist/form-associated.d.ts +46 -0
- package/dist/form-associated.js +77 -0
- package/dist/form-associated.js.map +1 -0
- package/dist/forms.d.ts +42 -30
- package/dist/forms.js +85 -41
- package/dist/forms.js.map +1 -1
- package/dist/frame-lane.d.ts +11 -0
- package/dist/frame-lane.js +28 -0
- package/dist/frame-lane.js.map +1 -0
- package/dist/head.d.ts +61 -0
- package/dist/head.js +85 -0
- package/dist/head.js.map +1 -0
- package/dist/hooks/invalid.d.ts +14 -0
- package/dist/hooks/invalid.js +72 -0
- package/dist/hooks/invalid.js.map +1 -0
- package/dist/host-model.d.ts +77 -0
- package/dist/host-model.js +278 -0
- package/dist/host-model.js.map +1 -0
- package/dist/hydration-client.d.ts +9 -0
- package/dist/hydration-client.js +35 -0
- package/dist/hydration-client.js.map +1 -0
- package/dist/hydration-loader.d.ts +13 -0
- package/dist/hydration-loader.js +58 -0
- package/dist/hydration-loader.js.map +1 -0
- package/dist/hydration-off.d.ts +8 -0
- package/dist/hydration-off.js +25 -0
- package/dist/hydration-off.js.map +1 -0
- package/dist/hydration.d.ts +3 -21
- package/dist/hydration.js +14 -63
- package/dist/hydration.js.map +1 -1
- package/dist/index.d.ts +24 -36
- package/dist/index.js +14 -32
- package/dist/index.js.map +1 -1
- package/dist/indexeddb-types.d.ts +97 -0
- package/dist/indexeddb-types.js +2 -0
- package/dist/indexeddb-types.js.map +1 -0
- package/dist/indexeddb.d.ts +5 -0
- package/dist/indexeddb.js +118 -0
- package/dist/indexeddb.js.map +1 -0
- package/dist/intent.d.ts +62 -17
- package/dist/intent.js +193 -100
- package/dist/intent.js.map +1 -1
- package/dist/internal/indexeddb-open.d.ts +8 -0
- package/dist/internal/indexeddb-open.js +96 -0
- package/dist/internal/indexeddb-open.js.map +1 -0
- package/dist/internal/indexeddb-transaction.d.ts +4 -0
- package/dist/internal/indexeddb-transaction.js +134 -0
- package/dist/internal/indexeddb-transaction.js.map +1 -0
- package/dist/internal/interpreter.d.ts +15 -1
- package/dist/internal/interpreter.js +42 -47
- package/dist/internal/interpreter.js.map +1 -1
- package/dist/internal/token.d.ts +1 -0
- package/dist/internal/token.js +7 -0
- package/dist/internal/token.js.map +1 -0
- package/dist/internal.d.ts +20 -0
- package/dist/internal.js +22 -0
- package/dist/internal.js.map +1 -0
- package/dist/invoker-fallback-used.d.ts +4 -0
- package/dist/invoker-fallback-used.js +10 -0
- package/dist/invoker-fallback-used.js.map +1 -0
- package/dist/invoker-fallback.d.ts +4 -0
- package/dist/invoker-fallback.js +15 -0
- package/dist/invoker-fallback.js.map +1 -0
- package/dist/invokers-shim.d.ts +6 -0
- package/dist/invokers-shim.js +32 -0
- package/dist/invokers-shim.js.map +1 -0
- package/dist/invokers.d.ts +3 -5
- package/dist/invokers.js +11 -51
- package/dist/invokers.js.map +1 -1
- package/dist/islands.d.ts +0 -2
- package/dist/islands.js +4 -11
- package/dist/islands.js.map +1 -1
- package/dist/light-dom.d.ts +4 -53
- package/dist/light-dom.js +5 -100
- package/dist/light-dom.js.map +1 -1
- package/dist/prop.d.ts +89 -0
- package/dist/prop.js +41 -0
- package/dist/prop.js.map +1 -0
- package/dist/props.d.ts +57 -21
- package/dist/props.js +157 -34
- package/dist/props.js.map +1 -1
- package/dist/retry.d.ts +15 -0
- package/dist/retry.js +48 -0
- package/dist/retry.js.map +1 -0
- package/dist/scheduler.d.ts +43 -0
- package/dist/scheduler.js +212 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/script-json.d.ts +2 -0
- package/dist/script-json.js +13 -0
- package/dist/script-json.js.map +1 -0
- package/dist/server-component.d.ts +10 -0
- package/dist/server-component.js +133 -0
- package/dist/server-component.js.map +1 -0
- package/dist/server-specs.d.ts +6 -0
- package/dist/server-specs.js +13 -0
- package/dist/server-specs.js.map +1 -0
- package/dist/server.d.ts +34 -0
- package/dist/server.js +59 -0
- package/dist/server.js.map +1 -0
- package/dist/settled.d.ts +11 -0
- package/dist/settled.js +62 -0
- package/dist/settled.js.map +1 -0
- package/dist/spec-features-used.d.ts +21 -0
- package/dist/spec-features-used.js +50 -0
- package/dist/spec-features-used.js.map +1 -0
- package/dist/spec-features.d.ts +28 -0
- package/dist/spec-features.js +42 -0
- package/dist/spec-features.js.map +1 -0
- package/dist/states.d.ts +3 -5
- package/dist/states.js +22 -11
- package/dist/states.js.map +1 -1
- package/dist/storage.d.ts +69 -0
- package/dist/storage.js +158 -0
- package/dist/storage.js.map +1 -0
- package/dist/store-binding.d.ts +6 -3
- package/dist/store-binding.js +7 -8
- package/dist/store-binding.js.map +1 -1
- package/dist/store-scope.d.ts +8 -11
- package/dist/store-scope.js +15 -40
- package/dist/store-scope.js.map +1 -1
- package/dist/store.d.ts +3 -0
- package/dist/store.js +45 -10
- package/dist/store.js.map +1 -1
- package/dist/stores-provider.d.ts +2 -6
- package/dist/stores-provider.js +21 -55
- package/dist/stores-provider.js.map +1 -1
- package/dist/subscription.d.ts +35 -0
- package/dist/subscription.js +74 -0
- package/dist/subscription.js.map +1 -0
- package/dist/subscriptions.d.ts +26 -0
- package/dist/subscriptions.js +98 -0
- package/dist/subscriptions.js.map +1 -0
- package/dist/transitions.d.ts +5 -7
- package/dist/transitions.js +17 -20
- package/dist/transitions.js.map +1 -1
- package/dist/types.d.ts +142 -49
- package/dist/types.js.map +1 -1
- package/dist/use-dialogs.d.ts +2 -0
- package/dist/use-dialogs.js +9 -0
- package/dist/use-dialogs.js.map +1 -0
- package/dist/use-disposal.d.ts +2 -0
- package/dist/use-disposal.js +9 -0
- package/dist/use-disposal.js.map +1 -0
- package/dist/use-error-view.d.ts +2 -0
- package/dist/use-error-view.js +9 -0
- package/dist/use-error-view.js.map +1 -0
- package/dist/use-errored.d.ts +2 -0
- package/dist/use-errored.js +9 -0
- package/dist/use-errored.js.map +1 -0
- package/dist/use-form-associated.d.ts +2 -0
- package/dist/use-form-associated.js +7 -0
- package/dist/use-form-associated.js.map +1 -0
- package/dist/use-frame-lane.d.ts +2 -0
- package/dist/use-frame-lane.js +10 -0
- package/dist/use-frame-lane.js.map +1 -0
- package/dist/use-invokers.d.ts +2 -0
- package/dist/use-invokers.js +10 -0
- package/dist/use-invokers.js.map +1 -0
- package/dist/use-states.d.ts +2 -0
- package/dist/use-states.js +10 -0
- package/dist/use-states.js.map +1 -0
- package/dist/use-subscriptions.d.ts +2 -0
- package/dist/use-subscriptions.js +10 -0
- package/dist/use-subscriptions.js.map +1 -0
- package/dist/use-transitions.d.ts +2 -0
- package/dist/use-transitions.js +10 -0
- package/dist/use-transitions.js.map +1 -0
- package/dist/view/attributes.d.ts +11 -0
- package/dist/view/attributes.js +15 -0
- package/dist/view/attributes.js.map +1 -0
- package/dist/view/compiled.d.ts +1 -0
- package/dist/view/compiled.js +6 -0
- package/dist/view/compiled.js.map +1 -0
- package/dist/view/dev-off.d.ts +1 -0
- package/dist/view/dev-off.js +4 -0
- package/dist/view/dev-off.js.map +1 -0
- package/dist/view/dev.d.ts +1 -0
- package/dist/view/dev.js +5 -0
- package/dist/view/dev.js.map +1 -0
- package/dist/view/flags.d.ts +1 -0
- package/dist/view/flags.js +4 -0
- package/dist/view/flags.js.map +1 -0
- package/dist/view/index.d.ts +26 -0
- package/dist/view/index.js +27 -0
- package/dist/view/index.js.map +1 -0
- package/dist/view/loc.d.ts +9 -0
- package/dist/view/loc.js +50 -0
- package/dist/view/loc.js.map +1 -0
- package/dist/view/message.d.ts +17 -0
- package/dist/view/message.js +40 -0
- package/dist/view/message.js.map +1 -0
- package/dist/view/messages.d.ts +43 -0
- package/dist/view/messages.js +84 -0
- package/dist/view/messages.js.map +1 -0
- package/dist/view/normalize/check.d.ts +23 -0
- package/dist/view/normalize/check.js +81 -0
- package/dist/view/normalize/check.js.map +1 -0
- package/dist/view/normalize/emit.d.ts +15 -0
- package/dist/view/normalize/emit.js +165 -0
- package/dist/view/normalize/emit.js.map +1 -0
- package/dist/view/normalize/entities.d.ts +4 -0
- package/dist/view/normalize/entities.js +38 -0
- package/dist/view/normalize/entities.js.map +1 -0
- package/dist/view/normalize/errors.d.ts +9 -0
- package/dist/view/normalize/errors.js +19 -0
- package/dist/view/normalize/errors.js.map +1 -0
- package/dist/view/normalize/id.d.ts +10 -0
- package/dist/view/normalize/id.js +55 -0
- package/dist/view/normalize/id.js.map +1 -0
- package/dist/view/normalize/normalize.d.ts +18 -0
- package/dist/view/normalize/normalize.js +42 -0
- package/dist/view/normalize/normalize.js.map +1 -0
- package/dist/view/normalize/repairs.d.ts +24 -0
- package/dist/view/normalize/repairs.js +166 -0
- package/dist/view/normalize/repairs.js.map +1 -0
- package/dist/view/normalize/rules.d.ts +39 -0
- package/dist/view/normalize/rules.js +120 -0
- package/dist/view/normalize/rules.js.map +1 -0
- package/dist/view/normalize/shape.d.ts +5 -0
- package/dist/view/normalize/shape.js +38 -0
- package/dist/view/normalize/shape.js.map +1 -0
- package/dist/view/normalize/source.d.ts +13 -0
- package/dist/view/normalize/source.js +34 -0
- package/dist/view/normalize/source.js.map +1 -0
- package/dist/view/normalize/svg.d.ts +14 -0
- package/dist/view/normalize/svg.js +40 -0
- package/dist/view/normalize/svg.js.map +1 -0
- package/dist/view/normalize/tag-states.d.ts +23 -0
- package/dist/view/normalize/tag-states.js +192 -0
- package/dist/view/normalize/tag-states.js.map +1 -0
- package/dist/view/normalize/tokenizer.d.ts +5 -0
- package/dist/view/normalize/tokenizer.js +233 -0
- package/dist/view/normalize/tokenizer.js.map +1 -0
- package/dist/view/normalize/tokens.d.ts +55 -0
- package/dist/view/normalize/tokens.js +24 -0
- package/dist/view/normalize/tokens.js.map +1 -0
- package/dist/view/normalize/tree.d.ts +65 -0
- package/dist/view/normalize/tree.js +235 -0
- package/dist/view/normalize/tree.js.map +1 -0
- package/dist/view/normalize/types.d.ts +146 -0
- package/dist/view/normalize/types.js +29 -0
- package/dist/view/normalize/types.js.map +1 -0
- package/dist/view/normalize/whitespace.d.ts +2 -0
- package/dist/{template-whitespace.js → view/normalize/whitespace.js} +27 -36
- package/dist/view/normalize/whitespace.js.map +1 -0
- package/dist/view/prepare-stub.d.ts +3 -0
- package/dist/view/prepare-stub.js +7 -0
- package/dist/view/prepare-stub.js.map +1 -0
- package/dist/view/prepare.d.ts +11 -0
- package/dist/view/prepare.js +63 -0
- package/dist/view/prepare.js.map +1 -0
- package/dist/view/registry.d.ts +78 -0
- package/dist/view/registry.js +27 -0
- package/dist/view/registry.js.map +1 -0
- package/dist/view/render/adopt-attr.d.ts +14 -0
- package/dist/view/render/adopt-attr.js +83 -0
- package/dist/view/render/adopt-attr.js.map +1 -0
- package/dist/view/render/adopt-plan.d.ts +10 -0
- package/dist/view/render/adopt-plan.js +26 -0
- package/dist/view/render/adopt-plan.js.map +1 -0
- package/dist/view/render/adopt.d.ts +3 -0
- package/dist/view/render/adopt.js +286 -0
- package/dist/view/render/adopt.js.map +1 -0
- package/dist/view/render/attr-parts.d.ts +72 -0
- package/dist/view/render/attr-parts.js +262 -0
- package/dist/view/render/attr-parts.js.map +1 -0
- package/dist/view/render/child-part.d.ts +51 -0
- package/dist/view/render/child-part.js +173 -0
- package/dist/view/render/child-part.js.map +1 -0
- package/dist/view/render/dev-check.d.ts +12 -0
- package/dist/view/render/dev-check.js +122 -0
- package/dist/view/render/dev-check.js.map +1 -0
- package/dist/view/render/dispose.d.ts +3 -0
- package/dist/view/render/dispose.js +76 -0
- package/dist/view/render/dispose.js.map +1 -0
- package/dist/view/render/hook-part.d.ts +5 -0
- package/dist/view/render/hook-part.js +36 -0
- package/dist/view/render/hook-part.js.map +1 -0
- package/dist/view/render/hook-run.d.ts +2 -0
- package/dist/view/render/hook-run.js +72 -0
- package/dist/view/render/hook-run.js.map +1 -0
- package/dist/view/render/hooks.d.ts +108 -0
- package/dist/view/render/hooks.js +108 -0
- package/dist/view/render/hooks.js.map +1 -0
- package/dist/view/render/hydrate.d.ts +10 -0
- package/dist/view/render/hydrate.js +33 -0
- package/dist/view/render/hydrate.js.map +1 -0
- package/dist/view/render/instance.d.ts +33 -0
- package/dist/view/render/instance.js +107 -0
- package/dist/view/render/instance.js.map +1 -0
- package/dist/view/render/keyed.d.ts +6 -0
- package/dist/view/render/keyed.js +15 -0
- package/dist/view/render/keyed.js.map +1 -0
- package/dist/view/render/list.d.ts +20 -0
- package/dist/view/render/list.js +156 -0
- package/dist/view/render/list.js.map +1 -0
- package/dist/view/render/mismatch.d.ts +10 -0
- package/dist/view/render/mismatch.js +55 -0
- package/dist/view/render/mismatch.js.map +1 -0
- package/dist/view/render/modal.d.ts +3 -0
- package/dist/view/render/modal.js +39 -0
- package/dist/view/render/modal.js.map +1 -0
- package/dist/view/render/nodes.d.ts +10 -0
- package/dist/view/render/nodes.js +37 -0
- package/dist/view/render/nodes.js.map +1 -0
- package/dist/view/render/place.d.ts +18 -0
- package/dist/view/render/place.js +69 -0
- package/dist/view/render/place.js.map +1 -0
- package/dist/view/render/plan.d.ts +26 -0
- package/dist/view/render/plan.js +124 -0
- package/dist/view/render/plan.js.map +1 -0
- package/dist/view/render/raw.d.ts +21 -0
- package/dist/view/render/raw.js +72 -0
- package/dist/view/render/raw.js.map +1 -0
- package/dist/view/render/render.d.ts +15 -0
- package/dist/view/render/render.js +65 -0
- package/dist/view/render/render.js.map +1 -0
- package/dist/view/render/reorder.d.ts +4 -0
- package/dist/view/render/reorder.js +101 -0
- package/dist/view/render/reorder.js.map +1 -0
- package/dist/view/render/rows.d.ts +23 -0
- package/dist/view/render/rows.js +95 -0
- package/dist/view/render/rows.js.map +1 -0
- package/dist/view/render/seen.d.ts +11 -0
- package/dist/view/render/seen.js +17 -0
- package/dist/view/render/seen.js.map +1 -0
- package/dist/view/render/toggles.d.ts +6 -0
- package/dist/view/render/toggles.js +6 -0
- package/dist/view/render/toggles.js.map +1 -0
- package/dist/view/render/values.d.ts +29 -0
- package/dist/view/render/values.js +13 -0
- package/dist/view/render/values.js.map +1 -0
- package/dist/view/render/warn.d.ts +28 -0
- package/dist/view/render/warn.js +114 -0
- package/dist/view/render/warn.js.map +1 -0
- package/dist/view/server/component.d.ts +12 -0
- package/dist/view/server/component.js +64 -0
- package/dist/view/server/component.js.map +1 -0
- package/dist/view/server/escape.d.ts +10 -0
- package/dist/view/server/escape.js +34 -0
- package/dist/view/server/escape.js.map +1 -0
- package/dist/view/server/index.d.ts +48 -0
- package/dist/view/server/index.js +80 -0
- package/dist/view/server/index.js.map +1 -0
- package/dist/view/server/sha256.d.ts +2 -0
- package/dist/view/server/sha256.js +75 -0
- package/dist/view/server/sha256.js.map +1 -0
- package/dist/view/server/tags.d.ts +68 -0
- package/dist/view/server/tags.js +132 -0
- package/dist/view/server/tags.js.map +1 -0
- package/dist/view/server/values.d.ts +18 -0
- package/dist/view/server/values.js +94 -0
- package/dist/view/server/values.js.map +1 -0
- package/dist/view/server/writer.d.ts +21 -0
- package/dist/view/server/writer.js +170 -0
- package/dist/view/server/writer.js.map +1 -0
- package/dist/view/styles.d.ts +25 -0
- package/dist/view/styles.js +58 -0
- package/dist/view/styles.js.map +1 -0
- package/dist/view/template-element.d.ts +10 -0
- package/dist/view/template-element.js +45 -0
- package/dist/view/template-element.js.map +1 -0
- package/dist/view/template.d.ts +29 -0
- package/dist/view/template.js +84 -0
- package/dist/view/template.js.map +1 -0
- package/dist/view/trusted-html.d.ts +6 -0
- package/dist/view/trusted-html.js +34 -0
- package/dist/view/trusted-html.js.map +1 -0
- package/dist/vite.d.ts +57 -11
- package/dist/vite.js +319 -27
- package/dist/vite.js.map +1 -1
- package/package.json +70 -4
- package/dist/accessible-name.d.ts +0 -19
- package/dist/accessible-name.js +0 -56
- package/dist/accessible-name.js.map +0 -1
- package/dist/element-directive.d.ts +0 -20
- package/dist/element-directive.js +0 -31
- package/dist/element-directive.js.map +0 -1
- package/dist/invalid.d.ts +0 -21
- package/dist/invalid.js +0 -70
- package/dist/invalid.js.map +0 -1
- package/dist/lit-html-check.d.ts +0 -6
- package/dist/lit-html-check.js +0 -48
- package/dist/lit-html-check.js.map +0 -1
- package/dist/live-boolean.d.ts +0 -22
- package/dist/live-boolean.js +0 -34
- package/dist/live-boolean.js.map +0 -1
- package/dist/random.d.ts +0 -13
- package/dist/random.js +0 -19
- package/dist/random.js.map +0 -1
- package/dist/styles.d.ts +0 -12
- package/dist/styles.js +0 -11
- package/dist/styles.js.map +0 -1
- package/dist/template-whitespace.d.ts +0 -7
- package/dist/template-whitespace.js.map +0 -1
- package/dist/templates.d.ts +0 -5
- package/dist/templates.js +0 -15
- package/dist/templates.js.map +0 -1
- package/dist/textarea.d.ts +0 -26
- package/dist/textarea.js +0 -85
- package/dist/textarea.js.map +0 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// Development-only errors and warnings of the renderer (view/02-bindings.md "Child values",
|
|
2
|
+
// view/03-lists.md "Keys", view/09-template-rules.md "Warnings"). Every call site is guarded by
|
|
3
|
+
// `if (DEV)`, so production bundles drop this module. Messages say what to write instead.
|
|
4
|
+
const SPEC = 'docs/design-docs/view';
|
|
5
|
+
const warned = new WeakSet();
|
|
6
|
+
const describe = (value) => typeof value === 'function'
|
|
7
|
+
? 'a function'
|
|
8
|
+
: Array.isArray(value)
|
|
9
|
+
? 'an array'
|
|
10
|
+
: typeof value === 'object'
|
|
11
|
+
? `an object (${Object.prototype.toString.call(value).slice(8, -1)})`
|
|
12
|
+
: `a ${typeof value}`;
|
|
13
|
+
/** A child hole got a value it can't render: an error in development. */
|
|
14
|
+
export function badChild(value) {
|
|
15
|
+
throw new TypeError(`gyral: a child hole got ${describe(value)}, which it can't render. Child holes take ` +
|
|
16
|
+
`text, numbers, html\`…\` results, each(…), arrays, raw(…), or null/undefined/false/` +
|
|
17
|
+
`nothing for nothing. Format the value as text, or render it with a template ` +
|
|
18
|
+
`(${SPEC}/02-bindings.md "Child values").`);
|
|
19
|
+
}
|
|
20
|
+
/** `true` in a child hole, once per part: usually a `cond && x` slip. */
|
|
21
|
+
export function warnTrue(part) {
|
|
22
|
+
if (warned.has(part))
|
|
23
|
+
return;
|
|
24
|
+
warned.add(part);
|
|
25
|
+
console.warn('gyral: `true` in a child hole renders nothing. It is usually a `cond && x` slip where ' +
|
|
26
|
+
'cond is a boolean and x is missing; write `cond ? x : nothing` ' +
|
|
27
|
+
`(${SPEC}/02-bindings.md "Child values").`);
|
|
28
|
+
}
|
|
29
|
+
/** An attribute or text-content hole got an object or function, once per part. */
|
|
30
|
+
export function warnValue(part, value, where) {
|
|
31
|
+
if (warned.has(part))
|
|
32
|
+
return;
|
|
33
|
+
warned.add(part);
|
|
34
|
+
console.warn(`gyral: ${where} got ${describe(value)}; it is written as String(value). Pass a string, ` +
|
|
35
|
+
`number or boolean, or null/undefined/nothing to leave it out ` +
|
|
36
|
+
`(${SPEC}/02-bindings.md "Attribute values").`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A property binding got a function, once per part (02 "Properties"): views attach no
|
|
40
|
+
* closures. Built-in elements and Gyral components warn; other custom elements may take a
|
|
41
|
+
* callback (a third-party widget's API), so they don't.
|
|
42
|
+
*/
|
|
43
|
+
export function warnFunctionProp(part, el, name) {
|
|
44
|
+
const gyral = el.constructor.spec !== undefined;
|
|
45
|
+
if (warned.has(part) || (el.localName.includes('-') && !gyral))
|
|
46
|
+
return;
|
|
47
|
+
warned.add(part);
|
|
48
|
+
console.warn(`gyral: .${name}=\${…} on <${el.localName}> got a function. Views attach no closures: ` +
|
|
49
|
+
(gyral
|
|
50
|
+
? 'props are data (they travel in hydration seeds); pass data and let the component ' +
|
|
51
|
+
'decide what to do with it, and hear back from it through its outputs'
|
|
52
|
+
: 'name an intent with data-intent=${i.Name} for events, and put behaviour on an ' +
|
|
53
|
+
'element in a hook (defineHook)') +
|
|
54
|
+
` (${SPEC}/02-bindings.md "Properties").`);
|
|
55
|
+
}
|
|
56
|
+
let rawWarned = false;
|
|
57
|
+
/** `raw()` parsed in the browser, once per page. */
|
|
58
|
+
export function warnRaw() {
|
|
59
|
+
if (rawWarned)
|
|
60
|
+
return;
|
|
61
|
+
rawWarned = true;
|
|
62
|
+
console.warn('gyral: raw() rendered in the browser. It works, but every change re-parses the markup; ' +
|
|
63
|
+
'prefer templates for content that changes, and keep raw() for server-rendered markup ' +
|
|
64
|
+
`(${SPEC}/09-template-rules.md "Warnings").`);
|
|
65
|
+
}
|
|
66
|
+
/** Keys must be unique strings or numbers: an error in development. */
|
|
67
|
+
export function badKey(key, index, duplicate) {
|
|
68
|
+
const problem = duplicate
|
|
69
|
+
? `the key ${JSON.stringify(key)} appears twice (again at index ${String(index)})`
|
|
70
|
+
: `the key at index ${String(index)} is ${describe(key)}`;
|
|
71
|
+
throw new Error(`gyral: each(): ${problem}. Keys must be unique strings or numbers within a list, such ` +
|
|
72
|
+
`as a stable id: each(items, (x) => x.id, Row) (${SPEC}/03-lists.md "Keys").`);
|
|
73
|
+
}
|
|
74
|
+
/** A skipped row would render differently: it reads something besides `item` and `pick`. */
|
|
75
|
+
export function warnImpureRow(row) {
|
|
76
|
+
const name = row.name === '' ? 'a row function' : `the row function ${row.name}`;
|
|
77
|
+
console.warn(`gyral: each(): ${name} depends on something not passed through \`item\` or \`pick\`, so ` +
|
|
78
|
+
'skipped rows would show stale content. Return what it reads from `pick` and take it as ' +
|
|
79
|
+
`the second argument (${SPEC}/03-lists.md "Rows must be pure").`);
|
|
80
|
+
}
|
|
81
|
+
/** A hook hole got something other than a hook result. */
|
|
82
|
+
/** `?modal`/`?popover-open` with the bindings' code left out of the build (toggles.ts). */
|
|
83
|
+
export function warnToggle(el, name) {
|
|
84
|
+
if (warned.has(el))
|
|
85
|
+
return;
|
|
86
|
+
warned.add(el);
|
|
87
|
+
console.warn(`gyral: ?${name} on <${el.localName}> does nothing: the build left its code out ` +
|
|
88
|
+
`(${SPEC}/05-element.md "Features register themselves").`);
|
|
89
|
+
}
|
|
90
|
+
export function badHook(value) {
|
|
91
|
+
throw new TypeError(`gyral: an element hook position (\${…} inside a start tag) got ${describe(value)}. Only ` +
|
|
92
|
+
`hooks made with defineHook() go there, e.g. <input \${invalid(errors)}> ` +
|
|
93
|
+
`(${SPEC}/02-bindings.md "Element hooks").`);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* An svg template renders only in SVG content: an SVG element other than <foreignObject>,
|
|
97
|
+
* <desc> or <title>, whose content is HTML (01 "svg templates"). A detached fragment (an
|
|
98
|
+
* instance being built) isn't checked: its place is known only when it is inserted.
|
|
99
|
+
*/
|
|
100
|
+
export function checkSvgParent(parent) {
|
|
101
|
+
if (parent.nodeType === 11 && !('host' in parent))
|
|
102
|
+
return;
|
|
103
|
+
const el = parent;
|
|
104
|
+
if (el.namespaceURI === 'http://www.w3.org/2000/svg' &&
|
|
105
|
+
!/^(foreignObject|desc|title)$/.test(el.localName)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const where = el.nodeType === 1 ? `<${el.localName}>` : 'a shadow root';
|
|
109
|
+
throw new Error(`gyral: an svg template is rendered into ${where}, which isn't SVG content. svg\`…\` ` +
|
|
110
|
+
'fragments are SVG elements: render them inside an <svg> (or another SVG element, not ' +
|
|
111
|
+
'<foreignObject>) of an html template, html`<svg viewBox="…">${svg`…`}</svg>`, or write ' +
|
|
112
|
+
`the whole graphic with html (${SPEC}/01-templates.md "svg templates").`);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=warn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warn.js","sourceRoot":"","sources":["../../../src/view/render/warn.ts"],"names":[],"mappings":"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","sourcesContent":["// Development-only errors and warnings of the renderer (view/02-bindings.md \"Child values\",\n// view/03-lists.md \"Keys\", view/09-template-rules.md \"Warnings\"). Every call site is guarded by\n// `if (DEV)`, so production bundles drop this module. Messages say what to write instead.\n\nconst SPEC = 'docs/design-docs/view';\nconst warned = new WeakSet<object>();\n\nconst describe = (value: unknown): string =>\n typeof value === 'function'\n ? 'a function'\n : Array.isArray(value)\n ? 'an array'\n : typeof value === 'object'\n ? `an object (${Object.prototype.toString.call(value).slice(8, -1)})`\n : `a ${typeof value}`;\n\n/** A child hole got a value it can't render: an error in development. */\nexport function badChild(value: unknown): never {\n throw new TypeError(\n `gyral: a child hole got ${describe(value)}, which it can't render. Child holes take ` +\n `text, numbers, html\\`…\\` results, each(…), arrays, raw(…), or null/undefined/false/` +\n `nothing for nothing. Format the value as text, or render it with a template ` +\n `(${SPEC}/02-bindings.md \"Child values\").`,\n );\n}\n\n/** `true` in a child hole, once per part: usually a `cond && x` slip. */\nexport function warnTrue(part: object): void {\n if (warned.has(part)) return;\n warned.add(part);\n console.warn(\n 'gyral: `true` in a child hole renders nothing. It is usually a `cond && x` slip where ' +\n 'cond is a boolean and x is missing; write `cond ? x : nothing` ' +\n `(${SPEC}/02-bindings.md \"Child values\").`,\n );\n}\n\n/** An attribute or text-content hole got an object or function, once per part. */\nexport function warnValue(part: object, value: unknown, where: string): void {\n if (warned.has(part)) return;\n warned.add(part);\n console.warn(\n `gyral: ${where} got ${describe(value)}; it is written as String(value). Pass a string, ` +\n `number or boolean, or null/undefined/nothing to leave it out ` +\n `(${SPEC}/02-bindings.md \"Attribute values\").`,\n );\n}\n\n/**\n * A property binding got a function, once per part (02 \"Properties\"): views attach no\n * closures. Built-in elements and Gyral components warn; other custom elements may take a\n * callback (a third-party widget's API), so they don't.\n */\nexport function warnFunctionProp(part: object, el: Element, name: string): void {\n const gyral = (el.constructor as { readonly spec?: unknown }).spec !== undefined;\n if (warned.has(part) || (el.localName.includes('-') && !gyral)) return;\n warned.add(part);\n console.warn(\n `gyral: .${name}=\\${…} on <${el.localName}> got a function. Views attach no closures: ` +\n (gyral\n ? 'props are data (they travel in hydration seeds); pass data and let the component ' +\n 'decide what to do with it, and hear back from it through its outputs'\n : 'name an intent with data-intent=${i.Name} for events, and put behaviour on an ' +\n 'element in a hook (defineHook)') +\n ` (${SPEC}/02-bindings.md \"Properties\").`,\n );\n}\n\nlet rawWarned = false;\n\n/** `raw()` parsed in the browser, once per page. */\nexport function warnRaw(): void {\n if (rawWarned) return;\n rawWarned = true;\n console.warn(\n 'gyral: raw() rendered in the browser. It works, but every change re-parses the markup; ' +\n 'prefer templates for content that changes, and keep raw() for server-rendered markup ' +\n `(${SPEC}/09-template-rules.md \"Warnings\").`,\n );\n}\n\n/** Keys must be unique strings or numbers: an error in development. */\nexport function badKey(key: unknown, index: number, duplicate: boolean): never {\n const problem = duplicate\n ? `the key ${JSON.stringify(key)} appears twice (again at index ${String(index)})`\n : `the key at index ${String(index)} is ${describe(key)}`;\n throw new Error(\n `gyral: each(): ${problem}. Keys must be unique strings or numbers within a list, such ` +\n `as a stable id: each(items, (x) => x.id, Row) (${SPEC}/03-lists.md \"Keys\").`,\n );\n}\n\n/** A skipped row would render differently: it reads something besides `item` and `pick`. */\nexport function warnImpureRow(row: (...args: never[]) => unknown): void {\n const name = row.name === '' ? 'a row function' : `the row function ${row.name}`;\n console.warn(\n `gyral: each(): ${name} depends on something not passed through \\`item\\` or \\`pick\\`, so ` +\n 'skipped rows would show stale content. Return what it reads from `pick` and take it as ' +\n `the second argument (${SPEC}/03-lists.md \"Rows must be pure\").`,\n );\n}\n\n/** A hook hole got something other than a hook result. */\n/** `?modal`/`?popover-open` with the bindings' code left out of the build (toggles.ts). */\nexport function warnToggle(el: Element, name: string): void {\n if (warned.has(el)) return;\n warned.add(el);\n console.warn(\n `gyral: ?${name} on <${el.localName}> does nothing: the build left its code out ` +\n `(${SPEC}/05-element.md \"Features register themselves\").`,\n );\n}\n\nexport function badHook(value: unknown): never {\n throw new TypeError(\n `gyral: an element hook position (\\${…} inside a start tag) got ${describe(value)}. Only ` +\n `hooks made with defineHook() go there, e.g. <input \\${invalid(errors)}> ` +\n `(${SPEC}/02-bindings.md \"Element hooks\").`,\n );\n}\n\n/**\n * An svg template renders only in SVG content: an SVG element other than <foreignObject>,\n * <desc> or <title>, whose content is HTML (01 \"svg templates\"). A detached fragment (an\n * instance being built) isn't checked: its place is known only when it is inserted.\n */\nexport function checkSvgParent(parent: Node): void {\n if (parent.nodeType === 11 && !('host' in parent)) return;\n const el = parent as Element;\n if (\n el.namespaceURI === 'http://www.w3.org/2000/svg' &&\n !/^(foreignObject|desc|title)$/.test(el.localName)\n ) {\n return;\n }\n const where = el.nodeType === 1 ? `<${el.localName}>` : 'a shadow root';\n throw new Error(\n `gyral: an svg template is rendered into ${where}, which isn't SVG content. svg\\`…\\` ` +\n 'fragments are SVG elements: render them inside an <svg> (or another SVG element, not ' +\n '<foreignObject>) of an html template, html`<svg viewBox=\"…\">${svg`…`}</svg>`, or write ' +\n `the whole graphic with html (${SPEC}/01-templates.md \"svg templates\").`,\n );\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ServerComponent } from '../registry.js';
|
|
2
|
+
import { type Deferred, type Item, type StyleValues } from './writer.js';
|
|
3
|
+
/**
|
|
4
|
+
* The text of a shadow component's `<style>` (its CSS texts joined by newlines, `</style`
|
|
5
|
+
* escaped), exactly as written, so `styleHashes()` hashes what the browser sees. `''`: none.
|
|
6
|
+
*/
|
|
7
|
+
export declare function styleText(component: ServerComponent): string;
|
|
8
|
+
/**
|
|
9
|
+
* Writes a deferred component; nested components are deferred again. A component that fails
|
|
10
|
+
* (ADR 0024) writes its error view instead, marked `data-gyral-error`, and `onError` hears it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function expand({ component, input }: Deferred, dev: boolean, styles: StyleValues | undefined, onError: (error: unknown) => void): Item[];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Rendering one Gyral component in place (view/06-server.md "Components"): the end of its start
|
|
2
|
+
// tag (light mark, seed, island attributes), then its view, inside a declarative shadow root
|
|
3
|
+
// with the component's CSS (08 "Server") or as light-DOM children (ADR 0014). The parent's
|
|
4
|
+
// children of a shadow component follow in the parent's walk, after the `<template>`.
|
|
5
|
+
import { ERROR_ATTRIBUTE, ISLAND_ATTRIBUTE, LIGHT_ATTRIBUTE, SEED_ATTRIBUTE, } from '../attributes.js';
|
|
6
|
+
import { escapeSeed, styleSafe } from './escape.js';
|
|
7
|
+
import { ROOT, Writer } from './writer.js';
|
|
8
|
+
const styleTexts = new WeakMap();
|
|
9
|
+
/**
|
|
10
|
+
* The text of a shadow component's `<style>` (its CSS texts joined by newlines, `</style`
|
|
11
|
+
* escaped), exactly as written, so `styleHashes()` hashes what the browser sees. `''`: none.
|
|
12
|
+
*/
|
|
13
|
+
export function styleText(component) {
|
|
14
|
+
let text = styleTexts.get(component);
|
|
15
|
+
if (text === undefined) {
|
|
16
|
+
text = styleSafe(component.styles.join('\n'));
|
|
17
|
+
styleTexts.set(component, text);
|
|
18
|
+
}
|
|
19
|
+
return text;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Writes a deferred component; nested components are deferred again. A component that fails
|
|
23
|
+
* (ADR 0024) writes its error view instead, marked `data-gyral-error`, and `onError` hears it.
|
|
24
|
+
*/
|
|
25
|
+
export function expand({ component, input }, dev, styles, onError) {
|
|
26
|
+
let rendering = component.render(input);
|
|
27
|
+
let items;
|
|
28
|
+
try {
|
|
29
|
+
items = write(component, input.scope, rendering, dev, styles);
|
|
30
|
+
}
|
|
31
|
+
catch (cause) {
|
|
32
|
+
if (component.fallback === undefined || rendering.failed !== undefined)
|
|
33
|
+
throw cause;
|
|
34
|
+
rendering = component.fallback(cause);
|
|
35
|
+
items = write(component, input.scope, rendering, dev, styles);
|
|
36
|
+
}
|
|
37
|
+
if (rendering.failed !== undefined)
|
|
38
|
+
onError(rendering.failed);
|
|
39
|
+
return items;
|
|
40
|
+
}
|
|
41
|
+
function write(component, scope, { view, seed, failed }, dev, styles) {
|
|
42
|
+
const w = new Writer(dev, scope, styles);
|
|
43
|
+
let tail = component.light ? ` ${LIGHT_ATTRIBUTE}` : '';
|
|
44
|
+
// Single-quoted, so the JSON's double quotes stay raw (ADR 0012).
|
|
45
|
+
if (failed === undefined)
|
|
46
|
+
tail += ` ${SEED_ATTRIBUTE}='${escapeSeed(JSON.stringify(seed))}'`;
|
|
47
|
+
else
|
|
48
|
+
tail += ` ${ERROR_ATTRIBUTE}`;
|
|
49
|
+
if (component.hydrate !== 'load') {
|
|
50
|
+
tail += ` defer-hydration ${ISLAND_ATTRIBUTE}="${component.hydrate}"`;
|
|
51
|
+
}
|
|
52
|
+
w.write(`${tail}>`);
|
|
53
|
+
if (component.light) {
|
|
54
|
+
w.child(view, undefined, ROOT);
|
|
55
|
+
return w.done();
|
|
56
|
+
}
|
|
57
|
+
const css = styleText(component);
|
|
58
|
+
const focus = component.delegatesFocus === true ? ' shadowrootdelegatesfocus' : '';
|
|
59
|
+
w.write(`<template shadowrootmode="open"${focus}>${css === '' ? '' : `<style>${css}</style>`}`);
|
|
60
|
+
w.child(view, undefined, ROOT);
|
|
61
|
+
w.write('</template>');
|
|
62
|
+
return w.done();
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/view/server/component.ts"],"names":[],"mappings":"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","sourcesContent":["// Rendering one Gyral component in place (view/06-server.md \"Components\"): the end of its start\n// tag (light mark, seed, island attributes), then its view, inside a declarative shadow root\n// with the component's CSS (08 \"Server\") or as light-DOM children (ADR 0014). The parent's\n// children of a shadow component follow in the parent's walk, after the `<template>`.\nimport {\n ERROR_ATTRIBUTE,\n ISLAND_ATTRIBUTE,\n LIGHT_ATTRIBUTE,\n SEED_ATTRIBUTE,\n} from '../attributes.js';\nimport type { ServerComponent, ServerRendering } from '../registry.js';\nimport { escapeSeed, styleSafe } from './escape.js';\nimport { ROOT, Writer, type Deferred, type Item, type StyleValues } from './writer.js';\n\nconst styleTexts = new WeakMap<ServerComponent, string>();\n\n/**\n * The text of a shadow component's `<style>` (its CSS texts joined by newlines, `</style`\n * escaped), exactly as written, so `styleHashes()` hashes what the browser sees. `''`: none.\n */\nexport function styleText(component: ServerComponent): string {\n let text = styleTexts.get(component);\n if (text === undefined) {\n text = styleSafe(component.styles.join('\\n'));\n styleTexts.set(component, text);\n }\n return text;\n}\n\n/**\n * Writes a deferred component; nested components are deferred again. A component that fails\n * (ADR 0024) writes its error view instead, marked `data-gyral-error`, and `onError` hears it.\n */\nexport function expand(\n { component, input }: Deferred,\n dev: boolean,\n styles: StyleValues | undefined,\n onError: (error: unknown) => void,\n): Item[] {\n let rendering = component.render(input);\n let items: Item[];\n try {\n items = write(component, input.scope, rendering, dev, styles);\n } catch (cause) {\n if (component.fallback === undefined || rendering.failed !== undefined) throw cause;\n rendering = component.fallback(cause);\n items = write(component, input.scope, rendering, dev, styles);\n }\n if (rendering.failed !== undefined) onError(rendering.failed);\n return items;\n}\n\nfunction write(\n component: ServerComponent,\n scope: unknown,\n { view, seed, failed }: ServerRendering,\n dev: boolean,\n styles: StyleValues | undefined,\n): Item[] {\n const w = new Writer(dev, scope, styles);\n let tail = component.light ? ` ${LIGHT_ATTRIBUTE}` : '';\n // Single-quoted, so the JSON's double quotes stay raw (ADR 0012).\n if (failed === undefined) tail += ` ${SEED_ATTRIBUTE}='${escapeSeed(JSON.stringify(seed))}'`;\n else tail += ` ${ERROR_ATTRIBUTE}`;\n if (component.hydrate !== 'load') {\n tail += ` defer-hydration ${ISLAND_ATTRIBUTE}=\"${component.hydrate}\"`;\n }\n w.write(`${tail}>`);\n if (component.light) {\n w.child(view, undefined, ROOT);\n return w.done();\n }\n const css = styleText(component);\n const focus = component.delegatesFocus === true ? ' shadowrootdelegatesfocus' : '';\n w.write(`<template shadowrootmode=\"open\"${focus}>${css === '' ? '' : `<style>${css}</style>`}`);\n w.child(view, undefined, ROOT);\n w.write('</template>');\n return w.done();\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Text content (child holes, `<textarea>`/`<title>` content). */
|
|
2
|
+
export declare function escapeText(text: string): string;
|
|
3
|
+
/** A double-quoted attribute value. */
|
|
4
|
+
export declare function escapeAttr(value: string): string;
|
|
5
|
+
/** A single-quoted attribute value: the `data-gyral-seed` JSON. */
|
|
6
|
+
export declare const escapeSeed: (json: string) => string;
|
|
7
|
+
/** CSS for a `<style>` element: `</style` (any case) would end it; `<\/style` is the same CSS. */
|
|
8
|
+
export declare const styleSafe: (css: string) => string;
|
|
9
|
+
/** HTML whitespace (WHATWG "ASCII whitespace"): text made only of it stays in table structure. */
|
|
10
|
+
export declare const onlyWhitespace: (text: string) => boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Escaping for the server renderer (view/06-server.md "Escaping"). Text escapes `&`, `<` and
|
|
2
|
+
// `>`; double-quoted attribute values escape `&`, `"`, `<` and `>`; the single-quoted seed
|
|
3
|
+
// attribute escapes `&`, `'`, `<` and `>` (so its JSON's double quotes stay raw). Only `&` and
|
|
4
|
+
// the quote can end a quoted value; `<` and `>` are escaped too (as newer revisions of WHATWG
|
|
5
|
+
// HTML's "Serializing HTML fragments" do), so no markup appears raw in an attribute, whatever
|
|
6
|
+
// later reads the page (raw-text contexts, naive tooling, filters).
|
|
7
|
+
const TEXT = /[&<>]/g;
|
|
8
|
+
const ATTR = /[&"<>]/g;
|
|
9
|
+
const SEED = /[&'<>]/g;
|
|
10
|
+
const ENTITY = {
|
|
11
|
+
'&': '&',
|
|
12
|
+
'<': '<',
|
|
13
|
+
'>': '>',
|
|
14
|
+
'"': '"',
|
|
15
|
+
"'": ''',
|
|
16
|
+
};
|
|
17
|
+
const entity = (c) => ENTITY[c] ?? c;
|
|
18
|
+
/** Text content (child holes, `<textarea>`/`<title>` content). */
|
|
19
|
+
export function escapeText(text) {
|
|
20
|
+
TEXT.lastIndex = 0;
|
|
21
|
+
return TEXT.test(text) ? text.replace(TEXT, entity) : text;
|
|
22
|
+
}
|
|
23
|
+
/** A double-quoted attribute value. */
|
|
24
|
+
export function escapeAttr(value) {
|
|
25
|
+
ATTR.lastIndex = 0;
|
|
26
|
+
return ATTR.test(value) ? value.replace(ATTR, entity) : value;
|
|
27
|
+
}
|
|
28
|
+
/** A single-quoted attribute value: the `data-gyral-seed` JSON. */
|
|
29
|
+
export const escapeSeed = (json) => json.replace(SEED, entity);
|
|
30
|
+
/** CSS for a `<style>` element: `</style` (any case) would end it; `<\/style` is the same CSS. */
|
|
31
|
+
export const styleSafe = (css) => css.replace(/<\/(style)/gi, '<\\/$1');
|
|
32
|
+
/** HTML whitespace (WHATWG "ASCII whitespace"): text made only of it stays in table structure. */
|
|
33
|
+
export const onlyWhitespace = (text) => !/[^\t\n\f\r ]/.test(text);
|
|
34
|
+
//# sourceMappingURL=escape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape.js","sourceRoot":"","sources":["../../../src/view/server/escape.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,2FAA2F;AAC3F,+FAA+F;AAC/F,8FAA8F;AAC9F,8FAA8F;AAC9F,oEAAoE;AAEpE,MAAM,IAAI,GAAG,QAAQ,CAAC;AACtB,MAAM,IAAI,GAAG,SAAS,CAAC;AACvB,MAAM,IAAI,GAAG,SAAS,CAAC;AAEvB,MAAM,MAAM,GAAqC;IAC/C,GAAG,EAAE,OAAO;IACZ,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,MAAM;IACX,GAAG,EAAE,QAAQ;IACb,GAAG,EAAE,OAAO;CACb,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAErD,kEAAkE;AAClE,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAChE,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAE/E,kGAAkG;AAClG,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;AAExF,kGAAkG;AAClG,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAW,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["// Escaping for the server renderer (view/06-server.md \"Escaping\"). Text escapes `&`, `<` and\n// `>`; double-quoted attribute values escape `&`, `\"`, `<` and `>`; the single-quoted seed\n// attribute escapes `&`, `'`, `<` and `>` (so its JSON's double quotes stay raw). Only `&` and\n// the quote can end a quoted value; `<` and `>` are escaped too (as newer revisions of WHATWG\n// HTML's \"Serializing HTML fragments\" do), so no markup appears raw in an attribute, whatever\n// later reads the page (raw-text contexts, naive tooling, filters).\n\nconst TEXT = /[&<>]/g;\nconst ATTR = /[&\"<>]/g;\nconst SEED = /[&'<>]/g;\n\nconst ENTITY: Readonly<Record<string, string>> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n};\n\nconst entity = (c: string): string => ENTITY[c] ?? c;\n\n/** Text content (child holes, `<textarea>`/`<title>` content). */\nexport function escapeText(text: string): string {\n TEXT.lastIndex = 0;\n return TEXT.test(text) ? text.replace(TEXT, entity) : text;\n}\n\n/** A double-quoted attribute value. */\nexport function escapeAttr(value: string): string {\n ATTR.lastIndex = 0;\n return ATTR.test(value) ? value.replace(ATTR, entity) : value;\n}\n\n/** A single-quoted attribute value: the `data-gyral-seed` JSON. */\nexport const escapeSeed = (json: string): string => json.replace(SEED, entity);\n\n/** CSS for a `<style>` element: `</style` (any case) would end it; `<\\/style` is the same CSS. */\nexport const styleSafe = (css: string): string => css.replace(/<\\/(style)/gi, '<\\\\/$1');\n\n/** HTML whitespace (WHATWG \"ASCII whitespace\"): text made only of it stays in table structure. */\nexport const onlyWhitespace = (text: string): boolean => !/[^\\t\\n\\f\\r ]/.test(text);\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { ChildValue } from '../render/values.js';
|
|
2
|
+
import { type StyleValues } from './writer.js';
|
|
3
|
+
export type { StyleValues };
|
|
4
|
+
export interface ServerRenderOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Development markers (`<!--gyral:ID-->` before each template instance, for hydration's
|
|
7
|
+
* checks, 07) and development checks. Default: on in development builds (the `development`
|
|
8
|
+
* export condition, as for the client), off otherwise.
|
|
9
|
+
*/
|
|
10
|
+
readonly dev?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Collects every `style` attribute value the render writes, decoded (as the DOM sees it),
|
|
13
|
+
* each mapped to where it was first written (template `loc` or id): static, bound,
|
|
14
|
+
* multi-part and element-hook values; not `raw()` markup. For hashing them into a CSP
|
|
15
|
+
* (ADR 0020). The markup is the same with or without it.
|
|
16
|
+
*/
|
|
17
|
+
readonly styleAttributes?: StyleValues;
|
|
18
|
+
/**
|
|
19
|
+
* Hears each component whose `init` or view threw (ADR 0024; core's `GyralError`): the page
|
|
20
|
+
* goes on with that component's error view, or nothing. Default `console.error`. Throwing
|
|
21
|
+
* from it ends the render with that error.
|
|
22
|
+
*/
|
|
23
|
+
readonly onError?: (error: unknown) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Collects the tag of every Gyral component the render writes, in document order, so a page
|
|
26
|
+
* can load exactly those components' client modules (automatic component loading).
|
|
27
|
+
*/
|
|
28
|
+
readonly tags?: Set<string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Renders `value` to HTML chunks, lazily: each step writes up to the next component boundary.
|
|
32
|
+
* Every component's `init` and view run in the step that writes it, so a caller can wrap each
|
|
33
|
+
* step in a per-request scope (ADR 0013).
|
|
34
|
+
*/
|
|
35
|
+
export declare function render(value: ChildValue, options?: ServerRenderOptions): Iterable<string>;
|
|
36
|
+
/** Renders `value` to one string. */
|
|
37
|
+
export declare function renderToString(value: ChildValue, options?: ServerRenderOptions): string;
|
|
38
|
+
/**
|
|
39
|
+
* `'sha256-…'` of a `<style>` element's text, for a CSP `style-src` (cached per text).
|
|
40
|
+
* Synchronous (sha256.ts), so a page can build its policy while it renders.
|
|
41
|
+
*/
|
|
42
|
+
export declare function styleHashSync(text: string): string;
|
|
43
|
+
/** `styleHashSync`, as a promise (the API before it existed). */
|
|
44
|
+
export declare const styleHash: (text: string) => Promise<string>;
|
|
45
|
+
/** Tag → `<style>` text of every registered shadow component with CSS (08 "Server"). */
|
|
46
|
+
export declare function componentStyles(): ReadonlyMap<string, string>;
|
|
47
|
+
/** The hashes of every registered shadow component's `<style>` (08 "Server"), deduplicated. */
|
|
48
|
+
export declare function styleHashes(): Promise<readonly string[]>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// The server renderer (view/06-server.md "API"): synchronous, chunked, runtime-agnostic (no
|
|
2
|
+
// DOM, no Node-only APIs: a JavaScript SHA-256 for the style hashes). `@gyral/core/internal/server` wraps these,
|
|
3
|
+
// registering recorded specs first; code outside view/ may import only this module of view/server/.
|
|
4
|
+
import { DEV } from '../flags.js';
|
|
5
|
+
import { serverComponents } from '../registry.js';
|
|
6
|
+
import { expand, styleText } from './component.js';
|
|
7
|
+
import { sha256 } from './sha256.js';
|
|
8
|
+
import { ROOT, Writer } from './writer.js';
|
|
9
|
+
const logError = (error) => {
|
|
10
|
+
console.error(error);
|
|
11
|
+
};
|
|
12
|
+
function push(stack, items) {
|
|
13
|
+
for (let i = items.length - 1; i >= 0; i--)
|
|
14
|
+
stack.push(items[i]);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Renders `value` to HTML chunks, lazily: each step writes up to the next component boundary.
|
|
18
|
+
* Every component's `init` and view run in the step that writes it, so a caller can wrap each
|
|
19
|
+
* step in a per-request scope (ADR 0013).
|
|
20
|
+
*/
|
|
21
|
+
export function* render(value, options = {}) {
|
|
22
|
+
const dev = options.dev ?? DEV;
|
|
23
|
+
const styles = options.styleAttributes;
|
|
24
|
+
const onError = options.onError ?? logError;
|
|
25
|
+
const tags = options.tags;
|
|
26
|
+
const root = new Writer(dev, undefined, styles);
|
|
27
|
+
root.child(value, undefined, ROOT);
|
|
28
|
+
const stack = [];
|
|
29
|
+
push(stack, root.done());
|
|
30
|
+
for (let item = stack.pop(); item !== undefined; item = stack.pop()) {
|
|
31
|
+
if (typeof item === 'string')
|
|
32
|
+
yield item;
|
|
33
|
+
else {
|
|
34
|
+
tags?.add(item.component.tag);
|
|
35
|
+
push(stack, expand(item, dev, styles, onError));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Renders `value` to one string. */
|
|
40
|
+
export function renderToString(value, options) {
|
|
41
|
+
let html = '';
|
|
42
|
+
for (const chunk of render(value, options))
|
|
43
|
+
html += chunk;
|
|
44
|
+
return html;
|
|
45
|
+
}
|
|
46
|
+
const hashes = new Map();
|
|
47
|
+
/**
|
|
48
|
+
* `'sha256-…'` of a `<style>` element's text, for a CSP `style-src` (cached per text).
|
|
49
|
+
* Synchronous (sha256.ts), so a page can build its policy while it renders.
|
|
50
|
+
*/
|
|
51
|
+
export function styleHashSync(text) {
|
|
52
|
+
let hash = hashes.get(text);
|
|
53
|
+
if (hash === undefined) {
|
|
54
|
+
// The parser turns CR and CRLF into LF before the browser hashes the element's text.
|
|
55
|
+
const digest = sha256(new TextEncoder().encode(text.replace(/\r\n?/g, '\n')));
|
|
56
|
+
let binary = '';
|
|
57
|
+
for (const byte of digest)
|
|
58
|
+
binary += String.fromCharCode(byte);
|
|
59
|
+
hash = `'sha256-${btoa(binary)}'`;
|
|
60
|
+
hashes.set(text, hash);
|
|
61
|
+
}
|
|
62
|
+
return hash;
|
|
63
|
+
}
|
|
64
|
+
/** `styleHashSync`, as a promise (the API before it existed). */
|
|
65
|
+
export const styleHash = (text) => Promise.resolve(styleHashSync(text));
|
|
66
|
+
/** Tag → `<style>` text of every registered shadow component with CSS (08 "Server"). */
|
|
67
|
+
export function componentStyles() {
|
|
68
|
+
const styles = new Map();
|
|
69
|
+
for (const component of serverComponents()) {
|
|
70
|
+
const text = styleText(component);
|
|
71
|
+
if (text !== '')
|
|
72
|
+
styles.set(component.tag, text);
|
|
73
|
+
}
|
|
74
|
+
return styles;
|
|
75
|
+
}
|
|
76
|
+
/** The hashes of every registered shadow component's `<style>` (08 "Server"), deduplicated. */
|
|
77
|
+
export function styleHashes() {
|
|
78
|
+
return Promise.resolve([...new Set([...componentStyles().values()].map(styleHashSync))]);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/view/server/index.ts"],"names":[],"mappings":"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","sourcesContent":["// The server renderer (view/06-server.md \"API\"): synchronous, chunked, runtime-agnostic (no\n// DOM, no Node-only APIs: a JavaScript SHA-256 for the style hashes). `@gyral/core/internal/server` wraps these,\n// registering recorded specs first; code outside view/ may import only this module of view/server/.\nimport { DEV } from '../flags.js';\nimport { serverComponents } from '../registry.js';\nimport type { ChildValue } from '../render/values.js';\nimport { expand, styleText } from './component.js';\nimport { sha256 } from './sha256.js';\nimport { ROOT, Writer, type Item, type StyleValues } from './writer.js';\n\nexport type { StyleValues };\n\nexport interface ServerRenderOptions {\n /**\n * Development markers (`<!--gyral:ID-->` before each template instance, for hydration's\n * checks, 07) and development checks. Default: on in development builds (the `development`\n * export condition, as for the client), off otherwise.\n */\n readonly dev?: boolean;\n /**\n * Collects every `style` attribute value the render writes, decoded (as the DOM sees it),\n * each mapped to where it was first written (template `loc` or id): static, bound,\n * multi-part and element-hook values; not `raw()` markup. For hashing them into a CSP\n * (ADR 0020). The markup is the same with or without it.\n */\n readonly styleAttributes?: StyleValues;\n /**\n * Hears each component whose `init` or view threw (ADR 0024; core's `GyralError`): the page\n * goes on with that component's error view, or nothing. Default `console.error`. Throwing\n * from it ends the render with that error.\n */\n readonly onError?: (error: unknown) => void;\n /**\n * Collects the tag of every Gyral component the render writes, in document order, so a page\n * can load exactly those components' client modules (automatic component loading).\n */\n readonly tags?: Set<string>;\n}\n\nconst logError = (error: unknown): void => {\n console.error(error);\n};\n\nfunction push(stack: Item[], items: readonly Item[]): void {\n for (let i = items.length - 1; i >= 0; i--) stack.push(items[i] as Item);\n}\n\n/**\n * Renders `value` to HTML chunks, lazily: each step writes up to the next component boundary.\n * Every component's `init` and view run in the step that writes it, so a caller can wrap each\n * step in a per-request scope (ADR 0013).\n */\nexport function* render(value: ChildValue, options: ServerRenderOptions = {}): Iterable<string> {\n const dev = options.dev ?? DEV;\n const styles = options.styleAttributes;\n const onError = options.onError ?? logError;\n const tags = options.tags;\n const root = new Writer(dev, undefined, styles);\n root.child(value, undefined, ROOT);\n const stack: Item[] = [];\n push(stack, root.done());\n for (let item = stack.pop(); item !== undefined; item = stack.pop()) {\n if (typeof item === 'string') yield item;\n else {\n tags?.add(item.component.tag);\n push(stack, expand(item, dev, styles, onError));\n }\n }\n}\n\n/** Renders `value` to one string. */\nexport function renderToString(value: ChildValue, options?: ServerRenderOptions): string {\n let html = '';\n for (const chunk of render(value, options)) html += chunk;\n return html;\n}\n\nconst hashes = new Map<string, string>();\n\n/**\n * `'sha256-…'` of a `<style>` element's text, for a CSP `style-src` (cached per text).\n * Synchronous (sha256.ts), so a page can build its policy while it renders.\n */\nexport function styleHashSync(text: string): string {\n let hash = hashes.get(text);\n if (hash === undefined) {\n // The parser turns CR and CRLF into LF before the browser hashes the element's text.\n const digest = sha256(new TextEncoder().encode(text.replace(/\\r\\n?/g, '\\n')));\n let binary = '';\n for (const byte of digest) binary += String.fromCharCode(byte);\n hash = `'sha256-${btoa(binary)}'`;\n hashes.set(text, hash);\n }\n return hash;\n}\n\n/** `styleHashSync`, as a promise (the API before it existed). */\nexport const styleHash = (text: string): Promise<string> => Promise.resolve(styleHashSync(text));\n\n/** Tag → `<style>` text of every registered shadow component with CSS (08 \"Server\"). */\nexport function componentStyles(): ReadonlyMap<string, string> {\n const styles = new Map<string, string>();\n for (const component of serverComponents()) {\n const text = styleText(component);\n if (text !== '') styles.set(component.tag, text);\n }\n return styles;\n}\n\n/** The hashes of every registered shadow component's `<style>` (08 \"Server\"), deduplicated. */\nexport function styleHashes(): Promise<readonly string[]> {\n return Promise.resolve([...new Set([...componentStyles().values()].map(styleHashSync))]);\n}\n"]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// SHA-256 (FIPS 180-4) in plain JavaScript, for CSP style hashes (view/06-server.md "CSP").
|
|
2
|
+
// Synchronous, unlike WebCrypto's `digest`, so `@gyral/ssr`'s `renderPage` can build the
|
|
3
|
+
// policy at render time, after the page's components are registered, and still return its
|
|
4
|
+
// Response synchronously. Runtime-agnostic (no `node:crypto`); server-only, never in client
|
|
5
|
+
// bundles. Checked against `node:crypto` (sha256.node.test.ts).
|
|
6
|
+
/** Round constants: the first 32 bits of the fractional parts of the cube roots of the first 64 primes. */
|
|
7
|
+
const K = new Uint32Array([
|
|
8
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
9
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
10
|
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
11
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
12
|
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
13
|
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
14
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
15
|
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
16
|
+
]);
|
|
17
|
+
/** Initial hash: the first 32 bits of the fractional parts of the square roots of the first 8 primes. */
|
|
18
|
+
const H0 = [
|
|
19
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
|
20
|
+
];
|
|
21
|
+
const rotr = (x, n) => (x >>> n) | (x << (32 - n));
|
|
22
|
+
/** The SHA-256 digest of `bytes` (32 bytes). */
|
|
23
|
+
export function sha256(bytes) {
|
|
24
|
+
// Padding: 0x80, zeros, then the bit length as a 64-bit big-endian number.
|
|
25
|
+
const blocks = (bytes.length + 9 + 63) >> 6;
|
|
26
|
+
const m = new Uint8Array(blocks * 64);
|
|
27
|
+
m.set(bytes);
|
|
28
|
+
m[bytes.length] = 0x80;
|
|
29
|
+
const view = new DataView(m.buffer);
|
|
30
|
+
const bits = bytes.length * 8;
|
|
31
|
+
view.setUint32(m.length - 8, Math.floor(bits / 0x100000000));
|
|
32
|
+
view.setUint32(m.length - 4, bits >>> 0);
|
|
33
|
+
const h = new Uint32Array(H0);
|
|
34
|
+
const w = new Uint32Array(64);
|
|
35
|
+
for (let off = 0; off < m.length; off += 64) {
|
|
36
|
+
for (let t = 0; t < 16; t++)
|
|
37
|
+
w[t] = view.getUint32(off + t * 4);
|
|
38
|
+
for (let t = 16; t < 64; t++) {
|
|
39
|
+
const x = w[t - 15];
|
|
40
|
+
const y = w[t - 2];
|
|
41
|
+
const s0 = rotr(x, 7) ^ rotr(x, 18) ^ (x >>> 3);
|
|
42
|
+
const s1 = rotr(y, 17) ^ rotr(y, 19) ^ (y >>> 10);
|
|
43
|
+
w[t] = w[t - 16] + s0 + w[t - 7] + s1;
|
|
44
|
+
}
|
|
45
|
+
let [a, b, c, d, e, f, g, k] = Array.from(h);
|
|
46
|
+
for (let t = 0; t < 64; t++) {
|
|
47
|
+
const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
48
|
+
const t1 = (k + s1 + ((e & f) ^ (~e & g)) + K[t] + w[t]) | 0;
|
|
49
|
+
const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
50
|
+
const t2 = (s0 + ((a & b) ^ (a & c) ^ (b & c))) | 0;
|
|
51
|
+
k = g;
|
|
52
|
+
g = f;
|
|
53
|
+
f = e;
|
|
54
|
+
e = (d + t1) | 0;
|
|
55
|
+
d = c;
|
|
56
|
+
c = b;
|
|
57
|
+
b = a;
|
|
58
|
+
a = (t1 + t2) | 0;
|
|
59
|
+
}
|
|
60
|
+
h[0] = h[0] + a;
|
|
61
|
+
h[1] = h[1] + b;
|
|
62
|
+
h[2] = h[2] + c;
|
|
63
|
+
h[3] = h[3] + d;
|
|
64
|
+
h[4] = h[4] + e;
|
|
65
|
+
h[5] = h[5] + f;
|
|
66
|
+
h[6] = h[6] + g;
|
|
67
|
+
h[7] = h[7] + k;
|
|
68
|
+
}
|
|
69
|
+
const out = new Uint8Array(32);
|
|
70
|
+
const outView = new DataView(out.buffer);
|
|
71
|
+
for (let i = 0; i < 8; i++)
|
|
72
|
+
outView.setUint32(i * 4, h[i]);
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=sha256.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sha256.js","sourceRoot":"","sources":["../../../src/view/server/sha256.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,yFAAyF;AACzF,0FAA0F;AAC1F,4FAA4F;AAC5F,gEAAgE;AAEhE,2GAA2G;AAC3G,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC;IACxB,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;IAC9F,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAC/F,CAAC,CAAC;AAEH,yGAAyG;AACzG,MAAM,EAAE,GAAG;IACT,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU;CAC/F,CAAC;AAKF,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AAE3E,gDAAgD;AAChD,MAAM,UAAU,MAAM,CAAC,KAAiB;IACtC,2EAA2E;IAC3E,MAAM,MAAM,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACb,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvB,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,KAAK,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAW,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAW,CAAC;YAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAChD,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAY,GAAG,EAAE,GAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAY,GAAG,EAAE,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAU,CAAC;QACtD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAI,CAAC,CAAC,CAAC,CAAY,CAAC,GAAG,CAAC,CAAC;YACrF,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACpD,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,CAAC;YACN,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QACD,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,CAAY,GAAG,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;QAAE,OAAO,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAW,CAAC,CAAC;IACrE,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["// SHA-256 (FIPS 180-4) in plain JavaScript, for CSP style hashes (view/06-server.md \"CSP\").\n// Synchronous, unlike WebCrypto's `digest`, so `@gyral/ssr`'s `renderPage` can build the\n// policy at render time, after the page's components are registered, and still return its\n// Response synchronously. Runtime-agnostic (no `node:crypto`); server-only, never in client\n// bundles. Checked against `node:crypto` (sha256.node.test.ts).\n\n/** Round constants: the first 32 bits of the fractional parts of the cube roots of the first 64 primes. */\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\n/** Initial hash: the first 32 bits of the fractional parts of the square roots of the first 8 primes. */\nconst H0 = [\n 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,\n];\n\n/** The eight working variables. */\ntype Words = [number, number, number, number, number, number, number, number];\n\nconst rotr = (x: number, n: number): number => (x >>> n) | (x << (32 - n));\n\n/** The SHA-256 digest of `bytes` (32 bytes). */\nexport function sha256(bytes: Uint8Array): Uint8Array {\n // Padding: 0x80, zeros, then the bit length as a 64-bit big-endian number.\n const blocks = (bytes.length + 9 + 63) >> 6;\n const m = new Uint8Array(blocks * 64);\n m.set(bytes);\n m[bytes.length] = 0x80;\n const view = new DataView(m.buffer);\n const bits = bytes.length * 8;\n view.setUint32(m.length - 8, Math.floor(bits / 0x100000000));\n view.setUint32(m.length - 4, bits >>> 0);\n const h = new Uint32Array(H0);\n const w = new Uint32Array(64);\n for (let off = 0; off < m.length; off += 64) {\n for (let t = 0; t < 16; t++) w[t] = view.getUint32(off + t * 4);\n for (let t = 16; t < 64; t++) {\n const x = w[t - 15] as number;\n const y = w[t - 2] as number;\n const s0 = rotr(x, 7) ^ rotr(x, 18) ^ (x >>> 3);\n const s1 = rotr(y, 17) ^ rotr(y, 19) ^ (y >>> 10);\n w[t] = (w[t - 16] as number) + s0 + (w[t - 7] as number) + s1;\n }\n let [a, b, c, d, e, f, g, k] = Array.from(h) as Words;\n for (let t = 0; t < 64; t++) {\n const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n const t1 = (k + s1 + ((e & f) ^ (~e & g)) + (K[t] as number) + (w[t] as number)) | 0;\n const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n const t2 = (s0 + ((a & b) ^ (a & c) ^ (b & c))) | 0;\n k = g;\n g = f;\n f = e;\n e = (d + t1) | 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) | 0;\n }\n h[0] = (h[0] as number) + a;\n h[1] = (h[1] as number) + b;\n h[2] = (h[2] as number) + c;\n h[3] = (h[3] as number) + d;\n h[4] = (h[4] as number) + e;\n h[5] = (h[5] as number) + f;\n h[6] = (h[6] as number) + g;\n h[7] = (h[7] as number) + k;\n }\n const out = new Uint8Array(32);\n const outView = new DataView(out.buffer);\n for (let i = 0; i < 8; i++) outView.setUint32(i * 4, h[i] as number);\n return out;\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Segment } from '../normalize/types.js';
|
|
2
|
+
import { type ServerComponent, type ServerProvider, type ServerRenderInput } from '../registry.js';
|
|
3
|
+
/** A component whose content is written later, in its own render step. */
|
|
4
|
+
export interface Deferred {
|
|
5
|
+
readonly component: ServerComponent;
|
|
6
|
+
readonly input: ServerRenderInput;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A render's `style` attribute values for a CSP (ADR 0020): each distinct value as the DOM sees
|
|
10
|
+
* it (decoded), mapped to where it was first written (the template's `loc` or id; `''` when
|
|
11
|
+
* neither is known).
|
|
12
|
+
*/
|
|
13
|
+
export type StyleValues = Map<string, string>;
|
|
14
|
+
/** What a walk produces: markup, with deferred components in document order. */
|
|
15
|
+
export type Item = string | Deferred;
|
|
16
|
+
/** A custom element's start tag while its attribute holes are written. */
|
|
17
|
+
export interface Opening {
|
|
18
|
+
readonly tag: string;
|
|
19
|
+
readonly component: ServerComponent | undefined;
|
|
20
|
+
readonly provider: ServerProvider | undefined;
|
|
21
|
+
readonly attributes: Record<string, string>;
|
|
22
|
+
readonly properties: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
/** An open custom element until its end tag: plain, a provider, or a light component. */
|
|
25
|
+
export type Frame = {
|
|
26
|
+
readonly k: 'plain';
|
|
27
|
+
} | {
|
|
28
|
+
readonly k: 'provider';
|
|
29
|
+
readonly outer: unknown;
|
|
30
|
+
} | {
|
|
31
|
+
readonly k: 'light';
|
|
32
|
+
readonly tag: string;
|
|
33
|
+
readonly items: number;
|
|
34
|
+
};
|
|
35
|
+
export declare const PLAIN: Frame;
|
|
36
|
+
export declare class Markup {
|
|
37
|
+
protected readonly dev: boolean;
|
|
38
|
+
protected scope: unknown;
|
|
39
|
+
protected readonly styles?: StyleValues | undefined;
|
|
40
|
+
protected buf: string;
|
|
41
|
+
protected readonly items: Item[];
|
|
42
|
+
/** The template being written, for `styles` (its `loc` or id). */
|
|
43
|
+
protected where: string;
|
|
44
|
+
/**
|
|
45
|
+
* `dev`: development markers and checks. `scope`: the nearest provider's scope, passed to
|
|
46
|
+
* components (undefined: the request's). `styles`: collects every `style` value written.
|
|
47
|
+
*/
|
|
48
|
+
constructor(dev: boolean, scope: unknown, styles?: StyleValues | undefined);
|
|
49
|
+
/** Records a `style` value the DOM will see (empty values declare nothing). */
|
|
50
|
+
protected style(value: string): void;
|
|
51
|
+
write(markup: string): void;
|
|
52
|
+
/** The markup and deferred components written so far. */
|
|
53
|
+
done(): Item[];
|
|
54
|
+
private flush;
|
|
55
|
+
/** `name=${v}` or `name="a ${v} b"`; returns the index of the next value. */
|
|
56
|
+
protected attr(s: Extract<Segment, {
|
|
57
|
+
k: 'attr';
|
|
58
|
+
}>, values: readonly unknown[], at: number, opening: Opening | undefined): number;
|
|
59
|
+
private valued;
|
|
60
|
+
/** A present boolean attribute (`?name`, or `true` from a hook's server half). */
|
|
61
|
+
protected bare(name: string, opening: Opening | undefined): void;
|
|
62
|
+
/** An element hook: its server half's attributes (02 "Element hooks"). */
|
|
63
|
+
protected hook(v: unknown, opening: Opening | undefined): void;
|
|
64
|
+
/** A custom element's start tag: a Gyral component, a provider, or a plain element. */
|
|
65
|
+
protected open(tag: string, html: string, attrs: readonly (readonly [string, string])[]): Opening | undefined;
|
|
66
|
+
protected openEnd(opening: Opening | undefined): Frame;
|
|
67
|
+
protected close(frame: Frame, tag: string): void;
|
|
68
|
+
}
|