ranuts 0.4.1-alpha.1 → 0.5.0

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 (331) hide show
  1. package/CLAUDE.md +178 -26
  2. package/README.de.md +62 -0
  3. package/README.es.md +62 -0
  4. package/README.fa.md +62 -0
  5. package/README.ja.md +62 -0
  6. package/README.ko.md +62 -0
  7. package/README.md +35 -90
  8. package/README.pt.md +62 -0
  9. package/README.zh-CN.md +35 -89
  10. package/dist/iife/index.iife.js +4 -0
  11. package/dist/iife/utils.iife.js +4 -0
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +306 -1
  14. package/dist/src/_virtual/_rolldown/runtime/index.js +12 -0
  15. package/dist/src/conversation/engine.d.ts +109 -0
  16. package/dist/src/conversation/engine.js +101 -0
  17. package/dist/src/conversation/index.d.ts +12 -0
  18. package/dist/src/conversation/index.js +4 -0
  19. package/dist/src/conversation/types.d.ts +99 -0
  20. package/dist/src/stream/accumulator.d.ts +51 -0
  21. package/dist/src/stream/accumulator.js +79 -0
  22. package/dist/src/stream/budget.d.ts +89 -0
  23. package/dist/src/stream/budget.js +45 -0
  24. package/dist/src/stream/index.d.ts +25 -0
  25. package/dist/src/stream/index.js +11 -0
  26. package/dist/src/stream/sse.d.ts +51 -0
  27. package/dist/src/stream/sse.js +61 -0
  28. package/dist/src/stream/types.d.ts +106 -0
  29. package/dist/src/sw/index.js +52 -1
  30. package/dist/src/utils/async.js +49 -0
  31. package/dist/src/utils/audioRecorder.js +1121 -0
  32. package/dist/src/utils/behavior.js +9 -0
  33. package/dist/src/utils/binary.js +89 -0
  34. package/dist/src/utils/bom.d.ts +31 -9
  35. package/dist/src/utils/bom.js +165 -0
  36. package/dist/src/utils/bridge.js +310 -0
  37. package/dist/src/utils/canvas.d.ts +1 -0
  38. package/dist/src/utils/canvas.js +103 -0
  39. package/dist/src/utils/chain.js +76 -0
  40. package/dist/src/utils/color.d.ts +0 -1
  41. package/dist/src/utils/color.js +312 -0
  42. package/dist/src/utils/compose.js +22 -0
  43. package/dist/src/utils/console.js +22 -0
  44. package/dist/src/utils/debounce.js +18 -0
  45. package/dist/src/utils/device.d.ts +0 -9
  46. package/dist/src/utils/device.js +31 -0
  47. package/dist/src/utils/diff.d.ts +51 -0
  48. package/dist/src/utils/diff.js +110 -0
  49. package/dist/src/utils/dom.d.ts +1 -1
  50. package/dist/src/utils/dom.js +89 -0
  51. package/dist/src/utils/error.js +11 -0
  52. package/dist/src/utils/event.d.ts +3 -3
  53. package/dist/src/utils/event.js +39 -0
  54. package/dist/src/utils/file.js +14 -0
  55. package/dist/src/utils/func.js +4 -0
  56. package/dist/src/utils/i18n/index.js +79 -1
  57. package/dist/src/utils/idb.js +177 -0
  58. package/dist/src/utils/img.d.ts +1 -1
  59. package/dist/src/utils/img.js +68 -0
  60. package/dist/src/utils/index.d.ts +81 -77
  61. package/dist/src/utils/index.js +306 -1
  62. package/dist/src/utils/lang.d.ts +23 -6
  63. package/dist/src/utils/lang.js +42 -0
  64. package/dist/src/utils/localePath.js +48 -0
  65. package/dist/src/utils/memoize.d.ts +1 -7
  66. package/dist/src/utils/memoize.js +16 -0
  67. package/dist/src/utils/mimeType.js +841 -0
  68. package/dist/src/utils/monitor.js +84 -0
  69. package/dist/src/utils/network.js +117 -0
  70. package/dist/src/utils/noop.js +5 -0
  71. package/dist/src/utils/number.d.ts +20 -0
  72. package/dist/src/utils/number.js +185 -0
  73. package/dist/src/utils/obj.d.ts +2 -2
  74. package/dist/src/utils/obj.js +140 -0
  75. package/dist/src/utils/paginate.js +93 -0
  76. package/dist/src/utils/performance.js +26 -0
  77. package/dist/src/utils/placement.d.ts +42 -5
  78. package/dist/src/utils/placement.js +37 -0
  79. package/dist/src/utils/prefetch.js +69 -0
  80. package/dist/src/utils/queue.js +46 -0
  81. package/dist/src/utils/report.js +44 -0
  82. package/dist/src/utils/request.js +35 -0
  83. package/dist/src/utils/script.d.ts +1 -1
  84. package/dist/src/utils/script.js +46 -0
  85. package/dist/src/utils/scroll.d.ts +93 -0
  86. package/dist/src/utils/scroll.js +62 -0
  87. package/dist/src/utils/secure.js +36 -0
  88. package/dist/src/utils/segment.js +43 -0
  89. package/dist/src/utils/signal.d.ts +1 -1
  90. package/dist/src/utils/signal.js +13 -0
  91. package/dist/src/utils/speech.js +59 -0
  92. package/dist/src/utils/storage.js +53 -0
  93. package/dist/src/utils/str.d.ts +0 -6
  94. package/dist/src/utils/str.js +395 -0
  95. package/dist/src/utils/style.js +29 -0
  96. package/dist/src/utils/subscribe.js +58 -0
  97. package/dist/src/utils/throttle.js +17 -0
  98. package/dist/src/utils/time.d.ts +0 -21
  99. package/dist/src/utils/time.js +97 -0
  100. package/dist/src/utils/totp/sha/common.d.ts +1 -1
  101. package/dist/src/utils/totp/sha/common.js +201 -0
  102. package/dist/src/utils/totp/sha/converters.d.ts +1 -1
  103. package/dist/src/utils/totp/sha/converters.js +188 -0
  104. package/dist/src/utils/totp/sha/primitives_32.js +55 -0
  105. package/dist/src/utils/totp/sha/primitives_64.js +85 -0
  106. package/dist/src/utils/totp/sha/sha.d.ts +1 -1
  107. package/dist/src/utils/totp/sha/sha.js +30 -0
  108. package/dist/src/utils/totp/sha/sha1.d.ts +2 -2
  109. package/dist/src/utils/totp/sha/sha1.js +51 -0
  110. package/dist/src/utils/totp/sha/sha256.d.ts +2 -2
  111. package/dist/src/utils/totp/sha/sha256.js +56 -0
  112. package/dist/src/utils/totp/sha/sha3.d.ts +3 -3
  113. package/dist/src/utils/totp/sha/sha3.js +253 -0
  114. package/dist/src/utils/totp/sha/sha512.d.ts +3 -3
  115. package/dist/src/utils/totp/sha/sha512.js +177 -0
  116. package/dist/src/utils/totp/totp.js +49 -0
  117. package/dist/src/utils/tween.js +59 -0
  118. package/dist/src/utils/visual/application.d.ts +4 -4
  119. package/dist/src/utils/visual/application.js +42 -0
  120. package/dist/src/utils/visual/enums.js +19 -0
  121. package/dist/src/utils/visual/event/boundary.d.ts +2 -2
  122. package/dist/src/utils/visual/event/boundary.js +93 -0
  123. package/dist/src/utils/visual/event/event.d.ts +1 -1
  124. package/dist/src/utils/visual/event/event.js +34 -0
  125. package/dist/src/utils/visual/event/index.d.ts +4 -4
  126. package/dist/src/utils/visual/event/types.d.ts +2 -2
  127. package/dist/src/utils/visual/event/types.js +23 -0
  128. package/dist/src/utils/visual/graphics/graphics.d.ts +8 -8
  129. package/dist/src/utils/visual/graphics/graphics.js +168 -0
  130. package/dist/src/utils/visual/graphics/graphicsData.d.ts +3 -3
  131. package/dist/src/utils/visual/graphics/graphicsData.js +12 -0
  132. package/dist/src/utils/visual/graphics/graphicsGeometry.d.ts +7 -7
  133. package/dist/src/utils/visual/graphics/graphicsGeometry.js +39 -0
  134. package/dist/src/utils/visual/graphics/index.d.ts +3 -3
  135. package/dist/src/utils/visual/index.d.ts +8 -8
  136. package/dist/src/utils/visual/index.js +20 -1
  137. package/dist/src/utils/visual/math/bezier.js +15 -0
  138. package/dist/src/utils/visual/math/enums.js +6 -0
  139. package/dist/src/utils/visual/math/index.d.ts +4 -4
  140. package/dist/src/utils/visual/math/matrix.d.ts +1 -1
  141. package/dist/src/utils/visual/math/matrix.js +59 -0
  142. package/dist/src/utils/visual/math/transform.d.ts +2 -2
  143. package/dist/src/utils/visual/math/transform.js +50 -0
  144. package/dist/src/utils/visual/render/batchRenderer.d.ts +4 -4
  145. package/dist/src/utils/visual/render/batchRenderer.js +59 -0
  146. package/dist/src/utils/visual/render/canvasRenderer.d.ts +3 -3
  147. package/dist/src/utils/visual/render/canvasRenderer.js +17 -0
  148. package/dist/src/utils/visual/render/filter.d.ts +1 -1
  149. package/dist/src/utils/visual/render/filter.js +92 -0
  150. package/dist/src/utils/visual/render/index.d.ts +2 -2
  151. package/dist/src/utils/visual/render/index.js +20 -0
  152. package/dist/src/utils/visual/render/render.d.ts +4 -4
  153. package/dist/src/utils/visual/render/render.js +19 -0
  154. package/dist/src/utils/visual/render/renderTarget.js +28 -0
  155. package/dist/src/utils/visual/render/utils/batch/index.d.ts +4 -4
  156. package/dist/src/utils/visual/render/utils/batch/index.js +88 -0
  157. package/dist/src/utils/visual/render/utils/earcut.js +328 -0
  158. package/dist/src/utils/visual/render/utils/float.js +65 -0
  159. package/dist/src/utils/visual/render/utils/index.js +50 -0
  160. package/dist/src/utils/visual/render/utils/verticy.d.ts +2 -2
  161. package/dist/src/utils/visual/render/utils/verticy.js +162 -0
  162. package/dist/src/utils/visual/render/utils/webgl/initShader.d.ts +1 -1
  163. package/dist/src/utils/visual/render/utils/webgl/initShader.js +31 -0
  164. package/dist/src/utils/visual/render/utils/webgl/shaders.js +22 -0
  165. package/dist/src/utils/visual/render/utils/webgpu/shaders.js +32 -0
  166. package/dist/src/utils/visual/render/webGPURenderer.d.ts +2 -2
  167. package/dist/src/utils/visual/render/webGPURenderer.js +185 -0
  168. package/dist/src/utils/visual/render/webGlRenderer.d.ts +2 -2
  169. package/dist/src/utils/visual/render/webGlRenderer.js +88 -0
  170. package/dist/src/utils/visual/shape/circle.d.ts +3 -3
  171. package/dist/src/utils/visual/shape/circle.js +17 -0
  172. package/dist/src/utils/visual/shape/ellipse.d.ts +3 -3
  173. package/dist/src/utils/visual/shape/ellipse.js +18 -0
  174. package/dist/src/utils/visual/shape/index.d.ts +6 -6
  175. package/dist/src/utils/visual/shape/polygon.d.ts +3 -3
  176. package/dist/src/utils/visual/shape/polygon.js +29 -0
  177. package/dist/src/utils/visual/shape/rectangle.d.ts +3 -3
  178. package/dist/src/utils/visual/shape/rectangle.js +18 -0
  179. package/dist/src/utils/visual/shape/roundedRectangle.d.ts +3 -3
  180. package/dist/src/utils/visual/shape/roundedRectangle.js +32 -0
  181. package/dist/src/utils/visual/shape/shape.d.ts +2 -2
  182. package/dist/src/utils/visual/shape/shape.js +5 -0
  183. package/dist/src/utils/visual/style/fill.js +18 -0
  184. package/dist/src/utils/visual/style/index.d.ts +2 -2
  185. package/dist/src/utils/visual/style/line.d.ts +2 -2
  186. package/dist/src/utils/visual/style/line.js +18 -0
  187. package/dist/src/utils/visual/types.d.ts +1 -1
  188. package/dist/src/utils/visual/vertex/container.d.ts +5 -5
  189. package/dist/src/utils/visual/vertex/container.js +54 -0
  190. package/dist/src/utils/visual/vertex/point.js +37 -0
  191. package/dist/src/utils/visual/vertex/vertex.d.ts +7 -7
  192. package/dist/src/utils/visual/vertex/vertex.js +76 -0
  193. package/dist/src/utils/worker.js +89 -0
  194. package/dist/src/utils/zip.js +161 -0
  195. package/dist/src/vnode/h.d.ts +1 -1
  196. package/dist/src/vnode/h.js +22 -0
  197. package/dist/src/vnode/hooks.d.ts +1 -1
  198. package/dist/src/vnode/htmlDomApi.js +94 -0
  199. package/dist/src/vnode/index.d.ts +16 -16
  200. package/dist/src/vnode/index.js +28 -1
  201. package/dist/src/vnode/init.d.ts +1 -1
  202. package/dist/src/vnode/init.js +104 -0
  203. package/dist/src/vnode/is.d.ts +1 -1
  204. package/dist/src/vnode/is.js +20 -0
  205. package/dist/src/vnode/modules/attributes.d.ts +1 -1
  206. package/dist/src/vnode/modules/attributes.js +21 -0
  207. package/dist/src/vnode/modules/class.d.ts +1 -1
  208. package/dist/src/vnode/modules/class.js +18 -0
  209. package/dist/src/vnode/modules/index.js +15 -0
  210. package/dist/src/vnode/modules/listeners.d.ts +1 -1
  211. package/dist/src/vnode/modules/listeners.js +36 -0
  212. package/dist/src/vnode/modules/props.d.ts +1 -1
  213. package/dist/src/vnode/modules/props.js +17 -0
  214. package/dist/src/vnode/modules/style.d.ts +1 -1
  215. package/dist/src/vnode/modules/style.js +52 -0
  216. package/dist/src/vnode/vnode.d.ts +6 -6
  217. package/dist/src/vnode/vnode.js +13 -0
  218. package/dist/third-party/jschardet/LICENSE.txt +504 -0
  219. package/dist/third-party/jschardet/NOTICE.txt +33 -0
  220. package/docs/API.md +86 -65
  221. package/package.json +20 -15
  222. package/dist/bin/generate-api-docs.d.ts +0 -1
  223. package/dist/build/build.es.d.ts +0 -2
  224. package/dist/build/build.umd.d.ts +0 -2
  225. package/dist/build/build.umd.node.d.ts +0 -2
  226. package/dist/build/build.umd.utils.d.ts +0 -2
  227. package/dist/chain-CTywmh_H.js +0 -1
  228. package/dist/color-B_KMM8UX.js +0 -1
  229. package/dist/enums-BAgbyGdH.js +0 -1
  230. package/dist/examples/clone-deep-example.d.ts +0 -1
  231. package/dist/examples/is-equal-example.d.ts +0 -1
  232. package/dist/i18n-BJIS1fR1.js +0 -1
  233. package/dist/plugins/vite-plugins-banner.d.ts +0 -2
  234. package/dist/rolldown-runtime-I3TIJKkN.js +0 -1
  235. package/dist/src/node/appendFile.d.ts +0 -7
  236. package/dist/src/node/body.d.ts +0 -9
  237. package/dist/src/node/color.d.ts +0 -7
  238. package/dist/src/node/command.d.ts +0 -8
  239. package/dist/src/node/ctx2req.d.ts +0 -5
  240. package/dist/src/node/fileInfo.d.ts +0 -7
  241. package/dist/src/node/fs.d.ts +0 -7
  242. package/dist/src/node/get.d.ts +0 -10
  243. package/dist/src/node/getIPAdress.d.ts +0 -1
  244. package/dist/src/node/index.d.ts +0 -25
  245. package/dist/src/node/index.js +0 -1
  246. package/dist/src/node/isColorSupported.d.ts +0 -2
  247. package/dist/src/node/paresUrl.d.ts +0 -19
  248. package/dist/src/node/readDir.d.ts +0 -6
  249. package/dist/src/node/readFile.d.ts +0 -9
  250. package/dist/src/node/router.d.ts +0 -42
  251. package/dist/src/node/send.d.ts +0 -7
  252. package/dist/src/node/server.d.ts +0 -18
  253. package/dist/src/node/startTask.d.ts +0 -2
  254. package/dist/src/node/stream.d.ts +0 -15
  255. package/dist/src/node/taskEnd.d.ts +0 -2
  256. package/dist/src/node/traverse.d.ts +0 -17
  257. package/dist/src/node/watchFile.d.ts +0 -8
  258. package/dist/src/node/writeFile.d.ts +0 -8
  259. package/dist/src/node/ws.d.ts +0 -8
  260. package/dist/src/utils/visual/render/utils/batch/index.test.d.ts +0 -1
  261. package/dist/src/utils/visual/render/utils/index.test.d.ts +0 -1
  262. package/dist/test/binary.test.d.ts +0 -1
  263. package/dist/test/bridge.test.d.ts +0 -1
  264. package/dist/test/canvas.test.d.ts +0 -1
  265. package/dist/test/clearBr.test.d.ts +0 -1
  266. package/dist/test/cloneDeep.test.d.ts +0 -1
  267. package/dist/test/color.test.d.ts +0 -1
  268. package/dist/test/command.test.d.ts +0 -1
  269. package/dist/test/encodeUrl.test.d.ts +0 -1
  270. package/dist/test/escapeHtml.test.d.ts +0 -1
  271. package/dist/test/is-equal.test.d.ts +0 -1
  272. package/dist/test/mimeType.test.d.ts +0 -1
  273. package/dist/test/package-exports.test.d.ts +0 -1
  274. package/dist/test/server.test.d.ts +0 -1
  275. package/dist/test/status.test.d.ts +0 -1
  276. package/dist/test/sw.test.d.ts +0 -1
  277. package/dist/test/totp.test.d.ts +0 -1
  278. package/dist/test/tween.test.d.ts +0 -1
  279. package/dist/test/utils/async.test.d.ts +0 -1
  280. package/dist/test/utils/autosize.test.d.ts +0 -1
  281. package/dist/test/utils/color-grade.test.d.ts +0 -1
  282. package/dist/test/utils/compose.test.d.ts +0 -1
  283. package/dist/test/utils/event.test.d.ts +0 -1
  284. package/dist/test/utils/file-read.test.d.ts +0 -1
  285. package/dist/test/utils/format.test.d.ts +0 -1
  286. package/dist/test/utils/i18n.test.d.ts +0 -1
  287. package/dist/test/utils/idb-collection.test.d.ts +0 -1
  288. package/dist/test/utils/idb.test.d.ts +0 -1
  289. package/dist/test/utils/instrumentation.test.d.ts +0 -1
  290. package/dist/test/utils/interp.test.d.ts +0 -1
  291. package/dist/test/utils/lang.test.d.ts +0 -1
  292. package/dist/test/utils/locale-path.test.d.ts +0 -1
  293. package/dist/test/utils/media-query.test.d.ts +0 -1
  294. package/dist/test/utils/mergeObj.test.d.ts +0 -1
  295. package/dist/test/utils/number-parse.test.d.ts +0 -1
  296. package/dist/test/utils/paginate.test.d.ts +0 -1
  297. package/dist/test/utils/placement.test.d.ts +0 -1
  298. package/dist/test/utils/prefetch.test.d.ts +0 -1
  299. package/dist/test/utils/query-storage.test.d.ts +0 -1
  300. package/dist/test/utils/queue.test.d.ts +0 -1
  301. package/dist/test/utils/report-config.test.d.ts +0 -1
  302. package/dist/test/utils/report-image.test.d.ts +0 -1
  303. package/dist/test/utils/secure.test.d.ts +0 -1
  304. package/dist/test/utils/segment.test.d.ts +0 -1
  305. package/dist/test/utils/signal-once.test.d.ts +0 -1
  306. package/dist/test/utils/single-flight.test.d.ts +0 -1
  307. package/dist/test/utils/speech.test.d.ts +0 -1
  308. package/dist/test/utils/text-boundary.test.d.ts +0 -1
  309. package/dist/test/utils/time.test.d.ts +0 -1
  310. package/dist/test/utils/timing.test.d.ts +0 -1
  311. package/dist/test/utils/truncate.test.d.ts +0 -1
  312. package/dist/test/utils/visual/filter.test.d.ts +0 -1
  313. package/dist/test/utils/worker-client.test.d.ts +0 -1
  314. package/dist/test/utils/worker-serve.test.d.ts +0 -1
  315. package/dist/test/utils/zip.test.d.ts +0 -1
  316. package/dist/test/visual/math.test.d.ts +0 -1
  317. package/dist/test/visual-application.test.d.ts +0 -1
  318. package/dist/test/visual-batch.test.d.ts +0 -1
  319. package/dist/test/visual-math.test.d.ts +0 -1
  320. package/dist/test/vnode/index.d.ts +0 -1
  321. package/dist/test/vnode/server.d.ts +0 -2
  322. package/dist/test/vnode/vnode.d.ts +0 -1
  323. package/dist/test/vnode.test.d.ts +0 -1
  324. package/dist/test/websocket.test.d.ts +0 -1
  325. package/dist/test/writeFile.test.d.ts +0 -1
  326. package/dist/umd/index.umd.cjs +0 -1
  327. package/dist/umd/node/node.umd.cjs +0 -1
  328. package/dist/umd/utils/utils.umd.cjs +0 -1
  329. package/dist/utils-BNwhohXq.js +0 -1
  330. package/dist/vite.config.d.ts +0 -8
  331. package/dist/vitest.config.d.ts +0 -2
