signalium 0.3.8 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +21 -0
  3. package/build/react.js +19 -0
  4. package/build/transform.js +19 -0
  5. package/dist/cjs/config.d.ts +8 -3
  6. package/dist/cjs/config.d.ts.map +1 -1
  7. package/dist/cjs/config.js +14 -8
  8. package/dist/cjs/config.js.map +1 -1
  9. package/dist/cjs/debug.d.ts +2 -2
  10. package/dist/cjs/debug.d.ts.map +1 -1
  11. package/dist/cjs/debug.js +3 -3
  12. package/dist/cjs/debug.js.map +1 -1
  13. package/dist/cjs/hooks.d.ts +14 -42
  14. package/dist/cjs/hooks.d.ts.map +1 -1
  15. package/dist/cjs/hooks.js +19 -240
  16. package/dist/cjs/hooks.js.map +1 -1
  17. package/dist/cjs/index.d.ts +5 -3
  18. package/dist/cjs/index.d.ts.map +1 -1
  19. package/dist/cjs/index.js +18 -18
  20. package/dist/cjs/index.js.map +1 -1
  21. package/dist/cjs/internals/async.d.ts +52 -0
  22. package/dist/cjs/internals/async.d.ts.map +1 -0
  23. package/dist/cjs/internals/async.js +394 -0
  24. package/dist/cjs/internals/async.js.map +1 -0
  25. package/dist/cjs/internals/connect.d.ts +4 -0
  26. package/dist/cjs/internals/connect.d.ts.map +1 -0
  27. package/dist/cjs/internals/connect.js +37 -0
  28. package/dist/cjs/internals/connect.js.map +1 -0
  29. package/dist/cjs/internals/consumer.d.ts +6 -0
  30. package/dist/cjs/internals/consumer.d.ts.map +1 -0
  31. package/dist/cjs/internals/consumer.js +13 -0
  32. package/dist/cjs/internals/consumer.js.map +1 -0
  33. package/dist/cjs/internals/contexts.d.ts +33 -0
  34. package/dist/cjs/internals/contexts.d.ts.map +1 -0
  35. package/dist/cjs/internals/contexts.js +103 -0
  36. package/dist/cjs/internals/contexts.js.map +1 -0
  37. package/dist/cjs/internals/derived.d.ts +66 -0
  38. package/dist/cjs/internals/derived.d.ts.map +1 -0
  39. package/dist/cjs/internals/derived.js +128 -0
  40. package/dist/cjs/internals/derived.js.map +1 -0
  41. package/dist/cjs/internals/dirty.d.ts +5 -0
  42. package/dist/cjs/internals/dirty.d.ts.map +1 -0
  43. package/dist/cjs/internals/dirty.js +79 -0
  44. package/dist/cjs/internals/dirty.js.map +1 -0
  45. package/dist/cjs/internals/edge.d.ts +32 -0
  46. package/dist/cjs/internals/edge.d.ts.map +1 -0
  47. package/dist/cjs/internals/edge.js +59 -0
  48. package/dist/cjs/internals/edge.js.map +1 -0
  49. package/dist/cjs/internals/get.d.ts +10 -0
  50. package/dist/cjs/internals/get.d.ts.map +1 -0
  51. package/dist/cjs/internals/get.js +255 -0
  52. package/dist/cjs/internals/get.js.map +1 -0
  53. package/dist/cjs/internals/scheduling.d.ts +12 -0
  54. package/dist/cjs/internals/scheduling.d.ts.map +1 -0
  55. package/dist/cjs/internals/scheduling.js +117 -0
  56. package/dist/cjs/internals/scheduling.js.map +1 -0
  57. package/dist/cjs/internals/state.d.ts +18 -0
  58. package/dist/cjs/internals/state.d.ts.map +1 -0
  59. package/dist/cjs/internals/state.js +88 -0
  60. package/dist/cjs/internals/state.js.map +1 -0
  61. package/dist/cjs/internals/utils/debug-name.d.ts +2 -0
  62. package/dist/cjs/internals/utils/debug-name.d.ts.map +1 -0
  63. package/dist/cjs/internals/utils/debug-name.js +14 -0
  64. package/dist/cjs/internals/utils/debug-name.js.map +1 -0
  65. package/dist/cjs/internals/utils/equals.d.ts +3 -0
  66. package/dist/cjs/internals/utils/equals.d.ts.map +1 -0
  67. package/dist/cjs/internals/utils/equals.js +13 -0
  68. package/dist/cjs/internals/utils/equals.js.map +1 -0
  69. package/dist/cjs/internals/utils/hash.d.ts +7 -0
  70. package/dist/cjs/internals/utils/hash.d.ts.map +1 -0
  71. package/dist/cjs/internals/utils/hash.js +181 -0
  72. package/dist/cjs/internals/utils/hash.js.map +1 -0
  73. package/dist/cjs/internals/utils/stringify.d.ts +3 -0
  74. package/dist/cjs/internals/utils/stringify.d.ts.map +1 -0
  75. package/dist/cjs/{utils.js → internals/utils/stringify.js} +5 -27
  76. package/dist/cjs/internals/utils/stringify.js.map +1 -0
  77. package/dist/cjs/internals/utils/type-utils.d.ts +6 -0
  78. package/dist/cjs/internals/utils/type-utils.d.ts.map +1 -0
  79. package/dist/cjs/internals/utils/type-utils.js +22 -0
  80. package/dist/cjs/internals/utils/type-utils.js.map +1 -0
  81. package/dist/cjs/react/context.d.ts +1 -1
  82. package/dist/cjs/react/context.d.ts.map +1 -1
  83. package/dist/cjs/react/provider.d.ts +4 -3
  84. package/dist/cjs/react/provider.d.ts.map +1 -1
  85. package/dist/cjs/react/provider.js +7 -3
  86. package/dist/cjs/react/provider.js.map +1 -1
  87. package/dist/cjs/react/setup.d.ts.map +1 -1
  88. package/dist/cjs/react/setup.js +2 -1
  89. package/dist/cjs/react/setup.js.map +1 -1
  90. package/dist/cjs/react/signal-value.d.ts +5 -1
  91. package/dist/cjs/react/signal-value.d.ts.map +1 -1
  92. package/dist/cjs/react/signal-value.js +35 -45
  93. package/dist/cjs/react/signal-value.js.map +1 -1
  94. package/dist/cjs/trace.d.ts +32 -28
  95. package/dist/cjs/trace.d.ts.map +1 -1
  96. package/dist/cjs/trace.js +14 -16
  97. package/dist/cjs/trace.js.map +1 -1
  98. package/dist/cjs/transform.d.ts +6 -0
  99. package/dist/cjs/transform.d.ts.map +1 -0
  100. package/dist/cjs/transform.js +92 -0
  101. package/dist/cjs/transform.js.map +1 -0
  102. package/dist/cjs/types.d.ts +32 -40
  103. package/dist/cjs/types.d.ts.map +1 -1
  104. package/dist/esm/config.d.ts +8 -3
  105. package/dist/esm/config.d.ts.map +1 -1
  106. package/dist/esm/config.js +12 -7
  107. package/dist/esm/config.js.map +1 -1
  108. package/dist/esm/debug.d.ts +2 -2
  109. package/dist/esm/debug.d.ts.map +1 -1
  110. package/dist/esm/debug.js +2 -2
  111. package/dist/esm/debug.js.map +1 -1
  112. package/dist/esm/hooks.d.ts +14 -42
  113. package/dist/esm/hooks.d.ts.map +1 -1
  114. package/dist/esm/hooks.js +17 -226
  115. package/dist/esm/hooks.js.map +1 -1
  116. package/dist/esm/index.d.ts +5 -3
  117. package/dist/esm/index.d.ts.map +1 -1
  118. package/dist/esm/index.js +5 -3
  119. package/dist/esm/index.js.map +1 -1
  120. package/dist/esm/internals/async.d.ts +52 -0
  121. package/dist/esm/internals/async.d.ts.map +1 -0
  122. package/dist/esm/internals/async.js +387 -0
  123. package/dist/esm/internals/async.js.map +1 -0
  124. package/dist/esm/internals/connect.d.ts +4 -0
  125. package/dist/esm/internals/connect.d.ts.map +1 -0
  126. package/dist/esm/internals/connect.js +33 -0
  127. package/dist/esm/internals/connect.js.map +1 -0
  128. package/dist/esm/internals/consumer.d.ts +6 -0
  129. package/dist/esm/internals/consumer.d.ts.map +1 -0
  130. package/dist/esm/internals/consumer.js +9 -0
  131. package/dist/esm/internals/consumer.js.map +1 -0
  132. package/dist/esm/internals/contexts.d.ts +33 -0
  133. package/dist/esm/internals/contexts.d.ts.map +1 -0
  134. package/dist/esm/internals/contexts.js +92 -0
  135. package/dist/esm/internals/contexts.js.map +1 -0
  136. package/dist/esm/internals/derived.d.ts +66 -0
  137. package/dist/esm/internals/derived.d.ts.map +1 -0
  138. package/dist/esm/internals/derived.js +118 -0
  139. package/dist/esm/internals/derived.js.map +1 -0
  140. package/dist/esm/internals/dirty.d.ts +5 -0
  141. package/dist/esm/internals/dirty.d.ts.map +1 -0
  142. package/dist/esm/internals/dirty.js +75 -0
  143. package/dist/esm/internals/dirty.js.map +1 -0
  144. package/dist/esm/internals/edge.d.ts +32 -0
  145. package/dist/esm/internals/edge.d.ts.map +1 -0
  146. package/dist/esm/internals/edge.js +54 -0
  147. package/dist/esm/internals/edge.js.map +1 -0
  148. package/dist/esm/internals/get.d.ts +10 -0
  149. package/dist/esm/internals/get.d.ts.map +1 -0
  150. package/dist/esm/internals/get.js +247 -0
  151. package/dist/esm/internals/get.js.map +1 -0
  152. package/dist/esm/internals/scheduling.d.ts +12 -0
  153. package/dist/esm/internals/scheduling.d.ts.map +1 -0
  154. package/dist/esm/internals/scheduling.js +106 -0
  155. package/dist/esm/internals/scheduling.js.map +1 -0
  156. package/dist/esm/internals/state.d.ts +18 -0
  157. package/dist/esm/internals/state.d.ts.map +1 -0
  158. package/dist/esm/internals/state.js +82 -0
  159. package/dist/esm/internals/state.js.map +1 -0
  160. package/dist/esm/internals/utils/debug-name.d.ts +2 -0
  161. package/dist/esm/internals/utils/debug-name.d.ts.map +1 -0
  162. package/dist/esm/internals/utils/debug-name.js +11 -0
  163. package/dist/esm/internals/utils/debug-name.js.map +1 -0
  164. package/dist/esm/internals/utils/equals.d.ts +3 -0
  165. package/dist/esm/internals/utils/equals.d.ts.map +1 -0
  166. package/dist/esm/internals/utils/equals.js +9 -0
  167. package/dist/esm/internals/utils/equals.js.map +1 -0
  168. package/dist/esm/internals/utils/hash.d.ts +7 -0
  169. package/dist/esm/internals/utils/hash.d.ts.map +1 -0
  170. package/dist/esm/internals/utils/hash.js +174 -0
  171. package/dist/esm/internals/utils/hash.js.map +1 -0
  172. package/dist/esm/internals/utils/stringify.d.ts +3 -0
  173. package/dist/esm/internals/utils/stringify.d.ts.map +1 -0
  174. package/dist/esm/{utils.js → internals/utils/stringify.js} +4 -25
  175. package/dist/esm/internals/utils/stringify.js.map +1 -0
  176. package/dist/esm/internals/utils/type-utils.d.ts +6 -0
  177. package/dist/esm/internals/utils/type-utils.d.ts.map +1 -0
  178. package/dist/esm/internals/utils/type-utils.js +15 -0
  179. package/dist/esm/internals/utils/type-utils.js.map +1 -0
  180. package/dist/esm/react/context.d.ts +1 -1
  181. package/dist/esm/react/context.d.ts.map +1 -1
  182. package/dist/esm/react/provider.d.ts +4 -3
  183. package/dist/esm/react/provider.d.ts.map +1 -1
  184. package/dist/esm/react/provider.js +6 -2
  185. package/dist/esm/react/provider.js.map +1 -1
  186. package/dist/esm/react/setup.d.ts.map +1 -1
  187. package/dist/esm/react/setup.js +3 -2
  188. package/dist/esm/react/setup.js.map +1 -1
  189. package/dist/esm/react/signal-value.d.ts +5 -1
  190. package/dist/esm/react/signal-value.d.ts.map +1 -1
  191. package/dist/esm/react/signal-value.js +34 -45
  192. package/dist/esm/react/signal-value.js.map +1 -1
  193. package/dist/esm/trace.d.ts +32 -28
  194. package/dist/esm/trace.d.ts.map +1 -1
  195. package/dist/esm/trace.js +13 -15
  196. package/dist/esm/trace.js.map +1 -1
  197. package/dist/esm/transform.d.ts +6 -0
  198. package/dist/esm/transform.d.ts.map +1 -0
  199. package/dist/esm/transform.js +89 -0
  200. package/dist/esm/transform.js.map +1 -0
  201. package/dist/esm/types.d.ts +32 -40
  202. package/dist/esm/types.d.ts.map +1 -1
  203. package/package.json +23 -4
  204. package/src/__tests__/__snapshots__/context.test.ts.snap +2101 -0
  205. package/src/__tests__/__snapshots__/nesting.test.ts.snap +16201 -0
  206. package/src/__tests__/__snapshots__/params-and-state.test.ts.snap +1879 -0
  207. package/src/__tests__/async-task.test.ts +327 -0
  208. package/src/__tests__/context.test.ts +517 -0
  209. package/src/__tests__/nesting.test.ts +298 -0
  210. package/src/__tests__/params-and-state.test.ts +230 -0
  211. package/src/__tests__/reactive-async.test.ts +548 -0
  212. package/src/__tests__/reactive-sync.test.ts +130 -0
  213. package/src/__tests__/subscription.test.ts +510 -0
  214. package/src/__tests__/utils/async.ts +1 -1
  215. package/src/__tests__/utils/instrumented-hooks.ts +229 -124
  216. package/src/__tests__/utils/permute.ts +25 -14
  217. package/src/config.ts +19 -9
  218. package/src/debug.ts +2 -2
  219. package/src/hooks.ts +46 -380
  220. package/src/index.ts +7 -24
  221. package/src/internals/async.ts +558 -0
  222. package/src/internals/connect.ts +41 -0
  223. package/src/internals/consumer.ts +13 -0
  224. package/src/internals/contexts.ts +133 -0
  225. package/src/internals/derived.ts +208 -0
  226. package/src/internals/dirty.ts +91 -0
  227. package/src/internals/edge.ts +109 -0
  228. package/src/internals/get.ts +298 -0
  229. package/src/internals/scheduling.ts +140 -0
  230. package/src/internals/state.ts +111 -0
  231. package/src/internals/utils/debug-name.ts +14 -0
  232. package/src/internals/utils/equals.ts +12 -0
  233. package/src/internals/utils/hash.ts +221 -0
  234. package/src/{utils.ts → internals/utils/stringify.ts} +3 -29
  235. package/src/internals/utils/type-utils.ts +19 -0
  236. package/src/react/__tests__/async.test.tsx +704 -0
  237. package/src/react/__tests__/basic.test.tsx +95 -0
  238. package/src/react/__tests__/contexts.test.tsx +99 -0
  239. package/src/react/__tests__/subscriptions.test.tsx +49 -0
  240. package/src/react/__tests__/utils.tsx +40 -0
  241. package/src/react/context.ts +1 -1
  242. package/src/react/provider.tsx +12 -4
  243. package/src/react/setup.ts +3 -2
  244. package/src/react/signal-value.ts +47 -67
  245. package/src/trace.ts +43 -38
  246. package/src/transform.ts +113 -0
  247. package/src/types.ts +56 -46
  248. package/transform.js +19 -0
  249. package/vitest.workspace.ts +38 -2
  250. package/dist/cjs/scheduling.d.ts +0 -11
  251. package/dist/cjs/scheduling.d.ts.map +0 -1
  252. package/dist/cjs/scheduling.js +0 -108
  253. package/dist/cjs/scheduling.js.map +0 -1
  254. package/dist/cjs/signals.d.ts +0 -73
  255. package/dist/cjs/signals.d.ts.map +0 -1
  256. package/dist/cjs/signals.js +0 -632
  257. package/dist/cjs/signals.js.map +0 -1
  258. package/dist/cjs/utils.d.ts +0 -4
  259. package/dist/cjs/utils.d.ts.map +0 -1
  260. package/dist/cjs/utils.js.map +0 -1
  261. package/dist/esm/scheduling.d.ts +0 -11
  262. package/dist/esm/scheduling.d.ts.map +0 -1
  263. package/dist/esm/scheduling.js +0 -97
  264. package/dist/esm/scheduling.js.map +0 -1
  265. package/dist/esm/signals.d.ts +0 -73
  266. package/dist/esm/signals.d.ts.map +0 -1
  267. package/dist/esm/signals.js +0 -614
  268. package/dist/esm/signals.js.map +0 -1
  269. package/dist/esm/utils.d.ts +0 -4
  270. package/dist/esm/utils.d.ts.map +0 -1
  271. package/dist/esm/utils.js.map +0 -1
  272. package/src/__tests__/hooks/async-computed.test.ts +0 -190
  273. package/src/__tests__/hooks/async-task.test.ts +0 -334
  274. package/src/__tests__/hooks/computed.test.ts +0 -126
  275. package/src/__tests__/hooks/context.test.ts +0 -527
  276. package/src/__tests__/hooks/nesting.test.ts +0 -303
  277. package/src/__tests__/hooks/params-and-state.test.ts +0 -168
  278. package/src/__tests__/hooks/subscription.test.ts +0 -97
  279. package/src/__tests__/signals/async.test.ts +0 -416
  280. package/src/__tests__/signals/basic.test.ts +0 -399
  281. package/src/__tests__/signals/subscription.test.ts +0 -632
  282. package/src/__tests__/signals/watcher.test.ts +0 -253
  283. package/src/__tests__/utils/builders.ts +0 -22
  284. package/src/__tests__/utils/instrumented-signals.ts +0 -291
  285. package/src/react/__tests__/react.test.tsx +0 -227
  286. package/src/scheduling.ts +0 -130
  287. package/src/signals.ts +0 -824
