@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,34 @@
|
|
|
1
|
+
import { langOf } from './ast.js';
|
|
2
|
+
import { type Feature } from './facts.js';
|
|
3
|
+
export type { Feature } from './facts.js';
|
|
4
|
+
/**
|
|
5
|
+
* Text a module must contain to use a feature (the plugins' transform filters list the same).
|
|
6
|
+
* `invokers`: also any import or export, which may reach `raw`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const FEATURE_HINTS: Readonly<Record<Feature, RegExp>>;
|
|
9
|
+
/** A plugin context's `resolve`, as far as detection needs it. */
|
|
10
|
+
type Resolve = (source: string, importer: string) => Promise<{
|
|
11
|
+
readonly id: string;
|
|
12
|
+
} | null>;
|
|
13
|
+
/** What the scan needs from the transform hook's plugin context. */
|
|
14
|
+
export interface ScanContext {
|
|
15
|
+
/** `this.parse` (Rolldown's parser, TypeScript included). */
|
|
16
|
+
readonly parse: (code: string, lang: ReturnType<typeof langOf>) => unknown;
|
|
17
|
+
readonly resolve: Resolve;
|
|
18
|
+
}
|
|
19
|
+
export interface FeatureHooks {
|
|
20
|
+
/** Finds the core copy the app imports (its compiled entry), to register with and to skip. */
|
|
21
|
+
buildStart(resolve: Resolve, root: string): Promise<void>;
|
|
22
|
+
resolveId(source: string): {
|
|
23
|
+
id: string;
|
|
24
|
+
moduleSideEffects: true;
|
|
25
|
+
} | null;
|
|
26
|
+
load(id: string): string | null;
|
|
27
|
+
/** The imports to append to module `id` for the features its `code` may use; '' for none. */
|
|
28
|
+
inject(code: string, id: string, context: ScanContext): Promise<string>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Detection for `features`. `ownEntry`: the compiled entry of the core copy running the plugin,
|
|
32
|
+
* used when the app's root can't resolve `@gyral/core/compiled` (fixtures, unusual layouts).
|
|
33
|
+
*/
|
|
34
|
+
export declare function createFeatures(features: readonly Feature[], ownEntry: string): FeatureHooks;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Build-time feature detection (view/05-element.md "Features register themselves",
|
|
2
|
+
// gyral-c5d.11, gyral-c5d.12), loaded lazily by the plugin shells in ../vite.ts. Some optional
|
|
3
|
+
// machinery can't register itself from an API call, because apps reach it through plain data:
|
|
4
|
+
// spec fields (`viewTransition`, `renderOnFrame`, `states`, `subscriptions`) and markup (`data-intent-on`
|
|
5
|
+
// values, `raw()` content). In builds that leave that machinery out by default (the
|
|
6
|
+
// `gyral-compiled` condition, and `gyral-client-only` for the invoker fallback), the modules
|
|
7
|
+
// that can affect Gyral components are scanned, and a module that may use a feature gets one
|
|
8
|
+
// import added at its end: `virtual:gyral-use/<feature>`, a side-effect module that calls
|
|
9
|
+
// `register()` from core's `use-<feature>` module before any module that imports it runs. The
|
|
10
|
+
// registration modules are reached only this way, never from an entry, so a build that doesn't
|
|
11
|
+
// use a feature doesn't even load its code (Rolldown emits chunks for every import() it loads,
|
|
12
|
+
// tree-shaken or not).
|
|
13
|
+
//
|
|
14
|
+
// Which modules (scope.ts): the app's own source, and installed packages that are Gyral's or
|
|
15
|
+
// depend on one, directly or through their dependencies. What counts in them (facts.ts): names
|
|
16
|
+
// and strings in the module's AST, never comments, and `raw` only when it comes from
|
|
17
|
+
// `@gyral/core`. Both over-approximate, so the scan stays sound: a field or event can only be
|
|
18
|
+
// set by writing its name somewhere, in a module that can reach Gyral (a name built at run
|
|
19
|
+
// time, such as `{ ['sta' + 'tes']: … }`, or spec data written in a package that doesn't
|
|
20
|
+
// depend on Gyral, are the gaps; view/05 says what then degrades). A false positive only bundles a few hundred
|
|
21
|
+
// bytes that weren't needed. Core's own modules are skipped (they implement it); a module that
|
|
22
|
+
// doesn't parse is matched on its text, comments included.
|
|
23
|
+
import { join } from 'node:path';
|
|
24
|
+
import { langOf } from './ast.js';
|
|
25
|
+
import { factsOf, writes } from './facts.js';
|
|
26
|
+
import { createScope } from './scope.js';
|
|
27
|
+
/** The text fallback, for a module that doesn't parse: the 0.3.1-next.0 scan. */
|
|
28
|
+
const TEXT_USES = {
|
|
29
|
+
invokers: /data-intent-command\s*=|data-intent-on\s*=\s*\\?["']?(?:[\w-]+\s+)*(?:command\b|\$\{)|(["'`])command\1|\braw\b\s*(?:\(|as\b)/i,
|
|
30
|
+
transitions: /\bviewTransition\b/,
|
|
31
|
+
frame: /\brenderOnFrame\b/,
|
|
32
|
+
states: /\bstates\b/,
|
|
33
|
+
forms: /\bformAssociated\b/,
|
|
34
|
+
subscriptions: /\bsubscriptions\b/,
|
|
35
|
+
dialogs: /\?(?:modal|popover-open)\s*=/i,
|
|
36
|
+
disposal: /\bdispose\b/,
|
|
37
|
+
errorView: /\berror\b/,
|
|
38
|
+
errored: /\bErrored\b/,
|
|
39
|
+
};
|
|
40
|
+
/** Each feature's registration module in core (`src/<name>.ts`, published as `dist/<name>.js`). */
|
|
41
|
+
const REGISTRATION = {
|
|
42
|
+
invokers: 'use-invokers',
|
|
43
|
+
transitions: 'use-transitions',
|
|
44
|
+
frame: 'use-frame-lane',
|
|
45
|
+
states: 'use-states',
|
|
46
|
+
forms: 'use-form-associated',
|
|
47
|
+
subscriptions: 'use-subscriptions',
|
|
48
|
+
dialogs: 'use-dialogs',
|
|
49
|
+
disposal: 'use-disposal',
|
|
50
|
+
errorView: 'use-error-view',
|
|
51
|
+
errored: 'use-errored',
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Text a module must contain to use a feature (the plugins' transform filters list the same).
|
|
55
|
+
* `invokers`: also any import or export, which may reach `raw`.
|
|
56
|
+
*/
|
|
57
|
+
export const FEATURE_HINTS = {
|
|
58
|
+
invokers: /data-intent-on|command|raw|import|export/i,
|
|
59
|
+
transitions: /viewTransition/,
|
|
60
|
+
frame: /renderOnFrame/,
|
|
61
|
+
states: /states/,
|
|
62
|
+
forms: /formAssociated/,
|
|
63
|
+
subscriptions: /subscriptions/,
|
|
64
|
+
dialogs: /modal|popover-open/i,
|
|
65
|
+
disposal: /dispose/,
|
|
66
|
+
errorView: /error/,
|
|
67
|
+
errored: /Errored/,
|
|
68
|
+
};
|
|
69
|
+
const PREFIX = 'virtual:gyral-use/';
|
|
70
|
+
/** The package that exports `raw`. */
|
|
71
|
+
const CORE = '@gyral/core';
|
|
72
|
+
const RESOLVED = '\0gyral-use/';
|
|
73
|
+
const SCRIPT = /\.[cm]?[jt]sx?$/;
|
|
74
|
+
/** core's compiled entry, in its source tree or its published dist/: [, dir, extension]. */
|
|
75
|
+
const ENTRY_FILE = /[\\/](src|dist)[\\/]view[\\/]compiled\.(ts|js)$/;
|
|
76
|
+
const importsOf = (features) => features.map((feature) => `\nimport ${JSON.stringify(PREFIX + feature)};`).join('');
|
|
77
|
+
/**
|
|
78
|
+
* Detection for `features`. `ownEntry`: the compiled entry of the core copy running the plugin,
|
|
79
|
+
* used when the app's root can't resolve `@gyral/core/compiled` (fixtures, unusual layouts).
|
|
80
|
+
*/
|
|
81
|
+
export function createFeatures(features, ownEntry) {
|
|
82
|
+
let entry = ownEntry;
|
|
83
|
+
let scope = createScope();
|
|
84
|
+
const skipped = new Set([ownEntry.replace(ENTRY_FILE, '/')]);
|
|
85
|
+
/** A registration module next to the compiled entry's view/ directory. */
|
|
86
|
+
const moduleOf = (name) => entry.replace(ENTRY_FILE, (_, dir, ext) => `/${dir}/${name}.${ext}`);
|
|
87
|
+
const isCore = (id) => [...skipped].some((dir) => id.startsWith(dir));
|
|
88
|
+
/**
|
|
89
|
+
* Whether one of `specifiers`, imported by `importer`, is a module of core (where `raw` comes
|
|
90
|
+
* from): `@gyral/core` or one of its subpaths, or a specifier that resolves into core (an
|
|
91
|
+
* alias, a path). Another package that re-exports core's `raw` counts in its own module.
|
|
92
|
+
*/
|
|
93
|
+
async function coreAmong(specifiers, importer, resolve) {
|
|
94
|
+
for (const specifier of specifiers) {
|
|
95
|
+
if (specifier === CORE || specifier.startsWith(`${CORE}/`))
|
|
96
|
+
return true;
|
|
97
|
+
let resolved = null;
|
|
98
|
+
try {
|
|
99
|
+
resolved = await resolve(specifier, importer);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// unresolvable: the bundler reports it
|
|
103
|
+
}
|
|
104
|
+
const id = resolved?.id.replace(/\?.*$/, '');
|
|
105
|
+
if (id !== undefined && (isCore(id) || scope.packageOf(id) === CORE))
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
async buildStart(resolve, root) {
|
|
112
|
+
scope = createScope(); // manifests may have changed since the last build (watch mode)
|
|
113
|
+
const resolved = await resolve('@gyral/core/compiled', join(root, 'index.html'));
|
|
114
|
+
if (resolved === null || !ENTRY_FILE.test(resolved.id))
|
|
115
|
+
return;
|
|
116
|
+
entry = resolved.id;
|
|
117
|
+
skipped.add(entry.replace(ENTRY_FILE, '/'));
|
|
118
|
+
},
|
|
119
|
+
resolveId(source) {
|
|
120
|
+
if (!source.startsWith(PREFIX))
|
|
121
|
+
return null;
|
|
122
|
+
const feature = source.slice(PREFIX.length);
|
|
123
|
+
return features.includes(feature)
|
|
124
|
+
? { id: RESOLVED + feature, moduleSideEffects: true }
|
|
125
|
+
: null;
|
|
126
|
+
},
|
|
127
|
+
load(id) {
|
|
128
|
+
if (!id.startsWith(RESOLVED))
|
|
129
|
+
return null;
|
|
130
|
+
const file = moduleOf(REGISTRATION[id.slice(RESOLVED.length)]);
|
|
131
|
+
return `import { register } from ${JSON.stringify(file)};\nregister();\n`;
|
|
132
|
+
},
|
|
133
|
+
async inject(code, id, context) {
|
|
134
|
+
const file = id.replace(/\?.*$/, '');
|
|
135
|
+
if (id.startsWith('\0') || !SCRIPT.test(file) || isCore(file))
|
|
136
|
+
return '';
|
|
137
|
+
const hinted = features.filter((feature) => FEATURE_HINTS[feature].test(code));
|
|
138
|
+
if (hinted.length === 0 || !scope.inScope(file))
|
|
139
|
+
return '';
|
|
140
|
+
let program;
|
|
141
|
+
try {
|
|
142
|
+
program = context.parse(code, langOf(file));
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return importsOf(hinted.filter((feature) => TEXT_USES[feature].test(code)));
|
|
146
|
+
}
|
|
147
|
+
const facts = factsOf(program);
|
|
148
|
+
const used = [];
|
|
149
|
+
for (const feature of hinted) {
|
|
150
|
+
if (writes(facts, feature) ||
|
|
151
|
+
(feature === 'invokers' && (await coreAmong(facts.rawSources, id, context.resolve))))
|
|
152
|
+
used.push(feature);
|
|
153
|
+
}
|
|
154
|
+
return importsOf(used);
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=features.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/compiler/features.ts"],"names":[],"mappings":"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","sourcesContent":["// Build-time feature detection (view/05-element.md \"Features register themselves\",\n// gyral-c5d.11, gyral-c5d.12), loaded lazily by the plugin shells in ../vite.ts. Some optional\n// machinery can't register itself from an API call, because apps reach it through plain data:\n// spec fields (`viewTransition`, `renderOnFrame`, `states`, `subscriptions`) and markup (`data-intent-on`\n// values, `raw()` content). In builds that leave that machinery out by default (the\n// `gyral-compiled` condition, and `gyral-client-only` for the invoker fallback), the modules\n// that can affect Gyral components are scanned, and a module that may use a feature gets one\n// import added at its end: `virtual:gyral-use/<feature>`, a side-effect module that calls\n// `register()` from core's `use-<feature>` module before any module that imports it runs. The\n// registration modules are reached only this way, never from an entry, so a build that doesn't\n// use a feature doesn't even load its code (Rolldown emits chunks for every import() it loads,\n// tree-shaken or not).\n//\n// Which modules (scope.ts): the app's own source, and installed packages that are Gyral's or\n// depend on one, directly or through their dependencies. What counts in them (facts.ts): names\n// and strings in the module's AST, never comments, and `raw` only when it comes from\n// `@gyral/core`. Both over-approximate, so the scan stays sound: a field or event can only be\n// set by writing its name somewhere, in a module that can reach Gyral (a name built at run\n// time, such as `{ ['sta' + 'tes']: … }`, or spec data written in a package that doesn't\n// depend on Gyral, are the gaps; view/05 says what then degrades). A false positive only bundles a few hundred\n// bytes that weren't needed. Core's own modules are skipped (they implement it); a module that\n// doesn't parse is matched on its text, comments included.\nimport { join } from 'node:path';\nimport { langOf, type Node } from './ast.js';\nimport { factsOf, writes, type Feature } from './facts.js';\nimport { createScope, type Scope } from './scope.js';\n\nexport type { Feature } from './facts.js';\n\n/** The text fallback, for a module that doesn't parse: the 0.3.1-next.0 scan. */\nconst TEXT_USES: Readonly<Record<Feature, RegExp>> = {\n invokers:\n /data-intent-command\\s*=|data-intent-on\\s*=\\s*\\\\?[\"']?(?:[\\w-]+\\s+)*(?:command\\b|\\$\\{)|([\"'`])command\\1|\\braw\\b\\s*(?:\\(|as\\b)/i,\n transitions: /\\bviewTransition\\b/,\n frame: /\\brenderOnFrame\\b/,\n states: /\\bstates\\b/,\n forms: /\\bformAssociated\\b/,\n subscriptions: /\\bsubscriptions\\b/,\n dialogs: /\\?(?:modal|popover-open)\\s*=/i,\n disposal: /\\bdispose\\b/,\n errorView: /\\berror\\b/,\n errored: /\\bErrored\\b/,\n};\n\n/** Each feature's registration module in core (`src/<name>.ts`, published as `dist/<name>.js`). */\nconst REGISTRATION: Readonly<Record<Feature, string>> = {\n invokers: 'use-invokers',\n transitions: 'use-transitions',\n frame: 'use-frame-lane',\n states: 'use-states',\n forms: 'use-form-associated',\n subscriptions: 'use-subscriptions',\n dialogs: 'use-dialogs',\n disposal: 'use-disposal',\n errorView: 'use-error-view',\n errored: 'use-errored',\n};\n\n/**\n * Text a module must contain to use a feature (the plugins' transform filters list the same).\n * `invokers`: also any import or export, which may reach `raw`.\n */\nexport const FEATURE_HINTS: Readonly<Record<Feature, RegExp>> = {\n invokers: /data-intent-on|command|raw|import|export/i,\n transitions: /viewTransition/,\n frame: /renderOnFrame/,\n states: /states/,\n forms: /formAssociated/,\n subscriptions: /subscriptions/,\n dialogs: /modal|popover-open/i,\n disposal: /dispose/,\n errorView: /error/,\n errored: /Errored/,\n};\n\nconst PREFIX = 'virtual:gyral-use/';\n/** The package that exports `raw`. */\nconst CORE = '@gyral/core';\nconst RESOLVED = '\\0gyral-use/';\nconst SCRIPT = /\\.[cm]?[jt]sx?$/;\n/** core's compiled entry, in its source tree or its published dist/: [, dir, extension]. */\nconst ENTRY_FILE = /[\\\\/](src|dist)[\\\\/]view[\\\\/]compiled\\.(ts|js)$/;\n\n/** A plugin context's `resolve`, as far as detection needs it. */\ntype Resolve = (source: string, importer: string) => Promise<{ readonly id: string } | null>;\n\n/** What the scan needs from the transform hook's plugin context. */\nexport interface ScanContext {\n /** `this.parse` (Rolldown's parser, TypeScript included). */\n readonly parse: (code: string, lang: ReturnType<typeof langOf>) => unknown;\n readonly resolve: Resolve;\n}\n\nexport interface FeatureHooks {\n /** Finds the core copy the app imports (its compiled entry), to register with and to skip. */\n buildStart(resolve: Resolve, root: string): Promise<void>;\n resolveId(source: string): { id: string; moduleSideEffects: true } | null;\n load(id: string): string | null;\n /** The imports to append to module `id` for the features its `code` may use; '' for none. */\n inject(code: string, id: string, context: ScanContext): Promise<string>;\n}\n\nconst importsOf = (features: readonly Feature[]): string =>\n features.map((feature) => `\\nimport ${JSON.stringify(PREFIX + feature)};`).join('');\n\n/**\n * Detection for `features`. `ownEntry`: the compiled entry of the core copy running the plugin,\n * used when the app's root can't resolve `@gyral/core/compiled` (fixtures, unusual layouts).\n */\nexport function createFeatures(features: readonly Feature[], ownEntry: string): FeatureHooks {\n let entry = ownEntry;\n let scope: Scope = createScope();\n const skipped = new Set([ownEntry.replace(ENTRY_FILE, '/')]);\n /** A registration module next to the compiled entry's view/ directory. */\n const moduleOf = (name: string): string =>\n entry.replace(ENTRY_FILE, (_, dir: string, ext: string) => `/${dir}/${name}.${ext}`);\n const isCore = (id: string): boolean => [...skipped].some((dir) => id.startsWith(dir));\n\n /**\n * Whether one of `specifiers`, imported by `importer`, is a module of core (where `raw` comes\n * from): `@gyral/core` or one of its subpaths, or a specifier that resolves into core (an\n * alias, a path). Another package that re-exports core's `raw` counts in its own module.\n */\n async function coreAmong(\n specifiers: readonly string[],\n importer: string,\n resolve: Resolve,\n ): Promise<boolean> {\n for (const specifier of specifiers) {\n if (specifier === CORE || specifier.startsWith(`${CORE}/`)) return true;\n let resolved: { readonly id: string } | null = null;\n try {\n resolved = await resolve(specifier, importer);\n } catch {\n // unresolvable: the bundler reports it\n }\n const id = resolved?.id.replace(/\\?.*$/, '');\n if (id !== undefined && (isCore(id) || scope.packageOf(id) === CORE)) return true;\n }\n return false;\n }\n\n return {\n async buildStart(resolve, root) {\n scope = createScope(); // manifests may have changed since the last build (watch mode)\n const resolved = await resolve('@gyral/core/compiled', join(root, 'index.html'));\n if (resolved === null || !ENTRY_FILE.test(resolved.id)) return;\n entry = resolved.id;\n skipped.add(entry.replace(ENTRY_FILE, '/'));\n },\n resolveId(source) {\n if (!source.startsWith(PREFIX)) return null;\n const feature = source.slice(PREFIX.length) as Feature;\n return features.includes(feature)\n ? { id: RESOLVED + feature, moduleSideEffects: true }\n : null;\n },\n load(id) {\n if (!id.startsWith(RESOLVED)) return null;\n const file = moduleOf(REGISTRATION[id.slice(RESOLVED.length) as Feature]);\n return `import { register } from ${JSON.stringify(file)};\\nregister();\\n`;\n },\n async inject(code, id, context) {\n const file = id.replace(/\\?.*$/, '');\n if (id.startsWith('\\0') || !SCRIPT.test(file) || isCore(file)) return '';\n const hinted = features.filter((feature) => FEATURE_HINTS[feature].test(code));\n if (hinted.length === 0 || !scope.inScope(file)) return '';\n let program: Node;\n try {\n program = context.parse(code, langOf(file)) as Node;\n } catch {\n return importsOf(hinted.filter((feature) => TEXT_USES[feature].test(code)));\n }\n const facts = factsOf(program);\n const used: Feature[] = [];\n for (const feature of hinted) {\n if (\n writes(facts, feature) ||\n (feature === 'invokers' && (await coreAmong(facts.rawSources, id, context.resolve)))\n )\n used.push(feature);\n }\n return importsOf(used);\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
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 CompilerHooks {
|
|
7
|
+
readonly configResolved: HookFn<'configResolved'>;
|
|
8
|
+
readonly buildStart: HookFn<'buildStart'>;
|
|
9
|
+
readonly resolveId: HookFn<'resolveId'>;
|
|
10
|
+
readonly load: HookFn<'load'>;
|
|
11
|
+
readonly transform: HookFn<'transform'>;
|
|
12
|
+
readonly generateBundle: HookFn<'generateBundle'>;
|
|
13
|
+
}
|
|
14
|
+
export interface CompilerSettings {
|
|
15
|
+
readonly sources: readonly string[];
|
|
16
|
+
/** The module to load parse5 from; undefined skips the parse5 check. */
|
|
17
|
+
readonly parse5: string | undefined;
|
|
18
|
+
/** The compiled entry of the core copy running the plugin (features.ts). */
|
|
19
|
+
readonly ownEntry: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function createCompiler(settings: CompilerSettings): CompilerHooks;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// The template compiler's build hooks (view/01-templates.md "Compiled",
|
|
2
|
+
// view/09-template-rules.md), loaded lazily by the plugin shell in ../vite.ts on the first
|
|
3
|
+
// `vite build` hook, so the preset stays loadable from any vite.config.ts:
|
|
4
|
+
// - `transform` (the shell is enforce: 'pre', so positions are the author's own source,
|
|
5
|
+
// TypeScript included, parsed by Rolldown's `this.parse`): rewrites each `html` call site
|
|
6
|
+
// of the configured sources into `compiled(<hoisted template object>, [values…])` (and
|
|
7
|
+
// each `svg` one into `compiledSvg(…)`), dependencies in node_modules included. Template
|
|
8
|
+
// rule violations, and references it can't follow, fail the build with a code frame.
|
|
9
|
+
// - `generateBundle`: fails when an uncompiled `html` or `svg` survived in a chunk anyway
|
|
10
|
+
// (re-exports across modules, dynamic imports): the guarantee that the `#prepare` stub is
|
|
11
|
+
// never hit.
|
|
12
|
+
// - In client environments, `transform` also adds the registration of view transitions, the
|
|
13
|
+
// frame lane and custom states to every module that names their spec field, among the
|
|
14
|
+
// modules that can affect Gyral components (the app's own, and packages that reach a Gyral
|
|
15
|
+
// package), so the `gyral-compiled` condition can leave them out otherwise (features.ts,
|
|
16
|
+
// gyral-c5d.12); `resolveId` and `load` serve those registration modules.
|
|
17
|
+
import { join, relative } from 'node:path';
|
|
18
|
+
import { langOf } from './ast.js';
|
|
19
|
+
import { CompileError, compileModule } from './compile.js';
|
|
20
|
+
import { createFeatures } from './features.js';
|
|
21
|
+
import { stripPropSchemas } from './prop-schemas.js';
|
|
22
|
+
import { loadParse5 } from './parse5-check.js';
|
|
23
|
+
import { VIEW } from './locate.js';
|
|
24
|
+
import { findUses, htmlImports } from './scan.js';
|
|
25
|
+
import { Lines, splice } from './source.js';
|
|
26
|
+
/** Appends `imports` after the module's last line: no code moves, so source maps hold. */
|
|
27
|
+
const appended = (result, code, imports) => imports === ''
|
|
28
|
+
? result
|
|
29
|
+
: result === null
|
|
30
|
+
? { code: code + imports, map: null }
|
|
31
|
+
: { ...result, code: result.code + imports };
|
|
32
|
+
/** Modules naming a template tag, or calling `.value(`: only those can need compiling. */
|
|
33
|
+
const NAMES_TAG = /html|svg|\.value\s*\(/;
|
|
34
|
+
/** A `prop.value(…)` call may be in the module (prop-schemas.ts). */
|
|
35
|
+
const PROP_VALUE = /\.value\s*\(/;
|
|
36
|
+
/** template.ts's symbol description: the module defining `html` and `svg`, in any copy of core. */
|
|
37
|
+
const DEFINES_HTML = /Symbol\(['"]gyral\.template['"]\)/;
|
|
38
|
+
const SCRIPT = /\.[cm]?[jt]sx?$/;
|
|
39
|
+
/**
|
|
40
|
+
* Whether an environment resolves core's `#view-dev` to its development module: the
|
|
41
|
+
* `development` condition is listed, or Vite's `development|production` placeholder is and
|
|
42
|
+
* the build isn't a production one. Exactly then the client keeps template ids (01).
|
|
43
|
+
*/
|
|
44
|
+
function developmentBuild(config) {
|
|
45
|
+
const { conditions } = config.resolve;
|
|
46
|
+
return (conditions.includes('development') ||
|
|
47
|
+
(!config.isProduction && conditions.includes('development|production')));
|
|
48
|
+
}
|
|
49
|
+
const CANT_FOLLOW = `This use of html can't be compiled: the template compiler rewrites only html\`…\` tagged ` +
|
|
50
|
+
`templates whose tag is the imported html itself (or ns.html for import * as ns; the same ` +
|
|
51
|
+
`for svg). ` +
|
|
52
|
+
`Aliasing it, passing it around or calling it as a function would reach the runtime ` +
|
|
53
|
+
`template preparer, which builds made with the Gyral preset leave out. Write html\`…\` at ` +
|
|
54
|
+
`the call site (view/01-templates.md "Compiled").`;
|
|
55
|
+
export function createCompiler(settings) {
|
|
56
|
+
const { sources } = settings;
|
|
57
|
+
const features = createFeatures([
|
|
58
|
+
'transitions',
|
|
59
|
+
'frame',
|
|
60
|
+
'states',
|
|
61
|
+
'forms',
|
|
62
|
+
'subscriptions',
|
|
63
|
+
'dialogs',
|
|
64
|
+
'disposal',
|
|
65
|
+
'errorView',
|
|
66
|
+
'errored',
|
|
67
|
+
], settings.ownEntry);
|
|
68
|
+
/** Per environment (client, ssr, …): Vite may build them with one plugin instance. */
|
|
69
|
+
const states = new WeakMap();
|
|
70
|
+
const global = {};
|
|
71
|
+
let root = '';
|
|
72
|
+
let treeshake = true;
|
|
73
|
+
let info = () => undefined;
|
|
74
|
+
let parse5;
|
|
75
|
+
function stateOf(env) {
|
|
76
|
+
const key = env ?? global;
|
|
77
|
+
let state = states.get(key);
|
|
78
|
+
if (state === undefined) {
|
|
79
|
+
state = { sourceIds: new Set(VIEW), definers: new Set(), seen: new Map() };
|
|
80
|
+
states.set(key, state);
|
|
81
|
+
}
|
|
82
|
+
return state;
|
|
83
|
+
}
|
|
84
|
+
/** parse5, loaded once; the notice when it is missing is printed once too. */
|
|
85
|
+
function loadOnce() {
|
|
86
|
+
const specifier = settings.parse5;
|
|
87
|
+
if (specifier === undefined)
|
|
88
|
+
return undefined;
|
|
89
|
+
if (parse5 === undefined) {
|
|
90
|
+
parse5 = { module: loadParse5(specifier, root) };
|
|
91
|
+
if (parse5.module === undefined) {
|
|
92
|
+
info(`gyral: ${specifier} is not installed, so the template compiler skips its extra ` +
|
|
93
|
+
`rule 7 check (the normalizer's own check still runs). To get it: pnpm add -D ` +
|
|
94
|
+
`parse5 (view/09-template-rules.md).`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return parse5.module;
|
|
98
|
+
}
|
|
99
|
+
/** Compiles the module's template call sites (the transform proper). */
|
|
100
|
+
async function compile(code, id, opts) {
|
|
101
|
+
if (id.startsWith('\0') || !SCRIPT.test(id))
|
|
102
|
+
return null;
|
|
103
|
+
const env = this.environment;
|
|
104
|
+
const state = stateOf(env);
|
|
105
|
+
if (DEFINES_HTML.test(code))
|
|
106
|
+
state.definers.add(id);
|
|
107
|
+
if (state.sourceIds.has(id))
|
|
108
|
+
return null;
|
|
109
|
+
let program;
|
|
110
|
+
try {
|
|
111
|
+
program = this.parse(code, { lang: langOf(id) });
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null; // not ours to report: the bundler fails on it with a better message
|
|
115
|
+
}
|
|
116
|
+
const lines = new Lines(code);
|
|
117
|
+
const file = relative(root, id);
|
|
118
|
+
// Production client builds: property-only prop checks can't run (prop-schemas.ts).
|
|
119
|
+
const client = opts?.ssr !== true && env.config.consumer === 'client';
|
|
120
|
+
const extra = client && !developmentBuild(env.config) && PROP_VALUE.test(code)
|
|
121
|
+
? stripPropSchemas(program, code)
|
|
122
|
+
: [];
|
|
123
|
+
const unchanged = () => (extra.length === 0 ? null : splice(lines, extra, id));
|
|
124
|
+
const { imports, reexports } = htmlImports(program);
|
|
125
|
+
if (imports.length === 0 && reexports.length === 0)
|
|
126
|
+
return unchanged();
|
|
127
|
+
const isSource = async (specifier) => {
|
|
128
|
+
if (sources.includes(specifier))
|
|
129
|
+
return true;
|
|
130
|
+
const resolved = await this.resolve(specifier, id);
|
|
131
|
+
return resolved !== null && state.sourceIds.has(resolved.id);
|
|
132
|
+
};
|
|
133
|
+
const where = (node) => `${file}:${String(lines.position(node.start).line)}`;
|
|
134
|
+
for (const r of reexports) {
|
|
135
|
+
if (!(await isSource(r.specifier)))
|
|
136
|
+
continue;
|
|
137
|
+
this.warn(`${where(r.node)}: re-exporting html or svg. The template compiler only follows the ` +
|
|
138
|
+
`tags imported straight from ${r.specifier}: templates written with this re-export ` +
|
|
139
|
+
`stay uncompiled and fail the build. Import them from ${r.specifier} instead.`);
|
|
140
|
+
}
|
|
141
|
+
const matched = [];
|
|
142
|
+
for (const binding of imports)
|
|
143
|
+
if (await isSource(binding.specifier))
|
|
144
|
+
matched.push(binding);
|
|
145
|
+
if (matched.length === 0)
|
|
146
|
+
return unchanged();
|
|
147
|
+
const fail = (start, end, message) => this.error({
|
|
148
|
+
message,
|
|
149
|
+
id,
|
|
150
|
+
loc: { file: id, ...lines.position(start) },
|
|
151
|
+
frame: lines.frame(start, end),
|
|
152
|
+
});
|
|
153
|
+
const { sites, leftovers } = findUses(program, matched);
|
|
154
|
+
for (const l of leftovers) {
|
|
155
|
+
if (l.exported)
|
|
156
|
+
this.warn(`${where(l.node)}: re-exporting a template tag; its users stay uncompiled.`);
|
|
157
|
+
else
|
|
158
|
+
fail(l.node.start, l.node.end, CANT_FOLLOW);
|
|
159
|
+
}
|
|
160
|
+
if (sites.length === 0)
|
|
161
|
+
return unchanged();
|
|
162
|
+
const ssr = opts?.ssr === true || env.config.consumer === 'server';
|
|
163
|
+
try {
|
|
164
|
+
return compileModule({
|
|
165
|
+
lines,
|
|
166
|
+
id,
|
|
167
|
+
file,
|
|
168
|
+
sites,
|
|
169
|
+
ssr,
|
|
170
|
+
ids: ssr || developmentBuild(env.config),
|
|
171
|
+
parse5: loadOnce(),
|
|
172
|
+
extra,
|
|
173
|
+
seen: state.seen,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
if (error instanceof CompileError)
|
|
178
|
+
return fail(error.start, error.end, error.message);
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
configResolved(config) {
|
|
184
|
+
root = config.root;
|
|
185
|
+
treeshake = config.build.rolldownOptions.treeshake !== false;
|
|
186
|
+
info = (message) => {
|
|
187
|
+
config.logger.info(message);
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
async buildStart() {
|
|
191
|
+
states.delete(this.environment);
|
|
192
|
+
const state = stateOf(this.environment);
|
|
193
|
+
for (const source of sources) {
|
|
194
|
+
const resolved = await this.resolve(source, join(root, 'index.html'));
|
|
195
|
+
if (resolved !== null)
|
|
196
|
+
state.sourceIds.add(resolved.id);
|
|
197
|
+
}
|
|
198
|
+
await features.buildStart((source, importer) => this.resolve(source, importer), root);
|
|
199
|
+
loadOnce();
|
|
200
|
+
},
|
|
201
|
+
resolveId(source) {
|
|
202
|
+
return features.resolveId(source);
|
|
203
|
+
},
|
|
204
|
+
load(id) {
|
|
205
|
+
return features.load(id);
|
|
206
|
+
},
|
|
207
|
+
async transform(code, id, opts) {
|
|
208
|
+
const client = opts?.ssr !== true && this.environment.config.consumer === 'client';
|
|
209
|
+
const imports = client
|
|
210
|
+
? await features.inject(code, id, {
|
|
211
|
+
parse: (text, lang) => this.parse(text, { lang }),
|
|
212
|
+
resolve: (source, importer) => this.resolve(source, importer),
|
|
213
|
+
})
|
|
214
|
+
: '';
|
|
215
|
+
const compiled = NAMES_TAG.test(code) ? await compile.call(this, code, id, opts) : null;
|
|
216
|
+
return appended(compiled, code, imports);
|
|
217
|
+
},
|
|
218
|
+
generateBundle(_, bundle) {
|
|
219
|
+
const state = stateOf(this.environment);
|
|
220
|
+
// Without tree-shaking every export is rendered, used or not.
|
|
221
|
+
if (state.definers.size === 0 || !treeshake)
|
|
222
|
+
return;
|
|
223
|
+
for (const chunk of Object.values(bundle)) {
|
|
224
|
+
if (chunk.type !== 'chunk')
|
|
225
|
+
continue;
|
|
226
|
+
for (const [id, module] of Object.entries(chunk.modules)) {
|
|
227
|
+
const tag = ['html', 'svg'].find((name) => module.renderedExports.includes(name));
|
|
228
|
+
if (!state.definers.has(id) || tag === undefined)
|
|
229
|
+
continue;
|
|
230
|
+
this.error(`gyral: an uncompiled ${tag} template remains in ${chunk.fileName}: something uses ` +
|
|
231
|
+
`${tag} from ${relative(root, id)} in a way the template compiler can't see (a ` +
|
|
232
|
+
`re-export, a dynamic import, or a module it doesn't process). With the ` +
|
|
233
|
+
`gyral-compiled condition the runtime preparer is left out, so that template ` +
|
|
234
|
+
`would throw. Import ${tag} straight from '@gyral/core' where you write templates ` +
|
|
235
|
+
`(view/01-templates.md "Compiled").`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/compiler/hooks.ts"],"names":[],"mappings":"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","sourcesContent":["// The template compiler's build hooks (view/01-templates.md \"Compiled\",\n// view/09-template-rules.md), loaded lazily by the plugin shell in ../vite.ts on the first\n// `vite build` hook, so the preset stays loadable from any vite.config.ts:\n// - `transform` (the shell is enforce: 'pre', so positions are the author's own source,\n// TypeScript included, parsed by Rolldown's `this.parse`): rewrites each `html` call site\n// of the configured sources into `compiled(<hoisted template object>, [values…])` (and\n// each `svg` one into `compiledSvg(…)`), dependencies in node_modules included. Template\n// rule violations, and references it can't follow, fail the build with a code frame.\n// - `generateBundle`: fails when an uncompiled `html` or `svg` survived in a chunk anyway\n// (re-exports across modules, dynamic imports): the guarantee that the `#prepare` stub is\n// never hit.\n// - In client environments, `transform` also adds the registration of view transitions, the\n// frame lane and custom states to every module that names their spec field, among the\n// modules that can affect Gyral components (the app's own, and packages that reach a Gyral\n// package), so the `gyral-compiled` condition can leave them out otherwise (features.ts,\n// gyral-c5d.12); `resolveId` and `load` serve those registration modules.\nimport { join, relative } from 'node:path';\nimport type { Plugin } from 'vite';\nimport { langOf, type Node } from './ast.js';\nimport { CompileError, compileModule } from './compile.js';\nimport { createFeatures } from './features.js';\nimport { stripPropSchemas } from './prop-schemas.js';\nimport { loadParse5, type Parse5 } from './parse5-check.js';\nimport { VIEW } from './locate.js';\nimport { findUses, htmlImports } from './scan.js';\nimport { Lines, splice, type SourceMap } 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 CompilerHooks {\n readonly configResolved: HookFn<'configResolved'>;\n readonly buildStart: HookFn<'buildStart'>;\n readonly resolveId: HookFn<'resolveId'>;\n readonly load: HookFn<'load'>;\n readonly transform: HookFn<'transform'>;\n readonly generateBundle: HookFn<'generateBundle'>;\n}\n\nexport interface CompilerSettings {\n readonly sources: readonly string[];\n /** The module to load parse5 from; undefined skips the parse5 check. */\n readonly parse5: string | undefined;\n /** The compiled entry of the core copy running the plugin (features.ts). */\n readonly ownEntry: string;\n}\n\ntype TransformContext = ThisParameterType<HookFn<'transform'>>;\ntype TransformOptions = Parameters<HookFn<'transform'>>[2];\n/** What `compile` returns: the rewritten module, or null when nothing changed. */\ntype Transformed = { readonly code: string; readonly map: SourceMap | null } | null;\n\n/** Appends `imports` after the module's last line: no code moves, so source maps hold. */\nconst appended = (result: Transformed, code: string, imports: string): Transformed =>\n imports === ''\n ? result\n : result === null\n ? { code: code + imports, map: null }\n : { ...result, code: result.code + imports };\n\n/** Modules naming a template tag, or calling `.value(`: only those can need compiling. */\nconst NAMES_TAG = /html|svg|\\.value\\s*\\(/;\n/** A `prop.value(…)` call may be in the module (prop-schemas.ts). */\nconst PROP_VALUE = /\\.value\\s*\\(/;\n\n/** template.ts's symbol description: the module defining `html` and `svg`, in any copy of core. */\nconst DEFINES_HTML = /Symbol\\(['\"]gyral\\.template['\"]\\)/;\nconst SCRIPT = /\\.[cm]?[jt]sx?$/;\n\ninterface BuildState {\n readonly sourceIds: Set<string>;\n readonly definers: Set<string>;\n readonly seen: Map<string, { readonly strings: string; readonly loc: string }>;\n}\n\n/**\n * Whether an environment resolves core's `#view-dev` to its development module: the\n * `development` condition is listed, or Vite's `development|production` placeholder is and\n * the build isn't a production one. Exactly then the client keeps template ids (01).\n */\nfunction developmentBuild(config: {\n readonly isProduction: boolean;\n readonly resolve: { readonly conditions: readonly string[] };\n}): boolean {\n const { conditions } = config.resolve;\n return (\n conditions.includes('development') ||\n (!config.isProduction && conditions.includes('development|production'))\n );\n}\n\nconst CANT_FOLLOW =\n `This use of html can't be compiled: the template compiler rewrites only html\\`…\\` tagged ` +\n `templates whose tag is the imported html itself (or ns.html for import * as ns; the same ` +\n `for svg). ` +\n `Aliasing it, passing it around or calling it as a function would reach the runtime ` +\n `template preparer, which builds made with the Gyral preset leave out. Write html\\`…\\` at ` +\n `the call site (view/01-templates.md \"Compiled\").`;\n\nexport function createCompiler(settings: CompilerSettings): CompilerHooks {\n const { sources } = settings;\n const features = createFeatures(\n [\n 'transitions',\n 'frame',\n 'states',\n 'forms',\n 'subscriptions',\n 'dialogs',\n 'disposal',\n 'errorView',\n 'errored',\n ],\n settings.ownEntry,\n );\n /** Per environment (client, ssr, …): Vite may build them with one plugin instance. */\n const states = new WeakMap<object, BuildState>();\n const global = {};\n let root = '';\n let treeshake = true;\n let info: (message: string) => void = () => undefined;\n let parse5: { readonly module: Parse5 | undefined } | undefined;\n\n function stateOf(env: object | undefined): BuildState {\n const key = env ?? global;\n let state = states.get(key);\n if (state === undefined) {\n state = { sourceIds: new Set(VIEW), definers: new Set(), seen: new Map() };\n states.set(key, state);\n }\n return state;\n }\n\n /** parse5, loaded once; the notice when it is missing is printed once too. */\n function loadOnce(): Parse5 | undefined {\n const specifier = settings.parse5;\n if (specifier === undefined) return undefined;\n if (parse5 === undefined) {\n parse5 = { module: loadParse5(specifier, root) };\n if (parse5.module === undefined) {\n info(\n `gyral: ${specifier} is not installed, so the template compiler skips its extra ` +\n `rule 7 check (the normalizer's own check still runs). To get it: pnpm add -D ` +\n `parse5 (view/09-template-rules.md).`,\n );\n }\n }\n return parse5.module;\n }\n\n /** Compiles the module's template call sites (the transform proper). */\n async function compile(\n this: TransformContext,\n code: string,\n id: string,\n opts: TransformOptions,\n ): Promise<Transformed> {\n if (id.startsWith('\\0') || !SCRIPT.test(id)) return null;\n const env = this.environment;\n const state = stateOf(env);\n if (DEFINES_HTML.test(code)) state.definers.add(id);\n if (state.sourceIds.has(id)) 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: the bundler fails on it with a better message\n }\n const lines = new Lines(code);\n const file = relative(root, id);\n // Production client builds: property-only prop checks can't run (prop-schemas.ts).\n const client = opts?.ssr !== true && env.config.consumer === 'client';\n const extra =\n client && !developmentBuild(env.config) && PROP_VALUE.test(code)\n ? stripPropSchemas(program, code)\n : [];\n const unchanged = (): Transformed => (extra.length === 0 ? null : splice(lines, extra, id));\n const { imports, reexports } = htmlImports(program);\n if (imports.length === 0 && reexports.length === 0) return unchanged();\n const isSource = async (specifier: string): Promise<boolean> => {\n if (sources.includes(specifier)) return true;\n const resolved = await this.resolve(specifier, id);\n return resolved !== null && state.sourceIds.has(resolved.id);\n };\n const where = (node: Node): string => `${file}:${String(lines.position(node.start).line)}`;\n for (const r of reexports) {\n if (!(await isSource(r.specifier))) continue;\n this.warn(\n `${where(r.node)}: re-exporting html or svg. The template compiler only follows the ` +\n `tags imported straight from ${r.specifier}: templates written with this re-export ` +\n `stay uncompiled and fail the build. Import them from ${r.specifier} instead.`,\n );\n }\n const matched = [];\n for (const binding of imports) if (await isSource(binding.specifier)) matched.push(binding);\n if (matched.length === 0) return unchanged();\n const fail = (start: number, end: number, message: string): never =>\n this.error({\n message,\n id,\n loc: { file: id, ...lines.position(start) },\n frame: lines.frame(start, end),\n });\n const { sites, leftovers } = findUses(program, matched);\n for (const l of leftovers) {\n if (l.exported)\n this.warn(`${where(l.node)}: re-exporting a template tag; its users stay uncompiled.`);\n else fail(l.node.start, l.node.end, CANT_FOLLOW);\n }\n if (sites.length === 0) return unchanged();\n const ssr = opts?.ssr === true || env.config.consumer === 'server';\n try {\n return compileModule({\n lines,\n id,\n file,\n sites,\n ssr,\n ids: ssr || developmentBuild(env.config),\n parse5: loadOnce(),\n extra,\n seen: state.seen,\n });\n } catch (error) {\n if (error instanceof CompileError) return fail(error.start, error.end, error.message);\n throw error;\n }\n }\n\n return {\n configResolved(config) {\n root = config.root;\n treeshake = config.build.rolldownOptions.treeshake !== false;\n info = (message) => {\n config.logger.info(message);\n };\n },\n\n async buildStart() {\n states.delete(this.environment);\n const state = stateOf(this.environment);\n for (const source of sources) {\n const resolved = await this.resolve(source, join(root, 'index.html'));\n if (resolved !== null) state.sourceIds.add(resolved.id);\n }\n await features.buildStart((source, importer) => this.resolve(source, importer), root);\n loadOnce();\n },\n\n resolveId(source) {\n return features.resolveId(source);\n },\n\n load(id) {\n return features.load(id);\n },\n\n async transform(code, id, opts) {\n const client = opts?.ssr !== true && this.environment.config.consumer === 'client';\n const imports = client\n ? await features.inject(code, id, {\n parse: (text, lang) => this.parse(text, { lang }),\n resolve: (source, importer) => this.resolve(source, importer),\n })\n : '';\n const compiled = NAMES_TAG.test(code) ? await compile.call(this, code, id, opts) : null;\n return appended(compiled, code, imports);\n },\n\n generateBundle(_, bundle) {\n const state = stateOf(this.environment);\n // Without tree-shaking every export is rendered, used or not.\n if (state.definers.size === 0 || !treeshake) return;\n for (const chunk of Object.values(bundle)) {\n if (chunk.type !== 'chunk') continue;\n for (const [id, module] of Object.entries(chunk.modules)) {\n const tag = ['html', 'svg'].find((name) => module.renderedExports.includes(name));\n if (!state.definers.has(id) || tag === undefined) continue;\n this.error(\n `gyral: an uncompiled ${tag} template remains in ${chunk.fileName}: something uses ` +\n `${tag} from ${relative(root, id)} in a way the template compiler can't see (a ` +\n `re-export, a dynamic import, or a module it doesn't process). With the ` +\n `gyral-compiled condition the runtime preparer is left out, so that template ` +\n `would throw. Import ${tag} straight from '@gyral/core' where you write templates ` +\n `(view/01-templates.md \"Compiled\").`,\n );\n }\n }\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** How a production build writes the loader (./components.ts). */
|
|
2
|
+
export interface LoaderOptions {
|
|
3
|
+
/** Tags the app's entry defines: wait for registration and watch their shadow roots. */
|
|
4
|
+
readonly known?: readonly string[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The loader: imports a tag's module the first time that tag is rendered, in the document or in
|
|
8
|
+
* the shadow root of a component it defined (now, or after a mutation, checked once per
|
|
9
|
+
* microtask), then forgets it. It registers itself on `globalThis[Symbol.for('gyral.components')]`
|
|
10
|
+
* so `componentsReady()` (core) can wait until every rendered tag it knows is defined.
|
|
11
|
+
* Shadow roots are observed by the one shared MutationObserver; a removed host's root is
|
|
12
|
+
* dropped from the scan and its registration is collected with it.
|
|
13
|
+
*/
|
|
14
|
+
export declare function loaderSource(tags: ReadonlyMap<string, string>, options?: LoaderOptions): string;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// The component loader's source (./components.ts): a module that imports a tag's module the
|
|
2
|
+
// first time that tag is in the document. No Node imports, so tests can run it in a browser.
|
|
3
|
+
/**
|
|
4
|
+
* The loader: imports a tag's module the first time that tag is rendered, in the document or in
|
|
5
|
+
* the shadow root of a component it defined (now, or after a mutation, checked once per
|
|
6
|
+
* microtask), then forgets it. It registers itself on `globalThis[Symbol.for('gyral.components')]`
|
|
7
|
+
* so `componentsReady()` (core) can wait until every rendered tag it knows is defined.
|
|
8
|
+
* Shadow roots are observed by the one shared MutationObserver; a removed host's root is
|
|
9
|
+
* dropped from the scan and its registration is collected with it.
|
|
10
|
+
*/
|
|
11
|
+
export function loaderSource(tags, options = {}) {
|
|
12
|
+
const entries = [
|
|
13
|
+
...[...tags].map(([tag, url]) => ` [${JSON.stringify(tag)}, () => import(${JSON.stringify(url)})],`),
|
|
14
|
+
...(options.known ?? [])
|
|
15
|
+
.filter((tag) => !tags.has(tag))
|
|
16
|
+
.map((tag) => ` [${JSON.stringify(tag)}, () => Promise.resolve()],`),
|
|
17
|
+
].join('\n');
|
|
18
|
+
const watched = [...new Set([...tags.keys(), ...(options.known ?? [])])].join(',');
|
|
19
|
+
return `// Generated by gyralVitePreset({ components: true }).
|
|
20
|
+
const pending = new Map([
|
|
21
|
+
${entries}
|
|
22
|
+
]);
|
|
23
|
+
const known = ${JSON.stringify(watched)};
|
|
24
|
+
const roots = new Set();
|
|
25
|
+
const inflight = new Set();
|
|
26
|
+
let queued = false;
|
|
27
|
+
const observer = new MutationObserver(() => {
|
|
28
|
+
if (!queued) {
|
|
29
|
+
queued = true;
|
|
30
|
+
queueMicrotask(scan);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
function watch(root) {
|
|
34
|
+
for (const host of root.querySelectorAll(known)) {
|
|
35
|
+
const shadow = host.shadowRoot;
|
|
36
|
+
if (shadow !== null && !roots.has(shadow)) {
|
|
37
|
+
roots.add(shadow);
|
|
38
|
+
observer.observe(shadow, { childList: true, subtree: true });
|
|
39
|
+
watch(shadow);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function scan() {
|
|
44
|
+
queued = false;
|
|
45
|
+
for (const root of roots) if (!root.host.isConnected) roots.delete(root);
|
|
46
|
+
if (known !== '') {
|
|
47
|
+
watch(document);
|
|
48
|
+
for (const root of [...roots]) watch(root);
|
|
49
|
+
}
|
|
50
|
+
for (const [tag, load] of pending) {
|
|
51
|
+
if (customElements.get(tag) !== undefined) {
|
|
52
|
+
pending.delete(tag);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
let found = document.querySelector(tag) !== null;
|
|
56
|
+
for (const root of roots) if (!found && root.querySelector(tag) !== null) found = true;
|
|
57
|
+
if (!found) continue;
|
|
58
|
+
pending.delete(tag);
|
|
59
|
+
const done = load()
|
|
60
|
+
.then(() => customElements.whenDefined(tag))
|
|
61
|
+
.then(() => {
|
|
62
|
+
// The upgraded host renders into its shadow root next: look there too.
|
|
63
|
+
if (!queued) {
|
|
64
|
+
queued = true;
|
|
65
|
+
queueMicrotask(scan);
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.finally(() => inflight.delete(done));
|
|
69
|
+
inflight.add(done);
|
|
70
|
+
}
|
|
71
|
+
if (pending.size === 0) observer.disconnect();
|
|
72
|
+
}
|
|
73
|
+
async function ready() {
|
|
74
|
+
for (;;) {
|
|
75
|
+
scan();
|
|
76
|
+
if (inflight.size === 0) return;
|
|
77
|
+
await Promise.allSettled([...inflight]);
|
|
78
|
+
await new Promise((resolve) => setTimeout(resolve));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
globalThis[Symbol.for('gyral.components')] = { ready };
|
|
82
|
+
observer.observe(document.documentElement, { childList: true, subtree: true });
|
|
83
|
+
scan();
|
|
84
|
+
`;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=loader-source.js.map
|