@greypan/js-kit 1.0.0 → 1.2.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 (49) hide show
  1. package/dist/fetch/index.d.ts +1 -0
  2. package/dist/timer/debounce.js +1 -1
  3. package/dist/url/index.js +1 -2
  4. package/dist/url/index.js.map +1 -1
  5. package/package.json +8 -9
  6. package/.turbo/turbo-build.log +0 -38
  7. package/.turbo/turbo-test.log +0 -87
  8. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/funnel.js +0 -40
  9. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/funnel.js.map +0 -1
  10. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/isNullish.js +0 -8
  11. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/isNullish.js.map +0 -1
  12. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/lazyDataLastImpl--3B10z3s.js +0 -12
  13. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/lazyDataLastImpl--3B10z3s.js.map +0 -1
  14. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/omitBy.js +0 -14
  15. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/omitBy.js.map +0 -1
  16. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/purry.js +0 -12
  17. package/dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/purry.js.map +0 -1
  18. package/src/fetch/__tests__/compose.spec.ts +0 -105
  19. package/src/fetch/compose.ts +0 -23
  20. package/src/index.ts +0 -7
  21. package/src/number/__tests__/number.spec.ts +0 -50
  22. package/src/number/index.ts +0 -22
  23. package/src/paradigm/__tests__/go.spec.ts +0 -63
  24. package/src/paradigm/__tests__/rust.spec.ts +0 -68
  25. package/src/paradigm/go.ts +0 -38
  26. package/src/paradigm/index.ts +0 -2
  27. package/src/paradigm/rust.ts +0 -50
  28. package/src/plugin/__tests__/batch-emitter.spec.ts +0 -48
  29. package/src/plugin/__tests__/core.spec.ts +0 -110
  30. package/src/plugin/__tests__/event-emiiter.spec.ts +0 -41
  31. package/src/plugin/batching-emitter.ts +0 -61
  32. package/src/plugin/core.ts +0 -37
  33. package/src/plugin/event-emitter.ts +0 -25
  34. package/src/plugin/index.ts +0 -2
  35. package/src/random/__tests__/random.spec.ts +0 -77
  36. package/src/random/index.ts +0 -37
  37. package/src/timer/__tests__/controllable-interval.spec.ts +0 -51
  38. package/src/timer/controllable-interval.ts +0 -86
  39. package/src/timer/debounce.ts +0 -92
  40. package/src/timer/index.ts +0 -2
  41. package/src/url/README.md +0 -0
  42. package/src/url/__tests__/url.spec.ts +0 -152
  43. package/src/url/index.ts +0 -44
  44. package/src/utility-types/index.ts +0 -19
  45. package/tsconfig.app.json +0 -11
  46. package/tsconfig.json +0 -8
  47. package/tsconfig.node.json +0 -18
  48. package/tsconfig.vitest.json +0 -10
  49. package/vite.config.ts +0 -32
@@ -0,0 +1 @@
1
+ export { asyncCompose, type Next, type Middleware } from './compose';
@@ -1,4 +1,4 @@
1
- import { funnel as e } from "../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/funnel.js";
1
+ import { funnel as e } from "remeda";
2
2
  //#region src/timer/debounce.ts
