ranuts 0.2.0-alpha.1 → 0.3.0-alpha.1

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 (112) hide show
  1. package/CLAUDE.md +107 -16
  2. package/README.md +7 -5
  3. package/README.zh-CN.md +7 -5
  4. package/dist/chain-CTywmh_H.js +1 -0
  5. package/dist/{color-CRdlaDqQ.js → color-Dohr9BXX.js} +1 -1
  6. package/dist/enums-BAgbyGdH.js +1 -0
  7. package/dist/i18n-Cf5TtRb4.js +1 -0
  8. package/dist/index.d.ts +1 -5
  9. package/dist/index.js +1 -1
  10. package/dist/src/node/appendFile.d.ts +3 -3
  11. package/dist/src/node/fileInfo.d.ts +2 -2
  12. package/dist/src/node/index.js +1 -1
  13. package/dist/src/node/paresUrl.d.ts +1 -1
  14. package/dist/src/node/readFile.d.ts +3 -3
  15. package/dist/src/node/traverse.d.ts +2 -2
  16. package/dist/src/node/watchFile.d.ts +3 -3
  17. package/dist/src/node/writeFile.d.ts +3 -3
  18. package/dist/src/utils/async.d.ts +81 -0
  19. package/dist/src/utils/audioRecorder.d.ts +1 -1
  20. package/dist/src/utils/behavior.d.ts +12 -3
  21. package/dist/src/utils/bom.d.ts +68 -178
  22. package/dist/src/utils/bridge.d.ts +153 -0
  23. package/dist/src/utils/canvas.d.ts +54 -0
  24. package/dist/src/utils/chain.d.ts +80 -0
  25. package/dist/src/utils/color.d.ts +76 -4
  26. package/dist/src/utils/compose.d.ts +1 -1
  27. package/dist/src/utils/console.d.ts +19 -1
  28. package/dist/src/utils/debounce.d.ts +27 -5
  29. package/dist/src/utils/device.d.ts +31 -3
  30. package/dist/src/utils/dom.d.ts +5 -84
  31. package/dist/src/utils/error.d.ts +18 -1
  32. package/dist/src/utils/event.d.ts +61 -0
  33. package/dist/src/utils/file.d.ts +30 -0
  34. package/dist/src/utils/i18n/index.js +1 -0
  35. package/dist/src/utils/i18n.d.ts +69 -0
  36. package/dist/src/utils/idb.d.ts +178 -0
  37. package/dist/src/utils/img.d.ts +60 -4
  38. package/dist/src/utils/index.d.ts +48 -16
  39. package/dist/src/utils/index.js +1 -1
  40. package/dist/src/utils/lang.d.ts +69 -0
  41. package/dist/src/utils/localePath.d.ts +62 -0
  42. package/dist/src/utils/memoize.d.ts +53 -5
  43. package/dist/src/utils/monitor.d.ts +55 -26
  44. package/dist/src/utils/number.d.ts +46 -9
  45. package/dist/src/utils/obj.d.ts +56 -31
  46. package/dist/src/utils/prefetch.d.ts +81 -0
  47. package/dist/src/utils/queue.d.ts +53 -23
  48. package/dist/src/utils/report.d.ts +51 -3
  49. package/dist/src/utils/request.d.ts +26 -7
  50. package/dist/src/utils/script.d.ts +26 -4
  51. package/dist/src/utils/segment.d.ts +62 -0
  52. package/dist/src/utils/signal.d.ts +35 -3
  53. package/dist/src/utils/storage.d.ts +57 -0
  54. package/dist/src/utils/str.d.ts +112 -88
  55. package/dist/src/utils/style.d.ts +31 -0
  56. package/dist/src/utils/subscribe.d.ts +5 -5
  57. package/dist/src/utils/throttle.d.ts +26 -13
  58. package/dist/src/utils/time.d.ts +38 -6
  59. package/dist/src/utils/tween.d.ts +40 -0
  60. package/dist/src/utils/visual/application.d.ts +4 -4
  61. package/dist/src/utils/visual/enums.d.ts +4 -4
  62. package/dist/src/utils/visual/graphics/graphics.d.ts +25 -25
  63. package/dist/src/utils/visual/graphics/graphicsData.d.ts +1 -1
  64. package/dist/src/utils/visual/graphics/graphicsGeometry.d.ts +6 -6
  65. package/dist/src/utils/visual/index.js +1 -1
  66. package/dist/src/utils/visual/math/matrix.d.ts +8 -8
  67. package/dist/src/utils/visual/math/transform.d.ts +1 -1
  68. package/dist/src/utils/visual/render/batchRenderer.d.ts +20 -18
  69. package/dist/src/utils/visual/render/utils/batch/index.d.ts +13 -13
  70. package/dist/src/utils/visual/render/utils/float.d.ts +13 -13
  71. package/dist/src/utils/visual/render/utils/verticy.d.ts +3 -3
  72. package/dist/src/utils/visual/render/utils/webgl/initShader.d.ts +3 -2
  73. package/dist/src/utils/visual/render/utils/webgpu/shaders.d.ts +2 -2
  74. package/dist/src/utils/visual/render/webGPURenderer.d.ts +8 -8
  75. package/dist/src/utils/visual/vertex/container.d.ts +17 -16
  76. package/dist/src/utils/worker.d.ts +76 -0
  77. package/dist/src/utils/zip.d.ts +162 -0
  78. package/dist/src/vnode/index.d.ts +1 -1
  79. package/dist/src/vnode/index.js +1 -1
  80. package/dist/src/vnode/is.d.ts +4 -0
  81. package/dist/test/canvas.test.d.ts +1 -0
  82. package/dist/test/color.test.d.ts +1 -0
  83. package/dist/test/tween.test.d.ts +1 -0
  84. package/dist/test/utils/async.test.d.ts +1 -0
  85. package/dist/test/utils/file-read.test.d.ts +1 -0
  86. package/dist/test/utils/format.test.d.ts +1 -0
  87. package/dist/test/utils/idb.test.d.ts +1 -0
  88. package/dist/test/utils/instrumentation.test.d.ts +1 -0
  89. package/dist/test/utils/lang.test.d.ts +1 -0
  90. package/dist/test/utils/locale-path.test.d.ts +1 -0
  91. package/dist/test/utils/media-query.test.d.ts +1 -0
  92. package/dist/test/utils/number-parse.test.d.ts +1 -0
  93. package/dist/test/utils/prefetch.test.d.ts +1 -0
  94. package/dist/test/utils/query-storage.test.d.ts +1 -0
  95. package/dist/test/utils/queue.test.d.ts +1 -0
  96. package/dist/test/utils/report-config.test.d.ts +1 -0
  97. package/dist/test/utils/report-image.test.d.ts +1 -0
  98. package/dist/test/utils/segment.test.d.ts +1 -0
  99. package/dist/test/utils/signal-once.test.d.ts +1 -0
  100. package/dist/test/utils/single-flight.test.d.ts +1 -0
  101. package/dist/test/utils/timing.test.d.ts +1 -0
  102. package/dist/test/utils/worker-client.test.d.ts +1 -0
  103. package/dist/test/utils/zip.test.d.ts +1 -0
  104. package/dist/umd/index.umd.cjs +1 -1
  105. package/dist/umd/node/node.umd.cjs +1 -1
  106. package/dist/umd/utils/utils.umd.cjs +1 -1
  107. package/dist/utils-BDtXHcK8.js +1 -0
  108. package/docs/API.md +306 -147
  109. package/package.json +9 -6
  110. package/dist/src/vnode/chainDom.d.ts +0 -47
  111. package/dist/subscribe-CINWsor3.js +0 -1
  112. package/dist/utils-_OxsVZmz.js +0 -1
