@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,120 @@
1
+ import { expect, test } from "vitest"
2
+
3
+ import {
4
+ streamConsumeInAsyncMacroTask,
5
+ streamConsumeInSyncMacroTask,
6
+ streamFromArray,
7
+ streamTransformInAsyncMacroTask,
8
+ } from "#Source/basic/index.ts"
9
+
10
+ test("streamFromArray creates a readable stream from array values", async () => {
11
+ const source = [1, 2, 3]
12
+ const values: number[] = []
13
+
14
+ const stream = streamFromArray(source)
15
+ for await (const value of stream) {
16
+ values.push(value)
17
+ }
18
+
19
+ expect(values).toEqual(source)
20
+ })
21
+
22
+ test("streamConsumeInSyncMacroTask consumes stream and handles callback errors", async () => {
23
+ const consumed: number[] = []
24
+ let doneCalled = false
25
+
26
+ await streamConsumeInSyncMacroTask<number>({
27
+ readableStream: streamFromArray([1, 2, 3]),
28
+ onValue: (chunk) => {
29
+ consumed.push(chunk)
30
+ },
31
+ onDone: () => {
32
+ doneCalled = true
33
+ },
34
+ })
35
+
36
+ expect(consumed).toEqual([1, 2, 3])
37
+ expect(doneCalled).toBe(true)
38
+
39
+ let errorMessage = ""
40
+ let doneCalledInErrorCase = false
41
+ await streamConsumeInSyncMacroTask<number>({
42
+ readableStream: streamFromArray([1, 2]),
43
+ onValue: (chunk) => {
44
+ if (chunk === 2) {
45
+ throw new Error("boom")
46
+ }
47
+ },
48
+ onDone: () => {
49
+ doneCalledInErrorCase = true
50
+ },
51
+ onError: (error) => {
52
+ errorMessage = error.message
53
+ },
54
+ })
55
+
56
+ expect(errorMessage).toContain("boom")
57
+ expect(doneCalledInErrorCase).toBe(false)
58
+ })
59
+
60
+ test("streamConsumeInAsyncMacroTask consumes stream and forwards callback failures", async () => {
61
+ const consumed: number[] = []
62
+ await new Promise<void>((resolve, reject) => {
63
+ streamConsumeInAsyncMacroTask<number>({
64
+ readableStream: streamFromArray([1, 2, 3]),
65
+ onValue: (chunk) => {
66
+ consumed.push(chunk)
67
+ },
68
+ onDone: () => {
69
+ resolve()
70
+ },
71
+ onError: (error) => {
72
+ reject(error)
73
+ },
74
+ })
75
+ })
76
+
77
+ expect(consumed).toEqual([1, 2, 3])
78
+
79
+ let errorMessage = ""
80
+ await new Promise<void>((resolve, reject) => {
81
+ streamConsumeInAsyncMacroTask<number>({
82
+ readableStream: streamFromArray([1]),
83
+ onValue: () => {
84
+ throw new Error("async-boom")
85
+ },
86
+ onDone: () => {
87
+ reject(new Error("onDone should not be called when onValue throws"))
88
+ },
89
+ onError: (error) => {
90
+ errorMessage = error.message
91
+ resolve()
92
+ },
93
+ })
94
+ })
95
+
96
+ expect(errorMessage).toContain("async-boom")
97
+ })
98
+
99
+ test("streamTransformInAsyncMacroTask transforms values and handles invalid inputs/errors", async () => {
100
+ expect(() => {
101
+ streamTransformInAsyncMacroTask<number, number>({})
102
+ }).toThrowError("Either readableStream or reader must be provided")
103
+
104
+ const transformed = streamTransformInAsyncMacroTask<number, number>({
105
+ readableStream: streamFromArray([1, 2, 3]),
106
+ onChunk: (chunk, controller) => {
107
+ if (chunk.done === true) {
108
+ controller.close()
109
+ return
110
+ }
111
+ controller.enqueue(chunk.value * 10)
112
+ },
113
+ })
114
+
115
+ const values: number[] = []
116
+ for await (const value of transformed) {
117
+ values.push(value)
118
+ }
119
+ expect(values).toEqual([10, 20, 30])
120
+ })
@@ -0,0 +1,74 @@
1
+ import { expect, test } from "vitest"
2
+
3
+ import {
4
+ stringCalculateUnits,
5
+ stringCamelCaseToKebabCase,
6
+ stringHelloWord,
7
+ stringKebabCaseToCamelCase,
8
+ stringRandom,
9
+ stringSliceByUnits,
10
+ stringSmartSplit,
11
+ stringSplit,
12
+ stringTruncate,
13
+ stringTruncateByUnits,
14
+ } from "#Source/basic/index.ts"
15
+
16
+ test("stringRandom returns expected output", () => {
17
+ const value = stringRandom(12)
18
+ expect(value).toHaveLength(12)
19
+
20
+ const constrained = stringRandom(10, "ab")
21
+ expect(constrained.split("").every(char => char === "a" || char === "b")).toBe(true)
22
+ })
23
+
24
+ test("stringCamelCaseToKebabCase converts correctly", () => {
25
+ expect(stringCamelCaseToKebabCase("helloWorld")).toBe("hello-world")
26
+ expect(stringCamelCaseToKebabCase("ab2Cd")).toBe("ab2-cd")
27
+ })
28
+
29
+ test("stringKebabCaseToCamelCase converts correctly", () => {
30
+ expect(stringKebabCaseToCamelCase("hello-world")).toBe("helloWorld")
31
+ expect(stringKebabCaseToCamelCase("ab2-cd")).toBe("ab2Cd")
32
+ })
33
+
34
+ test("stringHelloWord returns a greeting", () => {
35
+ const value = stringHelloWord()
36
+ expect(typeof value).toBe("string")
37
+ expect(value.length).toBeGreaterThan(0)
38
+ })
39
+
40
+ test("stringCalculateUnits counts half-width and full-width", () => {
41
+ expect(stringCalculateUnits("a中")).toBe(1.5)
42
+ expect(stringCalculateUnits("中文")).toBe(2)
43
+ })
44
+
45
+ test("stringTruncateByUnits respects unit limit", () => {
46
+ expect(stringTruncateByUnits("a中文", 1.5)).toBe("a中")
47
+ expect(stringTruncateByUnits("abc", 2)).toBe("abc")
48
+ })
49
+
50
+ test("stringSliceByUnits slices by unit indices", () => {
51
+ expect(stringSliceByUnits("a中文", 0, 1.5)).toBe("a中")
52
+ expect(stringSliceByUnits("中文ab", 1, 2)).toBe("文")
53
+ })
54
+
55
+ test("stringSplit returns overlapping chunks", () => {
56
+ expect(stringSplit({ input: "hello world", chunkSize: 5, chunkOverlap: 2 })).toEqual([
57
+ "hello",
58
+ "lo wo",
59
+ "world",
60
+ ])
61
+ })
62
+
63
+ test("stringSmartSplit respects max length", () => {
64
+ const parts = stringSmartSplit("a\nb\nc", 2)
65
+ expect(parts.join("\n")).toContain("a")
66
+ expect(parts.join("\n")).toContain("b")
67
+ expect(parts.join("\n")).toContain("c")
68
+ expect(parts.every(part => part.length <= 2)).toBe(true)
69
+ })
70
+
71
+ test("stringTruncate adds ellipsis", () => {
72
+ expect(stringTruncate("hello world", 5)).toBe("hello...")
73
+ expect(stringTruncate("hi", 5)).toBe("hi")
74
+ })
@@ -0,0 +1,72 @@
1
+ import { expect, test } from "vitest"
2
+
3
+ import {
4
+ symbolCreateGlobal,
5
+ symbolCreateLocal,
6
+ symbolGetDescription,
7
+ symbolGetKey,
8
+ symbolHasDescription,
9
+ symbolIsAnonymous,
10
+ symbolIsGlobal,
11
+ symbolIsLocal,
12
+ symbolIsWellKnown,
13
+ symbolToString,
14
+ } from "#Source/basic/index.ts"
15
+
16
+ test("symbolCreateLocal creates unique symbols", () => {
17
+ const first = symbolCreateLocal("demo")
18
+ const second = symbolCreateLocal("demo")
19
+ expect(typeof first).toBe("symbol")
20
+ expect(first === second).toBe(false)
21
+ })
22
+
23
+ test("symbolCreateGlobal returns registry symbols", () => {
24
+ const first = symbolCreateGlobal("demo")
25
+ const second = symbolCreateGlobal("demo")
26
+ expect(typeof first).toBe("symbol")
27
+ expect(first === second).toBe(true)
28
+ expect(first === Symbol.for("demo")).toBe(true)
29
+ })
30
+
31
+ test("symbolGetKey returns global key", () => {
32
+ expect(symbolGetKey(Symbol.for("demo"))).toBe("demo")
33
+ expect(symbolGetKey(Symbol("demo"))).toBeUndefined()
34
+ })
35
+
36
+ test("symbolIsGlobal checks registry membership", () => {
37
+ expect(symbolIsGlobal(Symbol.for("demo"))).toBe(true)
38
+ expect(symbolIsGlobal(Symbol("demo"))).toBe(false)
39
+ })
40
+
41
+ test("symbolIsLocal checks non-registry symbols", () => {
42
+ expect(symbolIsLocal(Symbol.for("demo"))).toBe(false)
43
+ expect(symbolIsLocal(Symbol("demo"))).toBe(true)
44
+ })
45
+
46
+ test("symbolHasDescription checks description presence", () => {
47
+ expect(symbolHasDescription(Symbol("demo"))).toBe(true)
48
+ // oxlint-disable-next-line symbol-description
49
+ expect(symbolHasDescription(Symbol())).toBe(false)
50
+ })
51
+
52
+ test("symbolGetDescription reads description", () => {
53
+ expect(symbolGetDescription(Symbol("demo"))).toBe("demo")
54
+ // oxlint-disable-next-line symbol-description
55
+ expect(symbolGetDescription(Symbol())).toBeUndefined()
56
+ })
57
+
58
+ test("symbolIsAnonymous checks empty description", () => {
59
+ expect(symbolIsAnonymous(Symbol("demo"))).toBe(false)
60
+ // oxlint-disable-next-line symbol-description
61
+ expect(symbolIsAnonymous(Symbol())).toBe(true)
62
+ })
63
+
64
+ test("symbolIsWellKnown detects well-known symbols", () => {
65
+ expect(symbolIsWellKnown(Symbol.iterator)).toBe(true)
66
+ expect(symbolIsWellKnown(Symbol("iterator"))).toBe(false)
67
+ })
68
+
69
+ test("symbolToString converts to string", () => {
70
+ expect(symbolToString(Symbol("demo"))).toBe("Symbol(demo)")
71
+ expect(symbolToString("demo")).toBeUndefined()
72
+ })
@@ -0,0 +1,78 @@
1
+ import { expect, test, vi } from "vitest"
2
+
3
+ import {
4
+ temporalFormatToRelativeTime,
5
+ temporalFormatToWechatRelativeTime,
6
+ temporalFormatToYYYYMMDD,
7
+ temporalFormatToYYYYMMDDhhmmss,
8
+ temporalFormatTohhmmss,
9
+ temporalHumanize,
10
+ temporalIsOutdated,
11
+ } from "#Source/basic/index.ts"
12
+
13
+ test("temporalIsOutdated returns expected values", () => {
14
+ const now = new Date(2_024, 0, 2, 0, 0, 0).getTime()
15
+ const nowSpy = vi.spyOn(Date, "now").mockReturnValue(now)
16
+
17
+ expect(temporalIsOutdated(new Date(now - 1_000))).toBe(true)
18
+ expect(temporalIsOutdated(new Date(now + 1_000))).toBe(false)
19
+ expect(temporalIsOutdated("not-a-date")).toBe(false)
20
+
21
+ nowSpy.mockRestore()
22
+ })
23
+
24
+ test("temporalFormatToYYYYMMDD formats dates", () => {
25
+ const timestamp = new Date(2_000, 0, 2, 3, 4, 5).getTime()
26
+
27
+ expect(temporalFormatToYYYYMMDD(timestamp)).toBe("2000-01-02")
28
+ expect(temporalFormatToYYYYMMDD(timestamp, "/")).toBe("2000/01/02")
29
+ })
30
+
31
+ test("temporalFormatTohhmmss formats times", () => {
32
+ const timestamp = new Date(2_000, 0, 2, 3, 4, 5).getTime()
33
+
34
+ expect(temporalFormatTohhmmss(timestamp)).toBe("03:04:05")
35
+ expect(temporalFormatTohhmmss(timestamp, "-")).toBe("03-04-05")
36
+ })
37
+
38
+ test("temporalFormatToYYYYMMDDhhmmss formats date and time", () => {
39
+ const timestamp = new Date(2_000, 0, 2, 3, 4, 5).getTime()
40
+
41
+ expect(temporalFormatToYYYYMMDDhhmmss(timestamp)).toBe("2000-01-02 03:04:05")
42
+ })
43
+
44
+ test("temporalFormatToRelativeTime returns expected labels", () => {
45
+ const now = new Date(2_024, 0, 2, 0, 0, 0).getTime()
46
+ const nowSpy = vi.spyOn(Date, "now").mockReturnValue(now)
47
+
48
+ expect(temporalFormatToRelativeTime(now - 30_000)).toBe("刚刚")
49
+ expect(temporalFormatToRelativeTime(now - 120_000)).toBe("2 分钟前")
50
+ expect(temporalFormatToRelativeTime(now - 3_600_000)).toBe("1 小时前")
51
+ expect(temporalFormatToRelativeTime(now - 90_000_000)).toBe("昨天")
52
+ expect(temporalFormatToRelativeTime(now - 259_200_000)).toBe("一周内")
53
+ expect(temporalFormatToRelativeTime(now - 691_200_000)).toBe("2023-12-25 00:00:00")
54
+
55
+ nowSpy.mockRestore()
56
+ })
57
+
58
+ test("temporalFormatToWechatRelativeTime formats WeChat-style labels", () => {
59
+ vi.useFakeTimers()
60
+ vi.setSystemTime(new Date(2_024, 0, 3, 12, 0, 0))
61
+
62
+ expect(temporalFormatToWechatRelativeTime({ timestamp: new Date(2_024, 0, 3, 9, 5, 0).getTime() })).toBe("09:05")
63
+ expect(temporalFormatToWechatRelativeTime({ timestamp: new Date(2_024, 0, 2, 9, 0, 0).getTime() })).toBe("昨天")
64
+ expect(temporalFormatToWechatRelativeTime({ timestamp: new Date(2_024, 0, 2, 9, 0, 0).getTime(), alwaysShowTime: true })).toBe("昨天 09:00")
65
+ expect(temporalFormatToWechatRelativeTime({ timestamp: new Date(2_024, 0, 1, 8, 0, 0).getTime() })).toBe("星期一")
66
+ expect(temporalFormatToWechatRelativeTime({ timestamp: new Date(2_023, 11, 24, 18, 30, 0).getTime() })).toBe("23/12/24")
67
+
68
+ vi.useRealTimers()
69
+ })
70
+
71
+ test("temporalHumanize returns expected labels", () => {
72
+ const nowSpy = vi.spyOn(Date, "now").mockReturnValue(3_600_000)
73
+
74
+ expect(temporalHumanize(3_600_000)).toBe("刚刚")
75
+ expect(temporalHumanize(0)).toBe("1 小时前")
76
+
77
+ nowSpy.mockRestore()
78
+ })
@@ -0,0 +1,40 @@
1
+ import { expect, test } from "vitest"
2
+
3
+ import {
4
+ assertBase64,
5
+ base64ToString,
6
+ isBase64,
7
+ stringToBase64,
8
+ } from "#Source/encoding/index.ts"
9
+
10
+ test("isBase64 validates Base64 input", () => {
11
+ expect(isBase64("aGVsbG8=")).toBe(true)
12
+ expect(isBase64("5L2g5aW9")).toBe(true)
13
+ expect(isBase64("8J+Ri/CfjI0=")).toBe(true)
14
+ expect(isBase64("aGVs\n bG8=")).toBe(true)
15
+
16
+ expect(isBase64("%%%")).toBe(false)
17
+ expect(isBase64("abc")).toBe(false)
18
+ })
19
+
20
+ test("assertBase64 throws on malformed input", () => {
21
+ expect(() => assertBase64("aGVsbG8=")).not.toThrow()
22
+ expect(() => assertBase64("aGVs\n bG8=")).not.toThrow()
23
+ expect(() => assertBase64("%%%")).toThrow(TypeError)
24
+ expect(() => assertBase64("abc")).toThrow(TypeError)
25
+ })
26
+
27
+ test("stringToBase64 converts UTF-8 text to Base64", () => {
28
+ expect(stringToBase64("hello")).toBe("aGVsbG8=")
29
+ expect(stringToBase64("你好")).toBe("5L2g5aW9")
30
+ expect(stringToBase64("👋🌍")).toBe("8J+Ri/CfjI0=")
31
+ })
32
+
33
+ test("base64ToString converts Base64 to UTF-8 text and validates malformed input", () => {
34
+ expect(base64ToString("aGVsbG8=")).toBe("hello")
35
+ expect(base64ToString("5L2g5aW9")).toBe("你好")
36
+ expect(base64ToString("8J+Ri/CfjI0=")).toBe("👋🌍")
37
+
38
+ expect(() => base64ToString("%%%")).toThrow(TypeError)
39
+ expect(() => base64ToString("abc")).toThrow(TypeError)
40
+ })
@@ -0,0 +1,37 @@
1
+ import { expect, test } from "vitest"
2
+
3
+ import { assertUuid, generateUuid, getUuidVersion, isUuid } from "#Source/random/index.ts"
4
+
5
+ test("isUuid validates UUID input", () => {
6
+ expect(isUuid("550e8400-e29b-41d4-a716-446655440000")).toBe(true)
7
+ expect(isUuid("550E8400-E29B-41D4-A716-446655440000")).toBe(true)
8
+ expect(isUuid("123e4567-e89b-12d3-a456-426614174000")).toBe(true)
9
+
10
+ expect(isUuid("not-a-uuid")).toBe(false)
11
+ expect(isUuid("550e8400e29b41d4a716446655440000")).toBe(false)
12
+ expect(isUuid("550e8400-e29b-91d4-a716-446655440000")).toBe(false)
13
+ expect(isUuid("550e8400-e29b-41d4-c716-446655440000")).toBe(false)
14
+ })
15
+
16
+ test("assertUuid throws on malformed input", () => {
17
+ expect(() => assertUuid("550e8400-e29b-41d4-a716-446655440000")).not.toThrow()
18
+ expect(() => assertUuid("not-a-uuid")).toThrow(TypeError)
19
+ expect(() => assertUuid("550e8400e29b41d4a716446655440000")).toThrow(TypeError)
20
+ })
21
+
22
+ test("getUuidVersion returns UUID version and throws on malformed input", () => {
23
+ expect(getUuidVersion("550e8400-e29b-41d4-a716-446655440000")).toBe(4)
24
+ expect(getUuidVersion("123e4567-e89b-12d3-a456-426614174000")).toBe(1)
25
+
26
+ expect(() => getUuidVersion("not-a-uuid")).toThrow(TypeError)
27
+ })
28
+
29
+ test("generateUuid returns RFC 4122 version-4 UUID format", () => {
30
+ const UUID_V4_REGEXP = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
31
+ const value1 = generateUuid()
32
+ const value2 = generateUuid()
33
+
34
+ expect(value1).toMatch(UUID_V4_REGEXP)
35
+ expect(value2).toMatch(UUID_V4_REGEXP)
36
+ expect(value1).not.toBe(value2)
37
+ })
package/dist/index.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export * as Reactor from "./reactor/index.ts";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAA"}
@@ -1,3 +0,0 @@
1
- export * from "./reactor-core/index.ts";
2
- export * from "./reactor-operators/index.ts";
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reactor/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,cAAc,8BAA8B,CAAA"}
@@ -1,99 +0,0 @@
1
- export declare const FLAG_DICT: {
2
- /**
3
- * 当前节点没有任何特性。
4
- */
5
- readonly None: 0;
6
- /**
7
- * 当前节点的值是可变的。值的变化可以通过此节点继续传递。
8
- */
9
- readonly Mutable: 1;
10
- /**
11
- * 当前节点的值可能发生了变化,待确定。
12
- */
13
- readonly Pending: 2;
14
- /**
15
- * 当前节点的值发生了变化。
16
- */
17
- readonly Dirty: 4;
18
- /**
19
- * 当前节点正在进行观察。当上游节点的值发生变化时应该通知当前节点。
20
- */
21
- readonly Watching: 8;
22
- /**
23
- * 当前节点正在进行依赖收集。
24
- *
25
- * 目前只考虑到以下用途:
26
- *
27
- * 1. 用于防止在某节点依赖收集过程中依赖发生变化导致该节点重复运行。
28
- * ```
29
- * const count = signal(0);
30
- * effect(() => {
31
- * count(count() + 1);
32
- * })
33
- * ```
34
- */
35
- readonly Tracking: 16;
36
- /**
37
- * 当前节点正在进行依赖收集,且正在尝试复用现存连接。
38
- */
39
- readonly TrackingReusing: 32;
40
- };
41
- export declare const hasMutable: (flags: number) => boolean;
42
- export declare const setMutable: (flags?: number | undefined) => number;
43
- export declare const unsetMutable: (flags: number) => number;
44
- export declare const toggleMutable: (flags: number) => number;
45
- export declare const hasDirty: (flags: number) => boolean;
46
- export declare const setDirty: (flags?: number | undefined) => number;
47
- export declare const unsetDirty: (flags: number) => number;
48
- export declare const toggleDirty: (flags: number) => number;
49
- export declare const hasPending: (flags: number) => boolean;
50
- export declare const setPending: (flags?: number | undefined) => number;
51
- export declare const unsetPending: (flags: number) => number;
52
- export declare const togglePending: (flags: number) => number;
53
- export declare const hasWatching: (flags: number) => boolean;
54
- export declare const setWatching: (flags?: number | undefined) => number;
55
- export declare const unsetWatching: (flags: number) => number;
56
- export declare const toggleWatching: (flags: number) => number;
57
- export declare const hasTracking: (flags: number) => boolean;
58
- export declare const setTracking: (flags?: number | undefined) => number;
59
- export declare const unsetTracking: (flags: number) => number;
60
- export declare const toggleTracking: (flags: number) => number;
61
- export declare const hasTrackingReusing: (flags: number) => boolean;
62
- export declare const setTrackingReusing: (flags?: number | undefined) => number;
63
- export declare const unsetTrackingReusing: (flags: number) => number;
64
- export declare const toggleTrackingReusing: (flags: number) => number;
65
- export declare class Flags {
66
- private flags;
67
- constructor();
68
- static clone(flags: Flags): Flags;
69
- get(): number;
70
- set(flags: number): this;
71
- clear(): this;
72
- hasMutable(): boolean;
73
- setMutable(): this;
74
- unsetMutable(): this;
75
- toggleMutable(): this;
76
- hasDirty(): boolean;
77
- setDirty(): this;
78
- unsetDirty(): this;
79
- toggleDirty(): this;
80
- hasPending(): boolean;
81
- setPending(): this;
82
- unsetPending(): this;
83
- togglePending(): this;
84
- hasWatching(): boolean;
85
- setWatching(): this;
86
- unsetWatching(): this;
87
- toggleWatching(): this;
88
- hasTracking(): boolean;
89
- setTracking(): this;
90
- unsetTracking(): this;
91
- toggleTracking(): this;
92
- hasTrackingReusing(): boolean;
93
- setTrackingReusing(): this;
94
- unsetTrackingReusing(): this;
95
- toggleTrackingReusing(): this;
96
- toString(): string;
97
- }
98
- export declare const flags: (flags?: number | undefined) => Flags;
99
- //# sourceMappingURL=flags.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"flags.d.ts","sourceRoot":"","sources":["../../../src/reactor/reactor-core/flags.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS;IACpB;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;IAGH;;;;;;;;;;;;OAYG;;IAEH;;OAEG;;CAEK,CAAC;AAEX,eAAO,MAAM,UAAU,4BAEtB,CAAA;AACD,eAAO,MAAM,UAAU,wCAEtB,CAAA;AACD,eAAO,MAAM,YAAY,2BAExB,CAAA;AACD,eAAO,MAAM,aAAa,2BAEzB,CAAA;AACD,eAAO,MAAM,QAAQ,4BAEpB,CAAA;AACD,eAAO,MAAM,QAAQ,wCAEpB,CAAA;AACD,eAAO,MAAM,UAAU,2BAEtB,CAAA;AACD,eAAO,MAAM,WAAW,2BAEvB,CAAA;AACD,eAAO,MAAM,UAAU,4BAEtB,CAAA;AACD,eAAO,MAAM,UAAU,wCAEtB,CAAA;AACD,eAAO,MAAM,YAAY,2BAExB,CAAA;AACD,eAAO,MAAM,aAAa,2BAEzB,CAAA;AACD,eAAO,MAAM,WAAW,4BAEvB,CAAA;AACD,eAAO,MAAM,WAAW,wCAEvB,CAAA;AACD,eAAO,MAAM,aAAa,2BAEzB,CAAA;AACD,eAAO,MAAM,cAAc,2BAE1B,CAAA;AACD,eAAO,MAAM,WAAW,4BAEvB,CAAA;AACD,eAAO,MAAM,WAAW,wCAEvB,CAAA;AACD,eAAO,MAAM,aAAa,2BAEzB,CAAA;AACD,eAAO,MAAM,cAAc,2BAE1B,CAAA;AACD,eAAO,MAAM,kBAAkB,4BAE9B,CAAA;AACD,eAAO,MAAM,kBAAkB,wCAE9B,CAAA;AACD,eAAO,MAAM,oBAAoB,2BAEhC,CAAA;AACD,eAAO,MAAM,qBAAqB,2BAEjC,CAAA;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAS;IAEtB,cAEC;IAED,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAIhC;IAED,GAAG,IAAI,MAAM,CAEZ;IAED,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGvB;IAED,KAAK,IAAI,IAAI,CAGZ;IAED,UAAU,IAAI,OAAO,CAEpB;IACD,UAAU,IAAI,IAAI,CAGjB;IACD,YAAY,IAAI,IAAI,CAGnB;IACD,aAAa,IAAI,IAAI,CAGpB;IAED,QAAQ,IAAI,OAAO,CAElB;IACD,QAAQ,IAAI,IAAI,CAGf;IACD,UAAU,IAAI,IAAI,CAGjB;IACD,WAAW,IAAI,IAAI,CAGlB;IAED,UAAU,IAAI,OAAO,CAEpB;IACD,UAAU,IAAI,IAAI,CAGjB;IACD,YAAY,IAAI,IAAI,CAGnB;IACD,aAAa,IAAI,IAAI,CAGpB;IAED,WAAW,IAAI,OAAO,CAErB;IACD,WAAW,IAAI,IAAI,CAGlB;IACD,aAAa,IAAI,IAAI,CAGpB;IACD,cAAc,IAAI,IAAI,CAGrB;IAED,WAAW,IAAI,OAAO,CAErB;IACD,WAAW,IAAI,IAAI,CAGlB;IACD,aAAa,IAAI,IAAI,CAGpB;IACD,cAAc,IAAI,IAAI,CAGrB;IAED,kBAAkB,IAAI,OAAO,CAE5B;IACD,kBAAkB,IAAI,IAAI,CAGzB;IACD,oBAAoB,IAAI,IAAI,CAG3B;IACD,qBAAqB,IAAI,IAAI,CAG5B;IAED,QAAQ,IAAI,MAAM,CA2BjB;CACF;AAED,eAAO,MAAM,KAAK,uCAMjB,CAAA"}
@@ -1,4 +0,0 @@
1
- export * from "./flags.ts";
2
- export * from "./reactive-system.ts";
3
- export * from "./primitive.ts";
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/reactor/reactor-core/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AACpC,cAAc,gBAAgB,CAAA"}