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.
Files changed (316) hide show
  1. package/README.md +5 -1
  2. package/docs/framework/README.md +3 -2
  3. package/docs/framework/UPSTREAM.md +1 -1
  4. package/docs/framework/cordis/acryl-in-a-cordis-app.md +6 -0
  5. package/docs/framework/getting-started/basic.md +1 -0
  6. package/docs/framework/getting-started/desktop.md +41 -0
  7. package/docs/framework/guides/jsx-dom.md +0 -3
  8. package/docs/framework/guides/jsx.md +24 -3
  9. package/docs/framework/helpers/css.md +0 -3
  10. package/docs/framework/helpers/ssg.md +3 -6
  11. package/docs/framework/middleware/builtin/jsx-renderer.md +0 -3
  12. package/docs/framework/upstream.json +3 -3
  13. package/lib/accepts.d.ts +1 -1
  14. package/lib/acryl-base.d.ts +1 -1
  15. package/lib/adapter.d.ts +1 -1
  16. package/lib/{app-BdrVHBlJ.d.ts → app-D8riatvv.d.ts} +1 -1
  17. package/lib/base-BpQy2Rk7.d.ts +783 -0
  18. package/lib/base-ddiVmiE7.js +721 -0
  19. package/lib/basic-auth.d.ts +1 -1
  20. package/lib/bearer-auth.d.ts +1 -1
  21. package/lib/body-limit.d.ts +1 -1
  22. package/lib/cache.d.ts +1 -1
  23. package/lib/cache.js +4 -4
  24. package/lib/{client-BHTr318g.js → client-DDLXwhBo.js} +2 -125
  25. package/lib/client.d.ts +2 -2
  26. package/lib/client.js +2 -1
  27. package/lib/combine.d.ts +1 -1
  28. package/lib/common-D8Z4JRCw.d.ts +46 -0
  29. package/lib/components-0o0CBYNv.js +268 -0
  30. package/lib/components-DdI7-ns7.js +24 -0
  31. package/lib/compress.d.ts +1 -1
  32. package/lib/conninfo.d.ts +2 -2
  33. package/lib/constants-BR9jM9BC.js +9 -0
  34. package/lib/{context-B5Y1lLha.d.ts → context-DS3fYyG-.d.ts} +2 -2
  35. package/lib/context-DxFdY_un.d.ts +250 -0
  36. package/lib/context-storage.d.ts +1 -1
  37. package/lib/{cookie-D9_nQbsM.d.ts → cookie-CCelEqky.d.ts} +1 -1
  38. package/lib/cookie.d.ts +3 -3
  39. package/lib/cors.d.ts +1 -1
  40. package/lib/csrf.d.ts +1 -1
  41. package/lib/css-D2jb7X8b.js +320 -0
  42. package/lib/css.d.ts +82 -0
  43. package/lib/css.js +134 -0
  44. package/lib/dev.d.ts +2 -2
  45. package/lib/etag.d.ts +1 -1
  46. package/lib/factory.d.ts +2 -2
  47. package/lib/hooks-BMw6BAyP.js +762 -0
  48. package/lib/html-SllAe0YT.d.ts +46 -0
  49. package/lib/html.d.ts +1 -1
  50. package/lib/{index-m12zcmph.d.ts → index-Bb7YJKCq.d.ts} +3 -3
  51. package/lib/{index-Kqou8Fjh.d.ts → index-BvFh1Gfx.d.ts} +2 -2
  52. package/lib/index-C850MeBA.d.ts +94 -0
  53. package/lib/{index-DtEoak1i.d.ts → index-CTy4N7ng.d.ts} +2 -2
  54. package/lib/index.d.ts +4 -4
  55. package/lib/ip-restriction.d.ts +2 -2
  56. package/lib/jsx/dom/client.d.ts +30 -0
  57. package/lib/jsx/dom/client.js +49 -0
  58. package/lib/jsx/dom/css.d.ts +84 -0
  59. package/lib/jsx/dom/css.js +2 -0
  60. package/lib/jsx/dom/jsx-dev-runtime.d.ts +3 -0
  61. package/lib/jsx/dom/jsx-dev-runtime.js +2 -0
  62. package/lib/jsx/dom/jsx-runtime.d.ts +3 -0
  63. package/lib/jsx/dom/jsx-runtime.js +2 -0
  64. package/lib/jsx/dom/server.d.ts +105 -0
  65. package/lib/jsx/dom/server.js +37 -0
  66. package/lib/jsx/dom.d.ts +5 -0
  67. package/lib/jsx/dom.js +74 -0
  68. package/lib/jsx/jsx-dev-runtime.d.ts +6 -0
  69. package/lib/jsx/jsx-dev-runtime.js +14 -0
  70. package/lib/jsx/jsx-runtime.d.ts +10 -0
  71. package/lib/jsx/jsx-runtime.js +30 -0
  72. package/lib/jsx/streaming.d.ts +2 -0
  73. package/lib/jsx/streaming.js +2 -0
  74. package/lib/jsx-dev-runtime-B22O-Npk.d.ts +7 -0
  75. package/lib/jsx-dev-runtime-D18Y35TI.js +354 -0
  76. package/lib/jsx-renderer.d.ts +75 -0
  77. package/lib/jsx-renderer.js +99 -0
  78. package/lib/jsx-runtime-BVVgDSdq.d.ts +1 -0
  79. package/lib/jsx.d.ts +3 -0
  80. package/lib/jsx.js +47 -0
  81. package/lib/jwk.d.ts +4 -4
  82. package/lib/{jwt-BA65QhnJ.d.ts → jwt-BARhotDz.d.ts} +1 -1
  83. package/lib/jwt.d.ts +4 -4
  84. package/lib/language.d.ts +1 -1
  85. package/lib/logger.d.ts +1 -1
  86. package/lib/loopback-only.d.ts +1 -1
  87. package/lib/method-not-allowed.d.ts +2 -2
  88. package/lib/method-override.d.ts +2 -2
  89. package/lib/mount.d.ts +1 -1
  90. package/lib/node-server/conninfo.d.ts +1 -1
  91. package/lib/node-server/serve-static.d.ts +1 -1
  92. package/lib/node-server/serve-static.js +1 -1
  93. package/lib/node-server.d.ts +1 -1
  94. package/lib/node-server.js +1 -1
  95. package/lib/powered-by.d.ts +1 -1
  96. package/lib/pretty-json.d.ts +1 -1
  97. package/lib/proxy.d.ts +1 -1
  98. package/lib/quick.d.ts +1 -1
  99. package/lib/request-id.d.ts +1 -1
  100. package/lib/request.d.ts +1 -1
  101. package/lib/route.d.ts +1 -1
  102. package/lib/schema-validator.d.ts +1 -1
  103. package/lib/secure-headers.d.ts +1 -1
  104. package/lib/{serve-static-Dw_m6KxR.js → serve-static-B14MF1Va.js} +2 -0
  105. package/lib/serve-static.d.ts +1 -1
  106. package/lib/ssg-BwjcA-Ge.js +389 -0
  107. package/lib/ssg.d.ts +156 -0
  108. package/lib/ssg.js +2 -0
  109. package/lib/streaming.d.ts +1 -1
  110. package/lib/testing.d.ts +4 -4
  111. package/lib/testing.js +1 -1
  112. package/lib/timeout.d.ts +1 -1
  113. package/lib/timing.d.ts +1 -1
  114. package/lib/tiny.d.ts +1 -1
  115. package/lib/trailing-slash.d.ts +1 -1
  116. package/lib/{types-ZM9gIiKh.d.ts → types-Dv_nV2cv.d.ts} +1 -1
  117. package/lib/{types-D9DEXMjE.d.ts → types-Lqx5BxQF.d.ts} +8 -1
  118. package/lib/{types-Bd29gh2o.d.ts → types-zNxyEpG2.d.ts} +3 -3
  119. package/lib/types.d.ts +1 -1
  120. package/lib/utils/body.d.ts +1 -1
  121. package/lib/utils/cookie.d.ts +1 -1
  122. package/lib/utils/crypto.d.ts +1 -1
  123. package/lib/utils/html.d.ts +1 -45
  124. package/lib/utils/ipaddr.d.ts +1 -1
  125. package/lib/utils/jwt.d.ts +1 -1
  126. package/lib/utils/types.d.ts +2 -2
  127. package/lib/utils-Cx61GFMC.js +125 -0
  128. package/lib/validator.d.ts +2 -2
  129. package/lib/ws.d.ts +1 -1
  130. package/package.json +53 -1
  131. package/plugins/acryl-inspect/upstream.json +1 -1
  132. package/plugins/acryl-node-server/upstream.json +1 -1
  133. package/plugins/acryl-router/src/core/helper/css/common.ts +337 -0
  134. package/plugins/acryl-router/src/core/helper/css/index.ts +262 -0
  135. package/plugins/acryl-router/src/core/helper/ssg/index.ts +14 -0
  136. package/plugins/acryl-router/src/core/helper/ssg/middleware.ts +83 -0
  137. package/plugins/acryl-router/src/core/helper/ssg/plugins.ts +72 -0
  138. package/plugins/acryl-router/src/core/helper/ssg/ssg.ts +471 -0
  139. package/plugins/acryl-router/src/core/helper/ssg/utils.ts +118 -0
  140. package/plugins/acryl-router/src/core/jsx/base.ts +490 -0
  141. package/plugins/acryl-router/src/core/jsx/children.ts +20 -0
  142. package/plugins/acryl-router/src/core/jsx/components.ts +257 -0
  143. package/plugins/acryl-router/src/core/jsx/constants.ts +6 -0
  144. package/plugins/acryl-router/src/core/jsx/context.ts +266 -0
  145. package/plugins/acryl-router/src/core/jsx/dom/client.ts +89 -0
  146. package/plugins/acryl-router/src/core/jsx/dom/components.ts +39 -0
  147. package/plugins/acryl-router/src/core/jsx/dom/context.ts +52 -0
  148. package/plugins/acryl-router/src/core/jsx/dom/css.ts +263 -0
  149. package/plugins/acryl-router/src/core/jsx/dom/hooks/index.ts +91 -0
  150. package/plugins/acryl-router/src/core/jsx/dom/index.ts +170 -0
  151. package/plugins/acryl-router/src/core/jsx/dom/intrinsic-element/components.ts +438 -0
  152. package/plugins/acryl-router/src/core/jsx/dom/jsx-dev-runtime.ts +23 -0
  153. package/plugins/acryl-router/src/core/jsx/dom/jsx-runtime.ts +8 -0
  154. package/plugins/acryl-router/src/core/jsx/dom/render.ts +879 -0
  155. package/plugins/acryl-router/src/core/jsx/dom/server.ts +76 -0
  156. package/plugins/acryl-router/src/core/jsx/dom/utils.ts +7 -0
  157. package/plugins/acryl-router/src/core/jsx/hooks/index.ts +437 -0
  158. package/plugins/acryl-router/src/core/jsx/index.ts +115 -0
  159. package/plugins/acryl-router/src/core/jsx/intrinsic-element/common.ts +23 -0
  160. package/plugins/acryl-router/src/core/jsx/intrinsic-element/components.ts +210 -0
  161. package/plugins/acryl-router/src/core/jsx/intrinsic-elements.ts +938 -0
  162. package/plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts +26 -0
  163. package/plugins/acryl-router/src/core/jsx/jsx-runtime.ts +51 -0
  164. package/plugins/acryl-router/src/core/jsx/streaming.ts +231 -0
  165. package/plugins/acryl-router/src/core/jsx/types.ts +41 -0
  166. package/plugins/acryl-router/src/core/jsx/utils.ts +202 -0
  167. package/plugins/acryl-router/src/core/middleware/cache/index.ts +4 -4
  168. package/plugins/acryl-router/src/core/middleware/jsx-renderer/index.ts +162 -0
  169. package/plugins/acryl-router/src/core/utils/types.ts +6 -0
  170. package/plugins/acryl-router/src/helpers/index.ts +2 -0
  171. package/plugins/acryl-router/src/middleware/index.ts +1 -0
  172. package/plugins/acryl-router/upstream.json +3 -3
  173. package/plugins/acryl-router-http/upstream.json +1 -1
  174. package/plugins/acryl-state/upstream.json +1 -1
  175. package/plugins/desktop/upstream.json +1 -1
  176. package/plugins/desktop-web/upstream.json +1 -1
  177. package/plugins/extensions/resolve.ts +4 -0
  178. package/plugins/save/plugin.json +1 -1
  179. package/shared/AGENTS.core.md +4 -0
  180. package/templates/agent/tsconfig.json +7 -1
  181. package/templates/todo/upstream.json +1 -1
  182. package/plugins/acryl-inspect/tests/report.spec.ts +0 -69
  183. package/plugins/acryl-inspect/tests/service.spec.ts +0 -121
  184. package/plugins/acryl-node-server/tests/adapter/app.ts +0 -76
  185. package/plugins/acryl-node-server/tests/adapter/assets/.static/plain.txt +0 -1
  186. package/plugins/acryl-node-server/tests/adapter/assets/favicon.ico +0 -0
  187. package/plugins/acryl-node-server/tests/adapter/assets/secret.txt +0 -1
  188. package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +0 -1
  189. package/plugins/acryl-node-server/tests/adapter/assets/static/admin/secret.txt +0 -1
  190. package/plugins/acryl-node-server/tests/adapter/assets/static/data.json +0 -5
  191. package/plugins/acryl-node-server/tests/adapter/assets/static/extensionless +0 -1
  192. package/plugins/acryl-node-server/tests/adapter/assets/static/foo..bar.txt +0 -0
  193. package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +0 -1
  194. package/plugins/acryl-node-server/tests/adapter/assets/static/plain.txt +0 -1
  195. package/plugins/acryl-node-server/tests/adapter/assets/static-with-context-path/plain.txt +0 -1
  196. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin +0 -1
  197. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin.br +0 -1
  198. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt +0 -1
  199. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.br +0 -1
  200. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.zst +0 -1
  201. package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +0 -34
  202. package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +0 -248
  203. package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +0 -457
  204. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-cert.pem +0 -23
  205. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-key.pem +0 -27
  206. package/plugins/acryl-node-server/tests/adapter/headers.test.ts +0 -252
  207. package/plugins/acryl-node-server/tests/adapter/helpers/request.ts +0 -190
  208. package/plugins/acryl-node-server/tests/adapter/listener.test.ts +0 -727
  209. package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +0 -189
  210. package/plugins/acryl-node-server/tests/adapter/request.test.ts +0 -1230
  211. package/plugins/acryl-node-server/tests/adapter/response.test.ts +0 -285
  212. package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +0 -849
  213. package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +0 -790
  214. package/plugins/acryl-node-server/tests/adapter/server.test.ts +0 -1312
  215. package/plugins/acryl-node-server/tests/adapter/setup.ts +0 -16
  216. package/plugins/acryl-node-server/tests/adapter/url.test.ts +0 -76
  217. package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +0 -23
  218. package/plugins/acryl-node-server/tests/adapter/utils/stream.test.ts +0 -75
  219. package/plugins/acryl-node-server/tests/adapter/utils.test.ts +0 -235
  220. package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +0 -260
  221. package/plugins/acryl-node-server/tests/server.spec.ts +0 -141
  222. package/plugins/acryl-router/src/core/app.test.ts +0 -3833
  223. package/plugins/acryl-router/src/core/client/client.test.ts +0 -2313
  224. package/plugins/acryl-router/src/core/client/types.test.ts +0 -149
  225. package/plugins/acryl-router/src/core/client/utils.test.ts +0 -405
  226. package/plugins/acryl-router/src/core/compose.test.ts +0 -751
  227. package/plugins/acryl-router/src/core/context.test.ts +0 -629
  228. package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +0 -344
  229. package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +0 -55
  230. package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +0 -510
  231. package/plugins/acryl-router/src/core/helper/dev/index.test.ts +0 -181
  232. package/plugins/acryl-router/src/core/helper/factory/index.test.ts +0 -434
  233. package/plugins/acryl-router/src/core/helper/html/index.test.ts +0 -78
  234. package/plugins/acryl-router/src/core/helper/proxy/index.test.ts +0 -356
  235. package/plugins/acryl-router/src/core/helper/route/index.test.ts +0 -259
  236. package/plugins/acryl-router/src/core/helper/streaming/stream.test.ts +0 -128
  237. package/plugins/acryl-router/src/core/helper/streaming/text.test.ts +0 -34
  238. package/plugins/acryl-router/src/core/helper/testing/index.test.ts +0 -42
  239. package/plugins/acryl-router/src/core/helper/websocket/index.test.ts +0 -124
  240. package/plugins/acryl-router/src/core/http-exception.test.ts +0 -45
  241. package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +0 -434
  242. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +0 -1018
  243. package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +0 -273
  244. package/plugins/acryl-router/src/core/middleware/cache/index.test.ts +0 -1211
  245. package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +0 -355
  246. package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +0 -535
  247. package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +0 -43
  248. package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +0 -532
  249. package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +0 -534
  250. package/plugins/acryl-router/src/core/middleware/etag/digest.test.ts +0 -21
  251. package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +0 -503
  252. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +0 -217
  253. package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +0 -1135
  254. package/plugins/acryl-router/src/core/middleware/jwk/keys.test.json +0 -48
  255. package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +0 -802
  256. package/plugins/acryl-router/src/core/middleware/language/index.test.ts +0 -552
  257. package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +0 -204
  258. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +0 -292
  259. package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +0 -221
  260. package/plugins/acryl-router/src/core/middleware/mount/index.test.ts +0 -334
  261. package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +0 -37
  262. package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +0 -218
  263. package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +0 -168
  264. package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +0 -671
  265. package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +0 -450
  266. package/plugins/acryl-router/src/core/middleware/serve-static/path.test.ts +0 -50
  267. package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +0 -70
  268. package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +0 -310
  269. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +0 -381
  270. package/plugins/acryl-router/src/core/preset/quick.test.ts +0 -42
  271. package/plugins/acryl-router/src/core/preset/tiny.test.ts +0 -42
  272. package/plugins/acryl-router/src/core/request.test.ts +0 -751
  273. package/plugins/acryl-router/src/core/router/common.case.test.ts +0 -1132
  274. package/plugins/acryl-router/src/core/router/linear-router/router.test.ts +0 -80
  275. package/plugins/acryl-router/src/core/router/pattern-router/router.test.ts +0 -46
  276. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.test.ts +0 -154
  277. package/plugins/acryl-router/src/core/router/reg-exp-router/router.test.ts +0 -265
  278. package/plugins/acryl-router/src/core/router/smart-router/router.test.ts +0 -13
  279. package/plugins/acryl-router/src/core/router/trie-router/node.test.ts +0 -896
  280. package/plugins/acryl-router/src/core/router/trie-router/router.test.ts +0 -8
  281. package/plugins/acryl-router/src/core/types.test.ts +0 -4134
  282. package/plugins/acryl-router/src/core/utils/accept.test.ts +0 -299
  283. package/plugins/acryl-router/src/core/utils/basic-auth.test.ts +0 -56
  284. package/plugins/acryl-router/src/core/utils/body.test.ts +0 -496
  285. package/plugins/acryl-router/src/core/utils/buffer.test.ts +0 -147
  286. package/plugins/acryl-router/src/core/utils/color.test.ts +0 -23
  287. package/plugins/acryl-router/src/core/utils/concurrent.test.ts +0 -69
  288. package/plugins/acryl-router/src/core/utils/cookie.test.ts +0 -460
  289. package/plugins/acryl-router/src/core/utils/crypto.test.ts +0 -43
  290. package/plugins/acryl-router/src/core/utils/encode.test.ts +0 -61
  291. package/plugins/acryl-router/src/core/utils/filepath.test.ts +0 -78
  292. package/plugins/acryl-router/src/core/utils/html.test.ts +0 -16
  293. package/plugins/acryl-router/src/core/utils/ipaddr.test.ts +0 -149
  294. package/plugins/acryl-router/src/core/utils/jwt/jwa.test.ts +0 -86
  295. package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +0 -1788
  296. package/plugins/acryl-router/src/core/utils/mime.test.ts +0 -64
  297. package/plugins/acryl-router/src/core/utils/stream.test.ts +0 -212
  298. package/plugins/acryl-router/src/core/utils/types.test.ts +0 -295
  299. package/plugins/acryl-router/src/core/utils/url.test.ts +0 -384
  300. package/plugins/acryl-router/src/core/validator/utils.test.ts +0 -82
  301. package/plugins/acryl-router/src/core/validator/validator.test.ts +0 -1488
  302. package/plugins/acryl-router/tests/docs-examples.spec.ts +0 -152
  303. package/plugins/acryl-router/tests/live-install.spec.ts +0 -64
  304. package/plugins/acryl-router/tests/loader.spec.ts +0 -72
  305. package/plugins/acryl-router/tests/loopback-only.spec.ts +0 -80
  306. package/plugins/acryl-router/tests/no-dom/consumer.ts +0 -11
  307. package/plugins/acryl-router/tests/no-dom/tsconfig.json +0 -13
  308. package/plugins/acryl-router/tests/service.spec.ts +0 -426
  309. package/plugins/acryl-router/tests/shadow-state.spec.ts +0 -79
  310. package/plugins/acryl-router-http/tests/adapter.spec.ts +0 -174
  311. package/plugins/acryl-router-http/tests/stream.spec.ts +0 -133
  312. package/plugins/acryl-router-http/tests/surfaces.spec.ts +0 -101
  313. package/plugins/acryl-state/src/react.ts +0 -11
  314. package/plugins/acryl-state/tests/cell.spec.ts +0 -71
  315. package/plugins/acryl-state/tests/react.spec.ts +0 -39
  316. package/plugins/acryl-state/tests/service.spec.ts +0 -132