package/CLAUDE.md CHANGED
@@ -13,7 +13,8 @@ and Node server tooling. Multi-entry, tree-shakeable, ships ESM + UMD.
13
13
 
14
14
  - **[docs/API.md](docs/API.md)** — ⭐ generated, authoritative list of **every exported
15
15
  symbol** with its signature + one-line description, grouped by entry point. Regenerate
16
- with `npm run doc:api` after changing any public API. Read this to find what exists.
16
+ with `npm run doc:api` after changing any public API — CI fails if you forget. Read
17
+ this to find what exists.
17
18
  - **This file** — orientation: which entry to import, runtime constraints, conventions,
18
19
  and gotchas. Read this to decide _where_ things go and _how_ to add them.
19
20
 
@@ -27,21 +28,21 @@ from the **subpath that owns it** (below) — not from a deep source path.
27
28
  Each subpath is an independent, tree-shakeable barrel. Import from the subpath, never from
28
29
  `ranuts/dist/...` or `@/...` (that alias is internal to the source).
29
30
 
30
- | Import from | Source | What | Runtime |
31
- | --------------- | --------------------------- | --------------------------------------------------- | ------------------ |
32
- | `ranuts` | `index.ts` | Root barrel — re-exports the utils + visual surface | browser + node |
33
- | `ranuts/utils` | `src/utils/index.ts` | DOM/BOM, string, object, number, color, time, etc. | browser + node\* |
34
- | `ranuts/node` | `src/node/index.ts` | HTTP server, router, ws, fs, streams, middleware | **node only** |
35
- | `ranuts/visual` | `src/utils/visual/index.ts` | 2D rendering engine (Canvas / WebGL / WebGPU) | **browser only** |
36
- | `ranuts/i18n` | `src/utils/i18n.ts` | `I18nCore` / `createI18n` / `useI18n` — DOM-free | browser + node |
37
- | `ranuts/sw` | `src/sw/index.ts` | Cache strategies + the precache protocol's SW half | **service worker** |
38
- | `ranuts/vnode` | `src/vnode/index.ts` | Snabbdom-style virtual DOM (`h`, `init`, modules) | browser |
31
+ | Import from | Source | What | Runtime |
32
+ | --------------------- | --------------------------- | --------------------------------------------------------------- | ------------------ |
33
+ | `ranuts` | `index.ts` | Root barrel — re-exports the utils + visual surface | browser + node |
34
+ | `ranuts/utils` | `src/utils/index.ts` | DOM/BOM, string, object, number, color, time, etc. | browser + node\* |
35
+ | `ranuts/visual` | `src/utils/visual/index.ts` | 2D rendering engine (Canvas / WebGL / WebGPU) | **browser only** |
36
+ | `ranuts/i18n` | `src/utils/i18n.ts` | `I18nCore` / `createI18n` / `useI18n` — DOM-free | browser + node |
37
+ | `ranuts/sw` | `src/sw/index.ts` | Cache strategies + the precache protocol's SW half | **service worker** |
38
+ | `ranuts/vnode` | `src/vnode/index.ts` | Snabbdom-style virtual DOM (`h`, `init`, modules) | browser |
39
+ | `ranuts/stream` | `src/stream/index.ts` | SSE parsing + provider-neutral model-stream fold + token budget | browser + node |
40
+ | `ranuts/conversation` | `src/conversation/index.ts` | Event log → renderable conversation nodes | browser + node |
39
41
 