package/CLAUDE.md CHANGED
@@ -33,6 +33,7 @@ Each subpath is an independent, tree-shakeable barrel. Import from the subpath,
33
33
  | `ranuts/utils` | `src/utils/index.ts` | DOM/BOM, string, object, number, color, time, etc. | browser + node\* |
34
34
  | `ranuts/node` | `src/node/index.ts` | HTTP server, router, ws, fs, streams, middleware | **node only** |
35
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 |
36
37
  | `ranuts/vnode` | `src/vnode/index.ts` | Snabbdom-style virtual DOM (`h`, `init`, modules) | browser |
37
38
 
38
39
  \* `ranuts/utils` is broad: most functions are browser-oriented (touch `window`/`document`),
@@ -49,8 +50,25 @@ the same for any new code. **Do not import `ranuts/node` in browser code** — i
49
50
  packages/ranuts/
50
51
  ├── index.ts # Root barrel (re-exports utils + visual + selected)
51
52
  ├── src/
52
- │ ├── utils/ # ranuts/utils — the largest surface (~13.8k LOC)
53
+ │ ├── utils/ # ranuts/utils — the largest surface (~14k LOC)
53
54
  │ │ ├── str.ts obj.ts number.ts color.ts bom.ts dom.ts time.ts …
55
+ │ │ ├── bridge.ts # postMessage request/response (split out of bom.ts)
56
+ │ │ ├── idb.ts # WebDB (declarative stores) + createHandoff (one-shot value handoff)
57
+ │ │ ├── worker.ts # WorkerClient — request/response over a Web Worker
58
+ │ │ ├── zip.ts # ZIP read/rewrite — crc32, inflateRaw, rewriteZip, createZip
59
+ │ │ ├── async.ts # deferred / withTimeout / withTimeoutFallback / delay
60
+ │ │ ├── storage.ts # localStorage* + createStore (prefixed JSON view)
61
+ │ │ ├── segment.ts # offsets ↔ chunks, range→segment splitting (highlights)
62
+ │ │ ├── localePath.ts # createLocalePath — i18n sub-directory URL maths
63
+ │ │ ├── prefetch.ts # whenIdle / networkAllowsDownload / prefetchUrls
64
+ │ │ ├── lang.ts # detectLanguage + resolveLocale (query→cookie→storage→navigator)
65
+ │ │ ├── file.ts # readFileAs* — FileReader promises
66
+ │ │ ├── i18n.ts # ranuts/i18n — I18nCore, {param} interpolation, locale persistence
67
+ │ │ ├── event.ts # EventManager — AbortController-scoped listeners + delegation
68
+ │ │ ├── chain.ts # Chain / create — chainable DOM builder (shared with vnode)
69
+ │ │ ├── style.ts # adoptStyles / adoptSheetText — Shadow DOM CSS injection
70
+ │ │ ├── canvas.ts # Canvas 2D geometry — roundRectByArc, fanShapedByArc, getLinearGradient
71
+ │ │ ├── tween.ts # easing curves (quad/cubic/quart/quint/sine/expo/circ)
54
72
  │ │ ├── visual/ # ranuts/visual — 2D rendering engine (see below)