@@ -0,0 +1,221 @@
1
+ const { log, floor, imul, abs } = Math;
2
+
3
+ function hashStr(key: string, seed = 0) {
4
+ let h = seed ^ key.length;
5
+ const c1 = 0xcc9e2d51;
6
+ const c2 = 0x1b873593;
7
+ let i = 0;
8
+ while (i + 4 <= key.length) {
9
+ let k =
10
+ (key.charCodeAt(i) & 0xff) |
11
+ ((key.charCodeAt(i + 1) & 0xff) << 8) |
12
+ ((key.charCodeAt(i + 2) & 0xff) << 16) |
13
+ ((key.charCodeAt(i + 3) & 0xff) << 24);
14
+ k = imul(k, c1);
15
+ k = (k << 15) | (k >>> 17);
16
+ k = imul(k, c2);
17
+ h ^= k;
18
+ h = (h << 13) | (h >>> 19);
19
+ h = imul(h, 5) + 0xe6546b64;
20
+ i += 4;
21
+ }
22
+ let k = 0;
23
+ switch (key.length & 3) {
24
+ case 3:
25
+ k ^= (key.charCodeAt(i + 2) & 0xff) << 16;
26
+ // eslint-disable-next-line no-fallthrough
27
+ case 2:
28
+ k ^= (key.charCodeAt(i + 1) & 0xff) << 8;
29
+ // eslint-disable-next-line no-fallthrough
30
+ case 1:
31
+ k ^= key.charCodeAt(i) & 0xff;
32
+ k = imul(k, c1);
33
+ k = (k << 15) | (k >>> 17);
34
+ k = imul(k, c2);
35
+ h ^= k;
36
+ }
37
+ h ^= key.length;
38
+ h ^= h >>> 16;
39
+ h = imul(h, 0x85ebca6b);
40
+ h ^= h >>> 13;
41
+ h = imul(h, 0xc2b2ae35);
42
+ h ^= h >>> 16;
43
+ return h >>> 0; // Convert to unsigned 32-bit integer
44
+ }
45
+
46
+ function hashNumber(num: number, seed = 0) {
47
+ // Handle negative numbers by taking absolute value
48
+ num = abs(num);
49
+
50
+ let h = seed;
51
+ const c1 = 0xcc9e2d51;
52
+ const c2 = 0x1b873593;
53
+
54
+ // Process 4 bytes at a time
55
+ while (num >= 0xffffffff) {
56
+ // Extract the lowest 32 bits
57
+ let k = num & 0xffffffff;
58
+ num = floor(num / 0x100000000);
59
+
60
+ k = imul(k, c1);
61
+ k = (k << 15) | (k >>> 17);
62
+ k = imul(k, c2);
63
+
64
+ h ^= k;
65
+ h = (h << 13) | (h >>> 19);
66
+ h = imul(h, 5) + 0xe6546b64;
67
+ }
68
+
69
+ // Process the remaining bytes (up to 4 bytes)
70
+ if (num > 0) {
71
+ let k = num & 0xffffffff;
72
+ k = imul(k, c1);
73
+ k = (k << 15) | (k >>> 17);
74
+ k = imul(k, c2);
75
+ h ^= k;
76
+ }
77
+
78
+ // Get the number of bytes in the original number
79
+ const numBytes = num === 0 ? 1 : floor(log(num) / log(256)) + 1;
80
+
81
+ h ^= numBytes;
82
+ h ^= h >>> 16;
83
+ h = imul(h, 0x85ebca6b);
84
+ h ^= h >>> 13;
85
+ h = imul(h, 0xc2b2ae35);
86
+ h ^= h >>> 16;
87
+
88
+ return h >>> 0; // Convert to unsigned 32-bit integer
89
+ }
90
+
91
+ function hashArray(arr: unknown[]) {
92
+ let h = HashType.ARRAY;
93
+ const c1 = 0xcc9e2d51;
94
+ const c2 = 0x1b873593;
95
+
96
+ // Process 4 bytes at a time
97
+ for (const item of arr) {
98
+ // Extract the lowest 32 bits
99
+ let k = hashValue(item);
100
+
101
+ k = imul(k, c1);
102
+ k = (k << 15) | (k >>> 17);
103
+ k = imul(k, c2);
104
+
105
+ h ^= k;
106
+ h = (h << 13) | (h >>> 19);
107
+ h = imul(h, 5) + 0xe6546b64;
108
+ }
109
+
110
+ h ^= arr.length;
111
+ h ^= h >>> 16;
112
+ h = imul(h, 0x85ebca6b);
113
+ h ^= h >>> 13;
114
+ h = imul(h, 0xc2b2ae35);
115
+ h ^= h >>> 16;
116
+
117
+ return h >>> 0; // Convert to unsigned 32-bit integer
118
+ }
119
+
120
+ function hashObject(obj: object) {
121
+ let sum = OBJECT;
122
+ const keys = Object.keys(obj);
123
+
124
+ for (const key of keys) {
125
+ sum += hashValue(key) ^ hashValue((obj as any)[key]);
126
+ }
127
+
128
+ return sum >>> 0;
129
+ }
130
+
131
+ const enum HashType {
132
+ UNDEFINED = 0,
133
+ NULL = 1,
134
+ TRUE = 2,
135
+ FALSE = 3,
136
+ NUMBER = 4,
137
+ STRING = 5,
138
+ BIGINT = 6,
139
+ ARRAY = 7,
140
+ OBJECT = 8,
141
+ REFERENCE = 9,
142
+ SYMBOL = 10,
143
+ CYCLE = 11,
144
+ }
145
+
146
+ const UNDEFINED = hashStr('undefined', HashType.UNDEFINED);
147
+ const NULL = hashStr('null', HashType.NULL);
148
+ const TRUE = hashStr('true', HashType.TRUE);
149
+ const FALSE = hashStr('false', HashType.FALSE);
150
+ const ARRAY = hashStr('array', HashType.ARRAY);
151
+ const OBJECT = hashStr('object', HashType.OBJECT);
152
+
153
+ const getObjectProto = Object.getPrototypeOf;
154
+
155
+ const PROTO_TO_HASH = new Map<object, (obj: any) => number>([
156
+ [Object.prototype, hashObject],
157
+ [Array.prototype, hashArray],
158
+ ]);
159
+
160
+ export const registerCustomHash = <T>(ctor: { new (): T }, hashFn: (obj: T) => number) => {
161
+ PROTO_TO_HASH.set(ctor.prototype, hashFn);
162
+ };
163
+
164
+ export function hashValue(node: unknown, seen: unknown[] = []) {
165
+ switch (typeof node) {
166
+ case 'undefined':
167
+ return UNDEFINED;
168
+ case 'boolean':
169
+ return node ? TRUE : FALSE;
170
+ case 'number':
171
+ return hashStr(String(node), HashType.NUMBER);
172
+ case 'string':
173
+ return hashStr(node, HashType.STRING);
174
+ case 'bigint':
175
+ return hashStr(node.toString(), HashType.BIGINT);
176
+ case 'object': {
177
+ if (node === null) {
178
+ return NULL;
179
+ }
180
+
181
+ const index = seen.indexOf(node);
182
+ if (index !== -1) {
183
+ return hashStr(String(index), HashType.CYCLE);
184
+ }
185
+
186
+ const hashFn = PROTO_TO_HASH.get(getObjectProto(node));
187
+
188
+ if (hashFn) {
189
+ seen.push(node);
190
+ const hash = hashFn(node);
191
+ seen.pop();
192
+ return hash;
193
+ }
194
+
195
+ return getObjectHash(node);
196
+ }
197
+ case 'function':
198
+ return getObjectHash(node);
199
+ case 'symbol':
200
+ return hashStr(node.toString(), HashType.SYMBOL);
201
+ }
202
+ }
203
+
204
+ const objectToHashMap = new WeakMap<object, number>();
205
+ let nextHashMapId = 1;
206
+
207
+ export function getObjectHash(obj: object): number {
208
+ let id = objectToHashMap.get(obj);
209
+ if (id === undefined) {
210
+ id = hashNumber(nextHashMapId++, HashType.REFERENCE);
211
+ objectToHashMap.set(obj, id);
212
+ }
213
+ return id;
214
+ }
215
+
216
+ const EMPTY_ARRAY_HASH = hashArray([]);
217
+
218
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
219
+ export function hashReactiveFn(fn: Function, args: unknown[]) {
220
+ return getObjectHash(fn) ^ (args.length > 0 ? hashArray(args) : EMPTY_ARRAY_HASH);
221
+ }
@@ -1,5 +1,3 @@
1
- import { createComputedSignal, createSubscriptionSignal } from './signals.js';
2
-
3
1
  const objectToIdMap = new WeakMap<object, string>();