40
42
  \* `ranuts/utils` is broad: most functions are browser-oriented (touch `window`/`document`),
41
43
  but pure helpers (`str`, `obj`, `number`, `compose`, `cloneDeep`, …) run anywhere. Functions
42
44
  that read browser globals generally guard with `typeof window/document !== 'undefined'`; do
43
- the same for any new code. **Do not import `ranuts/node` in browser code** — it pulls in
44
- `fs`/`http`/`child_process` (these are marked external in the build).
45
+ the same for any new code.
45
46
 
46
47
  ---
47
48
 
@@ -73,10 +74,13 @@ packages/ranuts/
73
74
  │ │ ├── canvas.ts # Canvas 2D geometry — roundRectByArc, fanShapedByArc, getLinearGradient
74
75
  │ │ ├── placement.ts # computePlacement — flip/shift floating-panel placement (re-exported by ranui/utils/placement)
75
76
  │ │ ├── tween.ts # easing curves (quad/cubic/quart/quint/sine/expo/circ)
77
+ │ │ ├── scroll.ts # createBottomFollower — follow the floor without fighting the reader
78
+ │ │ ├── diff.ts # diffLines — line-level diff as unified-style hunks
76
79
  │ │ ├── visual/ # ranuts/visual — 2D rendering engine (see below)