55
73
  │ │ └── totp/ # TOTP + hand-rolled SHA
56
74
  │ ├── node/ # ranuts/node — mini HTTP framework
@@ -99,12 +117,13 @@ Tests for the color pipeline and batch packing live next to the source as `*.tes
99
117
  ### Adding a function to an existing module
100
118
 
101
119
  1. Write it in the right `src/<module>/*.ts` file with a JSDoc block. This codebase uses the
102
- `@description:` tag (often Chinese) for the summary — the generator reads it:
120
+ `@description:` tag for the summary — the generator reads it. **Comments and JSDoc are
121
+ written in English**; user-facing translations belong in `packages/docs`, not in source:
103
122
  ```ts
104
123
  /**
105
- * @description: 防抖
106
- * @param fn 要执行的函数
107
- * @return 包装后的函数
124
+ * @description: Debounce — run only the last call, `ms` after the calls stop.
125
+ * @param fn function to debounce
126
+ * @return wrapped function with cancel / flush / pending
108
127
  */
109
128
  export const debounce = (fn, ms = 300) => { … };
110
129
  ```
@@ -126,8 +145,41 @@ Then `npm run doc:api`.
126
145
 
127
146
  - Guard every `window`/`document`/`localStorage`/`navigator` access with `typeof … !== 'undefined'`
128
147
  in code reachable from `ranuts/utils` (it's imported in node too).
148
+ - **Guard at call time, not module load.** `isClient` is a module-level constant evaluated when
149
+ the module is first imported, so it is `false` forever in any SSR-then-hydrate or
150
+ import-early/call-later flow — and it cannot be stubbed in tests. New code checks
151
+ `typeof window === 'undefined'` inside the function. `isClient` stays exported for
152
+ compatibility but should not be used for new branches.
153
+ - Never call `window.setTimeout` / `window.setInterval`. The bare globals work in Node, Web
154
+ Workers and the browser alike; the `window.`-prefixed ones throw `ReferenceError` outside a
155
+ document. (This is what made `throttle` unusable in SSR before 0.3.)
129
156
  - Keep `ranuts/node` server-only; never import it from browser-facing modules.
130
157
 
158
+ ### Anything that installs something must return how to uninstall it
159
+
160
+ `debounce`, `throttle`, `watchMediaQuery`, `whenIdle`, `WorkerClient`, `QuestQueue` hand back
161
+ something holding a timer, a listener or a worker. `replaceOld`, `handleConsole`,
162
+ `handleFetchHook`, `handleXhrHook`, `handleError`, `handleClick` and `Monitor.start()` patch a
163
+ global or register a listener. **All of them return a teardown function**, and callers are
164
+ expected to use it.
165
+
166
+ A utility of this shape without a teardown path is incomplete. The failure modes are concrete:
167
+ a pending timer firing into a destroyed component; a hot reload re-patching an already-patched
168
+ `console` until every log is nested through a dozen wrappers and every event is reported N
169
+ times; a test that can never give the next test a clean global back.
170
+
171
+ `replaceOld`'s restore additionally checks that **its own** wrapper is still installed before
172
+ writing the original back — otherwise unwinding an inner layer would silently uninstall an
173
+ outer one.
174
+
175
+ ### No hard-coded endpoints, cookie names or domains
176
+
177
+ A library cannot know where your telemetry goes or what your auth cookie is called. `report`
178
+ requires an endpoint (`setReportUrl` once, or per call) and returns `false` rather than
179
+ guessing; `createData` includes a user id only when `userIdCookie` is configured. This is what
180
+ `getHost` got wrong — it built a URL from a domain baked into this repo, and a stale edit had
181
+ already reduced its output to the unreachable literal `'//log.'`.
182
+
131
183
  ---
132
184
 
133
185
  ## Build, test, docs
@@ -151,14 +203,53 @@ npm run doc:api # regenerate docs/API.md from source + JSDoc
151
203
 
152
204
  ## Gotchas
153
205
 
154
- | Pitfall | Fix |
155
- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
156
- | Importing from a deep source path or `@/…` | Import from the public subpath (`ranuts/utils`, `ranuts/visual`, …). `@/…` is build-internal only. |
157
- | Importing `ranuts/node` in browser code | It externalizes `fs`/`http`/`child_process` — server-only. Use `ranuts/utils` for browser helpers. |
158
- | `new Application()` then `render()` with WebGPU | Device init is async — use `await Application.create(...)`, then `app.start()`. |
159
- | Hand-editing `docs/API.md` | It's generated. Edit the source JSDoc and run `npm run doc:api`. |
160
- | 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`. |
161
- | New entry point not importable as `ranuts/foo` | Wire all three: `package.json` exports + `vite.config.ts` es entry + generator `ENTRIES`. |
162
- | `console.log` left in a function that a test calls | `vitest.config.ts` `onConsoleLog` throws — remove it or the test fails. |
163
- | 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. |
164
- | 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. |
206
+ | Pitfall | Fix |
207
+ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
208
+ | Importing from a deep source path or `@/…` | Import from the public subpath (`ranuts/utils`, `ranuts/visual`, …). `@/…` is build-internal only. |
209
+ | Importing `ranuts/node` in browser code | It externalizes `fs`/`http`/`child_process` — server-only. Use `ranuts/utils` for browser helpers. |
210
+ | `new Application()` then `render()` with WebGPU | Device init is async — use `await Application.create(...)`, then `app.start()`. |
211
+ | Hand-editing `docs/API.md` | It's generated. Edit the source JSDoc and run `npm run doc:api`. |
212
+ | 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`. |
213
+ | New entry point not importable as `ranuts/foo` | Wire all three: `package.json` exports + `vite.config.ts` es entry + generator `ENTRIES`. |
214
+ | `console.log` left in a function that a test calls | `vitest.config.ts` `onConsoleLog` throws — remove it or the test fails. |
215
+ | 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. |
216
+ | 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. |
217
+ | 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. |
218
+ | `window.setTimeout` in a `ranuts/utils` module | Throws outside a document. Use the bare `setTimeout`. |
219
+ | 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). |
220
+ | 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. |
221
+ | Assuming `createSignal` deep-compares | It uses `Object.is` since 0.3. Pass `{ equals: isEqual }` when you want deep comparison. |
222
+ | Testing a boolean URL flag with `getQuery(url).embed` | `?embed` (no value) is the usual spelling and reads as `''`, which is falsy. Use `queryFlag('embed')`. |
223
+ | `Promise.race([task, timeoutPromise])` for a deadline | Leaks the timer when the task wins. Use `withTimeout` / `withTimeoutFallback` — they always clear it. |
224
+ | Expecting `rewriteZip` to recompress | Rewritten and injected entries are written STORED, so the output is larger. Untouched entries keep their original compressed bytes. |
225
+ | Expecting `zip.ts` to open a >4 GiB archive | No ZIP64, no encryption, no multi-disk. `readZipEntries` returns `[]` for anything it cannot parse. |
226
+ | Calling `createHandoff().take()` twice | It is one-shot by design — the read and the delete share a transaction. The second call resolves `null`. |
227
+
228
+ ---
229
+
230
+ ## Breaking changes in 0.3
231
+
232
+ The package is `0.x` and explicitly experimental, so these landed without a deprecation cycle.
233
+ Each fixed a defect rather than changing a preference.
234
+
235
+ | Symbol | Change | Migration |
236
+ | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
237
+ | `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)` |
238
+ | `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. |
239
+ | `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. |
240
+ | `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()`. |
241
+ | `report` | Return type narrowed to `boolean`; the image fallback is now reachable; **no default endpoint**. | `setReportUrl(url)` once, or pass `report({ url })`. |
242
+ | `debounce` / `throttle` | Now generically typed and return `cancel()` / `flush()` / `pending()`. | None; call `cancel()` on teardown. |
243
+ | `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 })`. |
244
+ | `createData` | No longer reads a hard-coded `chaxus_prod` cookie; `userId` appears only when configured. | `setReportUrl({ userIdCookie })`. |
245
+ | `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`. |
246
+ | `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)`. |
247
+ | `replaceOld` | Returns a restore function instead of `void`. | Additive; keep the returned function. |
248
+ | `handleConsole` / `handleFetchHook` / `handleXhrHook` / `handleError` / `handleClick` | Return a teardown function instead of `void`. | Additive; call it on teardown. |
249
+ | `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()`. |
250
+ | bridge symbols | Moved from `bom.ts` to `bridge.ts` (~600 lines of a different concern). | None — same barrel exports. |
251
+ | `getAllQueryString` / `getQuery` | Two byte-identical copies of a parser that **dropped every parameter without a value**, so `?embed` and `?readonly` read as absent. Rewritten once, aliased; bare flags now yield `''`, a fragment no longer leaks into the last value, and only the first `=` splits. | Use `queryFlag(key)` for boolean flags. |
252
+ | `localStorageGetItem` / `localStorageSetItem` | No longer branch on `isClient`, and no longer throw when storage access itself throws (blocked third-party frame, private mode, quota). | None. `createStore(prefix)` for JSON values. |
253
+ | `hexToRgb` | Return type narrowed from `RegExpExecArray \| null \| Array<number>` to `Array<number> \| null`, and 3-digit shorthand (`#abc`) is now expanded per CSS rules instead of failing to parse. | None — strictly more inputs accepted, narrower type. |
254
+ | `hsbToRgb` / `hsvToRgb` | Rounds instead of floors the final 0–255 channels. Flooring biased every channel down by up to 1, so `rgb → hsb → rgb` never converged (a colour picker lost saturation on repeated drags). | Values may differ by 1 per channel. None if you weren't asserting exact bytes. |
255
+ | `Chain` / `create` (`ranuts/vnode`) | `src/vnode/chainDom.ts` was a second copy missing SVG namespace support and listener management. Both entries now export the fuller `utils/chain` implementation. | None — the surviving one is a superset. |
package/README.md CHANGED
@@ -32,7 +32,7 @@ npm install ranuts@latest --save
32
32
 
