signalium 0.3.8 → 1.0.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 (287) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +15 -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 +50 -0
  22. package/dist/cjs/internals/async.d.ts.map +1 -0
  23. package/dist/cjs/internals/async.js +390 -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 +50 -0
  121. package/dist/esm/internals/async.d.ts.map +1 -0
  122. package/dist/esm/internals/async.js +383 -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 +556 -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
package/src/hooks.ts CHANGED
@@ -1,402 +1,68 @@
1
1
  import {
2
- createComputedSignal,
3
- createAsyncComputedSignal,
4
- createSubscriptionSignal,
5
- getCurrentConsumer,
6
- createWatcherSignal,
7
- ComputedSignal,
8
- createStateSignal,
9
- createAsyncTaskSignal,
10
- StateSignal,
11
- } from './signals.js';
12
- import {
13
- type AsyncTask,
14
- type AsyncReady,
15
- type AsyncResult,
16
- type Signal,
17
- type SignalOptions,
18
- type SignalOptionsWithInit,
19
- Watcher,
20
- WriteableSignal,
2
+ ReactiveTask,
3
+ ReactiveValue,
4
+ ReadyReactivePromise,
5
+ ReadyReactiveValue,
6
+ Signal,
7
+ SignalOptions,
21
8
  SignalSubscribe,
9
+ type SignalOptionsWithInit,
22
10
  } from './types.js';