77
80
  │ │ └── totp/ # TOTP + hand-rolled SHA
78
- │ ├── node/ # ranuts/node — mini HTTP framework
79
- │ └── vnode/ # ranuts/vnode — virtual DOM
81
+ │ ├── vnode/ # ranuts/vnode — virtual DOM
82
+ │ ├── stream/ # ranuts/stream — SSE + StreamChunk + accumulator + budget
83
+ │ └── conversation/ # ranuts/conversation — event log → nodes, with publication cadence
80
84
  ├── bin/
81
85
  │ ├── build.sh # build (tsc types + vite es/umd)
82
86
  │ └── generate-api-docs.ts # ⭐ doc:api — emits docs/API.md from source + JSDoc
@@ -126,6 +130,137 @@ in `utils/number.ts`; `srgbToLinear`/`luma`/`blend*`/`saturation`/`cosinePalette
126
130
 
127
131
  ---
128
132
 
133
+ ## Streaming a model response
134
+
135
+ `ranuts/stream` is four layers, each usable alone. The split is the point: only the
136
+ middle one is vendor-specific, and it is the one ranuts does **not** ship.
137
+
138
+ 1. `parseEventStream(source)` — bytes → `ServerSentEvent`. Transport only, no model
139
+ concepts. Handles the parts that bite: a chunk boundary anywhere (including inside a
140
+ multi-byte character or between `\r` and `\n`), repeated `data:` joined with `\n`, one
141
+ space stripped after the colon, `:` comment keep-alives, a leading BOM, and a trailing
142
+ block the server never terminated.
143
+ 2. `StreamChunk` — the provider-neutral vocabulary. **You write the mapping** from your
144
+ provider's event shape onto it; `mapEventStream(source, map)` is the seam, and returning
145
+ `[]` from the mapping is how a keep-alive or a `[DONE]` sentinel is dropped.
146
+ 3. `createStreamAccumulator()` — folds chunks into blocks, so a view reads `snapshot()`,
147
+ `text()`, `reasoning()`, or `toolCalls()` instead of concatenating deltas itself.
148
+ 4. `estimateTokens` / `addUsage` / `planCompaction` — the budget. A chat client that skips
149
+ this works for a week and then stops: every turn carries the whole history, the request
150
+ grows monotonically, and one day the provider refuses it as a wall.
151
+
152
+ Non-obvious rules the vocabulary encodes:
153
+
154
+ - **Group by `index`, never by arrival order.** Reasoning and text interleave, and several
155
+ tool calls open at once.
156
+ - **Tool arguments stay raw JSON text.** Half a JSON document is not a value. The
157
+ accumulator never parses `argumentsDelta`; parse once, after `finish`.
158
+ - **`block-start` is optional.** Several providers open a block with its first delta, so
159
+ the accumulator opens one on demand. Do not require it in your mapping either.
160
+ - **`block-end` wins.** When a provider sends an assembled block, it replaces whatever the
161
+ deltas accumulated.
162
+ - **`finish` terminates.** `usage` arrives before it; nothing after it.
163
+
164
+ Non-obvious rules the budget encodes:
165
+
166
+ - **`estimateTokens` is an estimate, and CJK is not four characters a token.** A BPE
167
+ vocabulary trained mostly on Latin script rarely merges CJK, so counting it at the Latin
168
+ rate underestimates a Chinese conversation about fourfold — the difference between
169
+ compacting in time and compacting after the provider refuses. A real tokenizer is a
170
+ per-model dependency measured in megabytes, and this decides _when to act_, not billing.
171
+ - **`addUsage` keeps a field one side omitted.** Providers differ in what they send, and a
172
+ running total that lost `outputTokens` the moment one response omitted it is worse than
173
+ no total.
174
+ - **`planCompaction` counts the summary it will add.** Without that it returns "fits" for a
175
+ request that does not. It also never touches the protected tail, and reports `fits: false`
176
+ rather than compacting it anyway — the caller decides, because nothing can be done there
177
+ that does not lose the user's own words.
178
+ - **It takes sizes, not messages.** What replaces a folded prefix, and which cut points a
179
+ wire format allows, are the caller's business.
180
+
181
+ ## Projecting an event log into a conversation
182
+
183
+ `ranuts/conversation` turns an append-only log into the nodes a view renders. The
184
+ alternative — a view that switches on event type and mutates a component tree — puts
185
+ ordering, identity and partial-update reconciliation in the view, where every new kind of
186
+ content has to be threaded through by hand.
187
+
188
+ Here each kind of content is an independently registered state machine:
189
+
190
+ ```ts
191
+ const engine = createConversationEngine<Event>({ definitions: [message, toolCall] });
192
+ engine.subscribe((nodes) => render(nodes));
193
+ engine.push(event);
194
+ ```
195
+
196
+ A definition says which events are its own (`match`), folds them into its own state
197
+ (`start` / `update`), and never learns that the others exist. Adding a kind is adding a
198
+ definition, not editing a renderer.
199
+
200
+ Semantics you need before writing one:
201
+
202
+ - **Every definition sees every event.** Claims are independent; the engine does not stop
203
+ at the first match, so one log event can drive two nodes.
204
+ - **Order is fixed at `start`.** A node that keeps updating stays where it opened, so a
205
+ streaming message does not jump to the end of the list on every delta.
206
+ - **An `update` for an id with no open node is dropped.** That is honest when the start
207
+ event was trimmed from a paged window; inventing a node from a partial update would
208
+ render something that never existed.
209
+ - **`publication` is the streaming throttle.** `animation-frame` coalesces every delta
210
+ between two paints into one notification; `immediate` is for discrete facts, where
211
+ waiting a frame only adds latency; `none` records without waking the view. Cadence
212
+ escalates and never relaxes — an `immediate` while a frame is pending fires now and
213
+ cancels the frame.
214
+ - **`reader.previous(kind)` is backward-only**, so replaying the same log reproduces the
215
+ same view. A definition that could see nodes started after it would not.
216
+ - **`batch(run)` for any replay.** Without it, restoring a stored conversation is
217
+ quadratic: every event publishes, every publication hands subscribers the whole node
218
+ list, and a DOM subscriber walks all of it. Measured on a 600-message transcript that was
219
+ 5.4 seconds of blocked main thread; batched it is 158ms. A live stream does not need it —
220
+ one delta changes one row.
221
+ - **A subscriber gets the keys that changed.** On a long transcript nearly every row is
222
+ unchanged on every frame, and rewriting all of them once per delta is the difference
223
+ between a transcript that streams and one that stalls. `undefined` means every node
224
+ changed, which is what a reset reports.
225
+ - **`truncate(key)` is what editing, regenerating and branching are made of.** All three
226
+ mean "the conversation diverges here", and what follows the divergence is no longer part
227
+ of it. It cuts by `seq` rather than by position — a node that opened before the cut
228
+ survives even if its latest update came after it, which is the same rule node order
229
+ follows — and returns how many nodes went, because zero is the caller's cue that its own
230
+ idea of the conversation is stale. Without it the only way back is `reset()` and a full
231
+ replay, which discards every node that did not change and makes the view flash.
232
+
233
+ `scheduler` is injectable, which is how the cadence tests run without a paint. The default
234
+ uses `requestAnimationFrame` in a browser and a microtask elsewhere.
235
+
236
+ `<r-conversation>` in ranui is the DOM consumer of all of this — see
237
+ [ranui/CLAUDE.md](../ranui/CLAUDE.md#r-conversation).
238
+
239
+ ## Following the bottom of a scroller
240
+
241
+ `createBottomFollower` (from `ranuts/utils`) keeps an append-only view — a streaming
242
+ transcript, a log tail, a terminal — pinned to its floor without fighting the reader.
243
+
244
+ The hard part is telling your own scroll writes apart from the reader's. It uses an
245
+ **observed-top ledger**: every programmatic write records the `scrollTop` it produced, and
246
+ a scroll event whose position deviates from the ledger is the reader. That covers wheel,
247
+ touch, scrollbar, keyboard and stray `scrollIntoView` calls at once, without listening for
248
+ any input device — no list of device listeners is ever complete.
249
+
250
+ Using it:
251
+
252
+ - Call `follow()` whenever content changes; it is a no-op while the reader is scrolled up.
253
+ - Pass `observe: [column]` for growth that appends no node — streaming text grows an
254
+ existing node, so it has to be observed rather than announced.
255
+ - Before loading older content, `captureAnchor(row)` on a row that is actually on screen,
256
+ and `restoreAnchor()` after the prepend lands. Resolving to `null` means the row did not
257
+ survive; omitting the resolver reuses the captured element.
258
+ - A shrink-clamp never transfers ownership. A reader who had scrolled up stays unpinned
259
+ even when the clamp leaves them at the floor, and re-pins on their next scroll —
260
+ re-pinning on a clamp would take control back with no input from them.
261
+ - Scrolling is always instant. Smooth scrolling animates toward a moving target during
262
+ streaming, and its intermediate positions read as reader input on the next event.
263
+
129
264
  ## Conventions
130
265
 
131
266
  ### Adding a function to an existing module
@@ -159,16 +294,12 @@ Then `npm run doc:api`.
159
294
 
160
295
  - Guard every `window`/`document`/`localStorage`/`navigator` access with `typeof … !== 'undefined'`
161
296
  in code reachable from `ranuts/utils` (it's imported in node too).
162
- - **Guard at call time, not module load.** `isClient` is a module-level constant evaluated when
163
- the module is first imported, so it is `false` forever in any SSR-then-hydrate or
164
- import-early/call-later flow — and it cannot be stubbed in tests. New code checks
165
- `typeof window === 'undefined'` inside the function. `isClient` stays exported for
166
- compatibility but should not be used for new branches.
297
+ - **Guard at call time, not module load.** Check `typeof window === 'undefined'` inside
298
+ the function, so SSR and delayed browser access use the current environment.
167
299
  - Never call `window.setTimeout` / `window.setInterval`. The bare globals work in Node, Web
168
300
  Workers and the browser alike; the `window.`-prefixed ones throw `ReferenceError` outside a
169
301
  document. (This is what made `throttle` unusable in SSR before 0.3.)
170
- - Keep `ranuts/node` server-only; never import it from browser-facing modules. Same for
171
- `ranuts/sw`: it runs in a `ServiceWorkerGlobalScope` with no `window`/`document`, which is
302
+ - Keep `ranuts/sw` separate: it runs in a `ServiceWorkerGlobalScope` with no `window`/`document`, which is
172
303
  why it is its own entry rather than part of the utils barrel.
173
304
 
174
305
  ### Ship both halves of a protocol, or neither
@@ -214,6 +345,7 @@ npm run tsc # type-check only (tsc --noEmit)
214
345
  npm run test # vitest run (node env)
215
346
  npm run test:coverage
216
347
  npm run doc:api # regenerate docs/API.md from source + JSDoc
348
+ npm run doc:api:check # verify it is fresh without writing (what CI runs)
217
349
  ```
