Launch Week Day 3: Introducing Organization Notifications in Socket.Learn More
Socket
Book a DemoSign in
Socket

alien-signals

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

alien-signals - npm Package Compare versions

Comparing version
1.1.0-alpha.3
to
2.0.0-alpha.0
+172
-183
cjs/index.cjs

@@ -42,14 +42,18 @@ "use strict";

SubscriberFlags2[SubscriberFlags2["Tracking"] = 4] = "Tracking";
SubscriberFlags2[SubscriberFlags2["Notified"] = 8] = "Notified";
SubscriberFlags2[SubscriberFlags2["Recursed"] = 16] = "Recursed";
SubscriberFlags2[SubscriberFlags2["Dirty"] = 32] = "Dirty";
SubscriberFlags2[SubscriberFlags2["PendingComputed"] = 64] = "PendingComputed";
SubscriberFlags2[SubscriberFlags2["PendingEffect"] = 128] = "PendingEffect";
SubscriberFlags2[SubscriberFlags2["Cold"] = 256] = "Cold";
SubscriberFlags2[SubscriberFlags2["Propagated"] = 224] = "Propagated";
SubscriberFlags2[SubscriberFlags2["Recursed"] = 8] = "Recursed";
SubscriberFlags2[SubscriberFlags2["Dirty"] = 16] = "Dirty";
SubscriberFlags2[SubscriberFlags2["Pending"] = 32] = "Pending";
SubscriberFlags2[SubscriberFlags2["Cold"] = 64] = "Cold";
SubscriberFlags2[SubscriberFlags2["Propagated"] = 48] = "Propagated";
return SubscriberFlags2;
})(SubscriberFlags || {});
function createReactiveSystem({
updateComputed,
notifyEffect: notifyEffect2
computed: {
update: updateComputed2,
onUnwatched: onUnwatchedComputed = () => {
}
},
effect: {
notify: notifyEffect2
}
}) {

@@ -93,3 +97,3 @@ let queuedEffects;

propagate(link2) {
let targetFlag = 32 /* Dirty */;
let targetFlag = 16 /* Dirty */ | 32 /* Pending */;
let subs = link2;

@@ -100,3 +104,3 @@ let stack = 0;

const subFlags = sub.flags;
if (!(subFlags & (4 /* Tracking */ | 16 /* Recursed */ | 224 /* Propagated */)) && (sub.flags = subFlags | targetFlag | 8 /* Notified */, true) || subFlags & 16 /* Recursed */ && !(subFlags & 4 /* Tracking */) && (sub.flags = subFlags & ~16 /* Recursed */ | targetFlag | 8 /* Notified */, true) || !(subFlags & 224 /* Propagated */) && isValidLink(link2, sub) && (sub.flags = subFlags | 16 /* Recursed */ | targetFlag | 8 /* Notified */, sub.subs !== void 0)) {
if (!(subFlags & (4 /* Tracking */ | 8 /* Recursed */ | 48 /* Propagated */)) && (sub.flags = subFlags | targetFlag, true) || subFlags & 8 /* Recursed */ && !(subFlags & 4 /* Tracking */) && (sub.flags = subFlags & ~8 /* Recursed */ | targetFlag, true) || !(subFlags & 48 /* Propagated */) && isValidLink(link2, sub) && (sub.flags = subFlags | 8 /* Recursed */ | targetFlag, sub.subs !== void 0)) {
const subSubs = sub.subs;

@@ -107,8 +111,7 @@ if (subSubs !== void 0) {

link2 = subs = subSubs;
targetFlag = 64 /* PendingComputed */;
++stack;
} else {
link2 = subSubs;
targetFlag = subFlags & 2 /* Effect */ ? 128 /* PendingEffect */ : 64 /* PendingComputed */;
}
targetFlag = 32 /* Pending */;
continue;

@@ -125,4 +128,4 @@ }

} else if (!(subFlags & (4 /* Tracking */ | targetFlag))) {
sub.flags = subFlags | targetFlag | 8 /* Notified */;
if ((subFlags & (2 /* Effect */ | 8 /* Notified */)) === 2 /* Effect */) {
sub.flags = subFlags | targetFlag;
if (subFlags & 2 /* Effect */ && !isQueued(sub)) {
if (queuedEffectsTail !== void 0) {

@@ -135,3 +138,3 @@ queuedEffectsTail.depsTail.nextDep = sub.deps;

}
} else if (!(subFlags & targetFlag) && subFlags & 224 /* Propagated */ && isValidLink(link2, sub)) {
} else if (!(subFlags & targetFlag) && subFlags & 48 /* Propagated */ && isValidLink(link2, sub)) {
sub.flags = subFlags | targetFlag;

@@ -141,3 +144,3 @@ }

subs = link2;
targetFlag = stack ? 64 /* PendingComputed */ : 32 /* Dirty */;
targetFlag = stack ? 32 /* Pending */ : 16 /* Dirty */ | 32 /* Pending */;
continue;

@@ -153,3 +156,3 @@ }

subs = link2;
targetFlag = stack ? 64 /* PendingComputed */ : 32 /* Dirty */;
targetFlag = stack ? 32 /* Pending */ : 16 /* Dirty */ | 32 /* Pending */;
continue top;

@@ -171,3 +174,3 @@ }

sub.depsTail = void 0;
sub.flags = sub.flags & ~(8 /* Notified */ | 16 /* Recursed */ | 224 /* Propagated */) | 4 /* Tracking */;
sub.flags = sub.flags & ~(8 /* Recursed */ | 48 /* Propagated */) | 4 /* Tracking */;
},

@@ -197,44 +200,77 @@ /**

/**
* Updates the dirty flag for the given subscriber based on its dependencies.
* Recursively checks and updates all computed subscribers marked as pending.
*
* If the subscriber has any pending computeds, this function sets the Dirty flag
* and returns `true`. Otherwise, it clears the PendingComputed flag and returns `false`.
* It traverses the linked structure using a stack mechanism. For each computed
* subscriber in a pending state, updateComputed is called and shallowPropagate
* is triggered if a value changes. Returns whether any updates occurred.
*
* @param sub - The subscriber to update.
* @param flags - The current flag set for this subscriber.
* @returns `true` if the subscriber is marked as Dirty; otherwise `false`.
* @param link - The starting link representing a sequence of pending computeds.
* @returns `true` if a computed was updated, otherwise `false`.
*/
updateDirtyFlag(sub, flags) {
if (checkDirty(sub.deps)) {
sub.flags = flags | 32 /* Dirty */;
return true;
} else {
sub.flags = flags & ~64 /* PendingComputed */;
return false;
}
checkDirty(link2) {
let stack = 0;
let dirty;
top: do {
dirty = false;
const dep = link2.dep;
if (dep.version !== link2.version) {
dirty = true;
} else if ("flags" in dep) {
const depFlags = dep.flags;
if ((depFlags & (1 /* Computed */ | 16 /* Dirty */)) === (1 /* Computed */ | 16 /* Dirty */)) {
if (updateComputed2(dep)) {
dirty = true;
}
} else if ((depFlags & (1 /* Computed */ | 32 /* Pending */)) === (1 /* Computed */ | 32 /* Pending */)) {
const depSubs = dep.subs;
if (depSubs.nextSub !== void 0) {
depSubs.prevSub = link2;
}
link2 = dep.deps;
++stack;
continue;
}
}
if (!dirty && link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue;
}
if (stack) {
let sub = link2.sub;
do {
--stack;
const subSubs = sub.subs;
if (dirty) {
if (updateComputed2(sub)) {
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
sub = link2.sub;
} else {
sub = subSubs.sub;
}
continue;
}
} else {
sub.flags &= ~32 /* Pending */;
}
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
if (link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue top;
}
sub = link2.sub;
} else {
if ((link2 = subSubs.nextDep) !== void 0) {
continue top;
}
sub = subSubs.sub;
}
dirty = false;
} while (stack);
}
return dirty;
} while (true);
},
/**
* Updates the computed subscriber if necessary before its value is accessed.
*
* If the subscriber is marked Dirty or PendingComputed, this function runs
* the provided updateComputed logic and triggers a shallowPropagate for any
* downstream subscribers if an actual update occurs.
*
* @param computed - The computed subscriber to update.
* @param flags - The current flag set for this subscriber.
*/
processComputedUpdate(computed2, flags) {
if (flags & 256 /* Cold */) {
warming(computed2, flags, computed2.deps);
flags = computed2.flags;
}
if (flags & 32 /* Dirty */) {
updateComputed(computed2);
} else if (checkDirty(computed2.deps)) {
updateComputed(computed2);
} else {
computed2.flags = flags & ~64 /* PendingComputed */;
}
},
/**
* Ensures all pending internal effects for the given subscriber are processed.

@@ -250,14 +286,11 @@ *

*/
processPendingInnerEffects(sub, flags) {
if (flags & 128 /* PendingEffect */) {
sub.flags = flags & ~128 /* PendingEffect */;
let link2 = sub.deps;
do {
const dep = link2.dep;
if ("flags" in dep && dep.flags & 2 /* Effect */ && dep.flags & 224 /* Propagated */) {
notifyEffect2(dep);
}
link2 = link2.nextDep;
} while (link2 !== void 0);
}
processPendingInnerEffects(sub) {
let link2 = sub.deps;
do {
const dep = link2.dep;
if ("flags" in dep && dep.flags & 2 /* Effect */ && dep.flags & 48 /* Propagated */) {
notifyEffect2(dep);
}
link2 = link2.nextDep;
} while (link2 !== void 0);
},

@@ -283,8 +316,18 @@ /**

}
if (!notifyEffect2(effect2)) {
effect2.flags &= ~8 /* Notified */;
}
notifyEffect2(effect2);
}
},
warming: warming2,
cooling: cooling2
};
function isQueued(effect2) {
let queuedEffect = queuedEffects;
while (queuedEffect !== void 0) {
if (queuedEffect === effect2) {
return true;
}
queuedEffect = queuedEffect.depsTail.nextDep?.sub;
}
};
return false;
}
function linkNewDep(dep, sub, nextDep, depsTail) {

@@ -315,67 +358,2 @@ const newLink = {

}
function checkDirty(link2) {
let stack = 0;
let dirty;
top: do {
dirty = false;
const dep = link2.dep;
if (dep.version !== link2.version) {
dirty = true;
} else if ("flags" in dep) {
const depFlags = dep.flags;
if ((depFlags & (1 /* Computed */ | 32 /* Dirty */)) === (1 /* Computed */ | 32 /* Dirty */)) {
if (updateComputed(dep)) {
dirty = true;
}
} else if ((depFlags & (1 /* Computed */ | 64 /* PendingComputed */)) === (1 /* Computed */ | 64 /* PendingComputed */)) {
const depSubs = dep.subs;
if (depSubs.nextSub !== void 0) {
depSubs.prevSub = link2;
}
link2 = dep.deps;
++stack;
continue;
}
}
if (!dirty && link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue;
}
if (stack) {
let sub = link2.sub;
do {
--stack;
const subSubs = sub.subs;
if (dirty) {
if (updateComputed(sub)) {
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
sub = link2.sub;
} else {
sub = subSubs.sub;
}
continue;
}
} else {
sub.flags &= ~64 /* PendingComputed */;
}
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
if (link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue top;
}
sub = link2.sub;
} else {
if ((link2 = subSubs.nextDep) !== void 0) {
continue top;
}
sub = subSubs.sub;
}
dirty = false;
} while (stack);
}
return dirty;
} while (true);
}
function isValidLink(checkLink, sub) {

@@ -421,3 +399,3 @@ const depsTail = sub.depsTail;

} else if (depFlags & 1 /* Computed */) {
cooling(dep, depFlags, depDeps);
onUnwatchedComputed(dep);
}