@@ -0,0 +1,337 @@
1
+ // provide utility functions for css helper both on server and client
2
+ export const PSEUDO_GLOBAL_SELECTOR = ':-acryl-global'
3
+ export const isPseudoGlobalSelectorRe = new RegExp(`^${PSEUDO_GLOBAL_SELECTOR}{(.*)}$`)
4
+ export const DEFAULT_STYLE_ID = 'acryl-css'
5
+
6
+ export const SELECTOR: unique symbol = Symbol()
7
+ export const CLASS_NAME: unique symbol = Symbol()
8
+ export const STYLE_STRING: unique symbol = Symbol()
9
+ export const SELECTORS: unique symbol = Symbol()
10
+ export const EXTERNAL_CLASS_NAMES: unique symbol = Symbol()
11
+ const CSS_ESCAPED: unique symbol = Symbol()
12
+
13
+ export interface CssClassName {
14
+ [SELECTOR]: string
15
+ [CLASS_NAME]: string
16
+ [STYLE_STRING]: string
17
+ [SELECTORS]: CssClassName[]
18
+ [EXTERNAL_CLASS_NAMES]: string[]
19
+ }
20
+
21
+ export const IS_CSS_ESCAPED = Symbol()
22
+
23
+ interface CssEscapedString {
24
+ [CSS_ESCAPED]: string
25
+ }
26
+
27
+ /**
28
+ * @experimental
29
+ * `rawCssString` is an experimental feature.
30
+ * The API might be changed.
31
+ */
32
+ export const rawCssString = (value: string): CssEscapedString => {
33
+ return {
34
+ [CSS_ESCAPED]: value,
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Used the goober'code as a reference:
40
+ * https://github.com/cristianbote/goober/blob/master/src/core/to-hash.js
41
+ * MIT License, Copyright (c) 2019 Cristian Bote
42
+ */
43
+ const toHash = (str: string): string => {
44
+ let i = 0,
45
+ out = 11
46
+ while (i < str.length) {
47
+ out = (101 * out + str.charCodeAt(i++)) >>> 0
48
+ }
49
+ return 'css-' + out
50
+ }
51
+
52
+ const normalizeLabel = (label: string): string => {
53
+ return label.trim().replace(/\s+/g, '-')
54
+ }
55
+
56
+ const isValidClassName = (name: string): boolean => /^-?[_a-zA-Z][_a-zA-Z0-9-]*$/.test(name)
57
+
58
+ // `<`, `{`, `}` never appear in valid class names but can break out of a <style> element
59
+ // or inject a CSS rule when an external cx() class name is used as a selector.
60
+ const hasUnsafeSelectorChar = (name: string): boolean => /[<{}]/.test(name)
61
+
62
+ // CSS-wide keywords that are invalid as @keyframes names per the spec
63
+ const RESERVED_KEYFRAME_NAMES = new Set([
64
+ 'default',
65
+ 'inherit',
66
+ 'initial',
67
+ 'none',
68
+ 'revert',
69
+ 'revert-layer',
70
+ 'unset',
71
+ ])
72
+ const isValidKeyframeName = (name: string): boolean =>
73
+ isValidClassName(name) && !RESERVED_KEYFRAME_NAMES.has(name.toLowerCase())
74
+
75
+ const defaultOnInvalidSlug = (slug: string) => {
76
+ console.warn(`Invalid slug: ${slug}`)
77
+ }
78
+
79
+ const cssStringReStr: string = [
80
+ '"(?:(?:\\\\[\\s\\S]|[^"\\\\])*)"', // double quoted string
81
+
82
+ "'(?:(?:\\\\[\\s\\S]|[^'\\\\])*)'", // single quoted string
83
+
84
+ 'url\\(\\s*[^)"\'\\s]*\\s*\\)', // unquoted url, which may contain "//"
85
+ ].join('|')
86
+ const minifyCssRe: RegExp = new RegExp(
87
+ [
88
+ '(' + cssStringReStr + ')', // $1: quoted string or unquoted url
89
+
90
+ '(?:' +
91
+ [
92
+ '^\\s+', // head whitespace
93
+ '\\/\\*.*?\\*\\/\\s*', // multi-line comment
94
+ '\\/\\/.*\\n\\s*', // single-line comment
95
+ '\\s+$', // tail whitespace
96
+ ].join('|') +
97
+ ')',
98
+
99
+ '\\s*;\\s*(}|$)\\s*', // $2: trailing semicolon
100
+ '\\s*([{};,])\\s*', // $3: whitespace around { } , ;
101
+ // $4: whitespace after : (the whitespace before it is a descendant combinator in a selector)
102
+ '(:)\\s*',
103
+ '(\\s)\\s+', // $5: 2+ spaces
104
+ ].join('|'),
105
+ 'g'
106
+ )
107
+
108
+ export const minify = (css: string): string => {
109
+ return css.replace(minifyCssRe, (_, $1, $2, $3, $4, $5) => $1 || $2 || $3 || $4 || $5 || '')
110
+ }
111
+
112
+ type CssVariableBasicType =
113
+ | CssClassName
114
+ | CssEscapedString
115
+ | string
116
+ | number
117
+ | boolean
118
+ | null
119
+ | undefined
120
+ type CssVariableAsyncType = Promise<CssVariableBasicType>
121
+ type CssVariableArrayType = (CssVariableBasicType | CssVariableAsyncType)[]
122
+ export type CssVariableType = CssVariableBasicType | CssVariableAsyncType | CssVariableArrayType
123
+
124
+ /**
125
+ * A function that customizes generated CSS class names.
126
+ *
127
+ * @param hash - The default hash-based class name (e.g. `css-1234567890`)
128
+ * @param label - The comment label extracted from the CSS template, may be empty.
129
+ * Whitespace is trimmed and inner spaces are replaced with hyphens.
130
+ * @param styleString - The minified CSS style string
131
+ * @returns The custom class name to use. Must be a safe CSS identifier;
132
+ * otherwise, the default hash is used as a fallback.
133
+ */
134
+ export type ClassNameSlug = (hash: string, label: string, styleString: string) => string
135
+
136
+ /**
137
+ * A callback function called when an invalid slug is returned from ClassNameSlug.
138
+ *
139
+ * @param slug - The invalid slug
140
+ */
141
+ export type OnInvalidSlug = (slug: string) => void
142
+
143
+ export const buildStyleString = (
144
+ strings: TemplateStringsArray,
145
+ values: CssVariableType[]
146
+ ): [string, string, CssClassName[], string[]] => {
147
+ const selectors: CssClassName[] = []
148
+ const externalClassNames: string[] = []
149
+
150
+ const label = strings[0].match(/^\s*\/\*(.*?)\*\//)?.[1] || ''
151
+ let styleString = ''
152
+ for (let i = 0, len = strings.length; i < len; i++) {
153
+ styleString += strings[i]
154
+ let vArray = values[i]
155
+ if (typeof vArray === 'boolean' || vArray === null || vArray === undefined) {
156
+ continue
157
+ }
158
+
159
+ if (!Array.isArray(vArray)) {
160
+ vArray = [vArray]
161
+ }
162
+ for (let j = 0, len = vArray.length; j < len; j++) {
163
+ let value = vArray[j]
164
+ if (typeof value === 'boolean' || value === null || value === undefined) {
165
+ continue
166
+ }
167
+ if (typeof value === 'string') {
168
+ if (/([\\"'\/])/.test(value)) {
169
+ styleString += value.replace(/([\\"']|(?<=<)\/)/g, '\\$1')
170
+ } else {
171
+ styleString += value
172
+ }
173
+ } else if (typeof value === 'number') {
174
+ styleString += value
175
+ } else if ((value as CssEscapedString)[CSS_ESCAPED]) {
176
+ styleString += (value as CssEscapedString)[CSS_ESCAPED]
177
+ } else if ((value as CssClassName)[CLASS_NAME].startsWith('@keyframes ')) {
178
+ selectors.push(value as CssClassName)
179
+ styleString += ` ${(value as CssClassName)[CLASS_NAME].substring(11)} `
180
+ } else {
181
+ if (strings[i + 1]?.match(/^\s*{/)) {
182
+ // assume this value is a class name
183
+ selectors.push(value as CssClassName)
184
+ value = `.${(value as CssClassName)[CLASS_NAME]}`
185
+ } else {
186
+ selectors.push(...(value as CssClassName)[SELECTORS])
187
+ externalClassNames.push(...(value as CssClassName)[EXTERNAL_CLASS_NAMES])
188
+ value = (value as CssClassName)[STYLE_STRING]
189
+ const valueLen = value.length
190
+ if (valueLen > 0) {
191
+ const lastChar = value[valueLen - 1]
192
+ if (lastChar !== ';' && lastChar !== '}') {
193
+ value += ';'
194
+ }
195
+ }
196
+ }
197
+ styleString += `${value || ''}`
198
+ }
199
+ }
200
+ }
201
+
202
+ return [label, minify(styleString), selectors, externalClassNames]
203
+ }
204
+
205
+ export const cssCommon = (
206
+ strings: TemplateStringsArray,
207
+ values: CssVariableType[],
208
+ classNameSlug?: ClassNameSlug,
209
+ onInvalidSlug?: OnInvalidSlug
210
+ ): CssClassName => {
211
+ let [label, thisStyleString, selectors, externalClassNames] = buildStyleString(strings, values)
212
+ const isPseudoGlobal = isPseudoGlobalSelectorRe.exec(thisStyleString)
213
+ if (isPseudoGlobal) {
214
+ thisStyleString = isPseudoGlobal[1]
215
+ }
216
+ const hash = toHash(label + thisStyleString)
217
+
218
+ let customSlug: string | undefined
219
+ if (classNameSlug) {
220
+ const slug = classNameSlug(hash, normalizeLabel(label), thisStyleString)
221
+ if (slug) {
222
+ if (isValidClassName(slug)) {
223
+ customSlug = slug
224
+ } else {
225
+ ;(onInvalidSlug || defaultOnInvalidSlug)(slug)
226
+ }
227
+ }
228
+ }
229
+
230
+ const selector = (isPseudoGlobal ? PSEUDO_GLOBAL_SELECTOR : '') + (customSlug || hash)
231
+ const className = (
232
+ isPseudoGlobal ? selectors.map((s) => s[CLASS_NAME]) : [selector, ...externalClassNames]
233
+ ).join(' ')
234
+
235
+ return {
236
+ [SELECTOR]: selector,
237
+ [CLASS_NAME]: className,
238
+ [STYLE_STRING]: thisStyleString,
239
+ [SELECTORS]: selectors,
240
+ [EXTERNAL_CLASS_NAMES]: externalClassNames,
241
+ }
242
+ }
243
+
244
+ export const cxCommon = (
245
+ args: (string | boolean | null | undefined | CssClassName)[]
246
+ ): (string | boolean | null | undefined | CssClassName)[] => {
247
+ for (let i = 0, len = args.length; i < len; i++) {
248
+ const arg = args[i]
249
+ if (typeof arg === 'string') {
250
+ args[i] = {
251
+ [SELECTOR]: '',
252
+ [CLASS_NAME]: '',
253
+ [STYLE_STRING]: '',
254
+ [SELECTORS]: [],
255
+ // drop names that are unsafe to emit as a selector
256
+ [EXTERNAL_CLASS_NAMES]: hasUnsafeSelectorChar(arg) ? [] : [arg],
257
+ }
258
+ }
259
+ }
260
+
261
+ return args
262
+ }
263
+
264
+ export const keyframesCommon = (
265
+ strings: TemplateStringsArray,
266
+ values: CssVariableType[],
267
+ classNameSlug?: ClassNameSlug,
268
+ onInvalidSlug?: OnInvalidSlug
269
+ ): CssClassName => {
270
+ const [label, styleString] = buildStyleString(strings, values)
271
+ const hash = toHash(label + styleString)
272
+
273
+ let customSlug: string | undefined
274
+ if (classNameSlug) {
275
+ const slug = classNameSlug(hash, normalizeLabel(label), styleString)
276
+ if (slug) {
277
+ if (isValidKeyframeName(slug)) {
278
+ customSlug = slug
279
+ } else {
280
+ ;(onInvalidSlug || defaultOnInvalidSlug)(slug)
281
+ }
282
+ }
283
+ }
284
+
285
+ return {
286
+ [SELECTOR]: '',
287
+ [CLASS_NAME]: `@keyframes ${customSlug || hash}`,
288
+ [STYLE_STRING]: styleString,
289
+ [SELECTORS]: [],
290
+ [EXTERNAL_CLASS_NAMES]: [],
291
+ }
292
+ }
293
+
294
+ type ViewTransitionType = {
295
+ (
296
+ strings: TemplateStringsArray,
297
+ values: CssVariableType[],
298
+ classNameSlug?: ClassNameSlug,
299
+ onInvalidSlug?: OnInvalidSlug
300
+ ): CssClassName
301
+ (content: CssClassName): CssClassName
302
+ (): CssClassName
303
+ }
304
+
305
+ let viewTransitionNameIndex = 0
306
+ export const viewTransitionCommon: ViewTransitionType = ((
307
+ strings: TemplateStringsArray | CssClassName | undefined,
308
+ values: CssVariableType[],
309
+ classNameSlug?: ClassNameSlug,
310
+ onInvalidSlug?: OnInvalidSlug
311
+ ): CssClassName => {
312
+ if (!strings) {
313
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
314
+ strings = [`/* h-v-t ${viewTransitionNameIndex++} */`] as any
315
+ }
316
+ const content = Array.isArray(strings)
317
+ ? cssCommon(strings as TemplateStringsArray, values, classNameSlug, onInvalidSlug)
318
+ : (strings as CssClassName)
319
+
320
+ const transitionName = content[CLASS_NAME]
321
+ const res = cssCommon(
322
+ ['view-transition-name:', ''] as any, // eslint-disable-line @typescript-eslint/no-explicit-any
323
+ [transitionName],
324
+ classNameSlug,
325
+ onInvalidSlug
326
+ )
327
+
328
+ content[CLASS_NAME] = PSEUDO_GLOBAL_SELECTOR + content[CLASS_NAME]
329
+ content[STYLE_STRING] = content[STYLE_STRING].replace(
330
+ /(?<=::view-transition(?:[a-z-]*)\()(?=\))/g,
331
+ transitionName
332
+ )
333
+ res[CLASS_NAME] = res[SELECTOR] = transitionName
334
+ res[SELECTORS] = [...content[SELECTORS], content]
335
+
336
+ return res
337
+ }) as ViewTransitionType
@@ -0,0 +1,262 @@
1
+ /**
2
+ * @module
3
+ * css Helper for Acryl.
4
+ */
5
+
6
+ import { raw } from '../html/index.ts'
7
+ import { DOM_RENDERER } from '../../jsx/constants.ts'
8
+ import { createCssJsxDomObjects } from '../../jsx/dom/css.ts'
9
+ import { escapeToBuffer } from '../../utils/html.ts'
10
+ import type { HtmlEscapedCallback, HtmlEscapedString } from '../../utils/html.ts'
11
+ import type {
12
+ ClassNameSlug,
13
+ CssClassName as CssClassNameCommon,
14
+ CssVariableType,
15
+ OnInvalidSlug,
16
+ } from './common.ts'
17
+ import {
18
+ CLASS_NAME,
19
+ DEFAULT_STYLE_ID,
20
+ PSEUDO_GLOBAL_SELECTOR,
21
+ SELECTOR,
22
+ SELECTORS,
23
+ STYLE_STRING,
24
+ cssCommon,
25
+ cxCommon,
26
+ keyframesCommon,
27
+ viewTransitionCommon,
28
+ } from './common.ts'
29
+ export { rawCssString } from './common.ts'
30
+ export type { ClassNameSlug, OnInvalidSlug } from './common.ts'
31
+
32
+ type CssClassName = HtmlEscapedString & CssClassNameCommon
33
+
34
+ type usedClassNameData = [
35
+ Record<string, string>, // class name to add
36
+ Record<string, true>, // class name already added
37
+ ]
38
+
39
+ interface CssType {
40
+ (strings: TemplateStringsArray, ...values: CssVariableType[]): Promise<string>
41
+ }
42
+
43
+ interface CxType {
44
+ (
45
+ ...args: (CssClassName | Promise<string> | string | boolean | null | undefined)[]
46
+ ): Promise<string>
47
+ }
48
+
49
+ interface KeyframesType {
50
+ (strings: TemplateStringsArray, ...values: CssVariableType[]): CssClassNameCommon
51
+ }
52
+
53
+ interface ViewTransitionType {
54
+ (strings: TemplateStringsArray, ...values: CssVariableType[]): Promise<string>
55
+ (content: Promise<string>): Promise<string>
56
+ (): Promise<string>
57
+ }
58
+
59
+ interface StyleType {
60
+ (args?: { children?: Promise<string>; nonce?: string }): HtmlEscapedString
61
+ }
62
+
63
+ /**
64
+ * @experimental
65
+ * `createCssContext` is an experimental feature.
66
+ * The API might be changed.
67
+ *
68
+ * @param options.id - The ID for the style element
69
+ * @param options.classNameSlug - Optional function to customize generated CSS class names
70
+ * @param options.onInvalidSlug - Optional callback function called when an invalid slug is returned from ClassNameSlug
71
+ */
72
+ export const createCssContext = ({
73
+ id,
74
+ classNameSlug,
75
+ onInvalidSlug,
76
+ }: {
77
+ id: Readonly<string>
78
+ classNameSlug?: ClassNameSlug
79
+ onInvalidSlug?: OnInvalidSlug
80
+ }): DefaultContextType => {
81
+ const [cssJsxDomObject, StyleRenderToDom] = createCssJsxDomObjects({ id })
82
+
83
+ const contextMap: WeakMap<object, usedClassNameData> = new WeakMap()
84
+ const nonceMap: WeakMap<object, string | undefined> = new WeakMap()
85
+
86
+ const replaceStyleRe = new RegExp(`(<style id="${id}"(?: nonce="[^"]*")?>.*?)(</style>)`, 's')
87
+
88
+ const newCssClassNameObject = (cssClassName: CssClassNameCommon): Promise<string> => {
89
+ const appendStyle: HtmlEscapedCallback = ({ buffer, context }): Promise<string> | undefined => {
90
+ const [toAdd, added] = contextMap.get(context) as usedClassNameData
91
+ const names = Object.keys(toAdd)
92
+
93
+ if (!names.length) {
94
+ return
95
+ }
96
+
97
+ let stylesStr = ''
98
+ names.forEach((className) => {
99
+ added[className] = true
100
+ stylesStr += className.startsWith(PSEUDO_GLOBAL_SELECTOR)
101
+ ? toAdd[className]
102
+ : `${className[0] === '@' ? '' : '.'}${className}{${toAdd[className]}}`
103
+ })
104
+ contextMap.set(context, [{}, added])
105
+
106
+ if (buffer && replaceStyleRe.test(buffer[0])) {
107
+ buffer[0] = buffer[0].replace(replaceStyleRe, (_, pre, post) => `${pre}${stylesStr}${post}`)
108
+ return
109
+ }
110
+
111
+ const nonce = nonceMap.get(context)
112
+ const appendStyleScript = `<script${
113
+ nonce ? ` nonce="${nonce}"` : ''
114
+ }>document.querySelector('#${id}').textContent+=${JSON.stringify(stylesStr)}</script>`
115
+
116
+ if (buffer) {
117
+ buffer[0] = `${appendStyleScript}${buffer[0]}`
118
+ return
119
+ }
120
+
121
+ return Promise.resolve(appendStyleScript)
122
+ }
123
+
124
+ const addClassNameToContext: HtmlEscapedCallback = ({ context }) => {
125
+ if (!contextMap.has(context)) {
126
+ contextMap.set(context, [{}, {}])
127
+ }
128
+ const [toAdd, added] = contextMap.get(context) as usedClassNameData
129
+ let allAdded = true
130
+ if (!added[cssClassName[SELECTOR]]) {
131
+ allAdded = false
132
+ toAdd[cssClassName[SELECTOR]] = cssClassName[STYLE_STRING]
133
+ }
134
+ cssClassName[SELECTORS].forEach(
135
+ ({ [CLASS_NAME]: className, [STYLE_STRING]: styleString }) => {
136
+ if (!added[className]) {
137
+ allAdded = false
138
+ toAdd[className] = styleString
139
+ }
140
+ }
141
+ )
142
+ if (allAdded) {
143
+ return
144
+ }
145
+
146
+ return Promise.resolve(raw('', [appendStyle]))
147
+ }
148
+
149
+ // external class names from cx() are untrusted but the result is marked isEscaped,
150
+ // so escape it here. skip the buffer when there is nothing to escape.
151
+ const rawClassName = cssClassName[CLASS_NAME]
152
+ let escapedClassName = rawClassName
153
+ if (/[&<>'"]/.test(rawClassName)) {
154
+ const escapedBuffer: [string] = ['']
155
+ escapeToBuffer(rawClassName, escapedBuffer)
156
+ escapedClassName = escapedBuffer[0]
157
+ }
158
+ const className = new String(escapedClassName) as CssClassName
159
+ Object.assign(className, cssClassName)
160
+ ;(className as HtmlEscapedString).isEscaped = true
161
+ ;(className as HtmlEscapedString).callbacks = [addClassNameToContext]
162
+ const promise = Promise.resolve(className)
163
+ Object.assign(promise, cssClassName)
164
+
165
+ promise.toString = cssJsxDomObject.toString
166
+ return promise
167
+ }
168
+
169
+ const css: CssType = (strings, ...values) => {
170
+ return newCssClassNameObject(cssCommon(strings, values, classNameSlug, onInvalidSlug))
171
+ }
172
+
173
+ const cx: CxType = (...args) => {
174
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
+ args = cxCommon(args as any) as any
176
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
177
+ return css(Array(args.length).fill('') as any, ...args)
178
+ }
179
+
180
+ const keyframes: KeyframesType = (strings, ...values) =>
181
+ keyframesCommon(strings, values, classNameSlug, onInvalidSlug)
182
+
183
+ const viewTransition: ViewTransitionType = ((
184
+ strings: TemplateStringsArray | Promise<string> | undefined,
185
+ ...values: CssVariableType[]
186
+ ) => {
187
+ return newCssClassNameObject(
188
+ viewTransitionCommon(strings as any, values, classNameSlug, onInvalidSlug) // eslint-disable-line @typescript-eslint/no-explicit-any
189
+ )
190
+ }) as ViewTransitionType
191
+
192
+ const Style: StyleType = ({ children, nonce } = {}) =>
193
+ raw(
194
+ `<style id="${id}"${nonce ? ` nonce="${nonce}"` : ''}>${
195
+ children ? (children as unknown as CssClassName)[STYLE_STRING] : ''
196
+ }</style>`,
197
+ [
198
+ ({ context }) => {
199
+ nonceMap.set(context, nonce)
200
+ return undefined
201
+ },
202
+ ]
203
+ )
204
+
205
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
206
+ ;(Style as any)[DOM_RENDERER] = StyleRenderToDom
207
+
208
+ return {
209
+ css,
210
+ cx,
211
+ keyframes,
212
+ viewTransition: viewTransition as ViewTransitionType,
213
+ Style,
214
+ }
215
+ }
216
+
217
+ interface DefaultContextType {
218
+ css: CssType
219
+ cx: CxType
220
+ keyframes: KeyframesType
221
+ viewTransition: ViewTransitionType
222
+ Style: StyleType
223
+ }
224
+
225
+ const defaultContext: DefaultContextType = createCssContext({
226
+ id: DEFAULT_STYLE_ID,
227
+ })
228
+
229
+ /**
230
+ * @experimental
231
+ * `css` is an experimental feature.
232
+ * The API might be changed.
233
+ */
234
+ export const css = defaultContext.css
235
+
236
+ /**
237
+ * @experimental
238
+ * `cx` is an experimental feature.
239
+ * The API might be changed.
240
+ */
241
+ export const cx = defaultContext.cx
242
+
243
+ /**
244
+ * @experimental
245
+ * `keyframes` is an experimental feature.
246
+ * The API might be changed.
247
+ */
248
+ export const keyframes = defaultContext.keyframes
249
+
250
+ /**
251
+ * @experimental
252
+ * `viewTransition` is an experimental feature.
253
+ * The API might be changed.
254
+ */
255
+ export const viewTransition = defaultContext.viewTransition
256
+
257
+ /**
258
+ * @experimental
259
+ * `Style` is an experimental feature.
260
+ * The API might be changed.
261
+ */
262
+ export const Style = defaultContext.Style
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @module
3
+ * SSG Helper for Acryl.
4
+ */
5
+
6
+ export * from './ssg.ts'
7
+ export {
8
+ X_ACRYL_DISABLE_SSG_HEADER_KEY,
9
+ ssgParams,
10
+ isSSGContext,
11
+ disableSSG,
12
+ onlySSG,
13
+ } from './middleware.ts'
14
+ export { defaultPlugin, redirectPlugin } from './plugins.ts'
@@ -0,0 +1,83 @@
1
+ import type { Context } from '../../context.ts'
2
+ import type { Env, MiddlewareHandler } from '../../types.ts'
3
+ import { isDynamicRoute } from './utils.ts'
4
+
5
+ export const SSG_CONTEXT = 'ACRYL_SSG_CONTEXT'
6
+ export const X_ACRYL_DISABLE_SSG_HEADER_KEY = 'x-acryl-disable-ssg'
7
+
8
+ /**
9
+ * @deprecated
10
+ * Use `X_ACRYL_DISABLE_SSG_HEADER_KEY` instead.
11
+ * This constant will be removed in the next minor version.
12
+ */
13
+ export const SSG_DISABLED_RESPONSE = (() => {
14
+ try {
15
+ return new Response('SSG is disabled', {
16
+ status: 404,
17
+ headers: { [X_ACRYL_DISABLE_SSG_HEADER_KEY]: 'true' },
18
+ })
19
+ } catch {
20
+ return null
21
+ }
22
+ })() as Response
23
+
24
+ interface SSGParam {
25
+ [key: string]: string
26
+ }
27
+ export type SSGParams = SSGParam[]
28
+
29
+ interface SSGParamsMiddleware {
30
+ <E extends Env = Env>(
31
+ generateParams: (c: Context<E>) => SSGParams | Promise<SSGParams>
32
+ ): MiddlewareHandler<E>
33
+ <E extends Env = Env>(params: SSGParams): MiddlewareHandler<E>
34
+ }
35
+
36
+ export type AddedSSGDataRequest = Request & {
37
+ ssgParams?: SSGParams
38
+ }
39
+
40
+ /**
41
+ * Define SSG Route
42
+ */
43
+ export const ssgParams: SSGParamsMiddleware = (params) => async (c, next) => {
44
+ if (isDynamicRoute(c.req.path)) {
45
+ ;(c.req.raw as AddedSSGDataRequest).ssgParams = Array.isArray(params) ? params : await params(c)
46
+ return c.notFound() // Prevent subsequent handler execution after ssgParams
47
+ }
48
+ await next()
49
+ }
50
+
51
+ /**
52
+ * @experimental
53
+ * `isSSGContext` is an experimental feature.
54
+ * The API might be changed.
55
+ */
56
+ export const isSSGContext = (c: Context): boolean => !!c.env?.[SSG_CONTEXT]
57
+
58
+ /**
59
+ * @experimental
60
+ * `disableSSG` is an experimental feature.
61
+ * The API might be changed.
62
+ */
63
+ export const disableSSG = (): MiddlewareHandler =>
64
+ async function disableSSG(c, next) {
65
+ if (isSSGContext(c)) {
66
+ c.header(X_ACRYL_DISABLE_SSG_HEADER_KEY, 'true')
67
+ return c.notFound()
68
+ }
69
+ await next()
70
+ }
71
+
72
+ /**
73
+ * @experimental
74
+ * `onlySSG` is an experimental feature.
75
+ * The API might be changed.
76
+ */
77
+ export const onlySSG = (): MiddlewareHandler =>
78
+ async function onlySSG(c, next) {
79
+ if (!isSSGContext(c)) {
80
+ return c.notFound()
81
+ }
82
+ await next()
83
+ }