218
350
 
219
351
  - **Tests**: Vitest, **node environment** (no jsdom) — `vitest.config.ts` has no `environment`
@@ -222,6 +354,11 @@ npm run doc:api # regenerate docs/API.md from source + JSDoc
222
354
  `getRgb`'s CSS fallback returns black without `document`).
223
355
  - **`onConsoleLog` throws**: the test config fails any test that logs to console — don't leave
224
356
  stray `console.*` in code under test.
357
+ - **Never assert on unseeded randomness**: sampling the real CSPRNG can only estimate the property
358
+ under test, and a window tight enough to catch a real bias also fails on chance every few
359
+ thousand runs — which reads as a mystery CI failure on one matrix leg. Replace the sample with
360
+ scripted bytes and assert the mapping exactly; `test/utils/secure.test.ts` has the `withBytes`
361
+ helper that stubs `crypto.getRandomValues` for the length of one draw.
225
362
 
226
363
  ---
227
364
 
@@ -230,7 +367,6 @@ npm run doc:api # regenerate docs/API.md from source + JSDoc
230
367
  | Pitfall | Fix |
231
368
  | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
232
369
  | Importing from a deep source path or `@/…` | Import from the public subpath (`ranuts/utils`, `ranuts/visual`, …). `@/…` is build-internal only. |
