@planet-matrix/mobius-model 0.5.0 → 0.9.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 (379) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +123 -36
  3. package/dist/index.js +715 -4
  4. package/dist/index.js.map +981 -13
  5. package/oxlint.config.ts +6 -0
  6. package/package.json +36 -18
  7. package/src/abort/README.md +92 -0
  8. package/src/abort/abort-manager.ts +278 -0
  9. package/src/abort/abort-signal-listener-manager.ts +81 -0
  10. package/src/abort/index.ts +2 -0
  11. package/src/ai/README.md +1 -0
  12. package/src/ai/ai.ts +107 -0
  13. package/src/ai/chat-completion-ai/aihubmix-chat-completion.ts +78 -0
  14. package/src/ai/chat-completion-ai/chat-completion-ai.ts +270 -0
  15. package/src/ai/chat-completion-ai/chat-completion.ts +189 -0
  16. package/src/ai/chat-completion-ai/index.ts +7 -0
  17. package/src/ai/chat-completion-ai/lingyiwanwu-chat-completion.ts +78 -0
  18. package/src/ai/chat-completion-ai/ohmygpt-chat-completion.ts +78 -0
  19. package/src/ai/chat-completion-ai/openai-next-chat-completion.ts +78 -0
  20. package/src/ai/embedding-ai/embedding-ai.ts +63 -0
  21. package/src/ai/embedding-ai/embedding.ts +50 -0
  22. package/src/ai/embedding-ai/index.ts +4 -0
  23. package/src/ai/embedding-ai/openai-next-embedding.ts +23 -0
  24. package/src/ai/index.ts +4 -0
  25. package/src/aio/README.md +100 -0
  26. package/src/aio/content.ts +141 -0
  27. package/src/aio/index.ts +3 -0
  28. package/src/aio/json.ts +127 -0
  29. package/src/aio/prompt.ts +246 -0
  30. package/src/basic/README.md +72 -116
  31. package/src/basic/error.ts +19 -5
  32. package/src/basic/function.ts +83 -64
  33. package/src/basic/index.ts +1 -0
  34. package/src/basic/is.ts +152 -71
  35. package/src/basic/promise.ts +29 -8
  36. package/src/basic/schedule.ts +111 -0
  37. package/src/basic/stream.ts +135 -25
  38. package/src/basic/string.ts +2 -33
  39. package/src/color/README.md +105 -0
  40. package/src/color/index.ts +3 -0
  41. package/src/color/internal.ts +42 -0
  42. package/src/color/rgb/analyze.ts +236 -0
  43. package/src/color/rgb/construct.ts +130 -0
  44. package/src/color/rgb/convert.ts +227 -0
  45. package/src/color/rgb/derive.ts +303 -0
  46. package/src/color/rgb/index.ts +6 -0
  47. package/src/color/rgb/internal.ts +208 -0
  48. package/src/color/rgb/parse.ts +302 -0
  49. package/src/color/rgb/serialize.ts +144 -0
  50. package/src/color/types.ts +57 -0
  51. package/src/color/xyz/analyze.ts +80 -0
  52. package/src/color/xyz/construct.ts +19 -0
  53. package/src/color/xyz/convert.ts +71 -0
  54. package/src/color/xyz/index.ts +3 -0
  55. package/src/color/xyz/internal.ts +23 -0
  56. package/src/credential/README.md +107 -0
  57. package/src/credential/api-key.ts +158 -0
  58. package/src/credential/bearer.ts +73 -0
  59. package/src/credential/index.ts +4 -0
  60. package/src/credential/json-web-token.ts +96 -0
  61. package/src/credential/password.ts +170 -0
  62. package/src/cron/README.md +86 -0
  63. package/src/cron/cron.ts +87 -0
  64. package/src/cron/index.ts +1 -0
  65. package/src/css/README.md +93 -0
  66. package/src/css/class.ts +559 -0
  67. package/src/css/index.ts +1 -0
  68. package/src/drizzle/README.md +1 -0
  69. package/src/drizzle/drizzle.ts +1 -0
  70. package/src/drizzle/helper.ts +47 -0
  71. package/src/drizzle/index.ts +5 -0
  72. package/src/drizzle/infer.ts +52 -0
  73. package/src/drizzle/kysely.ts +8 -0
  74. package/src/drizzle/pagination.ts +200 -0
  75. package/src/email/README.md +1 -0
  76. package/src/email/index.ts +1 -0
  77. package/src/email/resend.ts +25 -0
  78. package/src/encoding/README.md +66 -79
  79. package/src/encoding/base64.ts +13 -4
  80. package/src/environment/README.md +97 -0
  81. package/src/environment/basic.ts +26 -0
  82. package/src/environment/device.ts +311 -0
  83. package/src/environment/feature.ts +285 -0
  84. package/src/environment/geo.ts +337 -0
  85. package/src/environment/index.ts +7 -0
  86. package/src/environment/runtime.ts +400 -0
  87. package/src/environment/snapshot.ts +60 -0
  88. package/src/environment/variable.ts +239 -0
  89. package/src/event/README.md +90 -0
  90. package/src/event/class-event-proxy.ts +229 -0
  91. package/src/event/common.ts +29 -0
  92. package/src/event/event-manager.ts +203 -0
  93. package/src/event/index.ts +4 -0
  94. package/src/event/instance-event-proxy.ts +187 -0
  95. package/src/event/internal.ts +24 -0
  96. package/src/exception/README.md +96 -0
  97. package/src/exception/browser.ts +219 -0
  98. package/src/exception/index.ts +4 -0
  99. package/src/exception/nodejs.ts +169 -0
  100. package/src/exception/normalize.ts +106 -0
  101. package/src/exception/types.ts +99 -0
  102. package/src/form/README.md +25 -0
  103. package/src/form/index.ts +1 -0
  104. package/src/form/inputor-controller/base.ts +874 -0
  105. package/src/form/inputor-controller/boolean.ts +39 -0
  106. package/src/form/inputor-controller/file.ts +39 -0
  107. package/src/form/inputor-controller/form.ts +181 -0
  108. package/src/form/inputor-controller/helper.ts +117 -0
  109. package/src/form/inputor-controller/index.ts +17 -0
  110. package/src/form/inputor-controller/multi-select.ts +99 -0
  111. package/src/form/inputor-controller/number.ts +116 -0
  112. package/src/form/inputor-controller/select.ts +109 -0
  113. package/src/form/inputor-controller/text.ts +82 -0
  114. package/src/http/READMD.md +1 -0
  115. package/src/http/api/api-core.ts +84 -0
  116. package/src/http/api/api-handler.ts +79 -0
  117. package/src/http/api/api-host.ts +47 -0
  118. package/src/http/api/api-result.ts +56 -0
  119. package/src/http/api/api-schema.ts +154 -0
  120. package/src/http/api/api-server.ts +130 -0
  121. package/src/http/api/api-test.ts +142 -0
  122. package/src/http/api/api-type.ts +37 -0
  123. package/src/http/api/api.ts +81 -0
  124. package/src/http/api/index.ts +11 -0
  125. package/src/http/api-adapter/api-core-node-http.ts +260 -0
  126. package/src/http/api-adapter/api-host-node-http.ts +156 -0
  127. package/src/http/api-adapter/api-result-arktype.ts +297 -0
  128. package/src/http/api-adapter/api-result-zod.ts +286 -0
  129. package/src/http/api-adapter/index.ts +5 -0
  130. package/src/http/bin/gen-api-list/gen-api-list.ts +126 -0
  131. package/src/http/bin/gen-api-list/index.ts +1 -0
  132. package/src/http/bin/gen-api-test/gen-api-test.ts +136 -0
  133. package/src/http/bin/gen-api-test/index.ts +1 -0
  134. package/src/http/bin/gen-api-type/calc-code.ts +25 -0
  135. package/src/http/bin/gen-api-type/gen-api-type.ts +127 -0
  136. package/src/http/bin/gen-api-type/index.ts +2 -0
  137. package/src/http/bin/index.ts +2 -0
  138. package/src/http/index.ts +3 -0
  139. package/src/huawei/README.md +1 -0
  140. package/src/huawei/index.ts +2 -0
  141. package/src/huawei/moderation/index.ts +1 -0
  142. package/src/huawei/moderation/moderation.ts +355 -0
  143. package/src/huawei/obs/esdk-obs-nodejs.d.ts +87 -0
  144. package/src/huawei/obs/index.ts +1 -0
  145. package/src/huawei/obs/obs.ts +42 -0
  146. package/src/identifier/README.md +92 -0
  147. package/src/identifier/id.ts +119 -0
  148. package/src/identifier/index.ts +2 -0
  149. package/src/identifier/uuid.ts +187 -0
  150. package/src/index.ts +33 -1
  151. package/src/json/README.md +92 -0
  152. package/src/json/index.ts +1 -0
  153. package/src/json/repair.ts +18 -0
  154. package/src/log/README.md +79 -0
  155. package/src/log/index.ts +5 -0
  156. package/src/log/log-emitter.ts +72 -0
  157. package/src/log/log-record.ts +10 -0
  158. package/src/log/log-scheduler.ts +74 -0
  159. package/src/log/log-type.ts +8 -0
  160. package/src/log/logger.ts +554 -0
  161. package/src/openai/README.md +1 -0
  162. package/src/openai/index.ts +1 -0
  163. package/src/openai/openai.ts +510 -0
  164. package/src/orchestration/README.md +91 -0
  165. package/src/orchestration/coordination/barrier.ts +214 -0
  166. package/src/orchestration/coordination/count-down-latch.ts +215 -0
  167. package/src/orchestration/coordination/errors.ts +98 -0
  168. package/src/orchestration/coordination/index.ts +16 -0
  169. package/src/orchestration/coordination/internal/wait-constraints.ts +95 -0
  170. package/src/orchestration/coordination/internal/wait-queue.ts +109 -0
  171. package/src/orchestration/coordination/keyed-lock.ts +168 -0
  172. package/src/orchestration/coordination/mutex.ts +257 -0
  173. package/src/orchestration/coordination/permit.ts +127 -0
  174. package/src/orchestration/coordination/read-write-lock.ts +444 -0
  175. package/src/orchestration/coordination/semaphore.ts +280 -0
  176. package/src/orchestration/dispatching/dispatcher.ts +83 -0
  177. package/src/orchestration/dispatching/index.ts +2 -0
  178. package/src/orchestration/dispatching/selector/base-selector.ts +39 -0
  179. package/src/orchestration/dispatching/selector/down-count-selector.ts +119 -0
  180. package/src/orchestration/dispatching/selector/index.ts +2 -0
  181. package/src/orchestration/index.ts +3 -0
  182. package/src/orchestration/scheduling/index.ts +2 -0
  183. package/src/orchestration/scheduling/scheduler.ts +103 -0
  184. package/src/orchestration/scheduling/task.ts +32 -0
  185. package/src/random/README.md +56 -86
  186. package/src/random/base.ts +66 -0
  187. package/src/random/index.ts +5 -1
  188. package/src/random/random-boolean.ts +40 -0
  189. package/src/random/random-integer.ts +60 -0
  190. package/src/random/random-number.ts +72 -0
  191. package/src/random/random-string.ts +66 -0
  192. package/src/reactor/README.md +4 -0
  193. package/src/reactor/reactor-core/primitive.ts +9 -9
  194. package/src/reactor/reactor-core/reactive-system.ts +5 -5
  195. package/src/request/README.md +108 -0
  196. package/src/request/fetch/base.ts +108 -0
  197. package/src/request/fetch/browser.ts +285 -0
  198. package/src/request/fetch/general.ts +20 -0
  199. package/src/request/fetch/index.ts +4 -0
  200. package/src/request/fetch/nodejs.ts +285 -0
  201. package/src/request/index.ts +2 -0
  202. package/src/request/request/base.ts +250 -0
  203. package/src/request/request/general.ts +64 -0
  204. package/src/request/request/index.ts +3 -0
  205. package/src/request/request/resource.ts +68 -0
  206. package/src/result/README.md +4 -0
  207. package/src/result/controller.ts +54 -0
  208. package/src/result/either.ts +193 -0
  209. package/src/result/index.ts +2 -0
  210. package/src/route/README.md +105 -0
  211. package/src/route/adapter/browser.ts +122 -0
  212. package/src/route/adapter/driver.ts +56 -0
  213. package/src/route/adapter/index.ts +2 -0
  214. package/src/route/index.ts +3 -0
  215. package/src/route/router/index.ts +2 -0
  216. package/src/route/router/route.ts +630 -0
  217. package/src/route/router/router.ts +1642 -0
  218. package/src/route/uri/hash.ts +308 -0
  219. package/src/route/uri/index.ts +7 -0
  220. package/src/route/uri/pathname.ts +376 -0
  221. package/src/route/uri/search.ts +413 -0
  222. package/src/singleton/README.md +79 -0
  223. package/src/singleton/factory.ts +55 -0
  224. package/src/singleton/index.ts +2 -0
  225. package/src/singleton/manager.ts +204 -0
  226. package/src/socket/README.md +105 -0
  227. package/src/socket/client/index.ts +2 -0
  228. package/src/socket/client/socket-unit.ts +660 -0
  229. package/src/socket/client/socket.ts +203 -0
  230. package/src/socket/common/index.ts +2 -0
  231. package/src/socket/common/socket-unit-common.ts +23 -0
  232. package/src/socket/common/socket-unit-heartbeat.ts +427 -0
  233. package/src/socket/index.ts +3 -0
  234. package/src/socket/server/index.ts +3 -0
  235. package/src/socket/server/server.ts +183 -0
  236. package/src/socket/server/socket-unit.ts +449 -0
  237. package/src/socket/server/socket.ts +264 -0
  238. package/src/storage/README.md +107 -0
  239. package/src/storage/index.ts +1 -0
  240. package/src/storage/table.ts +449 -0
  241. package/src/timer/README.md +86 -0
  242. package/src/timer/expiration/expiration-manager.ts +594 -0
  243. package/src/timer/expiration/index.ts +3 -0
  244. package/src/timer/expiration/min-heap.ts +208 -0
  245. package/src/timer/expiration/remaining-manager.ts +241 -0
  246. package/src/timer/index.ts +1 -0
  247. package/src/tube/README.md +99 -0
  248. package/src/tube/helper.ts +138 -0
  249. package/src/tube/index.ts +2 -0
  250. package/src/tube/tube.ts +880 -0
  251. package/src/type/README.md +54 -307
  252. package/src/type/class.ts +2 -2
  253. package/src/type/index.ts +14 -14
  254. package/src/type/is.ts +265 -2
  255. package/src/type/object.ts +37 -0
  256. package/src/type/string.ts +7 -2
  257. package/src/type/tuple.ts +6 -6
  258. package/src/type/union.ts +16 -0
  259. package/src/web/README.md +77 -0
  260. package/src/web/capture.ts +35 -0
  261. package/src/web/clipboard.ts +97 -0
  262. package/src/web/dom.ts +117 -0
  263. package/src/web/download.ts +16 -0
  264. package/src/web/event.ts +46 -0
  265. package/src/web/index.ts +10 -0
  266. package/src/web/local-storage.ts +113 -0
  267. package/src/web/location.ts +28 -0
  268. package/src/web/permission.ts +172 -0
  269. package/src/web/script-loader.ts +432 -0
  270. package/src/weixin/README.md +1 -0
  271. package/src/weixin/index.ts +2 -0
  272. package/src/weixin/official-account/authorization.ts +159 -0
  273. package/src/weixin/official-account/index.ts +2 -0
  274. package/src/weixin/official-account/js-api.ts +134 -0
  275. package/src/weixin/open/index.ts +1 -0
  276. package/src/weixin/open/oauth2.ts +133 -0
  277. package/tests/unit/abort/abort-manager.spec.ts +225 -0
  278. package/tests/unit/abort/abort-signal-listener-manager.spec.ts +62 -0
  279. package/tests/unit/ai/ai.spec.ts +85 -0
  280. package/tests/unit/aio/content.spec.ts +105 -0
  281. package/tests/unit/aio/json.spec.ts +147 -0
  282. package/tests/unit/aio/prompt.spec.ts +111 -0
  283. package/tests/unit/basic/array.spec.ts +1 -1
  284. package/tests/unit/basic/error.spec.ts +16 -4
  285. package/tests/unit/basic/schedule.spec.ts +74 -0
  286. package/tests/unit/basic/stream.spec.ts +91 -38
  287. package/tests/unit/basic/string.spec.ts +0 -9
  288. package/tests/unit/color/rgb/analyze.spec.ts +110 -0
  289. package/tests/unit/color/rgb/construct.spec.ts +56 -0
  290. package/tests/unit/color/rgb/convert.spec.ts +60 -0
  291. package/tests/unit/color/rgb/derive.spec.ts +103 -0
  292. package/tests/unit/color/rgb/parse.spec.ts +66 -0
  293. package/tests/unit/color/rgb/serialize.spec.ts +46 -0
  294. package/tests/unit/color/xyz/analyze.spec.ts +33 -0
  295. package/tests/unit/color/xyz/construct.spec.ts +10 -0
  296. package/tests/unit/color/xyz/convert.spec.ts +18 -0
  297. package/tests/unit/credential/api-key.spec.ts +37 -0
  298. package/tests/unit/credential/bearer.spec.ts +23 -0
  299. package/tests/unit/credential/json-web-token.spec.ts +23 -0
  300. package/tests/unit/credential/password.spec.ts +41 -0
  301. package/tests/unit/cron/cron.spec.ts +84 -0
  302. package/tests/unit/css/class.spec.ts +157 -0
  303. package/tests/unit/environment/basic.spec.ts +20 -0
  304. package/tests/unit/environment/device.spec.ts +146 -0
  305. package/tests/unit/environment/feature.spec.ts +388 -0
  306. package/tests/unit/environment/geo.spec.ts +111 -0
  307. package/tests/unit/environment/runtime.spec.ts +364 -0
  308. package/tests/unit/environment/snapshot.spec.ts +4 -0
  309. package/tests/unit/environment/variable.spec.ts +190 -0
  310. package/tests/unit/event/class-event-proxy.spec.ts +225 -0
  311. package/tests/unit/event/event-manager.spec.ts +246 -0
  312. package/tests/unit/event/instance-event-proxy.spec.ts +187 -0
  313. package/tests/unit/exception/browser.spec.ts +213 -0
  314. package/tests/unit/exception/nodejs.spec.ts +144 -0
  315. package/tests/unit/exception/normalize.spec.ts +57 -0
  316. package/tests/unit/form/inputor-controller/base.spec.ts +458 -0
  317. package/tests/unit/form/inputor-controller/boolean.spec.ts +30 -0
  318. package/tests/unit/form/inputor-controller/file.spec.ts +27 -0
  319. package/tests/unit/form/inputor-controller/form.spec.ts +120 -0
  320. package/tests/unit/form/inputor-controller/helper.spec.ts +67 -0
  321. package/tests/unit/form/inputor-controller/multi-select.spec.ts +34 -0
  322. package/tests/unit/form/inputor-controller/number.spec.ts +36 -0
  323. package/tests/unit/form/inputor-controller/select.spec.ts +49 -0
  324. package/tests/unit/form/inputor-controller/text.spec.ts +34 -0
  325. package/tests/unit/http/api/api-core-host.spec.ts +207 -0
  326. package/tests/unit/http/api/api-schema.spec.ts +120 -0
  327. package/tests/unit/http/api/api-server.spec.ts +363 -0
  328. package/tests/unit/http/api/api-test.spec.ts +117 -0
  329. package/tests/unit/http/api/api.spec.ts +121 -0
  330. package/tests/unit/http/api-adapter/node-http.spec.ts +191 -0
  331. package/tests/unit/identifier/id.spec.ts +71 -0
  332. package/tests/unit/identifier/uuid.spec.ts +85 -0
  333. package/tests/unit/json/repair.spec.ts +11 -0
  334. package/tests/unit/log/log-emitter.spec.ts +33 -0
  335. package/tests/unit/log/log-scheduler.spec.ts +40 -0
  336. package/tests/unit/log/log-type.spec.ts +7 -0
  337. package/tests/unit/log/logger.spec.ts +237 -0
  338. package/tests/unit/openai/openai.spec.ts +64 -0
  339. package/tests/unit/orchestration/coordination/barrier.spec.ts +96 -0
  340. package/tests/unit/orchestration/coordination/count-down-latch.spec.ts +63 -0
  341. package/tests/unit/orchestration/coordination/errors.spec.ts +29 -0
  342. package/tests/unit/orchestration/coordination/keyed-lock.spec.ts +109 -0
  343. package/tests/unit/orchestration/coordination/mutex.spec.ts +132 -0
  344. package/tests/unit/orchestration/coordination/permit.spec.ts +43 -0
  345. package/tests/unit/orchestration/coordination/read-write-lock.spec.ts +154 -0
  346. package/tests/unit/orchestration/coordination/semaphore.spec.ts +135 -0
  347. package/tests/unit/orchestration/dispatching/dispatcher.spec.ts +41 -0
  348. package/tests/unit/orchestration/dispatching/selector/down-count-selector.spec.ts +81 -0
  349. package/tests/unit/orchestration/scheduling/scheduler.spec.ts +103 -0
  350. package/tests/unit/random/base.spec.ts +58 -0
  351. package/tests/unit/random/random-boolean.spec.ts +25 -0
  352. package/tests/unit/random/random-integer.spec.ts +32 -0
  353. package/tests/unit/random/random-number.spec.ts +33 -0
  354. package/tests/unit/random/random-string.spec.ts +22 -0
  355. package/tests/unit/reactor/alien-signals-effect.spec.ts +11 -10
  356. package/tests/unit/reactor/preact-signal.spec.ts +1 -2
  357. package/tests/unit/request/fetch/browser.spec.ts +222 -0
  358. package/tests/unit/request/fetch/general.spec.ts +43 -0
  359. package/tests/unit/request/fetch/nodejs.spec.ts +225 -0
  360. package/tests/unit/request/request/base.spec.ts +385 -0
  361. package/tests/unit/request/request/general.spec.ts +161 -0
  362. package/tests/unit/route/router/route.spec.ts +431 -0
  363. package/tests/unit/route/router/router.spec.ts +407 -0
  364. package/tests/unit/route/uri/hash.spec.ts +72 -0
  365. package/tests/unit/route/uri/pathname.spec.ts +147 -0
  366. package/tests/unit/route/uri/search.spec.ts +107 -0
  367. package/tests/unit/singleton/singleton.spec.ts +49 -0
  368. package/tests/unit/socket/client.spec.ts +208 -0
  369. package/tests/unit/socket/server.spec.ts +135 -0
  370. package/tests/unit/socket/socket-unit-heartbeat.spec.ts +214 -0
  371. package/tests/unit/storage/table.spec.ts +620 -0
  372. package/tests/unit/timer/expiration/expiration-manager.spec.ts +464 -0
  373. package/tests/unit/timer/expiration/min-heap.spec.ts +71 -0
  374. package/tests/unit/timer/expiration/remaining-manager.spec.ts +234 -0
  375. package/tests/unit/tube/helper.spec.ts +139 -0
  376. package/tests/unit/tube/tube.spec.ts +501 -0
  377. package/.oxlintrc.json +0 -5
  378. package/src/random/uuid.ts +0 -103
  379. package/tests/unit/random/uuid.spec.ts +0 -37
