From ae18035419f266a025ffbe4ece8bf95bf9400973 Mon Sep 17 00:00:00 2001 From: TechQuery Date: Thu, 25 Jul 2024 05:00:55 +0800 Subject: [PATCH 1/2] [add] Stream Rendering method [remove] internal Shadow Root finder [optimize] update Upstream packages --- package.json | 19 +++-- pnpm-lock.yaml | 163 ++++++++++++++++++++----------------- source/dist/DOMRenderer.ts | 51 ++++-------- 3 files changed, 114 insertions(+), 119 deletions(-) diff --git a/package.json b/package.json index 85518a3..7e97a88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dom-renderer", - "version": "2.2.0", + "version": "2.3.0", "license": "LGPL-3.0-or-later", "author": "shiy2008@gmail.com", "description": "A light-weight DOM Renderer supports Web components standard & TypeScript language", @@ -24,23 +24,24 @@ "types": "dist/index.d.ts", "main": "dist/index.js", "dependencies": { + "declarative-shadow-dom-polyfill": "^0.4.0-rc.0", "tslib": "^2.6.3", + "web-streams-polyfill": "^4.0.0", "web-utility": "^4.4.0" }, "devDependencies": { "@happy-dom/jest-environment": "^14.12.3", "@types/jest": "^29.5.12", - "@types/node": "^18.19.39", - "declarative-shadow-dom-polyfill": "^0.3.2", - "husky": "^9.0.11", + "@types/node": "^18.19.42", + "husky": "^9.1.1", "jest": "^29.7.0", "lint-staged": "^15.2.7", "open-cli": "^8.0.0", - "prettier": "^3.3.2", - "ts-jest": "^29.2.2", - "typedoc": "^0.26.4", - "typedoc-plugin-mdn-links": "^3.2.3", - "typescript": "~5.5.3" + "prettier": "^3.3.3", + "ts-jest": "^29.2.3", + "typedoc": "^0.26.5", + "typedoc-plugin-mdn-links": "^3.2.5", + "typescript": "~5.5.4" }, "prettier": { "singleQuote": true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd5b985..ed75e9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,18 @@ importers: .: dependencies: + declarative-shadow-dom-polyfill: + specifier: ^0.4.0-rc.0 + version: 0.4.0-rc.0(typescript@5.5.4) tslib: specifier: ^2.6.3 version: 2.6.3 + web-streams-polyfill: + specifier: ^4.0.0 + version: 4.0.0 web-utility: specifier: ^4.4.0 - version: 4.4.0(typescript@5.5.3) + version: 4.4.0(typescript@5.5.4) devDependencies: '@happy-dom/jest-environment': specifier: ^14.12.3 @@ -22,17 +28,14 @@ importers: specifier: ^29.5.12 version: 29.5.12 '@types/node': - specifier: ^18.19.39 - version: 18.19.39 - declarative-shadow-dom-polyfill: - specifier: ^0.3.2 - version: 0.3.2 + specifier: ^18.19.42 + version: 18.19.42 husky: - specifier: ^9.0.11 - version: 9.0.11 + specifier: ^9.1.1 + version: 9.1.1 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@18.19.39) + version: 29.7.0(@types/node@18.19.42) lint-staged: specifier: ^15.2.7 version: 15.2.7 @@ -40,20 +43,20 @@ importers: specifier: ^8.0.0 version: 8.0.0 prettier: - specifier: ^3.3.2 - version: 3.3.2 + specifier: ^3.3.3 + version: 3.3.3 ts-jest: - specifier: ^29.2.2 - version: 29.2.2(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@18.19.39))(typescript@5.5.3) + specifier: ^29.2.3 + version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@18.19.42))(typescript@5.5.4) typedoc: - specifier: ^0.26.4 - version: 0.26.4(typescript@5.5.3) + specifier: ^0.26.5 + version: 0.26.5(typescript@5.5.4) typedoc-plugin-mdn-links: - specifier: ^3.2.3 - version: 3.2.3(typedoc@0.26.4(typescript@5.5.3)) + specifier: ^3.2.5 + version: 3.2.5(typedoc@0.26.5(typescript@5.5.4)) typescript: - specifier: ~5.5.3 - version: 5.5.3 + specifier: ~5.5.4 + version: 5.5.4 packages: @@ -372,8 +375,8 @@ packages: '@types/jest@29.5.12': resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==} - '@types/node@18.19.39': - resolution: {integrity: sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==} + '@types/node@18.19.42': + resolution: {integrity: sha512-d2ZFc/3lnK2YCYhos8iaNIYu9Vfhr92nHiyJHRltXWjXUBjEE+A4I58Tdbnw4VhggSW+2j5y5gTrLs4biNnubg==} '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} @@ -594,8 +597,10 @@ packages: supports-color: optional: true - declarative-shadow-dom-polyfill@0.3.2: - resolution: {integrity: sha512-r0bIGcKMOr6CKV7cbFQ4gUzmAGru/Nb191fM/bIRhAHXttv2rqoQndA7+Olv8fU7SQE+aQdeu1kO+L4Sfxzo/g==} + declarative-shadow-dom-polyfill@0.4.0-rc.0: + resolution: {integrity: sha512-dEUpIerVi0rsEBaW4kr0tEdasEAcx8H65cqG8KCMVZZuUMtZq20vLrsYituTBUZP56VqR90Sf/AFyQvZijViLw==} + peerDependencies: + typescript: '>=5.5.3' dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} @@ -791,8 +796,8 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@9.0.11: - resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==} + husky@9.1.1: + resolution: {integrity: sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==} engines: {node: '>=18'} hasBin: true @@ -1243,8 +1248,8 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - prettier@3.3.2: - resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} engines: {node: '>=14'} hasBin: true @@ -1457,8 +1462,8 @@ packages: resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==} engines: {node: '>=14.16'} - ts-jest@29.2.2: - resolution: {integrity: sha512-sSW7OooaKT34AAngP6k1VS669a0HdLxkQZnlC7T76sckGCokXFnvJ3yRlQZGRTAoV5K19HfSgCiSwWOSIfcYlg==} + ts-jest@29.2.3: + resolution: {integrity: sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1500,20 +1505,20 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - typedoc-plugin-mdn-links@3.2.3: - resolution: {integrity: sha512-hz22UgFuzdtgpBXet2dxKf9d2HVixL2VcE9Ke1+X1Nu8W8jSGIB2awIA6HFVsD0vk1OLe3ehU0ibyD5sN7wh4w==} + typedoc-plugin-mdn-links@3.2.5: + resolution: {integrity: sha512-duQ0H7+bATNSWVQRt3HubspZ9gqgSZxiQkenlTJ8lGsUrldZwpjG56hJqLD6BspNJfEnElP9hIU7yY5+/vF1Eg==} peerDependencies: typedoc: '>= 0.23.14 || 0.24.x || 0.25.x || 0.26.x' - typedoc@0.26.4: - resolution: {integrity: sha512-FlW6HpvULDKgc3rK04V+nbFyXogPV88hurarDPOjuuB5HAwuAlrCMQ5NeH7Zt68a/ikOKu6Z/0hFXAeC9xPccQ==} + typedoc@0.26.5: + resolution: {integrity: sha512-Vn9YKdjKtDZqSk+by7beZ+xzkkr8T8CYoiasqyt4TTRFy5+UHzL/mF/o4wGBjRF+rlWQHDb0t6xCpA3JNL5phg==} engines: {node: '>= 18'} hasBin: true peerDependencies: typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x - typescript@5.5.3: - resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} hasBin: true @@ -1543,6 +1548,10 @@ packages: walker@1.0.8: resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + web-streams-polyfill@4.0.0: + resolution: {integrity: sha512-0zJXHRAYEjM2tUfZ2DiSOHAa2aw1tisnnhU3ufD57R8iefL+DcdJyRBRyJpG+NUimDgbTI/lH+gAE1PAvV3Cgw==} + engines: {node: '>= 8'} + web-utility@4.4.0: resolution: {integrity: sha512-Bw0RcX5jBNuw+FQ2NKkkegNK07czjXoUtDNpRO+2ueNNv3FL8GsTTU27eM+17bzFPpYqukAdkCLJf5ZAYiDZtg==} peerDependencies: @@ -1836,7 +1845,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -1849,14 +1858,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.39) + jest-config: 29.7.0(@types/node@18.19.42) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1881,7 +1890,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -1899,7 +1908,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 18.19.39 + '@types/node': 18.19.42 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -1921,7 +1930,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 18.19.39 + '@types/node': 18.19.42 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -1991,7 +2000,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 18.19.39 + '@types/node': 18.19.42 '@types/yargs': 17.0.32 chalk: 4.1.2 @@ -2055,7 +2064,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 18.19.39 + '@types/node': 18.19.42 '@types/hast@3.0.4': dependencies: @@ -2076,7 +2085,7 @@ snapshots: expect: 29.7.0 pretty-format: 29.7.0 - '@types/node@18.19.39': + '@types/node@18.19.42': dependencies: undici-types: 5.26.5 @@ -2279,13 +2288,13 @@ snapshots: convert-source-map@2.0.0: {} - create-jest@29.7.0(@types/node@18.19.39): + create-jest@29.7.0(@types/node@18.19.42): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.39) + jest-config: 29.7.0(@types/node@18.19.42) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -2308,7 +2317,9 @@ snapshots: dependencies: ms: 2.1.2 - declarative-shadow-dom-polyfill@0.3.2: {} + declarative-shadow-dom-polyfill@0.4.0-rc.0(typescript@5.5.4): + dependencies: + typescript: 5.5.4 dedent@1.5.3: {} @@ -2470,7 +2481,7 @@ snapshots: human-signals@5.0.0: {} - husky@9.0.11: {} + husky@9.1.1: {} ieee754@1.2.1: {} @@ -2582,7 +2593,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -2602,16 +2613,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@18.19.39): + jest-cli@29.7.0(@types/node@18.19.42): dependencies: '@jest/core': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.39) + create-jest: 29.7.0(@types/node@18.19.42) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@18.19.39) + jest-config: 29.7.0(@types/node@18.19.42) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -2621,7 +2632,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@18.19.39): + jest-config@29.7.0(@types/node@18.19.42): dependencies: '@babel/core': 7.24.8 '@jest/test-sequencer': 29.7.0 @@ -2646,7 +2657,7 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 18.19.39 + '@types/node': 18.19.42 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -2675,7 +2686,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -2685,7 +2696,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 18.19.39 + '@types/node': 18.19.42 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -2724,7 +2735,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -2759,7 +2770,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -2787,7 +2798,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 chalk: 4.1.2 cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 @@ -2833,7 +2844,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -2852,7 +2863,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 18.19.39 + '@types/node': 18.19.42 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -2861,17 +2872,17 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 18.19.39 + '@types/node': 18.19.42 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@18.19.39): + jest@29.7.0(@types/node@18.19.42): dependencies: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@18.19.39) + jest-cli: 29.7.0(@types/node@18.19.42) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -3083,7 +3094,7 @@ snapshots: dependencies: find-up: 4.1.0 - prettier@3.3.2: {} + prettier@3.3.3: {} pretty-format@29.7.0: dependencies: @@ -3273,18 +3284,18 @@ snapshots: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - ts-jest@29.2.2(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@18.19.39))(typescript@5.5.3): + ts-jest@29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@18.19.42))(typescript@5.5.4): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@18.19.39) + jest: 29.7.0(@types/node@18.19.42) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.2 - typescript: 5.5.3 + typescript: 5.5.4 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.24.8 @@ -3302,20 +3313,20 @@ snapshots: type-fest@2.19.0: {} - typedoc-plugin-mdn-links@3.2.3(typedoc@0.26.4(typescript@5.5.3)): + typedoc-plugin-mdn-links@3.2.5(typedoc@0.26.5(typescript@5.5.4)): dependencies: - typedoc: 0.26.4(typescript@5.5.3) + typedoc: 0.26.5(typescript@5.5.4) - typedoc@0.26.4(typescript@5.5.3): + typedoc@0.26.5(typescript@5.5.4): dependencies: lunr: 2.3.9 markdown-it: 14.1.0 minimatch: 9.0.5 shiki: 1.10.3 - typescript: 5.5.3 + typescript: 5.5.4 yaml: 2.4.5 - typescript@5.5.3: {} + typescript@5.5.4: {} uc.micro@2.1.0: {} @@ -3343,12 +3354,14 @@ snapshots: dependencies: makeerror: 1.0.12 - web-utility@4.4.0(typescript@5.5.3): + web-streams-polyfill@4.0.0: {} + + web-utility@4.4.0(typescript@5.5.4): dependencies: '@swc/helpers': 0.5.11 element-internals-polyfill: 1.3.11 regenerator-runtime: 0.14.1 - typescript: 5.5.3 + typescript: 5.5.4 webidl-conversions@7.0.0: {} diff --git a/source/dist/DOMRenderer.ts b/source/dist/DOMRenderer.ts index 640fc3f..a3e0397 100644 --- a/source/dist/DOMRenderer.ts +++ b/source/dist/DOMRenderer.ts @@ -1,4 +1,5 @@ -import type {} from 'declarative-shadow-dom-polyfill'; +import { findShadowRoots, generateHTML } from 'declarative-shadow-dom-polyfill'; +import { ReadableStream } from 'web-streams-polyfill'; import { diffKeys, DiffStatus, @@ -11,17 +12,6 @@ import { import { DataObject, VNode } from './VDOM'; -const { attachShadow } = HTMLElement.prototype, - shadowDOMs = new WeakMap(); - -HTMLElement.prototype.attachShadow = function (options: ShadowRootInit) { - const shadowRoot = attachShadow.call(this, options); - - shadowDOMs.set(this, shadowRoot); - - return shadowRoot; -}; - export class DOMRenderer { eventPattern = /^on[A-Z]/; ariaPattern = /^aira[A-Z]/; @@ -228,36 +218,27 @@ export class DOMRenderer { return root; } - *findShadowRoots(root: Node) { - const walker = this.document.createTreeWalker( - root, - NodeFilter.SHOW_ELEMENT, - { - acceptNode: (node: Element) => - node instanceof HTMLElement - ? NodeFilter.FILTER_ACCEPT - : NodeFilter.FILTER_SKIP - } - ); - var currentNode: HTMLElement | null = null; + protected buildRenderTree(tree: VNode) { + const { body } = this.document.implementation.createHTMLDocument(); - while ((currentNode = walker.nextNode() as HTMLElement)) { - const shadowRoot = shadowDOMs.get(currentNode); + this.render(tree, body); - if (shadowRoot) { - yield shadowRoot; - yield* this.findShadowRoots(shadowRoot); - } - } + const shadowRoots = [...findShadowRoots(body)]; + + return { body, shadowRoots }; } renderToStaticMarkup(tree: VNode) { - const { body } = this.document.implementation.createHTMLDocument(); + const { body, shadowRoots } = this.buildRenderTree(tree); - this.render(tree, body); + return body.getHTML({ serializableShadowRoots: true, shadowRoots }); + } - const shadowRoots = [...this.findShadowRoots(body)]; + renderToReadableStream(tree: VNode) { + const { body, shadowRoots } = this.buildRenderTree(tree); - return body.getHTML({ serializableShadowRoots: true, shadowRoots }); + return ReadableStream.from( + generateHTML(body, { serializableShadowRoots: true, shadowRoots }) + ); } } From c4cfb0c8cbc024eaa7990347a8539483367449dd Mon Sep 17 00:00:00 2001 From: TechQuery Date: Fri, 26 Jul 2024 00:02:07 +0800 Subject: [PATCH 2/2] [add] Stream Rendering test & document --- ReadMe.md | 18 ++++++++++++++++++ package.json | 4 ++-- pnpm-lock.yaml | 20 ++++++++++---------- test/DOMRenderer.spec.ts | 27 ++++++++++++++++++++------- 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 3f069b6..d74a65c 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -66,6 +66,24 @@ const newVNode = new DOMRenderer().render( console.log(newVNode); ``` +### Node.js & Bun + +```jsx +import { Readable } from 'stream'; +import { createServer } from 'http'; +import { DOMRenderer } from 'dom-renderer'; + +const renderer = new DOMRenderer(); + +const Hello = () =>

