@sigx/reactivity 0.1.5 → 0.1.6

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.
@@ -0,0 +1,37 @@
1
+ import type { ReactiveEffect } from './types';
2
+ /** Symbol for tracking iteration dependencies (forEach, keys, values, entries, size) */
3
+ export declare const ITERATE_KEY: unique symbol;
4
+ /** WeakMap to get raw object from reactive proxy */
5
+ export declare const reactiveToRaw: WeakMap<object, object>;
6
+ /** WeakMap to get reactive proxy from raw object */
7
+ export declare const rawToReactive: WeakMap<object, object>;
8
+ /**
9
+ * Returns the raw, original object from a reactive proxy.
10
+ * If the value is not a proxy, returns it as-is.
11
+ */
12
+ export declare function toRaw<T>(observed: T): T;
13
+ /**
14
+ * Checks if a value is a reactive proxy created by signal().
15
+ */
16
+ export declare function isReactive(value: unknown): boolean;
17
+ /**
18
+ * Checks if a value is a collection type (Set, Map, WeakSet, WeakMap).
19
+ */
20
+ export declare function isCollection(value: unknown): value is Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any>;
21
+ /**
22
+ * Checks if a value is an iterable collection (Set or Map, not Weak variants).
23
+ */
24
+ export declare function isIterableCollection(value: unknown): value is Map<any, any> | Set<any>;
25
+ /**
26
+ * Checks if a value is an "exotic" built-in object that should NOT be proxied.
27
+ * These objects have internal slots that cannot be accessed through Proxy.
28
+ * Proxying them causes errors like "Method X called on incompatible receiver".
29
+ */
30
+ export declare function shouldNotProxy(value: unknown): boolean;
31
+ /**
32
+ * Creates instrumented collection methods that properly handle reactivity.
33
+ * These methods call the real collection methods on the raw object while
34
+ * tracking dependencies and triggering updates.
35
+ */
36
+ export declare function createCollectionInstrumentations(depsMap: Map<string | symbol, Set<ReactiveEffect>>, getOrCreateDep: (key: string | symbol) => Set<ReactiveEffect>): Record<string | symbol, any>;
37
+ //# sourceMappingURL=collections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../src/collections.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,wFAAwF;AACxF,eAAO,MAAM,WAAW,eAAoB,CAAC;AAE7C,oDAAoD;AACpD,eAAO,MAAM,aAAa,yBAAgC,CAAC;AAE3D,oDAAoD;AACpD,eAAO,MAAM,aAAa,yBAAgC,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAGvC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAIjH;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAItF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA4BtD;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC5C,OAAO,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC,EAClD,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,GAAG,CAAC,cAAc,CAAC,gCA6JhE"}
@@ -0,0 +1,33 @@
1
+ import type { Computed, WritableComputed, ComputedGetter, WritableComputedOptions } from './types';
2
+ /**
3
+ * Creates a computed signal that lazily derives a value from other reactive sources.
4
+ *
5
+ * Performance characteristics:
6
+ * - Lazy: Only computes when accessed
7
+ * - Cached: Returns cached value if dependencies haven't changed
8
+ * - Minimal overhead: Uses dirty flag instead of always running getter
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const count = signal({ n: 0 });
13
+ * const doubled = computed(() => count.n * 2);
14
+ *
15
+ * console.log(doubled.value); // 0
16
+ * count.n = 5;
17
+ * console.log(doubled.value); // 10
18
+ * ```
19
+ */
20
+ export declare function computed<T>(getter: ComputedGetter<T>): Computed<T>;
21
+ export declare function computed<T>(options: WritableComputedOptions<T>): WritableComputed<T>;
22
+ /**
23
+ * Type guard to check if a value is a computed signal.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * const doubled = computed(() => count.value * 2);
28
+ * console.log(isComputed(doubled)); // true
29
+ * console.log(isComputed({ value: 1 })); // false
30
+ * ```
31
+ */
32
+ export declare function isComputed(value: unknown): value is Computed<unknown>;
33
+ //# sourceMappingURL=computed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../src/computed.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAER,QAAQ,EACR,gBAAgB,EAChB,cAAc,EAEd,uBAAuB,EAC1B,MAAM,SAAS,CAAC;AAKjB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;AACpE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;AA8EtF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,OAAO,CAAC,CAErE"}
@@ -0,0 +1,15 @@
1
+ import type { EffectFn, EffectRunner, ReactiveEffect } from './types';
2
+ export declare let activeEffect: ReactiveEffect | null;
3
+ export declare function setActiveEffect(effect: ReactiveEffect | null): void;
4
+ export declare function getActiveEffect(): ReactiveEffect | null;
5
+ export declare function batch(fn: () => void): void;
6
+ export declare function cleanup(effect: ReactiveEffect): void;
7
+ export declare function track(depSet: Set<ReactiveEffect>): void;
8
+ export declare function trigger(depSet: Set<ReactiveEffect>): void;
9
+ export declare function effect(fn: EffectFn): EffectRunner;
10
+ export declare function untrack<T>(fn: () => T): T;
11
+ export declare function effectScope(detached?: boolean): {
12
+ run<T>(fn: () => T): T | undefined;
13
+ stop(fromParent?: boolean): void;
14
+ };
15
+ //# sourceMappingURL=effect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../src/effect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEtE,eAAO,IAAI,YAAY,EAAE,cAAc,GAAG,IAAW,CAAC;AAItD,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CAEnE;AAED,wBAAgB,eAAe,IAAI,cAAc,GAAG,IAAI,CAEvD;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,QAcnC;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAMpD;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,GAAG,IAAI,CAIvD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,cAAc,CAAC,GAAG,IAAI,CASzD;AAmBD,wBAAgB,MAAM,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,CAEjD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQzC;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG;IAC7C,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACpC,CAcA"}
package/dist/index.d.ts CHANGED
@@ -1,36 +1,8 @@
1
- export type EffectFn = () => void;
2
- export interface EffectRunner<T = void> {
3
- (): T;
4
- stop: () => void;
5
- }
6
- export interface ReactiveEffect extends EffectFn {
7
- deps: Set<ReactiveEffect>[];
8
- }
9
- export declare function batch(fn: () => void): void;
10
- export type Signal<T> = T & {
11
- $set: (newValue: T) => void;
12
- };
13
- export declare function detectAccess(selector: () => any): [any, string | symbol] | null;
14
- export declare function untrack<T>(fn: () => T): T;
15
- export declare function signal<T extends object>(target: T): Signal<T>;
16
- export declare function effect(fn: EffectFn): EffectRunner;
17
- export type WatchSource<T = any> = T | (() => T);
18
- export type WatchCallback<V = any, OV = any> = (value: V, oldValue: OV, onCleanup: (fn: () => void) => void) => any;
19
- export interface WatchOptions<Immediate = boolean> {
20
- immediate?: Immediate;
21
- deep?: boolean | number;
22
- once?: boolean;
23
- }
24
- export interface WatchHandle {
25
- (): void;
26
- stop: () => void;
27
- pause: () => void;
28
- resume: () => void;
29
- }
30
- export declare function watch<T>(source: WatchSource<T>, cb: WatchCallback<T>, options?: WatchOptions): WatchHandle;
31
- export type EffectScope = {
32
- run<T>(fn: () => T): T | undefined;
33
- stop(fromParent?: boolean): void;
34
- };
35
- export declare function effectScope(detached?: boolean): EffectScope;
1
+ export type { EffectFn, EffectRunner, ReactiveEffect, Widen, Signal, PrimitiveSignal, Primitive, WatchSource, WatchCallback, WatchOptions, WatchHandle, Computed, WritableComputed, ComputedGetter, ComputedSetter, WritableComputedOptions, EffectScope } from './types';
2
+ export { ComputedSymbol } from './types';
3
+ export { effect, batch, untrack, effectScope, track, trigger, cleanup } from './effect';
4
+ export { toRaw, isReactive } from './collections';
5
+ export { signal, detectAccess } from './signal';
6
+ export { watch } from './watch';
7
+ export { computed, isComputed } from './computed';
36
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,IAAI;IAClC,IAAI,CAAC,CAAC;IACN,IAAI,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,QAAQ;IAC5C,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;CAC/B;AAMD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,QAcnC;AA4CD,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG;IACxB,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,IAAI,CAAC;CAC/B,CAAC;AAIF,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,CAe/E;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQzC;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CA2G7D;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,QAAQ,GAAG,YAAY,CAEjD;AAaD,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AACjD,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,KAAK,GAAG,CAAC;AACpH,MAAM,WAAW,YAAY,CAAC,SAAS,GAAG,OAAO;IAC7C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,IAAI,CAAC;IACT,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAsD1G;AAED,MAAM,MAAM,WAAW,GAAG;IACtB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACpC,CAAA;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,WAAW,CAc3D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,YAAY,EACR,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,KAAK,EACL,MAAM,EACN,eAAe,EACf,SAAS,EACT,WAAW,EACX,aAAa,EACb,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,uBAAuB,EACvB,WAAW,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC,OAAO,EACH,MAAM,EACN,KAAK,EACL,OAAO,EACP,WAAW,EACX,KAAK,EACL,OAAO,EACP,OAAO,EACV,MAAM,UAAU,CAAC;AAGlB,OAAO,EACH,KAAK,EACL,UAAU,EACb,MAAM,eAAe,CAAC;AAGvB,OAAO,EACH,MAAM,EACN,YAAY,EACf,MAAM,UAAU,CAAC;AAGlB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,13 @@
1
- //#region src/index.ts
1
+ const ComputedSymbol = Symbol("computed");
2
2
  let activeEffect = null;
