@sigx/reactivity 0.1.4 → 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.
- package/dist/collections.d.ts +37 -0
- package/dist/collections.d.ts.map +1 -0
- package/dist/computed.d.ts +33 -0
- package/dist/computed.d.ts.map +1 -0
- package/dist/effect.d.ts +15 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/index.d.ts +7 -35
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +378 -69
- package/dist/index.js.map +1 -1
- package/dist/signal.d.ts +7 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/watch.d.ts +3 -0
- package/dist/watch.d.ts.map +1 -0
- package/package.json +6 -5
|
@@ -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"}
|
package/dist/effect.d.ts
ADDED
|
@@ -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
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
export
|
|
7
|
-
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
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
|
-
|
|
1
|
+
const ComputedSymbol = Symbol("computed");
|
|
2
2
|
let activeEffect = null;
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
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
|
|
32
|
-
|
|
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
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
42
|
-
const effects =
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
-
if (!
|
|
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
|
|
139
|
-
|
|
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
|
-
|
|
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
|
|
210
|
-
|
|
211
|
-
let
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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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"}
|
package/dist/signal.d.ts
ADDED
|
@@ -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"}
|
package/dist/types.d.ts
ADDED
|
@@ -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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"}
|
package/dist/watch.d.ts
ADDED
|
@@ -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.
|
|
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
|
-
"
|
|
37
|
-
"
|
|
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": "
|
|
41
|
-
"dev": "
|
|
41
|
+
"build": "vite build && tsc --emitDeclarationOnly",
|
|
42
|
+
"dev": "vite build --watch"
|
|
42
43
|
}
|
|
43
44
|
}
|