acrylblends 0.6.2 → 0.6.4
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/README.md +5 -1
- package/docs/framework/README.md +3 -2
- package/docs/framework/UPSTREAM.md +1 -1
- package/docs/framework/cordis/acryl-in-a-cordis-app.md +6 -0
- package/docs/framework/getting-started/basic.md +1 -0
- package/docs/framework/getting-started/desktop.md +41 -0
- package/docs/framework/guides/jsx-dom.md +0 -3
- package/docs/framework/guides/jsx.md +24 -3
- package/docs/framework/helpers/css.md +0 -3
- package/docs/framework/helpers/ssg.md +3 -6
- package/docs/framework/middleware/builtin/jsx-renderer.md +0 -3
- package/docs/framework/upstream.json +3 -3
- package/lib/accepts.d.ts +1 -1
- package/lib/acryl-base.d.ts +1 -1
- package/lib/adapter.d.ts +1 -1
- package/lib/{app-BdrVHBlJ.d.ts → app-D8riatvv.d.ts} +1 -1
- package/lib/base-BpQy2Rk7.d.ts +783 -0
- package/lib/base-ddiVmiE7.js +721 -0
- package/lib/basic-auth.d.ts +1 -1
- package/lib/bearer-auth.d.ts +1 -1
- package/lib/body-limit.d.ts +1 -1
- package/lib/cache.d.ts +1 -1
- package/lib/cache.js +4 -4
- package/lib/{client-BHTr318g.js → client-DDLXwhBo.js} +2 -125
- package/lib/client.d.ts +2 -2
- package/lib/client.js +2 -1
- package/lib/combine.d.ts +1 -1
- package/lib/common-D8Z4JRCw.d.ts +46 -0
- package/lib/components-0o0CBYNv.js +268 -0
- package/lib/components-DdI7-ns7.js +24 -0
- package/lib/compress.d.ts +1 -1
- package/lib/conninfo.d.ts +2 -2
- package/lib/constants-BR9jM9BC.js +9 -0
- package/lib/{context-B5Y1lLha.d.ts → context-DS3fYyG-.d.ts} +2 -2
- package/lib/context-DxFdY_un.d.ts +250 -0
- package/lib/context-storage.d.ts +1 -1
- package/lib/{cookie-D9_nQbsM.d.ts → cookie-CCelEqky.d.ts} +1 -1
- package/lib/cookie.d.ts +3 -3
- package/lib/cors.d.ts +1 -1
- package/lib/csrf.d.ts +1 -1
- package/lib/css-D2jb7X8b.js +320 -0
- package/lib/css.d.ts +82 -0
- package/lib/css.js +134 -0
- package/lib/dev.d.ts +2 -2
- package/lib/etag.d.ts +1 -1
- package/lib/factory.d.ts +2 -2
- package/lib/hooks-BMw6BAyP.js +762 -0
- package/lib/html-SllAe0YT.d.ts +46 -0
- package/lib/html.d.ts +1 -1
- package/lib/{index-m12zcmph.d.ts → index-Bb7YJKCq.d.ts} +3 -3
- package/lib/{index-Kqou8Fjh.d.ts → index-BvFh1Gfx.d.ts} +2 -2
- package/lib/index-C850MeBA.d.ts +94 -0
- package/lib/{index-DtEoak1i.d.ts → index-CTy4N7ng.d.ts} +2 -2
- package/lib/index.d.ts +4 -4
- package/lib/ip-restriction.d.ts +2 -2
- package/lib/jsx/dom/client.d.ts +30 -0
- package/lib/jsx/dom/client.js +49 -0
- package/lib/jsx/dom/css.d.ts +84 -0
- package/lib/jsx/dom/css.js +2 -0
- package/lib/jsx/dom/jsx-dev-runtime.d.ts +3 -0
- package/lib/jsx/dom/jsx-dev-runtime.js +2 -0
- package/lib/jsx/dom/jsx-runtime.d.ts +3 -0
- package/lib/jsx/dom/jsx-runtime.js +2 -0
- package/lib/jsx/dom/server.d.ts +105 -0
- package/lib/jsx/dom/server.js +37 -0
- package/lib/jsx/dom.d.ts +5 -0
- package/lib/jsx/dom.js +74 -0
- package/lib/jsx/jsx-dev-runtime.d.ts +6 -0
- package/lib/jsx/jsx-dev-runtime.js +14 -0
- package/lib/jsx/jsx-runtime.d.ts +10 -0
- package/lib/jsx/jsx-runtime.js +30 -0
- package/lib/jsx/streaming.d.ts +2 -0
- package/lib/jsx/streaming.js +2 -0
- package/lib/jsx-dev-runtime-B22O-Npk.d.ts +7 -0
- package/lib/jsx-dev-runtime-D18Y35TI.js +354 -0
- package/lib/jsx-renderer.d.ts +75 -0
- package/lib/jsx-renderer.js +99 -0
- package/lib/jsx-runtime-BVVgDSdq.d.ts +1 -0
- package/lib/jsx.d.ts +3 -0
- package/lib/jsx.js +47 -0
- package/lib/jwk.d.ts +4 -4
- package/lib/{jwt-BA65QhnJ.d.ts → jwt-BARhotDz.d.ts} +1 -1
- package/lib/jwt.d.ts +4 -4
- package/lib/language.d.ts +1 -1
- package/lib/logger.d.ts +1 -1
- package/lib/loopback-only.d.ts +1 -1
- package/lib/method-not-allowed.d.ts +2 -2
- package/lib/method-override.d.ts +2 -2
- package/lib/mount.d.ts +1 -1
- package/lib/node-server/conninfo.d.ts +1 -1
- package/lib/node-server/serve-static.d.ts +1 -1
- package/lib/node-server/serve-static.js +1 -1
- package/lib/node-server.d.ts +1 -1
- package/lib/node-server.js +1 -1
- package/lib/powered-by.d.ts +1 -1
- package/lib/pretty-json.d.ts +1 -1
- package/lib/proxy.d.ts +1 -1
- package/lib/quick.d.ts +1 -1
- package/lib/request-id.d.ts +1 -1
- package/lib/request.d.ts +1 -1
- package/lib/route.d.ts +1 -1
- package/lib/schema-validator.d.ts +1 -1
- package/lib/secure-headers.d.ts +1 -1
- package/lib/{serve-static-Dw_m6KxR.js → serve-static-B14MF1Va.js} +2 -0
- package/lib/serve-static.d.ts +1 -1
- package/lib/ssg-BwjcA-Ge.js +389 -0
- package/lib/ssg.d.ts +156 -0
- package/lib/ssg.js +2 -0
- package/lib/streaming.d.ts +1 -1
- package/lib/testing.d.ts +4 -4
- package/lib/testing.js +1 -1
- package/lib/timeout.d.ts +1 -1
- package/lib/timing.d.ts +1 -1
- package/lib/tiny.d.ts +1 -1
- package/lib/trailing-slash.d.ts +1 -1
- package/lib/{types-ZM9gIiKh.d.ts → types-Dv_nV2cv.d.ts} +1 -1
- package/lib/{types-D9DEXMjE.d.ts → types-Lqx5BxQF.d.ts} +8 -1
- package/lib/{types-Bd29gh2o.d.ts → types-zNxyEpG2.d.ts} +3 -3
- package/lib/types.d.ts +1 -1
- package/lib/utils/body.d.ts +1 -1
- package/lib/utils/cookie.d.ts +1 -1
- package/lib/utils/crypto.d.ts +1 -1
- package/lib/utils/html.d.ts +1 -45
- package/lib/utils/ipaddr.d.ts +1 -1
- package/lib/utils/jwt.d.ts +1 -1
- package/lib/utils/types.d.ts +2 -2
- package/lib/utils-Cx61GFMC.js +125 -0
- package/lib/validator.d.ts +2 -2
- package/lib/ws.d.ts +1 -1
- package/package.json +53 -1
- package/plugins/acryl-inspect/upstream.json +1 -1
- package/plugins/acryl-node-server/upstream.json +1 -1
- package/plugins/acryl-router/src/core/helper/css/common.ts +337 -0
- package/plugins/acryl-router/src/core/helper/css/index.ts +262 -0
- package/plugins/acryl-router/src/core/helper/ssg/index.ts +14 -0
- package/plugins/acryl-router/src/core/helper/ssg/middleware.ts +83 -0
- package/plugins/acryl-router/src/core/helper/ssg/plugins.ts +72 -0
- package/plugins/acryl-router/src/core/helper/ssg/ssg.ts +471 -0
- package/plugins/acryl-router/src/core/helper/ssg/utils.ts +118 -0
- package/plugins/acryl-router/src/core/jsx/base.ts +490 -0
- package/plugins/acryl-router/src/core/jsx/children.ts +20 -0
- package/plugins/acryl-router/src/core/jsx/components.ts +257 -0
- package/plugins/acryl-router/src/core/jsx/constants.ts +6 -0
- package/plugins/acryl-router/src/core/jsx/context.ts +266 -0
- package/plugins/acryl-router/src/core/jsx/dom/client.ts +89 -0
- package/plugins/acryl-router/src/core/jsx/dom/components.ts +39 -0
- package/plugins/acryl-router/src/core/jsx/dom/context.ts +52 -0
- package/plugins/acryl-router/src/core/jsx/dom/css.ts +263 -0
- package/plugins/acryl-router/src/core/jsx/dom/hooks/index.ts +91 -0
- package/plugins/acryl-router/src/core/jsx/dom/index.ts +170 -0
- package/plugins/acryl-router/src/core/jsx/dom/intrinsic-element/components.ts +438 -0
- package/plugins/acryl-router/src/core/jsx/dom/jsx-dev-runtime.ts +23 -0
- package/plugins/acryl-router/src/core/jsx/dom/jsx-runtime.ts +8 -0
- package/plugins/acryl-router/src/core/jsx/dom/render.ts +879 -0
- package/plugins/acryl-router/src/core/jsx/dom/server.ts +76 -0
- package/plugins/acryl-router/src/core/jsx/dom/utils.ts +7 -0
- package/plugins/acryl-router/src/core/jsx/hooks/index.ts +437 -0
- package/plugins/acryl-router/src/core/jsx/index.ts +115 -0
- package/plugins/acryl-router/src/core/jsx/intrinsic-element/common.ts +23 -0
- package/plugins/acryl-router/src/core/jsx/intrinsic-element/components.ts +210 -0
- package/plugins/acryl-router/src/core/jsx/intrinsic-elements.ts +938 -0
- package/plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts +26 -0
- package/plugins/acryl-router/src/core/jsx/jsx-runtime.ts +51 -0
- package/plugins/acryl-router/src/core/jsx/streaming.ts +231 -0
- package/plugins/acryl-router/src/core/jsx/types.ts +41 -0
- package/plugins/acryl-router/src/core/jsx/utils.ts +202 -0
- package/plugins/acryl-router/src/core/middleware/cache/index.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/jsx-renderer/index.ts +162 -0
- package/plugins/acryl-router/src/core/utils/types.ts +6 -0
- package/plugins/acryl-router/src/helpers/index.ts +2 -0
- package/plugins/acryl-router/src/middleware/index.ts +1 -0
- package/plugins/acryl-router/upstream.json +3 -3
- package/plugins/acryl-router-http/upstream.json +1 -1
- package/plugins/acryl-state/upstream.json +1 -1
- package/plugins/desktop/upstream.json +1 -1
- package/plugins/desktop-web/upstream.json +1 -1
- package/plugins/extensions/resolve.ts +4 -0
- package/plugins/save/plugin.json +1 -1
- package/shared/AGENTS.core.md +4 -0
- package/templates/agent/tsconfig.json +7 -1
- package/templates/todo/upstream.json +1 -1
- package/plugins/acryl-inspect/tests/report.spec.ts +0 -69
- package/plugins/acryl-inspect/tests/service.spec.ts +0 -121
- package/plugins/acryl-node-server/tests/adapter/app.ts +0 -76
- package/plugins/acryl-node-server/tests/adapter/assets/.static/plain.txt +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/favicon.ico +0 -0
- package/plugins/acryl-node-server/tests/adapter/assets/secret.txt +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static/admin/secret.txt +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static/data.json +0 -5
- package/plugins/acryl-node-server/tests/adapter/assets/static/extensionless +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static/foo..bar.txt +0 -0
- package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static/plain.txt +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static-with-context-path/plain.txt +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin.br +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.br +0 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.zst +0 -1
- package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +0 -34
- package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +0 -248
- package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +0 -457
- package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-cert.pem +0 -23
- package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-key.pem +0 -27
- package/plugins/acryl-node-server/tests/adapter/headers.test.ts +0 -252
- package/plugins/acryl-node-server/tests/adapter/helpers/request.ts +0 -190
- package/plugins/acryl-node-server/tests/adapter/listener.test.ts +0 -727
- package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +0 -189
- package/plugins/acryl-node-server/tests/adapter/request.test.ts +0 -1230
- package/plugins/acryl-node-server/tests/adapter/response.test.ts +0 -285
- package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +0 -849
- package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +0 -790
- package/plugins/acryl-node-server/tests/adapter/server.test.ts +0 -1312
- package/plugins/acryl-node-server/tests/adapter/setup.ts +0 -16
- package/plugins/acryl-node-server/tests/adapter/url.test.ts +0 -76
- package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +0 -23
- package/plugins/acryl-node-server/tests/adapter/utils/stream.test.ts +0 -75
- package/plugins/acryl-node-server/tests/adapter/utils.test.ts +0 -235
- package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +0 -260
- package/plugins/acryl-node-server/tests/server.spec.ts +0 -141
- package/plugins/acryl-router/src/core/app.test.ts +0 -3833
- package/plugins/acryl-router/src/core/client/client.test.ts +0 -2313
- package/plugins/acryl-router/src/core/client/types.test.ts +0 -149
- package/plugins/acryl-router/src/core/client/utils.test.ts +0 -405
- package/plugins/acryl-router/src/core/compose.test.ts +0 -751
- package/plugins/acryl-router/src/core/context.test.ts +0 -629
- package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +0 -344
- package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +0 -55
- package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +0 -510
- package/plugins/acryl-router/src/core/helper/dev/index.test.ts +0 -181
- package/plugins/acryl-router/src/core/helper/factory/index.test.ts +0 -434
- package/plugins/acryl-router/src/core/helper/html/index.test.ts +0 -78
- package/plugins/acryl-router/src/core/helper/proxy/index.test.ts +0 -356
- package/plugins/acryl-router/src/core/helper/route/index.test.ts +0 -259
- package/plugins/acryl-router/src/core/helper/streaming/stream.test.ts +0 -128
- package/plugins/acryl-router/src/core/helper/streaming/text.test.ts +0 -34
- package/plugins/acryl-router/src/core/helper/testing/index.test.ts +0 -42
- package/plugins/acryl-router/src/core/helper/websocket/index.test.ts +0 -124
- package/plugins/acryl-router/src/core/http-exception.test.ts +0 -45
- package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +0 -434
- package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +0 -1018
- package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +0 -273
- package/plugins/acryl-router/src/core/middleware/cache/index.test.ts +0 -1211
- package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +0 -355
- package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +0 -535
- package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +0 -43
- package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +0 -532
- package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +0 -534
- package/plugins/acryl-router/src/core/middleware/etag/digest.test.ts +0 -21
- package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +0 -503
- package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +0 -217
- package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +0 -1135
- package/plugins/acryl-router/src/core/middleware/jwk/keys.test.json +0 -48
- package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +0 -802
- package/plugins/acryl-router/src/core/middleware/language/index.test.ts +0 -552
- package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +0 -204
- package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +0 -292
- package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +0 -221
- package/plugins/acryl-router/src/core/middleware/mount/index.test.ts +0 -334
- package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +0 -37
- package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +0 -218
- package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +0 -168
- package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +0 -671
- package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +0 -450
- package/plugins/acryl-router/src/core/middleware/serve-static/path.test.ts +0 -50
- package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +0 -70
- package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +0 -310
- package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +0 -381
- package/plugins/acryl-router/src/core/preset/quick.test.ts +0 -42
- package/plugins/acryl-router/src/core/preset/tiny.test.ts +0 -42
- package/plugins/acryl-router/src/core/request.test.ts +0 -751
- package/plugins/acryl-router/src/core/router/common.case.test.ts +0 -1132
- package/plugins/acryl-router/src/core/router/linear-router/router.test.ts +0 -80
- package/plugins/acryl-router/src/core/router/pattern-router/router.test.ts +0 -46
- package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.test.ts +0 -154
- package/plugins/acryl-router/src/core/router/reg-exp-router/router.test.ts +0 -265
- package/plugins/acryl-router/src/core/router/smart-router/router.test.ts +0 -13
- package/plugins/acryl-router/src/core/router/trie-router/node.test.ts +0 -896
- package/plugins/acryl-router/src/core/router/trie-router/router.test.ts +0 -8
- package/plugins/acryl-router/src/core/types.test.ts +0 -4134
- package/plugins/acryl-router/src/core/utils/accept.test.ts +0 -299
- package/plugins/acryl-router/src/core/utils/basic-auth.test.ts +0 -56
- package/plugins/acryl-router/src/core/utils/body.test.ts +0 -496
- package/plugins/acryl-router/src/core/utils/buffer.test.ts +0 -147
- package/plugins/acryl-router/src/core/utils/color.test.ts +0 -23
- package/plugins/acryl-router/src/core/utils/concurrent.test.ts +0 -69
- package/plugins/acryl-router/src/core/utils/cookie.test.ts +0 -460
- package/plugins/acryl-router/src/core/utils/crypto.test.ts +0 -43
- package/plugins/acryl-router/src/core/utils/encode.test.ts +0 -61
- package/plugins/acryl-router/src/core/utils/filepath.test.ts +0 -78
- package/plugins/acryl-router/src/core/utils/html.test.ts +0 -16
- package/plugins/acryl-router/src/core/utils/ipaddr.test.ts +0 -149
- package/plugins/acryl-router/src/core/utils/jwt/jwa.test.ts +0 -86
- package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +0 -1788
- package/plugins/acryl-router/src/core/utils/mime.test.ts +0 -64
- package/plugins/acryl-router/src/core/utils/stream.test.ts +0 -212
- package/plugins/acryl-router/src/core/utils/types.test.ts +0 -295
- package/plugins/acryl-router/src/core/utils/url.test.ts +0 -384
- package/plugins/acryl-router/src/core/validator/utils.test.ts +0 -82
- package/plugins/acryl-router/src/core/validator/validator.test.ts +0 -1488
- package/plugins/acryl-router/tests/docs-examples.spec.ts +0 -152
- package/plugins/acryl-router/tests/live-install.spec.ts +0 -64
- package/plugins/acryl-router/tests/loader.spec.ts +0 -72
- package/plugins/acryl-router/tests/loopback-only.spec.ts +0 -80
- package/plugins/acryl-router/tests/no-dom/consumer.ts +0 -11
- package/plugins/acryl-router/tests/no-dom/tsconfig.json +0 -13
- package/plugins/acryl-router/tests/service.spec.ts +0 -426
- package/plugins/acryl-router/tests/shadow-state.spec.ts +0 -79
- package/plugins/acryl-router-http/tests/adapter.spec.ts +0 -174
- package/plugins/acryl-router-http/tests/stream.spec.ts +0 -133
- package/plugins/acryl-router-http/tests/surfaces.spec.ts +0 -101
- package/plugins/acryl-state/src/react.ts +0 -11
- package/plugins/acryl-state/tests/cell.spec.ts +0 -71
- package/plugins/acryl-state/tests/react.spec.ts +0 -39
- package/plugins/acryl-state/tests/service.spec.ts +0 -132
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* This module provides APIs for `acryl-router/jsx/server`, which is compatible with `react-dom/server`.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { HtmlEscapedString } from '../../utils/html.ts'
|
|
7
|
+
import { renderChildren } from '../base.ts'
|
|
8
|
+
import type { Child } from '../base.ts'
|
|
9
|
+
import { renderToReadableStream as renderToReadableStreamAcryl } from '../streaming.ts'
|
|
10
|
+
import version from './index.ts'
|
|
11
|
+
|
|
12
|
+
export interface RenderToStringOptions {
|
|
13
|
+
identifierPrefix?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const prepareRoot = (element: Child): Child =>
|
|
17
|
+
typeof element === 'string' || Array.isArray(element) ? renderChildren([element]) : element
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Render JSX element to string.
|
|
21
|
+
* @param element JSX element to render.
|
|
22
|
+
* @param options Options for rendering.
|
|
23
|
+
* @returns Rendered string.
|
|
24
|
+
*/
|
|
25
|
+
const renderToString = (element: Child, options: RenderToStringOptions = {}): string => {
|
|
26
|
+
if (Object.keys(options).length > 0) {
|
|
27
|
+
console.warn('options are not supported yet')
|
|
28
|
+
}
|
|
29
|
+
element = prepareRoot(element)
|
|
30
|
+
const res = element instanceof Promise ? element : (element?.toString() ?? '')
|
|
31
|
+
if (typeof res !== 'string') {
|
|
32
|
+
throw new Error('Async component is not supported in renderToString')
|
|
33
|
+
}
|
|
34
|
+
return res
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface RenderToReadableStreamOptions {
|
|
38
|
+
identifierPrefix?: string
|
|
39
|
+
namespaceURI?: string
|
|
40
|
+
nonce?: string
|
|
41
|
+
bootstrapScriptContent?: string
|
|
42
|
+
bootstrapScripts?: string[]
|
|
43
|
+
bootstrapModules?: string[]
|
|
44
|
+
progressiveChunkSize?: number
|
|
45
|
+
signal?: AbortSignal
|
|
46
|
+
onError?: (error: unknown) => string | void
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Render JSX element to readable stream.
|
|
51
|
+
* @param element JSX element to render.
|
|
52
|
+
* @param options Options for rendering.
|
|
53
|
+
* @returns Rendered readable stream.
|
|
54
|
+
*/
|
|
55
|
+
const renderToReadableStream = async (
|
|
56
|
+
element: Child,
|
|
57
|
+
options: RenderToReadableStreamOptions = {}
|
|
58
|
+
): Promise<ReadableStream<Uint8Array>> => {
|
|
59
|
+
if (Object.keys(options).some((key) => key !== 'onError')) {
|
|
60
|
+
console.warn('options are not supported yet, except onError')
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
element = prepareRoot(element)
|
|
64
|
+
if (!element || typeof element !== 'object') {
|
|
65
|
+
element = element?.toString() ?? ''
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return renderToReadableStreamAcryl(element as HtmlEscapedString, options.onError)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { renderToString, renderToReadableStream, version }
|
|
72
|
+
export default {
|
|
73
|
+
renderToString,
|
|
74
|
+
renderToReadableStream,
|
|
75
|
+
version,
|
|
76
|
+
}
|
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import type { JSX } from '../base.ts'
|
|
2
|
+
import { DOM_STASH } from '../constants.ts'
|
|
3
|
+
import { buildDataStack, update } from '../dom/render.ts'
|
|
4
|
+
import type { Context, Node, NodeObject, PendingType, UpdateHook } from '../dom/render.ts'
|
|
5
|
+
|
|
6
|
+
type UpdateStateFunction<T> = (newState: T | ((currentState: T) => T)) => void
|
|
7
|
+
|
|
8
|
+
const STASH_SATE = 0
|
|
9
|
+
export const STASH_EFFECT = 1
|
|
10
|
+
const STASH_CALLBACK = 2
|
|
11
|
+
const STASH_MEMO = 3
|
|
12
|
+
const STASH_REF = 4
|
|
13
|
+
|
|
14
|
+
export type EffectData = [
|
|
15
|
+
readonly unknown[] | undefined, // deps
|
|
16
|
+
(() => void | (() => void)) | undefined, // layout effect
|
|
17
|
+
(() => void) | undefined, // cleanup
|
|
18
|
+
(() => void) | undefined, // effect
|
|
19
|
+
(() => void) | undefined, // insertion effect
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
const resolvedPromiseValueMap: WeakMap<Promise<unknown>, unknown> = new WeakMap<
|
|
23
|
+
Promise<unknown>,
|
|
24
|
+
unknown
|
|
25
|
+
>()
|
|
26
|
+
|
|
27
|
+
const isDepsChanged = (
|
|
28
|
+
prevDeps: readonly unknown[] | undefined,
|
|
29
|
+
deps: readonly unknown[] | undefined
|
|
30
|
+
): boolean =>
|
|
31
|
+
!prevDeps ||
|
|
32
|
+
!deps ||
|
|
33
|
+
prevDeps.length !== deps.length ||
|
|
34
|
+
deps.some((dep, i) => dep !== prevDeps[i])
|
|
35
|
+
|
|
36
|
+
let viewTransitionState:
|
|
37
|
+
| [
|
|
38
|
+
boolean, // isUpdating
|
|
39
|
+
boolean, // useViewTransition() is called
|
|
40
|
+
]
|
|
41
|
+
| undefined = undefined
|
|
42
|
+
|
|
43
|
+
const documentStartViewTransition: (cb: () => void) => { finished: Promise<void> } = (cb) => {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
if ((document as any)?.startViewTransition) {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
|
+
return (document as any).startViewTransition(cb)
|
|
48
|
+
} else {
|
|
49
|
+
cb()
|
|
50
|
+
return { finished: Promise.resolve() }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let updateHook: UpdateHook | undefined = undefined
|
|
55
|
+
const viewTransitionHook = (
|
|
56
|
+
context: Context,
|
|
57
|
+
node: Node,
|
|
58
|
+
cb: (context: Context) => void
|
|
59
|
+
): Promise<void> => {
|
|
60
|
+
const state: [boolean, boolean] = [true, false]
|
|
61
|
+
let lastVC = node.vC
|
|
62
|
+
return documentStartViewTransition(() => {
|
|
63
|
+
if (lastVC === node.vC) {
|
|
64
|
+
viewTransitionState = state
|
|
65
|
+
cb(context)
|
|
66
|
+
viewTransitionState = undefined
|
|
67
|
+
lastVC = node.vC
|
|
68
|
+
}
|
|
69
|
+
}).finished.then(() => {
|
|
70
|
+
if (state[1] && lastVC === node.vC) {
|
|
71
|
+
state[0] = false
|
|
72
|
+
viewTransitionState = state
|
|
73
|
+
cb(context)
|
|
74
|
+
viewTransitionState = undefined
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const startViewTransition = (callback: () => void): void => {
|
|
80
|
+
updateHook = viewTransitionHook
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
callback()
|
|
84
|
+
} finally {
|
|
85
|
+
updateHook = undefined
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const useViewTransition = (): [boolean, (callback: () => void) => void] => {
|
|
90
|
+
const buildData = buildDataStack.at(-1) as [Context, NodeObject]
|
|
91
|
+
if (!buildData) {
|
|
92
|
+
return [false, () => {}]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (viewTransitionState) {
|
|
96
|
+
viewTransitionState[1] = true
|
|
97
|
+
}
|
|
98
|
+
return [!!viewTransitionState?.[0], startViewTransition]
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// PendingType is defined in "../dom/render", 3 is used for useDeferredValue
|
|
102
|
+
const pendingStack: [PendingType | 3, Promise<void>][] = []
|
|
103
|
+
const runCallback = (type: PendingType, callback: Function): void => {
|
|
104
|
+
let resolve: (() => void) | undefined
|
|
105
|
+
const promise = new Promise<void>((r) => (resolve = r))
|
|
106
|
+
pendingStack.push([type, promise])
|
|
107
|
+
try {
|
|
108
|
+
const res = callback()
|
|
109
|
+
if (res instanceof Promise) {
|
|
110
|
+
res.then(resolve, resolve)
|
|
111
|
+
} else {
|
|
112
|
+
resolve!()
|
|
113
|
+
}
|
|
114
|
+
} finally {
|
|
115
|
+
pendingStack.pop()
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const startTransition = (callback: () => void): void => {
|
|
120
|
+
runCallback(1, callback)
|
|
121
|
+
}
|
|
122
|
+
const startTransitionHook = (callback: () => void | Promise<void>): void => {
|
|
123
|
+
runCallback(2, callback)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export const useTransition = (): [boolean, (callback: () => void | Promise<void>) => void] => {
|
|
127
|
+
const buildData = buildDataStack.at(-1) as [Context, NodeObject]
|
|
128
|
+
if (!buildData) {
|
|
129
|
+
return [false, () => {}]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const [error, setError] = useState<[Error]>()
|
|
133
|
+
const [state, updateState] = useState<boolean>()
|
|
134
|
+
if (error) {
|
|
135
|
+
throw error[0]
|
|
136
|
+
}
|
|
137
|
+
const startTransitionLocalHook = useCallback<typeof startTransitionHook>(
|
|
138
|
+
(callback) => {
|
|
139
|
+
startTransitionHook(() => {
|
|
140
|
+
updateState((state) => !state)
|
|
141
|
+
let res = callback()
|
|
142
|
+
if (res instanceof Promise) {
|
|
143
|
+
res = res.catch((e) => {
|
|
144
|
+
setError([e])
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
return res
|
|
148
|
+
})
|
|
149
|
+
},
|
|
150
|
+
[state]
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
const [context] = buildData
|
|
154
|
+
return [context[0] === 2, startTransitionLocalHook]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
type UseDeferredValue = <T>(value: T, initialValue?: T) => T
|
|
158
|
+
export const useDeferredValue: UseDeferredValue = <T>(value: T, ...rest: [T | undefined]): T => {
|
|
159
|
+
const [values, setValues] = useState<[T, T]>(
|
|
160
|
+
(rest.length ? [rest[0], rest[0]] : [value, value]) as [T, T]
|
|
161
|
+
)
|
|
162
|
+
if (Object.is(values[1], value)) {
|
|
163
|
+
return values[1]
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
pendingStack.push([3, Promise.resolve()])
|
|
167
|
+
updateHook = async (context: Context, _, cb: (context: Context) => void) => {
|
|
168
|
+
cb(context)
|
|
169
|
+
values[0] = value
|
|
170
|
+
}
|
|
171
|
+
setValues([values[0], value])
|
|
172
|
+
updateHook = undefined
|
|
173
|
+
pendingStack.pop()
|
|
174
|
+
|
|
175
|
+
return values[0]
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
type UseStateType = {
|
|
179
|
+
<T>(initialState: T | (() => T)): [T, UpdateStateFunction<T>]
|
|
180
|
+
<T = undefined>(): [T | undefined, UpdateStateFunction<T | undefined>]
|
|
181
|
+
}
|
|
182
|
+
export const useState: UseStateType = <T>(
|
|
183
|
+
initialState?: T | (() => T)
|
|
184
|
+
): [T, UpdateStateFunction<T>] => {
|
|
185
|
+
const resolveInitialState = () =>
|
|
186
|
+
typeof initialState === 'function' ? (initialState as () => T)() : (initialState as T)
|
|
187
|
+
|
|
188
|
+
const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
|
|
189
|
+
if (!buildData) {
|
|
190
|
+
return [resolveInitialState(), () => {}]
|
|
191
|
+
}
|
|
192
|
+
const [, node] = buildData
|
|
193
|
+
|
|
194
|
+
const stateArray = (node[DOM_STASH][1][STASH_SATE] ||= [])
|
|
195
|
+
const hookIndex = node[DOM_STASH][0]++
|
|
196
|
+
|
|
197
|
+
return (stateArray[hookIndex] ||= [
|
|
198
|
+
resolveInitialState(),
|
|
199
|
+
(newState: T | ((currentState: T) => T)) => {
|
|
200
|
+
const localUpdateHook = updateHook
|
|
201
|
+
const stateData = stateArray[hookIndex]
|
|
202
|
+
if (typeof newState === 'function') {
|
|
203
|
+
newState = (newState as (currentState: T) => T)(stateData[0])
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (!Object.is(newState, stateData[0])) {
|
|
207
|
+
stateData[0] = newState
|
|
208
|
+
if (pendingStack.length) {
|
|
209
|
+
const [pendingType, pendingPromise] = pendingStack.at(-1) as [
|
|
210
|
+
PendingType | 3,
|
|
211
|
+
Promise<void>,
|
|
212
|
+
]
|
|
213
|
+
Promise.all([
|
|
214
|
+
pendingType === 3
|
|
215
|
+
? node
|
|
216
|
+
: update([pendingType, false, localUpdateHook as UpdateHook], node),
|
|
217
|
+
pendingPromise,
|
|
218
|
+
]).then(([node]) => {
|
|
219
|
+
if (!node || !(pendingType === 2 || pendingType === 3)) {
|
|
220
|
+
return
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const lastVC = node.vC
|
|
224
|
+
|
|
225
|
+
const addUpdateTask = () => {
|
|
226
|
+
setTimeout(() => {
|
|
227
|
+
// return if `node` is rerendered after current transition
|
|
228
|
+
if (lastVC !== node.vC) {
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
update([pendingType === 3 ? 1 : 0, false, localUpdateHook as UpdateHook], node)
|
|
232
|
+
})
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
requestAnimationFrame(addUpdateTask)
|
|
236
|
+
})
|
|
237
|
+
} else {
|
|
238
|
+
update([0, false, localUpdateHook as UpdateHook], node)
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
])
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export const useReducer = <T, A>(
|
|
246
|
+
reducer: (state: T, action: A) => T,
|
|
247
|
+
initialArg: T,
|
|
248
|
+
init?: (initialState: T) => T
|
|
249
|
+
): [T, (action: A) => void] => {
|
|
250
|
+
const handler = useCallback(
|
|
251
|
+
(action: A) => {
|
|
252
|
+
setState((state) => reducer(state, action))
|
|
253
|
+
},
|
|
254
|
+
[reducer]
|
|
255
|
+
)
|
|
256
|
+
const [state, setState] = useState(() => (init ? init(initialArg) : initialArg))
|
|
257
|
+
return [state, handler]
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const useEffectCommon = (
|
|
261
|
+
index: number,
|
|
262
|
+
effect: () => void | (() => void),
|
|
263
|
+
deps?: readonly unknown[]
|
|
264
|
+
): void => {
|
|
265
|
+
const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
|
|
266
|
+
if (!buildData) {
|
|
267
|
+
return
|
|
268
|
+
}
|
|
269
|
+
const [, node] = buildData
|
|
270
|
+
|
|
271
|
+
const effectDepsArray = (node[DOM_STASH][1][STASH_EFFECT] ||= [])
|
|
272
|
+
const hookIndex = node[DOM_STASH][0]++
|
|
273
|
+
|
|
274
|
+
const [prevDeps, , prevCleanup] = (effectDepsArray[hookIndex] ||= [])
|
|
275
|
+
if (isDepsChanged(prevDeps, deps)) {
|
|
276
|
+
if (prevCleanup) {
|
|
277
|
+
prevCleanup()
|
|
278
|
+
}
|
|
279
|
+
const runner = () => {
|
|
280
|
+
data[index] = undefined // clear this effect in order to avoid calling effect twice
|
|
281
|
+
data[2] = effect() as (() => void) | undefined
|
|
282
|
+
}
|
|
283
|
+
const data: EffectData = [deps, undefined, undefined, undefined, undefined]
|
|
284
|
+
data[index] = runner
|
|
285
|
+
effectDepsArray[hookIndex] = data
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
export const useEffect = (effect: () => void | (() => void), deps?: readonly unknown[]): void =>
|
|
289
|
+
useEffectCommon(3, effect, deps)
|
|
290
|
+
export const useLayoutEffect = (
|
|
291
|
+
effect: () => void | (() => void),
|
|
292
|
+
deps?: readonly unknown[]
|
|
293
|
+
): void => useEffectCommon(1, effect, deps)
|
|
294
|
+
export const useInsertionEffect = (
|
|
295
|
+
effect: () => void | (() => void),
|
|
296
|
+
deps?: readonly unknown[]
|
|
297
|
+
): void => useEffectCommon(4, effect, deps)
|
|
298
|
+
|
|
299
|
+
export const useCallback = <T extends Function>(callback: T, deps: readonly unknown[]): T => {
|
|
300
|
+
const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
|
|
301
|
+
if (!buildData) {
|
|
302
|
+
return callback
|
|
303
|
+
}
|
|
304
|
+
const [, node] = buildData
|
|
305
|
+
|
|
306
|
+
const callbackArray = (node[DOM_STASH][1][STASH_CALLBACK] ||= [])
|
|
307
|
+
const hookIndex = node[DOM_STASH][0]++
|
|
308
|
+
|
|
309
|
+
const prevDeps = callbackArray[hookIndex]
|
|
310
|
+
if (isDepsChanged(prevDeps?.[1], deps)) {
|
|
311
|
+
callbackArray[hookIndex] = [callback, deps]
|
|
312
|
+
} else {
|
|
313
|
+
callback = callbackArray[hookIndex][0] as T
|
|
314
|
+
}
|
|
315
|
+
return callback
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export type RefObject<T> = { current: T }
|
|
319
|
+
|
|
320
|
+
export function useRef<T>(initialValue: T): RefObject<T>
|
|
321
|
+
export function useRef<T>(initialValue: T | null): RefObject<T | null>
|
|
322
|
+
export function useRef<T>(initialValue: T | undefined): RefObject<T | undefined>
|
|
323
|
+
export function useRef<T>(initialValue?: T | null): RefObject<T | null | undefined> {
|
|
324
|
+
const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
|
|
325
|
+
if (!buildData) {
|
|
326
|
+
return { current: initialValue } as RefObject<T | null | undefined>
|
|
327
|
+
}
|
|
328
|
+
const [, node] = buildData
|
|
329
|
+
|
|
330
|
+
const refArray = (node[DOM_STASH][1][STASH_REF] ||= [])
|
|
331
|
+
const hookIndex = node[DOM_STASH][0]++
|
|
332
|
+
|
|
333
|
+
return (refArray[hookIndex] ||= { current: initialValue })
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export const use = <T>(promise: Promise<T>): T => {
|
|
337
|
+
const cachedRes = resolvedPromiseValueMap.get(promise) as [T] | [undefined, unknown] | undefined
|
|
338
|
+
if (cachedRes) {
|
|
339
|
+
if (cachedRes.length === 2) {
|
|
340
|
+
throw cachedRes[1]
|
|
341
|
+
}
|
|
342
|
+
return cachedRes[0] as T
|
|
343
|
+
}
|
|
344
|
+
promise.then(
|
|
345
|
+
(res) => resolvedPromiseValueMap.set(promise, [res]),
|
|
346
|
+
(e) => resolvedPromiseValueMap.set(promise, [undefined, e])
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
throw promise
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export const useMemo = <T>(factory: () => T, deps: readonly unknown[]): T => {
|
|
353
|
+
const buildData = buildDataStack.at(-1) as [unknown, NodeObject]
|
|
354
|
+
if (!buildData) {
|
|
355
|
+
return factory()
|
|
356
|
+
}
|
|
357
|
+
const [, node] = buildData
|
|
358
|
+
|
|
359
|
+
const memoArray = (node[DOM_STASH][1][STASH_MEMO] ||= [])
|
|
360
|
+
const hookIndex = node[DOM_STASH][0]++
|
|
361
|
+
|
|
362
|
+
const prevDeps = memoArray[hookIndex]
|
|
363
|
+
if (isDepsChanged(prevDeps?.[1], deps)) {
|
|
364
|
+
memoArray[hookIndex] = [factory(), deps]
|
|
365
|
+
}
|
|
366
|
+
return memoArray[hookIndex][0] as T
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
let idCounter = 0
|
|
370
|
+
export const useId = (): string => useMemo(() => `:r${(idCounter++).toString(32)}:`, [])
|
|
371
|
+
|
|
372
|
+
// Define to avoid errors. This hook currently does nothing.
|
|
373
|
+
export const useDebugValue = (_value: unknown, _formatter?: (value: unknown) => string): void => {}
|
|
374
|
+
|
|
375
|
+
export const createRef = <T>(): RefObject<T | null> => {
|
|
376
|
+
return { current: null }
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export const forwardRef = <T, P = {}>(
|
|
380
|
+
Component: (props: P, ref?: RefObject<T | null>) => JSX.Element
|
|
381
|
+
): ((props: P & { ref?: RefObject<T | null> }) => JSX.Element) => {
|
|
382
|
+
return (props) => {
|
|
383
|
+
const { ref, ...rest } = props
|
|
384
|
+
return Component(rest as P, ref)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export const useImperativeHandle = <T>(
|
|
389
|
+
ref: RefObject<T | null>,
|
|
390
|
+
createHandle: () => T,
|
|
391
|
+
deps: readonly unknown[]
|
|
392
|
+
): void => {
|
|
393
|
+
useEffect(() => {
|
|
394
|
+
ref.current = createHandle()
|
|
395
|
+
return () => {
|
|
396
|
+
ref.current = null
|
|
397
|
+
}
|
|
398
|
+
}, deps)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
export const useSyncExternalStore = <T>(
|
|
402
|
+
subscribe: (callback: () => void) => () => void,
|
|
403
|
+
getSnapshot: () => T,
|
|
404
|
+
getServerSnapshot?: () => T
|
|
405
|
+
): T => {
|
|
406
|
+
const buildData = buildDataStack.at(-1) as [Context, unknown]
|
|
407
|
+
if (!buildData) {
|
|
408
|
+
// now a stringify process, maybe in server side
|
|
409
|
+
if (!getServerSnapshot) {
|
|
410
|
+
throw new Error('getServerSnapshot is required for server side rendering')
|
|
411
|
+
}
|
|
412
|
+
return getServerSnapshot()
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const snapshot =
|
|
416
|
+
buildData[0][4] && getServerSnapshot ? (getServerSnapshot as () => T)() : getSnapshot()
|
|
417
|
+
const [, setVersion] = useState(0)
|
|
418
|
+
const latestSnapshot = useRef<[T, () => T]>([snapshot, getSnapshot])
|
|
419
|
+
latestSnapshot.current = [snapshot, getSnapshot]
|
|
420
|
+
const unsubscribeRef = useRef<() => void>(null)
|
|
421
|
+
|
|
422
|
+
// Swap subscriptions at effect flush: a returned cleanup would run synchronously
|
|
423
|
+
// during render when `subscribe` changes, leaving a window with no subscription.
|
|
424
|
+
useEffect(() => {
|
|
425
|
+
const update = () => setVersion((version) => version + 1)
|
|
426
|
+
unsubscribeRef.current?.()
|
|
427
|
+
unsubscribeRef.current = subscribe(update)
|
|
428
|
+
const [snapshot, getSnapshot] = latestSnapshot.current!
|
|
429
|
+
if (!Object.is(snapshot, getSnapshot())) {
|
|
430
|
+
update()
|
|
431
|
+
}
|
|
432
|
+
}, [subscribe])
|
|
433
|
+
|
|
434
|
+
useEffect(() => () => unsubscribeRef.current?.(), [])
|
|
435
|
+
|
|
436
|
+
return snapshot
|
|
437
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* JSX for Acryl.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Fragment, cloneElement, isValidElement, jsx, memo, reactAPICompatVersion } from './base.ts'
|
|
7
|
+
import type { DOMAttributes } from './base.ts'
|
|
8
|
+
import { Children } from './children.ts'
|
|
9
|
+
import { ErrorBoundary } from './components.ts'
|
|
10
|
+
import { createContext, useContext } from './context.ts'
|
|
11
|
+
import { useActionState, useOptimistic } from './dom/hooks/index.ts'
|
|
12
|
+
import {
|
|
13
|
+
createRef,
|
|
14
|
+
forwardRef,
|
|
15
|
+
startTransition,
|
|
16
|
+
startViewTransition,
|
|
17
|
+
use,
|
|
18
|
+
useCallback,
|
|
19
|
+
useDebugValue,
|
|
20
|
+
useDeferredValue,
|
|
21
|
+
useEffect,
|
|
22
|
+
useId,
|
|
23
|
+
useImperativeHandle,
|
|
24
|
+
useInsertionEffect,
|
|
25
|
+
useLayoutEffect,
|
|
26
|
+
useMemo,
|
|
27
|
+
useReducer,
|
|
28
|
+
useRef,
|
|
29
|
+
useState,
|
|
30
|
+
useSyncExternalStore,
|
|
31
|
+
useTransition,
|
|
32
|
+
useViewTransition,
|
|
33
|
+
} from './hooks/index.ts'
|
|
34
|
+
import { Suspense } from './streaming.ts'
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
reactAPICompatVersion as version,
|
|
38
|
+
jsx,
|
|
39
|
+
memo,
|
|
40
|
+
Fragment,
|
|
41
|
+
Fragment as StrictMode,
|
|
42
|
+
isValidElement,
|
|
43
|
+
jsx as createElement,
|
|
44
|
+
cloneElement,
|
|
45
|
+
ErrorBoundary,
|
|
46
|
+
createContext,
|
|
47
|
+
useContext,
|
|
48
|
+
useState,
|
|
49
|
+
useEffect,
|
|
50
|
+
useRef,
|
|
51
|
+
useCallback,
|
|
52
|
+
useReducer,
|
|
53
|
+
useId,
|
|
54
|
+
useDebugValue,
|
|
55
|
+
use,
|
|
56
|
+
startTransition,
|
|
57
|
+
useTransition,
|
|
58
|
+
useDeferredValue,
|
|
59
|
+
startViewTransition,
|
|
60
|
+
useViewTransition,
|
|
61
|
+
useMemo,
|
|
62
|
+
useLayoutEffect,
|
|
63
|
+
useInsertionEffect,
|
|
64
|
+
createRef,
|
|
65
|
+
forwardRef,
|
|
66
|
+
useImperativeHandle,
|
|
67
|
+
useSyncExternalStore,
|
|
68
|
+
useActionState,
|
|
69
|
+
useOptimistic,
|
|
70
|
+
Suspense,
|
|
71
|
+
Children,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export type { DOMAttributes }
|
|
75
|
+
|
|
76
|
+
export default {
|
|
77
|
+
version: reactAPICompatVersion,
|
|
78
|
+
memo,
|
|
79
|
+
Fragment,
|
|
80
|
+
StrictMode: Fragment,
|
|
81
|
+
isValidElement,
|
|
82
|
+
createElement: jsx,
|
|
83
|
+
cloneElement,
|
|
84
|
+
ErrorBoundary,
|
|
85
|
+
createContext,
|
|
86
|
+
useContext,
|
|
87
|
+
useState,
|
|
88
|
+
useEffect,
|
|
89
|
+
useRef,
|
|
90
|
+
useCallback,
|
|
91
|
+
useReducer,
|
|
92
|
+
useId,
|
|
93
|
+
useDebugValue,
|
|
94
|
+
use,
|
|
95
|
+
startTransition,
|
|
96
|
+
useTransition,
|
|
97
|
+
useDeferredValue,
|
|
98
|
+
startViewTransition,
|
|
99
|
+
useViewTransition,
|
|
100
|
+
useMemo,
|
|
101
|
+
useLayoutEffect,
|
|
102
|
+
useInsertionEffect,
|
|
103
|
+
createRef,
|
|
104
|
+
forwardRef,
|
|
105
|
+
useImperativeHandle,
|
|
106
|
+
useSyncExternalStore,
|
|
107
|
+
useActionState,
|
|
108
|
+
useOptimistic,
|
|
109
|
+
Suspense,
|
|
110
|
+
Children,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type * from './types.ts'
|
|
114
|
+
|
|
115
|
+
export type { JSX } from './intrinsic-elements.ts'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Props } from '../base.ts'
|
|
2
|
+
|
|
3
|
+
export const deDupeKeyMap: Record<string, string[]> = {
|
|
4
|
+
title: [],
|
|
5
|
+
script: ['src'],
|
|
6
|
+
style: ['data-href'],
|
|
7
|
+
link: ['href'],
|
|
8
|
+
meta: ['name', 'httpEquiv', 'charset', 'itemProp'],
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const domRenderers: Record<string, Function> = {}
|
|
12
|
+
|
|
13
|
+
export const dataPrecedenceAttr = 'data-precedence'
|
|
14
|
+
|
|
15
|
+
export const isStylesheetLinkWithPrecedence = (props: Props): boolean =>
|
|
16
|
+
props.rel === 'stylesheet' && 'precedence' in props
|
|
17
|
+
|
|
18
|
+
export const shouldDeDupeByKey = (tagName: string, supportSort: boolean): boolean => {
|
|
19
|
+
if (tagName === 'link') {
|
|
20
|
+
return supportSort
|
|
21
|
+
}
|
|
22
|
+
return deDupeKeyMap[tagName].length > 0
|
|
23
|
+
}
|