acrylblends 0.6.1 → 0.6.3
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 +11 -6
- package/docs/framework/README.md +3 -2
- package/docs/framework/UPSTREAM.md +1 -1
- package/docs/framework/api/presets.md +0 -3
- package/docs/framework/cordis/acryl-in-a-cordis-app.md +9 -0
- package/docs/framework/getting-started/basic.md +5 -4
- package/docs/framework/getting-started/desktop.md +41 -0
- package/docs/framework/guides/jsx-dom.md +0 -3
- package/docs/framework/guides/jsx.md +1 -4
- package/docs/framework/guides/middleware.md +1 -1
- package/docs/framework/helpers/cookie.md +1 -1
- package/docs/framework/helpers/css.md +0 -3
- package/docs/framework/helpers/dev.md +0 -3
- package/docs/framework/helpers/jwt.md +1 -1
- package/docs/framework/helpers/proxy.md +0 -3
- package/docs/framework/middleware/builtin/basic-auth.md +6 -6
- package/docs/framework/middleware/builtin/cache.md +0 -3
- package/docs/framework/middleware/builtin/combine.md +1 -1
- package/docs/framework/middleware/builtin/ip-restriction.md +1 -1
- package/docs/framework/middleware/builtin/logger.md +1 -1
- package/docs/framework/middleware/builtin/mount.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-CmAYW1Al.d.ts → app-wFwpg-bt.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 +43 -0
- package/lib/cache.js +169 -0
- package/lib/client.d.ts +2 -2
- package/lib/combine.d.ts +1 -1
- package/lib/common-D8Z4JRCw.d.ts +46 -0
- package/lib/components-Ce5FRyHU.js +268 -0
- package/lib/components-DYZdxJIJ.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-Bm7rI-oK.d.ts → context-DVQBjuns.d.ts} +1 -1
- package/lib/context-DxFdY_un.d.ts +250 -0
- package/lib/context-storage.d.ts +1 -1
- package/lib/{cookie-ClMaKDQf.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 +19 -0
- package/lib/dev.js +50 -0
- package/lib/etag.d.ts +1 -1
- package/lib/factory.d.ts +2 -2
- package/lib/hooks-Bq5q9IMl.js +762 -0
- package/lib/html-SllAe0YT.d.ts +46 -0
- package/lib/html.d.ts +1 -1
- package/lib/index-C850MeBA.d.ts +94 -0
- package/lib/{index-oOClm_Xk.d.ts → index-CUTfU69R.d.ts} +3 -3
- package/lib/{index-B-3F4wt2.d.ts → index-Cqcdluyn.d.ts} +2 -2
- package/lib/{index-UTBmM3GX.d.ts → index-CsvB-F9j.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-kAhR_4C7.js +354 -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-Dg493Tai.d.ts → jwt-BARhotDz.d.ts} +1 -1
- package/lib/jwt.d.ts +4 -4
- package/lib/language.d.ts +1 -1
- package/lib/linear-router-C3FPib6h.js +96 -0
- 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 +44 -0
- package/lib/mount.js +67 -0
- 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/pattern-router-HZxjDGEQ.js +41 -0
- package/lib/powered-by.d.ts +1 -1
- package/lib/pretty-json.d.ts +1 -1
- package/lib/proxy.d.ts +72 -0
- package/lib/proxy.js +121 -0
- package/lib/quick.d.ts +8 -0
- package/lib/quick.js +17 -0
- package/lib/request-id.d.ts +1 -1
- package/lib/request.d.ts +1 -1
- package/lib/route.d.ts +1 -1
- package/lib/router/linear-router.js +1 -95
- package/lib/router/pattern-router.js +1 -40
- 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-Cw23shXv.js} +1 -0
- package/lib/serve-static.d.ts +1 -1
- package/lib/streaming.d.ts +1 -1
- package/lib/testing.d.ts +4 -4
- package/lib/timeout.d.ts +1 -1
- package/lib/timing.d.ts +1 -1
- package/lib/tiny.d.ts +8 -0
- package/lib/tiny.js +15 -0
- package/lib/trailing-slash.d.ts +1 -1
- package/lib/{types-CHesD1KG.d.ts → types-CQiGmsWW.d.ts} +3 -3
- package/lib/{types-CwrQjlaM.d.ts → types-Lqx5BxQF.d.ts} +10 -1
- package/lib/{types-CDO6I3B0.d.ts → types-nEL8VPDC.d.ts} +1 -1
- 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/validator.d.ts +2 -2
- package/lib/ws.d.ts +1 -1
- package/package.json +69 -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.case.test.tsx +506 -0
- package/plugins/acryl-router/src/core/helper/css/common.ts +337 -0
- package/plugins/acryl-router/src/core/helper/css/index.test.tsx +678 -0
- package/plugins/acryl-router/src/core/helper/css/index.ts +262 -0
- package/plugins/acryl-router/src/core/helper/dev/index.test.ts +181 -0
- package/plugins/acryl-router/src/core/helper/dev/index.ts +79 -0
- package/plugins/acryl-router/src/core/helper/proxy/index.test.ts +356 -0
- package/plugins/acryl-router/src/core/helper/proxy/index.ts +203 -0
- package/plugins/acryl-router/src/core/helper/streaming/sse.test.tsx +557 -0
- package/plugins/acryl-router/src/core/jsx/base.test.tsx +97 -0
- package/plugins/acryl-router/src/core/jsx/base.ts +490 -0
- package/plugins/acryl-router/src/core/jsx/children.test.ts +52 -0
- package/plugins/acryl-router/src/core/jsx/children.ts +20 -0
- package/plugins/acryl-router/src/core/jsx/components.test.tsx +936 -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-isolation.test.ts +655 -0
- package/plugins/acryl-router/src/core/jsx/context.ts +266 -0
- package/plugins/acryl-router/src/core/jsx/dom/client.test.tsx +128 -0
- package/plugins/acryl-router/src/core/jsx/dom/client.ts +89 -0
- package/plugins/acryl-router/src/core/jsx/dom/components.test.tsx +330 -0
- package/plugins/acryl-router/src/core/jsx/dom/components.ts +39 -0
- package/plugins/acryl-router/src/core/jsx/dom/context.test.tsx +184 -0
- package/plugins/acryl-router/src/core/jsx/dom/context.ts +52 -0
- package/plugins/acryl-router/src/core/jsx/dom/css.test.tsx +149 -0
- package/plugins/acryl-router/src/core/jsx/dom/css.ts +263 -0
- package/plugins/acryl-router/src/core/jsx/dom/hooks/index.test.tsx +172 -0
- package/plugins/acryl-router/src/core/jsx/dom/hooks/index.ts +91 -0
- package/plugins/acryl-router/src/core/jsx/dom/index.test.tsx +3681 -0
- package/plugins/acryl-router/src/core/jsx/dom/index.ts +170 -0
- package/plugins/acryl-router/src/core/jsx/dom/intrinsic-element/components.test.tsx +1344 -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.test.tsx +199 -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/dom.test.tsx +859 -0
- package/plugins/acryl-router/src/core/jsx/hooks/index.ts +437 -0
- package/plugins/acryl-router/src/core/jsx/hooks/string.test.tsx +40 -0
- package/plugins/acryl-router/src/core/jsx/index.test.tsx +1744 -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.test.tsx +666 -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.test.tsx +85 -0
- package/plugins/acryl-router/src/core/jsx/jsx-runtime.ts +51 -0
- package/plugins/acryl-router/src/core/jsx/streaming.test.tsx +1281 -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.test.ts +366 -0
- package/plugins/acryl-router/src/core/jsx/utils.ts +202 -0
- package/plugins/acryl-router/src/core/middleware/cache/index.test.ts +1211 -0
- package/plugins/acryl-router/src/core/middleware/cache/index.ts +323 -0
- package/plugins/acryl-router/src/core/middleware/mount/index.test.ts +334 -0
- package/plugins/acryl-router/src/core/middleware/mount/index.ts +108 -0
- package/plugins/acryl-router/src/core/preset/quick.test.ts +42 -0
- package/plugins/acryl-router/src/core/preset/quick.ts +24 -0
- package/plugins/acryl-router/src/core/preset/tiny.test.ts +42 -0
- package/plugins/acryl-router/src/core/preset/tiny.ts +20 -0
- package/plugins/acryl-router/src/core/utils/types.ts +9 -0
- package/plugins/acryl-router/src/helpers/index.ts +3 -0
- package/plugins/acryl-router/src/middleware/index.ts +2 -0
- package/plugins/acryl-router/src/service.ts +22 -5
- package/plugins/acryl-router/tests/jsx.spec.tsx +63 -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/save/plugin.json +1 -1
- package/templates/todo/upstream.json +1 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/** @jsxImportSource ../ */
|
|
2
|
+
import { raw } from '../../helper/html/index.ts'
|
|
3
|
+
import { renderToReadableStream, renderToString } from './server.ts'
|
|
4
|
+
|
|
5
|
+
const unsafeHtml = '<img src=x onerror=alert(1)>'
|
|
6
|
+
const escapedUnsafeHtml = '<img src=x onerror=alert(1)>'
|
|
7
|
+
|
|
8
|
+
describe('renderToString', () => {
|
|
9
|
+
it('Should be able to render HTML element', () => {
|
|
10
|
+
expect(renderToString(<h1>Hello</h1>)).toBe('<h1>Hello</h1>')
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('Should be able to render null', () => {
|
|
14
|
+
expect(renderToString(null)).toBe('')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it('Should be able to render undefined', () => {
|
|
18
|
+
expect(renderToString(undefined)).toBe('')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('Should be able to render number', () => {
|
|
22
|
+
expect(renderToString(1)).toBe('1')
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('Should be able to render string', () => {
|
|
26
|
+
expect(renderToString('Acryl')).toBe('Acryl')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('Should escape a string root', () => {
|
|
30
|
+
expect(renderToString(unsafeHtml)).toBe(escapedUnsafeHtml)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('Should preserve an explicitly trusted root', () => {
|
|
34
|
+
expect(renderToString(raw('<strong>trusted</strong>'))).toBe('<strong>trusted</strong>')
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
it('Should escape nested array roots without separators', () => {
|
|
38
|
+
expect(renderToString([unsafeHtml, [unsafeHtml]])).toBe(
|
|
39
|
+
`${escapedUnsafeHtml}${escapedUnsafeHtml}`
|
|
40
|
+
)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('Should preserve trusted content in an array root', () => {
|
|
44
|
+
expect(renderToString([raw('<strong>trusted</strong>'), unsafeHtml])).toBe(
|
|
45
|
+
`<strong>trusted</strong>${escapedUnsafeHtml}`
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('Should reject an asynchronous array root', () => {
|
|
50
|
+
expect(() => renderToString([Promise.resolve(unsafeHtml)])).toThrow(
|
|
51
|
+
'Async component is not supported in renderToString'
|
|
52
|
+
)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('Should keep non-string roots unchanged', () => {
|
|
56
|
+
const object = { toString: () => 'plain-text' }
|
|
57
|
+
|
|
58
|
+
expect(renderToString(10n as never)).toBe('10')
|
|
59
|
+
expect(renderToString(Symbol('value') as never)).toBe('Symbol(value)')
|
|
60
|
+
expect(renderToString(object as never)).toBe('plain-text')
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('Should omit options', () => {
|
|
64
|
+
expect(renderToString('Acryl', { identifierPrefix: 'test' })).toBe('Acryl')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('Should raise error for async component', async () => {
|
|
68
|
+
const AsyncComponent = async () => <h1>Hello from async component</h1>
|
|
69
|
+
expect(() => renderToString(<AsyncComponent />)).toThrowError()
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe('renderToReadableStream', () => {
|
|
74
|
+
const textDecoder = new TextDecoder()
|
|
75
|
+
const getStringFromStream = async (stream: ReadableStream<Uint8Array>): Promise<string> => {
|
|
76
|
+
const reader = stream.getReader()
|
|
77
|
+
let str = ''
|
|
78
|
+
for (;;) {
|
|
79
|
+
const { done, value } = await reader.read()
|
|
80
|
+
if (done) {
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
str += textDecoder.decode(value)
|
|
84
|
+
}
|
|
85
|
+
return str
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
it('Should be able to render HTML element', async () => {
|
|
89
|
+
const stream = await renderToReadableStream(<h1>Hello</h1>)
|
|
90
|
+
const reader = stream.getReader()
|
|
91
|
+
let { done, value } = await reader.read()
|
|
92
|
+
expect(done).toBe(false)
|
|
93
|
+
expect(textDecoder.decode(value)).toBe('<h1>Hello</h1>')
|
|
94
|
+
done = (await reader.read()).done
|
|
95
|
+
expect(done).toBe(true)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('Should be able to render null', async () => {
|
|
99
|
+
expect(await getStringFromStream(await renderToReadableStream(null))).toBe('')
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('Should be able to render undefined', async () => {
|
|
103
|
+
expect(await getStringFromStream(await renderToReadableStream(undefined))).toBe('')
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('Should be able to render number', async () => {
|
|
107
|
+
expect(await getStringFromStream(await renderToReadableStream(1))).toBe('1')
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('Should be able to render string', async () => {
|
|
111
|
+
expect(await getStringFromStream(await renderToReadableStream('Acryl'))).toBe('Acryl')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
it('Should escape a string root', async () => {
|
|
115
|
+
expect(await getStringFromStream(await renderToReadableStream(unsafeHtml))).toBe(
|
|
116
|
+
escapedUnsafeHtml
|
|
117
|
+
)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it('Should preserve an explicitly trusted root', async () => {
|
|
121
|
+
expect(
|
|
122
|
+
await getStringFromStream(await renderToReadableStream(raw('<strong>trusted</strong>')))
|
|
123
|
+
).toBe('<strong>trusted</strong>')
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('Should escape synchronous and asynchronous array roots', async () => {
|
|
127
|
+
expect(
|
|
128
|
+
await getStringFromStream(await renderToReadableStream([unsafeHtml, [unsafeHtml]]))
|
|
129
|
+
).toBe(`${escapedUnsafeHtml}${escapedUnsafeHtml}`)
|
|
130
|
+
expect(
|
|
131
|
+
await getStringFromStream(await renderToReadableStream([Promise.resolve(unsafeHtml)]))
|
|
132
|
+
).toBe(escapedUnsafeHtml)
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('Should preserve trusted content in an array root', async () => {
|
|
136
|
+
expect(
|
|
137
|
+
await getStringFromStream(
|
|
138
|
+
await renderToReadableStream([raw('<strong>trusted</strong>'), unsafeHtml])
|
|
139
|
+
)
|
|
140
|
+
).toBe(`<strong>trusted</strong>${escapedUnsafeHtml}`)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('Should keep non-string roots unchanged', async () => {
|
|
144
|
+
expect(await getStringFromStream(await renderToReadableStream(10n as never))).toBe('10')
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('Should be called `onError` if there is an error', async () => {
|
|
148
|
+
const ErrorComponent = async () => {
|
|
149
|
+
throw new Error('Server error')
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const onError = vi.fn()
|
|
153
|
+
expect(
|
|
154
|
+
await getStringFromStream(await renderToReadableStream(<ErrorComponent />, { onError }))
|
|
155
|
+
).toBe('')
|
|
156
|
+
expect(onError).toBeCalledWith(new Error('Server error'))
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
it('Should not be called `onError` if there is no error', async () => {
|
|
160
|
+
const onError = vi.fn(() => 'error')
|
|
161
|
+
expect(await getStringFromStream(await renderToReadableStream('Acryl', { onError }))).toBe(
|
|
162
|
+
'Acryl'
|
|
163
|
+
)
|
|
164
|
+
expect(onError).toBeCalledTimes(0)
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('Should omit options, except onError', async () => {
|
|
168
|
+
expect(
|
|
169
|
+
await getStringFromStream(await renderToReadableStream('Acryl', { identifierPrefix: 'test' }))
|
|
170
|
+
).toBe('Acryl')
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('Should be able to render async component', async () => {
|
|
174
|
+
const ChildAsyncComponent = async () => {
|
|
175
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
176
|
+
return <span>child async component</span>
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const AsyncComponent = async () => {
|
|
180
|
+
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
181
|
+
return (
|
|
182
|
+
<h1>
|
|
183
|
+
Hello from async component
|
|
184
|
+
<ChildAsyncComponent />
|
|
185
|
+
</h1>
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const stream = await renderToReadableStream(<AsyncComponent />)
|
|
190
|
+
const reader = stream.getReader()
|
|
191
|
+
let { done, value } = await reader.read()
|
|
192
|
+
expect(done).toBe(false)
|
|
193
|
+
expect(textDecoder.decode(value)).toBe(
|
|
194
|
+
'<h1>Hello from async component<span>child async component</span></h1>'
|
|
195
|
+
)
|
|
196
|
+
done = (await reader.read()).done
|
|
197
|
+
expect(done).toBe(true)
|
|
198
|
+
})
|
|
199
|
+
})
|
|
@@ -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
|
+
}
|