@planet-matrix/mobius-model 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +30 -1
  3. package/dist/index.js +4 -2
  4. package/dist/index.js.map +22 -4
  5. package/package.json +3 -3
  6. package/scripts/build.ts +4 -4
  7. package/src/basic/README.md +144 -0
  8. package/src/basic/array.ts +872 -0
  9. package/src/basic/bigint.ts +114 -0
  10. package/src/basic/boolean.ts +180 -0
  11. package/src/basic/enhance.ts +10 -0
  12. package/src/basic/error.ts +51 -0
  13. package/src/basic/function.ts +453 -0
  14. package/src/basic/helper.ts +276 -0
  15. package/src/basic/index.ts +17 -0
  16. package/src/basic/is.ts +320 -0
  17. package/src/basic/number.ts +178 -0
  18. package/src/basic/object.ts +140 -0
  19. package/src/basic/promise.ts +464 -0
  20. package/src/basic/regexp.ts +7 -0
  21. package/src/basic/stream.ts +140 -0
  22. package/src/basic/string.ts +308 -0
  23. package/src/basic/symbol.ts +164 -0
  24. package/src/basic/temporal.ts +224 -0
  25. package/src/encoding/README.md +105 -0
  26. package/src/encoding/base64.ts +98 -0
  27. package/src/encoding/index.ts +1 -0
  28. package/src/index.ts +4 -0
  29. package/src/random/README.md +109 -0
  30. package/src/random/index.ts +1 -0
  31. package/src/random/uuid.ts +103 -0
  32. package/src/type/README.md +330 -0
  33. package/src/type/array.ts +5 -0
  34. package/src/type/boolean.ts +471 -0
  35. package/src/type/class.ts +419 -0
  36. package/src/type/function.ts +1519 -0
  37. package/src/type/helper.ts +135 -0
  38. package/src/type/index.ts +14 -0
  39. package/src/type/intersection.ts +93 -0
  40. package/src/type/is.ts +247 -0
  41. package/src/type/iteration.ts +233 -0
  42. package/src/type/number.ts +732 -0
  43. package/src/type/object.ts +788 -0
  44. package/src/type/path.ts +73 -0
  45. package/src/type/string.ts +1004 -0
  46. package/src/type/tuple.ts +2424 -0
  47. package/src/type/union.ts +108 -0
  48. package/tests/unit/basic/array.spec.ts +290 -0
  49. package/tests/unit/basic/bigint.spec.ts +50 -0
  50. package/tests/unit/basic/boolean.spec.ts +74 -0
  51. package/tests/unit/basic/error.spec.ts +32 -0
  52. package/tests/unit/basic/function.spec.ts +175 -0
  53. package/tests/unit/basic/helper.spec.ts +118 -0
  54. package/tests/unit/basic/number.spec.ts +74 -0
  55. package/tests/unit/basic/object.spec.ts +46 -0
  56. package/tests/unit/basic/promise.spec.ts +232 -0
  57. package/tests/unit/basic/regexp.spec.ts +11 -0
  58. package/tests/unit/basic/stream.spec.ts +120 -0
  59. package/tests/unit/basic/string.spec.ts +74 -0
  60. package/tests/unit/basic/symbol.spec.ts +72 -0
  61. package/tests/unit/basic/temporal.spec.ts +78 -0
  62. package/tests/unit/encoding/base64.spec.ts +40 -0
  63. package/tests/unit/random/uuid.spec.ts +37 -0
  64. package/dist/index.d.ts +0 -2
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/reactor/index.d.ts +0 -3
  67. package/dist/reactor/index.d.ts.map +0 -1
  68. package/dist/reactor/reactor-core/flags.d.ts +0 -99
  69. package/dist/reactor/reactor-core/flags.d.ts.map +0 -1
  70. package/dist/reactor/reactor-core/index.d.ts +0 -4
  71. package/dist/reactor/reactor-core/index.d.ts.map +0 -1
  72. package/dist/reactor/reactor-core/primitive.d.ts +0 -276
  73. package/dist/reactor/reactor-core/primitive.d.ts.map +0 -1
  74. package/dist/reactor/reactor-core/reactive-system.d.ts +0 -241
  75. package/dist/reactor/reactor-core/reactive-system.d.ts.map +0 -1
  76. package/dist/reactor/reactor-operators/branch.d.ts +0 -19
  77. package/dist/reactor/reactor-operators/branch.d.ts.map +0 -1
  78. package/dist/reactor/reactor-operators/convert.d.ts +0 -30
  79. package/dist/reactor/reactor-operators/convert.d.ts.map +0 -1
  80. package/dist/reactor/reactor-operators/create.d.ts +0 -26
  81. package/dist/reactor/reactor-operators/create.d.ts.map +0 -1
  82. package/dist/reactor/reactor-operators/filter.d.ts +0 -269
  83. package/dist/reactor/reactor-operators/filter.d.ts.map +0 -1
  84. package/dist/reactor/reactor-operators/index.d.ts +0 -8
  85. package/dist/reactor/reactor-operators/index.d.ts.map +0 -1
  86. package/dist/reactor/reactor-operators/join.d.ts +0 -48
  87. package/dist/reactor/reactor-operators/join.d.ts.map +0 -1
  88. package/dist/reactor/reactor-operators/map.d.ts +0 -165
  89. package/dist/reactor/reactor-operators/map.d.ts.map +0 -1
  90. package/dist/reactor/reactor-operators/utility.d.ts +0 -48
  91. package/dist/reactor/reactor-operators/utility.d.ts.map +0 -1
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Normalize a value to a 0-1 range based on min and max.
3
+ *
4
+ * @example
5
+ * ```
6
+ * // Expect: 0.5
7
+ * const example1 = normalize(5, 0, 10)
8
+ * // Expect: 0
9
+ * const example2 = normalize(2, 2, 6)
10
+ * ```
11
+ */
12
+ export const normalize = (value: number, min: number, max: number): number => {
13
+ if (min === max) {
14
+ throw new Error("Min and max value are the same.")
15
+ }
16
+ if (value < min || value > max) {
17
+ throw new Error(`Value ${value} is not in the range of ${min} to ${max}.`)
18
+ }
19
+ return (value - min) / (max - min)
20
+ }
21
+
22
+ /**
23
+ * Check if a number is even.
24
+ *
25
+ * @example
26
+ * ```
27
+ * // Expect: true
28
+ * const example1 = isEven(10)
29
+ * // Expect: false
30
+ * const example2 = isEven(7)
31
+ * ```
32
+ */
33
+ export const isEven = (x: number): boolean => x % 2 === 0
34
+
35
+ /**
36
+ * Check if a number is odd.
37
+ *
38
+ * @example
39
+ * ```
40
+ * // Expect: true
41
+ * const example1 = isOdd(7)
42
+ * // Expect: false
43
+ * const example2 = isOdd(10)
44
+ * ```
45
+ */
46
+ export const isOdd = (x: number): boolean => x % 2 !== 0
47
+
48
+ /**
49
+ * Clamp a number to a maximum value.
50
+ *
51
+ * @example
52
+ * ```
53
+ * // Expect: 5
54
+ * const example1 = maxTo(5, 10)
55
+ * // Expect: 3
56
+ * const example2 = maxTo(5, 3)
57
+ * ```
58
+ */
59
+ export const maxTo = (max: number, x: number): number => x > max ? max : x
60
+
61
+ /**
62
+ * Clamp a number to a minimum value.
63
+ *
64
+ * @example
65
+ * ```
66
+ * // Expect: 5
67
+ * const example1 = minTo(5, 3)
68
+ * // Expect: 8
69
+ * const example2 = minTo(5, 8)
70
+ * ```
71
+ */
72
+ export const minTo = (min: number, x: number): number => x < min ? min : x
73
+
74
+ /**
75
+ * Get the smaller of two numbers.
76
+ *
77
+ * @example
78
+ * ```
79
+ * // Expect: 2
80
+ * const example1 = minOf(2, 9)
81
+ * // Expect: -1
82
+ * const example2 = minOf(5, -1)
83
+ * ```
84
+ */
85
+ export const minOf = (x: number, y: number): number => x < y ? x : y
86
+
87
+ /**
88
+ * Get the larger of two numbers.
89
+ *
90
+ * @example
91
+ * ```
92
+ * // Expect: 9
93
+ * const example1 = maxOf(2, 9)
94
+ * // Expect: 5
95
+ * const example2 = maxOf(5, -1)
96
+ * ```
97
+ */
98
+ export const maxOf = (x: number, y: number): number => x > y ? x : y
99
+
100
+ /**
101
+ * Clamp a number between two bounds.
102
+ *
103
+ * @example
104
+ * ```
105
+ * // Expect: 5
106
+ * const example1 = between(0, 10, 5)
107
+ * // Expect: 0
108
+ * const example2 = between(0, 10, -3)
109
+ * ```
110
+ */
111
+ export const between = (a: number, b: number, x: number): number => {
112
+ const min = minOf(a, b)
113
+ const max = maxOf(a, b)
114
+ return x < min ? min : (x > max ? max : x)
115
+ }
116
+
117
+ /**
118
+ * Get a random integer between min and max, inclusive.
119
+ *
120
+ * @example
121
+ * ```
122
+ * // Expect: 4
123
+ * const example1 = randomBetween(4, 4)
124
+ * // Expect: 10
125
+ * const example2 = randomBetween(10, 10)
126
+ * ```
127
+ */
128
+ export const randomBetween = (min: number, max: number): number => {
129
+ return Math.floor(Math.random() * (max - min + 1) + min)
130
+ }
131
+
132
+ /**
133
+ * Get a random integer between two values, regardless of order, inclusive.
134
+ *
135
+ * @example
136
+ * ```
137
+ * // Expect: 4
138
+ * const example1 = randomIntBetween(4, 4)
139
+ * // Expect: 10
140
+ * const example2 = randomIntBetween(10, 10)
141
+ * ```
142
+ */
143
+ export const randomIntBetween = (a: number, b: number): number => {
144
+ const min = minOf(a, b)
145
+ const max = maxOf(a, b)
146
+ return Math.floor(Math.random() * (max - min + 1)) + min
147
+ }
148
+
149
+ export interface NumberConstraints {
150
+ min?: number | undefined
151
+ max?: number | undefined
152
+ step?: number | undefined
153
+ }
154
+
155
+ /**
156
+ * Constrain a number by step size and min/max bounds.
157
+ *
158
+ * @example
159
+ * ```
160
+ * // Expect: 10
161
+ * const example1 = constrainNumber(12, { step: 5, max: 10 })
162
+ * // Expect: 3
163
+ * const example2 = constrainNumber(2.6, { step: 0.5, min: 3 })
164
+ * ```
165
+ */
166
+ export const constrainNumber = (value: number, constraints: NumberConstraints): number => {
167
+ let constrainedValue = value
168
+ if (constraints.step !== undefined) {
169
+ constrainedValue = Math.round(constrainedValue / constraints.step) * constraints.step
170
+ }
171
+ if (constraints.min !== undefined) {
172
+ constrainedValue = Math.max(constraints.min, constrainedValue)
173
+ }
174
+ if (constraints.max !== undefined) {
175
+ constrainedValue = Math.min(constraints.max, constrainedValue)
176
+ }
177
+ return constrainedValue
178
+ }
@@ -0,0 +1,140 @@
1
+ import type { AnyRecord } from "../type/index.ts"
2
+ import { isDate } from "./is.ts"
3
+
4
+ /**
5
+ * Return a new object that includes only the specified keys from the source object.
6
+ *
7
+ * @example
8
+ * ```
9
+ * // Expect: { a: 1, c: 3 }
10
+ * const example1 = includeFields({ a: 1, b: 2, c: 3 }, ["a", "c"])
11
+ * // Expect: {}
12
+ * const example2 = includeFields(null, ["a"])
13
+ * ```
14
+ */
15
+ export const includeFields = <T extends AnyRecord, K extends keyof T>(
16
+ object: T | null | undefined,
17
+ keys: K[],
18
+ ): Pick<T, K> => {
19
+ if (object === null || object === undefined) {
20
+ // oxlint-disable-next-line no-unsafe-type-assertion
21
+ return {} as Pick<T, K>
22
+ }
23
+ const newObject: Partial<Pick<T, K>> = {} // 初始化一个部分类型的对象
24
+ keys.forEach((key) => {
25
+ if (key in object) {
26
+ newObject[key] = object[key]
27
+ }
28
+ })
29
+ // oxlint-disable-next-line no-unsafe-type-assertion
30
+ return newObject as Pick<T, K> // 使用正确的变量名并断言返回类型
31
+ }
32
+
33
+ /**
34
+ * Return a new object that excludes the specified keys from the source object.
35
+ *
36
+ * @example
37
+ * ```
38
+ * // Expect: { a: 1 }
39
+ * const example1 = excludeFields({ a: 1, b: 2 }, ["b"])
40
+ * // Expect: {}
41
+ * const example2 = excludeFields(undefined, ["a"])
42
+ * ```
43
+ */
44
+ export const excludeFields = <T extends AnyRecord, K extends keyof T>(
45
+ object: T | null | undefined,
46
+ keys: K[],
47
+ ): Omit<T, K> => {
48
+ if (object === null || object === undefined) {
49
+ // oxlint-disable-next-line no-unsafe-type-assertion
50
+ return {} as Omit<T, K>
51
+ }
52
+ const newObject: Partial<T> = { ...object } // 创建原对象的浅拷贝
53
+ keys.forEach((key) => {
54
+ // oxlint-disable-next-line no-dynamic-delete
55
+ delete newObject[key] // 删除指定的键
56
+ })
57
+ // oxlint-disable-next-line no-unsafe-type-assertion
58
+ return newObject as Omit<T, K> // 使用Omit类型确保返回的类型反映了被排除的键
59
+ }
60
+
61
+ /**
62
+ * Convert all Date fields in an object to number.
63
+ *
64
+ * @example
65
+ * ```before
66
+ * type Obj = {
67
+ * createdAt: Date,
68
+ * }
69
+ * ```
70
+ * ```after
71
+ * type Obj = {
72
+ * createdAt: number,
73
+ * }
74
+ * ```
75
+ *
76
+ * @example
77
+ * ```before
78
+ * type Obj = {
79
+ * createdAt: Date | undefined,
80
+ * }
81
+ * ```
82
+ * ```after
83
+ * type Obj = {
84
+ * createdAt: number | undefined,
85
+ * }
86
+ * ```
87
+ *
88
+ * @example
89
+ * ```before
90
+ * type Obj = {
91
+ * createdAt: Date | null,
92
+ * }
93
+ * ```
94
+ * ```after
95
+ * type Obj = {
96
+ * createdAt: number | null,
97
+ * }
98
+ * ```
99
+ */
100
+ export type ObjectDateFieldsToNumber<O extends object> = {
101
+ [K in keyof O]: O[K] extends Date
102
+ ? number
103
+ : (
104
+ O[K] extends Date | undefined
105
+ ? number | undefined
106
+ :
107
+ (O[K] extends Date | null
108
+ ? number | null
109
+ : (
110
+ O[K] extends object
111
+ ? ObjectDateFieldsToNumber<O[K]>
112
+ : O[K]
113
+ )
114
+ )
115
+ )
116
+ }
117
+ /**
118
+ * Convert all Date fields in an object to number.
119
+ *
120
+ * @example
121
+ * ```
122
+ * const obj = { createdAt: new Date() };
123
+ * const result = objectDateFieldsToNumber(obj);
124
+ * // Expect: { createdAt: 1712345678901 }
125
+ * ```
126
+ */
127
+ export const objectDateFieldsToNumber = <O extends Record<string | number | symbol, unknown>>(
128
+ obj: O
129
+ ): ObjectDateFieldsToNumber<O> => {
130
+ // oxlint-disable-next-line guard-for-in
131
+ for (const key in obj) {
132
+ const value = obj[key];
133
+ if (isDate(value)) {
134
+ // oxlint-disable-next-line no-unsafe-type-assertion
135
+ obj[key] = value.getTime() as O[Extract<keyof O, string>]
136
+ }
137
+ }
138
+ // oxlint-disable-next-line no-unsafe-type-assertion
139
+ return obj as ObjectDateFieldsToNumber<O>
140
+ }