@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
package/dist/drivers-scope.js
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
// Tree-scoped driver overrides (gyral-czi.35, ADR 0006 addendum): which driver a command uses.
|
|
2
|
-
// Resolution: el.drivers → nearest driver provider (across shadow roots) → spec.drivers →
|
|
3
|
-
// the command's own driver. Mirrors <gyral-stores> (ADR 0013) for stores.
|
|
4
|
-
import { isServer } from 'lit';
|
|
5
|
-
const onServer = isServer;
|
|
6
1
|
/** Provider element name: `<gyral-drivers .drivers=${{ http: fake }}>…</gyral-drivers>`. */
|
|
7
2
|
export const DRIVERS_ELEMENT = 'gyral-drivers';
|
|
8
3
|
// Elements registered with provideDrivers() (any element can act as a provider).
|
|
@@ -30,11 +25,9 @@ function overridesOf(node) {
|
|
|
30
25
|
/**
|
|
31
26
|
* The override for `name` from the nearest provider that has one. Providers nest: an inner
|
|
32
27
|
* provider without that driver lets an outer one supply it. Commands never run on the server,
|
|
33
|
-
* so
|
|
28
|
+
* so only the browser calls this.
|
|
34
29
|
*/
|
|
35
30
|
export function providedDriver(host, name) {
|
|
36
|
-
if (onServer)
|
|
37
|
-
return undefined;
|
|
38
31
|
for (let node = host.parentNode; node !== null;) {
|
|
39
32
|
if (node instanceof Element) {
|
|
40
33
|
const driver = overridesOf(node)?.[name];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drivers-scope.js","sourceRoot":"","sources":["../src/drivers-scope.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"drivers-scope.js","sourceRoot":"","sources":["../src/drivers-scope.ts"],"names":[],"mappings":"AAKA,4FAA4F;AAC5F,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;AAE/C,iFAAiF;AACjF,MAAM,QAAQ,GAAG,IAAI,OAAO,EAA4B,CAAC;AAEzD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,OAAwB;IACvE,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,GAAG,EAAE;QACV,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,OAAO;YAAE,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAAa;IAChC,MAAM,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,IAAI,CAAC,SAAS,KAAK,eAAe;QAAE,OAAO,SAAS,CAAC;IACzD,OAAQ,IAAgD,CAAC,OAAO,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,IAAY;IACxD,KAAK,IAAI,IAAI,GAAgB,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,IAAI,GAAG,CAAC;QAC7D,IAAI,IAAI,YAAY,OAAO,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YACzC,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,MAAM,CAAC;QAC1C,CAAC;QACD,IAAI,GAAG,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;IAClE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["// Tree-scoped driver overrides (gyral-czi.35, ADR 0006 addendum): which driver a command uses.\n// Resolution: el.drivers → nearest driver provider (across shadow roots) → the command's own\n// driver; a driver token (defineDriver('name')) has no own implementation. Mirrors <gyral-stores> (ADR 0013) for stores.\nimport type { AnyDriver, DriverOverrides } from './command.js';\n\n/** Provider element name: `<gyral-drivers .drivers=${{ http: fake }}>…</gyral-drivers>`. */\nexport const DRIVERS_ELEMENT = 'gyral-drivers';\n\n// Elements registered with provideDrivers() (any element can act as a provider).\nconst provided = new WeakMap<Element, DriverOverrides>();\n\n/**\n * Makes `element` a driver provider for every Gyral component below it (including inside\n * shadow roots). Returns a function that removes the overrides. Use it on a test container\n * or an app root; a `<gyral-drivers>` element with a `.drivers` property works the same way.\n */\nexport function provideDrivers(element: Element, drivers: DriverOverrides): () => void {\n provided.set(element, drivers);\n return () => {\n if (provided.get(element) === drivers) provided.delete(element);\n };\n}\n\nfunction overridesOf(node: Element): DriverOverrides | undefined {\n const registered = provided.get(node);\n if (registered !== undefined) return registered;\n if (node.localName !== DRIVERS_ELEMENT) return undefined;\n return (node as Element & { drivers?: DriverOverrides }).drivers;\n}\n\n/**\n * The override for `name` from the nearest provider that has one. Providers nest: an inner\n * provider without that driver lets an outer one supply it. Commands never run on the server,\n * so only the browser calls this.\n */\nexport function providedDriver(host: Element, name: string): AnyDriver | undefined {\n for (let node: Node | null = host.parentNode; node !== null;) {\n if (node instanceof Element) {\n const driver = overridesOf(node)?.[name];\n if (driver !== undefined) return driver;\n }\n node = node instanceof ShadowRoot ? node.host : node.parentNode;\n }\n return undefined;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function internalsOf(host: HTMLElement): ElementInternals;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Native features share one attachment: attachInternals() may only be called once per host.
|
|
2
|
+
const internals = new WeakMap();
|
|
3
|
+
export function internalsOf(host) {
|
|
4
|
+
let value = internals.get(host);
|
|
5
|
+
if (value === undefined) {
|
|
6
|
+
value = host.attachInternals();
|
|
7
|
+
internals.set(host, value);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=element-internals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element-internals.js","sourceRoot":"","sources":["../src/element-internals.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,MAAM,SAAS,GAAG,IAAI,OAAO,EAAiC,CAAC;AAE/D,MAAM,UAAU,WAAW,CAAC,IAAiB;IAC3C,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["// Native features share one attachment: attachInternals() may only be called once per host.\nconst internals = new WeakMap<HTMLElement, ElementInternals>();\n\nexport function internalsOf(host: HTMLElement): ElementInternals {\n let value = internals.get(host);\n if (value === undefined) {\n value = host.attachInternals();\n internals.set(host, value);\n }\n return value;\n}\n"]}
|
package/dist/element-types.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { LitElement } from 'lit';
|
|
2
1
|
import type { DriverOverrides } from './command.js';
|
|
3
2
|
import type { StoreOverrides } from './store.js';
|
|
4
3
|
import type { ComponentSpec, Tagged } from './types.js';
|
|
5
|
-
/**
|
|
6
|
-
|
|
4
|
+
/**
|
|
5
|
+
* The custom element `define()` produces: a plain `HTMLElement` (view/05-element.md "Public
|
|
6
|
+
* instance API"). Tests wait for rendering with `settled()`.
|
|
7
|
+
*/
|
|
8
|
+
export interface GyralElement<S, M extends Tagged> extends HTMLElement {
|
|
7
9
|
/** Current model state. */
|
|
8
10
|
readonly state: S;
|
|
9
11
|
/** Feeds a message through `update`, as if an intent had produced it. */
|
|
@@ -22,13 +24,17 @@ export interface GyralElement<S, M extends Tagged> extends LitElement {
|
|
|
22
24
|
*/
|
|
23
25
|
initialMessages: readonly Tagged[];
|
|
24
26
|
}
|
|
25
|
-
export interface GyralElementClass<S, M extends Tagged, P, O extends Tagged = never> {
|
|
27
|
+
export interface GyralElementClass<S, M extends Tagged, P, O extends Tagged = never, N extends string = string> {
|
|
26
28
|
/** Instances expose their declared props as settable properties. */
|
|
27
29
|
new (): GyralElement<S, M> & {
|
|
28
30
|
-readonly [K in keyof P]: P[K];
|
|
29
31
|
};
|
|
30
|
-
readonly spec: ComponentSpec<S, M, P>;
|
|
32
|
+
readonly spec: ComponentSpec<S, M, P, N>;
|
|
31
33
|
readonly tagName: string;
|
|
34
|
+
/** Native custom-element registration flag, true when the spec opts into forms. */
|
|
35
|
+
readonly formAssociated?: boolean;
|
|
32
36
|
/** Type-only: the outputs this component emits (read by `child()`). */
|
|
33
37
|
readonly outputs?: O;
|
|
38
|
+
/** Type-only: the component's intent names, the keys of `intent` (read by `intentsOf()`). */
|
|
39
|
+
readonly intentNames?: N;
|
|
34
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-types.js","sourceRoot":"","sources":["../src/element-types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"element-types.js","sourceRoot":"","sources":["../src/element-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { DriverOverrides } from './command.js';\nimport type { StoreOverrides } from './store.js';\nimport type { ComponentSpec, Tagged } from './types.js';\n\n/**\n * The custom element `define()` produces: a plain `HTMLElement` (view/05-element.md \"Public\n * instance API\"). Tests wait for rendering with `settled()`.\n */\nexport interface GyralElement<S, M extends Tagged> extends HTMLElement {\n /** Current model state. */\n readonly state: S;\n /** Feeds a message through `update`, as if an intent had produced it. */\n send(msg: M): void;\n /** Per-instance driver substitutions by name (test fakes). Checked before the spec's. */\n drivers: DriverOverrides;\n /**\n * Per-instance store instances by store name (tests, islands). Checked before the nearest\n * `<gyral-stores>` provider and the document default (ADR 0013).\n */\n stores: StoreOverrides;\n /**\n * Messages applied through `update` right after `init`, before the first render. The server\n * uses it to render a rejected form with the same reducer as the JS path (ADR 0008). Ignored\n * when the element resumes from a hydration seed (the seed already contains their effect).\n */\n initialMessages: readonly Tagged[];\n}\n\nexport interface GyralElementClass<\n S,\n M extends Tagged,\n P,\n O extends Tagged = never,\n N extends string = string,\n> {\n /** Instances expose their declared props as settable properties. */\n new (): GyralElement<S, M> & { -readonly [K in keyof P]: P[K] };\n readonly spec: ComponentSpec<S, M, P, N>;\n readonly tagName: string;\n /** Native custom-element registration flag, true when the spec opts into forms. */\n readonly formAssociated?: boolean;\n /** Type-only: the outputs this component emits (read by `child()`). */\n readonly outputs?: O;\n /** Type-only: the component's intent names, the keys of `intent` (read by `intentsOf()`). */\n readonly intentNames?: N;\n}\n"]}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ComponentSpec, Tagged } from './types.js';
|
|
2
|
+
/** The element class for `spec` (not yet registered); define() types it for the spec. */
|
|
3
|
+
export declare function elementClass<S, M extends Tagged, P>(tag: string, spec: ComponentSpec<S, M, P>): CustomElementConstructor;
|
package/dist/element.js
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
// The element define() creates (docs/design-docs/view/05-element.md): a plain HTMLElement
|
|
2
|
+
// subclass. Declared props are prototype accessors over Standard Schema builders; renders go
|
|
3
|
+
// through the global scheduler (view/04-scheduler.md); intents are delegated listeners on the
|
|
4
|
+
// root (ADR 0001). The model side (state, commands, stores) is host-model.ts.
|
|
5
|
+
import { DEVTOOLS_ENABLED, devConnect, devHydrated } from '#devtools';
|
|
6
|
+
import { fail } from './errors.js';
|
|
7
|
+
import { HostModel } from './host-model.js';
|
|
8
|
+
import { hydrationCode, takeSeed, whenHydrationLoads } from '#hydration-loader';
|
|
9
|
+
import { DEFAULT_EVENTS, eventsOf, handleIntent, hostDepth, intentNames, listenForIntents, } from './intent.js';
|
|
10
|
+
import { isLight } from './light-dom.js';
|
|
11
|
+
import { features } from './features.js';
|
|
12
|
+
import { afterRender, markDirty, POST_HYDRATED, POST_INIT, POST_STATES, } from './scheduler.js';
|
|
13
|
+
import { checkSpecFeatures, customStates, errorView, formAssociation } from '#spec-features';
|
|
14
|
+
import { DEV, ERROR_ATTRIBUTE, message, onHookFailure, render, sheetsFor, suspendHooks, } from './view/index.js';
|
|
15
|
+
const DEFER = 'defer-hydration';
|
|
16
|
+
// A hook that throws is reported for the host owning the render root (ADR 0024).
|
|
17
|
+
onHookFailure((error, root) => {
|
|
18
|
+
const host = root instanceof ShadowRoot ? root.host : root;
|
|
19
|
+
fail(error, 'hook', message(75, host.localName), { host, tag: host.localName });
|
|
20
|
+
});
|
|
21
|
+
/** The element class for `spec` (not yet registered); define() types it for the spec. */
|
|
22
|
+
export function elementClass(tag, spec) {
|
|
23
|
+
const table = (spec.props ?? {});
|
|
24
|
+
const names = Object.keys(table);
|
|
25
|
+
// Registered by the prop builders (features.ts): set whenever a component declares props.
|
|
26
|
+
const props = features.props;
|
|
27
|
+
/** Property sets and seeds: checked in development, kept as given in production (05). */
|
|
28
|
+
const checked = (props) => props.propertyValue;
|
|
29
|
+
const attrs = new Map();
|
|
30
|
+
const light = isLight(spec);
|
|
31
|
+
let sheets;
|
|
32
|
+
const parsers = (spec.intent ?? {});
|
|
33
|
+
const model = spec;
|
|
34
|
+
if (DEV)
|
|
35
|
+
checkSpecFeatures(tag, spec);
|
|
36
|
+
class Element extends HTMLElement {
|
|
37
|
+
static { this.spec = spec; }
|
|
38
|
+
static { this.tagName = tag; }
|
|
39
|
+
static get observedAttributes() {
|
|
40
|
+
return [...attrs.keys(), DEFER];
|
|
41
|
+
}
|
|
42
|
+
static {
|
|
43
|
+
for (const name of names) {
|
|
44
|
+
const def = table[name];
|
|
45
|
+
const attr = def === undefined ? undefined : props.attributeOf(name, def);
|
|
46
|
+
if (attr !== undefined)
|
|
47
|
+
attrs.set(attr, name);
|
|
48
|
+
Object.defineProperty(this.prototype, name, {
|
|
49
|
+
configurable: true,
|
|
50
|
+
enumerable: true,
|
|
51
|
+
get() {
|
|
52
|
+
return this.#values[name];
|
|
53
|
+
},
|
|
54
|
+
set(value) {
|
|
55
|
+
this.#write(name, DEV ? checked(props)(tag, name, table[name], value) : value);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
#values = {};
|
|
61
|
+
#root;
|
|
62
|
+
#rendered = false;
|
|
63
|
+
/** Something changed while disconnected: render on reconnect. */
|
|
64
|
+
#stale = false;
|
|
65
|
+
#serverRendered = false;
|
|
66
|
+
/** The first render adopts the server's DOM (07): resumed from a seed, root not empty. */
|
|
67
|
+
#hydrating = false;
|
|
68
|
+
/** init's commands for a server-rendered host: started after its first render. */
|
|
69
|
+
#afterInit = [];
|
|
70
|
+
#task = {
|
|
71
|
+
tag,
|
|
72
|
+
depth: 0,
|
|
73
|
+
render: () => {
|
|
74
|
+
this.#render();
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
#model = new HostModel({
|
|
78
|
+
el: this,
|
|
79
|
+
tag,
|
|
80
|
+
props: () => (names.length > 0 ? props.readProps(this.#values, table) : {}),
|
|
81
|
+
root: () => this.#root,
|
|
82
|
+
invalidate: (onFrame) => {
|
|
83
|
+
this.#invalidate(onFrame);
|
|
84
|
+
},
|
|
85
|
+
}, model);
|
|
86
|
+
constructor() {
|
|
87
|
+
super();
|
|
88
|
+
const self = this;
|
|
89
|
+
self['drivers'] ??= {};
|
|
90
|
+
self['stores'] ??= {};
|
|
91
|
+
self['initialMessages'] ??= [];
|
|
92
|
+
// Upgrade capture: a property set before the class was defined hides the accessor.
|
|
93
|
+
for (const name of names) {
|
|
94
|
+
if (!Object.hasOwn(this, name))
|
|
95
|
+
continue;
|
|
96
|
+
const value = self[name];
|
|
97
|
+
Reflect.deleteProperty(this, name);
|
|
98
|
+
self[name] = value;
|
|
99
|
+
}
|
|
100
|
+
formAssociation?.create(this, this.#model, spec.formAssociated);
|
|
101
|
+
}
|
|
102
|
+
get state() {
|
|
103
|
+
return this.#state();
|
|
104
|
+
}
|
|
105
|
+
#state() {
|
|
106
|
+
if (!this.#model.ready && names.length > 0)
|
|
107
|
+
props.warnMissing(tag, this.#values, table);
|
|
108
|
+
return this.#model.state(this.initialMessages);
|
|
109
|
+
}
|
|
110
|
+
send(msg) {
|
|
111
|
+
this.#model.dispatch(msg);
|
|
112
|
+
}
|
|
113
|
+
connectedCallback() {
|
|
114
|
+
if (this.#root !== undefined) {
|
|
115
|
+
this.#connect();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.#resume();
|
|
119
|
+
this.#begin();
|
|
120
|
+
}
|
|
121
|
+
/** `moveBefore()` keeps everything: no disconnect, no re-resolution (view/03-lists.md). */
|
|
122
|
+
connectedMoveCallback() {
|
|
123
|
+
// Intentionally empty.
|
|
124
|
+
}
|
|
125
|
+
disconnectedCallback() {
|
|
126
|
+
this.#model.disconnect();
|
|
127
|
+
// Element hooks' dispose; they run client again after the render on reconnect (02).
|
|
128
|
+
if (suspendHooks(this.#root))
|
|
129
|
+
this.#stale = true;
|
|
130
|
+
if (DEVTOOLS_ENABLED)
|
|
131
|
+
devConnect(this, tag, false);
|
|
132
|
+
}
|
|
133
|
+
attributeChangedCallback(name, _old, raw) {
|
|
134
|
+
if (name === DEFER) {
|
|
135
|
+
if (raw === null && this.isConnected && this.#root === undefined)
|
|
136
|
+
this.#begin();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const prop = attrs.get(name);
|
|
140
|
+
if (prop !== undefined)
|
|
141
|
+
this.#write(prop, props.attributeValue(tag, prop, table[prop], name, raw));
|
|
142
|
+
}
|
|
143
|
+
#write(name, value) {
|
|
144
|
+
// The prop's `equals` (prop.ts): `Object.is`, the same JSON for prop.json, or the option.
|
|
145
|
+
if (table[name]?.equals(this.#values[name], value))
|
|
146
|
+
return;
|
|
147
|
+
this.#values[name] = value;
|
|
148
|
+
if (this.#model.ready)
|
|
149
|
+
this.#invalidate();
|
|
150
|
+
}
|
|
151
|
+
/** Hydration seeds (ADR 0012): the server's state and the props no attribute carried. */
|
|
152
|
+
#resume() {
|
|
153
|
+
if (this.#model.ready)
|
|
154
|
+
return;
|
|
155
|
+
const seed = takeSeed(this);
|
|
156
|
+
if (seed === undefined)
|
|
157
|
+
return;
|
|
158
|
+
for (const [name, value] of Object.entries(seed.props)) {
|
|
159
|
+
const def = table[name];
|
|
160
|
+
if (def === undefined || this.#values[name] !== undefined)
|
|
161
|
+
continue;
|
|
162
|
+
this.#values[name] = DEV ? checked(props)(tag, name, def, value, 'the seed') : value;
|
|
163
|
+
}
|
|
164
|
+
this.#afterInit = this.#model.resume(seed);
|
|
165
|
+
this.#serverRendered = true;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Starts the host, or waits: for the hydration code (a server-rendered host or an island,
|
|
169
|
+
* view/07-hydration.md "Loading"), then for an island's trigger (released by
|
|
170
|
+
* attributeChangedCallback).
|
|
171
|
+
*/
|
|
172
|
+
#begin() {
|
|
173
|
+
const defer = this.hasAttribute(DEFER);
|
|
174
|
+
if (hydrationCode === undefined && (this.#serverRendered || defer)) {
|
|
175
|
+
whenHydrationLoads(() => {
|
|
176
|
+
if (this.isConnected && this.#root === undefined)
|
|
177
|
+
this.#begin();
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else if (defer && hydrationCode !== null)
|
|
181
|
+
hydrationCode?.scheduleIsland(this);
|
|
182
|
+
else
|
|
183
|
+
this.#start();
|
|
184
|
+
}
|
|
185
|
+
#start() {
|
|
186
|
+
// `shadow: { delegatesFocus }` (05 "Focus"); `true` and `undefined` spread nothing.
|
|
187
|
+
const root = light
|
|
188
|
+
? this
|
|
189
|
+
: (this.shadowRoot ??
|
|
190
|
+
this.attachShadow({ ...spec.shadow, mode: 'open' }));
|
|
191
|
+
this.#root = root;
|
|
192
|
+
this.#hydrating = this.#serverRendered && hydrationCode != null && root.hasChildNodes();
|
|
193
|
+
sheets ??= light ? [] : sheetsFor(spec.styles);
|
|
194
|
+
// Rendering fresh: a shadow root without a seed (hand-written DSD) or a server-rendered
|
|
195
|
+
// host whose hydration code failed to load starts empty.
|
|
196
|
+
// A host that failed on the server (ADR 0024) starts fresh: its content is a fallback.
|
|
197
|
+
const failedOnServer = this.hasAttribute(ERROR_ATTRIBUTE);
|
|
198
|
+
if (failedOnServer)
|
|
199
|
+
this.removeAttribute(ERROR_ATTRIBUTE);
|
|
200
|
+
if (!this.#hydrating) {
|
|
201
|
+
if (!light || this.#serverRendered || failedOnServer)
|
|
202
|
+
root.replaceChildren();
|
|
203
|
+
if (!light)
|
|
204
|
+
root.adoptedStyleSheets = sheets;
|
|
205
|
+
}
|
|
206
|
+
this.#listen(DEFAULT_EVENTS);
|
|
207
|
+
this.#state(); // init, unless resumed from a seed
|
|
208
|
+
this.#connect();
|
|
209
|
+
}
|
|
210
|
+
#connect() {
|
|
211
|
+
this.#task.depth = hostDepth(this);
|
|
212
|
+
const rebound = this.#model.connect();
|
|
213
|
+
if (DEVTOOLS_ENABLED)
|
|
214
|
+
devConnect(this, tag, true);
|
|
215
|
+
if (!this.#rendered || this.#stale || rebound)
|
|
216
|
+
this.#invalidate();
|
|
217
|
+
}
|
|
218
|
+
#invalidate(onFrame = false) {
|
|
219
|
+
if (this.#root === undefined)
|
|
220
|
+
return;
|
|
221
|
+
if (this.isConnected)
|
|
222
|
+
markDirty(this.#task, onFrame);
|
|
223
|
+
else
|
|
224
|
+
this.#stale = true;
|
|
225
|
+
}
|
|
226
|
+
/** One render (the scheduler calls it): PropsChanged first, then the view and its commit. */
|
|
227
|
+
#render() {
|
|
228
|
+
const root = this.#root;
|
|
229
|
+
if (root === undefined || !this.isConnected) {
|
|
230
|
+
this.#stale = true;
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
this.#stale = false;
|
|
234
|
+
this.#model.syncProps(names);
|
|
235
|
+
const failure = this.#model.failure;
|
|
236
|
+
if (failure !== undefined) {
|
|
237
|
+
// init threw (ADR 0024): the error view, once; nothing else runs for this host.
|
|
238
|
+
if (!this.#rendered)
|
|
239
|
+
this.#fallback(root, failure, undefined);
|
|
240
|
+
this.#rendered = true;
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const view = spec.view(this.state, intentNames, this.#model.ctx());
|
|
245
|
+
if (this.#hydrating) {
|
|
246
|
+
hydrationCode?.hydrateRoot(this, tag, view, root, light ? undefined : sheets, this.#seen);
|
|
247
|
+
this.#hydrating = false;
|
|
248
|
+
}
|
|
249
|
+
else
|
|
250
|
+
render(view, root, this.#seen);
|
|
251
|
+
formAssociation?.sync(this, this.state, this.#model.ctx(), root);
|
|
252
|
+
}
|
|
253
|
+
catch (cause) {
|
|
254
|
+
const error = this.#model.fail(cause, 'view', message(31, tag));
|
|
255
|
+
this.#fallback(root, error, this.state);
|
|
256
|
+
return; // the first-render steps wait for a render that succeeds
|
|
257
|
+
}
|
|
258
|
+
const states = spec.states;
|
|
259
|
+
const sync = customStates;
|
|
260
|
+
if (states !== undefined && sync !== undefined) {
|
|
261
|
+
afterRender(POST_STATES, () => {
|
|
262
|
+
sync(this, states(this.state));
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (this.#rendered)
|
|
266
|
+
return;
|
|
267
|
+
this.#rendered = true;
|
|
268
|
+
if (DEVTOOLS_ENABLED)
|
|
269
|
+
devHydrated(this, tag, this.#serverRendered);
|
|
270
|
+
if (this.#model.hasReducer('Hydrated')) {
|
|
271
|
+
const msg = { _tag: 'Hydrated', serverRendered: this.#serverRendered };
|
|
272
|
+
afterRender(POST_HYDRATED, () => {
|
|
273
|
+
this.#model.dispatch(msg);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
const commands = this.#afterInit;
|
|
277
|
+
this.#afterInit = [];
|
|
278
|
+
if (commands.length > 0) {
|
|
279
|
+
afterRender(POST_INIT, () => {
|
|
280
|
+
this.#model.run(commands);
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (spec.subscriptions !== undefined) {
|
|
284
|
+
afterRender(POST_INIT, () => {
|
|
285
|
+
this.#model.subscribe();
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Renders `spec.error` (ADR 0024). Without one the root keeps what it shows; a fallback that
|
|
291
|
+
* throws too is reported and changes nothing.
|
|
292
|
+
*/
|
|
293
|
+
#fallback(root, error, state) {
|
|
294
|
+
if (spec.error === undefined || errorView === undefined)
|
|
295
|
+
return;
|
|
296
|
+
const view = (failure, at) => spec.error?.(failure, at);
|
|
297
|
+
if (errorView(view, root, error, state, this.#hydrating, this.#seen, this, tag)) {
|
|
298
|
+
this.#hydrating = false;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/** Intent event types this host's root listens for (view/05-element.md "Intent events"). */
|
|
302
|
+
#listening = new Set();
|
|
303
|
+
#listen(types) {
|
|
304
|
+
listenForIntents(this.#root, this.#listening, types, this.#onEvent);
|
|
305
|
+
}
|
|
306
|
+
/** Told about each template a render instantiates: listen for what its markup names. */
|
|
307
|
+
#seen = (markup) => {
|
|
308
|
+
this.#listen(eventsOf(markup));
|
|
309
|
+
};
|
|
310
|
+
#onEvent = (event) => {
|
|
311
|
+
if (this.#root === undefined)
|
|
312
|
+
return;
|
|
313
|
+
handleIntent(event, this.#root, parsers, tag, this.#model, (msg) => {
|
|
314
|
+
if (msg !== undefined && this.isConnected)
|
|
315
|
+
this.#model.dispatch(msg);
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
formAssociation?.install(Element, spec.formAssociated !== undefined);
|
|
320
|
+
return Element;
|
|
321
|
+
}
|
|
322
|
+
//# sourceMappingURL=element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element.js","sourceRoot":"","sources":["../src/element.ts"],"names":[],"mappings":"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","sourcesContent":["// The element define() creates (docs/design-docs/view/05-element.md): a plain HTMLElement\n// subclass. Declared props are prototype accessors over Standard Schema builders; renders go\n// through the global scheduler (view/04-scheduler.md); intents are delegated listeners on the\n// root (ADR 0001). The model side (state, commands, stores) is host-model.ts.\nimport { DEVTOOLS_ENABLED, devConnect, devHydrated } from '#devtools';\nimport type { DriverOverrides } from './command.js';\nimport type { GyralElement } from './element-types.js';\nimport { fail, type GyralError } from './errors.js';\nimport { HostModel, type ModelCommand } from './host-model.js';\nimport { hydrationCode, takeSeed, whenHydrationLoads } from '#hydration-loader';\nimport {\n DEFAULT_EVENTS,\n eventsOf,\n handleIntent,\n hostDepth,\n intentNames,\n listenForIntents,\n} from './intent.js';\nimport { isLight } from './light-dom.js';\nimport { features } from './features.js';\nimport type { PropFeature, PropTable, propertyValue } from './props.js';\nimport {\n afterRender,\n markDirty,\n POST_HYDRATED,\n POST_INIT,\n POST_STATES,\n type HostTask,\n} from './scheduler.js';\nimport { checkSpecFeatures, customStates, errorView, formAssociation } from '#spec-features';\nimport type { StoreOverrides } from './store.js';\nimport type { ComponentSpec, IntentNames, IntentParser, Tagged } from './types.js';\nimport {\n DEV,\n ERROR_ATTRIBUTE,\n message,\n onHookFailure,\n render,\n sheetsFor,\n suspendHooks,\n type Markup,\n} from './view/index.js';\n\nconst DEFER = 'defer-hydration';\n\n// A hook that throws is reported for the host owning the render root (ADR 0024).\nonHookFailure((error, root) => {\n const host = root instanceof ShadowRoot ? root.host : (root as Element);\n fail(error, 'hook', message(75, host.localName), { host, tag: host.localName });\n});\n\ntype Bag = Record<string, unknown>;\n/** The element class for `spec` (not yet registered); define() types it for the spec. */\nexport function elementClass<S, M extends Tagged, P>(\n tag: string,\n spec: ComponentSpec<S, M, P>,\n): CustomElementConstructor {\n const table = (spec.props ?? {}) as PropTable;\n const names = Object.keys(table);\n // Registered by the prop builders (features.ts): set whenever a component declares props.\n const props = features.props as PropFeature;\n /** Property sets and seeds: checked in development, kept as given in production (05). */\n const checked = (props: PropFeature): typeof propertyValue =>\n props.propertyValue as typeof propertyValue;\n const attrs = new Map<string, string>();\n const light = isLight(spec);\n let sheets: CSSStyleSheet[] | undefined;\n const parsers = (spec.intent ?? {}) as Readonly<\n Record<string, IntentParser<M> | true | undefined>\n >;\n const model = spec as unknown as ComponentSpec<S, Tagged, P>;\n if (DEV) checkSpecFeatures(tag, spec);\n\n class Element extends HTMLElement implements GyralElement<S, M> {\n static readonly spec = spec;\n static readonly tagName = tag;\n static get observedAttributes(): string[] {\n return [...attrs.keys(), DEFER];\n }\n\n static {\n for (const name of names) {\n const def = table[name];\n const attr = def === undefined ? undefined : props.attributeOf(name, def);\n if (attr !== undefined) attrs.set(attr, name);\n Object.defineProperty(this.prototype, name, {\n configurable: true,\n enumerable: true,\n get(this: Element): unknown {\n return this.#values[name];\n },\n set(this: Element, value: unknown) {\n this.#write(name, DEV ? checked(props)(tag, name, table[name], value) : value);\n },\n });\n }\n }\n\n declare drivers: DriverOverrides;\n declare stores: StoreOverrides;\n declare initialMessages: readonly Tagged[];\n\n #values: Bag = {};\n #root: ShadowRoot | HTMLElement | undefined;\n #rendered = false;\n /** Something changed while disconnected: render on reconnect. */\n #stale = false;\n #serverRendered = false;\n /** The first render adopts the server's DOM (07): resumed from a seed, root not empty. */\n #hydrating = false;\n /** init's commands for a server-rendered host: started after its first render. */\n #afterInit: readonly ModelCommand[] = [];\n #task: HostTask = {\n tag,\n depth: 0,\n render: () => {\n this.#render();\n },\n };\n #model = new HostModel<S, P>(\n {\n el: this,\n tag,\n props: () => (names.length > 0 ? props.readProps(this.#values, table) : {}),\n root: () => this.#root,\n invalidate: (onFrame) => {\n this.#invalidate(onFrame);\n },\n },\n model,\n );\n\n constructor() {\n super();\n const self = this as unknown as Bag;\n self['drivers'] ??= {};\n self['stores'] ??= {};\n self['initialMessages'] ??= [];\n // Upgrade capture: a property set before the class was defined hides the accessor.\n for (const name of names) {\n if (!Object.hasOwn(this, name)) continue;\n const value = self[name];\n Reflect.deleteProperty(this, name);\n self[name] = value;\n }\n formAssociation?.create(this, this.#model, spec.formAssociated);\n }\n\n get state(): S {\n return this.#state();\n }\n\n #state(): S {\n if (!this.#model.ready && names.length > 0) props.warnMissing(tag, this.#values, table);\n return this.#model.state(this.initialMessages);\n }\n\n send(msg: M): void {\n this.#model.dispatch(msg);\n }\n\n connectedCallback(): void {\n if (this.#root !== undefined) {\n this.#connect();\n return;\n }\n this.#resume();\n this.#begin();\n }\n\n /** `moveBefore()` keeps everything: no disconnect, no re-resolution (view/03-lists.md). */\n connectedMoveCallback(): void {\n // Intentionally empty.\n }\n\n disconnectedCallback(): void {\n this.#model.disconnect();\n // Element hooks' dispose; they run client again after the render on reconnect (02).\n if (suspendHooks(this.#root)) this.#stale = true;\n if (DEVTOOLS_ENABLED) devConnect(this, tag, false);\n }\n\n attributeChangedCallback(name: string, _old: string | null, raw: string | null): void {\n if (name === DEFER) {\n if (raw === null && this.isConnected && this.#root === undefined) this.#begin();\n return;\n }\n const prop = attrs.get(name);\n if (prop !== undefined)\n this.#write(prop, props.attributeValue(tag, prop, table[prop], name, raw));\n }\n\n #write(name: string, value: unknown): void {\n // The prop's `equals` (prop.ts): `Object.is`, the same JSON for prop.json, or the option.\n if (table[name]?.equals(this.#values[name], value)) return;\n this.#values[name] = value;\n if (this.#model.ready) this.#invalidate();\n }\n\n /** Hydration seeds (ADR 0012): the server's state and the props no attribute carried. */\n #resume(): void {\n if (this.#model.ready) return;\n const seed = takeSeed(this);\n if (seed === undefined) return;\n for (const [name, value] of Object.entries(seed.props)) {\n const def = table[name];\n if (def === undefined || this.#values[name] !== undefined) continue;\n this.#values[name] = DEV ? checked(props)(tag, name, def, value, 'the seed') : value;\n }\n this.#afterInit = this.#model.resume(seed);\n this.#serverRendered = true;\n }\n\n /**\n * Starts the host, or waits: for the hydration code (a server-rendered host or an island,\n * view/07-hydration.md \"Loading\"), then for an island's trigger (released by\n * attributeChangedCallback).\n */\n #begin(): void {\n const defer = this.hasAttribute(DEFER);\n if (hydrationCode === undefined && (this.#serverRendered || defer)) {\n whenHydrationLoads(() => {\n if (this.isConnected && this.#root === undefined) this.#begin();\n });\n } else if (defer && hydrationCode !== null) hydrationCode?.scheduleIsland(this);\n else this.#start();\n }\n\n #start(): void {\n // `shadow: { delegatesFocus }` (05 \"Focus\"); `true` and `undefined` spread nothing.\n const root = light\n ? this\n : (this.shadowRoot ??\n this.attachShadow({ ...(spec.shadow as object | undefined), mode: 'open' }));\n this.#root = root;\n this.#hydrating = this.#serverRendered && hydrationCode != null && root.hasChildNodes();\n sheets ??= light ? [] : sheetsFor(spec.styles);\n // Rendering fresh: a shadow root without a seed (hand-written DSD) or a server-rendered\n // host whose hydration code failed to load starts empty.\n // A host that failed on the server (ADR 0024) starts fresh: its content is a fallback.\n const failedOnServer = this.hasAttribute(ERROR_ATTRIBUTE);\n if (failedOnServer) this.removeAttribute(ERROR_ATTRIBUTE);\n if (!this.#hydrating) {\n if (!light || this.#serverRendered || failedOnServer) root.replaceChildren();\n if (!light) (root as ShadowRoot).adoptedStyleSheets = sheets;\n }\n this.#listen(DEFAULT_EVENTS);\n this.#state(); // init, unless resumed from a seed\n this.#connect();\n }\n\n #connect(): void {\n this.#task.depth = hostDepth(this);\n const rebound = this.#model.connect();\n if (DEVTOOLS_ENABLED) devConnect(this, tag, true);\n if (!this.#rendered || this.#stale || rebound) this.#invalidate();\n }\n\n #invalidate(onFrame = false): void {\n if (this.#root === undefined) return;\n if (this.isConnected) markDirty(this.#task, onFrame);\n else this.#stale = true;\n }\n\n /** One render (the scheduler calls it): PropsChanged first, then the view and its commit. */\n #render(): void {\n const root = this.#root;\n if (root === undefined || !this.isConnected) {\n this.#stale = true;\n return;\n }\n this.#stale = false;\n this.#model.syncProps(names);\n const failure = this.#model.failure;\n if (failure !== undefined) {\n // init threw (ADR 0024): the error view, once; nothing else runs for this host.\n if (!this.#rendered) this.#fallback(root, failure, undefined);\n this.#rendered = true;\n return;\n }\n try {\n const view = spec.view(this.state, intentNames as IntentNames<string>, this.#model.ctx());\n if (this.#hydrating) {\n hydrationCode?.hydrateRoot(this, tag, view, root, light ? undefined : sheets, this.#seen);\n this.#hydrating = false;\n } else render(view, root, this.#seen);\n formAssociation?.sync(this, this.state, this.#model.ctx(), root);\n } catch (cause) {\n const error = this.#model.fail(cause, 'view', message(31, tag));\n this.#fallback(root, error, this.state);\n return; // the first-render steps wait for a render that succeeds\n }\n const states = spec.states;\n const sync = customStates;\n if (states !== undefined && sync !== undefined) {\n afterRender(POST_STATES, () => {\n sync(this, states(this.state));\n });\n }\n if (this.#rendered) return;\n this.#rendered = true;\n if (DEVTOOLS_ENABLED) devHydrated(this, tag, this.#serverRendered);\n if (this.#model.hasReducer('Hydrated')) {\n const msg = { _tag: 'Hydrated', serverRendered: this.#serverRendered } as Tagged;\n afterRender(POST_HYDRATED, () => {\n this.#model.dispatch(msg);\n });\n }\n const commands = this.#afterInit;\n this.#afterInit = [];\n if (commands.length > 0) {\n afterRender(POST_INIT, () => {\n this.#model.run(commands);\n });\n }\n if (spec.subscriptions !== undefined) {\n afterRender(POST_INIT, () => {\n this.#model.subscribe();\n });\n }\n }\n\n /**\n * Renders `spec.error` (ADR 0024). Without one the root keeps what it shows; a fallback that\n * throws too is reported and changes nothing.\n */\n #fallback(root: ShadowRoot | HTMLElement, error: GyralError, state: S | undefined): void {\n if (spec.error === undefined || errorView === undefined) return;\n const view = (failure: GyralError, at: never): unknown => spec.error?.(failure, at);\n if (errorView(view, root, error, state, this.#hydrating, this.#seen, this, tag)) {\n this.#hydrating = false;\n }\n }\n\n /** Intent event types this host's root listens for (view/05-element.md \"Intent events\"). */\n #listening = new Set<string>();\n\n #listen(types: readonly string[]): void {\n listenForIntents(this.#root as Node, this.#listening, types, this.#onEvent);\n }\n\n /** Told about each template a render instantiates: listen for what its markup names. */\n #seen = (markup: Markup): void => {\n this.#listen(eventsOf(markup));\n };\n\n #onEvent = (event: Event): void => {\n if (this.#root === undefined) return;\n handleIntent(event, this.#root, parsers, tag, this.#model, (msg) => {\n if (msg !== undefined && this.isConnected) this.#model.dispatch(msg);\n });\n };\n }\n formAssociation?.install(Element, spec.formAssociated !== undefined);\n return Element;\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ErrorPhase, type GyralError } from './errors.js';
|
|
2
|
+
import type { Tagged } from './types.js';
|
|
3
|
+
import { type SeenMarkup } from './view/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Renders a component's `error` view into `root`; true when it rendered (a hydrating root is
|
|
6
|
+
* cleared first). A view that throws too is reported and changes nothing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function renderErrorView(view: (error: GyralError, state: never) => unknown, root: ShadowRoot | HTMLElement, error: GyralError, state: unknown, hydrating: boolean, seen: SeenMarkup, host: HTMLElement, tag: string): boolean;
|
|
9
|
+
/** Sends `Errored` to a component whose `update` handles it (a failed update, parse or command). */
|
|
10
|
+
export declare function sendErrored(dispatch: (msg: Tagged) => unknown, phase: ErrorPhase, error: GyralError): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Optional error handling a component asks for by name (ADR 0024, gyral-1zd.17): the `error`
|
|
2
|
+
// fallback view and the `Errored` framework message. Reached through `#spec-features`, so a
|
|
3
|
+
// compiled build bundles each only when some module names `error` or `Errored`
|
|
4
|
+
// (compiler/features.ts); the reporting channel itself (errors.ts) is in every app.
|
|
5
|
+
import { fail } from './errors.js';
|
|
6
|
+
import { message, render } from './view/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Renders a component's `error` view into `root`; true when it rendered (a hydrating root is
|
|
9
|
+
* cleared first). A view that throws too is reported and changes nothing.
|
|
10
|
+
*/
|
|
11
|
+
export function renderErrorView(view, root, error, state, hydrating, seen, host, tag) {
|
|
12
|
+
try {
|
|
13
|
+
const value = view(error, state);
|
|
14
|
+
if (hydrating)
|
|
15
|
+
root.replaceChildren();
|
|
16
|
+
render(value, root, seen);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch (cause) {
|
|
20
|
+
fail(cause, 'view', message(31, tag), { host, tag });
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Sends `Errored` to a component whose `update` handles it (a failed update, parse or command). */
|
|
25
|
+
export function sendErrored(dispatch, phase, error) {
|
|
26
|
+
if (phase === 'update' || phase === 'parse' || phase === 'command') {
|
|
27
|
+
dispatch({ _tag: 'Errored', phase, error });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=error-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-view.js","sourceRoot":"","sources":["../src/error-view.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,4FAA4F;AAC5F,+EAA+E;AAC/E,oFAAoF;AACpF,OAAO,EAAE,IAAI,EAAoC,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAoC,MAAM,iBAAiB,CAAC;AAEpF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAkD,EAClD,IAA8B,EAC9B,KAAiB,EACjB,KAAc,EACd,SAAkB,EAClB,IAAgB,EAChB,IAAiB,EACjB,GAAW;IAEX,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,KAAc,CAAe,CAAC;QACxD,IAAI,SAAS;YAAE,IAAI,CAAC,eAAe,EAAE,CAAC;QACtC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,WAAW,CACzB,QAAkC,EAClC,KAAiB,EACjB,KAAiB;IAEjB,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACnE,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAY,CAAC,CAAC;IACxD,CAAC;AACH,CAAC","sourcesContent":["// Optional error handling a component asks for by name (ADR 0024, gyral-1zd.17): the `error`\n// fallback view and the `Errored` framework message. Reached through `#spec-features`, so a\n// compiled build bundles each only when some module names `error` or `Errored`\n// (compiler/features.ts); the reporting channel itself (errors.ts) is in every app.\nimport { fail, type ErrorPhase, type GyralError } from './errors.js';\nimport type { Tagged } from './types.js';\nimport { message, render, type ChildValue, type SeenMarkup } from './view/index.js';\n\n/**\n * Renders a component's `error` view into `root`; true when it rendered (a hydrating root is\n * cleared first). A view that throws too is reported and changes nothing.\n */\nexport function renderErrorView(\n view: (error: GyralError, state: never) => unknown,\n root: ShadowRoot | HTMLElement,\n error: GyralError,\n state: unknown,\n hydrating: boolean,\n seen: SeenMarkup,\n host: HTMLElement,\n tag: string,\n): boolean {\n try {\n const value = view(error, state as never) as ChildValue;\n if (hydrating) root.replaceChildren();\n render(value, root, seen);\n return true;\n } catch (cause) {\n fail(cause, 'view', message(31, tag), { host, tag });\n return false;\n }\n}\n\n/** Sends `Errored` to a component whose `update` handles it (a failed update, parse or command). */\nexport function sendErrored(\n dispatch: (msg: Tagged) => unknown,\n phase: ErrorPhase,\n error: GyralError,\n): void {\n if (phase === 'update' || phase === 'parse' || phase === 'command') {\n dispatch({ _tag: 'Errored', phase, error } as Tagged);\n }\n}\n"]}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Where a failure happened. */
|
|
2
|
+
export type ErrorPhase = 'init' | 'update' | 'view' | 'parse' | 'command' | 'hook' | 'store' | 'subscribe';
|
|
3
|
+
/** A failure Gyral caught, with its context; `cause` is what was thrown. */
|
|
4
|
+
export declare class GyralError extends Error {
|
|
5
|
+
readonly name = "GyralError";
|
|
6
|
+
/** The failing host's tag; `undefined` for a store or work not tied to one component. */
|
|
7
|
+
readonly component: string | undefined;
|
|
8
|
+
readonly phase: ErrorPhase;
|
|
9
|
+
/** The message tag being reduced, the intent name, or the driver's name. */
|
|
10
|
+
readonly msg: string | undefined;
|
|
11
|
+
constructor(phase: ErrorPhase, text: string, cause: unknown, component?: string, msg?: string);
|
|
12
|
+
}
|
|
13
|
+
/** Where a failure happened, for `fail()`. */
|
|
14
|
+
export interface FailureSite {
|
|
15
|
+
/** The failing host: it gets the boundary event. */
|
|
16
|
+
readonly host?: Element | undefined;
|
|
17
|
+
readonly tag?: string | undefined;
|
|
18
|
+
readonly msg?: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Reports `cause` (ADR 0024 "Recommendation"); returns the GyralError it reported. */
|
|
21
|
+
export declare function fail(cause: unknown, phase: ErrorPhase, text: string, site?: FailureSite): GyralError;
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Errors (ADR 0024): one reporting channel. Every failure Gyral catches becomes a `GyralError`
|
|
2
|
+
// carrying the component, the phase and the message, and goes through `fail()`: the devtools
|
|
3
|
+
// timeline, then a bubbling, composed, cancelable `ErrorEvent('error')` on the failing host
|
|
4
|
+
// (a parent claims it with `preventDefault()`), then `reportError()` unless it was claimed, so
|
|
5
|
+
// `window` `error` listeners and monitoring tools see it. The boundary event stops at the
|
|
6
|
+
// document, so `window` gets each failure once, from `reportError`.
|
|
7
|
+
import { DEVTOOLS_ENABLED, devError } from '#devtools';
|
|
8
|
+
/** A failure Gyral caught, with its context; `cause` is what was thrown. */
|
|
9
|
+
export class GyralError extends Error {
|
|
10
|
+
constructor(phase, text, cause, component, msg) {
|
|
11
|
+
super(text, { cause });
|
|
12
|
+
this.name = 'GyralError';
|
|
13
|
+
this.phase = phase;
|
|
14
|
+
this.component = component;
|
|
15
|
+
this.msg = msg;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
let stopping = false;
|
|
19
|
+
/** Reports `cause` (ADR 0024 "Recommendation"); returns the GyralError it reported. */
|
|
20
|
+
export function fail(cause, phase, text, site = {}) {
|
|
21
|
+
const { host, tag, msg } = site;
|
|
22
|
+
const error = cause instanceof GyralError ? cause : new GyralError(phase, text, cause, tag, msg);
|
|
23
|
+
if (DEVTOOLS_ENABLED)
|
|
24
|
+
devError(host, error);
|
|
25
|
+
let claimed = false;
|
|
26
|
+
if (host?.isConnected === true) {
|
|
27
|
+
if (!stopping) {
|
|
28
|
+
// The boundary event ends at the document: `window` hears the failure from reportError.
|
|
29
|
+
stopping = true;
|
|
30
|
+
document.addEventListener('error', (event) => {
|
|
31
|
+
if (event.error instanceof GyralError)
|
|
32
|
+
event.stopPropagation();
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
claimed = !host.dispatchEvent(new ErrorEvent('error', {
|
|
36
|
+
error,
|
|
37
|
+
message: error.message,
|
|
38
|
+
bubbles: true,
|
|
39
|
+
composed: true,
|
|
40
|
+
cancelable: true,
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
if (!claimed)
|
|
44
|
+
reportError(error); // Baseline widely available since 2024-09 (ADR 0024)
|
|
45
|
+
return error;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,6FAA6F;AAC7F,4FAA4F;AAC5F,+FAA+F;AAC/F,0FAA0F;AAC1F,oEAAoE;AACpE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAMvD,4EAA4E;AAC5E,MAAM,OAAO,UAAW,SAAQ,KAAK;IAQnC,YAAY,KAAiB,EAAE,IAAY,EAAE,KAAc,EAAE,SAAkB,EAAE,GAAY;QAC3F,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QARP,SAAI,GAAG,YAAY,CAAC;QASpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;CACF;AAUD,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB,uFAAuF;AACvF,MAAM,UAAU,IAAI,CAClB,KAAc,EACd,KAAiB,EACjB,IAAY,EACZ,OAAoB,EAAE;IAEtB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAChC,MAAM,KAAK,GAAG,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IACjG,IAAI,gBAAgB;QAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5C,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,IAAI,EAAE,WAAW,KAAK,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,wFAAwF;YACxF,QAAQ,GAAG,IAAI,CAAC;YAChB,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC3C,IAAI,KAAK,CAAC,KAAK,YAAY,UAAU;oBAAE,KAAK,CAAC,eAAe,EAAE,CAAC;YACjE,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC,aAAa,CAC3B,IAAI,UAAU,CAAC,OAAO,EAAE;YACtB,KAAK;YACL,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,IAAI;SACjB,CAAC,CACH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO;QAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,qDAAqD;IACvF,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["// Errors (ADR 0024): one reporting channel. Every failure Gyral catches becomes a `GyralError`\n// carrying the component, the phase and the message, and goes through `fail()`: the devtools\n// timeline, then a bubbling, composed, cancelable `ErrorEvent('error')` on the failing host\n// (a parent claims it with `preventDefault()`), then `reportError()` unless it was claimed, so\n// `window` `error` listeners and monitoring tools see it. The boundary event stops at the\n// document, so `window` gets each failure once, from `reportError`.\nimport { DEVTOOLS_ENABLED, devError } from '#devtools';\n\n/** Where a failure happened. */\nexport type ErrorPhase =\n 'init' | 'update' | 'view' | 'parse' | 'command' | 'hook' | 'store' | 'subscribe';\n\n/** A failure Gyral caught, with its context; `cause` is what was thrown. */\nexport class GyralError extends Error {\n override readonly name = 'GyralError';\n /** The failing host's tag; `undefined` for a store or work not tied to one component. */\n readonly component: string | undefined;\n readonly phase: ErrorPhase;\n /** The message tag being reduced, the intent name, or the driver's name. */\n readonly msg: string | undefined;\n\n constructor(phase: ErrorPhase, text: string, cause: unknown, component?: string, msg?: string) {\n super(text, { cause });\n this.phase = phase;\n this.component = component;\n this.msg = msg;\n }\n}\n\n/** Where a failure happened, for `fail()`. */\nexport interface FailureSite {\n /** The failing host: it gets the boundary event. */\n readonly host?: Element | undefined;\n readonly tag?: string | undefined;\n readonly msg?: string | undefined;\n}\n\nlet stopping = false;\n\n/** Reports `cause` (ADR 0024 \"Recommendation\"); returns the GyralError it reported. */\nexport function fail(\n cause: unknown,\n phase: ErrorPhase,\n text: string,\n site: FailureSite = {},\n): GyralError {\n const { host, tag, msg } = site;\n const error = cause instanceof GyralError ? cause : new GyralError(phase, text, cause, tag, msg);\n if (DEVTOOLS_ENABLED) devError(host, error);\n let claimed = false;\n if (host?.isConnected === true) {\n if (!stopping) {\n // The boundary event ends at the document: `window` hears the failure from reportError.\n stopping = true;\n document.addEventListener('error', (event) => {\n if (event.error instanceof GyralError) event.stopPropagation();\n });\n }\n claimed = !host.dispatchEvent(\n new ErrorEvent('error', {\n error,\n message: error.message,\n bubbles: true,\n composed: true,\n cancelable: true,\n }),\n );\n }\n if (!claimed) reportError(error); // Baseline widely available since 2024-09 (ADR 0024)\n return error;\n}\n"]}
|