Hello, JSX SSR!

; + +createServer((request, response) => { + const stream = renderer.renderToReadableStream(); + + Readable.fromWeb(stream).pipe(response); +}).listen(8080); +``` + ## Framework ### Web components diff --git a/package.json b/package.json index 7e97a88..61b716f 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "types": "dist/index.d.ts", "main": "dist/index.js", "dependencies": { - "declarative-shadow-dom-polyfill": "^0.4.0-rc.0", + "declarative-shadow-dom-polyfill": "^0.4.0", "tslib": "^2.6.3", "web-streams-polyfill": "^4.0.0", "web-utility": "^4.4.0" @@ -33,7 +33,7 @@ "@happy-dom/jest-environment": "^14.12.3", "@types/jest": "^29.5.12", "@types/node": "^18.19.42", - "husky": "^9.1.1", + "husky": "^9.1.2", "jest": "^29.7.0", "lint-staged": "^15.2.7", "open-cli": "^8.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed75e9f..fbdb73a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: declarative-shadow-dom-polyfill: - specifier: ^0.4.0-rc.0 - version: 0.4.0-rc.0(typescript@5.5.4) + specifier: ^0.4.0 + version: 0.4.0(typescript@5.5.4) tslib: specifier: ^2.6.3 version: 2.6.3 @@ -31,8 +31,8 @@ importers: specifier: ^18.19.42 version: 18.19.42 husky: - specifier: ^9.1.1 - version: 9.1.1 + specifier: ^9.1.2 + version: 9.1.2 jest: specifier: ^29.7.0 version: 29.7.0(@types/node@18.19.42) @@ -597,8 +597,8 @@ packages: supports-color: optional: true - declarative-shadow-dom-polyfill@0.4.0-rc.0: - resolution: {integrity: sha512-dEUpIerVi0rsEBaW4kr0tEdasEAcx8H65cqG8KCMVZZuUMtZq20vLrsYituTBUZP56VqR90Sf/AFyQvZijViLw==} + declarative-shadow-dom-polyfill@0.4.0: + resolution: {integrity: sha512-a3c/x43EIo+gzc7ZPY1NuOowPOClqaaU+5G1wwOG7h5xQ8UhZPM6NYcSDsvhTn9Pyc275pmvSUPPY+r4pPTOVA==} peerDependencies: typescript: '>=5.5.3' @@ -796,8 +796,8 @@ packages: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - husky@9.1.1: - resolution: {integrity: sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==} + husky@9.1.2: + resolution: {integrity: sha512-1/aDMXZdhr1VdJJTLt6e7BipM0Jd9qkpubPiIplon1WmCeOy3nnzsCMeBqS9AsL5ioonl8F8y/F2CLOmk19/Pw==} engines: {node: '>=18'} hasBin: true @@ -2317,7 +2317,7 @@ snapshots: dependencies: ms: 2.1.2 - declarative-shadow-dom-polyfill@0.4.0-rc.0(typescript@5.5.4): + declarative-shadow-dom-polyfill@0.4.0(typescript@5.5.4): dependencies: typescript: 5.5.4 @@ -2481,7 +2481,7 @@ snapshots: human-signals@5.0.0: {} - husky@9.1.1: {} + husky@9.1.2: {} ieee754@1.2.1: {} diff --git a/test/DOMRenderer.spec.ts b/test/DOMRenderer.spec.ts index 69ff677..5a26212 100644 --- a/test/DOMRenderer.spec.ts +++ b/test/DOMRenderer.spec.ts @@ -122,15 +122,15 @@ describe('DOM Renderer', () => { expect(shadowRoot.innerHTML).toBe(''); }); - it('should render the Shadow Root to HTML strings', () => { - class ShadowRootTag extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: 'closed' }).innerHTML = ''; - } + class ShadowRootTag extends HTMLElement { + constructor() { + super(); + this.attachShadow({ mode: 'closed' }).innerHTML = ''; } - customElements.define('shadow-root-tag', ShadowRootTag); + } + customElements.define('shadow-root-tag', ShadowRootTag); + it('should render the Shadow Root to HTML strings', () => { const markup = renderer.renderToStaticMarkup( new VNode({ tagName: 'shadow-root-tag' }) ); @@ -138,4 +138,17 @@ describe('DOM Renderer', () => { `` ); }); + + it('should render the Shadow Root to a Readable Stream', async () => { + const stream = renderer.renderToReadableStream( + new VNode({ tagName: 'shadow-root-tag' }) + ), + markups: string[] = []; + + for await (const markup of stream) markups.push(markup); + + expect(markups.join('')).toBe( + `` + ); + }); });