23
- import { getObjectId, getUnknownSignalFnName, hashValue } from './utils.js';
24
- import { getFrameworkScope, useSignalValue } from './config.js';
25
- import WeakRef from './weakref.js';
26
-
27
- declare const CONTEXT_KEY: unique symbol;
28
-
29
- export type Context<T> = symbol & {
30
- [CONTEXT_KEY]: T;
31
- };
32
-
33
- const CONTEXT_DEFAULT_VALUES = new Map<Context<unknown>, unknown>();
34
- const CONTEXT_MASKS = new Map<Context<unknown>, bigint>();
35
-
36
- let CONTEXT_MASKS_COUNT = 0;
37
-
38
- const COMPUTED_CONTEXT_MASKS = new Map<object, bigint>();
39
- export const COMPUTED_OWNERS = new WeakMap<ComputedSignal<unknown>, SignalScope>();
40
-
41
- let CURRENT_MASK: bigint | null = null;
42
-
43
- export const state = <T>(value: T, opts?: Partial<SignalOptions<T, unknown[]>>): WriteableSignal<T> => {
44
- const signal = createStateSignal(value, opts) as StateSignal<T>;
45
-
46
- return {
47
- set(v: T) {
48
- signal.set(v);
49
- },
50
-
51
- get() {
52
- // eslint-disable-next-line react-hooks/rules-of-hooks
53
- return useSignalValue(signal._desc, () => signal.get());
54
- },
55
- };
56
- };
57
-
58
- export const createContext = <T>(initialValue: T, description?: string) => {
59
- const count = CONTEXT_MASKS_COUNT++;
60
- const key = Symbol(description ?? `context:${count}`) as Context<T>;
61
-
62
- CONTEXT_DEFAULT_VALUES.set(key, initialValue);
63
- CONTEXT_MASKS.set(key, BigInt(1) << BigInt(count));
64
-
65
- return key;
66
- };
67
-
68
- export type SignalStoreMap = {
69
- [K in Context<unknown>]: K extends Context<infer T> ? T : never;
70
- };
71
-
72
- export class SignalScope {
73
- constructor(
74
- contexts: SignalStoreMap,
75
- private parent?: SignalScope,
76
- ) {
77
- this.contexts = Object.create(parent?.contexts || null);
78
-
79
- for (const key of Object.getOwnPropertySymbols(contexts)) {
80
- this.contexts[key as Context<unknown>] = contexts[key as Context<unknown>];
81
- this.contextMask |= CONTEXT_MASKS.get(key as Context<unknown>)!;
82
- }
83
- }
84
-
85
- private contexts: SignalStoreMap;
86
- private children = new Map<string, SignalScope>();
87
- private contextMask = 0n;
88
- private signals = new Map<string, WeakRef<Signal<unknown>>>();
89
-
90
- getChild(contexts: SignalStoreMap) {
91
- const key = hashValue(contexts);
92
-
93
- let child = this.children.get(key);
94
-
95
- if (child === undefined) {
96
- child = new SignalScope(contexts, this);
97
- this.children.set(key, child);
98
- }
99
-
100
- return child;
101
- }
102
-
103
- getContext<T>(context: Context<T>): T | undefined {
104
- const value = this.contexts[context];
105
-
106
- if (CURRENT_MASK !== null) {
107
- CURRENT_MASK |= CONTEXT_MASKS.get(context)!;
108
- }
109
-
110
- return value as T | undefined;
111
- }
112
-
113
- private getSignal(key: string, computedMask: bigint): Signal<unknown> | undefined {
114
- return (this.contextMask & computedMask) === 0n && this.parent
115
- ? this.parent.getSignal(key, computedMask)
116
- : this.signals.get(key)?.deref();
117
- }
118
-
119
- private setSignal(key: string, signal: Signal<unknown>, mask: bigint, isPromoting: boolean) {
120
- if ((this.contextMask & mask) === 0n && this.parent) {
121
- this.parent.setSignal(key, signal, mask, isPromoting);
122
- } else {
123
- this.signals.set(key, new WeakRef(signal));
124
-
125
- if (isPromoting) {
126
- this.parent?.deleteSignal(key);
127
- }
128
- }
129
- }
130
-
131
- private deleteSignal(key: string) {
132
- this.signals.delete(key);
133
- this.parent?.deleteSignal(key);
134
- }
135
-
136
- run(fn: (...args: any[]) => any, args: any[], key: string, signal: Signal<unknown>, initialized: boolean) {
137
- const prevMask = CURRENT_MASK;
138
- const fnMask = COMPUTED_CONTEXT_MASKS.get(fn) ?? 0n;
139
- const signalMask = COMPUTED_CONTEXT_MASKS.get(signal) ?? 0n;
140
-
141
- try {
142
- CURRENT_MASK = signalMask | fnMask;
143
-
144
- return fn(...args);
145
- } finally {
146
- if (!initialized || signalMask !== CURRENT_MASK) {
147
- COMPUTED_CONTEXT_MASKS.set(fn, CURRENT_MASK!);
148
- COMPUTED_CONTEXT_MASKS.set(signal, CURRENT_MASK!);
149
- getCurrentScope().setSignal(key, signal!, CURRENT_MASK!, initialized);
150
- initialized = true;
151
- }
152
-
153
- CURRENT_MASK = prevMask;
154
- }
155
- }
156
-
157
- get(
158
- makeSignal: (
159
- fn: (...args: any[]) => any,
160
- opts?: Partial<SignalOptionsWithInit<unknown, unknown[]>>,
161
- ) => Signal<unknown>,
162
- fn: (...args: any[]) => any,
163
- key: string,
164
- params: string,
165
- args: unknown[],
166
- opts?: Partial<SignalOptions<unknown, unknown[]>>,
167
- ): unknown {
168
- const computedMask = COMPUTED_CONTEXT_MASKS.get(fn) ?? 0n;
169
-
170
- const fnName = opts?.desc ?? fn.name ?? getUnknownSignalFnName(fn, makeSignal);
171
-
172
- let signal = this.getSignal(key, computedMask);
173
-
174
- if (signal === undefined) {
175
- const optsWithMeta = { ...opts, id: key, desc: fnName, params };
176
- let initialized = false;
177
-
178
- if (makeSignal === createSubscriptionSignal) {
179
- signal = makeSignal(state => {
180
- const sub = this.run(fn, [state, ...args], key, signal!, initialized);
181
-
182
- if (typeof sub === 'object' && sub !== null && sub?.update) {
183
- const originalUpdate = sub.update;
184
-
185
- sub.update = () => {
186
- return this.run(originalUpdate, [], key, signal!, initialized);
187
- };
188
- }
189
-
190
- initialized = true;
191
-
192
- return sub;
193
- }, optsWithMeta);
194
- } else {
195
- signal = makeSignal((...runArgs) => {
196
- const result = this.run(fn, [...args, ...runArgs], key, signal!, initialized);
197
-
198
- initialized = true;
199
-
200
- return result;
201
- }, optsWithMeta);
202
- }
203
- }
11
+ import { useDerivedSignal } from './config.js';
12
+ import { getCurrentScope, SignalScope } from './internals/contexts.js';
13
+ import { createStateSignal } from './internals/state.js';
14
+ import { createDerivedSignal } from './internals/derived.js';
15
+ import { ReactivePromise } from './internals/async.js';
16
+ import { Tracer } from './trace.js';
204
17
 
205
- COMPUTED_OWNERS.set(signal as ComputedSignal<unknown>, this);
18
+ export const state = createStateSignal;
206
19
 
207
- const value = signal.get();
208
-
209
- if (CURRENT_MASK !== null) {
210
- CURRENT_MASK |= COMPUTED_CONTEXT_MASKS.get(fn) ?? 0n;
211
- }
212
-
213
- return value;
214
- }
215
- }
216
-
217
- export let ROOT_SCOPE = new SignalScope({});
218
-
219
- export const clearRootScope = () => {
220
- ROOT_SCOPE = new SignalScope({});
221
- };
222
-
223
- let OVERRIDE_SCOPE: SignalScope | undefined;
224
-
225
- export const getOverrideScope = () => {
226
- return OVERRIDE_SCOPE;
227
- };
228
-
229
- export const setOverrideScope = (scope: SignalScope | undefined) => {
230
- OVERRIDE_SCOPE = scope;
231
- };
232
-
233
- const getCurrentScope = (): SignalScope => {
234
- if (OVERRIDE_SCOPE !== undefined) {
235
- return OVERRIDE_SCOPE;
236
- }
237
-
238
- const currentConsumer = getCurrentConsumer();
239
-
240
- if (currentConsumer) {
241
- const scope = COMPUTED_OWNERS.get(currentConsumer);
242
-
243
- return scope ?? ROOT_SCOPE;
244
- }
245
-
246
- return getFrameworkScope() ?? ROOT_SCOPE;
247
- };
248
-
249
- export const withContext = <T>(contexts: SignalStoreMap, fn: () => T): T => {
250
- const prevScope = OVERRIDE_SCOPE;
251
- const currentScope = getCurrentScope();
252
-
253
- try {
254
- OVERRIDE_SCOPE = currentScope.getChild(contexts);
255
- return fn();
256
- } finally {
257
- OVERRIDE_SCOPE = prevScope;
258
- }
259
- };
260
-
261
- export const useContext = <T>(context: Context<T>): T => {
262
- let scope = OVERRIDE_SCOPE;
263
-
264
- if (scope === undefined) {
265
- const currentConsumer = getCurrentConsumer();
266
- scope = currentConsumer ? COMPUTED_OWNERS.get(currentConsumer) : undefined;
267
- }
268
-
269
- if (scope === undefined) {
270
- scope = getFrameworkScope();
271
- }
272
-
273
- if (scope === undefined) {
274
- throw new Error(
275
- 'useContext must be used within a signal hook, a withContext, or within a framework-specific context provider.',
276
- );
277
- }
278
-
279
- return scope.getContext(context) ?? (CONTEXT_DEFAULT_VALUES.get(context) as T);
280
- };
281
-
282
- const getParamsKey = (args: unknown[], opts?: Partial<SignalOptions<any, any[]>>) => {
283
- return opts?.paramKey ? opts.paramKey(...args) : args.map(arg => hashValue(arg)).join(', ');
284
- };
285
-
286
- const getComputedKey = (fn: (...args: any[]) => any, params: string) => {
287
- const fnId = getObjectId(fn);
288
- return `${fnId}(${params})`;
289
- };
290
-
291
- export function computed<T, Args extends unknown[]>(
20
+ export function reactive<T, Args extends unknown[]>(
21
+ fn: (...args: Args) => T,
22
+ opts?: Partial<SignalOptionsWithInit<T, Args>>,
23
+ ): (...args: Args) => ReactiveValue<T>;
24
+ export function reactive<T, Args extends unknown[]>(
292
25
  fn: (...args: Args) => T,
293
- opts?: Partial<SignalOptions<T, Args>>,
294
- ): (...args: Args) => T {
295
- return (...args) => {
296
- const params = getParamsKey(args, opts);
297
- const key = getComputedKey(fn, params);
298
-
299
- return useSignalValue(key, () => {
300
- const scope = getCurrentScope();
301
- return scope.get(
302
- createComputedSignal,
303
- fn,
304
- key,
305
- params,
306
- args,
307
- opts as Partial<SignalOptionsWithInit<unknown, unknown[]>>,
308
- ) as T;
309
- });
310
- };
311
- }
312
-
313
- export type AsyncAwaitableResult<T> = T | Promise<T>;
314
-
315
- export function asyncComputed<T, Args extends unknown[]>(
316
- fn: (...args: Args) => T | Promise<T>,
317
- opts?: SignalOptions<T, Args>,
318
- ): (...args: Args) => AsyncResult<T>;
319
- export function asyncComputed<T, Args extends unknown[]>(
320
- fn: (...args: Args) => T | Promise<T>,
321
26
  opts: SignalOptionsWithInit<T, Args>,
322
- ): (...args: Args) => AsyncReady<T>;
323
- export function asyncComputed<T, Args extends unknown[]>(
324
- fn: (...args: Args) => T | Promise<T>,
27
+ ): (...args: Args) => ReadyReactiveValue<T>;
28
+ export function reactive<T, Args extends unknown[]>(
29
+ fn: (...args: Args) => T,
325
30
  opts?: Partial<SignalOptionsWithInit<T, Args>>,
326
- ): (...args: Args) => AsyncResult<T> | AsyncReady<T> {
31
+ ): (...args: Args) => ReactiveValue<T> {
327
32
  return (...args) => {
328
- const params = getParamsKey(args, opts);
329
- const key = getComputedKey(fn, params);
33
+ const scope = getCurrentScope();
34
+ const signal = scope.get(fn as any, args, opts);
330
35
 
331
- return useSignalValue(key, () => {
332
- const scope = getCurrentScope();
333
- return scope.get(
334
- createAsyncComputedSignal,
335
- fn,
336
- key,
337
- params,
338
- args,
339
- opts as Partial<SignalOptionsWithInit<unknown, unknown[]>>,
340
- ) as AsyncResult<T>;
341
- });
36
+ return useDerivedSignal(signal)!;
342
37
  };
343
38
  }
344
39
 
345
- export function subscription<T, Args extends unknown[]>(
346
- fn: SignalSubscribe<T, Args>,
347
- opts?: Partial<SignalOptionsWithInit<T, Args>>,
348
- ): (...args: Args) => T {
349
- return (...args) => {
350
- const params = getParamsKey(args, opts);
351
- const key = getComputedKey(fn, params);
352
-
353
- return useSignalValue(key, () => {
354
- const scope = getCurrentScope();
355
- return scope.get(
356
- createSubscriptionSignal,
357
- fn,
358
- key,
359
- params,
360
- args,
361
- opts as Partial<SignalOptionsWithInit<unknown, unknown[]>>,
362
- ) as T;
363
- });
364
- };
40
+ export function subscription<T>(subscribe: SignalSubscribe<T>, opts?: SignalOptions<T, unknown[]>): ReactivePromise<T>;
41
+ export function subscription<T>(
42
+ subscribe: SignalSubscribe<T>,
43
+ opts: SignalOptionsWithInit<T, unknown[]>,
44
+ ): ReadyReactivePromise<T>;
45
+ export function subscription<T>(
46
+ subscribe: SignalSubscribe<T>,
47
+ opts?: Partial<SignalOptionsWithInit<T, unknown[]>>,
48
+ ): ReactivePromise<T> | ReadyReactivePromise<T> {
49
+ const scope = getCurrentScope();
50
+
51
+ return ReactivePromise.createSubscription(subscribe, scope, opts);
365
52
  }
366
53
 
367
- export const asyncTask = <T, Args extends unknown[]>(
54
+ export const task = <T, Args extends unknown[]>(
368
55
  fn: (...args: Args) => Promise<T>,
369
56
  opts?: Partial<SignalOptionsWithInit<T, Args>>,
370
- ): (<BuildArgs extends unknown[], RunArgs extends Args extends [...BuildArgs, ...infer _Rest] ? _Rest : Args>(
371
- ...args: Args extends [...BuildArgs, ...infer _Rest] ? BuildArgs : Args
372
- ) => AsyncTask<T, RunArgs>) => {
373
- return (...args) => {
374
- const params = getParamsKey(args, opts);
375
- const key = getComputedKey(fn, params);
57
+ ): ReactiveTask<T, Args> => {
58
+ const scope = getCurrentScope();
376
59
 
377
- return useSignalValue(key, () => {
378
- const scope = getCurrentScope();
379
- return scope.get(
380
- createAsyncTaskSignal,
381
- fn,
382
- key,
383
- params,
384
- args,
385
- opts as Partial<SignalOptionsWithInit<unknown, unknown[]>>,
386
- ) as AsyncTask<T>;
387
- });
388
- };
60
+ return ReactivePromise.createTask(fn, scope, opts);
389
61
  };
390
62
 
391
63
  export function watcher<T>(
392
- fn: (prev: T | undefined) => T,
393
- opts?: SignalOptions<T, unknown[]> & { scope?: SignalScope },
394
- ): Watcher<T> {
395
- const scope = opts?.scope ?? ROOT_SCOPE;
396
-
397
- const w = createWatcherSignal(fn, opts);
398
-
399
- COMPUTED_OWNERS.set(w as ComputedSignal<unknown>, scope);
400
-
401
- return w;
64
+ fn: () => T,
65
+ opts?: SignalOptions<T, unknown[]> & { scope?: SignalScope; tracer?: Tracer },
66
+ ): Signal<ReactiveValue<T>> {
67
+ return createDerivedSignal(fn, undefined, undefined, opts?.scope, opts);
402
68
  }
package/src/index.ts CHANGED
@@ -1,30 +1,13 @@
1
1
  export type * from './types.js';
2
2
 
3
- export {
4
- createStateSignal,
5
- createComputedSignal,
6
- createAsyncComputedSignal,
7
- createSubscriptionSignal,
8
- createWatcherSignal,
9
- createAsyncTaskSignal,
10
- getCurrentConsumer,
11
- } from './signals.js';
3
+ export { state, reactive, subscription, task, watcher } from './hooks.js';
12
4
 
13
- export {
14
- state,
15
- createContext,
16
- useContext,
17
- withContext,
18
- computed,
19
- asyncComputed,
20
- asyncTask,
21
- subscription,
22
- watcher,
23
- SignalScope,
24
- type Context,
25
- type SignalStoreMap,
26
- } from './hooks.js';
5
+ export { isReactivePromise, isReactiveTask, isReactiveSubscription } from './internals/async.js';
6
+
7
+ export { callback } from './internals/get.js';
8
+
9
+ export { createContext, useContext, withContexts, SignalScope, CONTEXT_KEY } from './internals/contexts.js';
27
10
 
28
11
  export { setConfig } from './config.js';
29
12
 
30
- export { hashValue as stringifyArgs } from './utils.js';
13
+ export { hashValue, registerCustomHash } from './internals/utils/hash.js';