233
- | Importing `ranuts/node` in browser code | It externalizes `fs`/`http`/`child_process` — server-only. Use `ranuts/utils` for browser helpers. |
234
370
  | `new Application()` then `render()` with WebGPU | Device init is async — use `await Application.create(...)`, then `app.start()`. |
235
371
  | Hand-editing `docs/API.md` | It's generated. Edit the source JSDoc and run `npm run doc:api`. |
236
372
  | Adding an export but it's missing from `docs/API.md` | Re-export it from the module's `index.ts` barrel, then `npm run doc:api`. |
@@ -238,13 +374,12 @@ npm run doc:api # regenerate docs/API.md from source + JSDoc
238
374
  | `console.log` left in a function that a test calls | `vitest.config.ts` `onConsoleLog` throws — remove it or the test fails. |
239
375
  | Assuming a GPU/Canvas test can run in CI | Test env is node (no DOM/GPU). Test pure logic; gate visual checks behind a browser demo. |
240
376
  | Passing a non-`#rrggbb` color to the GPU backend and expecting it to fail | It won't — `getRgb` resolves any CSS color via the browser parser, matching the Canvas backend. |
241
- | Branching on `isClient` in new code | It's a module-load-time constant — wrong after SSR, unstubbable in tests. Check `typeof window === 'undefined'` inside the function. |
242
377
  | Reaching for `randomString` / `getRandomString` to make a token or code | Both are `Math.random()` based and predictable. Use `secureRandomString` / `secureToken` from `secure.ts` for anything an attacker would want to guess. |
243
378
  | Comparing a secret with `===` | Returns early at the first differing byte, leaking the shared prefix through timing. Use `safeEqual`. |
379
+ | Asserting a distribution drawn from the real CSPRNG | The window that catches the bias also fires on sampling noise. Script the bytes with `withBytes` (`test/utils/secure.test.ts`) and assert an equality. |
244
380
  | Decoding chunked text per chunk | A multi-byte character straddling a boundary becomes replacement characters. `concatBytes` first, decode once. |
245
381
  | `window.setTimeout` in a `ranuts/utils` module | Throws outside a document. Use the bare `setTimeout`. |
246
382
  | A module-level factory that keeps mutable state shared by everything it produces | Give each produced function its own state (this is why `generateThrottle` was removed). |
247
- | Reaching for `memoize` expecting per-argument caching | It only runs once and ignores later arguments. Use `once` (its new name), `singleFlight` for async, or a `Map` for real keyed caching. |
248
383
  | Assuming `createSignal` deep-compares | It uses `Object.is` since 0.3. Pass `{ equals: isEqual }` when you want deep comparison. |
249
384
  | Testing a boolean URL flag with `getAllQueryString(url).embed` | `?embed` (no value) is the usual spelling and reads as `''`, which is falsy. Use `queryFlag('embed')`. |
250
385
  | `Promise.race([task, timeoutPromise])` for a deadline | Leaks the timer when the task wins. Use `withTimeout` / `withTimeoutFallback` — they always clear it. |
@@ -262,7 +397,7 @@ Each fixed a defect rather than changing a preference.
262
397
  | Symbol | Change | Migration |
263
398
  | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
264
399
  | `generateThrottle` | **Removed.** The factory's generated functions shared one timer and one timestamp, so unrelated throttled functions suppressed each other. | `const f = throttle(fn, delay)` |
265
- | `memoize` | Renamed to `once`, kept as a deprecated alias. The old type declared zero arguments while forwarding them. | Prefer `once`; use `singleFlight` for the async case. |
400
+ | `memoize` | Removed. Use `once`; per-argument caching requires its own key map. |
266
401
  | `createSignal` | `{ equals: true }` used to freeze the signal (it meant "always equal"); every write ran `cloneDeep` + `isEqual`, which overrode `equals` and put an O(size) copy on the write path. | Pass `{ equals: isEqual }` if you relied on deep comparison. |
267
402
  | `QuestQueue` | Rewritten. `add()` never started anything, it popped LIFO, one promise carried unrelated tasks' results, and `allSettled` was off by one. The `total` constructor option is gone. | Use `await queue.add(task)`, `queue.allSettled(tasks)`, `queue.onIdle()`. |
268
403
  | `report` | Return type narrowed to `boolean`; the image fallback is now reachable; **no default endpoint**. | `setReportUrl(url)` once, or pass `report({ url })`. |
@@ -270,7 +405,7 @@ Each fixed a defect rather than changing a preference.
270
405
  | `getHost` | **Removed.** Built a URL from a domain baked into this repo, and a stale edit had reduced its output to the unreachable literal `'//log.'`. | `setReportUrl` / `report({ url })`. |
271
406
  | `createData` | No longer reads a hard-coded `chaxus_prod` cookie; `userId` appears only when configured. | `setReportUrl({ userIdCookie })`. |
272
407
  | `formatJson` | Now `JSON.stringify` with lenient parsing in front. The old hand-rolled formatter corrupted braces/commas **inside string values** and mis-handled escaped quotes. Gained an `indent` param. | Output spacing now matches `JSON.stringify`. |
273
- | `timestampToTime` | Deprecated in favour of `formatDate`. Chained case-insensitive `.replace()` calls made lowercase patterns like `yyyy-mm-dd` render as year-minute-day. | `formatDate(value, pattern)`. |
408
+ | `timestampToTime` | Removed. Use `formatDate` for strings, or `new Date(timestamp)` for a date object. |
274
409
  | `replaceOld` | Returns a restore function instead of `void`. | Additive; keep the returned function. |
275
410
  | `handleConsole` / `handleFetchHook` / `handleXhrHook` / `handleError` / `handleClick` | Return a teardown function instead of `void`. | Additive; call it on teardown. |
276
411
  | `Monitor` | No longer auto-starts from the constructor (it was gated on a global `window.ranlog`, so a second instance silently did nothing). Takes `{ url, channels, … }`; `start()` returns `stop()`. `createData()` is now evaluated per event, not captured at install time. | `new Monitor({ url }).start()`. |
@@ -304,3 +439,20 @@ page. Removed rather than deprecated, per the same `0.x`-experimental rationale
304
439
  in-repo consumers found (`isBangDevice` for an unused `$env.isBang` field, `setAttributeByGlobal`
305
440
  for a one-line `window.__VUE_PROD_DEVTOOLS__ = false`) — both inlined rather than kept as a
306
441
  reason to preserve the library export.