3
3
  function t(t, { timing: n, waitMs: r, maxWaitMs: i }) {
4
4
  if (i !== void 0 && r !== void 0 && i < r) throw Error(`debounce: maxWaitMs (${i.toString()}) cannot be less than waitMs (${r.toString()})`);
package/dist/url/index.js CHANGED
@@ -1,5 +1,4 @@
1
- import { isNullish as e } from "../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/isNullish.js";
2
- import { omitBy as t } from "../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/omitBy.js";
1
+ import { isNullish as e, omitBy as t } from "remeda";
3
2
  //#region src/url/index.ts
4
3
  function n(e = "") {
5
4
  let t = !/^(https?:)?\/\//.test(e);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/url/index.ts"],"sourcesContent":["import { isNullish, omitBy } from 'remeda'\n\ntype QueryValue = string | number | boolean | undefined | null\ninterface URLObject {\n base: string\n query: Record<string, QueryValue>\n hash: string\n}\n\nexport function urlParse(url = ''): URLObject {\n const isRelative = !/^(https?:)?\\/\\//.test(url)\n\n try {\n // 如果 url 是相对路径,就借用 http://n.n 作为 base\n const parsed = new URL(url, isRelative ? 'http://n.n' : undefined)\n\n return {\n base: isRelative ? parsed.pathname : `${parsed.origin}${parsed.pathname}`,\n query: Object.fromEntries(parsed.searchParams),\n hash: parsed.hash\n }\n } catch {\n throw new Error('Invalid URL.')\n }\n}\n\nexport function urlStringify(opts: Partial<URLObject>, omitNil = true): string {\n const { base = '', query = {}, hash = '' } = opts\n\n const cleanQuery = omitNil ? omitBy(query, isNullish) : query\n const params = new URLSearchParams()\n\n Object.entries(cleanQuery).forEach(([key, val]) => {\n params.append(key, String(val))\n })\n\n // 修复 Hash 自动补全 # 的问题\n const normalizedHash = hash ? (hash.startsWith('#') ? hash : `#${hash}`) : ''\n const queryString = params.toString()\n if (!queryString) return base + normalizedHash\n\n const connector = base.includes('?') ? '&' : '?'\n return `${base}${connector}${queryString}${normalizedHash}`\n}\n"],"mappings":";;;AASA,SAAgB,EAAS,IAAM,IAAe;CAC5C,IAAM,IAAa,CAAC,kBAAkB,KAAK,CAAG;CAE9C,IAAI;EAEF,IAAM,IAAS,IAAI,IAAI,GAAK,IAAa,eAAe,KAAA,CAAS;EAEjE,OAAO;GACL,MAAM,IAAa,EAAO,WAAW,GAAG,EAAO,SAAS,EAAO;GAC/D,OAAO,OAAO,YAAY,EAAO,YAAY;GAC7C,MAAM,EAAO;EACf;CACF,QAAQ;EACN,MAAU,MAAM,cAAc;CAChC;AACF;AAEA,SAAgB,EAAa,GAA0B,IAAU,IAAc;CAC7E,IAAM,EAAE,UAAO,IAAI,WAAQ,CAAC,GAAG,UAAO,OAAO,GAEvC,IAAa,IAAU,EAAO,GAAO,CAAS,IAAI,GAClD,IAAS,IAAI,gBAAgB;CAEnC,OAAO,QAAQ,CAAU,CAAC,CAAC,SAAS,CAAC,GAAK,OAAS;EACjD,EAAO,OAAO,GAAK,OAAO,CAAG,CAAC;CAChC,CAAC;CAGD,IAAM,IAAiB,IAAQ,EAAK,WAAW,GAAG,IAAI,IAAO,IAAI,MAAU,IACrE,IAAc,EAAO,SAAS;CAIpC,OAHK,IAGE,GAAG,IADQ,EAAK,SAAS,GAAG,IAAI,MAAM,MAChB,IAAc,MAHlB,IAAO;AAIlC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/url/index.ts"],"sourcesContent":["import { isNullish, omitBy } from 'remeda'\n\ntype QueryValue = string | number | boolean | undefined | null\ninterface URLObject {\n base: string\n query: Record<string, QueryValue>\n hash: string\n}\n\nexport function urlParse(url = ''): URLObject {\n const isRelative = !/^(https?:)?\\/\\//.test(url)\n\n try {\n // 如果 url 是相对路径,就借用 http://n.n 作为 base\n const parsed = new URL(url, isRelative ? 'http://n.n' : undefined)\n\n return {\n base: isRelative ? parsed.pathname : `${parsed.origin}${parsed.pathname}`,\n query: Object.fromEntries(parsed.searchParams),\n hash: parsed.hash\n }\n } catch {\n throw new Error('Invalid URL.')\n }\n}\n\nexport function urlStringify(opts: Partial<URLObject>, omitNil = true): string {\n const { base = '', query = {}, hash = '' } = opts\n\n const cleanQuery = omitNil ? omitBy(query, isNullish) : query\n const params = new URLSearchParams()\n\n Object.entries(cleanQuery).forEach(([key, val]) => {\n params.append(key, String(val))\n })\n\n // 修复 Hash 自动补全 # 的问题\n const normalizedHash = hash ? (hash.startsWith('#') ? hash : `#${hash}`) : ''\n const queryString = params.toString()\n if (!queryString) return base + normalizedHash\n\n const connector = base.includes('?') ? '&' : '?'\n return `${base}${connector}${queryString}${normalizedHash}`\n}\n"],"mappings":";;AASA,SAAgB,EAAS,IAAM,IAAe;CAC5C,IAAM,IAAa,CAAC,kBAAkB,KAAK,CAAG;CAE9C,IAAI;EAEF,IAAM,IAAS,IAAI,IAAI,GAAK,IAAa,eAAe,KAAA,CAAS;EAEjE,OAAO;GACL,MAAM,IAAa,EAAO,WAAW,GAAG,EAAO,SAAS,EAAO;GAC/D,OAAO,OAAO,YAAY,EAAO,YAAY;GAC7C,MAAM,EAAO;EACf;CACF,QAAQ;EACN,MAAU,MAAM,cAAc;CAChC;AACF;AAEA,SAAgB,EAAa,GAA0B,IAAU,IAAc;CAC7E,IAAM,EAAE,UAAO,IAAI,WAAQ,CAAC,GAAG,UAAO,OAAO,GAEvC,IAAa,IAAU,EAAO,GAAO,CAAS,IAAI,GAClD,IAAS,IAAI,gBAAgB;CAEnC,OAAO,QAAQ,CAAU,CAAC,CAAC,SAAS,CAAC,GAAK,OAAS;EACjD,EAAO,OAAO,GAAK,OAAO,CAAG,CAAC;CAChC,CAAC;CAGD,IAAM,IAAiB,IAAQ,EAAK,WAAW,GAAG,IAAI,IAAO,IAAI,MAAU,IACrE,IAAc,EAAO,SAAS;CAIpC,OAHK,IAGE,GAAG,IADQ,EAAK,SAAS,GAAG,IAAI,MAAM,MAChB,IAAc,MAHlB,IAAO;AAIlC"}
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@greypan/js-kit",
3
- "version": "1.0.0",
4
- "description": "",
3
+ "version": "1.2.0",
4
+ "description": "JavaScript utility functions",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/pan-Z2l0aHVi/mono.git"
9
9
  },
10
10
  "type": "module",
11
+ "files": [
12
+ "dist"
13
+ ],
11
14
  "sideEffects": false,
12
15
  "main": "./dist/index.js",
13
16
  "module": "./dist/index.js",
@@ -34,18 +37,14 @@
34
37
  "access": "public",
35
38
  "registry": "https://registry.npmjs.org/"
36
39
  },
