@sigx/reactivity 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +202 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type EffectFn = () => void;
|
|
2
|
+
export interface ReactiveEffect extends EffectFn {
|
|
3
|
+
deps: Set<ReactiveEffect>[];
|
|
4
|
+
}
|
|
5
|
+
export declare function batch(fn: () => void): void;
|
|
6
|
+
export type Signal<T> = T & {
|
|
7
|
+
$set: (newValue: T) => void;
|
|
8
|
+
};
|
|
9
|
+
export declare function detectAccess(selector: () => any): [any, string | symbol] | null;
|
|
10
|
+
export declare function untrack<T>(fn: () => T): T;
|
|
11
|
+
export declare function signal<T extends object>(target: T): Signal<T>;
|
|
12
|
+
export declare function effect(fn: EffectFn): () => void;
|
|
13
|
+
export type WatchSource<T = any> = T | (() => T);
|
|
14
|
+
export type WatchCallback<V = any, OV = any> = (value: V, oldValue: OV, onCleanup: (fn: () => void) => void) => any;
|
|
15
|
+
export interface WatchOptions<Immediate = boolean> {
|
|
16
|
+
immediate?: Immediate;
|
|
17
|
+
deep?: boolean | number;
|
|
18
|
+
once?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface WatchHandle {
|
|
21
|
+
(): void;
|
|
22
|
+
pause: () => void;
|
|
23
|
+
resume: () => void;
|
|
24
|
+
stop: () => void;
|
|
25
|
+
}
|
|
26
|
+
export declare function watch<T>(source: WatchSource<T>, cb: WatchCallback<T>, options?: WatchOptions): WatchHandle;
|
|
27
|
+
export type EffectScope = {
|
|
28
|
+
run<T>(fn: () => T): T | undefined;
|
|
29
|
+
stop(fromParent?: boolean): void;
|
|
30
|
+
};
|
|
31
|
+
export declare function effectScope(detached?: boolean): EffectScope;
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,cAAe,SAAQ,QAAQ;IAC5C,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;CAC/B;AAMD,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,IAAI,QAcnC;AA0CD,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,MAAM,IAAI,CAE/C;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,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;CACpB;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,CAgC1G;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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
//#region src/index.ts
|
|
2
|
+
let activeEffect = null;
|
|
3
|
+
let batchDepth = 0;
|
|
4
|
+
const pendingEffects = /* @__PURE__ */ new Set();
|
|
5
|
+
function batch(fn) {
|
|
6
|
+
batchDepth++;
|
|
7
|
+
try {
|
|
8
|
+
fn();
|
|
9
|
+
} finally {
|
|
10
|
+
batchDepth--;
|
|
11
|
+
if (batchDepth === 0) {
|
|
12
|
+
const effects = Array.from(pendingEffects);
|
|
13
|
+
pendingEffects.clear();
|
|
14
|
+
for (const effect$1 of effects) effect$1();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function runEffect(fn) {
|
|
19
|
+
const effect$1 = function() {
|
|
20
|
+
cleanup(effect$1);
|
|
21
|
+
activeEffect = effect$1;
|
|
22
|
+
fn();
|
|
23
|
+
activeEffect = null;
|
|
24
|
+
};
|
|
25
|
+
effect$1.deps = [];
|
|
26
|
+
effect$1();
|
|
27
|
+
return () => cleanup(effect$1);
|
|
28
|
+
}
|
|
29
|
+
function cleanup(effect$1) {
|
|
30
|
+
if (!effect$1.deps) return;
|
|
31
|
+
for (const dep of effect$1.deps) dep.delete(effect$1);
|
|
32
|
+
effect$1.deps.length = 0;
|
|
33
|
+
}
|
|
34
|
+
function track(depSet) {
|
|
35
|
+
if (!activeEffect) return;
|
|
36
|
+
depSet.add(activeEffect);
|
|
37
|
+
activeEffect.deps.push(depSet);
|
|
38
|
+
}
|
|
39
|
+
function trigger(depSet) {
|
|
40
|
+
const effects = Array.from(depSet);
|
|
41
|
+
for (const effect$1 of effects) if (batchDepth > 0) pendingEffects.add(effect$1);
|
|
42
|
+
else effect$1();
|
|
43
|
+
}
|
|
44
|
+
let accessObserver = null;
|
|
45
|
+
function detectAccess(selector) {
|
|
46
|
+
let result = null;
|
|
47
|
+
const prev = accessObserver;
|
|
48
|
+
accessObserver = (target, key) => {
|
|
49
|
+
result = [target, key];
|
|
50
|
+
};
|
|
51
|
+
try {
|
|
52
|
+
selector();
|
|
53
|
+
} finally {
|
|
54
|
+
accessObserver = prev;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
function untrack(fn) {
|
|
59
|
+
const prev = activeEffect;
|
|
60
|
+
activeEffect = null;
|
|
61
|
+
try {
|
|
62
|
+
return fn();
|
|
63
|
+
} finally {
|
|
64
|
+
activeEffect = prev;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function signal(target) {
|
|
68
|
+
const depsMap = /* @__PURE__ */ new Map();
|
|
69
|
+
const reactiveCache = /* @__PURE__ */ new WeakMap();
|
|
70
|
+
return new Proxy(target, {
|
|
71
|
+
get(obj, prop, receiver) {
|
|
72
|
+
if (prop === "$set") return (newValue) => {
|
|
73
|
+
batch(() => {
|
|
74
|
+
if (Array.isArray(obj) && Array.isArray(newValue)) {
|
|
75
|
+
const len = newValue.length;
|
|
76
|
+
for (let i = 0; i < len; i++) Reflect.set(receiver, String(i), newValue[i]);
|
|
77
|
+
Reflect.set(receiver, "length", len);
|
|
78
|
+
} else {
|
|
79
|
+
const newKeys = Object.keys(newValue);
|
|
80
|
+
const oldKeys = Object.keys(obj);
|
|
81
|
+
for (const key of newKeys) Reflect.set(receiver, key, newValue[key]);
|
|
82
|
+
for (const key of oldKeys) if (!(key in newValue)) Reflect.deleteProperty(receiver, key);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
if (Array.isArray(obj) && typeof prop === "string" && arrayInstrumentations.hasOwnProperty(prop)) return arrayInstrumentations[prop];
|
|
87
|
+
const value = Reflect.get(obj, prop);
|
|
88
|
+
if (accessObserver) accessObserver(receiver, prop);
|
|
89
|
+
let dep = depsMap.get(prop);
|
|
90
|
+
if (!dep) {
|
|
91
|
+
dep = /* @__PURE__ */ new Set();
|
|
92
|
+
depsMap.set(prop, dep);
|
|
93
|
+
}
|
|
94
|
+
track(dep);
|
|
95
|
+
if (value && typeof value === "object") {
|
|
96
|
+
let cached = reactiveCache.get(value);
|
|
97
|
+
if (!cached) {
|
|
98
|
+
cached = signal(value);
|
|
99
|
+
reactiveCache.set(value, cached);
|
|
100
|
+
}
|
|
101
|
+
return cached;
|
|
102
|
+
}
|
|
103
|
+
return value;
|
|
104
|
+
},
|
|
105
|
+
set(obj, prop, newValue) {
|
|
106
|
+
const oldLength = Array.isArray(obj) ? obj.length : 0;
|
|
107
|
+
const oldValue = Reflect.get(obj, prop);
|
|
108
|
+
const result = Reflect.set(obj, prop, newValue);
|
|
109
|
+
if (!Object.is(oldValue, newValue)) {
|
|
110
|
+
const dep = depsMap.get(prop);
|
|
111
|
+
if (dep) trigger(dep);
|
|
112
|
+
if (Array.isArray(obj)) {
|
|
113
|
+
if (prop !== "length" && obj.length !== oldLength) {
|
|
114
|
+
const lengthDep = depsMap.get("length");
|
|
115
|
+
if (lengthDep) trigger(lengthDep);
|
|
116
|
+
}
|
|
117
|
+
if (prop === "length" && typeof newValue === "number" && newValue < oldLength) for (let i = newValue; i < oldLength; i++) {
|
|
118
|
+
const idxDep = depsMap.get(String(i));
|
|
119
|
+
if (idxDep) trigger(idxDep);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
124
|
+
},
|
|
125
|
+
deleteProperty(obj, prop) {
|
|
126
|
+
const hasKey = Object.prototype.hasOwnProperty.call(obj, prop);
|
|
127
|
+
const result = Reflect.deleteProperty(obj, prop);
|
|
128
|
+
if (result && hasKey) {
|
|
129
|
+
const dep = depsMap.get(prop);
|
|
130
|
+
if (dep) trigger(dep);
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
function effect(fn) {
|
|
137
|
+
return runEffect(fn);
|
|
138
|
+
}
|
|
139
|
+
const arrayInstrumentations = {};
|
|
140
|
+
[
|
|
141
|
+
"push",
|
|
142
|
+
"pop",
|
|
143
|
+
"shift",
|
|
144
|
+
"unshift",
|
|
145
|
+
"splice",
|
|
146
|
+
"sort",
|
|
147
|
+
"reverse"
|
|
148
|
+
].forEach((method) => {
|
|
149
|
+
arrayInstrumentations[method] = function(...args) {
|
|
150
|
+
let res;
|
|
151
|
+
batch(() => {
|
|
152
|
+
res = Array.prototype[method].apply(this, args);
|
|
153
|
+
});
|
|
154
|
+
return res;
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
function watch(source, cb, options) {
|
|
158
|
+
let oldValue;
|
|
159
|
+
let isFirst = true;
|
|
160
|
+
let cleanupFn = null;
|
|
161
|
+
const runner = effect(() => {
|
|
162
|
+
const newValue = typeof source === "function" ? source() : source;
|
|
163
|
+
if (isFirst) {
|
|
164
|
+
if (options?.immediate) {
|
|
165
|
+
if (cleanupFn) cleanupFn();
|
|
166
|
+
cb(newValue, oldValue, (fn) => cleanupFn = fn);
|
|
167
|
+
}
|
|
168
|
+
isFirst = false;
|
|
169
|
+
} else {
|
|
170
|
+
if (cleanupFn) cleanupFn();
|
|
171
|
+
cb(newValue, oldValue, (fn) => cleanupFn = fn);
|
|
172
|
+
}
|
|
173
|
+
oldValue = newValue;
|
|
174
|
+
});
|
|
175
|
+
const stop = () => {
|
|
176
|
+
runner();
|
|
177
|
+
if (cleanupFn) cleanupFn();
|
|
178
|
+
};
|
|
179
|
+
const handle = stop;
|
|
180
|
+
handle.stop = stop;
|
|
181
|
+
handle.pause = () => {};
|
|
182
|
+
handle.resume = () => {};
|
|
183
|
+
return handle;
|
|
184
|
+
}
|
|
185
|
+
function effectScope(detached) {
|
|
186
|
+
const effects = [];
|
|
187
|
+
let active = true;
|
|
188
|
+
return {
|
|
189
|
+
run(fn) {
|
|
190
|
+
if (!active) return void 0;
|
|
191
|
+
return fn();
|
|
192
|
+
},
|
|
193
|
+
stop() {
|
|
194
|
+
active = false;
|
|
195
|
+
effects.forEach((e) => e());
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
//#endregion
|
|
201
|
+
export { batch, detectAccess, effect, effectScope, signal, untrack, watch };
|
|
202
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["activeEffect: ReactiveEffect | null","effect","effect: ReactiveEffect","accessObserver: ((target: any, key: string | symbol) => void) | null","result: [any, string | symbol] | null","arrayInstrumentations: Record<string, Function>","oldValue: T | undefined","cleanupFn: (() => void) | null","effects: (() => void)[]"],"sources":["../src/index.ts"],"sourcesContent":["// signals.ts\r\n\r\nexport type EffectFn = () => void;\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): () => void {\r\n const effect: ReactiveEffect = function () {\r\n cleanup(effect);\r\n activeEffect = effect;\r\n fn();\r\n activeEffect = null;\r\n } as ReactiveEffect;\r\n\r\n effect.deps = [];\r\n effect();\r\n\r\n // disposer\r\n return () => cleanup(effect);\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): () => void {\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; // stop\r\n pause: () => void;\r\n resume: () => void;\r\n stop: () => 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\r\n const runner = effect(() => {\r\n const newValue = typeof source === 'function' ? (source as () => T)() : source;\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();\r\n if (cleanupFn) cleanupFn();\r\n };\r\n\r\n const handle = stop as unknown as WatchHandle;\r\n handle.stop = stop;\r\n handle.pause = () => { }; // Not implemented\r\n handle.resume = () => { }; // Not implemented\r\n\r\n return handle;\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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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sigx/reactivity",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Reactivity system for SignalX",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "rolldown -c && tsc --emitDeclarationOnly",
|
|
19
|
+
"dev": "rolldown -c -w"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"sigx",
|
|
23
|
+
"reactivity",
|
|
24
|
+
"signals",
|
|
25
|
+
"reactive",
|
|
26
|
+
"state-management"
|
|
27
|
+
],
|
|
28
|
+
"author": "Andreas Ekdahl",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/signalxjs/core.git",
|
|
33
|
+
"directory": "packages/reactivity"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/signalxjs",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/signalxjs/core/issues"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"rolldown": "^1.0.0-beta.52",
|
|
41
|
+
"typescript": "^5.9.3"
|
|
42
|
+
}
|
|
43
|
+
}
|