33
33
  ## Document
34
34
 
35
- [Some commonly used functions and tools](https://chaxus.github.io/ran/src/ranuts/)
35
+ [Some commonly used functions and tools](https://ran.chaxus.com/src/ranuts/)
36
36
 
37
37
  **For AI agents / LLMs:** start from [CLAUDE.md](./CLAUDE.md) (orientation: entry points,
38
38
  runtime constraints, conventions) and [docs/API.md](./docs/API.md) (generated reference of
@@ -53,14 +53,16 @@ Claude then uses it automatically (or invoke it as `/ranuts:ranuts`).
53
53
 
54
54
  Import as required. You can select:
55
55
 
56
- - ranuts/utils
57
- - ranuts/node
58
- - ranuts/react
56
+ - `ranuts/utils` — DOM/BOM, string, object, number, colour, time, storage, i18n helpers
57
+ - `ranuts/node` — HTTP server, router, ws, fs, streams, middleware (**Node only**)
58
+ - `ranuts/visual` — 2D rendering engine (Canvas / WebGL / WebGPU, **browser only**)
59
+ - `ranuts/vnode` — Snabbdom-style virtual DOM
60
+ - `ranuts/i18n` — the i18n engine on its own, without the rest of `utils`
59
61
 
60
62
  ```js
61
63
  import { str2Xml } from 'ranuts/utils';
62
64
  import { readFile } from 'ranuts/node';
63
- import { reactify } from 'ranuts/react';
65
+ import { createI18n } from 'ranuts/i18n';
64
66
  ```
65
67
 
66
68
  Full import,(Full import will introduce many unnecessary modules. You are advised to import them on demand)
package/README.zh-CN.md CHANGED
@@ -34,20 +34,22 @@ npm install ranuts@latest --save
34
34
 
35
35
  ## 文档
36
36
 
37
- [一些常用的函数和工具](https://chaxus.github.io/ran/cn/src/ranuts/)
37
+ [一些常用的函数和工具](https://ran.chaxus.com/cn/src/ranuts/)
38
38
 
39
39
  ## 使用方式
40
40
 
41
41
  按需导入。您可以选择:
42
42
 
43
- - ranuts/utils
44
- - ranuts/node
45
- - ranuts/react
43
+ - `ranuts/utils` —— DOM/BOM、字符串、对象、数字、颜色、时间、存储、i18n 等工具
44
+ - `ranuts/node` —— HTTP 服务、路由、ws、fs、流、中间件(**仅 Node**)
45
+ - `ranuts/visual` —— 2D 渲染引擎(Canvas / WebGL / WebGPU,**仅浏览器**)
46
+ - `ranuts/vnode` —— Snabbdom 风格的虚拟 DOM
47
+ - `ranuts/i18n` —— 单独的 i18n 引擎,不牵入 `utils` 的其余部分
46
48
 
47
49
  ```js
48
50
  import { str2Xml } from 'ranuts/utils';
49
51
  import { readFile } from 'ranuts/node';
50
- import { reactify } from 'ranuts/react';
52
+ import { createI18n } from 'ranuts/i18n';
51
53
  ```
52
54
 
53
55
  全量导入(全量导入会引入许多不必要的模块,建议按需导入)
@@ -0,0 +1 @@
1
+ var e=["svg","path","g","circle","rect","line","polyline","polygon","ellipse","text","tspan","textPath","defs","marker","radialGradient","stop","linearGradient","clipPath","mask","pattern","image","use","symbol","foreignObject","feGaussianBlur","feColorMatrix"],t=class t{listener;element;constructor(e,t){this.element=this.create(e,t),this.listener=/* @__PURE__ */new Map}create=(t,n)=>e.includes(t)?document.createElementNS("http://www.w3.org/2000/svg",t,n):document.createElement(t,n);setAttribute=(e,t)=>(this.element.setAttribute(e,t),this);removeAttribute=e=>(this.element.removeAttribute(e),this);append=e=>(this.element.appendChild(e),this);remove=e=>(this.element.removeChild(e),this);setTextContent=e=>(this.element.textContent=e,this);setStyle=(e,t)=>(this.element.style.setProperty(e,t),this);addElementByType=(e,n)=>{e instanceof t&&n.appendChild(e.element),e instanceof HTMLElement&&n.appendChild(e)};addChild=e=>{if(Array.isArray(e)){const t=document.createDocumentFragment();e.forEach(e=>{this.addElementByType(e,t)}),this.element.appendChild(t)}else this.addElementByType(e,this.element);return this};listen=(e,t,n)=>{let s=this.listener.get(e);s||(s=/* @__PURE__ */new Map,this.listener.set(e,s));const i=s.get(t.name);return i===t&&console.warn(`${i.name} listener has been added to ${e} event, please remove it first.`),this.element.addEventListener(e,t,n),s.set(t.name,t),this};clearListener=(e,t,n)=>{this.element.removeEventListener(e,t,n);const s=this.listener.get(e);return s?s.delete(t.name):console.warn(`No ${e} event listener has been added.`),this};clearAllListener=()=>{for(const[e,t]of this.listener){for(const[n,s]of t)this.element.removeEventListener(e,s),t.delete(n);this.listener.delete(e)}return this}},n=(e,n)=>new t(e,n);export{n,t};