@@ -428,4 +406,5 @@ }

}
function warming(sub, flags, link2) {
sub.flags = flags & ~256 /* Cold */;
function warming2(sub) {
sub.flags &= ~64 /* Cold */;
let link2 = sub.deps;
do {

@@ -444,4 +423,4 @@ const dep = link2.dep;

const depFlags = dep.flags;
if (depFlags & 256 /* Cold */) {
warming(dep, depFlags, dep.deps);
if (depFlags & 64 /* Cold */) {
warming2(dep);
}

@@ -451,4 +430,5 @@ }

}
function cooling(sub, flags, link2) {
sub.flags = flags | 256 /* Cold */ | 64 /* PendingComputed */;
function cooling2(sub) {
sub.flags |= 64 /* Cold */;
let link2 = sub.deps;
do {

@@ -470,7 +450,4 @@ const dep = link2.dep;

}
if (dep.subs === void 0 && "deps" in dep) {
const depDeps = dep.deps;
if (depDeps !== void 0) {
cooling(dep, dep.flags, depDeps);
}
if (dep.subs === void 0 && "flags" in dep && dep.flags & 1 /* Computed */ && dep.deps !== void 0) {
cooling2(dep);
}

@@ -484,33 +461,24 @@ } while ((link2 = link2.nextDep) !== void 0);

link,
warming,
cooling,
propagate,
updateDirtyFlag,
checkDirty,
endTracking,
startTracking,
endTracking,
processEffectNotifications,
processComputedUpdate,
processPendingInnerEffects
} = createReactiveSystem({
updateComputed(computed2) {
const prevSub = activeSub;
activeSub = computed2;
startTracking(computed2);
try {
const oldValue = computed2.currentValue;
const newValue = computed2.getter(oldValue);
if (oldValue !== newValue) {
computed2.currentValue = newValue;
computed2.version++;
return true;
}
return false;
} finally {
activeSub = prevSub;
endTracking(computed2);
computed: {
update: updateComputed,
onUnwatched(computed2) {
cooling(computed2);
}
},
notifyEffect(e) {
if ("isScope" in e) {
return notifyEffectScope(e);
} else {
return notifyEffect(e);
effect: {
notify(e) {
if ("isScope" in e) {
notifyEffectScope(e);
} else {
notifyEffect(e);
}
}

@@ -560,3 +528,3 @@ }

depsTail: void 0,
flags: 1 /* Computed */ | 32 /* Dirty */,
flags: 1 /* Computed */ | 16 /* Dirty */,
getter

@@ -592,2 +560,20 @@ });

}
function updateComputed(computed2) {
const prevSub = activeSub;
activeSub = computed2;
startTracking(computed2);
try {
const oldValue = computed2.currentValue;
const newValue = computed2.getter(oldValue);
if (oldValue !== newValue) {
computed2.currentValue = newValue;
computed2.version++;
return true;
}
return false;
} finally {
activeSub = prevSub;
endTracking(computed2);
}
}
function runEffect(e) {

@@ -617,21 +603,24 @@ const prevSub = activeSub;

const flags = e.flags;
if (flags & 32 /* Dirty */ || flags & 64 /* PendingComputed */ && updateDirtyFlag(e, flags)) {
if (flags & 16 /* Dirty */ || checkDirty(e.deps)) {
runEffect(e);
} else {
processPendingInnerEffects(e, e.flags);
e.flags = flags & ~32 /* Pending */;
processPendingInnerEffects(e);
}
return true;
}
function notifyEffectScope(e) {
const flags = e.flags;
if (flags & 128 /* PendingEffect */) {
processPendingInnerEffects(e, e.flags);
return true;
if (flags & 32 /* Pending */) {
e.flags = flags & ~32 /* Pending */;
processPendingInnerEffects(e);
}
return false;
}
function computedGetter() {
const flags = this.flags;
if (flags & (32 /* Dirty */ | 64 /* PendingComputed */)) {
processComputedUpdate(this, flags);
if (flags & 64 /* Cold */ && (warming(this), true) || flags & (16 /* Dirty */ | 32 /* Pending */)) {
if (flags & 16 /* Dirty */ || checkDirty(this.deps)) {
updateComputed(this);
} else {
this.flags &= ~32 /* Pending */;
}
}

@@ -638,0 +627,0 @@ if (activeSub !== void 0) {

@@ -7,14 +7,18 @@ // src/system.ts

SubscriberFlags2[SubscriberFlags2["Tracking"] = 4] = "Tracking";
SubscriberFlags2[SubscriberFlags2["Notified"] = 8] = "Notified";
SubscriberFlags2[SubscriberFlags2["Recursed"] = 16] = "Recursed";
SubscriberFlags2[SubscriberFlags2["Dirty"] = 32] = "Dirty";
SubscriberFlags2[SubscriberFlags2["PendingComputed"] = 64] = "PendingComputed";
SubscriberFlags2[SubscriberFlags2["PendingEffect"] = 128] = "PendingEffect";
SubscriberFlags2[SubscriberFlags2["Cold"] = 256] = "Cold";
SubscriberFlags2[SubscriberFlags2["Propagated"] = 224] = "Propagated";
SubscriberFlags2[SubscriberFlags2["Recursed"] = 8] = "Recursed";
SubscriberFlags2[SubscriberFlags2["Dirty"] = 16] = "Dirty";
SubscriberFlags2[SubscriberFlags2["Pending"] = 32] = "Pending";
SubscriberFlags2[SubscriberFlags2["Cold"] = 64] = "Cold";
SubscriberFlags2[SubscriberFlags2["Propagated"] = 48] = "Propagated";
return SubscriberFlags2;
})(SubscriberFlags || {});
function createReactiveSystem({
updateComputed,
notifyEffect: notifyEffect2
computed: {
update: updateComputed2,
onUnwatched: onUnwatchedComputed = () => {
}
},
effect: {
notify: notifyEffect2
}
}) {

@@ -58,3 +62,3 @@ let queuedEffects;

propagate(link2) {
let targetFlag = 32 /* Dirty */;
let targetFlag = 16 /* Dirty */ | 32 /* Pending */;
let subs = link2;

@@ -65,3 +69,3 @@ let stack = 0;

const subFlags = sub.flags;
if (!(subFlags & (4 /* Tracking */ | 16 /* Recursed */ | 224 /* Propagated */)) && (sub.flags = subFlags | targetFlag | 8 /* Notified */, true) || subFlags & 16 /* Recursed */ && !(subFlags & 4 /* Tracking */) && (sub.flags = subFlags & ~16 /* Recursed */ | targetFlag | 8 /* Notified */, true) || !(subFlags & 224 /* Propagated */) && isValidLink(link2, sub) && (sub.flags = subFlags | 16 /* Recursed */ | targetFlag | 8 /* Notified */, sub.subs !== void 0)) {
if (!(subFlags & (4 /* Tracking */ | 8 /* Recursed */ | 48 /* Propagated */)) && (sub.flags = subFlags | targetFlag, true) || subFlags & 8 /* Recursed */ && !(subFlags & 4 /* Tracking */) && (sub.flags = subFlags & ~8 /* Recursed */ | targetFlag, true) || !(subFlags & 48 /* Propagated */) && isValidLink(link2, sub) && (sub.flags = subFlags | 8 /* Recursed */ | targetFlag, sub.subs !== void 0)) {
const subSubs = sub.subs;

@@ -72,8 +76,7 @@ if (subSubs !== void 0) {

link2 = subs = subSubs;
targetFlag = 64 /* PendingComputed */;
++stack;
} else {
link2 = subSubs;
targetFlag = subFlags & 2 /* Effect */ ? 128 /* PendingEffect */ : 64 /* PendingComputed */;
}
targetFlag = 32 /* Pending */;
continue;

@@ -90,4 +93,4 @@ }

} else if (!(subFlags & (4 /* Tracking */ | targetFlag))) {
sub.flags = subFlags | targetFlag | 8 /* Notified */;
if ((subFlags & (2 /* Effect */ | 8 /* Notified */)) === 2 /* Effect */) {
sub.flags = subFlags | targetFlag;
if (subFlags & 2 /* Effect */ && !isQueued(sub)) {
if (queuedEffectsTail !== void 0) {

@@ -100,3 +103,3 @@ queuedEffectsTail.depsTail.nextDep = sub.deps;

}
} else if (!(subFlags & targetFlag) && subFlags & 224 /* Propagated */ && isValidLink(link2, sub)) {
} else if (!(subFlags & targetFlag) && subFlags & 48 /* Propagated */ && isValidLink(link2, sub)) {
sub.flags = subFlags | targetFlag;

@@ -106,3 +109,3 @@ }

subs = link2;
targetFlag = stack ? 64 /* PendingComputed */ : 32 /* Dirty */;
targetFlag = stack ? 32 /* Pending */ : 16 /* Dirty */ | 32 /* Pending */;
continue;

@@ -118,3 +121,3 @@ }

subs = link2;
targetFlag = stack ? 64 /* PendingComputed */ : 32 /* Dirty */;
targetFlag = stack ? 32 /* Pending */ : 16 /* Dirty */ | 32 /* Pending */;
continue top;

@@ -136,3 +139,3 @@ }

sub.depsTail = void 0;
sub.flags = sub.flags & ~(8 /* Notified */ | 16 /* Recursed */ | 224 /* Propagated */) | 4 /* Tracking */;
sub.flags = sub.flags & ~(8 /* Recursed */ | 48 /* Propagated */) | 4 /* Tracking */;
},

@@ -162,44 +165,77 @@ /**

/**
* Updates the dirty flag for the given subscriber based on its dependencies.
* Recursively checks and updates all computed subscribers marked as pending.
*
* If the subscriber has any pending computeds, this function sets the Dirty flag
* and returns `true`. Otherwise, it clears the PendingComputed flag and returns `false`.
* It traverses the linked structure using a stack mechanism. For each computed
* subscriber in a pending state, updateComputed is called and shallowPropagate
* is triggered if a value changes. Returns whether any updates occurred.
*
* @param sub - The subscriber to update.
* @param flags - The current flag set for this subscriber.
* @returns `true` if the subscriber is marked as Dirty; otherwise `false`.
* @param link - The starting link representing a sequence of pending computeds.
* @returns `true` if a computed was updated, otherwise `false`.
*/
updateDirtyFlag(sub, flags) {
if (checkDirty(sub.deps)) {
sub.flags = flags | 32 /* Dirty */;
return true;
} else {
sub.flags = flags & ~64 /* PendingComputed */;
return false;
}
checkDirty(link2) {
let stack = 0;
let dirty;
top: do {
dirty = false;
const dep = link2.dep;
if (dep.version !== link2.version) {
dirty = true;
} else if ("flags" in dep) {
const depFlags = dep.flags;
if ((depFlags & (1 /* Computed */ | 16 /* Dirty */)) === (1 /* Computed */ | 16 /* Dirty */)) {
if (updateComputed2(dep)) {
dirty = true;
}
} else if ((depFlags & (1 /* Computed */ | 32 /* Pending */)) === (1 /* Computed */ | 32 /* Pending */)) {
const depSubs = dep.subs;
if (depSubs.nextSub !== void 0) {
depSubs.prevSub = link2;
}
link2 = dep.deps;
++stack;
continue;
}
}
if (!dirty && link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue;
}
if (stack) {
let sub = link2.sub;
do {
--stack;
const subSubs = sub.subs;
if (dirty) {
if (updateComputed2(sub)) {
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
sub = link2.sub;
} else {
sub = subSubs.sub;
}
continue;
}
} else {
sub.flags &= ~32 /* Pending */;
}
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
if (link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue top;
}
sub = link2.sub;
} else {
if ((link2 = subSubs.nextDep) !== void 0) {
continue top;
}
sub = subSubs.sub;
}
dirty = false;
} while (stack);
}
return dirty;
} while (true);
},
/**
* Updates the computed subscriber if necessary before its value is accessed.
*
* If the subscriber is marked Dirty or PendingComputed, this function runs
* the provided updateComputed logic and triggers a shallowPropagate for any
* downstream subscribers if an actual update occurs.
*
* @param computed - The computed subscriber to update.
* @param flags - The current flag set for this subscriber.
*/
processComputedUpdate(computed2, flags) {
if (flags & 256 /* Cold */) {
warming(computed2, flags, computed2.deps);
flags = computed2.flags;
}
if (flags & 32 /* Dirty */) {
updateComputed(computed2);
} else if (checkDirty(computed2.deps)) {
updateComputed(computed2);
} else {
computed2.flags = flags & ~64 /* PendingComputed */;
}
},
/**
* Ensures all pending internal effects for the given subscriber are processed.

@@ -215,14 +251,11 @@ *

*/
processPendingInnerEffects(sub, flags) {
if (flags & 128 /* PendingEffect */) {
sub.flags = flags & ~128 /* PendingEffect */;
let link2 = sub.deps;
do {
const dep = link2.dep;
if ("flags" in dep && dep.flags & 2 /* Effect */ && dep.flags & 224 /* Propagated */) {
notifyEffect2(dep);
}
link2 = link2.nextDep;
} while (link2 !== void 0);
}
processPendingInnerEffects(sub) {
let link2 = sub.deps;
do {
const dep = link2.dep;
if ("flags" in dep && dep.flags & 2 /* Effect */ && dep.flags & 48 /* Propagated */) {
notifyEffect2(dep);
}
link2 = link2.nextDep;
} while (link2 !== void 0);
},

@@ -248,8 +281,18 @@ /**

}
if (!notifyEffect2(effect2)) {
effect2.flags &= ~8 /* Notified */;
}
notifyEffect2(effect2);
}
},
warming: warming2,
cooling: cooling2
};
function isQueued(effect2) {
let queuedEffect = queuedEffects;
while (queuedEffect !== void 0) {
if (queuedEffect === effect2) {
return true;
}
queuedEffect = queuedEffect.depsTail.nextDep?.sub;
}
};
return false;
}
function linkNewDep(dep, sub, nextDep, depsTail) {

@@ -280,67 +323,2 @@ const newLink = {

}
function checkDirty(link2) {
let stack = 0;
let dirty;
top: do {
dirty = false;
const dep = link2.dep;
if (dep.version !== link2.version) {
dirty = true;
} else if ("flags" in dep) {
const depFlags = dep.flags;
if ((depFlags & (1 /* Computed */ | 32 /* Dirty */)) === (1 /* Computed */ | 32 /* Dirty */)) {
if (updateComputed(dep)) {
dirty = true;
}
} else if ((depFlags & (1 /* Computed */ | 64 /* PendingComputed */)) === (1 /* Computed */ | 64 /* PendingComputed */)) {
const depSubs = dep.subs;
if (depSubs.nextSub !== void 0) {
depSubs.prevSub = link2;
}
link2 = dep.deps;
++stack;
continue;
}
}
if (!dirty && link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue;
}
if (stack) {
let sub = link2.sub;
do {
--stack;
const subSubs = sub.subs;
if (dirty) {
if (updateComputed(sub)) {
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
sub = link2.sub;
} else {
sub = subSubs.sub;
}
continue;
}
} else {
sub.flags &= ~64 /* PendingComputed */;
}
if ((link2 = subSubs.prevSub) !== void 0) {
subSubs.prevSub = void 0;
if (link2.nextDep !== void 0) {
link2 = link2.nextDep;
continue top;
}
sub = link2.sub;
} else {
if ((link2 = subSubs.nextDep) !== void 0) {
continue top;
}
sub = subSubs.sub;
}
dirty = false;
} while (stack);
}
return dirty;
} while (true);
}
function isValidLink(checkLink, sub) {

@@ -386,3 +364,3 @@ const depsTail = sub.depsTail;

} else if (depFlags & 1 /* Computed */) {
cooling(dep, depFlags, depDeps);
onUnwatchedComputed(dep);
}

@@ -393,4 +371,5 @@ }

}
function warming(sub, flags, link2) {
sub.flags = flags & ~256 /* Cold */;
function warming2(sub) {
sub.flags &= ~64 /* Cold */;
let link2 = sub.deps;
do {

@@ -409,4 +388,4 @@ const dep = link2.dep;

const depFlags = dep.flags;
if (depFlags & 256 /* Cold */) {
warming(dep, depFlags, dep.deps);
if (depFlags & 64 /* Cold */) {
warming2(dep);
}

@@ -416,4 +395,5 @@ }

}
function cooling(sub, flags, link2) {
sub.flags = flags | 256 /* Cold */ | 64 /* PendingComputed */;
function cooling2(sub) {
sub.flags |= 64 /* Cold */;
let link2 = sub.deps;
do {

@@ -435,7 +415,4 @@ const dep = link2.dep;

}
if (dep.subs === void 0 && "deps" in dep) {
const depDeps = dep.deps;
if (depDeps !== void 0) {
cooling(dep, dep.flags, depDeps);
}
if (dep.subs === void 0 && "flags" in dep && dep.flags & 1 /* Computed */ && dep.deps !== void 0) {
cooling2(dep);
}

@@ -449,33 +426,24 @@ } while ((link2 = link2.nextDep) !== void 0);

link,
warming,
cooling,
propagate,
updateDirtyFlag,
checkDirty,
endTracking,
startTracking,
endTracking,
processEffectNotifications,
processComputedUpdate,
processPendingInnerEffects
} = createReactiveSystem({
updateComputed(computed2) {
const prevSub = activeSub;
activeSub = computed2;
startTracking(computed2);
try {
const oldValue = computed2.currentValue;
const newValue = computed2.getter(oldValue);
if (oldValue !== newValue) {
computed2.currentValue = newValue;
computed2.version++;
return true;
}
return false;
} finally {
activeSub = prevSub;
endTracking(computed2);
computed: {
update: updateComputed,
onUnwatched(computed2) {
cooling(computed2);
}
},
notifyEffect(e) {
if ("isScope" in e) {
return notifyEffectScope(e);
} else {
return notifyEffect(e);
effect: {
notify(e) {
if ("isScope" in e) {
notifyEffectScope(e);
} else {
notifyEffect(e);
}
}

@@ -525,3 +493,3 @@ }

depsTail: void 0,
flags: 1 /* Computed */ | 32 /* Dirty */,
flags: 1 /* Computed */ | 16 /* Dirty */,
getter

@@ -557,2 +525,20 @@ });

}
function updateComputed(computed2) {
const prevSub = activeSub;
activeSub = computed2;
startTracking(computed2);
try {
const oldValue = computed2.currentValue;
const newValue = computed2.getter(oldValue);
if (oldValue !== newValue) {
computed2.currentValue = newValue;
computed2.version++;
return true;
}
return false;
} finally {
activeSub = prevSub;
endTracking(computed2);
}
}
function runEffect(e) {

@@ -582,21 +568,24 @@ const prevSub = activeSub;

const flags = e.flags;
if (flags & 32 /* Dirty */ || flags & 64 /* PendingComputed */ && updateDirtyFlag(e, flags)) {
if (flags & 16 /* Dirty */ || checkDirty(e.deps)) {
runEffect(e);
} else {
processPendingInnerEffects(e, e.flags);
e.flags = flags & ~32 /* Pending */;
processPendingInnerEffects(e);
}
return true;
}
function notifyEffectScope(e) {
const flags = e.flags;
if (flags & 128 /* PendingEffect */) {
processPendingInnerEffects(e, e.flags);
return true;
if (flags & 32 /* Pending */) {
e.flags = flags & ~32 /* Pending */;
processPendingInnerEffects(e);
}
return false;
}
function computedGetter() {
const flags = this.flags;
if (flags & (32 /* Dirty */ | 64 /* PendingComputed */)) {
processComputedUpdate(this, flags);
if (flags & 64 /* Cold */ && (warming(this), true) || flags & (16 /* Dirty */ | 32 /* Pending */)) {
if (flags & 16 /* Dirty */ || checkDirty(this.deps)) {
updateComputed(this);
} else {
this.flags &= ~32 /* Pending */;
}
}

@@ -603,0 +592,0 @@ if (activeSub !== void 0) {

{
"name": "alien-signals",
"version": "1.1.0-alpha.3",
"version": "2.0.0-alpha.0",
"sideEffects": false,

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -24,34 +24,37 @@ export interface Dependency {

Tracking = 4,
Notified = 8,
Recursed = 16,
Dirty = 32,
PendingComputed = 64,
PendingEffect = 128,
Cold = 256,
Propagated = 224
Recursed = 8,
Dirty = 16,
Pending = 32,
Cold = 64,
Propagated = 48
}
export declare function createReactiveSystem({ updateComputed, notifyEffect, }: {
/**
* Updates the computed subscriber's value and returns whether it changed.
*
* This function should be called when a computed subscriber is marked as Dirty.
* The computed subscriber's getter function is invoked, and its value is updated.
* If the value changes, the new value is stored, and the function returns `true`.
*
* @param computed - The computed subscriber to update.
* @returns `true` if the computed subscriber's value changed; otherwise `false`.
*/
updateComputed(computed: Dependency & Subscriber): boolean;
/**
* Handles effect notifications by processing the specified `effect`.
*
* When an `effect` first receives any of the following flags:
* - `Dirty`
* - `PendingComputed`
* - `PendingEffect`
* this method will process them and return `true` if the flags are successfully handled.
* If not fully handled, future changes to these flags will trigger additional calls
* until the method eventually returns `true`.
*/
notifyEffect(effect: Subscriber): boolean;
export declare function createReactiveSystem({ computed: { update: updateComputed, onUnwatched: onUnwatchedComputed, }, effect: { notify: notifyEffect, }, }: {
computed: {
/**
* Updates the computed subscriber's value and returns whether it changed.
*
* This function should be called when a computed subscriber is marked as Dirty.
* The computed subscriber's getter function is invoked, and its value is updated.
* If the value changes, the new value is stored, and the function returns `true`.
*
* @param computed - The computed subscriber to update.
* @returns `true` if the computed subscriber's value changed; otherwise `false`.
*/
update(computed: Dependency & Subscriber): boolean;
onUnwatched?: (computed: Dependency & Subscriber) => void;
};
effect: {
/**
* Handles effect notifications by processing the specified `effect`.
*
* When an `effect` first receives any of the following flags:
* - `Dirty`
* - `PendingComputed`
* - `PendingEffect`
* this method will process them and return `true` if the flags are successfully handled.
* If not fully handled, future changes to these flags will trigger additional calls
* until the method eventually returns `true`.
*/
notify(effect: Subscriber): void;
};
}): {

@@ -95,24 +98,13 @@ /**

/**
* Updates the dirty flag for the given subscriber based on its dependencies.
* Recursively checks and updates all computed subscribers marked as pending.
*
* If the subscriber has any pending computeds, this function sets the Dirty flag
* and returns `true`. Otherwise, it clears the PendingComputed flag and returns `false`.
* It traverses the linked structure using a stack mechanism. For each computed
* subscriber in a pending state, updateComputed is called and shallowPropagate
* is triggered if a value changes. Returns whether any updates occurred.
*
* @param sub - The subscriber to update.
* @param flags - The current flag set for this subscriber.
* @returns `true` if the subscriber is marked as Dirty; otherwise `false`.
* @param link - The starting link representing a sequence of pending computeds.
* @returns `true` if a computed was updated, otherwise `false`.
*/
updateDirtyFlag(sub: Subscriber, flags: SubscriberFlags): boolean;
checkDirty(link: Link): boolean;
/**
* Updates the computed subscriber if necessary before its value is accessed.
*
* If the subscriber is marked Dirty or PendingComputed, this function runs
* the provided updateComputed logic and triggers a shallowPropagate for any
* downstream subscribers if an actual update occurs.
*
* @param computed - The computed subscriber to update.
* @param flags - The current flag set for this subscriber.
*/
processComputedUpdate(computed: Dependency & Subscriber, flags: SubscriberFlags): void;
/**
* Ensures all pending internal effects for the given subscriber are processed.

@@ -128,3 +120,3 @@ *

*/
processPendingInnerEffects(sub: Subscriber, flags: SubscriberFlags): void;
processPendingInnerEffects(sub: Subscriber): void;
/**

@@ -138,2 +130,4 @@ * Processes queued effect notifications after a batch operation finishes.

processEffectNotifications(): void;
warming: (sub: Subscriber & Dependency) => void;
cooling: (sub: Subscriber & Dependency) => void;
};