@gyral/core 0.3.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 +42 -0
- package/NOTICE +19 -0
- package/README.md +30 -5
- 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 +25 -3
- package/dist/children.js +18 -1
- 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 +25 -11
- package/dist/command.js.map +1 -1
- package/dist/compiler/ast.d.ts +2 -0
- package/dist/compiler/ast.js +5 -1
- package/dist/compiler/ast.js.map +1 -1
- package/dist/compiler/compile.d.ts +5 -2
- package/dist/compiler/compile.js +36 -17
- package/dist/compiler/compile.js.map +1 -1
- 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 +4 -0
- package/dist/compiler/hooks.js +144 -89
- package/dist/compiler/hooks.js.map +1 -1
- 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 +1 -1
- package/dist/compiler/parse5-check.js +8 -3
- package/dist/compiler/parse5-check.js.map +1 -1
- 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 +13 -3
- package/dist/compiler/scan.js +21 -13
- package/dist/compiler/scan.js.map +1 -1
- 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/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 +8 -12
- package/dist/define.js.map +1 -1
- package/dist/devtools-events.d.ts +8 -0
- package/dist/devtools-events.js.map +1 -1
- package/dist/devtools-off.d.ts +1 -0
- package/dist/devtools-off.js +1 -0
- package/dist/devtools-off.js.map +1 -1
- package/dist/devtools.d.ts +3 -0
- package/dist/devtools.js +14 -0
- package/dist/devtools.js.map +1 -1
- 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 +6 -2
- package/dist/element-types.js.map +1 -1
- package/dist/element.js +80 -27
- package/dist/element.js.map +1 -1
- 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 +2 -0
- package/dist/eslint/imports.js +2 -2
- package/dist/eslint/imports.js.map +1 -1
- package/dist/eslint/index.d.ts +2 -1
- package/dist/eslint/index.js +11 -3
- package/dist/eslint/index.js.map +1 -1
- package/dist/eslint/template-rule.d.ts +1 -0
- package/dist/eslint/template-rule.js +15 -5
- package/dist/eslint/template-rule.js.map +1 -1
- 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 +2 -2
- package/dist/features.js.map +1 -1
- package/dist/focus.d.ts +6 -0
- package/dist/focus.js +32 -2
- 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/host-model.d.ts +34 -5
- package/dist/host-model.js +146 -23
- package/dist/host-model.js.map +1 -1
- package/dist/hydration-client.js +2 -2
- package/dist/hydration-client.js.map +1 -1
- 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 +0 -12
- package/dist/hydration.js +3 -52
- package/dist/hydration.js.map +1 -1
- package/dist/index.d.ts +20 -24
- package/dist/index.js +10 -19
- 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 +41 -19
- package/dist/intent.js +144 -106
- 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 +12 -4
- package/dist/internal/interpreter.js +36 -48
- 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/light-dom.d.ts +1 -1
- package/dist/light-dom.js.map +1 -1
- package/dist/prop.d.ts +30 -7
- package/dist/prop.js +19 -0
- package/dist/prop.js.map +1 -1
- package/dist/props.d.ts +8 -3
- package/dist/props.js +22 -15
- 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 +7 -3
- package/dist/scheduler.js +38 -56
- package/dist/scheduler.js.map +1 -1
- 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 +1 -1
- package/dist/server-component.js +45 -14
- package/dist/server-component.js.map +1 -1
- package/dist/server.d.ts +8 -2
- package/dist/server.js +11 -2
- package/dist/server.js.map +1 -1
- package/dist/settled.d.ts +4 -3
- package/dist/settled.js +48 -26
- package/dist/settled.js.map +1 -1
- 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 -8
- 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.js +2 -2
- package/dist/store-binding.js.map +1 -1
- package/dist/store-scope.d.ts +2 -4
- package/dist/store-scope.js +6 -16
- package/dist/store-scope.js.map +1 -1
- package/dist/store.js +36 -8
- package/dist/store.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 +4 -5
- package/dist/transitions.js +10 -4
- package/dist/transitions.js.map +1 -1
- package/dist/types.d.ts +124 -27
- 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 +5 -0
- package/dist/view/attributes.js +5 -0
- package/dist/view/attributes.js.map +1 -1
- package/dist/view/compiled.d.ts +1 -1
- package/dist/view/compiled.js +1 -1
- package/dist/view/compiled.js.map +1 -1
- package/dist/view/index.d.ts +9 -4
- package/dist/view/index.js +9 -3
- package/dist/view/index.js.map +1 -1
- 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 +5 -2
- package/dist/view/normalize/check.js +6 -3
- package/dist/view/normalize/check.js.map +1 -1
- package/dist/view/normalize/emit.d.ts +2 -0
- package/dist/view/normalize/emit.js +40 -11
- package/dist/view/normalize/emit.js.map +1 -1
- package/dist/view/normalize/errors.js +1 -1
- package/dist/view/normalize/errors.js.map +1 -1
- package/dist/view/normalize/id.d.ts +5 -2
- package/dist/view/normalize/id.js +9 -2
- package/dist/view/normalize/id.js.map +1 -1
- package/dist/view/normalize/normalize.d.ts +7 -4
- package/dist/view/normalize/normalize.js +15 -9
- package/dist/view/normalize/normalize.js.map +1 -1
- package/dist/view/normalize/rules.d.ts +9 -0
- package/dist/view/normalize/rules.js +35 -5
- package/dist/view/normalize/rules.js.map +1 -1
- 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/tokens.d.ts +5 -1
- package/dist/view/normalize/tokens.js.map +1 -1
- package/dist/view/normalize/tree.d.ts +8 -2
- package/dist/view/normalize/tree.js +58 -13
- package/dist/view/normalize/tree.js.map +1 -1
- package/dist/view/normalize/types.d.ts +24 -4
- package/dist/view/normalize/types.js +4 -1
- package/dist/view/normalize/types.js.map +1 -1
- package/dist/view/normalize/whitespace.js +4 -3
- package/dist/view/normalize/whitespace.js.map +1 -1
- package/dist/view/prepare-stub.js +2 -2
- package/dist/view/prepare-stub.js.map +1 -1
- package/dist/view/prepare.d.ts +5 -2
- package/dist/view/prepare.js +9 -3
- package/dist/view/prepare.js.map +1 -1
- package/dist/view/registry.d.ts +15 -0
- package/dist/view/registry.js +10 -2
- package/dist/view/registry.js.map +1 -1
- package/dist/view/render/adopt-attr.js +7 -1
- package/dist/view/render/adopt-attr.js.map +1 -1
- package/dist/view/render/adopt.js +21 -4
- package/dist/view/render/adopt.js.map +1 -1
- package/dist/view/render/attr-parts.d.ts +12 -1
- package/dist/view/render/attr-parts.js +38 -5
- package/dist/view/render/attr-parts.js.map +1 -1
- package/dist/view/render/child-part.js +5 -2
- package/dist/view/render/child-part.js.map +1 -1
- 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 +3 -1
- package/dist/view/render/hook-part.js +21 -5
- package/dist/view/render/hook-part.js.map +1 -1
- 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 +73 -5
- package/dist/view/render/hooks.js +79 -17
- package/dist/view/render/hooks.js.map +1 -1
- package/dist/view/render/hydrate.js +2 -2
- package/dist/view/render/hydrate.js.map +1 -1
- 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/mismatch.js +5 -3
- package/dist/view/render/mismatch.js.map +1 -1
- 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/raw.d.ts +4 -1
- package/dist/view/render/raw.js +6 -2
- package/dist/view/render/raw.js.map +1 -1
- package/dist/view/render/render.d.ts +4 -1
- package/dist/view/render/render.js +17 -12
- package/dist/view/render/render.js.map +1 -1
- 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/warn.d.ts +14 -0
- package/dist/view/render/warn.js +45 -0
- package/dist/view/render/warn.js.map +1 -1
- package/dist/view/server/component.d.ts +6 -3
- package/dist/view/server/component.js +29 -7
- package/dist/view/server/component.js.map +1 -1
- package/dist/view/server/index.d.ts +20 -0
- package/dist/view/server/index.js +12 -4
- package/dist/view/server/index.js.map +1 -1
- package/dist/view/server/tags.d.ts +13 -2
- package/dist/view/server/tags.js +13 -2
- package/dist/view/server/tags.js.map +1 -1
- package/dist/view/server/values.d.ts +2 -0
- package/dist/view/server/values.js +8 -0
- package/dist/view/server/values.js.map +1 -1
- package/dist/view/server/writer.d.ts +9 -4
- package/dist/view/server/writer.js +33 -18
- package/dist/view/server/writer.js.map +1 -1
- package/dist/view/template-element.d.ts +7 -0
- package/dist/view/template-element.js +25 -5
- package/dist/view/template-element.js.map +1 -1
- package/dist/view/template.d.ts +10 -2
- package/dist/view/template.js +62 -8
- package/dist/view/template.js.map +1 -1
- 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 +38 -31
- package/dist/vite.js +198 -31
- package/dist/vite.js.map +1 -1
- package/package.json +34 -3
- package/dist/hooks/labelled-by.d.ts +0 -13
- package/dist/hooks/labelled-by.js +0 -51
- package/dist/hooks/labelled-by.js.map +0 -1
- package/dist/random.d.ts +0 -13
- package/dist/random.js +0 -19
- package/dist/random.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw.js","sourceRoot":"","sources":["../../../src/view/render/raw.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,8FAA8F;AAC9F,+EAA+E;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,GAAG,EAAkB,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,MAAM,EAAkB,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,8EAA8E;AAC9E,MAAM,OAAO,QAAQ;IACnB,YACW,KAAc,EAChB,GAAS,EACT,IAAY;QAFV,UAAK,GAAL,KAAK,CAAS;QAChB,QAAG,GAAH,GAAG,CAAM;QACT,SAAI,GAAJ,IAAI,CAAQ;IAClB,CAAC;IAEJ,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAED,MAAM;QACJ,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;CACF;AAED,IAAI,MAAuC,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"raw.js","sourceRoot":"","sources":["../../../src/view/render/raw.ts"],"names":[],"mappings":"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","sourcesContent":["// `raw(html)` (view/02-bindings.md \"`raw(html)`\"): trusted markup parsed in a child hole, kept\n// as a node range after a start anchor and re-parsed only when the string changes. Its result\n// carries `commitRaw`, so apps that never call `raw` don't bundle this module.\nimport { DEV } from '#view-dev';\nimport { EMPTY, RAW, type ChildPart } from './child-part.js';\nimport { removeRange } from './nodes.js';\nimport { trustedHTML } from '../trusted-html.js';\nimport { report } from './seen.js';\nimport { MARKUP, type RawResult } from './values.js';\nimport { warnRaw } from './warn.js';\n\n/** Parsed `raw()` markup: the start anchor, the last node, and the string. */\nexport class RawRange {\n constructor(\n readonly start: Comment,\n public end: Node,\n public html: string,\n ) {}\n\n first(): Node {\n return this.start;\n }\n\n last(): Node {\n return this.end;\n }\n\n remove(): void {\n removeRange(this.start, this.end);\n }\n}\n\nlet parser: HTMLTemplateElement | undefined;\n\n/**\n * `html` parsed by a <template> through the `gyral` Trusted Types policy (its content is reused:\n * read it before the next call).\n */\nexport function parse(html: string): DocumentFragment {\n parser ??= document.createElement('template');\n parser.innerHTML = trustedHTML(html);\n return parser.content;\n}\n\n/** Commits `raw()` markup into `part`. */\nfunction commitRaw(part: ChildPart, html: string): void {\n if (DEV) warnRaw();\n report({ html });\n if (part.kind === RAW) {\n const range = part.content as RawRange;\n if (range.html === html) return;\n if (range.end !== range.start) removeRange(range.start.nextSibling as Node, range.end);\n const frag = parse(html);\n range.end = frag.lastChild ?? range.start;\n range.html = html;\n range.start.after(frag);\n return;\n }\n if (part.kind !== EMPTY) part.clear();\n const start = document.createComment('');\n const frag = parse(html);\n const end = frag.lastChild ?? start;\n frag.prepend(start);\n part.parent().insertBefore(frag, part.end());\n part.kind = RAW;\n part.content = new RawRange(start, end, html);\n}\n\n/**\n * Trusted markup from your own code (Markdown output, JSON-LD), parsed in a child hole and\n * re-parsed only when the string changes. Never pass user input.\n */\nexport function raw(html: string): RawResult {\n return { [MARKUP]: commitRaw, html };\n}\n"]}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { ChildPart } from './child-part.js';
|
|
2
2
|
import { type SeenMarkup } from './seen.js';
|
|
3
3
|
import type { ChildValue } from './values.js';
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Runs `fn` (one scheduler flush) with one shared row-check budget for every render in it, and
|
|
6
|
+
* element hooks deferred to `flushHooks` (after each pass) and the end of the flush.
|
|
7
|
+
*/
|
|
5
8
|
export declare function renderBatch(fn: () => void): void;
|
|
6
9
|
/**
|
|
7
10
|
* Renders `value` into `root`, updating what an earlier call rendered there. `seen` is told
|
|
@@ -1,30 +1,35 @@
|
|
|
1
1
|
// `render(value, root)`: the client renderer's entry point (view/02-bindings.md "Commit order").
|
|
2
2
|
// The root's child part is cached per root, so later calls update in place. Synchronous: when
|
|
3
|
-
// it returns, the DOM is committed and every element hook's `client` call has
|
|
4
|
-
// scheduler (view/04-scheduler.md) calls it once per dirty host, inside `renderBatch`,
|
|
5
|
-
// list dev check's budget (03) is per flush
|
|
3
|
+
// it returns, the DOM is committed, and outside a flush every element hook's `client` call has
|
|
4
|
+
// run. The scheduler (view/04-scheduler.md) calls it once per dirty host, inside `renderBatch`,
|
|
5
|
+
// so the list dev check's budget (03) is per flush and hooks run once every host has rendered,
|
|
6
|
+
// children first (hooks.ts); a call outside a batch gets a budget and a hook run of its own.
|
|
6
7
|
// `hydrate(value, root)` (hydrate.ts) makes the same root part from server DOM instead (07).
|
|
7
8
|
import { DEV } from '#view-dev';
|
|
8
9
|
import { ChildPart } from './child-part.js';
|
|
9
10
|
import { resetRowChecks } from './dev-check.js';
|
|
10
|
-
import { dropHooks, hookMark, runHooks } from './hooks.js';
|
|
11
|
+
import { dropHooks, endHooks, hookMark, runHooks, startHooks } from './hooks.js';
|
|
11
12
|
import { listenFor } from './seen.js';
|
|
12
13
|
const roots = new WeakMap();
|
|
13
14
|
let batching = false;
|
|
14
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Runs `fn` (one scheduler flush) with one shared row-check budget for every render in it, and
|
|
17
|
+
* element hooks deferred to `flushHooks` (after each pass) and the end of the flush.
|
|
18
|
+
*/
|
|
15
19
|
export function renderBatch(fn) {
|
|
16
|
-
if (
|
|
17
|
-
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
resetRowChecks();
|
|
20
|
+
if (DEV)
|
|
21
|
+
resetRowChecks(); // the budget is a development check
|
|
21
22
|
const outer = batching;
|
|
23
|
+
startHooks(); // element hooks wait for the flush (hook-run.ts)
|
|
24
|
+
let ok = false;
|
|
22
25
|
batching = true;
|
|
23
26
|
try {
|
|
24
27
|
fn();
|
|
28
|
+
ok = true;
|
|
25
29
|
}
|
|
26
30
|
finally {
|
|
27
31
|
batching = outer;
|
|
32
|
+
endHooks(ok);
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
@@ -37,7 +42,7 @@ export function render(value, root, seen) {
|
|
|
37
42
|
part = new ChildPart(root, null, null, 0, false, 0);
|
|
38
43
|
roots.set(root, part);
|
|
39
44
|
}
|
|
40
|
-
const mark = hookMark();
|
|
45
|
+
const mark = hookMark(root);
|
|
41
46
|
if (DEV && !batching)
|
|
42
47
|
resetRowChecks();
|
|
43
48
|
const outer = listenFor(seen);
|
|
@@ -51,7 +56,7 @@ export function render(value, root, seen) {
|
|
|
51
56
|
finally {
|
|
52
57
|
listenFor(outer);
|
|
53
58
|
}
|
|
54
|
-
runHooks(mark);
|
|
59
|
+
runHooks(mark, root);
|
|
55
60
|
}
|
|
56
61
|
/** Hydration (hydrate.ts): `part`, built over server DOM, is `root`'s part from now on. */
|
|
57
62
|
export function setRootPart(root, part) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/view/render/render.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,8FAA8F;AAC9F
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/view/render/render.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,8FAA8F;AAC9F,+FAA+F;AAC/F,gGAAgG;AAChG,+FAA+F;AAC/F,6FAA6F;AAC7F,6FAA6F;AAC7F,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,SAAS,EAAmB,MAAM,WAAW,CAAC;AAGvD,MAAM,KAAK,GAAG,IAAI,OAAO,EAAmB,CAAC;AAC7C,IAAI,QAAQ,GAAG,KAAK,CAAC;AAErB;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,EAAc;IACxC,IAAI,GAAG;QAAE,cAAc,EAAE,CAAC,CAAC,oCAAoC;IAC/D,MAAM,KAAK,GAAG,QAAQ,CAAC;IACvB,UAAU,EAAE,CAAC,CAAC,iDAAiD;IAC/D,IAAI,EAAE,GAAG,KAAK,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAChB,IAAI,CAAC;QACH,EAAE,EAAE,CAAC;QACL,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,QAAQ,GAAG,KAAK,CAAC;QACjB,QAAQ,CAAC,EAAE,CAAC,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CACpB,KAAiB,EACjB,IAA6C,EAC7C,IAAiB;IAEjB,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,IAAI,GAAG,IAAI,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACpD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,GAAG,IAAI,CAAC,QAAQ;QAAE,cAAc,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,WAAW,CAAC,IAAU,EAAE,IAAe;IACrD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACxB,CAAC","sourcesContent":["// `render(value, root)`: the client renderer's entry point (view/02-bindings.md \"Commit order\").\n// The root's child part is cached per root, so later calls update in place. Synchronous: when\n// it returns, the DOM is committed, and outside a flush every element hook's `client` call has\n// run. The scheduler (view/04-scheduler.md) calls it once per dirty host, inside `renderBatch`,\n// so the list dev check's budget (03) is per flush and hooks run once every host has rendered,\n// children first (hooks.ts); a call outside a batch gets a budget and a hook run of its own.\n// `hydrate(value, root)` (hydrate.ts) makes the same root part from server DOM instead (07).\nimport { DEV } from '#view-dev';\nimport { ChildPart } from './child-part.js';\nimport { resetRowChecks } from './dev-check.js';\nimport { dropHooks, endHooks, hookMark, runHooks, startHooks } from './hooks.js';\nimport { listenFor, type SeenMarkup } from './seen.js';\nimport type { ChildValue } from './values.js';\n\nconst roots = new WeakMap<Node, ChildPart>();\nlet batching = false;\n\n/**\n * Runs `fn` (one scheduler flush) with one shared row-check budget for every render in it, and\n * element hooks deferred to `flushHooks` (after each pass) and the end of the flush.\n */\nexport function renderBatch(fn: () => void): void {\n if (DEV) resetRowChecks(); // the budget is a development check\n const outer = batching;\n startHooks(); // element hooks wait for the flush (hook-run.ts)\n let ok = false;\n batching = true;\n try {\n fn();\n ok = true;\n } finally {\n batching = outer;\n endHooks(ok);\n }\n}\n\n/**\n * Renders `value` into `root`, updating what an earlier call rendered there. `seen` is told\n * about each template the render instantiates (seen.ts).\n */\nexport function render(\n value: ChildValue,\n root: Element | ShadowRoot | DocumentFragment,\n seen?: SeenMarkup,\n): void {\n let part = roots.get(root);\n if (part === undefined) {\n part = new ChildPart(root, null, null, 0, false, 0);\n roots.set(root, part);\n }\n const mark = hookMark(root);\n if (DEV && !batching) resetRowChecks();\n const outer = listenFor(seen);\n try {\n part.commit(value);\n } catch (error) {\n dropHooks(mark);\n throw error;\n } finally {\n listenFor(outer);\n }\n runHooks(mark, root);\n}\n\n/** Hydration (hydrate.ts): `part`, built over server DOM, is `root`'s part from now on. */\nexport function setRootPart(root: Node, part: ChildPart): void {\n roots.set(root, part);\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HookPart } from './hooks.js';
|
|
2
|
+
/** Queues a native action after this part's DOM is committed and inserted. */
|
|
3
|
+
export type Toggle = (part: HookPart, name: string, on: boolean) => void;
|
|
4
|
+
export declare let toggle: Toggle | undefined;
|
|
5
|
+
/** Internal: turns the bindings on (modal.ts's `applyToggle`). */
|
|
6
|
+
export declare function useToggles(run: Toggle): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggles.js","sourceRoot":"","sources":["../../../src/view/render/toggles.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,IAAI,MAA0B,CAAC;AAEtC,kEAAkE;AAClE,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,GAAG,GAAG,CAAC;AACf,CAAC","sourcesContent":["// Dialogs and popovers from state (view/02-bindings.md \"Dialogs and popovers\", gyral-1zd.27):\n// `?modal=${open}` on a `<dialog>` and `?popover-open=${open}` on a `[popover]` element open and\n// close them with the platform's methods. The code that does it (modal.ts) registers here, so\n// only builds that use the bindings bundle it: core's `#spec-features` registers it at load\n// without a build step, and compiled builds register it when a module writes either binding.\nimport type { HookPart } from './hooks.js';\n\n/** Queues a native action after this part's DOM is committed and inserted. */\nexport type Toggle = (part: HookPart, name: string, on: boolean) => void;\n\nexport let toggle: Toggle | undefined;\n\n/** Internal: turns the bindings on (modal.ts's `applyToggle`). */\nexport function useToggles(run: Toggle): void {\n toggle = run;\n}\n"]}
|
|
@@ -4,6 +4,12 @@ export declare function badChild(value: unknown): never;
|
|
|
4
4
|
export declare function warnTrue(part: object): void;
|
|
5
5
|
/** An attribute or text-content hole got an object or function, once per part. */
|
|
6
6
|
export declare function warnValue(part: object, value: unknown, where: string): void;
|
|
7
|
+
/**
|
|
8
|
+
* A property binding got a function, once per part (02 "Properties"): views attach no
|
|
9
|
+
* closures. Built-in elements and Gyral components warn; other custom elements may take a
|
|
10
|
+
* callback (a third-party widget's API), so they don't.
|
|
11
|
+
*/
|
|
12
|
+
export declare function warnFunctionProp(part: object, el: Element, name: string): void;
|
|
7
13
|
/** `raw()` parsed in the browser, once per page. */
|
|
8
14
|
export declare function warnRaw(): void;
|
|
9
15
|
/** Keys must be unique strings or numbers: an error in development. */
|
|
@@ -11,4 +17,12 @@ export declare function badKey(key: unknown, index: number, duplicate: boolean):
|
|
|
11
17
|
/** A skipped row would render differently: it reads something besides `item` and `pick`. */
|
|
12
18
|
export declare function warnImpureRow(row: (...args: never[]) => unknown): void;
|
|
13
19
|
/** A hook hole got something other than a hook result. */
|
|
20
|
+
/** `?modal`/`?popover-open` with the bindings' code left out of the build (toggles.ts). */
|
|
21
|
+
export declare function warnToggle(el: Element, name: string): void;
|
|
14
22
|
export declare function badHook(value: unknown): never;
|
|
23
|
+
/**
|
|
24
|
+
* An svg template renders only in SVG content: an SVG element other than <foreignObject>,
|
|
25
|
+
* <desc> or <title>, whose content is HTML (01 "svg templates"). A detached fragment (an
|
|
26
|
+
* instance being built) isn't checked: its place is known only when it is inserted.
|
|
27
|
+
*/
|
|
28
|
+
export declare function checkSvgParent(parent: Node): void;
|
package/dist/view/render/warn.js
CHANGED
|
@@ -35,6 +35,24 @@ export function warnValue(part, value, where) {
|
|
|
35
35
|
`number or boolean, or null/undefined/nothing to leave it out ` +
|
|
36
36
|
`(${SPEC}/02-bindings.md "Attribute values").`);
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* A property binding got a function, once per part (02 "Properties"): views attach no
|
|
40
|
+
* closures. Built-in elements and Gyral components warn; other custom elements may take a
|
|
41
|
+
* callback (a third-party widget's API), so they don't.
|
|
42
|
+
*/
|
|
43
|
+
export function warnFunctionProp(part, el, name) {
|
|
44
|
+
const gyral = el.constructor.spec !== undefined;
|
|
45
|
+
if (warned.has(part) || (el.localName.includes('-') && !gyral))
|
|
46
|
+
return;
|
|
47
|
+
warned.add(part);
|
|
48
|
+
console.warn(`gyral: .${name}=\${…} on <${el.localName}> got a function. Views attach no closures: ` +
|
|
49
|
+
(gyral
|
|
50
|
+
? 'props are data (they travel in hydration seeds); pass data and let the component ' +
|
|
51
|
+
'decide what to do with it, and hear back from it through its outputs'
|
|
52
|
+
: 'name an intent with data-intent=${i.Name} for events, and put behaviour on an ' +
|
|
53
|
+
'element in a hook (defineHook)') +
|
|
54
|
+
` (${SPEC}/02-bindings.md "Properties").`);
|
|
55
|
+
}
|
|
38
56
|
let rawWarned = false;
|
|
39
57
|
/** `raw()` parsed in the browser, once per page. */
|
|
40
58
|
export function warnRaw() {
|
|
@@ -61,9 +79,36 @@ export function warnImpureRow(row) {
|
|
|
61
79
|
`the second argument (${SPEC}/03-lists.md "Rows must be pure").`);
|
|
62
80
|
}
|
|
63
81
|
/** A hook hole got something other than a hook result. */
|
|
82
|
+
/** `?modal`/`?popover-open` with the bindings' code left out of the build (toggles.ts). */
|
|
83
|
+
export function warnToggle(el, name) {
|
|
84
|
+
if (warned.has(el))
|
|
85
|
+
return;
|
|
86
|
+
warned.add(el);
|
|
87
|
+
console.warn(`gyral: ?${name} on <${el.localName}> does nothing: the build left its code out ` +
|
|
88
|
+
`(${SPEC}/05-element.md "Features register themselves").`);
|
|
89
|
+
}
|
|
64
90
|
export function badHook(value) {
|
|
65
91
|
throw new TypeError(`gyral: an element hook position (\${…} inside a start tag) got ${describe(value)}. Only ` +
|
|
66
92
|
`hooks made with defineHook() go there, e.g. <input \${invalid(errors)}> ` +
|
|
67
93
|
`(${SPEC}/02-bindings.md "Element hooks").`);
|
|
68
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* An svg template renders only in SVG content: an SVG element other than <foreignObject>,
|
|
97
|
+
* <desc> or <title>, whose content is HTML (01 "svg templates"). A detached fragment (an
|
|
98
|
+
* instance being built) isn't checked: its place is known only when it is inserted.
|
|
99
|
+
*/
|
|
100
|
+
export function checkSvgParent(parent) {
|
|
101
|
+
if (parent.nodeType === 11 && !('host' in parent))
|
|
102
|
+
return;
|
|
103
|
+
const el = parent;
|
|
104
|
+
if (el.namespaceURI === 'http://www.w3.org/2000/svg' &&
|
|
105
|
+
!/^(foreignObject|desc|title)$/.test(el.localName)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const where = el.nodeType === 1 ? `<${el.localName}>` : 'a shadow root';
|
|
109
|
+
throw new Error(`gyral: an svg template is rendered into ${where}, which isn't SVG content. svg\`…\` ` +
|
|
110
|
+
'fragments are SVG elements: render them inside an <svg> (or another SVG element, not ' +
|
|
111
|
+
'<foreignObject>) of an html template, html`<svg viewBox="…">${svg`…`}</svg>`, or write ' +
|
|
112
|
+
`the whole graphic with html (${SPEC}/01-templates.md "svg templates").`);
|
|
113
|
+
}
|
|
69
114
|
//# sourceMappingURL=warn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"warn.js","sourceRoot":"","sources":["../../../src/view/render/warn.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,gGAAgG;AAChG,0FAA0F;AAE1F,MAAM,IAAI,GAAG,uBAAuB,CAAC;AACrC,MAAM,MAAM,GAAG,IAAI,OAAO,EAAU,CAAC;AAErC,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAU,EAAE,CAC1C,OAAO,KAAK,KAAK,UAAU;IACzB,CAAC,CAAC,YAAY;IACd,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,CAAC,cAAc,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG;YACrE,CAAC,CAAC,KAAK,OAAO,KAAK,EAAE,CAAC;AAE9B,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,MAAM,IAAI,SAAS,CACjB,2BAA2B,QAAQ,CAAC,KAAK,CAAC,4CAA4C;QACpF,qFAAqF;QACrF,8EAA8E;QAC9E,IAAI,IAAI,kCAAkC,CAC7C,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO;IAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CACV,wFAAwF;QACtF,iEAAiE;QACjE,IAAI,IAAI,kCAAkC,CAC7C,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAc,EAAE,KAAa;IACnE,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO;IAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CACV,UAAU,KAAK,QAAQ,QAAQ,CAAC,KAAK,CAAC,mDAAmD;QACvF,+DAA+D;QAC/D,IAAI,IAAI,sCAAsC,CACjD,CAAC;AACJ,CAAC;AAED,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,oDAAoD;AACpD,MAAM,UAAU,OAAO;IACrB,IAAI,SAAS;QAAE,OAAO;IACtB,SAAS,GAAG,IAAI,CAAC;IACjB,OAAO,CAAC,IAAI,CACV,yFAAyF;QACvF,uFAAuF;QACvF,IAAI,IAAI,oCAAoC,CAC/C,CAAC;AACJ,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,MAAM,CAAC,GAAY,EAAE,KAAa,EAAE,SAAkB;IACpE,MAAM,OAAO,GAAG,SAAS;QACvB,CAAC,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kCAAkC,MAAM,CAAC,KAAK,CAAC,GAAG;QAClF,CAAC,CAAC,oBAAoB,MAAM,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5D,MAAM,IAAI,KAAK,CACb,kBAAkB,OAAO,+DAA+D;QACtF,kDAAkD,IAAI,uBAAuB,CAChF,CAAC;AACJ,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,aAAa,CAAC,GAAkC;IAC9D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,GAAG,CAAC,IAAI,EAAE,CAAC;IACjF,OAAO,CAAC,IAAI,CACV,kBAAkB,IAAI,oEAAoE;QACxF,yFAAyF;QACzF,wBAAwB,IAAI,oCAAoC,CACnE,CAAC;AACJ,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,MAAM,IAAI,SAAS,CACjB,kEAAkE,QAAQ,CAAC,KAAK,CAAC,SAAS;QACxF,0EAA0E;QAC1E,IAAI,IAAI,mCAAmC,CAC9C,CAAC;AACJ,CAAC","sourcesContent":["// Development-only errors and warnings of the renderer (view/02-bindings.md \"Child values\",\n// view/03-lists.md \"Keys\", view/09-template-rules.md \"Warnings\"). Every call site is guarded by\n// `if (DEV)`, so production bundles drop this module. Messages say what to write instead.\n\nconst SPEC = 'docs/design-docs/view';\nconst warned = new WeakSet<object>();\n\nconst describe = (value: unknown): string =>\n typeof value === 'function'\n ? 'a function'\n : Array.isArray(value)\n ? 'an array'\n : typeof value === 'object'\n ? `an object (${Object.prototype.toString.call(value).slice(8, -1)})`\n : `a ${typeof value}`;\n\n/** A child hole got a value it can't render: an error in development. */\nexport function badChild(value: unknown): never {\n throw new TypeError(\n `gyral: a child hole got ${describe(value)}, which it can't render. Child holes take ` +\n `text, numbers, html\\`…\\` results, each(…), arrays, raw(…), or null/undefined/false/` +\n `nothing for nothing. Format the value as text, or render it with a template ` +\n `(${SPEC}/02-bindings.md \"Child values\").`,\n );\n}\n\n/** `true` in a child hole, once per part: usually a `cond && x` slip. */\nexport function warnTrue(part: object): void {\n if (warned.has(part)) return;\n warned.add(part);\n console.warn(\n 'gyral: `true` in a child hole renders nothing. It is usually a `cond && x` slip where ' +\n 'cond is a boolean and x is missing; write `cond ? x : nothing` ' +\n `(${SPEC}/02-bindings.md \"Child values\").`,\n );\n}\n\n/** An attribute or text-content hole got an object or function, once per part. */\nexport function warnValue(part: object, value: unknown, where: string): void {\n if (warned.has(part)) return;\n warned.add(part);\n console.warn(\n `gyral: ${where} got ${describe(value)}; it is written as String(value). Pass a string, ` +\n `number or boolean, or null/undefined/nothing to leave it out ` +\n `(${SPEC}/02-bindings.md \"Attribute values\").`,\n );\n}\n\nlet rawWarned = false;\n\n/** `raw()` parsed in the browser, once per page. */\nexport function warnRaw(): void {\n if (rawWarned) return;\n rawWarned = true;\n console.warn(\n 'gyral: raw() rendered in the browser. It works, but every change re-parses the markup; ' +\n 'prefer templates for content that changes, and keep raw() for server-rendered markup ' +\n `(${SPEC}/09-template-rules.md \"Warnings\").`,\n );\n}\n\n/** Keys must be unique strings or numbers: an error in development. */\nexport function badKey(key: unknown, index: number, duplicate: boolean): never {\n const problem = duplicate\n ? `the key ${JSON.stringify(key)} appears twice (again at index ${String(index)})`\n : `the key at index ${String(index)} is ${describe(key)}`;\n throw new Error(\n `gyral: each(): ${problem}. Keys must be unique strings or numbers within a list, such ` +\n `as a stable id: each(items, (x) => x.id, Row) (${SPEC}/03-lists.md \"Keys\").`,\n );\n}\n\n/** A skipped row would render differently: it reads something besides `item` and `pick`. */\nexport function warnImpureRow(row: (...args: never[]) => unknown): void {\n const name = row.name === '' ? 'a row function' : `the row function ${row.name}`;\n console.warn(\n `gyral: each(): ${name} depends on something not passed through \\`item\\` or \\`pick\\`, so ` +\n 'skipped rows would show stale content. Return what it reads from `pick` and take it as ' +\n `the second argument (${SPEC}/03-lists.md \"Rows must be pure\").`,\n );\n}\n\n/** A hook hole got something other than a hook result. */\nexport function badHook(value: unknown): never {\n throw new TypeError(\n `gyral: an element hook position (\\${…} inside a start tag) got ${describe(value)}. Only ` +\n `hooks made with defineHook() go there, e.g. <input \\${invalid(errors)}> ` +\n `(${SPEC}/02-bindings.md \"Element hooks\").`,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"warn.js","sourceRoot":"","sources":["../../../src/view/render/warn.ts"],"names":[],"mappings":"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","sourcesContent":["// Development-only errors and warnings of the renderer (view/02-bindings.md \"Child values\",\n// view/03-lists.md \"Keys\", view/09-template-rules.md \"Warnings\"). Every call site is guarded by\n// `if (DEV)`, so production bundles drop this module. Messages say what to write instead.\n\nconst SPEC = 'docs/design-docs/view';\nconst warned = new WeakSet<object>();\n\nconst describe = (value: unknown): string =>\n typeof value === 'function'\n ? 'a function'\n : Array.isArray(value)\n ? 'an array'\n : typeof value === 'object'\n ? `an object (${Object.prototype.toString.call(value).slice(8, -1)})`\n : `a ${typeof value}`;\n\n/** A child hole got a value it can't render: an error in development. */\nexport function badChild(value: unknown): never {\n throw new TypeError(\n `gyral: a child hole got ${describe(value)}, which it can't render. Child holes take ` +\n `text, numbers, html\\`…\\` results, each(…), arrays, raw(…), or null/undefined/false/` +\n `nothing for nothing. Format the value as text, or render it with a template ` +\n `(${SPEC}/02-bindings.md \"Child values\").`,\n );\n}\n\n/** `true` in a child hole, once per part: usually a `cond && x` slip. */\nexport function warnTrue(part: object): void {\n if (warned.has(part)) return;\n warned.add(part);\n console.warn(\n 'gyral: `true` in a child hole renders nothing. It is usually a `cond && x` slip where ' +\n 'cond is a boolean and x is missing; write `cond ? x : nothing` ' +\n `(${SPEC}/02-bindings.md \"Child values\").`,\n );\n}\n\n/** An attribute or text-content hole got an object or function, once per part. */\nexport function warnValue(part: object, value: unknown, where: string): void {\n if (warned.has(part)) return;\n warned.add(part);\n console.warn(\n `gyral: ${where} got ${describe(value)}; it is written as String(value). Pass a string, ` +\n `number or boolean, or null/undefined/nothing to leave it out ` +\n `(${SPEC}/02-bindings.md \"Attribute values\").`,\n );\n}\n\n/**\n * A property binding got a function, once per part (02 \"Properties\"): views attach no\n * closures. Built-in elements and Gyral components warn; other custom elements may take a\n * callback (a third-party widget's API), so they don't.\n */\nexport function warnFunctionProp(part: object, el: Element, name: string): void {\n const gyral = (el.constructor as { readonly spec?: unknown }).spec !== undefined;\n if (warned.has(part) || (el.localName.includes('-') && !gyral)) return;\n warned.add(part);\n console.warn(\n `gyral: .${name}=\\${…} on <${el.localName}> got a function. Views attach no closures: ` +\n (gyral\n ? 'props are data (they travel in hydration seeds); pass data and let the component ' +\n 'decide what to do with it, and hear back from it through its outputs'\n : 'name an intent with data-intent=${i.Name} for events, and put behaviour on an ' +\n 'element in a hook (defineHook)') +\n ` (${SPEC}/02-bindings.md \"Properties\").`,\n );\n}\n\nlet rawWarned = false;\n\n/** `raw()` parsed in the browser, once per page. */\nexport function warnRaw(): void {\n if (rawWarned) return;\n rawWarned = true;\n console.warn(\n 'gyral: raw() rendered in the browser. It works, but every change re-parses the markup; ' +\n 'prefer templates for content that changes, and keep raw() for server-rendered markup ' +\n `(${SPEC}/09-template-rules.md \"Warnings\").`,\n );\n}\n\n/** Keys must be unique strings or numbers: an error in development. */\nexport function badKey(key: unknown, index: number, duplicate: boolean): never {\n const problem = duplicate\n ? `the key ${JSON.stringify(key)} appears twice (again at index ${String(index)})`\n : `the key at index ${String(index)} is ${describe(key)}`;\n throw new Error(\n `gyral: each(): ${problem}. Keys must be unique strings or numbers within a list, such ` +\n `as a stable id: each(items, (x) => x.id, Row) (${SPEC}/03-lists.md \"Keys\").`,\n );\n}\n\n/** A skipped row would render differently: it reads something besides `item` and `pick`. */\nexport function warnImpureRow(row: (...args: never[]) => unknown): void {\n const name = row.name === '' ? 'a row function' : `the row function ${row.name}`;\n console.warn(\n `gyral: each(): ${name} depends on something not passed through \\`item\\` or \\`pick\\`, so ` +\n 'skipped rows would show stale content. Return what it reads from `pick` and take it as ' +\n `the second argument (${SPEC}/03-lists.md \"Rows must be pure\").`,\n );\n}\n\n/** A hook hole got something other than a hook result. */\n/** `?modal`/`?popover-open` with the bindings' code left out of the build (toggles.ts). */\nexport function warnToggle(el: Element, name: string): void {\n if (warned.has(el)) return;\n warned.add(el);\n console.warn(\n `gyral: ?${name} on <${el.localName}> does nothing: the build left its code out ` +\n `(${SPEC}/05-element.md \"Features register themselves\").`,\n );\n}\n\nexport function badHook(value: unknown): never {\n throw new TypeError(\n `gyral: an element hook position (\\${…} inside a start tag) got ${describe(value)}. Only ` +\n `hooks made with defineHook() go there, e.g. <input \\${invalid(errors)}> ` +\n `(${SPEC}/02-bindings.md \"Element hooks\").`,\n );\n}\n\n/**\n * An svg template renders only in SVG content: an SVG element other than <foreignObject>,\n * <desc> or <title>, whose content is HTML (01 \"svg templates\"). A detached fragment (an\n * instance being built) isn't checked: its place is known only when it is inserted.\n */\nexport function checkSvgParent(parent: Node): void {\n if (parent.nodeType === 11 && !('host' in parent)) return;\n const el = parent as Element;\n if (\n el.namespaceURI === 'http://www.w3.org/2000/svg' &&\n !/^(foreignObject|desc|title)$/.test(el.localName)\n ) {\n return;\n }\n const where = el.nodeType === 1 ? `<${el.localName}>` : 'a shadow root';\n throw new Error(\n `gyral: an svg template is rendered into ${where}, which isn't SVG content. svg\\`…\\` ` +\n 'fragments are SVG elements: render them inside an <svg> (or another SVG element, not ' +\n '<foreignObject>) of an html template, html`<svg viewBox=\"…\">${svg`…`}</svg>`, or write ' +\n `the whole graphic with html (${SPEC}/01-templates.md \"svg templates\").`,\n );\n}\n"]}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { ServerComponent } from '../registry.js';
|
|
2
|
-
import { type Deferred, type Item } from './writer.js';
|
|
2
|
+
import { type Deferred, type Item, type StyleValues } from './writer.js';
|
|
3
3
|
/**
|
|
4
4
|
* The text of a shadow component's `<style>` (its CSS texts joined by newlines, `</style`
|
|
5
5
|
* escaped), exactly as written, so `styleHashes()` hashes what the browser sees. `''`: none.
|
|
6
6
|
*/
|
|
7
7
|
export declare function styleText(component: ServerComponent): string;
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Writes a deferred component; nested components are deferred again. A component that fails
|
|
10
|
+
* (ADR 0024) writes its error view instead, marked `data-gyral-error`, and `onError` hears it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function expand({ component, input }: Deferred, dev: boolean, styles: StyleValues | undefined, onError: (error: unknown) => void): Item[];
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// tag (light mark, seed, island attributes), then its view, inside a declarative shadow root
|
|
3
3
|
// with the component's CSS (08 "Server") or as light-DOM children (ADR 0014). The parent's
|
|
4
4
|
// children of a shadow component follow in the parent's walk, after the `<template>`.
|
|
5
|
-
import { ISLAND_ATTRIBUTE, LIGHT_ATTRIBUTE, SEED_ATTRIBUTE } from '../attributes.js';
|
|
5
|
+
import { ERROR_ATTRIBUTE, ISLAND_ATTRIBUTE, LIGHT_ATTRIBUTE, SEED_ATTRIBUTE, } from '../attributes.js';
|
|
6
6
|
import { escapeSeed, styleSafe } from './escape.js';
|
|
7
7
|
import { ROOT, Writer } from './writer.js';
|
|
8
8
|
const styleTexts = new WeakMap();
|
|
@@ -18,13 +18,34 @@ export function styleText(component) {
|
|
|
18
18
|
}
|
|
19
19
|
return text;
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Writes a deferred component; nested components are deferred again. A component that fails
|
|
23
|
+
* (ADR 0024) writes its error view instead, marked `data-gyral-error`, and `onError` hears it.
|
|
24
|
+
*/
|
|
25
|
+
export function expand({ component, input }, dev, styles, onError) {
|
|
26
|
+
let rendering = component.render(input);
|
|
27
|
+
let items;
|
|
28
|
+
try {
|
|
29
|
+
items = write(component, input.scope, rendering, dev, styles);
|
|
30
|
+
}
|
|
31
|
+
catch (cause) {
|
|
32
|
+
if (component.fallback === undefined || rendering.failed !== undefined)
|
|
33
|
+
throw cause;
|
|
34
|
+
rendering = component.fallback(cause);
|
|
35
|
+
items = write(component, input.scope, rendering, dev, styles);
|
|
36
|
+
}
|
|
37
|
+
if (rendering.failed !== undefined)
|
|
38
|
+
onError(rendering.failed);
|
|
39
|
+
return items;
|
|
40
|
+
}
|
|
41
|
+
function write(component, scope, { view, seed, failed }, dev, styles) {
|
|
42
|
+
const w = new Writer(dev, scope, styles);
|
|
25
43
|
let tail = component.light ? ` ${LIGHT_ATTRIBUTE}` : '';
|
|
26
44
|
// Single-quoted, so the JSON's double quotes stay raw (ADR 0012).
|
|
27
|
-
|
|
45
|
+
if (failed === undefined)
|
|
46
|
+
tail += ` ${SEED_ATTRIBUTE}='${escapeSeed(JSON.stringify(seed))}'`;
|
|
47
|
+
else
|
|
48
|
+
tail += ` ${ERROR_ATTRIBUTE}`;
|
|
28
49
|
if (component.hydrate !== 'load') {
|
|
29
50
|
tail += ` defer-hydration ${ISLAND_ATTRIBUTE}="${component.hydrate}"`;
|
|
30
51
|
}
|
|
@@ -34,7 +55,8 @@ export function expand({ component, input }, dev) {
|
|
|
34
55
|
return w.done();
|
|
35
56
|
}
|
|
36
57
|
const css = styleText(component);
|
|
37
|
-
|
|
58
|
+
const focus = component.delegatesFocus === true ? ' shadowrootdelegatesfocus' : '';
|
|
59
|
+
w.write(`<template shadowrootmode="open"${focus}>${css === '' ? '' : `<style>${css}</style>`}`);
|
|
38
60
|
w.child(view, undefined, ROOT);
|
|
39
61
|
w.write('</template>');
|
|
40
62
|
return w.done();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/view/server/component.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,6FAA6F;AAC7F,2FAA2F;AAC3F,sFAAsF;AACtF,OAAO,
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../src/view/server/component.ts"],"names":[],"mappings":"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","sourcesContent":["// Rendering one Gyral component in place (view/06-server.md \"Components\"): the end of its start\n// tag (light mark, seed, island attributes), then its view, inside a declarative shadow root\n// with the component's CSS (08 \"Server\") or as light-DOM children (ADR 0014). The parent's\n// children of a shadow component follow in the parent's walk, after the `<template>`.\nimport {\n ERROR_ATTRIBUTE,\n ISLAND_ATTRIBUTE,\n LIGHT_ATTRIBUTE,\n SEED_ATTRIBUTE,\n} from '../attributes.js';\nimport type { ServerComponent, ServerRendering } from '../registry.js';\nimport { escapeSeed, styleSafe } from './escape.js';\nimport { ROOT, Writer, type Deferred, type Item, type StyleValues } from './writer.js';\n\nconst styleTexts = new WeakMap<ServerComponent, string>();\n\n/**\n * The text of a shadow component's `<style>` (its CSS texts joined by newlines, `</style`\n * escaped), exactly as written, so `styleHashes()` hashes what the browser sees. `''`: none.\n */\nexport function styleText(component: ServerComponent): string {\n let text = styleTexts.get(component);\n if (text === undefined) {\n text = styleSafe(component.styles.join('\\n'));\n styleTexts.set(component, text);\n }\n return text;\n}\n\n/**\n * Writes a deferred component; nested components are deferred again. A component that fails\n * (ADR 0024) writes its error view instead, marked `data-gyral-error`, and `onError` hears it.\n */\nexport function expand(\n { component, input }: Deferred,\n dev: boolean,\n styles: StyleValues | undefined,\n onError: (error: unknown) => void,\n): Item[] {\n let rendering = component.render(input);\n let items: Item[];\n try {\n items = write(component, input.scope, rendering, dev, styles);\n } catch (cause) {\n if (component.fallback === undefined || rendering.failed !== undefined) throw cause;\n rendering = component.fallback(cause);\n items = write(component, input.scope, rendering, dev, styles);\n }\n if (rendering.failed !== undefined) onError(rendering.failed);\n return items;\n}\n\nfunction write(\n component: ServerComponent,\n scope: unknown,\n { view, seed, failed }: ServerRendering,\n dev: boolean,\n styles: StyleValues | undefined,\n): Item[] {\n const w = new Writer(dev, scope, styles);\n let tail = component.light ? ` ${LIGHT_ATTRIBUTE}` : '';\n // Single-quoted, so the JSON's double quotes stay raw (ADR 0012).\n if (failed === undefined) tail += ` ${SEED_ATTRIBUTE}='${escapeSeed(JSON.stringify(seed))}'`;\n else tail += ` ${ERROR_ATTRIBUTE}`;\n if (component.hydrate !== 'load') {\n tail += ` defer-hydration ${ISLAND_ATTRIBUTE}=\"${component.hydrate}\"`;\n }\n w.write(`${tail}>`);\n if (component.light) {\n w.child(view, undefined, ROOT);\n return w.done();\n }\n const css = styleText(component);\n const focus = component.delegatesFocus === true ? ' shadowrootdelegatesfocus' : '';\n w.write(`<template shadowrootmode=\"open\"${focus}>${css === '' ? '' : `<style>${css}</style>`}`);\n w.child(view, undefined, ROOT);\n w.write('</template>');\n return w.done();\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ChildValue } from '../render/values.js';
|
|
2
|
+
import { type StyleValues } from './writer.js';
|
|
3
|
+
export type { StyleValues };
|
|
2
4
|
export interface ServerRenderOptions {
|
|
3
5
|
/**
|
|
4
6
|
* Development markers (`<!--gyral:ID-->` before each template instance, for hydration's
|
|
@@ -6,6 +8,24 @@ export interface ServerRenderOptions {
|
|
|
6
8
|
* export condition, as for the client), off otherwise.
|
|
7
9
|
*/
|
|
8
10
|
readonly dev?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Collects every `style` attribute value the render writes, decoded (as the DOM sees it),
|
|
13
|
+
* each mapped to where it was first written (template `loc` or id): static, bound,
|
|
14
|
+
* multi-part and element-hook values; not `raw()` markup. For hashing them into a CSP
|
|
15
|
+
* (ADR 0020). The markup is the same with or without it.
|
|
16
|
+
*/
|
|
17
|
+
readonly styleAttributes?: StyleValues;
|
|
18
|
+
/**
|
|
19
|
+
* Hears each component whose `init` or view threw (ADR 0024; core's `GyralError`): the page
|
|
20
|
+
* goes on with that component's error view, or nothing. Default `console.error`. Throwing
|
|
21
|
+
* from it ends the render with that error.
|
|
22
|
+
*/
|
|
23
|
+
readonly onError?: (error: unknown) => void;
|
|
24
|
+
/**
|
|
25
|
+
* Collects the tag of every Gyral component the render writes, in document order, so a page
|
|
26
|
+
* can load exactly those components' client modules (automatic component loading).
|
|
27
|
+
*/
|
|
28
|
+
readonly tags?: Set<string>;
|
|
9
29
|
}
|
|
10
30
|
/**
|
|
11
31
|
* Renders `value` to HTML chunks, lazily: each step writes up to the next component boundary.
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// The server renderer (view/06-server.md "API"): synchronous, chunked, runtime-agnostic (no
|
|
2
|
-
// DOM, no Node-only APIs: a JavaScript SHA-256 for the style hashes). `@gyral/core/server` wraps these,
|
|
2
|
+
// DOM, no Node-only APIs: a JavaScript SHA-256 for the style hashes). `@gyral/core/internal/server` wraps these,
|
|
3
3
|
// registering recorded specs first; code outside view/ may import only this module of view/server/.
|
|
4
4
|
import { DEV } from '../flags.js';
|
|
5
5
|
import { serverComponents } from '../registry.js';
|
|
6
6
|
import { expand, styleText } from './component.js';
|
|
7
7
|
import { sha256 } from './sha256.js';
|
|
8
8
|
import { ROOT, Writer } from './writer.js';
|
|
9
|
+
const logError = (error) => {
|
|
10
|
+
console.error(error);
|
|
11
|
+
};
|
|
9
12
|
function push(stack, items) {
|
|
10
13
|
for (let i = items.length - 1; i >= 0; i--)
|
|
11
14
|
stack.push(items[i]);
|
|
@@ -17,15 +20,20 @@ function push(stack, items) {
|
|
|
17
20
|
*/
|
|
18
21
|
export function* render(value, options = {}) {
|
|
19
22
|
const dev = options.dev ?? DEV;
|
|
20
|
-
const
|
|
23
|
+
const styles = options.styleAttributes;
|
|
24
|
+
const onError = options.onError ?? logError;
|
|
25
|
+
const tags = options.tags;
|
|
26
|
+
const root = new Writer(dev, undefined, styles);
|
|
21
27
|
root.child(value, undefined, ROOT);
|
|
22
28
|
const stack = [];
|
|
23
29
|
push(stack, root.done());
|
|
24
30
|
for (let item = stack.pop(); item !== undefined; item = stack.pop()) {
|
|
25
31
|
if (typeof item === 'string')
|
|
26
32
|
yield item;
|
|
27
|
-
else
|
|
28
|
-
|
|
33
|
+
else {
|
|
34
|
+
tags?.add(item.component.tag);
|
|
35
|
+
push(stack, expand(item, dev, styles, onError));
|
|
36
|
+
}
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
39
|
/** Renders `value` to one string. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/view/server/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/view/server/index.ts"],"names":[],"mappings":"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","sourcesContent":["// The server renderer (view/06-server.md \"API\"): synchronous, chunked, runtime-agnostic (no\n// DOM, no Node-only APIs: a JavaScript SHA-256 for the style hashes). `@gyral/core/internal/server` wraps these,\n// registering recorded specs first; code outside view/ may import only this module of view/server/.\nimport { DEV } from '../flags.js';\nimport { serverComponents } from '../registry.js';\nimport type { ChildValue } from '../render/values.js';\nimport { expand, styleText } from './component.js';\nimport { sha256 } from './sha256.js';\nimport { ROOT, Writer, type Item, type StyleValues } from './writer.js';\n\nexport type { StyleValues };\n\nexport interface ServerRenderOptions {\n /**\n * Development markers (`<!--gyral:ID-->` before each template instance, for hydration's\n * checks, 07) and development checks. Default: on in development builds (the `development`\n * export condition, as for the client), off otherwise.\n */\n readonly dev?: boolean;\n /**\n * Collects every `style` attribute value the render writes, decoded (as the DOM sees it),\n * each mapped to where it was first written (template `loc` or id): static, bound,\n * multi-part and element-hook values; not `raw()` markup. For hashing them into a CSP\n * (ADR 0020). The markup is the same with or without it.\n */\n readonly styleAttributes?: StyleValues;\n /**\n * Hears each component whose `init` or view threw (ADR 0024; core's `GyralError`): the page\n * goes on with that component's error view, or nothing. Default `console.error`. Throwing\n * from it ends the render with that error.\n */\n readonly onError?: (error: unknown) => void;\n /**\n * Collects the tag of every Gyral component the render writes, in document order, so a page\n * can load exactly those components' client modules (automatic component loading).\n */\n readonly tags?: Set<string>;\n}\n\nconst logError = (error: unknown): void => {\n console.error(error);\n};\n\nfunction push(stack: Item[], items: readonly Item[]): void {\n for (let i = items.length - 1; i >= 0; i--) stack.push(items[i] as Item);\n}\n\n/**\n * Renders `value` to HTML chunks, lazily: each step writes up to the next component boundary.\n * Every component's `init` and view run in the step that writes it, so a caller can wrap each\n * step in a per-request scope (ADR 0013).\n */\nexport function* render(value: ChildValue, options: ServerRenderOptions = {}): Iterable<string> {\n const dev = options.dev ?? DEV;\n const styles = options.styleAttributes;\n const onError = options.onError ?? logError;\n const tags = options.tags;\n const root = new Writer(dev, undefined, styles);\n root.child(value, undefined, ROOT);\n const stack: Item[] = [];\n push(stack, root.done());\n for (let item = stack.pop(); item !== undefined; item = stack.pop()) {\n if (typeof item === 'string') yield item;\n else {\n tags?.add(item.component.tag);\n push(stack, expand(item, dev, styles, onError));\n }\n }\n}\n\n/** Renders `value` to one string. */\nexport function renderToString(value: ChildValue, options?: ServerRenderOptions): string {\n let html = '';\n for (const chunk of render(value, options)) html += chunk;\n return html;\n}\n\nconst hashes = new Map<string, string>();\n\n/**\n * `'sha256-…'` of a `<style>` element's text, for a CSP `style-src` (cached per text).\n * Synchronous (sha256.ts), so a page can build its policy while it renders.\n */\nexport function styleHashSync(text: string): string {\n let hash = hashes.get(text);\n if (hash === undefined) {\n // The parser turns CR and CRLF into LF before the browser hashes the element's text.\n const digest = sha256(new TextEncoder().encode(text.replace(/\\r\\n?/g, '\\n')));\n let binary = '';\n for (const byte of digest) binary += String.fromCharCode(byte);\n hash = `'sha256-${btoa(binary)}'`;\n hashes.set(text, hash);\n }\n return hash;\n}\n\n/** `styleHashSync`, as a promise (the API before it existed). */\nexport const styleHash = (text: string): Promise<string> => Promise.resolve(styleHashSync(text));\n\n/** Tag → `<style>` text of every registered shadow component with CSS (08 \"Server\"). */\nexport function componentStyles(): ReadonlyMap<string, string> {\n const styles = new Map<string, string>();\n for (const component of serverComponents()) {\n const text = styleText(component);\n if (text !== '') styles.set(component.tag, text);\n }\n return styles;\n}\n\n/** The hashes of every registered shadow component's `<style>` (08 \"Server\"), deduplicated. */\nexport function styleHashes(): Promise<readonly string[]> {\n return Promise.resolve([...new Set([...componentStyles().values()].map(styleHashSync))]);\n}\n"]}
|
|
@@ -5,6 +5,12 @@ export interface Deferred {
|
|
|
5
5
|
readonly component: ServerComponent;
|
|
6
6
|
readonly input: ServerRenderInput;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* A render's `style` attribute values for a CSP (ADR 0020): each distinct value as the DOM sees
|
|
10
|
+
* it (decoded), mapped to where it was first written (the template's `loc` or id; `''` when
|
|
11
|
+
* neither is known).
|
|
12
|
+
*/
|
|
13
|
+
export type StyleValues = Map<string, string>;
|
|
8
14
|
/** What a walk produces: markup, with deferred components in document order. */
|
|
9
15
|
export type Item = string | Deferred;
|
|
10
16
|
/** A custom element's start tag while its attribute holes are written. */
|
|
@@ -30,13 +36,18 @@ export declare const PLAIN: Frame;
|
|
|
30
36
|
export declare class Markup {
|
|
31
37
|
protected readonly dev: boolean;
|
|
32
38
|
protected scope: unknown;
|
|
39
|
+
protected readonly styles?: StyleValues | undefined;
|
|
33
40
|
protected buf: string;
|
|
34
41
|
protected readonly items: Item[];
|
|
42
|
+
/** The template being written, for `styles` (its `loc` or id). */
|
|
43
|
+
protected where: string;
|
|
35
44
|
/**
|
|
36
45
|
* `dev`: development markers and checks. `scope`: the nearest provider's scope, passed to
|
|
37
|
-
* components (undefined: the request's).
|
|
46
|
+
* components (undefined: the request's). `styles`: collects every `style` value written.
|
|
38
47
|
*/
|
|
39
|
-
constructor(dev: boolean, scope: unknown);
|
|
48
|
+
constructor(dev: boolean, scope: unknown, styles?: StyleValues | undefined);
|
|
49
|
+
/** Records a `style` value the DOM will see (empty values declare nothing). */
|
|
50
|
+
protected style(value: string): void;
|
|
40
51
|
write(markup: string): void;
|
|
41
52
|
/** The markup and deferred components written so far. */
|
|
42
53
|
done(): Item[];
|
package/dist/view/server/tags.js
CHANGED
|
@@ -7,13 +7,22 @@ export const PLAIN = { k: 'plain' };
|
|
|
7
7
|
export class Markup {
|
|
8
8
|
/**
|
|
9
9
|
* `dev`: development markers and checks. `scope`: the nearest provider's scope, passed to
|
|
10
|
-
* components (undefined: the request's).
|
|
10
|
+
* components (undefined: the request's). `styles`: collects every `style` value written.
|
|
11
11
|
*/
|
|
12
|
-
constructor(dev, scope) {
|
|
12
|
+
constructor(dev, scope, styles) {
|
|
13
13
|
this.dev = dev;
|
|
14
14
|
this.scope = scope;
|
|
15
|
+
this.styles = styles;
|
|
15
16
|
this.buf = '';
|
|
16
17
|
this.items = [];
|
|
18
|
+
/** The template being written, for `styles` (its `loc` or id). */
|
|
19
|
+
this.where = '';
|
|
20
|
+
}
|
|
21
|
+
/** Records a `style` value the DOM will see (empty values declare nothing). */
|
|
22
|
+
style(value) {
|
|
23
|
+
if (value !== '' && this.styles !== undefined && !this.styles.has(value)) {
|
|
24
|
+
this.styles.set(value, this.where);
|
|
25
|
+
}
|
|
17
26
|
}
|
|
18
27
|
write(markup) {
|
|
19
28
|
this.buf += markup;
|
|
@@ -40,6 +49,8 @@ export class Markup {
|
|
|
40
49
|
}
|
|
41
50
|
valued(name, value, opening) {
|
|
42
51
|
this.buf += ` ${name}="${escapeAttr(value)}"`;
|
|
52
|
+
if (name === 'style')
|
|
53
|
+
this.style(value);
|
|
43
54
|
if (opening !== undefined)
|
|
44
55
|
opening.attributes[name] = value;
|
|
45
56
|
}
|