37
- "dependencies": {},
38
- "devDependencies": {
39
- "vite": "npm:@voidzero-dev/vite-plus-core@latest",
40
- "vite-plus": "latest"
40
+ "dependencies": {
41
+ "remeda": "^2.39.0"
41
42
  },
42
43
  "browserslist": [
43
44
  "defaults"
44
45
  ],
45
46
  "scripts": {
46
- "build": "run-p type-check \"build-only {@}\" --",
47
- "build-only": "vp build",
48
- "deploy": "npm publish",
47
+ "build": "vue-tsc --build && vp build",
49
48
  "preview": "vp preview",
50
49
  "test": "vp test run",
51
50
  "type-check": "vue-tsc --build",
@@ -1,38 +0,0 @@
1
-
2
- > @greypan/js-kit@1.0.0 build /Users/bopan/VibeCoding/mono/packages/js-kit
3
- > run-p type-check "build-only {@}" --
4
-
5
-
6
- > @greypan/js-kit@1.0.0 build-only /Users/bopan/VibeCoding/mono/packages/js-kit
7
- > vp build
8
-
9
-
10
- > @greypan/js-kit@1.0.0 type-check /Users/bopan/VibeCoding/mono/packages/js-kit
11
- > vue-tsc --build
12
-
13
- vite v8.1.2 building client environment for production...
14
- 
15
- rendering chunks...
16
-
17
- [unplugin:dts] Start generate declaration files...
18
- [unplugin:dts] Declaration files built in 684ms.
19
-
20
- computing gzip size...
21
- dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/isNullish.js 0.20 kB │ gzip: 0.16 kB │ map: 0.35 kB
22
- dist/_virtual/_rolldown/runtime.js 0.26 kB │ gzip: 0.22 kB
23
- dist/plugin/core.js 0.29 kB │ gzip: 0.19 kB │ map: 1.36 kB
24
- dist/number/index.js 0.30 kB │ gzip: 0.22 kB │ map: 1.07 kB
25
- dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/lazyDataLastImpl--3B10z3s.js 0.31 kB │ gzip: 0.24 kB │ map: 0.56 kB
26
- dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/omitBy.js 0.35 kB │ gzip: 0.25 kB │ map: 0.64 kB
27
- dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/purry.js 0.37 kB │ gzip: 0.27 kB │ map: 0.62 kB
28
- dist/random/index.js 0.49 kB │ gzip: 0.27 kB │ map: 1.59 kB
29
- dist/paradigm/rust.js 0.67 kB │ gzip: 0.37 kB │ map: 1.81 kB
30
- dist/paradigm/go.js 0.69 kB │ gzip: 0.38 kB │ map: 1.55 kB
31
- dist/plugin/batching-emitter.js 0.75 kB │ gzip: 0.43 kB │ map: 2.41 kB
32
- dist/timer/controllable-interval.js 0.83 kB │ gzip: 0.42 kB │ map: 3.24 kB
33
- dist/timer/debounce.js 0.88 kB │ gzip: 0.50 kB │ map: 3.59 kB
34
- dist/index.js 0.91 kB │ gzip: 0.36 kB
35
- dist/url/index.js 0.95 kB │ gzip: 0.56 kB │ map: 2.17 kB
36
- dist/node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/funnel.js 1.23 kB │ gzip: 0.57 kB │ map: 2.10 kB
37
-
38
- ✓ built in 741ms
@@ -1,87 +0,0 @@
1
-
2
- > @mono/js-kit@1.0.0 test /Users/bopan/VibeCoding/mono/packages/js-kit
3
- > vp test run
4
-
5
- [?25l
6
-  RUN  v4.1.9 /Users/bopan/VibeCoding/mono/packages/js-kit
7
-
8
- [?2026h
9
-  ❯ src/plugin/__tests__/batch-emitter.spec.ts [queued]
10
-
11
-  Test Files 0 passed (10)
12
-  Tests 0 passed (0)
13
-  Start at 22:41:27
14
-  Duration 329ms
15
- [?2026l[?2026h
16
-  ❯ src/paradigm/__tests__/rust.spec.ts [queued]
17
-  ❯ src/plugin/__tests__/batch-emitter.spec.ts [queued]
18
-  ❯ src/plugin/__tests__/core.spec.ts [queued]
19
-  ❯ src/plugin/__tests__/event-emiiter.spec.ts [queued]
20
-  ❯ src/random/__tests__/random.spec.ts [queued]
21
-
22
-  Test Files 0 passed (10)
23
-  Tests 0 passed (0)
24
-  Start at 22:41:27
25
-  Duration 537ms
26
- [?2026l[?2026h ✓ src/paradigm/__tests__/rust.spec.ts (9 tests) 14ms
27
- ✓ src/random/__tests__/random.spec.ts (7 tests) 16ms
28
- stdout | src/plugin/__tests__/event-emiiter.spec.ts > EventEmitter 单元测试 > 应当支持注册和触发事件回调
29
- Tom click 1
30
- Tom click 2
31
-
32
- ✓ src/plugin/__tests__/event-emiiter.spec.ts (2 tests) 6ms
33
- stdout | src/plugin/__tests__/core.spec.ts > definePlugin 单元测试 > use > 应当正确组合 Store, Logger 和 Persist 逻辑
34
- set a = 100.
35
-
36
-
37
-  ❯ src/plugin/__tests__/batch-emitter.spec.ts 1/4
38
-  ❯ src/plugin/__tests__/core.spec.ts 0/3
39
-  ❯ src/plugin/__tests__/event-emiiter.spec.ts 2/2
40
-  ❯ src/random/__tests__/random.spec.ts 7/7
41
-  ❯ src/timer/__tests__/controllable-interval.spec.ts [queued]
42
-  ❯ src/url/__tests__/url.spec.ts [queued]
43
-
44
-  Test Files 3 passed (10)
45
-  Tests 19 passed (25)
46
-  Start at 22:41:27
47
-  Duration 638ms
48
- [?2026l[?2026h ✓ src/plugin/__tests__/batch-emitter.spec.ts (4 tests) 20ms
49
- ✓ src/plugin/__tests__/core.spec.ts (3 tests) 40ms
50
-
51
-  ❯ src/plugin/__tests__/event-emiiter.spec.ts 2/2
52
-  ❯ src/random/__tests__/random.spec.ts 7/7
53
-  ❯ src/timer/__tests__/controllable-interval.spec.ts [queued]
54
-  ❯ src/url/__tests__/url.spec.ts 0/12
55
-
56
-  Test Files 5 passed (10)
57
-  Tests 25 passed (37)
58
-  Start at 22:41:27
59
-  Duration 914ms
60
- [?2026l[?2026h ✓ src/url/__tests__/url.spec.ts (12 tests) 8ms
61
-
62
-  ❯ src/fetch/__tests__/compose.spec.ts [queued]
63
-  ❯ src/number/__tests__/number.spec.ts 0/8
64
-  ❯ src/timer/__tests__/controllable-interval.spec.ts 1/3
65
-
66
-  Test Files 6 passed (10)
67
-  Tests 38 passed (48)
68
-  Start at 22:41:27
69
-  Duration 1.01s
70
- [?2026l[?2026h ✓ src/timer/__tests__/controllable-interval.spec.ts (3 tests) 8ms
71
- ✓ src/number/__tests__/number.spec.ts (8 tests) 7ms
72
- ✓ src/fetch/__tests__/compose.spec.ts (6 tests) 9ms
73
-
74
-  ❯ src/paradigm/__tests__/go.spec.ts 1/8
75
-
76
-  Test Files 9 passed (10)
77
-  Tests 55 passed (62)
78
-  Start at 22:41:27
79
-  Duration 1.12s
80
- [?2026l ✓ src/paradigm/__tests__/go.spec.ts (8 tests) 6ms
81
-
82
-  Test Files  10 passed (10)
83
-  Tests  62 passed (62)
84
-  Start at  22:41:27
85
-  Duration  1.16s (transform 705ms, setup 0ms, import 1.53s, tests 135ms, environment 1ms)
86
-
87
- [?25h
@@ -1,40 +0,0 @@
1
- //#region ../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/funnel.js
2
- var e = Symbol("funnel/voidReducer"), t = () => e;
3
- function n(n, { triggerAt: r = "end", minQuietPeriodMs: i, maxBurstDurationMs: a, minGapMs: o, reducer: s = t }) {
4
- let c, l, u, d, f = () => {
5
- let t = u;
6
- t !== void 0 && (u = void 0, t === e ? n() : n(t), o !== void 0 && (l = setTimeout(p, o)));
7
- }, p = () => {
8
- clearTimeout(l), l = void 0, c === void 0 && f();
9
- }, m = () => {
10
- clearTimeout(c), c = void 0, d = void 0, l === void 0 && f();
11
- };
12
- return {
13
- call: (...e) => {
14
- let t = c === void 0 && l === void 0;
15
- if ((r !== "start" || t) && (u = s(u, ...e)), !(c === void 0 && !t)) {
16
- if (i !== void 0 || a !== void 0 || o === void 0) {
17
- clearTimeout(c);
18
- let e = Date.now();
19
- d ??= e;
20
- let t = a === void 0 ? i ?? 0 : Math.min(i ?? a, Math.max(0, a - (e - d)));
21
- c = setTimeout(m, t);
22
- }
23
- r !== "end" && t && f();
24
- }
25
- },
26
- cancel: () => {
27
- clearTimeout(c), c = void 0, d = void 0, clearTimeout(l), l = void 0, u = void 0;
28
- },
29
- flush: () => {
30
- m(), p();
31
- },
32
- get isIdle() {
33
- return c === void 0 && l === void 0;
34
- }
35
- };
36
- }
37
- //#endregion
38
- export { n as funnel };
39
-
40
- //# sourceMappingURL=funnel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"funnel.js","names":[],"sources":["../../../../../../../../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/funnel.js"],"sourcesContent":["const e=Symbol(`funnel/voidReducer`),t=()=>e;function n(n,{triggerAt:r=`end`,minQuietPeriodMs:i,maxBurstDurationMs:a,minGapMs:o,reducer:s=t}){let c,l,u,d,f=()=>{let t=u;t!==void 0&&(u=void 0,t===e?n():n(t),o!==void 0&&(l=setTimeout(p,o)))},p=()=>{clearTimeout(l),l=void 0,c===void 0&&f()},m=()=>{clearTimeout(c),c=void 0,d=void 0,l===void 0&&f()};return{call:(...e)=>{let t=c===void 0&&l===void 0;if((r!==`start`||t)&&(u=s(u,...e)),!(c===void 0&&!t)){if(i!==void 0||a!==void 0||o===void 0){clearTimeout(c);let e=Date.now();d??=e;let t=a===void 0?i??0:Math.min(i??a,Math.max(0,a-(e-d)));c=setTimeout(m,t)}r!==`end`&&t&&f()}},cancel:()=>{clearTimeout(c),c=void 0,d=void 0,clearTimeout(l),l=void 0,u=void 0},flush:()=>{m(),p()},get isIdle(){return c===void 0&&l===void 0}}}export{n as funnel};\n//# sourceMappingURL=funnel.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,IAAM,IAAE,OAAO,oBAAoB,GAAE,UAAM;AAAE,SAAS,EAAE,GAAE,EAAC,WAAU,IAAE,OAAM,kBAAiB,GAAE,oBAAmB,GAAE,UAAS,GAAE,SAAQ,IAAE,KAAG;CAAC,IAAI,GAAE,GAAE,GAAE,GAAE,UAAM;EAAC,IAAI,IAAE;EAAE,MAAI,KAAK,MAAI,IAAE,KAAK,GAAE,MAAI,IAAE,EAAE,IAAE,EAAE,CAAC,GAAE,MAAI,KAAK,MAAI,IAAE,WAAW,GAAE,CAAC;CAAG,GAAE,UAAM;EAAC,aAAa,CAAC,GAAE,IAAE,KAAK,GAAE,MAAI,KAAK,KAAG,EAAE;CAAC,GAAE,UAAM;EAAC,aAAa,CAAC,GAAE,IAAE,KAAK,GAAE,IAAE,KAAK,GAAE,MAAI,KAAK,KAAG,EAAE;CAAC;CAAE,OAAM;EAAC,OAAM,GAAG,MAAI;GAAC,IAAI,IAAE,MAAI,KAAK,KAAG,MAAI,KAAK;GAAE,KAAI,MAAI,WAAS,OAAK,IAAE,EAAE,GAAE,GAAG,CAAC,IAAG,EAAE,MAAI,KAAK,KAAG,CAAC,IAAG;IAAC,IAAG,MAAI,KAAK,KAAG,MAAI,KAAK,KAAG,MAAI,KAAK,GAAE;KAAC,aAAa,CAAC;KAAE,IAAI,IAAE,KAAK,IAAI;KAAE,MAAI;KAAE,IAAI,IAAE,MAAI,KAAK,IAAE,KAAG,IAAE,KAAK,IAAI,KAAG,GAAE,KAAK,IAAI,GAAE,KAAG,IAAE,EAAE,CAAC;KAAE,IAAE,WAAW,GAAE,CAAC;IAAC;IAAC,MAAI,SAAO,KAAG,EAAE;GAAC;EAAC;EAAE,cAAW;GAAC,aAAa,CAAC,GAAE,IAAE,KAAK,GAAE,IAAE,KAAK,GAAE,aAAa,CAAC,GAAE,IAAE,KAAK,GAAE,IAAE,KAAK;EAAC;EAAE,aAAU;GAAC,EAAE,GAAE,EAAE;EAAC;EAAE,IAAI,SAAQ;GAAC,OAAO,MAAI,KAAK,KAAG,MAAI,KAAK;EAAC;CAAC;AAAC"}
@@ -1,8 +0,0 @@
1
- //#region ../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/isNullish.js
2
- function e(e) {
3
- return e == null;
4
- }
5
- //#endregion
6
- export { e as isNullish };
7
-
8
- //# sourceMappingURL=isNullish.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"isNullish.js","names":[],"sources":["../../../../../../../../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/isNullish.js"],"sourcesContent":["function e(e){return e==null}export{e as isNullish};\n//# sourceMappingURL=isNullish.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAS,EAAE,GAAE;CAAC,OAAO,KAAG;AAAI"}
@@ -1,12 +0,0 @@
1
- //#region ../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/lazyDataLastImpl--3B10z3s.js
2
- function e(e, t, n) {
3
- let r = (n) => e(n, ...t);
4
- return n === void 0 ? r : Object.assign(r, {
5
- lazy: n,
6
- lazyArgs: t
7
- });
8
- }
9
- //#endregion
10
- export { e as t };
11
-
12
- //# sourceMappingURL=lazyDataLastImpl--3B10z3s.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lazyDataLastImpl--3B10z3s.js","names":[],"sources":["../../../../../../../../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/lazyDataLastImpl--3B10z3s.js"],"sourcesContent":["function e(e,t,n){let r=n=>e(n,...t);return n===void 0?r:Object.assign(r,{lazy:n,lazyArgs:t})}export{e as t};\n//# sourceMappingURL=lazyDataLastImpl--3B10z3s.js.map"],"x_google_ignoreList":[0],"mappings":";AAAA,SAAS,EAAE,GAAE,GAAE,GAAE;CAAC,IAAI,KAAE,MAAG,EAAE,GAAE,GAAG,CAAC;CAAE,OAAO,MAAI,KAAK,IAAE,IAAE,OAAO,OAAO,GAAE;EAAC,MAAK;EAAE,UAAS;CAAC,CAAC;AAAC"}
@@ -1,14 +0,0 @@
1
- import { purry as e } from "./purry.js";
2
- //#region ../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/omitBy.js
3
- function t(...t) {
4
- return e(n, t);
5
- }
6
- function n(e, t) {
7
- let n = { ...e };
8
- for (let [r, i] of Object.entries(n)) t(i, r, e) && delete n[r];
9
- return n;
10
- }
11
- //#endregion
12
- export { t as omitBy };
13
-
14
- //# sourceMappingURL=omitBy.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"omitBy.js","names":["e"],"sources":["../../../../../../../../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/omitBy.js"],"sourcesContent":["import{purry as e}from\"./purry.js\";function t(...t){return e(n,t)}function n(e,t){let n={...e};for(let[r,i]of Object.entries(n))t(i,r,e)&&delete n[r];return n}export{t as omitBy};\n//# sourceMappingURL=omitBy.js.map"],"x_google_ignoreList":[0],"mappings":";;AAAmC,SAAS,EAAE,GAAG,GAAE;CAAC,OAAOA,EAAE,GAAE,CAAC;AAAC;AAAC,SAAS,EAAE,GAAE,GAAE;CAAC,IAAI,IAAE,EAAC,GAAG,EAAC;CAAE,KAAI,IAAG,CAAC,GAAE,MAAK,OAAO,QAAQ,CAAC,GAAE,EAAE,GAAE,GAAE,CAAC,KAAG,OAAO,EAAE;CAAG,OAAO;AAAC"}
@@ -1,12 +0,0 @@
1
- import { t as e } from "./lazyDataLastImpl--3B10z3s.js";
2
- //#region ../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/purry.js
3
- function t(t, n, r) {
4
- let i = t.length - n.length;
5
- if (i === 0) return t(...n);
6
- if (i === 1) return e(t, n, r);
7
- throw Error("Wrong number of arguments");
8
- }
9
- //#endregion
10
- export { t as purry };
11
-
12
- //# sourceMappingURL=purry.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"purry.js","names":[],"sources":["../../../../../../../../../node_modules/.pnpm/remeda@2.39.0/node_modules/remeda/dist/purry.js"],"sourcesContent":["import{t as e}from\"./lazyDataLastImpl--3B10z3s.js\";function t(t,n,r){let i=t.length-n.length;if(i===0)return t(...n);if(i===1)return e(t,n,r);throw Error(`Wrong number of arguments`)}export{t as purry};\n//# sourceMappingURL=purry.js.map"],"x_google_ignoreList":[0],"mappings":";;AAAmD,SAAS,EAAE,GAAE,GAAE,GAAE;CAAC,IAAI,IAAE,EAAE,SAAO,EAAE;CAAO,IAAG,MAAI,GAAE,OAAO,EAAE,GAAG,CAAC;CAAE,IAAG,MAAI,GAAE,OAAO,EAAE,GAAE,GAAE,CAAC;CAAE,MAAM,MAAM,2BAA2B;AAAC"}
@@ -1,105 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { asyncCompose, type Middleware } from '../compose'
4
-
5
- describe('Compose 单元测试', () => {
6
- describe('基本用法', () => {
7
- it('应当按顺序运行中间件', async () => {
8
- const calls: string[] = []
9
-
10
- const middleware1: Middleware = async (ctx, next) => {
11
- calls.push('m1-before')
12
- await next()
13
- calls.push('m1-after')
14
- }
15
- const middleware2: Middleware = async (ctx, next) => {
16
- calls.push('m2-before')
17
- await next()
18
- calls.push('m2-after')
19
- }
20
- const middleware3: Middleware = async (ctx, next) => {
21
- calls.push('m3')
22
- await next()
23
- }
24
-
25
- const fn = asyncCompose(middleware1, middleware2, middleware3)
26
-
27
- await fn({}, async () => {
28
- calls.push('end')
29
- })
30
-
31
- expect(calls).toEqual(['m1-before', 'm2-before', 'm3', 'end', 'm2-after', 'm1-after'])
32
- })
33
- })
34
-
35
- describe('compose 边界情况', () => {
36
- it('空中间件数组时应直接调用外层 next', async () => {
37
- const calls: string[] = []
38
- const fn = asyncCompose()
39
- await fn({}, async () => {
40
- calls.push('end')
41
- })
42
- expect(calls).toEqual(['end'])
43
- })
44
-
45
- it('单个中间件时应正常执行并调用外层 next', async () => {
46
- const calls: string[] = []
47
- const fn = asyncCompose(async (ctx, next) => {
48
- calls.push('single')
49
- await next()
50
- })
51
- await fn({}, async () => {
52
- calls.push('end')
53
- })
54
- expect(calls).toEqual(['single', 'end'])
55
- })
56
-
57
- it('多次调用同一个 compose 函数时索引不应污染', async () => {
58
- const fn = asyncCompose(
59
- async (ctx: { calls: string[] }, next) => {
60
- ctx.calls.push('m1')
61
- await next()
62
- },
63
- async (ctx: { calls: string[] }, next) => {
64
- ctx.calls.push('m2')
65
- await next()
66
- }
67
- )
68
- const calls1: string[] = []
69
- const calls2: string[] = []
70
- await fn({ calls: calls1 }, async () => {
71
- calls1.push('end')
72
- })
73
- await fn({ calls: calls2 }, async () => {
74
- calls2.push('end')
75
- })
76
- expect(calls1).toEqual(['m1', 'm2', 'end'])
77
- expect(calls2).toEqual(['m1', 'm2', 'end'])
78
- })
79
-
80
- it('中间件抛出错误时应正确传递异常', async () => {
81
- const fn = asyncCompose(
82
- async () => {
83
- throw new Error('boom')
84
- },
85
- async (ctx, next) => {
86
- await next()
87
- }
88
- )
89
- await expect(fn({}, async () => {})).rejects.toThrow('boom')
90
- })
91
-
92
- it('同一个中间件里重复调用 next 应该抛错', async () => {
93
- const fn = asyncCompose(
94
- async (ctx, next) => {
95
- await next()
96
- await next() // 第二次调用,触发防护
97
- },
98
- async (ctx, next) => {
99
- await next()
100
- }
101
- )
102
- await expect(fn({}, async () => {})).rejects.toThrow('Should not call "await next()" multiple times!')
103
- })
104
- })
105
- })
@@ -1,23 +0,0 @@
1
- export type Next = () => Promise<void>
2
- export type Middleware<T = unknown> = (ctx: T, next: Next) => Promise<void>
3
-
4
- export function asyncCompose<T = unknown>(...fns: Middleware<T>[]): Middleware<T> {
5
- return async function dispatch(ctx: T, next: Next, i = 0): Promise<void> {
6
- if (!fns.length) return next()
7
- const fn = fns[i]
8
- if (!fn) return next()
9
- return fn(
10
- ctx,
11
- // 为什么不是 () => dispatch(ctx, next, i + 1)?
12
- // 利用闭包防止中间件重复调用 next
13
- (() => {
14
- let called = false
15
- return async () => {
16
- if (called) throw new Error('Should not call "await next()" multiple times!')
17
- called = true
18
- await dispatch(ctx, next, i + 1)
19
- }
20
- })()
21
- )
22
- }
23
- }
package/src/index.ts DELETED
@@ -1,7 +0,0 @@
1
- export * from './number'
2
- export * from './paradigm'
3
- export * from './plugin'
4
- export * from './random'
5
- export * from './timer'
6
- export * from './url'
7
- export * from './utility-types'
@@ -1,50 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { clamp, toPrecision } from '..'
4
-
5
- describe('number 单元测试', () => {
6
- describe('toPrecision', () => {
7
- it('应正确处理正数精度(四舍五入)', () => {
8
- expect(toPrecision(1234.567, 2)).toBe(1234.57)
9
- expect(toPrecision(1.45, 1)).toBe(1.5)
10
- expect(toPrecision(1.44, 1)).toBe(1.4)
11
- })
12
-
13
- it('应正确处理负数精度(取整到十位/百位)', () => {
14
- expect(toPrecision(1234.56, -1)).toBe(1230)
15
- expect(toPrecision(1234.56, -2)).toBe(1200)
16
- expect(toPrecision(1260.56, -2)).toBe(1300)
17
- })
18
-
19
- it('应正确处理精度为 0 的情况', () => {
20
- expect(toPrecision(1234.56, 0)).toBe(1235)
21
- })
22
-
23
- it('应对非有限数字(NaN, Infinity)原样返回', () => {
24
- expect(toPrecision(NaN, 2)).toBeNaN()
25
- expect(toPrecision(Infinity, 2)).toBe(Infinity)
26
- expect(toPrecision(-Infinity, 2)).toBe(-Infinity)
27
- })
28
- })
29
-
30
- describe('clamp', () => {
31
- it('数值在范围内时应返回原值', () => {
32
- expect(clamp(5, 0, 10)).toBe(5)
33
- expect(clamp(0, 0, 10)).toBe(0)
34
- expect(clamp(10, 0, 10)).toBe(10)
35
- })
36
-
37
- it('数值小于最小值时应返回最小值', () => {
38
- expect(clamp(-5, 0, 10)).toBe(0)
39
- })
40
-
41
- it('数值大于最大值时应返回最大值', () => {
42
- expect(clamp(15, 0, 10)).toBe(10)
43
- })
44
-
45
- it('处理负数区间', () => {
46
- expect(clamp(-20, -10, -5)).toBe(-10)
47
- expect(clamp(-2, -10, -5)).toBe(-5)
48
- })
49
- })
50
- })
@@ -1,22 +0,0 @@
1
- /**
2
- * 转换为指定精度的数字
3
- * @param val 需要转换的数字
4
- * @param precision 精度。表示小数点后位数。如果传了负数(比如 -2),则取整到百位(1234.56->1200)。
5
- * @returns 转换后的数字
6
- */
7
- export function toPrecision(val: number, precision: number): number {
8
- if (Number.isNaN(val) || !Number.isFinite(val)) return val
9
-
10
- const factor = Math.pow(10, precision)
11
- return Math.round(val * factor) / factor
12
- }
13
-
14
- /**
15
- * 将数字限制在指定的范围内
16
- * @param val 当前值
17
- * @param min 最小值
18
- * @param max 最大值
19
- */
20
- export function clamp(val: number, min: number, max: number): number {
21
- return Math.max(min, Math.min(val, max))
22
- }
@@ -1,63 +0,0 @@
1
- import { describe, expect, it } from 'vite-plus/test'
2
-
3
- import { err, isErr, isOk, ok, to, unwrap } from '../go'
4
-
5
- describe('Result 工具函数(Go 风格)单元测试', () => {
6
- it('ok() 应当返回 Ok<T>', () => {
7
- const result = ok(42)
8
- expect(result).toEqual([null, 42])
9
- expect(isOk(result)).toBe(true)
10
- expect(isErr(result)).toBe(false)
11
- })
12
-
13
- it('err() 应当返回 Err<E>', () => {
14
- const error = new Error('Failed.')
15
- const result = err(error)
16
- expect(result).toEqual([error, null])
17
- expect(isErr(result)).toBe(true)
18
- expect(isOk(result)).toBe(false)
19
- })
20
-
21
- it('isOk() 和 isErr() 应当正确区分结果', () => {
22
- const success = ok(123)
23
- const failure = err('error')
24
-
25
- expect(isOk(success)).toBe(true)
26
- expect(isErr(success)).toBe(false)
27
-
28
- expect(isOk(failure)).toBe(false)
29
- expect(isErr(failure)).toBe(true)
30
- })
31
-
32
- it('to() 应当把成功的 Promise 包装成 Ok', async () => {
33
- const result = await to(Promise.resolve('hi'))
34
- expect(isOk(result)).toBe(true)
35
- expect(result).toEqual([null, 'hi'])
36
- })
37
-
38
- it('to() 应当把失败的 Promise 包装成 Err', async () => {
39
- const result = await to(Promise.reject('error'))
40
- expect(isErr(result)).toBe(true)
41
- expect(result).toEqual(['error', null])
42
- })
43
-
44
- it('unwrap() 在 Ok 时返回值', () => {
45
- const result = ok('data')
46
- expect(unwrap(result)).toBe('data')
47
- })
48
-
49
- it('unwrap() 在 Err 时返回错误', () => {
50
- const result = err('error')
51
- expect(unwrap(result)).toBe('error')
52
- })
53
-
54
- it('Result 数据结构应当是 [error, value]', () => {
55
- const success = ok(1)
56
- expect(success[0]).toBeNull()
57
- expect(success[1]).toBe(1)
58
-
59
- const failure = err('boom')
60
- expect(failure[0]).toBe('boom')
61
- expect(failure[1]).toBeNull()
62
- })
63
- })