4
2
  let nextId = 1;
5
3
 
@@ -21,7 +19,7 @@ function isPlainArray(arr: unknown): arr is unknown[] {
21
19
  return Array.isArray(arr);
22
20
  }
23
21
 
24
- export function hashValue(value: unknown): string {
22
+ export function stringifyValue(value: unknown): string {
25
23
  if (value === null) return 'null';
26
24
  if (value === undefined) return 'undefined';
27
25
 
@@ -39,7 +37,7 @@ export function hashValue(value: unknown): string {
39
37
  return value.toISOString();
40
38
  }
41
39
  if (isPlainArray(value)) {
42
- return `[${value.map(hashValue).join(',')}]`;
40
+ return `[${value.map(stringifyValue).join(',')}]`;
43
41
  }
44
42
  if (isPOJO(value)) {
45
43
  const entries = [
@@ -47,7 +45,7 @@ export function hashValue(value: unknown): string {
47
45
  ...Object.getOwnPropertySymbols(value).map(sym => [sym, value[sym as keyof typeof value]]),
48
46
  ].sort(([a], [b]) => (String(a) < String(b) ? -1 : String(a) > String(b) ? 1 : 0));
49
47
 
50
- return `{ ${entries.map(([k, v]) => `${String(k)}: ${hashValue(v)}`).join(', ')} }`;
48
+ return `{ ${entries.map(([k, v]) => `${String(k)}: ${stringifyValue(v)}`).join(', ')} }`;
51
49
  }
52
50
  return getObjectId(value);
53
51
  }
@@ -57,27 +55,3 @@ export function hashValue(value: unknown): string {
57
55
  return getObjectId(value as object);
58
56
  }
59
57
  }
60
-
61
- let UNKNOWN_SUBSCRIPTION_ID = 0;
62
- let UNKNOWN_COMPUTED_ID = 0;
63
- let UNKNOWN_ASYNC_COMPUTED_ID = 0;
64
-
65
- const UNKNOWN_SIGNAL_NAMES = new Map<object, string>();
66
-
67
- export function getUnknownSignalFnName(fn: object, makeSignal: unknown) {
68
- let name = UNKNOWN_SIGNAL_NAMES.get(fn);
69
-
70
- if (name === undefined) {
71
- if (makeSignal === createSubscriptionSignal) {
72
- name = `unknownSubscription${UNKNOWN_SUBSCRIPTION_ID++}`;
73
- } else if (makeSignal === createComputedSignal) {
74
- name = `unknownComputed${UNKNOWN_COMPUTED_ID++}`;
75
- } else {
76
- name = `unknownAsyncComputed${UNKNOWN_ASYNC_COMPUTED_ID++}`;
77
- }
78
-
79
- UNKNOWN_SIGNAL_NAMES.set(fn, name);
80
- }
81
-
82
- return name;
83
- }
@@ -0,0 +1,19 @@
1
+ import { ReactivePromise } from '../async.js';
2
+
3
+ export const unreachable = (value: never) => {
4
+ throw new Error(`Unreachable code: ${value}`);
5
+ };
6
+
7
+ const GeneratorResultConstructor = (function* () {})().constructor;
8
+
9
+ export function isGeneratorResult(value: object): value is Generator {
10
+ return value.constructor === GeneratorResultConstructor;
11
+ }
12
+
13
+ export function isPromise(value: object): value is Promise<unknown> {
14
+ return value.constructor === Promise;
15
+ }
16
+
17
+ export function isReactivePromise(value: object): value is ReactivePromise<unknown> {
18
+ return value.constructor === ReactivePromise;
19
+ }