442
+
443
+ ## Alpha removals
444
+
445
+ The `ranuts/node` subpath and the `memoize`, `timeFormat`, `timestampToTime`, `isClient`,
446
+ `md5`, `FMT` exports have been removed. Use platform Node APIs and the maintained utility names.
447
+
448
+ ## Binary response types
449
+
450
+ `requestUrlToBuffer(url)` returns ArrayBuffer data by default. An explicit `responseType`
451
+ selects Blob, string or Document/null; JSON and a fully dynamic mode yield unknown until
452
+ validated. `onProgress` observes download progress; the wrapper does not expose cancellation.
453
+ `createObjectURL` also accepts existing string URLs and returns them unchanged.
454
+
455
+ The declaration build uses the shared `bin/prepare-declarations.mjs` normalizer to resolve
456
+ aliases and add NodeNext-compatible relative specifiers. Packages publish ESM only; no
457
+ CommonJS builds or `.d.cts` forwarding declarations are generated. Browser script tags can
458
+ load `dist/iife/index.iife.js` (`ranuts`) or `dist/iife/utils.iife.js` (`ranuts_utils`).
package/README.de.md ADDED
@@ -0,0 +1,62 @@
1
+ # ranuts
2
+
3
+ TypeScript-Werkzeuge für Browser-APIs, Datenverarbeitung, Streams und 2D-Rendering.
4
+
5
+ [![npm](https://img.shields.io/npm/v/ranuts.svg)](https://www.npmjs.com/package/ranuts) · [MIT](./LICENSE)
6
+
7
+ ESM · IIFE · TypeScript
8
+
9
+ [English](./README.md) | [中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Español](./README.es.md) | [Português](./README.pt.md) | [한국어](./README.ko.md) | **Deutsch** | [فارسی](./README.fa.md)
10
+
11
+ ## Schnellstart
12
+
13
+ ```sh
14
+ npm install ranuts
15
+ ```
16
+
17
+ ```ts
18
+ import { rgbToHex } from 'ranuts/utils';
19
+
20
+ console.log(rgbToHex(1, 2, 3)); // #010203
21
+ ```
22
+
23
+ ## ESM
24
+
25
+ Wähle den Einstieg nach Laufzeit und Aufgabe. Einzelne Helfer brauchen Browser-Globals; nicht alle Funktionen sind serverkompatibel.
26
+
27
+ | Paket | Einsatz |
28
+ | --------------------- | -------------------------------------------------------- |
29
+ | `ranuts/utils` | DOM/BOM, Farben, Binärdaten, Speicher und weitere Helfer |
30
+ | `ranuts/i18n` | Eigenständige Internationalisierung |
31
+ | `ranuts/stream` | SSE-Parsing und Zustand gestreamter Antworten |
32
+ | `ranuts/conversation` | Projektion von Gesprächsereignissen |
33
+ | `ranuts/visual` | 2D-Rendering; Browser |
34
+ | `ranuts/vnode` | Virtuelles DOM; Browser |
35
+ | `ranuts/sw` | Cache-Strategien für Service Worker |
36
+
37
+ ## IIFE / CDN
38
+
39
+ Für ein klassisches script-Tag steht ein eigenständiges IIFE bereit. Ersetze VERSION durch eine veröffentlichte Version; ein Bundler oder Modullader ist nicht nötig.
40
+
41
+ ```html
42
+ <script src="https://cdn.jsdelivr.net/npm/ranuts@VERSION/dist/iife/utils.iife.js"></script>
43
+ <script>
44
+ console.log(ranuts_utils.rgbToHex(1, 2, 3));
45
+ </script>
46
+ ```
47
+
48
+ Das Utility-IIFE stellt `ranuts_utils` bereit, das vollständige `dist/iife/index.iife.js` stellt `ranuts` bereit. Ersetze VERSION durch eine veröffentlichte Version.
49
+
50
+ ## Dokumentation
51
+
52
+ - [ranuts](https://ran.chaxus.com/de/src/ranuts/)
53
+ - [API](./docs/API.md)
54
+ - [Referenz für Maintainer und Agents](./CLAUDE.md)
55
+
56
+ ## Mitwirken
57
+
58
+ [Referenz für Maintainer und Agents](./CLAUDE.md) · [AGENTS.md](https://github.com/chaxus/ran/blob/main/AGENTS.md)
59
+
60
+ ## Lizenz
61
+
62
+ [MIT](./LICENSE)
package/README.es.md ADDED
@@ -0,0 +1,62 @@
1
+ # ranuts
2
+
3
+ Utilidades TypeScript para APIs del navegador, datos, flujos y renderizado 2D.
4
+
5
+ [![npm](https://img.shields.io/npm/v/ranuts.svg)](https://www.npmjs.com/package/ranuts) · [MIT](./LICENSE)
6
+
7
+ ESM · IIFE · TypeScript
8
+
9
+ [English](./README.md) | [中文](./README.zh-CN.md) | [日本語](./README.ja.md) | **Español** | [Português](./README.pt.md) | [한국어](./README.ko.md) | [Deutsch](./README.de.md) | [فارسی](./README.fa.md)
10
+
11
+ ## Inicio rápido
12
+
13
+ ```sh
14
+ npm install ranuts
15
+ ```
16
+
17
+ ```ts
18
+ import { rgbToHex } from 'ranuts/utils';
19
+
20
+ console.log(rgbToHex(1, 2, 3)); // #010203
21
+ ```
22
+
23
+ ## ESM
24
+
25
+ Elige una entrada según el entorno y la tarea. Algunas utilidades necesitan objetos globales del navegador; importar el paquete no hace que todas funcionen en el servidor.
26
+
27
+ | Paquete | Uso |
28
+ | --------------------- | ----------------------------------------------------------- |
29
+ | `ranuts/utils` | DOM/BOM, color, binarios, almacenamiento y otras utilidades |
30
+ | `ranuts/i18n` | Internacionalización independiente |
31
+ | `ranuts/stream` | Análisis SSE y estado de respuestas en streaming |
32
+ | `ranuts/conversation` | Proyección del registro de eventos de conversación |
33
+ | `ranuts/visual` | Renderizado 2D; navegador |
34
+ | `ranuts/vnode` | DOM virtual; navegador |
35
+ | `ranuts/sw` | Estrategias de caché de Service Worker |
36
+
37
+ ## IIFE / CDN
38
+
39
+ Para una etiqueta script clásica, usa un IIFE independiente. Sustituye VERSION por una versión publicada; no necesitas bundler ni cargador de módulos.
40
+
41
+ ```html
42
+ <script src="https://cdn.jsdelivr.net/npm/ranuts@VERSION/dist/iife/utils.iife.js"></script>
43
+ <script>
44
+ console.log(ranuts_utils.rgbToHex(1, 2, 3));
45
+ </script>
46
+ ```
47
+
48
+ El IIFE de utilidades expone `ranuts_utils`; el completo `dist/iife/index.iife.js` expone `ranuts`. Sustituye VERSION por una versión publicada.
49
+
50
+ ## Documentación
51
+
52
+ - [ranuts](https://ran.chaxus.com/es/src/ranuts/)
53
+ - [API](./docs/API.md)
54
+ - [Referencia para mantenedores y agentes](./CLAUDE.md)
55
+
56
+ ## Contribuir
57
+
58
+ [Referencia para mantenedores y agentes](./CLAUDE.md) · [AGENTS.md](https://github.com/chaxus/ran/blob/main/AGENTS.md)
59
+
60
+ ## Licencia
61
+
62
+ [MIT](./LICENSE)
package/README.fa.md ADDED
@@ -0,0 +1,62 @@
1
+ # ranuts
2
+
3
+ ابزارهای TypeScript برای API مرورگر، پردازش داده، جریان‌ها و ترسیم دوبعدی.
4
+
5
+ [![npm](https://img.shields.io/npm/v/ranuts.svg)](https://www.npmjs.com/package/ranuts) · [MIT](./LICENSE)
6
+
7
+ ESM · IIFE · TypeScript
8
+
9
+ [English](./README.md) | [中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Español](./README.es.md) | [Português](./README.pt.md) | [한국어](./README.ko.md) | [Deutsch](./README.de.md) | **فارسی**
10
+
11
+ ## شروع سریع
12
+
13
+ ```sh
14
+ npm install ranuts
15
+ ```
16
+
17
+ ```ts
18
+ import { rgbToHex } from 'ranuts/utils';
19
+
20
+ console.log(rgbToHex(1, 2, 3)); // #010203
21
+ ```
22
+
23
+ ## ESM
24
+
25
+ ورودی را بر اساس محیط اجرا و کار انتخاب کنید. بعضی ابزارها به متغیرهای سراسری مرورگر نیاز دارند و همه توابع روی سرور قابل اجرا نیستند.
26
+
27
+ | بسته | کاربرد |
28
+ | --------------------- | ----------------------------------------------------- |
29
+ | `ranuts/utils` | DOM/BOM، رنگ، داده دودویی، ذخیره‌سازی و ابزارهای دیگر |
30
+ | `ranuts/i18n` | بین‌المللی‌سازی مستقل |
31
+ | `ranuts/stream` | تجزیه SSE و وضعیت پاسخ جریانی |
32
+ | `ranuts/conversation` | نگاشت رویدادهای گفتگو |
33
+ | `ranuts/visual` | ترسیم دوبعدی؛ مرورگر |
34
+ | `ranuts/vnode` | DOM مجازی؛ مرورگر |
35
+ | `ranuts/sw` | راهبردهای کش Service Worker |
36
+
37
+ ## IIFE / CDN
38
+
39
+ برای تگ script معمولی از IIFE مستقل استفاده کنید. VERSION را با نسخه منتشرشده جایگزین کنید؛ نیازی به ابزار ساخت یا بارگذار ماژول نیست.
40
+
41
+ ```html
42
+ <script src="https://cdn.jsdelivr.net/npm/ranuts@VERSION/dist/iife/utils.iife.js"></script>
43
+ <script>
44
+ console.log(ranuts_utils.rgbToHex(1, 2, 3));
45
+ </script>
46
+ ```
47
+
48
+ IIFE ابزارها `ranuts_utils` و بسته کامل `dist/iife/index.iife.js` نام `ranuts` را ارائه می‌کند. VERSION را با نسخه منتشرشده جایگزین کنید.
49
+
50
+ ## مستندات
51
+
52
+ - [ranuts](https://ran.chaxus.com/fa/src/ranuts/)
53
+ - [API](./docs/API.md)
54
+ - [مرجع نگهدارندگان و Agentها](./CLAUDE.md)
55
+
56
+ ## مشارکت
57
+
58
+ [مرجع نگهدارندگان و Agentها](./CLAUDE.md) · [AGENTS.md](https://github.com/chaxus/ran/blob/main/AGENTS.md)
59
+
60
+ ## مجوز
61
+
62
+ [MIT](./LICENSE)
package/README.ja.md ADDED
@@ -0,0 +1,62 @@
1
+ # ranuts
2
+
3
+ ブラウザー API、データ処理、ストリーム、2D 描画向け TypeScript ユーティリティ。
4
+
5
+ [![npm](https://img.shields.io/npm/v/ranuts.svg)](https://www.npmjs.com/package/ranuts) · [MIT](./LICENSE)
6
+
7
+ ESM · IIFE · TypeScript
8
+
9
+ [English](./README.md) | [中文](./README.zh-CN.md) | **日本語** | [Español](./README.es.md) | [Português](./README.pt.md) | [한국어](./README.ko.md) | [Deutsch](./README.de.md) | [فارسی](./README.fa.md)
10
+
11
+ ## クイックスタート
12
+
13
+ ```sh
14
+ npm install ranuts
15
+ ```
16
+
17
+ ```ts
18
+ import { rgbToHex } from 'ranuts/utils';
19
+
20
+ console.log(rgbToHex(1, 2, 3)); // #010203
21
+ ```
22
+
23
+ ## ESM
24
+
25
+ 実行環境と用途に合う入口を選んでください。一部の関数はブラウザーのグローバル変数を必要とし、すべての関数がサーバー対応とは限りません。
26
+
27
+ | パッケージ | 用途 |
28
+ | --------------------- | ------------------------------------- |
29
+ | `ranuts/utils` | DOM/BOM、色、バイナリ、ストレージなど |
30
+ | `ranuts/i18n` | 独立した国際化エンジン |
31
+ | `ranuts/stream` | SSE 解析とストリーム応答の状態 |
32
+ | `ranuts/conversation` | 会話イベントログの投影 |
33
+ | `ranuts/visual` | 2D 描画;ブラウザー |
34
+ | `ranuts/vnode` | 仮想 DOM;ブラウザー |
35
+ | `ranuts/sw` | Service Worker のキャッシュ戦略 |
36
+
37
+ ## IIFE / CDN
38
+
39
+ 通常の script タグでは独立 IIFE を使用します。VERSION を公開済みバージョンに置き換えてください。バンドラーやモジュールローダーは不要です。
40
+
41
+ ```html
42
+ <script src="https://cdn.jsdelivr.net/npm/ranuts@VERSION/dist/iife/utils.iife.js"></script>
43
+ <script>
44
+ console.log(ranuts_utils.rgbToHex(1, 2, 3));
45
+ </script>
46
+ ```
47
+
48
+ ユーティリティ IIFE のグローバル名は `ranuts_utils`、完全版 `dist/iife/index.iife.js` は `ranuts` です。VERSION を公開済みバージョンに置き換えてください。
49
+
50
+ ## ドキュメント
51
+
52
+ - [ranuts](https://ran.chaxus.com/ja/src/ranuts/)
53
+ - [API](./docs/API.md)
54
+ - [メンテナーと Agent 向け資料](./CLAUDE.md)
55
+
56
+ ## 貢献
57
+
58
+ [メンテナーと Agent 向け資料](./CLAUDE.md) · [AGENTS.md](https://github.com/chaxus/ran/blob/main/AGENTS.md)
59
+
60
+ ## ライセンス
61
+
62
+ [MIT](./LICENSE)
package/README.ko.md ADDED
@@ -0,0 +1,62 @@
1
+ # ranuts
2
+
3
+ 브라우저 API, 데이터 처리, 스트림, 2D 렌더링을 위한 TypeScript 유틸리티.
4
+
5
+ [![npm](https://img.shields.io/npm/v/ranuts.svg)](https://www.npmjs.com/package/ranuts) · [MIT](./LICENSE)
6
+
7
+ ESM · IIFE · TypeScript
8
+
9
+ [English](./README.md) | [中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Español](./README.es.md) | [Português](./README.pt.md) | **한국어** | [Deutsch](./README.de.md) | [فارسی](./README.fa.md)
10
+
11
+ ## 빠른 시작
12
+
13
+ ```sh
14
+ npm install ranuts
15
+ ```
16
+
17
+ ```ts
18
+ import { rgbToHex } from 'ranuts/utils';
19
+
20
+ console.log(rgbToHex(1, 2, 3)); // #010203
21
+ ```
22
+
23
+ ## ESM
24
+
25
+ 실행 환경과 작업에 맞는 진입점을 선택하세요. 일부 함수는 브라우저 전역 객체가 필요하며 모든 함수가 서버에서 작동하는 것은 아닙니다.
26
+
27
+ | 패키지 | 용도 |
28
+ | --------------------- | ---------------------------------- |
29
+ | `ranuts/utils` | DOM/BOM, 색상, 바이너리, 저장소 등 |
30
+ | `ranuts/i18n` | 독립 국제화 엔진 |
31
+ | `ranuts/stream` | SSE 파싱과 스트리밍 응답 상태 |
32
+ | `ranuts/conversation` | 대화 이벤트 로그 투영 |
33
+ | `ranuts/visual` | 2D 렌더링; 브라우저 |
34
+ | `ranuts/vnode` | 가상 DOM; 브라우저 |
35
+ | `ranuts/sw` | Service Worker 캐시 전략 |
36
+
37
+ ## IIFE / CDN
38
+
39
+ 일반 script 태그에서는 독립 IIFE를 사용하세요. VERSION을 배포된 버전으로 바꾸면 번들러나 모듈 로더 없이 사용할 수 있습니다.
40
+
41
+ ```html
42
+ <script src="https://cdn.jsdelivr.net/npm/ranuts@VERSION/dist/iife/utils.iife.js"></script>
43
+ <script>
44
+ console.log(ranuts_utils.rgbToHex(1, 2, 3));
45
+ </script>
46
+ ```
47
+
48
+ 유틸리티 IIFE는 `ranuts_utils`, 전체 `dist/iife/index.iife.js`는 `ranuts`를 노출합니다. VERSION을 배포된 버전으로 바꾸세요.
49
+
50
+ ## 문서
51
+
52
+ - [ranuts](https://ran.chaxus.com/ko/src/ranuts/)
53
+ - [API](./docs/API.md)
54
+ - [유지 관리자와 Agent 참고](./CLAUDE.md)
55
+
56
+ ## 기여
57
+
58
+ [유지 관리자와 Agent 참고](./CLAUDE.md) · [AGENTS.md](https://github.com/chaxus/ran/blob/main/AGENTS.md)
59
+
60
+ ## 라이선스
61
+
62
+ [MIT](./LICENSE)