@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 @@
|
|
|
1
|
+
{"version":3,"file":"loader-source.js","sourceRoot":"","sources":["../../src/compiler/loader-source.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,6FAA6F;AAQ7F;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAiC,EACjC,UAAyB,EAAE;IAE3B,MAAM,OAAO,GAAG;QACd,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CACd,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CACpF;QACD,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;aACrB,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aAC/B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,6BAA6B,CAAC;KACxE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACb,MAAM,OAAO,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnF,OAAO;;EAEP,OAAO;;gBAEO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DtC,CAAC;AACF,CAAC","sourcesContent":["// The component loader's source (./components.ts): a module that imports a tag's module the\n// first time that tag is in the document. No Node imports, so tests can run it in a browser.\n\n/** How a production build writes the loader (./components.ts). */\nexport interface LoaderOptions {\n /** Tags the app's entry defines: wait for registration and watch their shadow roots. */\n readonly known?: readonly string[];\n}\n\n/**\n * The loader: imports a tag's module the first time that tag is rendered, in the document or in\n * the shadow root of a component it defined (now, or after a mutation, checked once per\n * microtask), then forgets it. It registers itself on `globalThis[Symbol.for('gyral.components')]`\n * so `componentsReady()` (core) can wait until every rendered tag it knows is defined.\n * Shadow roots are observed by the one shared MutationObserver; a removed host's root is\n * dropped from the scan and its registration is collected with it.\n */\nexport function loaderSource(\n tags: ReadonlyMap<string, string>,\n options: LoaderOptions = {},\n): string {\n const entries = [\n ...[...tags].map(\n ([tag, url]) => ` [${JSON.stringify(tag)}, () => import(${JSON.stringify(url)})],`,\n ),\n ...(options.known ?? [])\n .filter((tag) => !tags.has(tag))\n .map((tag) => ` [${JSON.stringify(tag)}, () => Promise.resolve()],`),\n ].join('\\n');\n const watched = [...new Set([...tags.keys(), ...(options.known ?? [])])].join(',');\n return `// Generated by gyralVitePreset({ components: true }).\nconst pending = new Map([\n${entries}\n]);\nconst known = ${JSON.stringify(watched)};\nconst roots = new Set();\nconst inflight = new Set();\nlet queued = false;\nconst observer = new MutationObserver(() => {\n if (!queued) {\n queued = true;\n queueMicrotask(scan);\n }\n});\nfunction watch(root) {\n for (const host of root.querySelectorAll(known)) {\n const shadow = host.shadowRoot;\n if (shadow !== null && !roots.has(shadow)) {\n roots.add(shadow);\n observer.observe(shadow, { childList: true, subtree: true });\n watch(shadow);\n }\n }\n}\nfunction scan() {\n queued = false;\n for (const root of roots) if (!root.host.isConnected) roots.delete(root);\n if (known !== '') {\n watch(document);\n for (const root of [...roots]) watch(root);\n }\n for (const [tag, load] of pending) {\n if (customElements.get(tag) !== undefined) {\n pending.delete(tag);\n continue;\n }\n let found = document.querySelector(tag) !== null;\n for (const root of roots) if (!found && root.querySelector(tag) !== null) found = true;\n if (!found) continue;\n pending.delete(tag);\n const done = load()\n .then(() => customElements.whenDefined(tag))\n .then(() => {\n // The upgraded host renders into its shadow root next: look there too.\n if (!queued) {\n queued = true;\n queueMicrotask(scan);\n }\n })\n .finally(() => inflight.delete(done));\n inflight.add(done);\n }\n if (pending.size === 0) observer.disconnect();\n}\nasync function ready() {\n for (;;) {\n scan();\n if (inflight.size === 0) return;\n await Promise.allSettled([...inflight]);\n await new Promise((resolve) => setTimeout(resolve));\n }\n}\nglobalThis[Symbol.for('gyral.components')] = { ready };\nobserver.observe(document.documentElement, { childList: true, subtree: true });\nscan();\n`;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
type Fn<H> = H extends {
|
|
3
|
+
handler: infer F;
|
|
4
|
+
} ? F : H;
|
|
5
|
+
type HookFn<K extends keyof Plugin> = Fn<NonNullable<Plugin[K]>>;
|
|
6
|
+
export interface LocatorHooks {
|
|
7
|
+
readonly configResolved: HookFn<'configResolved'>;
|
|
8
|
+
readonly transform: HookFn<'transform'>;
|
|
9
|
+
}
|
|
10
|
+
/** Core's own view modules: always sources (core-internal templates, tests). */
|
|
11
|
+
export declare const VIEW: string[];
|
|
12
|
+
/** `sources`: as the compiler's (module specifiers whose `html` and `svg` are the view layer's tags). */
|
|
13
|
+
export declare function createLocator(sources: readonly string[]): LocatorHooks;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Development source locations for runtime templates (view/01-templates.md "Source locations",
|
|
2
|
+
// gyral-g1r.24). `vite serve` (the dev server and Vitest) doesn't compile templates, and stack
|
|
3
|
+
// traces point into Vite's transformed modules, whose lines aren't the author's. So the preset's
|
|
4
|
+
// `gyral:template-locations` plugin (serve only, enforce: 'pre', loaded lazily like the
|
|
5
|
+
// compiler) rewrites each html`…` call site of the configured sources into
|
|
6
|
+
// (html.at?.("src/app.ts:12:5") ?? html)`…`
|
|
7
|
+
// (svg`…` call sites the same way, with svg.at) and the development runtime records that
|
|
8
|
+
// position for the template (view/loc.ts). Nothing else changes and no line moves. Uses the
|
|
9
|
+
// compiler can't follow (an aliased html) stay as they are: the runtime falls back to the stack
|
|
10
|
+
// trace there.
|
|
11
|
+
import { relative } from 'node:path';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
13
|
+
import { langOf, nodeAt } from './ast.js';
|
|
14
|
+
import { findUses, htmlImports } from './scan.js';
|
|
15
|
+
import { Lines, splice } from './source.js';
|
|
16
|
+
/** Core's own view modules: always sources (core-internal templates, tests). */
|
|
17
|
+
export const VIEW = ['index', 'template'].flatMap((name) => ['.ts', '.js'].map((ext) => fileURLToPath(new URL(`../view/${name}${ext}`, import.meta.url))));
|
|
18
|
+
const SCRIPT = /\.[cm]?[jt]sx?$/;
|
|
19
|
+
/** `sources`: as the compiler's (module specifiers whose `html` and `svg` are the view layer's tags). */
|
|
20
|
+
export function createLocator(sources) {
|
|
21
|
+
let root = '';
|
|
22
|
+
/** Resolved ids of the sources, per environment (resolution may differ between them). */
|
|
23
|
+
const resolved = new WeakMap();
|
|
24
|
+
return {
|
|
25
|
+
configResolved(config) {
|
|
26
|
+
root = config.root;
|
|
27
|
+
},
|
|
28
|
+
async transform(code, id) {
|
|
29
|
+
if (id.startsWith('\0') || !SCRIPT.test(id) || id.includes('/node_modules/'))
|
|
30
|
+
return null;
|
|
31
|
+
let program;
|
|
32
|
+
try {
|
|
33
|
+
program = this.parse(code, { lang: langOf(id) });
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null; // not ours to report
|
|
37
|
+
}
|
|
38
|
+
const { imports } = htmlImports(program);
|
|
39
|
+
if (imports.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
let ids = resolved.get(this.environment);
|
|
42
|
+
if (ids === undefined) {
|
|
43
|
+
ids = Promise.all(sources.map((s) => this.resolve(s, id))).then((rs) => new Set([...VIEW, ...rs.flatMap((r) => (r === null ? [] : [r.id]))]));
|
|
44
|
+
resolved.set(this.environment, ids);
|
|
45
|
+
}
|
|
46
|
+
const sourceIds = await ids;
|
|
47
|
+
const matched = [];
|
|
48
|
+
for (const binding of imports) {
|
|
49
|
+
const r = sources.includes(binding.specifier)
|
|
50
|
+
? null
|
|
51
|
+
: await this.resolve(binding.specifier, id);
|
|
52
|
+
if (sources.includes(binding.specifier) || (r !== null && sourceIds.has(r.id))) {
|
|
53
|
+
matched.push(binding);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (matched.length === 0)
|
|
57
|
+
return null;
|
|
58
|
+
const { sites } = findUses(program, matched);
|
|
59
|
+
if (sites.length === 0)
|
|
60
|
+
return null;
|
|
61
|
+
const lines = new Lines(code);
|
|
62
|
+
const file = relative(root, id);
|
|
63
|
+
const edits = [];
|
|
64
|
+
for (const { node } of sites) {
|
|
65
|
+
const tag = nodeAt(node, 'tag');
|
|
66
|
+
if (tag === undefined)
|
|
67
|
+
continue;
|
|
68
|
+
const { line, column } = lines.position(node.start);
|
|
69
|
+
const loc = JSON.stringify(`${file}:${String(line)}:${String(column + 1)}`);
|
|
70
|
+
const name = code.slice(tag.start, tag.end);
|
|
71
|
+
edits.push({ start: tag.start, end: tag.start, text: '(' });
|
|
72
|
+
edits.push({ start: tag.end, end: tag.end, text: `.at?.(${loc}) ?? ${name})` });
|
|
73
|
+
}
|
|
74
|
+
return splice(lines, edits, id);
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=locate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locate.js","sourceRoot":"","sources":["../../src/compiler/locate.ts"],"names":[],"mappings":"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","sourcesContent":["// Development source locations for runtime templates (view/01-templates.md \"Source locations\",\n// gyral-g1r.24). `vite serve` (the dev server and Vitest) doesn't compile templates, and stack\n// traces point into Vite's transformed modules, whose lines aren't the author's. So the preset's\n// `gyral:template-locations` plugin (serve only, enforce: 'pre', loaded lazily like the\n// compiler) rewrites each html`…` call site of the configured sources into\n// (html.at?.(\"src/app.ts:12:5\") ?? html)`…`\n// (svg`…` call sites the same way, with svg.at) and the development runtime records that\n// position for the template (view/loc.ts). Nothing else changes and no line moves. Uses the\n// compiler can't follow (an aliased html) stay as they are: the runtime falls back to the stack\n// trace there.\nimport { relative } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Plugin } from 'vite';\nimport { langOf, nodeAt, type Node } from './ast.js';\nimport { findUses, htmlImports } from './scan.js';\nimport { Lines, splice, type Edit } from './source.js';\n\ntype Fn<H> = H extends { handler: infer F } ? F : H;\ntype HookFn<K extends keyof Plugin> = Fn<NonNullable<Plugin[K]>>;\n\nexport interface LocatorHooks {\n readonly configResolved: HookFn<'configResolved'>;\n readonly transform: HookFn<'transform'>;\n}\n\n/** Core's own view modules: always sources (core-internal templates, tests). */\nexport const VIEW = ['index', 'template'].flatMap((name) =>\n ['.ts', '.js'].map((ext) => fileURLToPath(new URL(`../view/${name}${ext}`, import.meta.url))),\n);\n\nconst SCRIPT = /\\.[cm]?[jt]sx?$/;\n\n/** `sources`: as the compiler's (module specifiers whose `html` and `svg` are the view layer's tags). */\nexport function createLocator(sources: readonly string[]): LocatorHooks {\n let root = '';\n /** Resolved ids of the sources, per environment (resolution may differ between them). */\n const resolved = new WeakMap<object, Promise<Set<string>>>();\n\n return {\n configResolved(config) {\n root = config.root;\n },\n\n async transform(code, id) {\n if (id.startsWith('\\0') || !SCRIPT.test(id) || id.includes('/node_modules/')) return null;\n let program: Node;\n try {\n program = this.parse(code, { lang: langOf(id) }) as unknown as Node;\n } catch {\n return null; // not ours to report\n }\n const { imports } = htmlImports(program);\n if (imports.length === 0) return null;\n let ids = resolved.get(this.environment);\n if (ids === undefined) {\n ids = Promise.all(sources.map((s) => this.resolve(s, id))).then(\n (rs) => new Set([...VIEW, ...rs.flatMap((r) => (r === null ? [] : [r.id]))]),\n );\n resolved.set(this.environment, ids);\n }\n const sourceIds = await ids;\n const matched = [];\n for (const binding of imports) {\n const r = sources.includes(binding.specifier)\n ? null\n : await this.resolve(binding.specifier, id);\n if (sources.includes(binding.specifier) || (r !== null && sourceIds.has(r.id))) {\n matched.push(binding);\n }\n }\n if (matched.length === 0) return null;\n const { sites } = findUses(program, matched);\n if (sites.length === 0) return null;\n const lines = new Lines(code);\n const file = relative(root, id);\n const edits: Edit[] = [];\n for (const { node } of sites) {\n const tag = nodeAt(node, 'tag');\n if (tag === undefined) continue;\n const { line, column } = lines.position(node.start);\n const loc = JSON.stringify(`${file}:${String(line)}:${String(column + 1)}`);\n const name = code.slice(tag.start, tag.end);\n edits.push({ start: tag.start, end: tag.start, text: '(' });\n edits.push({ start: tag.end, end: tag.end, text: `.at?.(${loc}) ?? ${name})` });\n }\n return splice(lines, edits, id);\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Shape, type TemplateObject } from '../view/index.js';
|
|
2
|
+
/** The slice of parse5's API the check uses (default tree adapter). */
|
|
3
|
+
export interface Parse5 {
|
|
4
|
+
parseFragment(html: string): Parse5Node;
|
|
5
|
+
}
|
|
6
|
+
interface Parse5Node {
|
|
7
|
+
readonly nodeName: string;
|
|
8
|
+
readonly tagName?: string;
|
|
9
|
+
readonly childNodes?: readonly Parse5Node[];
|
|
10
|
+
readonly content?: Parse5Node;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Loads parse5 (`specifier`) as resolved from `@gyral/core`, else from the app's `root`;
|
|
14
|
+
* undefined when neither has it. `require` (Node loads ES modules with it too) rather than
|
|
15
|
+
* `import()`: when core runs from source, this module is loaded by a Vite module runner that
|
|
16
|
+
* is closed by the time the build starts.
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadParse5(specifier: string, root: string): Parse5 | undefined;
|
|
19
|
+
/** Rule 7's error when parse5 builds a different tree than `shape`; undefined if it agrees. */
|
|
20
|
+
export declare function checkWithParse5(parse5: Parse5, template: TemplateObject, shape: Shape): Error | undefined;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Rule 7 at build time with parse5 (view/09-template-rules.md "How rule 7 is checked"): a
|
|
2
|
+
// spec-compliant HTML parser parses each template's HTML as <template> content, exactly like
|
|
3
|
+
// the runtime path's `<template>.innerHTML`, and its tree is compared with the shape the
|
|
4
|
+
// normalizer computed paths for (view/normalize/shape.ts, shared with the browser check). An
|
|
5
|
+
// svg template is parsed inside an <svg>, as the browser path does (template-element.ts).
|
|
6
|
+
//
|
|
7
|
+
// parse5 is an optional peer dependency of @gyral/core, loaded at build time by the compiler
|
|
8
|
+
// only: it never reaches browser or server bundles. Without it the build still runs
|
|
9
|
+
// the normalizer's structural rule 7 check and skips this one.
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
import { repairError, shapeMismatch, } from '../view/index.js';
|
|
13
|
+
const isParse5 = (value) => typeof value === 'object' &&
|
|
14
|
+
value !== null &&
|
|
15
|
+
typeof value.parseFragment === 'function';
|
|
16
|
+
/**
|
|
17
|
+
* Loads parse5 (`specifier`) as resolved from `@gyral/core`, else from the app's `root`;
|
|
18
|
+
* undefined when neither has it. `require` (Node loads ES modules with it too) rather than
|
|
19
|
+
* `import()`: when core runs from source, this module is loaded by a Vite module runner that
|
|
20
|
+
* is closed by the time the build starts.
|
|
21
|
+
*/
|
|
22
|
+
export function loadParse5(specifier, root) {
|
|
23
|
+
for (const base of [import.meta.url, join(root, 'package.json')]) {
|
|
24
|
+
try {
|
|
25
|
+
const module = createRequire(base)(specifier);
|
|
26
|
+
if (isParse5(module))
|
|
27
|
+
return module;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// not resolvable from here
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
function toShape(nodes) {
|
|
36
|
+
return nodes.map((node) => {
|
|
37
|
+
if (node.nodeName === '#text')
|
|
38
|
+
return '#text';
|
|
39
|
+
if (node.nodeName === '#comment')
|
|
40
|
+
return '#comment';
|
|
41
|
+
const inner = node.tagName === 'template' ? node.content?.childNodes : node.childNodes;
|
|
42
|
+
return [(node.tagName ?? node.nodeName).toLowerCase(), toShape(inner ?? [])];
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** Rule 7's error when parse5 builds a different tree than `shape`; undefined if it agrees. */
|
|
46
|
+
export function checkWithParse5(parse5, template, shape) {
|
|
47
|
+
// Page shells (document-level tags) are written by the server and never parsed as a
|
|
48
|
+
// fragment; fragment parsing would drop their <html>/<head>/<body> tags.
|
|
49
|
+
if (template.server)
|
|
50
|
+
return undefined;
|
|
51
|
+
let nodes = parse5.parseFragment(template.svg ? `<svg>${template.html}</svg>` : template.html).childNodes;
|
|
52
|
+
// An svg template: the <svg>'s children, plus anything the parser moved out of it.
|
|
53
|
+
if (template.svg && nodes !== undefined)
|
|
54
|
+
nodes = [...(nodes[0]?.childNodes ?? []), ...nodes.slice(1)];
|
|
55
|
+
const problem = shapeMismatch(shape, toShape(nodes ?? []));
|
|
56
|
+
return problem === undefined
|
|
57
|
+
? undefined
|
|
58
|
+
: repairError(template, 'The HTML parser (parse5)', problem);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=parse5-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse5-check.js","sourceRoot":"","sources":["../../src/compiler/parse5-check.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,6FAA6F;AAC7F,yFAAyF;AACzF,6FAA6F;AAC7F,0FAA0F;AAC1F,EAAE;AACF,6FAA6F;AAC7F,oFAAoF;AACpF,+DAA+D;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,WAAW,EACX,aAAa,GAId,MAAM,kBAAkB,CAAC;AAc1B,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAmB,EAAE,CACnD,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,OAAQ,KAAqC,CAAC,aAAa,KAAK,UAAU,CAAC;AAE7E;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,IAAY;IACxD,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC;YACH,MAAM,MAAM,GAAY,aAAa,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;YACvD,IAAI,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,OAAO,CAAC,KAA4B;IAC3C,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAa,EAAE;QACnC,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO;YAAE,OAAO,OAAO,CAAC;QAC9C,IAAI,IAAI,CAAC,QAAQ,KAAK,UAAU;YAAE,OAAO,UAAU,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACvF,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;AACL,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,QAAwB,EACxB,KAAY;IAEZ,oFAAoF;IACpF,yEAAyE;IACzE,IAAI,QAAQ,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACtC,IAAI,KAAK,GAAG,MAAM,CAAC,aAAa,CAC9B,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,QAAQ,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAC7D,CAAC,UAAU,CAAC;IACb,mFAAmF;IACnF,IAAI,QAAQ,CAAC,GAAG,IAAI,KAAK,KAAK,SAAS;QACrC,KAAK,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,OAAO,KAAK,SAAS;QAC1B,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,WAAW,CAAC,QAAQ,EAAE,0BAA0B,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC","sourcesContent":["// Rule 7 at build time with parse5 (view/09-template-rules.md \"How rule 7 is checked\"): a\n// spec-compliant HTML parser parses each template's HTML as <template> content, exactly like\n// the runtime path's `<template>.innerHTML`, and its tree is compared with the shape the\n// normalizer computed paths for (view/normalize/shape.ts, shared with the browser check). An\n// svg template is parsed inside an <svg>, as the browser path does (template-element.ts).\n//\n// parse5 is an optional peer dependency of @gyral/core, loaded at build time by the compiler\n// only: it never reaches browser or server bundles. Without it the build still runs\n// the normalizer's structural rule 7 check and skips this one.\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport {\n repairError,\n shapeMismatch,\n type Shape,\n type ShapeNode,\n type TemplateObject,\n} from '../view/index.js';\n\n/** The slice of parse5's API the check uses (default tree adapter). */\nexport interface Parse5 {\n parseFragment(html: string): Parse5Node;\n}\n\ninterface Parse5Node {\n readonly nodeName: string;\n readonly tagName?: string;\n readonly childNodes?: readonly Parse5Node[];\n readonly content?: Parse5Node;\n}\n\nconst isParse5 = (value: unknown): value is Parse5 =>\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { parseFragment?: unknown }).parseFragment === 'function';\n\n/**\n * Loads parse5 (`specifier`) as resolved from `@gyral/core`, else from the app's `root`;\n * undefined when neither has it. `require` (Node loads ES modules with it too) rather than\n * `import()`: when core runs from source, this module is loaded by a Vite module runner that\n * is closed by the time the build starts.\n */\nexport function loadParse5(specifier: string, root: string): Parse5 | undefined {\n for (const base of [import.meta.url, join(root, 'package.json')]) {\n try {\n const module: unknown = createRequire(base)(specifier);\n if (isParse5(module)) return module;\n } catch {\n // not resolvable from here\n }\n }\n return undefined;\n}\n\nfunction toShape(nodes: readonly Parse5Node[]): Shape {\n return nodes.map((node): ShapeNode => {\n if (node.nodeName === '#text') return '#text';\n if (node.nodeName === '#comment') return '#comment';\n const inner = node.tagName === 'template' ? node.content?.childNodes : node.childNodes;\n return [(node.tagName ?? node.nodeName).toLowerCase(), toShape(inner ?? [])];\n });\n}\n\n/** Rule 7's error when parse5 builds a different tree than `shape`; undefined if it agrees. */\nexport function checkWithParse5(\n parse5: Parse5,\n template: TemplateObject,\n shape: Shape,\n): Error | undefined {\n // Page shells (document-level tags) are written by the server and never parsed as a\n // fragment; fragment parsing would drop their <html>/<head>/<body> tags.\n if (template.server) return undefined;\n let nodes = parse5.parseFragment(\n template.svg ? `<svg>${template.html}</svg>` : template.html,\n ).childNodes;\n // An svg template: the <svg>'s children, plus anything the parser moved out of it.\n if (template.svg && nodes !== undefined)\n nodes = [...(nodes[0]?.childNodes ?? []), ...nodes.slice(1)];\n const problem = shapeMismatch(shape, toShape(nodes ?? []));\n return problem === undefined\n ? undefined\n : repairError(template, 'The HTML parser (parse5)', problem);\n}\n"]}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Property-only prop schemas out of production client builds (gyral-c5d.14, view/05-element.md
|
|
2
|
+
// "When props are validated"): `prop.value(check, opts)` declares a prop with no attribute, and
|
|
3
|
+
// production never checks property sets (or seeds), so its schema or type guard can't run
|
|
4
|
+
// there. Replacing a check that is a plain reference (`prop.value(Settings)`, `schemas.settings`) or an
|
|
5
|
+
// inline function (`prop.value((u): u is Settings => …)`) with `void 0` lets the bundler drop it and
|
|
6
|
+
// whatever only it used, e.g. a schema module (when the bundler can: Rolldown in Vite 8.3 keeps
|
|
7
|
+
// side-effect-free schema builders in a lazy chunk once their library is in a chunk shared with
|
|
8
|
+
// the entry; view/05 "When props are validated"). Calls (`prop.value(v.array(Item))`) stay: their
|
|
9
|
+
// evaluation could have effects, and this pass never changes what runs. `prop.json` keeps its
|
|
10
|
+
// check (attributes are parsed through it in production). Development builds keep everything:
|
|
11
|
+
// they validate property sets.
|
|
12
|
+
import { children, nodeAt, nodesAt, scopeNames } from './ast.js';
|
|
13
|
+
/** Where `prop` comes from: the documented import only (`import { prop } from '@gyral/core'`). */
|
|
14
|
+
const CORE = '@gyral/core';
|
|
15
|
+
/** TypeScript wrappers around a runtime expression (`x as T`, `x satisfies T`, `x!`). */
|
|
16
|
+
const WRAPPERS = new Set(['TSAsExpression', 'TSSatisfiesExpression', 'TSNonNullExpression']);
|
|
17
|
+
/** Expressions whose evaluation has no effect: dropping them changes nothing that runs. */
|
|
18
|
+
function droppable(node) {
|
|
19
|
+
if (node === undefined)
|
|
20
|
+
return false;
|
|
21
|
+
if (WRAPPERS.has(node.type))
|
|
22
|
+
return droppable(nodeAt(node, 'expression'));
|
|
23
|
+
switch (node.type) {
|
|
24
|
+
case 'Identifier':
|
|
25
|
+
case 'ArrowFunctionExpression':
|
|
26
|
+
case 'FunctionExpression':
|
|
27
|
+
return true;
|
|
28
|
+
case 'MemberExpression': {
|
|
29
|
+
// `schemas.settings`: a chain of plain names (no computed keys, no calls, no optional links).
|
|
30
|
+
const object = nodeAt(node, 'object');
|
|
31
|
+
return (node['computed'] !== true &&
|
|
32
|
+
node['optional'] !== true &&
|
|
33
|
+
(object?.type === 'Identifier' ||
|
|
34
|
+
(object?.type === 'MemberExpression' && droppable(object))));
|
|
35
|
+
}
|
|
36
|
+
default:
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** The names `prop` is imported as: `{ local }` or, for `import * as ns`, `{ ns }`. */
|
|
41
|
+
function propImports(program) {
|
|
42
|
+
const locals = new Set();
|
|
43
|
+
const ns = new Set();
|
|
44
|
+
for (const statement of nodesAt(program, 'body')) {
|
|
45
|
+
if (statement.type !== 'ImportDeclaration' || statement['importKind'] === 'type')
|
|
46
|
+
continue;
|
|
47
|
+
if (nodeAt(statement, 'source')?.['value'] !== CORE)
|
|
48
|
+
continue;
|
|
49
|
+
for (const s of nodesAt(statement, 'specifiers')) {
|
|
50
|
+
const local = nodeAt(s, 'local')?.['name'];
|
|
51
|
+
if (typeof local !== 'string' || s['importKind'] === 'type')
|
|
52
|
+
continue;
|
|
53
|
+
if (s.type === 'ImportNamespaceSpecifier')
|
|
54
|
+
ns.add(local);
|
|
55
|
+
const imported = nodeAt(s, 'imported');
|
|
56
|
+
if (s.type === 'ImportSpecifier' && (imported?.['name'] ?? imported?.['value']) === 'prop') {
|
|
57
|
+
locals.add(local);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return { locals, ns };
|
|
62
|
+
}
|
|
63
|
+
/** Edits that replace the droppable first argument of each `prop.value(…)` call with `void 0`. */
|
|
64
|
+
export function stripPropSchemas(program, code) {
|
|
65
|
+
const { locals, ns } = propImports(program);
|
|
66
|
+
if (locals.size === 0 && ns.size === 0)
|
|
67
|
+
return [];
|
|
68
|
+
const edits = [];
|
|
69
|
+
const scopes = [];
|
|
70
|
+
const visible = (name, names) => typeof name === 'string' && names.has(name) && !scopes.some((s) => s.has(name));
|
|
71
|
+
/** `prop.value` (or `ns.prop.value`) with `prop`/`ns` the imported binding. */
|
|
72
|
+
const isPropValue = (callee) => {
|
|
73
|
+
if (callee?.type !== 'MemberExpression' || callee['computed'] === true)
|
|
74
|
+
return false;
|
|
75
|
+
if (nodeAt(callee, 'property')?.['name'] !== 'value')
|
|
76
|
+
return false;
|
|
77
|
+
const object = nodeAt(callee, 'object');
|
|
78
|
+
if (object?.type === 'Identifier')
|
|
79
|
+
return visible(object['name'], locals);
|
|
80
|
+
if (object?.type !== 'MemberExpression' || object['computed'] === true)
|
|
81
|
+
return false;
|
|
82
|
+
const base = nodeAt(object, 'object');
|
|
83
|
+
return (nodeAt(object, 'property')?.['name'] === 'prop' &&
|
|
84
|
+
base?.type === 'Identifier' &&
|
|
85
|
+
visible(base['name'], ns));
|
|
86
|
+
};
|
|
87
|
+
const walk = (node) => {
|
|
88
|
+
const declared = scopeNames(node)?.filter((name) => locals.has(name) || ns.has(name));
|
|
89
|
+
if (declared !== undefined && declared.length > 0)
|
|
90
|
+
scopes.push(new Set(declared));
|
|
91
|
+
if (node.type === 'CallExpression' && isPropValue(nodeAt(node, 'callee'))) {
|
|
92
|
+
const [check] = nodesAt(node, 'arguments');
|
|
93
|
+
if (check !== undefined && droppable(check)) {
|
|
94
|
+
// Keep the line count, so every following line keeps its number.
|
|
95
|
+
const lines = code.slice(check.start, check.end).split('\n').length - 1;
|
|
96
|
+
edits.push({ start: check.start, end: check.end, text: `void 0${'\n'.repeat(lines)}` });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
for (const child of children(node))
|
|
100
|
+
walk(child);
|
|
101
|
+
if (declared !== undefined && declared.length > 0)
|
|
102
|
+
scopes.pop();
|
|
103
|
+
};
|
|
104
|
+
for (const statement of nodesAt(program, 'body'))
|
|
105
|
+
walk(statement);
|
|
106
|
+
return edits;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=prop-schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prop-schemas.js","sourceRoot":"","sources":["../../src/compiler/prop-schemas.ts"],"names":[],"mappings":"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","sourcesContent":["// Property-only prop schemas out of production client builds (gyral-c5d.14, view/05-element.md\n// \"When props are validated\"): `prop.value(check, opts)` declares a prop with no attribute, and\n// production never checks property sets (or seeds), so its schema or type guard can't run\n// there. Replacing a check that is a plain reference (`prop.value(Settings)`, `schemas.settings`) or an\n// inline function (`prop.value((u): u is Settings => …)`) with `void 0` lets the bundler drop it and\n// whatever only it used, e.g. a schema module (when the bundler can: Rolldown in Vite 8.3 keeps\n// side-effect-free schema builders in a lazy chunk once their library is in a chunk shared with\n// the entry; view/05 \"When props are validated\"). Calls (`prop.value(v.array(Item))`) stay: their\n// evaluation could have effects, and this pass never changes what runs. `prop.json` keeps its\n// check (attributes are parsed through it in production). Development builds keep everything:\n// they validate property sets.\nimport { children, nodeAt, nodesAt, scopeNames, type Node } from './ast.js';\nimport type { Edit } from './source.js';\n\n/** Where `prop` comes from: the documented import only (`import { prop } from '@gyral/core'`). */\nconst CORE = '@gyral/core';\n\n/** TypeScript wrappers around a runtime expression (`x as T`, `x satisfies T`, `x!`). */\nconst WRAPPERS = new Set(['TSAsExpression', 'TSSatisfiesExpression', 'TSNonNullExpression']);\n\n/** Expressions whose evaluation has no effect: dropping them changes nothing that runs. */\nfunction droppable(node: Node | undefined): boolean {\n if (node === undefined) return false;\n if (WRAPPERS.has(node.type)) return droppable(nodeAt(node, 'expression'));\n switch (node.type) {\n case 'Identifier':\n case 'ArrowFunctionExpression':\n case 'FunctionExpression':\n return true;\n case 'MemberExpression': {\n // `schemas.settings`: a chain of plain names (no computed keys, no calls, no optional links).\n const object = nodeAt(node, 'object');\n return (\n node['computed'] !== true &&\n node['optional'] !== true &&\n (object?.type === 'Identifier' ||\n (object?.type === 'MemberExpression' && droppable(object)))\n );\n }\n default:\n return false;\n }\n}\n\n/** The names `prop` is imported as: `{ local }` or, for `import * as ns`, `{ ns }`. */\nfunction propImports(program: Node): { readonly locals: Set<string>; readonly ns: Set<string> } {\n const locals = new Set<string>();\n const ns = new Set<string>();\n for (const statement of nodesAt(program, 'body')) {\n if (statement.type !== 'ImportDeclaration' || statement['importKind'] === 'type') continue;\n if (nodeAt(statement, 'source')?.['value'] !== CORE) continue;\n for (const s of nodesAt(statement, 'specifiers')) {\n const local = nodeAt(s, 'local')?.['name'];\n if (typeof local !== 'string' || s['importKind'] === 'type') continue;\n if (s.type === 'ImportNamespaceSpecifier') ns.add(local);\n const imported = nodeAt(s, 'imported');\n if (s.type === 'ImportSpecifier' && (imported?.['name'] ?? imported?.['value']) === 'prop') {\n locals.add(local);\n }\n }\n }\n return { locals, ns };\n}\n\n/** Edits that replace the droppable first argument of each `prop.value(…)` call with `void 0`. */\nexport function stripPropSchemas(program: Node, code: string): Edit[] {\n const { locals, ns } = propImports(program);\n if (locals.size === 0 && ns.size === 0) return [];\n const edits: Edit[] = [];\n const scopes: Set<string>[] = [];\n const visible = (name: unknown, names: Set<string>): boolean =>\n typeof name === 'string' && names.has(name) && !scopes.some((s) => s.has(name));\n\n /** `prop.value` (or `ns.prop.value`) with `prop`/`ns` the imported binding. */\n const isPropValue = (callee: Node | undefined): boolean => {\n if (callee?.type !== 'MemberExpression' || callee['computed'] === true) return false;\n if (nodeAt(callee, 'property')?.['name'] !== 'value') return false;\n const object = nodeAt(callee, 'object');\n if (object?.type === 'Identifier') return visible(object['name'], locals);\n if (object?.type !== 'MemberExpression' || object['computed'] === true) return false;\n const base = nodeAt(object, 'object');\n return (\n nodeAt(object, 'property')?.['name'] === 'prop' &&\n base?.type === 'Identifier' &&\n visible(base['name'], ns)\n );\n };\n\n const walk = (node: Node): void => {\n const declared = scopeNames(node)?.filter((name) => locals.has(name) || ns.has(name));\n if (declared !== undefined && declared.length > 0) scopes.push(new Set(declared));\n if (node.type === 'CallExpression' && isPropValue(nodeAt(node, 'callee'))) {\n const [check] = nodesAt(node, 'arguments');\n if (check !== undefined && droppable(check)) {\n // Keep the line count, so every following line keeps its number.\n const lines = code.slice(check.start, check.end).split('\\n').length - 1;\n edits.push({ start: check.start, end: check.end, text: `void 0${'\\n'.repeat(lines)}` });\n }\n }\n for (const child of children(node)) walk(child);\n if (declared !== undefined && declared.length > 0) scopes.pop();\n };\n for (const statement of nodesAt(program, 'body')) walk(statement);\n return edits;\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type Node } from './ast.js';
|
|
2
|
+
/** The template tags the compiler rewrites. */
|
|
3
|
+
export type Tag = 'html' | 'svg';
|
|
4
|
+
/**
|
|
5
|
+
* `import { html as local } from 'specifier'` (`tag` says which tag, html or svg), or
|
|
6
|
+
* `import * as local from 'specifier'` (no `tag`: `ns.html` and `ns.svg` both are).
|
|
7
|
+
*/
|
|
8
|
+
export interface HtmlImport {
|
|
9
|
+
readonly local: string;
|
|
10
|
+
readonly namespace: boolean;
|
|
11
|
+
readonly specifier: string;
|
|
12
|
+
readonly tag?: Tag;
|
|
13
|
+
}
|
|
14
|
+
export interface Imports {
|
|
15
|
+
readonly imports: readonly HtmlImport[];
|
|
16
|
+
/** `export { html } from 'specifier'` (its node, for a code frame). */
|
|
17
|
+
readonly reexports: readonly {
|
|
18
|
+
readonly node: Node;
|
|
19
|
+
readonly specifier: string;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
export interface Uses {
|
|
23
|
+
/** TaggedTemplateExpression nodes whose tag is a matching binding, and which tag it is. */
|
|
24
|
+
readonly sites: readonly {
|
|
25
|
+
readonly node: Node;
|
|
26
|
+
readonly binding: HtmlImport;
|
|
27
|
+
readonly tag: Tag;
|
|
28
|
+
}[];
|
|
29
|
+
/** Other references; `exported`: an `export { html }` specifier. */
|
|
30
|
+
readonly leftovers: readonly {
|
|
31
|
+
readonly node: Node;
|
|
32
|
+
readonly exported: boolean;
|
|
33
|
+
}[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Imports of `html` and `svg` (named) and namespace imports, plus `export { html } from`
|
|
37
|
+
* re-exports (of either tag).
|
|
38
|
+
*/
|
|
39
|
+
export declare function htmlImports(program: Node): Imports;
|
|
40
|
+
/** Every use of `bindings` in `program`, skipping names that a nested scope redeclares. */
|
|
41
|
+
export declare function findUses(program: Node, bindings: readonly HtmlImport[]): Uses;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// Finds a module's `html` and `svg` call sites for the template compiler (view/01-templates.md
|
|
2
|
+
// "Compiled"). Two steps, because matching an import against the configured sources may need
|
|
3
|
+
// module resolution (async, in the plugin): `htmlImports` lists the candidate imports, and
|
|
4
|
+
// `findUses` walks the module, scope-aware, for every reference to the matching bindings:
|
|
5
|
+
// - html`…` (or ns.html`…` for `import * as ns`) is a call site, and so is svg`…`;
|
|
6
|
+
// - any other reference (`const h = html`, `html(strings)`, `ns[x]`, `{ html } = ns`) is a
|
|
7
|
+
// leftover the compiler can't follow: an error, since it would reach the runtime preparer;
|
|
8
|
+
// - `export { html }` re-exports it: a warning here, an error in generateBundle when an
|
|
9
|
+
// uncompiled `html` survives in the bundle. Everything said of `html` holds for `svg`.
|
|
10
|
+
import { children, nodeAt, nodesAt, scopeNames } from './ast.js';
|
|
11
|
+
const TAGS = ['html', 'svg'];
|
|
12
|
+
const tagOf = (name) => name !== undefined && TAGS.includes(name) ? name : undefined;
|
|
13
|
+
const nameOf = (node) => node === undefined
|
|
14
|
+
? undefined
|
|
15
|
+
: node.type === 'Identifier'
|
|
16
|
+
? node['name']
|
|
17
|
+
: node.type === 'Literal' && typeof node['value'] === 'string'
|
|
18
|
+
? node['value']
|
|
19
|
+
: undefined;
|
|
20
|
+
const specifierOf = (node) => nameOf(nodeAt(node, 'source'));
|
|
21
|
+
const isValue = (node) => node['importKind'] !== 'type' && node['exportKind'] !== 'type';
|
|
22
|
+
/**
|
|
23
|
+
* Imports of `html` and `svg` (named) and namespace imports, plus `export { html } from`
|
|
24
|
+
* re-exports (of either tag).
|
|
25
|
+
*/
|
|
26
|
+
export function htmlImports(program) {
|
|
27
|
+
const imports = [];
|
|
28
|
+
const reexports = [];
|
|
29
|
+
for (const statement of nodesAt(program, 'body')) {
|
|
30
|
+
const specifier = specifierOf(statement);
|
|
31
|
+
if (specifier === undefined || !isValue(statement))
|
|
32
|
+
continue;
|
|
33
|
+
if (statement.type === 'ImportDeclaration') {
|
|
34
|
+
for (const s of nodesAt(statement, 'specifiers')) {
|
|
35
|
+
const local = nameOf(nodeAt(s, 'local'));
|
|
36
|
+
if (local === undefined || !isValue(s))
|
|
37
|
+
continue;
|
|
38
|
+
if (s.type === 'ImportNamespaceSpecifier') {
|
|
39
|
+
imports.push({ local, namespace: true, specifier });
|
|
40
|
+
}
|
|
41
|
+
else if (s.type === 'ImportSpecifier') {
|
|
42
|
+
const tag = tagOf(nameOf(nodeAt(s, 'imported')));
|
|
43
|
+
if (tag !== undefined)
|
|
44
|
+
imports.push({ local, namespace: false, specifier, tag });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (statement.type === 'ExportNamedDeclaration') {
|
|
49
|
+
const html = nodesAt(statement, 'specifiers').find((s) => isValue(s) && tagOf(nameOf(nodeAt(s, 'local'))) !== undefined);
|
|
50
|
+
if (html !== undefined)
|
|
51
|
+
reexports.push({ node: html, specifier });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { imports, reexports };
|
|
55
|
+
}
|
|
56
|
+
const unparen = (node) => node?.type === 'ParenthesizedExpression' ? unparen(nodeAt(node, 'expression')) : node;
|
|
57
|
+
/** Every use of `bindings` in `program`, skipping names that a nested scope redeclares. */
|
|
58
|
+
export function findUses(program, bindings) {
|
|
59
|
+
const byName = new Map(bindings.map((b) => [b.local, b]));
|
|
60
|
+
const sites = [];
|
|
61
|
+
const leftovers = [];
|
|
62
|
+
const scopes = [];
|
|
63
|
+
const binding = (node) => {
|
|
64
|
+
const name = node?.type === 'Identifier' ? node['name'] : undefined;
|
|
65
|
+
if (name === undefined || scopes.some((s) => s.has(name)))
|
|
66
|
+
return undefined;
|
|
67
|
+
return byName.get(name);
|
|
68
|
+
};
|
|
69
|
+
/** The binding a tag refers to, and which tag: `html` itself, or `ns.html` (or svg). */
|
|
70
|
+
const tagBinding = (tag) => {
|
|
71
|
+
if (tag?.type === 'Identifier') {
|
|
72
|
+
const b = binding(tag);
|
|
73
|
+
return b?.tag === undefined ? undefined : { binding: b, tag: b.tag };
|
|
74
|
+
}
|
|
75
|
+
if (tag?.type !== 'MemberExpression' || tag['computed'] === true)
|
|
76
|
+
return undefined;
|
|
77
|
+
const b = binding(nodeAt(tag, 'object'));
|
|
78
|
+
const name = tagOf(nameOf(nodeAt(tag, 'property')));
|
|
79
|
+
return b?.namespace === true && name !== undefined ? { binding: b, tag: name } : undefined;
|
|
80
|
+
};
|
|
81
|
+
const walkAll = (nodes) => {
|
|
82
|
+
for (const n of nodes)
|
|
83
|
+
walk(n);
|
|
84
|
+
};
|
|
85
|
+
function visit(node) {
|
|
86
|
+
switch (node.type) {
|
|
87
|
+
case 'ImportDeclaration':
|
|
88
|
+
case 'ExportAllDeclaration':
|
|
89
|
+
case 'MetaProperty':
|
|
90
|
+
case 'BreakStatement':
|
|
91
|
+
case 'ContinueStatement':
|
|
92
|
+
return;
|
|
93
|
+
case 'ExportNamedDeclaration':
|
|
94
|
+
if (nodeAt(node, 'source') === undefined) {
|
|
95
|
+
for (const s of nodesAt(node, 'specifiers')) {
|
|
96
|
+
if (binding(nodeAt(s, 'local')) !== undefined)
|
|
97
|
+
leftovers.push({ node: s, exported: true });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
walkAll(nodesAt(node, 'declaration'));
|
|
101
|
+
return;
|
|
102
|
+
case 'TaggedTemplateExpression': {
|
|
103
|
+
const tag = unparen(nodeAt(node, 'tag'));
|
|
104
|
+
const b = tagBinding(tag);
|
|
105
|
+
if (b === undefined)
|
|
106
|
+
break;
|
|
107
|
+
sites.push({ node, ...b });
|
|
108
|
+
walkAll(nodesAt(nodeAt(node, 'quasi') ?? node, 'expressions'));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
case 'MemberExpression': {
|
|
112
|
+
const object = nodeAt(node, 'object');
|
|
113
|
+
const b = binding(object);
|
|
114
|
+
const computed = node['computed'] === true;
|
|
115
|
+
if (b !== undefined) {
|
|
116
|
+
// ns.other is fine; ns.html (or ns.svg) outside a tag, or ns[expr], can't be followed.
|
|
117
|
+
if (!b.namespace || computed || tagOf(nameOf(nodeAt(node, 'property'))) !== undefined) {
|
|
118
|
+
leftovers.push({ node, exported: false });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else
|
|
122
|
+
walkAll(nodesAt(node, 'object'));
|
|
123
|
+
if (computed)
|
|
124
|
+
walkAll(nodesAt(node, 'property'));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
case 'Property':
|
|
128
|
+
case 'MethodDefinition':
|
|
129
|
+
case 'PropertyDefinition':
|
|
130
|
+
case 'AccessorProperty':
|
|
131
|
+
if (node['computed'] === true)
|
|
132
|
+
walkAll(nodesAt(node, 'key'));
|
|
133
|
+
walkAll(nodesAt(node, 'decorators'));
|
|
134
|
+
walkAll(nodesAt(node, 'value'));
|
|
135
|
+
return;
|
|
136
|
+
case 'LabeledStatement':
|
|
137
|
+
walkAll(nodesAt(node, 'body'));
|
|
138
|
+
return;
|
|
139
|
+
case 'Identifier':
|
|
140
|
+
if (binding(node) !== undefined)
|
|
141
|
+
leftovers.push({ node, exported: false });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
walkAll(children(node));
|
|
145
|
+
}
|
|
146
|
+
function walk(node) {
|
|
147
|
+
const declared = scopeNames(node)?.filter((name) => byName.has(name));
|
|
148
|
+
if (declared === undefined || declared.length === 0) {
|
|
149
|
+
visit(node);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
scopes.push(new Set(declared));
|
|
153
|
+
visit(node);
|
|
154
|
+
scopes.pop();
|
|
155
|
+
}
|
|
156
|
+
if (byName.size > 0)
|
|
157
|
+
walkAll(nodesAt(program, 'body'));
|
|
158
|
+
return { sites, leftovers };
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/compiler/scan.ts"],"names":[],"mappings":"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","sourcesContent":["// Finds a module's `html` and `svg` call sites for the template compiler (view/01-templates.md\n// \"Compiled\"). Two steps, because matching an import against the configured sources may need\n// module resolution (async, in the plugin): `htmlImports` lists the candidate imports, and\n// `findUses` walks the module, scope-aware, for every reference to the matching bindings:\n// - html`…` (or ns.html`…` for `import * as ns`) is a call site, and so is svg`…`;\n// - any other reference (`const h = html`, `html(strings)`, `ns[x]`, `{ html } = ns`) is a\n// leftover the compiler can't follow: an error, since it would reach the runtime preparer;\n// - `export { html }` re-exports it: a warning here, an error in generateBundle when an\n// uncompiled `html` survives in the bundle. Everything said of `html` holds for `svg`.\nimport { children, nodeAt, nodesAt, scopeNames, type Node } from './ast.js';\n\n/** The template tags the compiler rewrites. */\nexport type Tag = 'html' | 'svg';\nconst TAGS: readonly string[] = ['html', 'svg'];\nconst tagOf = (name: string | undefined): Tag | undefined =>\n name !== undefined && TAGS.includes(name) ? (name as Tag) : undefined;\n\n/**\n * `import { html as local } from 'specifier'` (`tag` says which tag, html or svg), or\n * `import * as local from 'specifier'` (no `tag`: `ns.html` and `ns.svg` both are).\n */\nexport interface HtmlImport {\n readonly local: string;\n readonly namespace: boolean;\n readonly specifier: string;\n readonly tag?: Tag;\n}\n\nexport interface Imports {\n readonly imports: readonly HtmlImport[];\n /** `export { html } from 'specifier'` (its node, for a code frame). */\n readonly reexports: readonly { readonly node: Node; readonly specifier: string }[];\n}\n\nexport interface Uses {\n /** TaggedTemplateExpression nodes whose tag is a matching binding, and which tag it is. */\n readonly sites: readonly {\n readonly node: Node;\n readonly binding: HtmlImport;\n readonly tag: Tag;\n }[];\n /** Other references; `exported`: an `export { html }` specifier. */\n readonly leftovers: readonly { readonly node: Node; readonly exported: boolean }[];\n}\n\nconst nameOf = (node: Node | undefined): string | undefined =>\n node === undefined\n ? undefined\n : node.type === 'Identifier'\n ? (node['name'] as string)\n : node.type === 'Literal' && typeof node['value'] === 'string'\n ? node['value']\n : undefined;\n\nconst specifierOf = (node: Node): string | undefined => nameOf(nodeAt(node, 'source'));\n\nconst isValue = (node: Node): boolean =>\n node['importKind'] !== 'type' && node['exportKind'] !== 'type';\n\n/**\n * Imports of `html` and `svg` (named) and namespace imports, plus `export { html } from`\n * re-exports (of either tag).\n */\nexport function htmlImports(program: Node): Imports {\n const imports: HtmlImport[] = [];\n const reexports: { node: Node; specifier: string }[] = [];\n for (const statement of nodesAt(program, 'body')) {\n const specifier = specifierOf(statement);\n if (specifier === undefined || !isValue(statement)) continue;\n if (statement.type === 'ImportDeclaration') {\n for (const s of nodesAt(statement, 'specifiers')) {\n const local = nameOf(nodeAt(s, 'local'));\n if (local === undefined || !isValue(s)) continue;\n if (s.type === 'ImportNamespaceSpecifier') {\n imports.push({ local, namespace: true, specifier });\n } else if (s.type === 'ImportSpecifier') {\n const tag = tagOf(nameOf(nodeAt(s, 'imported')));\n if (tag !== undefined) imports.push({ local, namespace: false, specifier, tag });\n }\n }\n } else if (statement.type === 'ExportNamedDeclaration') {\n const html = nodesAt(statement, 'specifiers').find(\n (s) => isValue(s) && tagOf(nameOf(nodeAt(s, 'local'))) !== undefined,\n );\n if (html !== undefined) reexports.push({ node: html, specifier });\n }\n }\n return { imports, reexports };\n}\n\nconst unparen = (node: Node | undefined): Node | undefined =>\n node?.type === 'ParenthesizedExpression' ? unparen(nodeAt(node, 'expression')) : node;\n\n/** Every use of `bindings` in `program`, skipping names that a nested scope redeclares. */\nexport function findUses(program: Node, bindings: readonly HtmlImport[]): Uses {\n const byName = new Map(bindings.map((b) => [b.local, b]));\n const sites: { node: Node; binding: HtmlImport; tag: Tag }[] = [];\n const leftovers: { node: Node; exported: boolean }[] = [];\n const scopes: Set<string>[] = [];\n\n const binding = (node: Node | undefined): HtmlImport | undefined => {\n const name = node?.type === 'Identifier' ? (node['name'] as string) : undefined;\n if (name === undefined || scopes.some((s) => s.has(name))) return undefined;\n return byName.get(name);\n };\n\n /** The binding a tag refers to, and which tag: `html` itself, or `ns.html` (or svg). */\n const tagBinding = (tag: Node | undefined): { binding: HtmlImport; tag: Tag } | undefined => {\n if (tag?.type === 'Identifier') {\n const b = binding(tag);\n return b?.tag === undefined ? undefined : { binding: b, tag: b.tag };\n }\n if (tag?.type !== 'MemberExpression' || tag['computed'] === true) return undefined;\n const b = binding(nodeAt(tag, 'object'));\n const name = tagOf(nameOf(nodeAt(tag, 'property')));\n return b?.namespace === true && name !== undefined ? { binding: b, tag: name } : undefined;\n };\n\n const walkAll = (nodes: readonly Node[]): void => {\n for (const n of nodes) walk(n);\n };\n\n function visit(node: Node): void {\n switch (node.type) {\n case 'ImportDeclaration':\n case 'ExportAllDeclaration':\n case 'MetaProperty':\n case 'BreakStatement':\n case 'ContinueStatement':\n return;\n case 'ExportNamedDeclaration':\n if (nodeAt(node, 'source') === undefined) {\n for (const s of nodesAt(node, 'specifiers')) {\n if (binding(nodeAt(s, 'local')) !== undefined)\n leftovers.push({ node: s, exported: true });\n }\n }\n walkAll(nodesAt(node, 'declaration'));\n return;\n case 'TaggedTemplateExpression': {\n const tag = unparen(nodeAt(node, 'tag'));\n const b = tagBinding(tag);\n if (b === undefined) break;\n sites.push({ node, ...b });\n walkAll(nodesAt(nodeAt(node, 'quasi') ?? node, 'expressions'));\n return;\n }\n case 'MemberExpression': {\n const object = nodeAt(node, 'object');\n const b = binding(object);\n const computed = node['computed'] === true;\n if (b !== undefined) {\n // ns.other is fine; ns.html (or ns.svg) outside a tag, or ns[expr], can't be followed.\n if (!b.namespace || computed || tagOf(nameOf(nodeAt(node, 'property'))) !== undefined) {\n leftovers.push({ node, exported: false });\n }\n } else walkAll(nodesAt(node, 'object'));\n if (computed) walkAll(nodesAt(node, 'property'));\n return;\n }\n case 'Property':\n case 'MethodDefinition':\n case 'PropertyDefinition':\n case 'AccessorProperty':\n if (node['computed'] === true) walkAll(nodesAt(node, 'key'));\n walkAll(nodesAt(node, 'decorators'));\n walkAll(nodesAt(node, 'value'));\n return;\n case 'LabeledStatement':\n walkAll(nodesAt(node, 'body'));\n return;\n case 'Identifier':\n if (binding(node) !== undefined) leftovers.push({ node, exported: false });\n return;\n }\n walkAll(children(node));\n }\n\n function walk(node: Node): void {\n const declared = scopeNames(node)?.filter((name) => byName.has(name));\n if (declared === undefined || declared.length === 0) {\n visit(node);\n return;\n }\n scopes.push(new Set(declared));\n visit(node);\n scopes.pop();\n }\n\n if (byName.size > 0) walkAll(nodesAt(program, 'body'));\n return { sites, leftovers };\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface Scope {
|
|
2
|
+
/** Whether module `id` can affect Gyral components, so the scan must read it. */
|
|
3
|
+
inScope(id: string): boolean;
|
|
4
|
+
/** The name of the package module `id` belongs to (`@gyral/core` is where `raw` comes from). */
|
|
5
|
+
packageOf(id: string): string | undefined;
|
|
6
|
+
}
|
|
7
|
+
/** A scope for one build: manifests and answers are cached per package directory. */
|
|
8
|
+
export declare function createScope(): Scope;
|