3
- let batchDepth = 0;
4
- const pendingEffects = /* @__PURE__ */ new Set();
3
+ var batchDepth = 0;
4
+ var pendingEffects = /* @__PURE__ */ new Set();
5
+ function setActiveEffect(effect) {
6
+ activeEffect = effect;
7
+ }
8
+ function getActiveEffect() {
9
+ return activeEffect;
10
+ }
5
11
  function batch(fn) {
6
12
  batchDepth++;
7
13
  try {
@@ -11,10 +17,25 @@ function batch(fn) {
11
17
  if (batchDepth === 0) {
12
18
  const effects = Array.from(pendingEffects);
13
19
  pendingEffects.clear();
14
- for (const effect$1 of effects) effect$1();
20
+ for (const effect of effects) effect();
15
21
  }
16
22
  }
17
23
  }
24
+ function cleanup(effect) {
25
+ if (!effect.deps) return;
26
+ for (const dep of effect.deps) dep.delete(effect);
27
+ effect.deps.length = 0;
28
+ }
29
+ function track(depSet) {
30
+ if (!activeEffect) return;
31
+ depSet.add(activeEffect);
32
+ activeEffect.deps.push(depSet);
33
+ }
34
+ function trigger(depSet) {
35
+ const effects = Array.from(depSet);
36
+ for (const effect of effects) if (batchDepth > 0) pendingEffects.add(effect);
37
+ else effect();
38
+ }
18
39
  function runEffect(fn) {
19
40
  const effectFn = function() {
20
41
  cleanup(effectFn);
@@ -28,27 +49,228 @@ function runEffect(fn) {
28
49
  runner.stop = () => cleanup(effectFn);
29
50
  return runner;
30
51
  }
31
- function cleanup(effect$1) {
32
- if (!effect$1.deps) return;
33
- for (const dep of effect$1.deps) dep.delete(effect$1);
34
- effect$1.deps.length = 0;
52
+ function effect(fn) {
53
+ return runEffect(fn);
35
54
  }
36
- function track(depSet) {
37
- if (!activeEffect) return;
38
- depSet.add(activeEffect);
39
- activeEffect.deps.push(depSet);
55
+ function untrack(fn) {
56
+ const prev = activeEffect;
57
+ activeEffect = null;
58
+ try {
59
+ return fn();
60
+ } finally {
61
+ activeEffect = prev;
62
+ }
40
63
  }
41
- function trigger(depSet) {
42
- const effects = Array.from(depSet);
43
- for (const effect$1 of effects) if (batchDepth > 0) pendingEffects.add(effect$1);
44
- else effect$1();
64
+ function effectScope(detached) {
65
+ const effects = [];
66
+ let active = true;
67
+ return {
68
+ run(fn) {
69
+ if (!active) return void 0;
70
+ return fn();
71
+ },
72
+ stop() {
73
+ active = false;
74
+ effects.forEach((e) => e());
75
+ }
76
+ };
77
+ }
78
+ const ITERATE_KEY = Symbol("iterate");
79
+ const reactiveToRaw = /* @__PURE__ */ new WeakMap();
80
+ const rawToReactive = /* @__PURE__ */ new WeakMap();
81
+ function toRaw(observed) {
82
+ const raw = reactiveToRaw.get(observed);
83
+ return raw ? toRaw(raw) : observed;
84
+ }
85
+ function isReactive(value) {
86
+ return reactiveToRaw.has(value);
87
+ }
88
+ function isCollection(value) {
89
+ if (!value || typeof value !== "object") return false;
90
+ const ctor = value.constructor;
91
+ return ctor === Set || ctor === Map || ctor === WeakSet || ctor === WeakMap;
92
+ }
93
+ function isIterableCollection(value) {
94
+ if (!value || typeof value !== "object") return false;
95
+ const ctor = value.constructor;
96
+ return ctor === Set || ctor === Map;
97
+ }
98
+ function shouldNotProxy(value) {
99
+ if (!value || typeof value !== "object") return false;
100
+ const proto = Object.prototype.toString.call(value);
101
+ return [
102
+ "[object Date]",
103
+ "[object RegExp]",
104
+ "[object Error]",
105
+ "[object Promise]",
106
+ "[object ArrayBuffer]",
107
+ "[object DataView]",
108
+ "[object Int8Array]",
109
+ "[object Uint8Array]",
110
+ "[object Uint8ClampedArray]",
111
+ "[object Int16Array]",
112
+ "[object Uint16Array]",
113
+ "[object Int32Array]",
114
+ "[object Uint32Array]",
115
+ "[object Float32Array]",
116
+ "[object Float64Array]",
117
+ "[object BigInt64Array]",
118
+ "[object BigUint64Array]"
119
+ ].includes(proto);
120
+ }
121
+ function createCollectionInstrumentations(depsMap, getOrCreateDep) {
122
+ const instrumentations = {};
123
+ instrumentations.has = function(key) {
124
+ const target = toRaw(this);
125
+ const rawKey = toRaw(key);
126
+ track(getOrCreateDep(rawKey));
127
+ return target.has(rawKey);
128
+ };
129
+ instrumentations.get = function(key) {
130
+ const target = toRaw(this);
131
+ const rawKey = toRaw(key);
132
+ track(getOrCreateDep(rawKey));
133
+ const value = target.get(rawKey);
134
+ if (value && typeof value === "object") return rawToReactive.get(value) || value;
135
+ return value;
136
+ };
137
+ Object.defineProperty(instrumentations, "size", { get() {
138
+ const target = toRaw(this);
139
+ track(getOrCreateDep(ITERATE_KEY));
140
+ return target.size;
141
+ } });
142
+ instrumentations.forEach = function(callback, thisArg) {
143
+ const target = toRaw(this);
144
+ track(getOrCreateDep(ITERATE_KEY));
145
+ target.forEach((value, key) => {
146
+ const reactiveValue = value && typeof value === "object" ? rawToReactive.get(value) || value : value;
147
+ const reactiveKey = key && typeof key === "object" ? rawToReactive.get(key) || key : key;
148
+ callback.call(thisArg, reactiveValue, reactiveKey, this);
149
+ });
150
+ };
151
+ instrumentations.keys = function() {
152
+ const target = toRaw(this);
153
+ track(getOrCreateDep(ITERATE_KEY));
154
+ return createReactiveIterator(target.keys(), false);
155
+ };
156
+ instrumentations.values = function() {
157
+ const target = toRaw(this);
158
+ track(getOrCreateDep(ITERATE_KEY));
159
+ return createReactiveIterator(target.values(), true);
160
+ };
161
+ instrumentations.entries = function() {
162
+ const target = toRaw(this);
163
+ track(getOrCreateDep(ITERATE_KEY));
164
+ return createReactiveEntriesIterator(target.entries());
165
+ };
166
+ instrumentations[Symbol.iterator] = function() {
167
+ const target = toRaw(this);
168
+ track(getOrCreateDep(ITERATE_KEY));
169
+ if (target instanceof Set) return createReactiveIterator(target.values(), true);
170
+ else return createReactiveEntriesIterator(target.entries());
171
+ };
172
+ instrumentations.add = function(value) {
173
+ const target = toRaw(this);
174
+ const rawValue = toRaw(value);
175
+ const hadKey = target.has(rawValue);
176
+ target.add(rawValue);
177
+ if (!hadKey) {
178
+ const dep = depsMap.get(rawValue);
179
+ if (dep) trigger(dep);
180
+ const iterDep = depsMap.get(ITERATE_KEY);
181
+ if (iterDep) trigger(iterDep);
182
+ }
183
+ return this;
184
+ };
185
+ instrumentations.set = function(key, value) {
186
+ const target = toRaw(this);
187
+ const rawKey = toRaw(key);
188
+ const rawValue = toRaw(value);
189
+ const hadKey = target.has(rawKey);
190
+ const oldValue = target.get(rawKey);
191
+ target.set(rawKey, rawValue);
192
+ if (!hadKey) {
193
+ const iterDep = depsMap.get(ITERATE_KEY);
194
+ if (iterDep) trigger(iterDep);
195
+ }
196
+ if (!hadKey || !Object.is(oldValue, rawValue)) {
197
+ const dep = depsMap.get(rawKey);
198
+ if (dep) trigger(dep);
199
+ }
200
+ return this;
201
+ };
202
+ instrumentations.delete = function(key) {
203
+ const target = toRaw(this);
204
+ const rawKey = toRaw(key);
205
+ const hadKey = target.has(rawKey);
206
+ const result = target.delete(rawKey);
207
+ if (hadKey) {
208
+ const dep = depsMap.get(rawKey);
209
+ if (dep) trigger(dep);
210
+ const iterDep = depsMap.get(ITERATE_KEY);
211
+ if (iterDep) trigger(iterDep);
212
+ }
213
+ return result;
214
+ };
215
+ instrumentations.clear = function() {
216
+ const target = toRaw(this);
217
+ const hadItems = target.size > 0;
218
+ target.clear();
219
+ if (hadItems) for (const dep of depsMap.values()) trigger(dep);
220
+ };
221
+ return instrumentations;
222
+ }
223
+ function createReactiveIterator(innerIterator, wrapValues) {
224
+ return {
225
+ next() {
226
+ const { value, done } = innerIterator.next();
227
+ if (done) return {
228
+ value: void 0,
229
+ done: true
230
+ };
231
+ return {
232
+ value: wrapValues && value && typeof value === "object" ? rawToReactive.get(value) || value : value,
233
+ done: false
234
+ };
235
+ },
236
+ [Symbol.iterator]() {
237
+ return this;
238
+ }
239
+ };
240
+ }
241
+ function createReactiveEntriesIterator(innerIterator) {
242
+ return {
243
+ next() {
244
+ const { value, done } = innerIterator.next();
245
+ if (done) return {
246
+ value: void 0,
247
+ done: true
248
+ };
249
+ const [key, val] = value;
250
+ return {
251
+ value: [key && typeof key === "object" ? rawToReactive.get(key) || key : key, val && typeof val === "object" ? rawToReactive.get(val) || val : val],
252
+ done: false
253
+ };
254
+ },
255
+ [Symbol.iterator]() {
256
+ return this;
257
+ }
258
+ };
259
+ }
260
+ function isPrimitive(value) {
261
+ if (value === null || value === void 0) return true;
262
+ const type = typeof value;
263
+ return type === "string" || type === "number" || type === "boolean" || type === "symbol" || type === "bigint";
264
+ }
265
+ var accessObserver = null;
266
+ function getAccessObserver() {
267
+ return accessObserver;
45
268
  }
46
- let accessObserver = null;
47
269
  function detectAccess(selector) {
48
270
  let result = null;
49
271
  const prev = accessObserver;
50
272
  accessObserver = (target, key) => {
51
- result = [target, key];
273
+ if (result === null) result = [target, key];
52
274
  };
53
275
  try {
54
276
  selector();
@@ -57,19 +279,43 @@ function detectAccess(selector) {
57
279
  }
58
280
  return result;
59
281
  }
60
- function untrack(fn) {
61
- const prev = activeEffect;
62
- activeEffect = null;
63
- try {
64
- return fn();
65
- } finally {
66
- activeEffect = prev;
67
- }
68
- }
282
+ var arrayInstrumentations = {};
283
+ [
284
+ "push",
285
+ "pop",
286
+ "shift",
287
+ "unshift",
288
+ "splice",
289
+ "sort",
290
+ "reverse"
291
+ ].forEach((method) => {
292
+ arrayInstrumentations[method] = function(...args) {
293
+ let res;
294
+ batch(() => {
295
+ res = Array.prototype[method].apply(this, args);
296
+ });
297
+ return res;
298
+ };
299
+ });
69
300
  function signal(target) {
301
+ if (isPrimitive(target)) return signal({ value: target });
302
+ const objectTarget = target;
303
+ if (shouldNotProxy(objectTarget)) return objectTarget;
304
+ if (isReactive(objectTarget)) return objectTarget;
305
+ const existingProxy = rawToReactive.get(objectTarget);
306
+ if (existingProxy) return existingProxy;
70
307
  const depsMap = /* @__PURE__ */ new Map();
71
308
  const reactiveCache = /* @__PURE__ */ new WeakMap();
72
- return new Proxy(target, {
309
+ const getOrCreateDep = (key) => {
310
+ let dep = depsMap.get(key);
311
+ if (!dep) {
312
+ dep = /* @__PURE__ */ new Set();
313
+ depsMap.set(key, dep);
314
+ }
315
+ return dep;
316
+ };
317
+ const collectionInstrumentations = isCollection(objectTarget) ? createCollectionInstrumentations(depsMap, getOrCreateDep) : null;
318
+ const proxy = new Proxy(objectTarget, {
73
319
  get(obj, prop, receiver) {
74
320
  if (prop === "$set") return (newValue) => {
75
321
  batch(() => {
@@ -85,16 +331,22 @@ function signal(target) {
85
331
  }
86
332
  });
87
333
  };
334
+ if (collectionInstrumentations) {
335
+ if (prop === "size" && isIterableCollection(obj)) {
336
+ track(getOrCreateDep(ITERATE_KEY));
337
+ return obj.size;
338
+ }
339
+ if (prop in collectionInstrumentations) {
340
+ const instrumented = collectionInstrumentations[prop];
341
+ if (typeof instrumented === "function") return instrumented.bind(receiver);
342
+ return instrumented;
343
+ }
344
+ }
88
345
  if (Array.isArray(obj) && typeof prop === "string" && arrayInstrumentations.hasOwnProperty(prop)) return arrayInstrumentations[prop];
89
346
  const value = Reflect.get(obj, prop);
90
347
  if (accessObserver) accessObserver(receiver, prop);
91
- let dep = depsMap.get(prop);
92
- if (!dep) {
93
- dep = /* @__PURE__ */ new Set();
94
- depsMap.set(prop, dep);
95
- }
96
- track(dep);
97
- if (value && typeof value === "object") {
348
+ if (!collectionInstrumentations) track(getOrCreateDep(prop));
349
+ if (value && typeof value === "object" && !shouldNotProxy(value)) {
98
350
  let cached = reactiveCache.get(value);
99
351
  if (!cached) {
100
352
  cached = signal(value);
@@ -134,28 +386,26 @@ function signal(target) {
134
386
  return result;
135
387
  }
136
388
  });
389
+ reactiveToRaw.set(proxy, objectTarget);
390
+ rawToReactive.set(objectTarget, proxy);
391
+ return proxy;
137
392
  }
138
- function effect(fn) {
139
- return runEffect(fn);
393
+ function traverse(value, depth = Infinity, seen = /* @__PURE__ */ new Set()) {
394
+ if (depth <= 0) return value;
395
+ if (value === null || typeof value !== "object") return value;
396
+ if (seen.has(value)) return value;
397
+ seen.add(value);
398
+ if (Array.isArray(value)) for (let i = 0; i < value.length; i++) traverse(value[i], depth - 1, seen);
399
+ else if (value instanceof Map) value.forEach((v, k) => {
400
+ traverse(k, depth - 1, seen);
401
+ traverse(v, depth - 1, seen);
402
+ });
403
+ else if (value instanceof Set) value.forEach((v) => {
404
+ traverse(v, depth - 1, seen);
405
+ });
406
+ else for (const key of Object.keys(value)) traverse(value[key], depth - 1, seen);
407
+ return value;
140
408
  }
141
- const arrayInstrumentations = {};
142
- [
143
- "push",
144
- "pop",
145
- "shift",
146
- "unshift",
147
- "splice",
148
- "sort",
149
- "reverse"
150
- ].forEach((method) => {
151
- arrayInstrumentations[method] = function(...args) {
152
- let res;
153
- batch(() => {
154
- res = Array.prototype[method].apply(this, args);
155
- });
156
- return res;
157
- };
158
- });
159
409
  function watch(source, cb, options) {
160
410
  let oldValue;
161
411
  let isFirst = true;
@@ -163,8 +413,13 @@ function watch(source, cb, options) {
163
413
  let paused = false;
164
414
  let pendingValue;
165
415
  let hasPending = false;
416
+ let stopped = false;
417
+ const deep = options?.deep;
418
+ const traverseDepth = deep === true ? Infinity : typeof deep === "number" ? deep : 0;
166
419
  const runner = effect(() => {
167
- const newValue = typeof source === "function" ? source() : source;
420
+ if (stopped) return;
421
+ let newValue = typeof source === "function" ? source() : source;
422
+ if (traverseDepth > 0) traverse(newValue, traverseDepth);
168
423
  if (paused) {
169
424
  pendingValue = newValue;
170
425
  hasPending = true;
@@ -174,15 +429,24 @@ function watch(source, cb, options) {
174
429
  if (options?.immediate) {
175
430
  if (cleanupFn) cleanupFn();
176
431
  cb(newValue, oldValue, (fn) => cleanupFn = fn);
432
+ if (options?.once) {
433
+ stopped = true;
434
+ queueMicrotask(() => stop());
435
+ }
177
436
  }
178
437
  isFirst = false;
179
438
  } else {
180
439
  if (cleanupFn) cleanupFn();
181
440
  cb(newValue, oldValue, (fn) => cleanupFn = fn);
441
+ if (options?.once) {
442
+ stopped = true;
443
+ queueMicrotask(() => stop());
444
+ }
182
445
  }
183
446
  oldValue = newValue;
184
447
  });
185
448
  const stop = () => {
449
+ stopped = true;
186
450
  runner.stop();
187
451
  if (cleanupFn) cleanupFn();
188
452
  };
@@ -206,21 +470,66 @@ function watch(source, cb, options) {
206
470
  resume
207
471
  });
208
472
  }
209
- function effectScope(detached) {
210
- const effects = [];
211
- let active = true;
212
- return {
213
- run(fn) {
214
- if (!active) return void 0;
215
- return fn();
216
- },
217
- stop() {
218
- active = false;
219
- effects.forEach((e) => e());
473
+ function computed(getterOrOptions) {
474
+ let getter;
475
+ let setter;
476
+ if (typeof getterOrOptions === "function") getter = getterOrOptions;
477
+ else {
478
+ getter = getterOrOptions.get;
479
+ setter = getterOrOptions.set;
480
+ }
481
+ const subscribers = /* @__PURE__ */ new Set();
482
+ let cachedValue;
483
+ let dirty = true;
484
+ const computedEffect = function() {
485
+ if (!dirty) {
486
+ dirty = true;
487
+ trigger(subscribers);
220
488
  }
221
489
  };
490
+ computedEffect.deps = [];
491
+ const computeValue = () => {
492
+ cleanup(computedEffect);
493
+ const prevEffect = getActiveEffect();
494
+ setActiveEffect(computedEffect);
495
+ try {
496
+ cachedValue = getter();
497
+ dirty = false;
498
+ return cachedValue;
499
+ } finally {
500
+ setActiveEffect(prevEffect);
501
+ }
502
+ };
503
+ const computedObj = {
504
+ [ComputedSymbol]: true,
505
+ get value() {
506
+ const observer = getAccessObserver();
507
+ if (observer) observer(computedObj, "value");
508
+ track(subscribers);
509
+ return dirty ? computeValue() : cachedValue;
510
+ }
511
+ };
512
+ if (setter) {
513
+ Object.defineProperty(computedObj, "value", {
514
+ get() {
515
+ const observer = getAccessObserver();
516
+ if (observer) observer(computedObj, "value");
517
+ track(subscribers);
518
+ return dirty ? computeValue() : cachedValue;
519
+ },
520
+ set(newValue) {
521
+ setter(newValue);
522
+ },
523
+ enumerable: true,
524
+ configurable: false
525
+ });
526
+ return computedObj;
527
+ }
528
+ return computedObj;
529
+ }
530
+ function isComputed(value) {
531
+ return value !== null && typeof value === "object" && ComputedSymbol in value;
222
532
  }
533
+ export { ComputedSymbol, batch, cleanup, computed, detectAccess, effect, effectScope, isComputed, isReactive, signal, toRaw, track, trigger, untrack, watch };
223
534
 
224
- //#endregion
225
- export { batch, detectAccess, effect, effectScope, signal, untrack, watch };
226
535
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["activeEffect: ReactiveEffect | null","effect","effectFn: ReactiveEffect","accessObserver: ((target: any, key: string | symbol) => void) | null","result: [any, string | symbol] | null","arrayInstrumentations: Record<string, Function>","oldValue: T | undefined","cleanupFn: (() => void) | null","pendingValue: T | undefined","effects: (() => void)[]"],"sources":["../src/index.ts"],"sourcesContent":["// signals.ts\r\n\r\nexport type EffectFn = () => void;\r\n\r\nexport interface EffectRunner<T = void> {\r\n (): T;\r\n stop: () => void;\r\n}\r\n\r\nexport interface ReactiveEffect extends EffectFn {\r\n deps: Set<ReactiveEffect>[];\r\n}\r\n\r\nlet activeEffect: ReactiveEffect | null = null;\r\nlet batchDepth = 0;\r\nconst pendingEffects = new Set<ReactiveEffect>();\r\n\r\nexport function batch(fn: () => void) {\r\n batchDepth++;\r\n try {\r\n fn();\r\n } finally {\r\n batchDepth--;\r\n if (batchDepth === 0) {\r\n const effects = Array.from(pendingEffects);\r\n pendingEffects.clear();\r\n for (const effect of effects) {\r\n effect();\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction runEffect(fn: EffectFn): EffectRunner {\r\n const effectFn: ReactiveEffect = function () {\r\n cleanup(effectFn);\r\n activeEffect = effectFn;\r\n fn();\r\n activeEffect = null;\r\n } as ReactiveEffect;\r\n\r\n effectFn.deps = [];\r\n effectFn();\r\n\r\n // Return the effect as a runner with a stop method\r\n const runner = (() => effectFn()) as EffectRunner;\r\n runner.stop = () => cleanup(effectFn);\r\n return runner;\r\n}\r\n\r\nfunction cleanup(effect: ReactiveEffect): void {\r\n if (!effect.deps) return;\r\n for (const dep of effect.deps) {\r\n dep.delete(effect);\r\n }\r\n effect.deps.length = 0;\r\n}\r\n\r\nfunction track(depSet: Set<ReactiveEffect>): void {\r\n if (!activeEffect) return;\r\n depSet.add(activeEffect);\r\n activeEffect.deps.push(depSet);\r\n}\r\n\r\nfunction trigger(depSet: Set<ReactiveEffect>): void {\r\n const effects = Array.from(depSet);\r\n for (const effect of effects) {\r\n if (batchDepth > 0) {\r\n pendingEffects.add(effect);\r\n } else {\r\n effect();\r\n }\r\n }\r\n}\r\n\r\nexport type Signal<T> = T & {\r\n $set: (newValue: T) => void;\r\n};\r\n\r\nlet accessObserver: ((target: any, key: string | symbol) => void) | null = null;\r\n\r\nexport function detectAccess(selector: () => any): [any, string | symbol] | null {\r\n let result: [any, string | symbol] | null = null;\r\n const prev = accessObserver;\r\n\r\n accessObserver = (target, key) => {\r\n result = [target, key];\r\n };\r\n\r\n try {\r\n selector();\r\n } finally {\r\n accessObserver = prev;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport function untrack<T>(fn: () => T): T {\r\n const prev = activeEffect;\r\n activeEffect = null;\r\n try {\r\n return fn();\r\n } finally {\r\n activeEffect = prev;\r\n }\r\n}\r\n\r\nexport function signal<T extends object>(target: T): Signal<T> {\r\n const depsMap = new Map<string | symbol, Set<ReactiveEffect>>();\r\n const reactiveCache = new WeakMap<object, any>();\r\n\r\n return new Proxy(target, {\r\n get(obj, prop, receiver) {\r\n if (prop === '$set') {\r\n return (newValue: T) => {\r\n batch(() => {\r\n if (Array.isArray(obj) && Array.isArray(newValue)) {\r\n const len = newValue.length;\r\n for (let i = 0; i < len; i++) {\r\n Reflect.set(receiver, String(i), newValue[i]);\r\n }\r\n Reflect.set(receiver, 'length', len);\r\n } else {\r\n const newKeys = Object.keys(newValue);\r\n const oldKeys = Object.keys(obj);\r\n for (const key of newKeys) {\r\n Reflect.set(receiver, key, (newValue as any)[key]);\r\n }\r\n for (const key of oldKeys) {\r\n if (!(key in newValue)) {\r\n Reflect.deleteProperty(receiver, key);\r\n }\r\n }\r\n }\r\n });\r\n };\r\n }\r\n\r\n if (Array.isArray(obj) && typeof prop === 'string' && arrayInstrumentations.hasOwnProperty(prop)) {\r\n return arrayInstrumentations[prop];\r\n }\r\n\r\n const value = Reflect.get(obj, prop);\r\n\r\n if (accessObserver) {\r\n accessObserver(receiver, prop);\r\n }\r\n\r\n // Track this property access\r\n let dep = depsMap.get(prop);\r\n if (!dep) {\r\n dep = new Set<ReactiveEffect>();\r\n depsMap.set(prop, dep);\r\n }\r\n track(dep);\r\n\r\n // If the value is an object, make it reactive too (with caching)\r\n if (value && typeof value === 'object') {\r\n let cached = reactiveCache.get(value);\r\n if (!cached) {\r\n cached = signal(value);\r\n reactiveCache.set(value, cached);\r\n }\r\n return cached;\r\n }\r\n\r\n return value;\r\n },\r\n set(obj, prop, newValue) {\r\n const oldLength = Array.isArray(obj) ? obj.length : 0;\r\n const oldValue = Reflect.get(obj, prop);\r\n const result = Reflect.set(obj, prop, newValue);\r\n\r\n // Only trigger if value actually changed\r\n if (!Object.is(oldValue, newValue)) {\r\n const dep = depsMap.get(prop);\r\n if (dep) {\r\n trigger(dep);\r\n }\r\n\r\n // Special handling for Arrays\r\n if (Array.isArray(obj)) {\r\n // If we set an index and length changed, trigger length dependency\r\n if (prop !== 'length' && obj.length !== oldLength) {\r\n const lengthDep = depsMap.get('length');\r\n if (lengthDep) {\r\n trigger(lengthDep);\r\n }\r\n }\r\n // If we set length, trigger indices that are now out of bounds\r\n if (prop === 'length' && typeof newValue === 'number' && newValue < oldLength) {\r\n for (let i = newValue; i < oldLength; i++) {\r\n const idxDep = depsMap.get(String(i));\r\n if (idxDep) trigger(idxDep);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n deleteProperty(obj, prop) {\r\n const hasKey = Object.prototype.hasOwnProperty.call(obj, prop);\r\n const result = Reflect.deleteProperty(obj, prop);\r\n\r\n if (result && hasKey) {\r\n const dep = depsMap.get(prop);\r\n if (dep) {\r\n trigger(dep);\r\n }\r\n }\r\n return result;\r\n }\r\n }) as Signal<T>;\r\n}\r\n\r\nexport function effect(fn: EffectFn): EffectRunner {\r\n return runEffect(fn);\r\n}\r\n\r\nconst arrayInstrumentations: Record<string, Function> = {};\r\n['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {\r\n arrayInstrumentations[method] = function (this: any, ...args: any[]) {\r\n let res;\r\n batch(() => {\r\n res = (Array.prototype as any)[method].apply(this, args);\r\n });\r\n return res;\r\n };\r\n});\r\n\r\nexport type WatchSource<T = any> = T | (() => T);\r\nexport type WatchCallback<V = any, OV = any> = (value: V, oldValue: OV, onCleanup: (fn: () => void) => void) => any;\r\nexport interface WatchOptions<Immediate = boolean> {\r\n immediate?: Immediate;\r\n deep?: boolean | number;\r\n once?: boolean;\r\n}\r\n\r\nexport interface WatchHandle {\r\n (): void; // callable to stop\r\n stop: () => void;\r\n pause: () => void;\r\n resume: () => void;\r\n}\r\n\r\nexport function watch<T>(source: WatchSource<T>, cb: WatchCallback<T>, options?: WatchOptions): WatchHandle {\r\n let oldValue: T | undefined;\r\n let isFirst = true;\r\n let cleanupFn: (() => void) | null = null;\r\n let paused = false;\r\n let pendingValue: T | undefined;\r\n let hasPending = false;\r\n\r\n const runner = effect(() => {\r\n const newValue = typeof source === 'function' ? (source as () => T)() : source;\r\n\r\n if (paused) {\r\n // Store pending value to process on resume\r\n pendingValue = newValue;\r\n hasPending = true;\r\n return;\r\n }\r\n\r\n if (isFirst) {\r\n if (options?.immediate) {\r\n if (cleanupFn) cleanupFn();\r\n cb(newValue, oldValue, (fn) => cleanupFn = fn);\r\n }\r\n isFirst = false;\r\n } else {\r\n if (cleanupFn) cleanupFn();\r\n cb(newValue, oldValue, (fn) => cleanupFn = fn);\r\n }\r\n oldValue = newValue;\r\n });\r\n\r\n const stop = () => {\r\n runner.stop();\r\n if (cleanupFn) cleanupFn();\r\n };\r\n\r\n const pause = () => {\r\n paused = true;\r\n };\r\n\r\n const resume = () => {\r\n if (!paused) return;\r\n paused = false;\r\n // If value changed while paused, trigger callback now\r\n if (hasPending && !Object.is(pendingValue, oldValue)) {\r\n if (cleanupFn) cleanupFn();\r\n cb(pendingValue as T, oldValue, (fn) => cleanupFn = fn);\r\n oldValue = pendingValue;\r\n }\r\n hasPending = false;\r\n pendingValue = undefined;\r\n };\r\n\r\n return Object.assign(stop, { stop, pause, resume });\r\n}\r\n\r\nexport type EffectScope = {\r\n run<T>(fn: () => T): T | undefined;\r\n stop(fromParent?: boolean): void;\r\n}\r\n\r\nexport function effectScope(detached?: boolean): EffectScope {\r\n const effects: (() => void)[] = [];\r\n let active = true;\r\n\r\n return {\r\n run<T>(fn: () => T): T | undefined {\r\n if (!active) return undefined;\r\n return fn();\r\n },\r\n stop() {\r\n active = false;\r\n effects.forEach(e => e());\r\n }\r\n };\r\n}\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/types.ts","../src/effect.ts","../src/collections.ts","../src/signal.ts","../src/watch.ts","../src/computed.ts"],"sourcesContent":["// ============================================================================\r\n// Type Definitions\r\n// ============================================================================\r\n\r\n/** Symbol to identify computed values */\r\nexport const ComputedSymbol: unique symbol = Symbol('computed');\r\n\r\nexport type EffectFn = () => void;\r\n\r\nexport interface EffectRunner<T = void> {\r\n (): T;\r\n stop: () => void;\r\n}\r\n\r\nexport interface ReactiveEffect extends EffectFn {\r\n deps: Set<ReactiveEffect>[];\r\n}\r\n\r\n/** \r\n * Widens literal types to their base primitive types.\r\n * e.g., `false` → `boolean`, `\"hello\"` → `string`, `123` → `number`\r\n */\r\nexport type Widen<T> = \r\n T extends boolean ? boolean :\r\n T extends number ? number :\r\n T extends string ? string :\r\n T extends bigint ? bigint :\r\n T extends symbol ? symbol :\r\n T;\r\n\r\n/** Type for object/array signals - includes $set for replacing the whole object */\r\nexport type Signal<T> = T & {\r\n $set: (newValue: T) => void;\r\n};\r\n\r\n/** Type for primitive values that get wrapped in { value: T } - no $set, use .value instead */\r\nexport type PrimitiveSignal<T> = { value: Widen<T> };\r\n\r\n/** Primitive types that will be wrapped in { value: T } */\r\nexport type Primitive = string | number | boolean | symbol | bigint | null | undefined;\r\n\r\n// Watch types\r\nexport type WatchSource<T = any> = T | (() => T);\r\nexport type WatchCallback<V = any, OV = any> = (value: V, oldValue: OV, onCleanup: (fn: () => void) => void) => any;\r\n\r\nexport interface WatchOptions<Immediate = boolean> {\r\n immediate?: Immediate;\r\n deep?: boolean | number;\r\n once?: boolean;\r\n}\r\n\r\nexport interface WatchHandle {\r\n (): void; // callable to stop\r\n stop: () => void;\r\n pause: () => void;\r\n resume: () => void;\r\n}\r\n\r\n// Computed types\r\n/** A read-only computed signal - access via .value */\r\nexport interface Computed<T> {\r\n readonly value: T;\r\n readonly [ComputedSymbol]: true;\r\n}\r\n\r\n/** A writable computed signal - access and set via .value */\r\nexport interface WritableComputed<T> {\r\n value: T;\r\n readonly [ComputedSymbol]: true;\r\n}\r\n\r\nexport interface ComputedGetter<T> {\r\n (): T;\r\n}\r\n\r\nexport interface ComputedSetter<T> {\r\n (value: T): void;\r\n}\r\n\r\nexport interface WritableComputedOptions<T> {\r\n get: ComputedGetter<T>;\r\n set: ComputedSetter<T>;\r\n}\r\n\r\n// Effect scope types\r\nexport type EffectScope = {\r\n run<T>(fn: () => T): T | undefined;\r\n stop(fromParent?: boolean): void;\r\n}\r\n","// ============================================================================\r\n// Effect System - Core reactivity primitives\r\n// ============================================================================\r\n\r\nimport type { EffectFn, EffectRunner, ReactiveEffect } from './types';\r\n\r\nexport let activeEffect: ReactiveEffect | null = null;\r\nlet batchDepth = 0;\r\nconst pendingEffects = new Set<ReactiveEffect>();\r\n\r\nexport function setActiveEffect(effect: ReactiveEffect | null): void {\r\n activeEffect = effect;\r\n}\r\n\r\nexport function getActiveEffect(): ReactiveEffect | null {\r\n return activeEffect;\r\n}\r\n\r\nexport function batch(fn: () => void) {\r\n batchDepth++;\r\n try {\r\n fn();\r\n } finally {\r\n batchDepth--;\r\n if (batchDepth === 0) {\r\n const effects = Array.from(pendingEffects);\r\n pendingEffects.clear();\r\n for (const effect of effects) {\r\n effect();\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport function cleanup(effect: ReactiveEffect): void {\r\n if (!effect.deps) return;\r\n for (const dep of effect.deps) {\r\n dep.delete(effect);\r\n }\r\n effect.deps.length = 0;\r\n}\r\n\r\nexport function track(depSet: Set<ReactiveEffect>): void {\r\n if (!activeEffect) return;\r\n depSet.add(activeEffect);\r\n activeEffect.deps.push(depSet);\r\n}\r\n\r\nexport function trigger(depSet: Set<ReactiveEffect>): void {\r\n const effects = Array.from(depSet);\r\n for (const effect of effects) {\r\n if (batchDepth > 0) {\r\n pendingEffects.add(effect);\r\n } else {\r\n effect();\r\n }\r\n }\r\n}\r\n\r\nfunction runEffect(fn: EffectFn): EffectRunner {\r\n const effectFn: ReactiveEffect = function () {\r\n cleanup(effectFn);\r\n activeEffect = effectFn;\r\n fn();\r\n activeEffect = null;\r\n } as ReactiveEffect;\r\n\r\n effectFn.deps = [];\r\n effectFn();\r\n\r\n // Return the effect as a runner with a stop method\r\n const runner = (() => effectFn()) as EffectRunner;\r\n runner.stop = () => cleanup(effectFn);\r\n return runner;\r\n}\r\n\r\nexport function effect(fn: EffectFn): EffectRunner {\r\n return runEffect(fn);\r\n}\r\n\r\nexport function untrack<T>(fn: () => T): T {\r\n const prev = activeEffect;\r\n activeEffect = null;\r\n try {\r\n return fn();\r\n } finally {\r\n activeEffect = prev;\r\n }\r\n}\r\n\r\nexport function effectScope(detached?: boolean): {\r\n run<T>(fn: () => T): T | undefined;\r\n stop(fromParent?: boolean): void;\r\n} {\r\n const effects: (() => void)[] = [];\r\n let active = true;\r\n\r\n return {\r\n run<T>(fn: () => T): T | undefined {\r\n if (!active) return undefined;\r\n return fn();\r\n },\r\n stop() {\r\n active = false;\r\n effects.forEach(e => e());\r\n }\r\n };\r\n}\r\n","// ============================================================================\r\n// Collection Reactivity Support (Set, Map, WeakSet, WeakMap)\r\n// ============================================================================\r\n\r\nimport type { ReactiveEffect } from './types';\r\nimport { track, trigger } from './effect';\r\n\r\n/** Symbol for tracking iteration dependencies (forEach, keys, values, entries, size) */\r\nexport const ITERATE_KEY = Symbol('iterate');\r\n\r\n/** WeakMap to get raw object from reactive proxy */\r\nexport const reactiveToRaw = new WeakMap<object, object>();\r\n\r\n/** WeakMap to get reactive proxy from raw object */\r\nexport const rawToReactive = new WeakMap<object, object>();\r\n\r\n/**\r\n * Returns the raw, original object from a reactive proxy.\r\n * If the value is not a proxy, returns it as-is.\r\n */\r\nexport function toRaw<T>(observed: T): T {\r\n const raw = reactiveToRaw.get(observed as object);\r\n return raw ? toRaw(raw as T) : observed;\r\n}\r\n\r\n/**\r\n * Checks if a value is a reactive proxy created by signal().\r\n */\r\nexport function isReactive(value: unknown): boolean {\r\n return reactiveToRaw.has(value as object);\r\n}\r\n\r\n/**\r\n * Checks if a value is a collection type (Set, Map, WeakSet, WeakMap).\r\n */\r\nexport function isCollection(value: unknown): value is Map<any, any> | Set<any> | WeakMap<any, any> | WeakSet<any> {\r\n if (!value || typeof value !== 'object') return false;\r\n const ctor = value.constructor;\r\n return ctor === Set || ctor === Map || ctor === WeakSet || ctor === WeakMap;\r\n}\r\n\r\n/**\r\n * Checks if a value is an iterable collection (Set or Map, not Weak variants).\r\n */\r\nexport function isIterableCollection(value: unknown): value is Map<any, any> | Set<any> {\r\n if (!value || typeof value !== 'object') return false;\r\n const ctor = value.constructor;\r\n return ctor === Set || ctor === Map;\r\n}\r\n\r\n/**\r\n * Checks if a value is an \"exotic\" built-in object that should NOT be proxied.\r\n * These objects have internal slots that cannot be accessed through Proxy.\r\n * Proxying them causes errors like \"Method X called on incompatible receiver\".\r\n */\r\nexport function shouldNotProxy(value: unknown): boolean {\r\n if (!value || typeof value !== 'object') return false;\r\n \r\n // Check against constructors of built-ins with internal slots\r\n const proto = Object.prototype.toString.call(value);\r\n \r\n // Built-ins that should not be proxied\r\n const nonProxyable = [\r\n '[object Date]',\r\n '[object RegExp]',\r\n '[object Error]',\r\n '[object Promise]',\r\n '[object ArrayBuffer]',\r\n '[object DataView]',\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ];\r\n \r\n return nonProxyable.includes(proto);\r\n}\r\n\r\n/**\r\n * Creates instrumented collection methods that properly handle reactivity.\r\n * These methods call the real collection methods on the raw object while\r\n * tracking dependencies and triggering updates.\r\n */\r\nexport function createCollectionInstrumentations(\r\n depsMap: Map<string | symbol, Set<ReactiveEffect>>,\r\n getOrCreateDep: (key: string | symbol) => Set<ReactiveEffect>\r\n) {\r\n const instrumentations: Record<string | symbol, any> = {};\r\n\r\n // ---- READ METHODS (track dependencies) ----\r\n\r\n // has() - works on Set, Map, WeakSet, WeakMap\r\n instrumentations.has = function (this: any, key: unknown): boolean {\r\n const target = toRaw(this);\r\n const rawKey = toRaw(key);\r\n track(getOrCreateDep(rawKey as string | symbol));\r\n return target.has(rawKey);\r\n };\r\n\r\n // get() - works on Map, WeakMap\r\n instrumentations.get = function (this: any, key: unknown): any {\r\n const target = toRaw(this);\r\n const rawKey = toRaw(key);\r\n track(getOrCreateDep(rawKey as string | symbol));\r\n const value = target.get(rawKey);\r\n // Make the returned value reactive if it's an object\r\n if (value && typeof value === 'object') {\r\n return rawToReactive.get(value) || value;\r\n }\r\n return value;\r\n };\r\n\r\n // size - works on Set, Map (not WeakSet, WeakMap)\r\n Object.defineProperty(instrumentations, 'size', {\r\n get(this: any) {\r\n const target = toRaw(this);\r\n track(getOrCreateDep(ITERATE_KEY));\r\n return target.size;\r\n }\r\n });\r\n\r\n // forEach() - works on Set, Map\r\n instrumentations.forEach = function (this: any, callback: Function, thisArg?: unknown): void {\r\n const target = toRaw(this);\r\n track(getOrCreateDep(ITERATE_KEY));\r\n target.forEach((value: any, key: any) => {\r\n // Make values reactive when iterating\r\n const reactiveValue = (value && typeof value === 'object') \r\n ? (rawToReactive.get(value) || value) \r\n : value;\r\n const reactiveKey = (key && typeof key === 'object') \r\n ? (rawToReactive.get(key) || key) \r\n : key;\r\n callback.call(thisArg, reactiveValue, reactiveKey, this);\r\n });\r\n };\r\n\r\n // keys() - works on Set, Map\r\n instrumentations.keys = function (this: any): IterableIterator<any> {\r\n const target = toRaw(this);\r\n track(getOrCreateDep(ITERATE_KEY));\r\n const innerIterator = target.keys();\r\n return createReactiveIterator(innerIterator, false);\r\n };\r\n\r\n // values() - works on Set, Map\r\n instrumentations.values = function (this: any): IterableIterator<any> {\r\n const target = toRaw(this);\r\n track(getOrCreateDep(ITERATE_KEY));\r\n const innerIterator = target.values();\r\n return createReactiveIterator(innerIterator, true);\r\n };\r\n\r\n // entries() - works on Set, Map\r\n instrumentations.entries = function (this: any): IterableIterator<any> {\r\n const target = toRaw(this);\r\n track(getOrCreateDep(ITERATE_KEY));\r\n const innerIterator = target.entries();\r\n return createReactiveEntriesIterator(innerIterator);\r\n };\r\n\r\n // [Symbol.iterator] - works on Set, Map\r\n instrumentations[Symbol.iterator] = function (this: any): IterableIterator<any> {\r\n const target = toRaw(this);\r\n track(getOrCreateDep(ITERATE_KEY));\r\n // Set uses values(), Map uses entries() for default iterator\r\n if (target instanceof Set) {\r\n return createReactiveIterator(target.values(), true);\r\n } else {\r\n return createReactiveEntriesIterator(target.entries());\r\n }\r\n };\r\n\r\n // ---- WRITE METHODS (trigger updates) ----\r\n\r\n // add() - works on Set, WeakSet\r\n instrumentations.add = function (this: any, value: unknown): any {\r\n const target = toRaw(this);\r\n const rawValue = toRaw(value);\r\n const hadKey = target.has(rawValue);\r\n target.add(rawValue);\r\n if (!hadKey) {\r\n // Trigger both the specific key and iteration\r\n const dep = depsMap.get(rawValue as string | symbol);\r\n if (dep) trigger(dep);\r\n const iterDep = depsMap.get(ITERATE_KEY);\r\n if (iterDep) trigger(iterDep);\r\n }\r\n return this; // Return the proxy, not raw\r\n };\r\n\r\n // set() - works on Map, WeakMap\r\n instrumentations.set = function (this: any, key: unknown, value: unknown): any {\r\n const target = toRaw(this);\r\n const rawKey = toRaw(key);\r\n const rawValue = toRaw(value);\r\n const hadKey = target.has(rawKey);\r\n const oldValue = target.get(rawKey);\r\n target.set(rawKey, rawValue);\r\n if (!hadKey) {\r\n // New key - trigger iteration\r\n const iterDep = depsMap.get(ITERATE_KEY);\r\n if (iterDep) trigger(iterDep);\r\n }\r\n if (!hadKey || !Object.is(oldValue, rawValue)) {\r\n // Value changed - trigger key dependency\r\n const dep = depsMap.get(rawKey as string | symbol);\r\n if (dep) trigger(dep);\r\n }\r\n return this; // Return the proxy, not raw\r\n };\r\n\r\n // delete() - works on Set, Map, WeakSet, WeakMap\r\n instrumentations.delete = function (this: any, key: unknown): boolean {\r\n const target = toRaw(this);\r\n const rawKey = toRaw(key);\r\n const hadKey = target.has(rawKey);\r\n const result = target.delete(rawKey);\r\n if (hadKey) {\r\n // Trigger both the specific key and iteration\r\n const dep = depsMap.get(rawKey as string | symbol);\r\n if (dep) trigger(dep);\r\n const iterDep = depsMap.get(ITERATE_KEY);\r\n if (iterDep) trigger(iterDep);\r\n }\r\n return result;\r\n };\r\n\r\n // clear() - works on Set, Map\r\n instrumentations.clear = function (this: any): void {\r\n const target = toRaw(this);\r\n const hadItems = target.size > 0;\r\n target.clear();\r\n if (hadItems) {\r\n // Trigger all dependencies\r\n for (const dep of depsMap.values()) {\r\n trigger(dep);\r\n }\r\n }\r\n };\r\n\r\n return instrumentations;\r\n}\r\n\r\n/**\r\n * Creates a reactive iterator that wraps values in reactive proxies.\r\n */\r\nfunction createReactiveIterator(innerIterator: IterableIterator<any>, wrapValues: boolean): IterableIterator<any> {\r\n return {\r\n next() {\r\n const { value, done } = innerIterator.next();\r\n if (done) {\r\n return { value: undefined, done: true };\r\n }\r\n const wrappedValue = wrapValues && value && typeof value === 'object'\r\n ? (rawToReactive.get(value) || value)\r\n : value;\r\n return { value: wrappedValue, done: false };\r\n },\r\n [Symbol.iterator]() {\r\n return this;\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Creates a reactive entries iterator that wraps both keys and values.\r\n */\r\nfunction createReactiveEntriesIterator(innerIterator: IterableIterator<[any, any]>): IterableIterator<[any, any]> {\r\n return {\r\n next() {\r\n const { value, done } = innerIterator.next();\r\n if (done) {\r\n return { value: undefined, done: true };\r\n }\r\n const [key, val] = value;\r\n const wrappedKey = key && typeof key === 'object' ? (rawToReactive.get(key) || key) : key;\r\n const wrappedVal = val && typeof val === 'object' ? (rawToReactive.get(val) || val) : val;\r\n return { value: [wrappedKey, wrappedVal] as [any, any], done: false };\r\n },\r\n [Symbol.iterator]() {\r\n return this;\r\n }\r\n };\r\n}\r\n","// ============================================================================\r\n// Signal - Reactive state primitives\r\n// ============================================================================\r\n\r\nimport type { ReactiveEffect, Signal, PrimitiveSignal, Primitive } from './types';\r\nimport { batch, track, trigger } from './effect';\r\nimport { \r\n isReactive, \r\n isCollection, \r\n isIterableCollection, \r\n shouldNotProxy,\r\n reactiveToRaw,\r\n rawToReactive,\r\n createCollectionInstrumentations,\r\n ITERATE_KEY\r\n} from './collections';\r\n\r\n/** Check if a value is a primitive type */\r\nfunction isPrimitive(value: unknown): value is Primitive {\r\n if (value === null || value === undefined) return true;\r\n const type = typeof value;\r\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'symbol' || type === 'bigint';\r\n}\r\n\r\nlet accessObserver: ((target: any, key: string | symbol) => void) | null = null;\r\n\r\n/** @internal Get the current access observer for computed/model integration */\r\nexport function getAccessObserver(): ((target: any, key: string | symbol) => void) | null {\r\n return accessObserver;\r\n}\r\n\r\nexport function detectAccess(selector: () => any): [any, string | symbol] | null {\r\n let result: [any, string | symbol] | null = null;\r\n const prev = accessObserver;\r\n\r\n // Capture only the FIRST access, ignore subsequent ones\r\n // This ensures that when accessing computed.value, we get the computed\r\n // object, not the underlying signals it depends on\r\n accessObserver = (target, key) => {\r\n if (result === null) {\r\n result = [target, key];\r\n }\r\n };\r\n\r\n try {\r\n selector();\r\n } finally {\r\n accessObserver = prev;\r\n }\r\n\r\n return result;\r\n}\r\n\r\nconst arrayInstrumentations: Record<string, Function> = {};\r\n['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].forEach(method => {\r\n arrayInstrumentations[method] = function (this: any, ...args: any[]) {\r\n let res;\r\n batch(() => {\r\n res = (Array.prototype as any)[method].apply(this, args);\r\n });\r\n return res;\r\n };\r\n});\r\n\r\n// Overload for primitive types - wraps in { value: T }, no $set (use .value instead)\r\nexport function signal<T extends Primitive>(target: T): PrimitiveSignal<T>;\r\n// Overload for object types - includes $set for replacing the whole object\r\nexport function signal<T extends object>(target: T): Signal<T>;\r\n// Implementation\r\nexport function signal<T>(target: T): PrimitiveSignal<T> | Signal<T & object> {\r\n // Handle primitive types by wrapping in { value: T }\r\n if (isPrimitive(target)) {\r\n return signal({ value: target }) as unknown as PrimitiveSignal<T>;\r\n }\r\n\r\n const objectTarget = target as T & object;\r\n\r\n // Skip exotic built-ins that can't be proxied (Date, RegExp, etc.)\r\n // These have internal slots and will throw errors if proxied\r\n if (shouldNotProxy(objectTarget)) {\r\n return objectTarget as Signal<T & object>;\r\n }\r\n\r\n // Check if already reactive\r\n if (isReactive(objectTarget)) {\r\n return objectTarget as Signal<T & object>;\r\n }\r\n\r\n // Check if we already have a reactive version of this raw object\r\n const existingProxy = rawToReactive.get(objectTarget);\r\n if (existingProxy) {\r\n return existingProxy as Signal<T & object>;\r\n }\r\n\r\n const depsMap = new Map<string | symbol, Set<ReactiveEffect>>();\r\n const reactiveCache = new WeakMap<object, any>();\r\n\r\n // Helper to get or create a dependency set for a key\r\n const getOrCreateDep = (key: string | symbol): Set<ReactiveEffect> => {\r\n let dep = depsMap.get(key);\r\n if (!dep) {\r\n dep = new Set<ReactiveEffect>();\r\n depsMap.set(key, dep);\r\n }\r\n return dep;\r\n };\r\n\r\n // Create collection instrumentations if this is a collection\r\n const collectionInstrumentations = isCollection(objectTarget) \r\n ? createCollectionInstrumentations(depsMap, getOrCreateDep)\r\n : null;\r\n\r\n const proxy = new Proxy(objectTarget, {\r\n get(obj, prop, receiver) {\r\n if (prop === '$set') {\r\n return (newValue: T & object) => {\r\n batch(() => {\r\n if (Array.isArray(obj) && Array.isArray(newValue)) {\r\n const len = newValue.length;\r\n for (let i = 0; i < len; i++) {\r\n Reflect.set(receiver, String(i), newValue[i]);\r\n }\r\n Reflect.set(receiver, 'length', len);\r\n } else {\r\n const newKeys = Object.keys(newValue);\r\n const oldKeys = Object.keys(obj);\r\n for (const key of newKeys) {\r\n Reflect.set(receiver, key, (newValue as any)[key]);\r\n }\r\n for (const key of oldKeys) {\r\n if (!(key in newValue)) {\r\n Reflect.deleteProperty(receiver, key);\r\n }\r\n }\r\n }\r\n });\r\n };\r\n }\r\n\r\n // Handle collection instrumentations (Set, Map, WeakSet, WeakMap)\r\n if (collectionInstrumentations) {\r\n // Special handling for 'size' getter\r\n if (prop === 'size' && isIterableCollection(obj)) {\r\n track(getOrCreateDep(ITERATE_KEY));\r\n return (obj as Set<any> | Map<any, any>).size;\r\n }\r\n \r\n // Check if this is an instrumented method\r\n if (prop in collectionInstrumentations) {\r\n const instrumented = collectionInstrumentations[prop];\r\n if (typeof instrumented === 'function') {\r\n return instrumented.bind(receiver);\r\n }\r\n return instrumented;\r\n }\r\n }\r\n\r\n if (Array.isArray(obj) && typeof prop === 'string' && arrayInstrumentations.hasOwnProperty(prop)) {\r\n return arrayInstrumentations[prop];\r\n }\r\n\r\n const value = Reflect.get(obj, prop);\r\n\r\n if (accessObserver) {\r\n accessObserver(receiver, prop);\r\n }\r\n\r\n // Track this property access (skip for collections - they use instrumentations)\r\n if (!collectionInstrumentations) {\r\n const dep = getOrCreateDep(prop);\r\n track(dep);\r\n }\r\n\r\n // If the value is an object, make it reactive too (with caching)\r\n // Skip exotic built-ins like Date, RegExp, etc. that have internal slots\r\n if (value && typeof value === 'object' && !shouldNotProxy(value)) {\r\n let cached = reactiveCache.get(value);\r\n if (!cached) {\r\n cached = signal(value);\r\n reactiveCache.set(value, cached);\r\n }\r\n return cached;\r\n }\r\n\r\n return value;\r\n },\r\n set(obj, prop, newValue) {\r\n const oldLength = Array.isArray(obj) ? obj.length : 0;\r\n const oldValue = Reflect.get(obj, prop);\r\n const result = Reflect.set(obj, prop, newValue);\r\n\r\n // Only trigger if value actually changed\r\n if (!Object.is(oldValue, newValue)) {\r\n const dep = depsMap.get(prop);\r\n if (dep) {\r\n trigger(dep);\r\n }\r\n\r\n // Special handling for Arrays\r\n if (Array.isArray(obj)) {\r\n // If we set an index and length changed, trigger length dependency\r\n if (prop !== 'length' && obj.length !== oldLength) {\r\n const lengthDep = depsMap.get('length');\r\n if (lengthDep) {\r\n trigger(lengthDep);\r\n }\r\n }\r\n // If we set length, trigger indices that are now out of bounds\r\n if (prop === 'length' && typeof newValue === 'number' && newValue < oldLength) {\r\n for (let i = newValue; i < oldLength; i++) {\r\n const idxDep = depsMap.get(String(i));\r\n if (idxDep) trigger(idxDep);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n deleteProperty(obj, prop) {\r\n const hasKey = Object.prototype.hasOwnProperty.call(obj, prop);\r\n const result = Reflect.deleteProperty(obj, prop);\r\n\r\n if (result && hasKey) {\r\n const dep = depsMap.get(prop);\r\n if (dep) {\r\n trigger(dep);\r\n }\r\n }\r\n return result;\r\n }\r\n }) as Signal<T & object>;\r\n\r\n // Store the raw ↔ reactive mappings\r\n reactiveToRaw.set(proxy, objectTarget);\r\n rawToReactive.set(objectTarget, proxy);\r\n\r\n return proxy;\r\n}\r\n","// ============================================================================\r\n// Watch - Reactive watchers with cleanup and options\r\n// ============================================================================\r\n\r\nimport type { WatchSource, WatchCallback, WatchOptions, WatchHandle } from './types';\r\nimport { effect } from './effect';\r\n\r\n/**\r\n * Deeply traverses an object to trigger reactive tracking on all nested properties.\r\n * @param value The value to traverse\r\n * @param depth Maximum depth to traverse (Infinity for unlimited, number for limited)\r\n * @param seen Set of already visited objects to prevent circular references\r\n */\r\nfunction traverse(value: unknown, depth: number = Infinity, seen: Set<unknown> = new Set()): unknown {\r\n // Don't traverse primitives, null, or if we've exceeded depth\r\n if (depth <= 0) return value;\r\n if (value === null || typeof value !== 'object') return value;\r\n \r\n // Prevent circular references\r\n if (seen.has(value)) return value;\r\n seen.add(value);\r\n \r\n if (Array.isArray(value)) {\r\n // Traverse array elements\r\n for (let i = 0; i < value.length; i++) {\r\n traverse(value[i], depth - 1, seen);\r\n }\r\n } else if (value instanceof Map) {\r\n // Traverse Map entries\r\n value.forEach((v, k) => {\r\n traverse(k, depth - 1, seen);\r\n traverse(v, depth - 1, seen);\r\n });\r\n } else if (value instanceof Set) {\r\n // Traverse Set values\r\n value.forEach(v => {\r\n traverse(v, depth - 1, seen);\r\n });\r\n } else {\r\n // Traverse object properties\r\n for (const key of Object.keys(value)) {\r\n traverse((value as Record<string, unknown>)[key], depth - 1, seen);\r\n }\r\n }\r\n \r\n return value;\r\n}\r\n\r\nexport function watch<T>(source: WatchSource<T>, cb: WatchCallback<T>, options?: WatchOptions): WatchHandle {\r\n let oldValue: T | undefined;\r\n let isFirst = true;\r\n let cleanupFn: (() => void) | null = null;\r\n let paused = false;\r\n let pendingValue: T | undefined;\r\n let hasPending = false;\r\n let stopped = false;\r\n\r\n // Determine traverse depth from deep option\r\n const deep = options?.deep;\r\n const traverseDepth = deep === true ? Infinity : (typeof deep === 'number' ? deep : 0);\r\n\r\n const runner = effect(() => {\r\n if (stopped) return;\r\n \r\n let newValue = typeof source === 'function' ? (source as () => T)() : source;\r\n \r\n // If deep watching, traverse the value to track nested properties\r\n if (traverseDepth > 0) {\r\n traverse(newValue, traverseDepth);\r\n }\r\n\r\n if (paused) {\r\n // Store pending value to process on resume\r\n pendingValue = newValue;\r\n hasPending = true;\r\n return;\r\n }\r\n\r\n if (isFirst) {\r\n if (options?.immediate) {\r\n if (cleanupFn) cleanupFn();\r\n cb(newValue, oldValue, (fn) => cleanupFn = fn);\r\n // If once option, stop after immediate callback\r\n if (options?.once) {\r\n stopped = true;\r\n // Schedule stop for next tick to allow effect to complete\r\n queueMicrotask(() => stop());\r\n }\r\n }\r\n isFirst = false;\r\n } else {\r\n if (cleanupFn) cleanupFn();\r\n cb(newValue, oldValue, (fn) => cleanupFn = fn);\r\n // If once option, stop after first callback\r\n if (options?.once) {\r\n stopped = true;\r\n // Schedule stop for next tick to allow effect to complete\r\n queueMicrotask(() => stop());\r\n }\r\n }\r\n oldValue = newValue;\r\n });\r\n\r\n const stop = () => {\r\n stopped = true;\r\n runner.stop();\r\n if (cleanupFn) cleanupFn();\r\n };\r\n\r\n const pause = () => {\r\n paused = true;\r\n };\r\n\r\n const resume = () => {\r\n if (!paused) return;\r\n paused = false;\r\n // If value changed while paused, trigger callback now\r\n if (hasPending && !Object.is(pendingValue, oldValue)) {\r\n if (cleanupFn) cleanupFn();\r\n cb(pendingValue as T, oldValue, (fn) => cleanupFn = fn);\r\n oldValue = pendingValue;\r\n }\r\n hasPending = false;\r\n pendingValue = undefined;\r\n };\r\n\r\n return Object.assign(stop, { stop, pause, resume });\r\n}\r\n","// ============================================================================\r\n// Computed Signals - Lazy, cached, reactive derived values\r\n// ============================================================================\r\n\r\nimport type { \r\n ReactiveEffect, \r\n Computed, \r\n WritableComputed, \r\n ComputedGetter, \r\n ComputedSetter, \r\n WritableComputedOptions \r\n} from './types';\r\nimport { ComputedSymbol } from './types';\r\nimport { cleanup, track, trigger, setActiveEffect, getActiveEffect } from './effect';\r\nimport { getAccessObserver } from './signal';\r\n\r\n/**\r\n * Creates a computed signal that lazily derives a value from other reactive sources.\r\n * \r\n * Performance characteristics:\r\n * - Lazy: Only computes when accessed\r\n * - Cached: Returns cached value if dependencies haven't changed\r\n * - Minimal overhead: Uses dirty flag instead of always running getter\r\n * \r\n * @example\r\n * ```ts\r\n * const count = signal({ n: 0 });\r\n * const doubled = computed(() => count.n * 2);\r\n * \r\n * console.log(doubled.value); // 0\r\n * count.n = 5;\r\n * console.log(doubled.value); // 10\r\n * ```\r\n */\r\nexport function computed<T>(getter: ComputedGetter<T>): Computed<T>;\r\nexport function computed<T>(options: WritableComputedOptions<T>): WritableComputed<T>;\r\nexport function computed<T>(\r\n getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>\r\n): Computed<T> | WritableComputed<T> {\r\n let getter: ComputedGetter<T>;\r\n let setter: ComputedSetter<T> | undefined;\r\n\r\n if (typeof getterOrOptions === 'function') {\r\n getter = getterOrOptions;\r\n } else {\r\n getter = getterOrOptions.get;\r\n setter = getterOrOptions.set;\r\n }\r\n\r\n const subscribers = new Set<ReactiveEffect>();\r\n let cachedValue: T;\r\n let dirty = true;\r\n\r\n // Internal effect for dependency tracking\r\n const computedEffect: ReactiveEffect = function () {\r\n if (!dirty) {\r\n dirty = true;\r\n trigger(subscribers);\r\n }\r\n } as ReactiveEffect;\r\n computedEffect.deps = [];\r\n\r\n const computeValue = (): T => {\r\n cleanup(computedEffect);\r\n const prevEffect = getActiveEffect();\r\n setActiveEffect(computedEffect);\r\n try {\r\n cachedValue = getter();\r\n dirty = false;\r\n return cachedValue;\r\n } finally {\r\n setActiveEffect(prevEffect);\r\n }\r\n };\r\n\r\n // The computed object with .value accessor\r\n const computedObj = {\r\n [ComputedSymbol]: true as const,\r\n get value(): T {\r\n // Notify access observer for model binding integration (detectAccess)\r\n const observer = getAccessObserver();\r\n if (observer) {\r\n observer(computedObj, 'value');\r\n }\r\n track(subscribers);\r\n return dirty ? computeValue() : cachedValue;\r\n },\r\n };\r\n\r\n // Add setter if provided (writable computed)\r\n if (setter) {\r\n Object.defineProperty(computedObj, 'value', {\r\n get(): T {\r\n // Notify access observer for model binding integration (detectAccess)\r\n const observer = getAccessObserver();\r\n if (observer) {\r\n observer(computedObj, 'value');\r\n }\r\n track(subscribers);\r\n return dirty ? computeValue() : cachedValue;\r\n },\r\n set(newValue: T) {\r\n setter!(newValue);\r\n },\r\n enumerable: true,\r\n configurable: false,\r\n });\r\n return computedObj as WritableComputed<T>;\r\n }\r\n\r\n return computedObj as Computed<T>;\r\n}\r\n\r\n/**\r\n * Type guard to check if a value is a computed signal.\r\n * \r\n * @example\r\n * ```ts\r\n * const doubled = computed(() => count.value * 2);\r\n * console.log(isComputed(doubled)); // true\r\n * console.log(isComputed({ value: 1 })); // false\r\n * ```\r\n */\r\nexport function isComputed(value: unknown): value is Computed<unknown> {\r\n return value !== null && typeof value === 'object' && ComputedSymbol in value;\r\n}\r\n"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Signal, PrimitiveSignal, Primitive } from './types';
2
+ /** @internal Get the current access observer for computed/model integration */
3
+ export declare function getAccessObserver(): ((target: any, key: string | symbol) => void) | null;
4
+ export declare function detectAccess(selector: () => any): [any, string | symbol] | null;
5
+ export declare function signal<T extends Primitive>(target: T): PrimitiveSignal<T>;
6
+ export declare function signal<T extends object>(target: T): Signal<T>;
7
+ //# sourceMappingURL=signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkB,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAsBlF,+EAA+E;AAC/E,wBAAgB,iBAAiB,IAAI,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAExF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,IAAI,CAoB/E;AAcD,wBAAgB,MAAM,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;AAE3E,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,63 @@
1
+ /** Symbol to identify computed values */
2
+ export declare const ComputedSymbol: unique symbol;
3
+ export type EffectFn = () => void;
4
+ export interface EffectRunner<T = void> {
5
+ (): T;
6
+ stop: () => void;
7
+ }
8
+ export interface ReactiveEffect extends EffectFn {
9
+ deps: Set<ReactiveEffect>[];
10
+ }
11
+ /**
12
+ * Widens literal types to their base primitive types.
13
+ * e.g., `false` → `boolean`, `"hello"` → `string`, `123` → `number`
14
+ */
15
+ export type Widen<T> = T extends boolean ? boolean : T extends number ? number : T extends string ? string : T extends bigint ? bigint : T extends symbol ? symbol : T;
16
+ /** Type for object/array signals - includes $set for replacing the whole object */
17
+ export type Signal<T> = T & {
18
+ $set: (newValue: T) => void;
19
+ };
20
+ /** Type for primitive values that get wrapped in { value: T } - no $set, use .value instead */
21
+ export type PrimitiveSignal<T> = {
22
+ value: Widen<T>;
23
+ };
24
+ /** Primitive types that will be wrapped in { value: T } */
25
+ export type Primitive = string | number | boolean | symbol | bigint | null | undefined;
26
+ export type WatchSource<T = any> = T | (() => T);
27
+ export type WatchCallback<V = any, OV = any> = (value: V, oldValue: OV, onCleanup: (fn: () => void) => void) => any;
28
+ export interface WatchOptions<Immediate = boolean> {
29
+ immediate?: Immediate;
30
+ deep?: boolean | number;
31
+ once?: boolean;
32
+ }
33
+ export interface WatchHandle {
34
+ (): void;
35
+ stop: () => void;
36
+ pause: () => void;
37
+ resume: () => void;
38
+ }
39
+ /** A read-only computed signal - access via .value */
40
+ export interface Computed<T> {
41
+ readonly value: T;
42
+ readonly [ComputedSymbol]: true;
43
+ }
44
+ /** A writable computed signal - access and set via .value */
45
+ export interface WritableComputed<T> {
46
+ value: T;
47
+ readonly [ComputedSymbol]: true;
48
+ }
49
+ export interface ComputedGetter<T> {
50
+ (): T;
51
+ }
52
+ export interface ComputedSetter<T> {
53
+ (value: T): void;
54
+ }
55
+ export interface WritableComputedOptions<T> {
56
+ get: ComputedGetter<T>;
57
+ set: ComputedSetter<T>;
58
+ }
59
+ export type EffectScope = {
60
+ run<T>(fn: () => T): T | undefined;
61
+ stop(fromParent?: boolean): void;
62
+ };
63
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { WatchSource, WatchCallback, WatchOptions, WatchHandle } from './types';
2
+ export declare function watch<T>(source: WatchSource<T>, cb: WatchCallback<T>, options?: WatchOptions): WatchHandle;
3
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AA4CrF,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CA+E1G"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigx/reactivity",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Reactivity system for SignalX",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -33,11 +33,12 @@
33
33
  "url": "https://github.com/signalxjs/core/issues"
34
34
  },
35
35
  "devDependencies": {
36
- "rolldown": "^1.0.0-beta.52",
37
- "typescript": "^5.9.3"
36
+ "typescript": "^5.9.3",
37
+ "vite": "^8.0.0-beta.9",
38
+ "@sigx/vite": "^0.1.6"
38
39
  },
39
40
  "scripts": {
40
- "build": "rolldown -c && tsc --emitDeclarationOnly",
41
- "dev": "rolldown -c -w"
41
+ "build": "vite build && tsc --emitDeclarationOnly",
42
+ "dev": "vite build --watch"
42
43
  }
43
44
  }