@@ -0,0 +1,72 @@
1
+ import type { LogRecord } from "./log-record.ts"
2
+
3
+ /**
4
+ * Describe options consumed by log emitters.
5
+ */
6
+ export interface LogEmitterOptions extends Omit<LogRecord, "type"> {
7
+ }
8
+ /**
9
+ * Define the base emitter contract for dispatching formatted logs.
10
+ */
11
+ export abstract class LogEmitter {
12
+ readonly tags: string[]
13
+ readonly messages: unknown[]
14
+
15
+ readonly formattedMessages: string[]
16
+
17
+ constructor(options: LogEmitterOptions) {
18
+ this.tags = options.tags ?? []
19
+ this.messages = options.messages ?? []
20
+
21
+ this.formattedMessages = []
22
+ this.formattedMessages.push(this.tags.map(tag => `[${tag}]`).join(""))
23
+ this.formattedMessages.push(this.messages.map(message => String(message)).join(" "))
24
+ }
25
+
26
+ abstract emit(): void
27
+ }
28
+
29
+ /**
30
+ * Emit `log` records via `console.log`.
31
+ */
32
+ export class ConsoleLogLogEmitter extends LogEmitter {
33
+ emit(): void {
34
+ console.log(this.formattedMessages.join(" "))
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Emit `info` records via `console.info`.
40
+ */
41
+ export class ConsoleInfoLogEmitter extends LogEmitter {
42
+ emit(): void {
43
+ console.info(this.formattedMessages.join(" "))
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Emit `warn` records via `console.warn`.
49
+ */
50
+ export class ConsoleWarnLogEmitter extends LogEmitter {
51
+ emit(): void {
52
+ console.warn(this.formattedMessages.join(" "))
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Emit `error` records via `console.error`.
58
+ */
59
+ export class ConsoleErrorLogEmitter extends LogEmitter {
60
+ emit(): void {
61
+ console.error(this.formattedMessages.join(" "))
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Emit `debug` records via `console.debug`.
67
+ */
68
+ export class ConsoleDebugLogEmitter extends LogEmitter {
69
+ emit(): void {
70
+ console.debug(this.formattedMessages.join(" "))
71
+ }
72
+ }
@@ -0,0 +1,10 @@
1
+ import type { LogType } from "./log-type.ts"
2
+
3
+ /**
4
+ * Describe a normalized log payload before emitter dispatch.
5
+ */
6
+ export interface LogRecord {
7
+ type?: LogType | undefined
8
+ tags?: string[] | undefined
9
+ messages?: unknown[] | undefined
10
+ }
@@ -0,0 +1,74 @@
1
+ import type { LogRecord } from "./log-record.ts"
2
+
3
+ /**
4
+ * Describe a schedulable log emission task.
5
+ */
6
+ export interface LogTask {
7
+ record: LogRecord
8
+ emit: () => void
9
+ }
10
+ /**
11
+ * Represent supported scheduling strategies.
12
+ */
13
+ export type LogSchedulerStrategy = "immediate"
14
+ /**
15
+ * Describe options used to configure a log scheduler.
16
+ */
17
+ export interface LogSchedulerOptions {
18
+ strategy: LogSchedulerStrategy
19
+ }
20
+ /**
21
+ * Queue and dispatch log tasks based on scheduling strategy.
22
+ */
23
+ export class LogScheduler {
24
+ protected strategy: LogSchedulerStrategy
25
+
26
+ protected taskQueue: LogTask[][]
27
+
28
+ constructor(options: LogSchedulerOptions) {
29
+ this.strategy = options.strategy
30
+
31
+ this.taskQueue = []
32
+ }
33
+
34
+ /**
35
+ * Check if there are any tasks in the queue.
36
+ */
37
+ hasTasks(): boolean {
38
+ return this.taskQueue.length !== 0
39
+ }
40
+
41
+ /**
42
+ * Enqueue tasks and run immediately when strategy requires.
43
+ */
44
+ enqueue(task: LogTask[]): void {
45
+ this.taskQueue.push(task)
46
+ if (this.strategy === "immediate") {
47
+ this.run()
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Flush queued tasks in insertion order.
53
+ */
54
+ run(): void {
55
+ const tasksToRun = [...this.taskQueue].flat()
56
+ this.taskQueue = []
57
+ for (const task of tasksToRun) {
58
+ task.emit()
59
+ }
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Get the singleton global `LogScheduler` instance.
65
+ */
66
+ export const getGlobalLogScheduler: () => LogScheduler = (
67
+ () => {
68
+ let instance: LogScheduler | undefined = undefined
69
+ return (): LogScheduler => {
70
+ instance = instance ?? new LogScheduler({ strategy: "immediate" })
71
+ return instance
72
+ }
73
+ }
74
+ )()
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Define supported log level identifiers.
3
+ */
4
+ export const LOG_TYPES = ["log", "info", "warn", "error", "debug"] as const
5
+ /**
6
+ * Represent the union type of all supported log levels.
7
+ */
8
+ export type LogType = typeof LOG_TYPES[number]
@@ -0,0 +1,554 @@
1
+ import { generateUuidV4FromUrl } from "#Source/identifier/index.ts"
2
+ import { getGlobalLogScheduler } from "./log-scheduler.ts"
3
+
4
+ import type { LogRecord } from "./log-record.ts"
5
+ import type { LogTask } from "./log-scheduler.ts"
6
+ import type { LogType } from "./log-type.ts"
7
+ import {
8
+ ConsoleDebugLogEmitter,
9
+ ConsoleErrorLogEmitter,
10
+ ConsoleInfoLogEmitter,
11
+ ConsoleLogLogEmitter,
12
+ ConsoleWarnLogEmitter,
13
+ } from "./log-emitter.ts"
14
+ import type { LogEmitter, LogEmitterOptions } from "./log-emitter.ts"
15
+
16
+ const globalLogScheduler = getGlobalLogScheduler()
17
+
18
+ /**
19
+ * Describe an object that exposes a `Logger` instance.
20
+ */
21
+ export interface LoggerFriendly {
22
+ logger: Logger
23
+ }
24
+ /**
25
+ * Describe options that may provide an existing `Logger`.
26
+ */
27
+ export interface LoggerFriendlyOptions {
28
+ logger?: Logger | undefined
29
+ }
30
+
31
+ /**
32
+ * Describe an emitter registration for a specific log type.
33
+ */
34
+ export interface LogEmitterItem {
35
+ logType: LogType
36
+ // oxlint-disable-next-line no-explicit-any
37
+ LogEmitter: new (...args: any[]) => LogEmitter
38
+ injectOptions?: ((options: LogEmitterOptions) => LogEmitterOptions) | undefined
39
+ }
40
+ /**
41
+ * Define the default console-based emitters.
42
+ */
43
+ const DEFAULT_CONSOLE_LOG_EMITTER_ITEMS: LogEmitterItem[] = [
44
+ {
45
+ logType: "log",
46
+ LogEmitter: ConsoleLogLogEmitter,
47
+ },
48
+ {
49
+ logType: "info",
50
+ LogEmitter: ConsoleInfoLogEmitter,
51
+ },
52
+ {
53
+ logType: "warn",
54
+ LogEmitter: ConsoleWarnLogEmitter,
55
+ },
56
+ {
57
+ logType: "error",
58
+ LogEmitter: ConsoleErrorLogEmitter,
59
+ },
60
+ {
61
+ logType: "debug",
62
+ LogEmitter: ConsoleDebugLogEmitter,
63
+ },
64
+ ]
65
+
66
+ /**
67
+ * Describe runtime logger configuration values.
68
+ */
69
+ export interface LoggerConfigs {
70
+ enabled: boolean
71
+ autoSend: boolean
72
+ filter: ((logRecord: LogRecord) => boolean)
73
+ emitters: LogEmitterItem[]
74
+ }
75
+ /**
76
+ * Describe options used to construct a `Logger`.
77
+ */
78
+ export interface LoggerOptions {
79
+ name?: string | undefined
80
+ parent?: Logger | undefined
81
+ configs?: Partial<LoggerConfigs> | undefined
82
+ }
83
+ /**
84
+ * 表示支持层级继承、标签管理与延迟发送的日志记录器。
85
+ *
86
+ * 规范:
87
+ * - 初始配置的优先级为 parentConfigs -> configs -> 默认值。
88
+ * - 当 parent 为 undefined 时,parentConfigs 也应该是 undefined。
89
+ * - 更新 parent 时,parentConfigs 也应该同步更新。
90
+ * - 作为 parent 修改自己的 configs 时,不会影响 child 的 configs。
91
+ * - 作为 child 可以独立修改自己的 configs,也可以将 parentConfigs 应用到自己的 configs。
92
+ */
93
+ export class Logger implements Disposable {
94
+ /**
95
+ * 从选项中解析 logger;如果未提供,则基于全局 logger 派生一个新 logger。
96
+ *
97
+ * @example
98
+ * ```
99
+ * // Expect: example1 === customLogger
100
+ * const customLogger = new Logger({ name: "Custom" })
101
+ * const example1 = Logger.fromOptions({ logger: customLogger })
102
+ *
103
+ * // Expect: example2 !== globalLogger
104
+ * // Expect: example2.hasParent() === true
105
+ * const globalLogger = getGlobalLogger()
106
+ * const example2 = Logger.fromOptions({})
107
+ *
108
+ * class CustomClass implements LoggerFriendly {
109
+ * logger: Logger
110
+ *
111
+ * constructor(options: LoggerFriendlyOptions) {
112
+ * this.logger = Logger.fromOptions(options)
113
+ * }
114
+ * }
115
+ *
116
+ * // Expect: example3.logger instanceof Logger
117
+ * const example3 = new CustomClass({ logger: customLogger })
118
+ * ```
119
+ */
120
+ static fromOptions(options: LoggerFriendlyOptions): Logger {
121
+ if (options.logger !== undefined) {
122
+ return options.logger
123
+ }
124
+
125
+ const parent = getGlobalLogger()
126
+ const logger = Logger.derive(parent)
127
+ return logger
128
+ }
129
+
130
+ /**
131
+ * Create a child logger from a parent logger.
132
+ */
133
+ static derive(parentLogger: Logger): Logger {
134
+ const logger = new Logger({ parent: parentLogger })
135
+ return logger
136
+ }
137
+
138
+ protected defaultName: string
139
+ protected name?: string | undefined
140
+ protected parent?: Logger | undefined
141
+ protected childs: Logger[]
142
+ protected parentConfigs?: LoggerConfigs | undefined
143
+ protected configs: LoggerConfigs
144
+
145
+ protected instanceTags: string[]
146
+ protected sessionTags: string[]
147
+ protected onceTags: string[]
148
+
149
+ private logTasks: LogTask[]
150
+ private cachedLogMethodMap: Map<string, (...messages: unknown[]) => this>
151
+
152
+ constructor(options: LoggerOptions) {
153
+ this.defaultName = "Unnamed"
154
+ this.name = options.name
155
+ this.parent = options.parent
156
+ this.childs = []
157
+ const parentConfigs = options.parent?.getConfigs()
158
+ const configs = options.configs
159
+ this.parentConfigs = parentConfigs
160
+ this.configs = {
161
+ enabled: parentConfigs?.enabled ?? configs?.enabled ?? true,
162
+ autoSend: parentConfigs?.autoSend ?? configs?.autoSend ?? true,
163
+ filter: parentConfigs?.filter ?? configs?.filter ?? ((): boolean => true),
164
+ emitters: parentConfigs?.emitters ?? configs?.emitters ?? DEFAULT_CONSOLE_LOG_EMITTER_ITEMS
165
+ }
166
+
167
+ this.instanceTags = []
168
+ this.sessionTags = []
169
+ this.onceTags = []
170
+
171
+ this.logTasks = []
172
+ this.cachedLogMethodMap = new Map()
173
+ }
174
+
175
+ /**
176
+ * Set the default name if the current name is empty,
177
+ * and return the logger for chaining.
178
+ */
179
+ setDefaultName(name: string): this {
180
+ this.defaultName = name
181
+ return this
182
+ }
183
+
184
+ /**
185
+ * Get the logger display name.
186
+ */
187
+ getName(): string {
188
+ return this.name ?? this.defaultName
189
+ }
190
+
191
+ /**
192
+ * Set the logger display name.
193
+ */
194
+ setName(name: string | undefined): this {
195
+ this.name = name
196
+ return this
197
+ }
198
+
199
+ /**
200
+ * Check whether the logger currently has a parent.
201
+ */
202
+ hasParent(): boolean {
203
+ return this.parent !== undefined
204
+ }
205
+
206
+ /**
207
+ * Set or clear the parent logger.
208
+ */
209
+ setParent(parentLogger?: Logger | undefined): this {
210
+ this.parent = parentLogger
211
+ this.parentConfigs = parentLogger?.getConfigs()
212
+ return this
213
+ }
214
+
215
+ /**
216
+ * Get merged effective configs from parent and local overrides.
217
+ */
218
+ getConfigs(): LoggerConfigs {
219
+ return { ...this.parentConfigs, ...this.configs }
220
+ }
221
+
222
+ /**
223
+ * Update local configs and refresh inherited configs on child loggers.
224
+ */
225
+ setConfigs(configs: Partial<LoggerConfigs>): this {
226
+ this.configs = { ...this.getConfigs(), ...configs }
227
+ for (const child of this.childs) {
228
+ child.setParent(this)
229
+ }
230
+ return this
231
+ }
232
+
233
+ /**
234
+ * Apply current parent configs onto local configs.
235
+ */
236
+ useParentConfigs(): this {
237
+ if (this.parentConfigs !== undefined) {
238
+ this.setConfigs(this.parentConfigs)
239
+ }
240
+ return this
241
+ }
242
+
243
+ /**
244
+ * Get all configured emitter registrations.
245
+ */
246
+ getAllLogEmitters(): LogEmitterItem[] {
247
+ const emitters = this.getConfigs().emitters
248
+ return emitters
249
+ }
250
+
251
+ /**
252
+ * Get emitter registrations for a specific log type.
253
+ */
254
+ getLogEmitters(logType: LogType): LogEmitterItem[] {
255
+ const emitters = this.getConfigs().emitters
256
+ const filteredEmitters = emitters.filter(item => item.logType === logType)
257
+ return filteredEmitters
258
+ }
259
+
260
+ /**
261
+ * 支持为同一类型的 Log 添加多个 LogEmitter。
262
+ */
263
+ addLogEmitters(logEmitters: LogEmitterItem[]): this {
264
+ const newEmitters = [...this.getConfigs().emitters]
265
+ for (const item of logEmitters) {
266
+ if (!newEmitters.some((e) => e.logType === item.logType && e.LogEmitter === item.LogEmitter)) {
267
+ newEmitters.push(item)
268
+ }
269
+ }
270
+ this.setConfigs({
271
+ emitters: newEmitters
272
+ })
273
+ return this
274
+ }
275
+
276
+ /**
277
+ * Remove matched emitter registrations.
278
+ */
279
+ removeLogEmitters(logEmitters: LogEmitterItem[]): this {
280
+ const emitters = this.getConfigs().emitters
281
+ const remainingEmitters = emitters.filter((item) => {
282
+ return !logEmitters.some((e) => e.logType === item.logType && e.LogEmitter === item.LogEmitter)
283
+ })
284
+ this.setConfigs({
285
+ emitters: remainingEmitters
286
+ })
287
+ return this
288
+ }
289
+
290
+ /**
291
+ * Invoke all emitters that match the record log type.
292
+ */
293
+ invokeLogEmitter(record: LogRecord): void {
294
+ const { type } = record
295
+ if (type === undefined) {
296
+ return
297
+ }
298
+ const logEmitterList = this.getLogEmitters(type)
299
+ if (logEmitterList.length === 0) {
300
+ return
301
+ }
302
+ logEmitterList.forEach((item) => {
303
+ const injectOptions = item.injectOptions ?? (<T>(v: T): T => v)
304
+ const LogEmitter = item.LogEmitter
305
+ const logEmitter = new LogEmitter(injectOptions(record))
306
+ logEmitter.emit()
307
+ })
308
+ }
309
+
310
+ /**
311
+ * Get full hierarchical name tags from root to current logger.
312
+ */
313
+ getNameTags(): string[] {
314
+ const names = [...this.parent?.getNameTags() ?? [], this.getName()]
315
+ return names
316
+ }
317
+
318
+ /**
319
+ * Add persistent instance tags.
320
+ */
321
+ addInstanceTags(tags: string[]): this {
322
+ this.instanceTags.push(...tags)
323
+ return this
324
+ }
325
+
326
+ /**
327
+ * Remove matched instance tags.
328
+ */
329
+ removeInstanceTags(tags: string[]): this {
330
+ this.instanceTags = this.instanceTags.filter(tag => !tags.includes(tag))
331
+ return this
332
+ }
333
+
334
+ /**
335
+ * Get current instance tags.
336
+ */
337
+ getInstanceTags(): string[] {
338
+ return this.instanceTags
339
+ }
340
+
341
+ /**
342
+ * Clear all instance tags.
343
+ */
344
+ clearInstanceTags(): this {
345
+ this.instanceTags = []
346
+ return this
347
+ }
348
+
349
+ /**
350
+ * Add session tags used until `tagEnd` is called.
351
+ */
352
+ addSessionTags(tags: string[]): this {
353
+ this.sessionTags.push(...tags)
354
+ return this
355
+ }
356
+
357
+ /**
358
+ * Remove matched session tags.
359
+ */
360
+ removeSessionTags(tags: string[]): this {
361
+ this.sessionTags = this.sessionTags.filter(tag => !tags.includes(tag))
362
+ return this
363
+ }
364
+
365
+ /**
366
+ * Get current session tags.
367
+ */
368
+ getSessionTags(): string[] {
369
+ return this.sessionTags
370
+ }
371
+
372
+ /**
373
+ * Clear all session tags.
374
+ */
375
+ clearSessionTags(): this {
376
+ this.sessionTags = []
377
+ return this
378
+ }
379
+
380
+ /**
381
+ * Start and automatically end a session tag scope on dispose.
382
+ */
383
+ autoTag(tags: string[]): Disposable {
384
+ this.tagStart(tags)
385
+ return {
386
+ [Symbol.dispose]: (): void => {
387
+ this.tagEnd()
388
+ },
389
+ }
390
+ }
391
+
392
+ /**
393
+ * Start a session tag scope.
394
+ */
395
+ tagStart(tags: string[]): this {
396
+ this.addSessionTags(tags)
397
+ return this
398
+ }
399
+
400
+ /**
401
+ * End the current session tag scope.
402
+ */
403
+ tagEnd(): this {
404
+ this.clearSessionTags()
405
+ return this
406
+ }
407
+
408
+ /**
409
+ * Add one-shot tags consumed by the next log call.
410
+ */
411
+ addOnceTags(tags: string[]): this {
412
+ this.onceTags.push(...tags)
413
+ return this
414
+ }
415
+
416
+ /**
417
+ * Get current one-shot tags.
418
+ */
419
+ getOnceTags(): string[] {
420
+ return this.onceTags
421
+ }
422
+
423
+ /**
424
+ * Clear all one-shot tags.
425
+ */
426
+ clearOnceTags(): this {
427
+ this.onceTags = []
428
+ return this
429
+ }
430
+
431
+ /**
432
+ * Build and cache a log method bound to type and prefix.
433
+ */
434
+ private makeLogMethod(logType: LogType, prefix: string): ((...args: unknown[]) => this) {
435
+ const cachedLogMethodKey = `${logType}-${prefix}`
436
+ const cachedLogMethod = this.cachedLogMethodMap.get(cachedLogMethodKey)
437
+ if (cachedLogMethod !== undefined) {
438
+ return cachedLogMethod
439
+ }
440
+
441
+ const newMethod = (...messages: unknown[]): this => {
442
+ const configs = this.getConfigs()
443
+ if (configs.enabled === false) {
444
+ return this
445
+ }
446
+
447
+ const tags = [
448
+ prefix,
449
+ ...this.getNameTags(),
450
+ ...this.getInstanceTags(),
451
+ ...this.getSessionTags(),
452
+ ...this.getOnceTags()
453
+ ]
454
+ const logRecord: LogRecord = {
455
+ type: logType,
456
+ tags: tags,
457
+ messages,
458
+ }
459
+
460
+ // oxlint-disable-next-line no-array-callback-reference
461
+ if (configs.filter(logRecord) === false) {
462
+ return this
463
+ }
464
+
465
+ this.logTasks.push({
466
+ record: logRecord,
467
+ emit: () => {
468
+ this.invokeLogEmitter(logRecord)
469
+ }
470
+ })
471
+ if (configs.autoSend === true) {
472
+ this.send()
473
+ }
474
+ this.clearOnceTags()
475
+ return this
476
+ }
477
+ this.cachedLogMethodMap.set(cachedLogMethodKey, newMethod)
478
+
479
+ return newMethod
480
+ }
481
+
482
+ /**
483
+ * Queue a `log` level record.
484
+ */
485
+ log(...messages: unknown[]): this {
486
+ return this.makeLogMethod("log", "🟢")(...messages)
487
+ }
488
+
489
+ /**
490
+ * Queue an `info` level record.
491
+ */
492
+ info(...messages: unknown[]): this {
493
+ return this.makeLogMethod("info", "🔵")(...messages)
494
+ }
495
+
496
+ /**
497
+ * Queue a `warn` level record.
498
+ */
499
+ warn(...messages: unknown[]): this {
500
+ return this.makeLogMethod("warn", "🟡")(...messages)
501
+ }
502
+
503
+ /**
504
+ * Queue an `error` level record.
505
+ */
506
+ error(...messages: unknown[]): this {
507
+ return this.makeLogMethod("error", "🔴")(...messages)
508
+ }
509
+
510
+ /**
511
+ * Queue a `debug` level record.
512
+ */
513
+ debug(...messages: unknown[]): this {
514
+ return this.makeLogMethod("debug", "🟤")(...messages)
515
+ }
516
+
517
+ /**
518
+ * Create a child logger configured for manual batched sending.
519
+ */
520
+ batch(id?: string | undefined): Logger {
521
+ const logger = Logger.derive(this)
522
+ logger.setConfigs({ autoSend: false })
523
+ logger.addInstanceTags([id ?? generateUuidV4FromUrl()])
524
+ return logger
525
+ }
526
+
527
+ /**
528
+ * Flush queued records to the global scheduler.
529
+ */
530
+ send(): void {
531
+ globalLogScheduler.enqueue(this.logTasks)
532
+ this.logTasks = []
533
+ }
534
+
535
+ /**
536
+ * Flush queued records when used with `using` disposal.
537
+ */
538
+ [Symbol.dispose](): void {
539
+ this.send()
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Get the singleton global `Logger` instance.
545
+ */
546
+ export const getGlobalLogger: () => Logger = (
547
+ () => {
548
+ let instance: Logger | undefined = undefined
549
+ return (): Logger => {
550
+ instance = instance ?? new Logger({ name: "GlobalLogger" })
551
+ return instance
552
+ }
553
+ }
554
+ )()
@@ -0,0 +1 @@
1
+ # Openai
@@ -0,0 +1 @@
1
+ export * from "./openai.ts"