@maverick-js/signals
Advanced tools
Comparing version 5.2.0 to 5.3.0
@@ -0,1 +1,7 @@ | ||
// src/symbols.ts | ||
var SCOPE = Symbol(true ? "SCOPE" : 0); | ||
var TASKS = Symbol(true ? "TASKS" : 0); | ||
var FLAGS = Symbol(true ? "FLAGS" : 0); | ||
var HANDLERS = Symbol(true ? "ERROR_HANDLERS" : 0); | ||
// src/scheduler.ts | ||
@@ -9,7 +15,2 @@ function createScheduler() { | ||
} | ||
function enqueueBatch(batch) { | ||
batch(tasks); | ||
if (!scheduled) | ||
scheduleFlush(); | ||
} | ||
function scheduleFlush() { | ||
@@ -29,3 +30,3 @@ if (scheduled) | ||
for (; i3 < tasks.length; i3++) | ||
tasks[i3](); | ||
tasks[i3].call(tasks[i3]); | ||
for (j = 0; j < afterTasks.length; j++) | ||
@@ -42,4 +43,4 @@ afterTasks[j](); | ||
return { | ||
[TASKS]: () => tasks, | ||
enqueue, | ||
enqueueBatch, | ||
flush: scheduleFlush, | ||
@@ -57,7 +58,2 @@ flushSync: flush, | ||
// src/symbols.ts | ||
var SCOPE = Symbol(true ? "SCOPE" : 0); | ||
var FLAGS = Symbol(true ? "FLAGS" : 0); | ||
var HANDLERS = Symbol(true ? "ERROR_HANDLERS" : 0); | ||
// src/signals.ts | ||
@@ -94,20 +90,10 @@ var i = 0; | ||
SCHEDULER.onFlush(() => { | ||
callStack.length = 0; | ||
callStack = []; | ||
}); | ||
} | ||
function root(init) { | ||
const $root = { | ||
[SCOPE]: currentScope, | ||
_nextSibling: null, | ||
_prevSibling: null | ||
}; | ||
if (currentScope) | ||
appendScope($root); | ||
const scope = new RootScope(); | ||
return compute( | ||
$root, | ||
!init.length ? init : function createRoot() { | ||
return init(function disposeRoot() { | ||
dispose($root, true); | ||
}); | ||
}, | ||
scope, | ||
!init.length ? init : init.bind(null, dispose.bind(scope)), | ||
null | ||
@@ -173,5 +159,8 @@ ); | ||
read.call(signal2); | ||
return function stopEffect() { | ||
dispose(signal2, true); | ||
}; | ||
if (true) { | ||
return function stopEffect() { | ||
dispose.call(signal2, true); | ||
}; | ||
} | ||
return dispose.bind(signal2, true); | ||
} | ||
@@ -224,19 +213,27 @@ function readonly(signal2) { | ||
const node = currentScope; | ||
if (!node._disposal) | ||
node._disposal = []; | ||
node._disposal.push(dispose2); | ||
if (!node._disposal) { | ||
node._disposal = dispose2; | ||
} else if (Array.isArray(node._disposal)) { | ||
node._disposal.push(dispose2); | ||
} else { | ||
node._disposal = [node._disposal, dispose2]; | ||
} | ||
return function removeDispose() { | ||
if (isDisposed(node)) | ||
return; | ||
dispose2(); | ||
node._disposal.splice(node._disposal.indexOf(dispose2), 1); | ||
dispose2.call(null); | ||
if (isFunction(node._disposal)) { | ||
node._disposal = null; | ||
} else if (Array.isArray(node._disposal)) { | ||
node._disposal.splice(node._disposal.indexOf(dispose2), 1); | ||
} | ||
}; | ||
} | ||
var scopes = /* @__PURE__ */ new Set(); | ||
function dispose(scope, self = false) { | ||
if (isDisposed(scope)) | ||
function dispose(self = true) { | ||
if (isDisposed(this)) | ||
return; | ||
let current = self ? scope : scope._nextSibling, head = self ? scope._prevSibling : scope; | ||
let current = self ? this : this._nextSibling, head = self ? this._prevSibling : this; | ||
if (current) { | ||
scopes.add(scope); | ||
scopes.add(this); | ||
do { | ||
@@ -267,5 +264,11 @@ if (current._disposal) | ||
try { | ||
for (i = 0; i < scope._disposal.length; i++) | ||
scope._disposal[i](); | ||
scope._disposal.length = 0; | ||
if (Array.isArray(scope._disposal)) { | ||
for (i = 0; i < scope._disposal.length; i++) { | ||
const callable = scope._disposal[i]; | ||
callable.call(callable); | ||
} | ||
} else { | ||
scope._disposal.call(scope._disposal); | ||
} | ||
scope._disposal = null; | ||
} catch (error) { | ||
@@ -282,3 +285,3 @@ handleError(scope, error); | ||
try { | ||
return compute2(); | ||
return compute2.call(scope); | ||
} finally { | ||
@@ -315,5 +318,5 @@ if (currentObserver) | ||
function selector(source) { | ||
let currentKey, count = /* @__PURE__ */ new Map(), nodes = /* @__PURE__ */ new Map(); | ||
let currentKey, nodes = /* @__PURE__ */ new Map(); | ||
read.call( | ||
createComputation(void 0, function selectorChange() { | ||
createComputation(currentKey, function selectorChange() { | ||
const newKey = source(), prev = nodes.get(currentKey), next = nodes.get(newKey); | ||
@@ -325,23 +328,27 @@ prev && write.call(prev, false); | ||
); | ||
return function observeSelector(key) { | ||
if (currentScope) { | ||
if (!currentScope._disposal) | ||
currentScope._disposal = []; | ||
currentScope._disposal.push(function disposeSelector() { | ||
const remaining = count.get(key) - 1; | ||
if (remaining === 0) { | ||
count.delete(key); | ||
nodes.delete(key); | ||
} else | ||
count.set(key, remaining); | ||
}); | ||
class SelectorNode { | ||
_key; | ||
_value; | ||
_count = 0; | ||
constructor(key, initialValue) { | ||
this._key = key; | ||
this._value = initialValue; | ||
} | ||
let value = nodes.get(key); | ||
if (!value) { | ||
count.set(key, 1); | ||
nodes.set(key, value = createComputation(key === currentKey, null)); | ||
return read.bind(value); | ||
call() { | ||
this._count -= 1; | ||
if (!this._count) | ||
nodes.delete(this._key); | ||
} | ||
count.set(key, count.get(key) + 1); | ||
return read.bind(value); | ||
} | ||
const SelectorNodeProto = SelectorNode.prototype; | ||
SelectorNodeProto[FLAGS] = FLAG_DIRTY; | ||
SelectorNodeProto._observers = null; | ||
SelectorNodeProto._changed = isNotEqual; | ||
return function observeSelector(key) { | ||
let node = nodes.get(key); | ||
if (!node) | ||
nodes.set(key, node = new SelectorNode(key, key === currentKey)); | ||
node._count += 1; | ||
onDispose(node); | ||
return read.bind(node); | ||
}; | ||
@@ -361,3 +368,4 @@ } | ||
_compute: compute2, | ||
_changed: isNotEqual | ||
_changed: isNotEqual, | ||
call: read | ||
}; | ||
@@ -368,6 +376,8 @@ if (true) | ||
appendScope(node); | ||
if (options && options.scoped) | ||
node[FLAGS] |= FLAG_SCOPED; | ||
if (options && options.dirty) | ||
node._changed = options.dirty; | ||
if (options) { | ||
if (options.scoped) | ||
node[FLAGS] |= FLAG_SCOPED; | ||
if (options.dirty) | ||
node._changed = options.dirty; | ||
} | ||
return node; | ||
@@ -403,7 +413,7 @@ } | ||
if (this._nextSibling && this._nextSibling[SCOPE] === this) | ||
dispose(this); | ||
dispose.call(this, false); | ||
if (this._disposal) | ||
emptyDisposal(this); | ||
if (this._context && this._context[HANDLERS]) | ||
this._context[HANDLERS].length = 0; | ||
this._context[HANDLERS] = []; | ||
} | ||
@@ -469,15 +479,15 @@ const result = compute(scoped2 ? this : currentScope, this._compute, this); | ||
return this._value; | ||
SCHEDULER.enqueueBatch((queue) => { | ||
for (i = 0; i < this._observers.length; i++) { | ||
const observer = this._observers[i]; | ||
if (observer._compute) { | ||
observer[FLAGS] |= FLAG_DIRTY; | ||
if (isScoped(observer)) { | ||
effects.push(observer); | ||
} else { | ||
queue.push(read.bind(observer)); | ||
} | ||
const tasks = SCHEDULER[TASKS](); | ||
for (i = 0; i < this._observers.length; i++) { | ||
const observer = this._observers[i]; | ||
if (observer._compute) { | ||
observer[FLAGS] |= FLAG_DIRTY; | ||
if (isScoped(observer)) { | ||
effects.push(observer); | ||
} else { | ||
tasks.push(observer); | ||
} | ||
} | ||
}); | ||
} | ||
SCHEDULER.flush(); | ||
return this._value; | ||
@@ -531,2 +541,15 @@ } | ||
} | ||
var RootScope = class RootScope2 { | ||
constructor() { | ||
if (currentScope) { | ||
this[SCOPE] = currentScope; | ||
appendScope(this); | ||
} | ||
} | ||
}; | ||
var RootScopeProto = RootScope.prototype; | ||
RootScopeProto[SCOPE] = null; | ||
RootScopeProto._prevSibling = null; | ||
RootScopeProto._nextSibling = null; | ||
RootScopeProto.call = dispose; | ||
@@ -536,3 +559,3 @@ // src/map.ts | ||
let items = [], mapped = [], disposal = [], signals = [], i3, len = 0; | ||
onDispose(() => runAll(disposal)); | ||
onDispose(() => emptyDisposal2(disposal)); | ||
return computed( | ||
@@ -544,3 +567,3 @@ () => { | ||
if (len !== 0) { | ||
runAll(disposal); | ||
emptyDisposal2(disposal); | ||
disposal = []; | ||
@@ -558,7 +581,7 @@ items = []; | ||
} else if (i3 >= items.length) { | ||
mapped[i3] = root(mapper); | ||
mapped[i3] = compute(new RootScope(), mapper, null); | ||
} | ||
} | ||
for (; i3 < items.length; i3++) | ||
disposal[i3](); | ||
disposal[i3].call(disposal[i3]); | ||
len = signals.length = disposal.length = newItems.length; | ||
@@ -568,4 +591,4 @@ items = newItems.slice(0); | ||
}); | ||
function mapper(dispose2) { | ||
disposal[i3] = dispose2; | ||
function mapper() { | ||
disposal[i3] = this; | ||
const $o = signal(newItems[i3]); | ||
@@ -581,3 +604,3 @@ signals[i3] = $o.set; | ||
let items = [], mapping = [], disposal = [], len = 0, indicies = map.length > 1 ? [] : null; | ||
onDispose(() => runAll(disposal)); | ||
onDispose(() => emptyDisposal2(disposal)); | ||
return computed( | ||
@@ -590,3 +613,3 @@ () => { | ||
if (len !== 0) { | ||
runAll(disposal); | ||
emptyDisposal2(disposal); | ||
disposal = []; | ||
@@ -602,3 +625,3 @@ items = []; | ||
items[j] = newItems[j]; | ||
mapping[j] = root(mapper); | ||
mapping[j] = compute(new RootScope(), mapper, null); | ||
} | ||
@@ -633,3 +656,3 @@ len = newLen; | ||
} else | ||
disposal[i3](); | ||
disposal[i3].call(disposal[i3]); | ||
} | ||
@@ -644,4 +667,5 @@ for (j = start; j < newLen; j++) { | ||
} | ||
} else | ||
mapping[j] = root(mapper); | ||
} else { | ||
mapping[j] = compute(new RootScope(), mapper, null); | ||
} | ||
} | ||
@@ -653,8 +677,7 @@ mapping = mapping.slice(0, len = newLen); | ||
}); | ||
function mapper(dispose2) { | ||
disposal[j] = dispose2; | ||
function mapper() { | ||
disposal[j] = this; | ||
if (indicies) { | ||
const $signal = signal(j); | ||
indicies[j] = $signal.set; | ||
$signal.set = void 0; | ||
return map(newItems[j], $signal); | ||
@@ -669,5 +692,5 @@ } | ||
var i2 = 0; | ||
function runAll(fns) { | ||
for (i2 = 0; i2 < fns.length; i2++) | ||
fns[i2](); | ||
function emptyDisposal2(disposal) { | ||
for (i2 = 0; i2 < disposal.length; i2++) | ||
disposal[i2].call(disposal[i2]); | ||
} | ||
@@ -677,3 +700,6 @@ export { | ||
HANDLERS, | ||
RootScope, | ||
SCOPE, | ||
TASKS, | ||
compute, | ||
computed, | ||
@@ -680,0 +706,0 @@ computedKeyedMap, |
@@ -0,1 +1,7 @@ | ||
// src/symbols.ts | ||
var SCOPE = Symbol(false ? "SCOPE" : 0); | ||
var TASKS = Symbol(false ? "TASKS" : 0); | ||
var FLAGS = Symbol(false ? "FLAGS" : 0); | ||
var HANDLERS = Symbol(false ? "ERROR_HANDLERS" : 0); | ||
// src/scheduler.ts | ||
@@ -9,7 +15,2 @@ function createScheduler() { | ||
} | ||
function enqueueBatch(batch) { | ||
batch(tasks); | ||
if (!scheduled) | ||
scheduleFlush(); | ||
} | ||
function scheduleFlush() { | ||
@@ -29,3 +30,3 @@ if (scheduled) | ||
for (; i3 < tasks.length; i3++) | ||
tasks[i3](); | ||
tasks[i3].call(tasks[i3]); | ||
for (j = 0; j < afterTasks.length; j++) | ||
@@ -42,4 +43,4 @@ afterTasks[j](); | ||
return { | ||
[TASKS]: () => tasks, | ||
enqueue, | ||
enqueueBatch, | ||
flush: scheduleFlush, | ||
@@ -57,7 +58,2 @@ flushSync: flush, | ||
// src/symbols.ts | ||
var SCOPE = Symbol(false ? "SCOPE" : 0); | ||
var FLAGS = Symbol(false ? "FLAGS" : 0); | ||
var HANDLERS = Symbol(false ? "ERROR_HANDLERS" : 0); | ||
// src/signals.ts | ||
@@ -92,20 +88,10 @@ var i = 0; | ||
SCHEDULER.onFlush(() => { | ||
callStack.length = 0; | ||
callStack = []; | ||
}); | ||
} | ||
function root(init) { | ||
const $root = { | ||
[SCOPE]: currentScope, | ||
d: null, | ||
f: null | ||
}; | ||
if (currentScope) | ||
appendScope($root); | ||
const scope = new RootScope(); | ||
return compute( | ||
$root, | ||
!init.length ? init : function createRoot() { | ||
return init(function disposeRoot() { | ||
dispose($root, true); | ||
}); | ||
}, | ||
scope, | ||
!init.length ? init : init.bind(null, dispose.bind(scope)), | ||
null | ||
@@ -171,5 +157,8 @@ ); | ||
read.call(signal2); | ||
return function stopEffect() { | ||
dispose(signal2, true); | ||
}; | ||
if (false) { | ||
return function stopEffect() { | ||
dispose.call(signal2, true); | ||
}; | ||
} | ||
return dispose.bind(signal2, true); | ||
} | ||
@@ -208,3 +197,3 @@ function readonly(signal2) { | ||
if (currentScope) | ||
(currentScope.g ??= {})[key] = value; | ||
(currentScope.f ??= {})[key] = value; | ||
} | ||
@@ -214,3 +203,3 @@ function onError(handler) { | ||
return; | ||
const context = currentScope.g ??= {}; | ||
const context = currentScope.f ??= {}; | ||
if (!context[HANDLERS]) | ||
@@ -224,40 +213,48 @@ context[HANDLERS] = []; | ||
const node = currentScope; | ||
if (!node.c) | ||
node.c = []; | ||
node.c.push(dispose2); | ||
if (!node.a) { | ||
node.a = dispose2; | ||
} else if (Array.isArray(node.a)) { | ||
node.a.push(dispose2); | ||
} else { | ||
node.a = [node.a, dispose2]; | ||
} | ||
return function removeDispose() { | ||
if (isDisposed(node)) | ||
return; | ||
dispose2(); | ||
node.c.splice(node.c.indexOf(dispose2), 1); | ||
dispose2.call(null); | ||
if (isFunction(node.a)) { | ||
node.a = null; | ||
} else if (Array.isArray(node.a)) { | ||
node.a.splice(node.a.indexOf(dispose2), 1); | ||
} | ||
}; | ||
} | ||
var scopes = /* @__PURE__ */ new Set(); | ||
function dispose(scope, self = false) { | ||
if (isDisposed(scope)) | ||
function dispose(self = true) { | ||
if (isDisposed(this)) | ||
return; | ||
let current = self ? scope : scope.d, head = self ? scope.f : scope; | ||
let current = self ? this : this.e, head = self ? this.g : this; | ||
if (current) { | ||
scopes.add(scope); | ||
scopes.add(this); | ||
do { | ||
if (current.c) | ||
if (current.a) | ||
emptyDisposal(current); | ||
if (current.a) | ||
if (current.b) | ||
removeSourceObservers(current, 0); | ||
current[SCOPE] = null; | ||
current.a = null; | ||
current.b = null; | ||
current.c = null; | ||
current.g = null; | ||
current.f = null; | ||
current.g = null; | ||
current[FLAGS] |= FLAG_DISPOSED; | ||
scopes.add(current); | ||
current = current.d; | ||
current = current.e; | ||
if (current) | ||
current.f.d = null; | ||
current.g.e = null; | ||
} while (current && scopes.has(current[SCOPE])); | ||
} | ||
if (head) | ||
head.d = current; | ||
head.e = current; | ||
if (current) | ||
current.f = head; | ||
current.g = head; | ||
scopes.clear(); | ||
@@ -267,5 +264,11 @@ } | ||
try { | ||
for (i = 0; i < scope.c.length; i++) | ||
scope.c[i](); | ||
scope.c.length = 0; | ||
if (Array.isArray(scope.a)) { | ||
for (i = 0; i < scope.a.length; i++) { | ||
const callable = scope.a[i]; | ||
callable.call(callable); | ||
} | ||
} else { | ||
scope.a.call(scope.a); | ||
} | ||
scope.a = null; | ||
} catch (error) { | ||
@@ -282,3 +285,3 @@ handleError(scope, error); | ||
try { | ||
return compute2(); | ||
return compute2.call(scope); | ||
} finally { | ||
@@ -296,3 +299,3 @@ if (false) | ||
while (current) { | ||
value = current.g?.[key]; | ||
value = current.f?.[key]; | ||
if (value !== void 0) | ||
@@ -316,5 +319,5 @@ return value; | ||
function selector(source) { | ||
let currentKey, count = /* @__PURE__ */ new Map(), nodes = /* @__PURE__ */ new Map(); | ||
let currentKey, nodes = /* @__PURE__ */ new Map(); | ||
read.call( | ||
createComputation(void 0, function selectorChange() { | ||
createComputation(currentKey, function selectorChange() { | ||
const newKey = source(), prev = nodes.get(currentKey), next = nodes.get(newKey); | ||
@@ -326,23 +329,27 @@ prev && write.call(prev, false); | ||
); | ||
return function observeSelector(key) { | ||
if (currentScope) { | ||
if (!currentScope.c) | ||
currentScope.c = []; | ||
currentScope.c.push(function disposeSelector() { | ||
const remaining = count.get(key) - 1; | ||
if (remaining === 0) { | ||
count.delete(key); | ||
nodes.delete(key); | ||
} else | ||
count.set(key, remaining); | ||
}); | ||
class SelectorNode { | ||
k; | ||
d; | ||
h = 0; | ||
constructor(key, initialValue) { | ||
this.k = key; | ||
this.d = initialValue; | ||
} | ||
let value = nodes.get(key); | ||
if (!value) { | ||
count.set(key, 1); | ||
nodes.set(key, value = createComputation(key === currentKey, null)); | ||
return read.bind(value); | ||
call() { | ||
this.h -= 1; | ||
if (!this.h) | ||
nodes.delete(this.k); | ||
} | ||
count.set(key, count.get(key) + 1); | ||
return read.bind(value); | ||
} | ||
const SelectorNodeProto = SelectorNode.prototype; | ||
SelectorNodeProto[FLAGS] = FLAG_DIRTY; | ||
SelectorNodeProto.c = null; | ||
SelectorNodeProto.i = isNotEqual; | ||
return function observeSelector(key) { | ||
let node = nodes.get(key); | ||
if (!node) | ||
nodes.set(key, node = new SelectorNode(key, key === currentKey)); | ||
node.h += 1; | ||
onDispose(node); | ||
return read.bind(node); | ||
}; | ||
@@ -354,20 +361,23 @@ } | ||
[SCOPE]: currentScope, | ||
d: null, | ||
e: null, | ||
g: null, | ||
f: null, | ||
g: null, | ||
a: null, | ||
b: null, | ||
c: null, | ||
e: initialValue, | ||
h: compute2, | ||
i: isNotEqual | ||
a: null, | ||
d: initialValue, | ||
j: compute2, | ||
i: isNotEqual, | ||
call: read | ||
}; | ||
if (false) | ||
node.id = options?.id ?? (node.h ? "computed" : "signal"); | ||
node.id = options?.id ?? (node.j ? "computed" : "signal"); | ||
if (currentScope) | ||
appendScope(node); | ||
if (options && options.scoped) | ||
node[FLAGS] |= FLAG_SCOPED; | ||
if (options && options.dirty) | ||
node.i = options.dirty; | ||
if (options) { | ||
if (options.scoped) | ||
node[FLAGS] |= FLAG_SCOPED; | ||
if (options.dirty) | ||
node.i = options.dirty; | ||
} | ||
return node; | ||
@@ -377,3 +387,3 @@ } | ||
if (isDisposed(this)) | ||
return this.e; | ||
return this.d; | ||
if (false) { | ||
@@ -389,3 +399,3 @@ const calls = callStack.map((c) => c.id ?? "?").join(" --> "); | ||
if (currentObserver) { | ||
if (!currentObservers && currentObserver.a && currentObserver.a[currentObserversIndex] == this) { | ||
if (!currentObservers && currentObserver.b && currentObserver.b[currentObserversIndex] == this) { | ||
currentObserversIndex++; | ||
@@ -397,3 +407,3 @@ } else if (!currentObservers) | ||
} | ||
if (this.h && isDirty(this)) { | ||
if (this.j && isDirty(this)) { | ||
let prevObservers = currentObservers, prevObserversIndex = currentObserversIndex; | ||
@@ -405,35 +415,35 @@ currentObservers = null; | ||
if (scoped2) { | ||
if (this.d && this.d[SCOPE] === this) | ||
dispose(this); | ||
if (this.c) | ||
if (this.e && this.e[SCOPE] === this) | ||
dispose.call(this, false); | ||
if (this.a) | ||
emptyDisposal(this); | ||
if (this.g && this.g[HANDLERS]) | ||
this.g[HANDLERS].length = 0; | ||
if (this.f && this.f[HANDLERS]) | ||
this.f[HANDLERS] = []; | ||
} | ||
const result = compute(scoped2 ? this : currentScope, this.h, this); | ||
const result = compute(scoped2 ? this : currentScope, this.j, this); | ||
if (currentObservers) { | ||
if (this.a) | ||
if (this.b) | ||
removeSourceObservers(this, currentObserversIndex); | ||
if (this.a && currentObserversIndex > 0) { | ||
this.a.length = currentObserversIndex + currentObservers.length; | ||
if (this.b && currentObserversIndex > 0) { | ||
this.b.length = currentObserversIndex + currentObservers.length; | ||
for (i = 0; i < currentObservers.length; i++) { | ||
this.a[currentObserversIndex + i] = currentObservers[i]; | ||
this.b[currentObserversIndex + i] = currentObservers[i]; | ||
} | ||
} else { | ||
this.a = currentObservers; | ||
this.b = currentObservers; | ||
} | ||
let source; | ||
for (i = currentObserversIndex; i < this.a.length; i++) { | ||
source = this.a[i]; | ||
if (!source.b) | ||
source.b = [this]; | ||
for (i = currentObserversIndex; i < this.b.length; i++) { | ||
source = this.b[i]; | ||
if (!source.c) | ||
source.c = [this]; | ||
else | ||
source.b.push(this); | ||
source.c.push(this); | ||
} | ||
} else if (this.a && currentObserversIndex < this.a.length) { | ||
} else if (this.b && currentObserversIndex < this.b.length) { | ||
removeSourceObservers(this, currentObserversIndex); | ||
this.a.length = currentObserversIndex; | ||
this.b.length = currentObserversIndex; | ||
} | ||
if (scoped2 || !isInit(this)) { | ||
this.e = result; | ||
this.d = result; | ||
} else { | ||
@@ -456,3 +466,3 @@ write.call(this, result); | ||
handleError(this, error); | ||
return this.e; | ||
return this.d; | ||
} | ||
@@ -464,34 +474,34 @@ currentObservers = prevObservers; | ||
} | ||
return this.e; | ||
return this.d; | ||
} | ||
function write(newValue) { | ||
const value = !isFunction(this.e) && isFunction(newValue) ? newValue(this.e) : newValue; | ||
if (isDisposed(this) || !this.i(this.e, value)) | ||
return this.e; | ||
this.e = value; | ||
if (!this.b || !this.b.length) | ||
return this.e; | ||
SCHEDULER.enqueueBatch((queue) => { | ||
for (i = 0; i < this.b.length; i++) { | ||
const observer = this.b[i]; | ||
if (observer.h) { | ||
observer[FLAGS] |= FLAG_DIRTY; | ||
if (isScoped(observer)) { | ||
effects.push(observer); | ||
} else { | ||
queue.push(read.bind(observer)); | ||
} | ||
const value = !isFunction(this.d) && isFunction(newValue) ? newValue(this.d) : newValue; | ||
if (isDisposed(this) || !this.i(this.d, value)) | ||
return this.d; | ||
this.d = value; | ||
if (!this.c || !this.c.length) | ||
return this.d; | ||
const tasks = SCHEDULER[TASKS](); | ||
for (i = 0; i < this.c.length; i++) { | ||
const observer = this.c[i]; | ||
if (observer.j) { | ||
observer[FLAGS] |= FLAG_DIRTY; | ||
if (isScoped(observer)) { | ||
effects.push(observer); | ||
} else { | ||
tasks.push(observer); | ||
} | ||
} | ||
}); | ||
return this.e; | ||
} | ||
SCHEDULER.flush(); | ||
return this.d; | ||
} | ||
function removeSourceObservers(node, index) { | ||
let source, swap; | ||
for (let i3 = index; i3 < node.a.length; i3++) { | ||
source = node.a[i3]; | ||
if (source.b) { | ||
swap = source.b.indexOf(node); | ||
source.b[swap] = source.b[source.b.length - 1]; | ||
source.b.pop(); | ||
for (let i3 = index; i3 < node.b.length; i3++) { | ||
source = node.b[i3]; | ||
if (source.c) { | ||
swap = source.c.indexOf(node); | ||
source.c[swap] = source.c[source.c.length - 1]; | ||
source.c.pop(); | ||
} | ||
@@ -501,10 +511,10 @@ } | ||
function appendScope(node) { | ||
node.f = currentScope; | ||
if (currentScope.d) { | ||
const next = currentScope.d; | ||
currentScope.d = node; | ||
node.d = next; | ||
next.f = node; | ||
node.g = currentScope; | ||
if (currentScope.e) { | ||
const next = currentScope.e; | ||
currentScope.e = node; | ||
node.e = next; | ||
next.g = node; | ||
} else { | ||
currentScope.d = node; | ||
currentScope.e = node; | ||
} | ||
@@ -536,2 +546,15 @@ } | ||
} | ||
var RootScope = class RootScope2 { | ||
constructor() { | ||
if (currentScope) { | ||
this[SCOPE] = currentScope; | ||
appendScope(this); | ||
} | ||
} | ||
}; | ||
var RootScopeProto = RootScope.prototype; | ||
RootScopeProto[SCOPE] = null; | ||
RootScopeProto.g = null; | ||
RootScopeProto.e = null; | ||
RootScopeProto.call = dispose; | ||
@@ -541,3 +564,3 @@ // src/map.ts | ||
let items = [], mapped = [], disposal = [], signals = [], i3, len = 0; | ||
onDispose(() => runAll(disposal)); | ||
onDispose(() => emptyDisposal2(disposal)); | ||
return computed( | ||
@@ -549,3 +572,3 @@ () => { | ||
if (len !== 0) { | ||
runAll(disposal); | ||
emptyDisposal2(disposal); | ||
disposal = []; | ||
@@ -563,7 +586,7 @@ items = []; | ||
} else if (i3 >= items.length) { | ||
mapped[i3] = root(mapper); | ||
mapped[i3] = compute(new RootScope(), mapper, null); | ||
} | ||
} | ||
for (; i3 < items.length; i3++) | ||
disposal[i3](); | ||
disposal[i3].call(disposal[i3]); | ||
len = signals.length = disposal.length = newItems.length; | ||
@@ -573,4 +596,4 @@ items = newItems.slice(0); | ||
}); | ||
function mapper(dispose2) { | ||
disposal[i3] = dispose2; | ||
function mapper() { | ||
disposal[i3] = this; | ||
const $o = signal(newItems[i3]); | ||
@@ -586,3 +609,3 @@ signals[i3] = $o.set; | ||
let items = [], mapping = [], disposal = [], len = 0, indicies = map.length > 1 ? [] : null; | ||
onDispose(() => runAll(disposal)); | ||
onDispose(() => emptyDisposal2(disposal)); | ||
return computed( | ||
@@ -595,3 +618,3 @@ () => { | ||
if (len !== 0) { | ||
runAll(disposal); | ||
emptyDisposal2(disposal); | ||
disposal = []; | ||
@@ -607,3 +630,3 @@ items = []; | ||
items[j] = newItems[j]; | ||
mapping[j] = root(mapper); | ||
mapping[j] = compute(new RootScope(), mapper, null); | ||
} | ||
@@ -638,3 +661,3 @@ len = newLen; | ||
} else | ||
disposal[i3](); | ||
disposal[i3].call(disposal[i3]); | ||
} | ||
@@ -649,4 +672,5 @@ for (j = start; j < newLen; j++) { | ||
} | ||
} else | ||
mapping[j] = root(mapper); | ||
} else { | ||
mapping[j] = compute(new RootScope(), mapper, null); | ||
} | ||
} | ||
@@ -658,8 +682,7 @@ mapping = mapping.slice(0, len = newLen); | ||
}); | ||
function mapper(dispose2) { | ||
disposal[j] = dispose2; | ||
function mapper() { | ||
disposal[j] = this; | ||
if (indicies) { | ||
const $signal = signal(j); | ||
indicies[j] = $signal.set; | ||
$signal.set = void 0; | ||
return map(newItems[j], $signal); | ||
@@ -674,5 +697,5 @@ } | ||
var i2 = 0; | ||
function runAll(fns) { | ||
for (i2 = 0; i2 < fns.length; i2++) | ||
fns[i2](); | ||
function emptyDisposal2(disposal) { | ||
for (i2 = 0; i2 < disposal.length; i2++) | ||
disposal[i2].call(disposal[i2]); | ||
} | ||
@@ -682,3 +705,6 @@ export { | ||
HANDLERS, | ||
RootScope, | ||
SCOPE, | ||
TASKS, | ||
compute, | ||
computed, | ||
@@ -685,0 +711,0 @@ computedKeyedMap, |
@@ -1,4 +0,6 @@ | ||
export declare type BatchTasks = (queue: ScheduledTask[]) => void; | ||
export declare interface Callable<Args extends any[] = never, Return = void> { | ||
call(_this: any, ...args: Args): Return; | ||
} | ||
export declare interface Computation<T = any> { | ||
export declare interface Computation<T = any> extends Callable<never, T> { | ||
id?: string | undefined; | ||
@@ -10,3 +12,3 @@ [FLAGS]: number; | ||
_value: T; | ||
_disposal: Dispose[] | null; | ||
_disposal: Dispose | Dispose[] | null; | ||
_context: ContextRecord | null; | ||
@@ -19,2 +21,4 @@ _sources: Computation[] | null; | ||
export declare function compute<T extends Scope | null, R>(scope: T, compute: (this: T) => R, observer: Computation | null): R; | ||
/** | ||
@@ -83,4 +87,3 @@ * Creates a new signal whose value is computed and returned by the given function. The given | ||
export declare interface Dispose { | ||
(): void; | ||
export declare interface Dispose extends Callable { | ||
} | ||
@@ -208,11 +211,14 @@ | ||
export declare type ScheduledTask = () => void; | ||
export declare const RootScope: ScopeConstructor; | ||
export declare type Scheduler = { | ||
export declare interface ScheduledTask extends Callable { | ||
} | ||
export declare interface Scheduler { | ||
[TASKS]: () => ScheduledTask[]; | ||
enqueue: (task: ScheduledTask) => void; | ||
enqueueBatch: (batch: BatchTasks) => void; | ||
flush: () => void; | ||
flushSync: () => void; | ||
onFlush: (callback: () => void) => StopFlushUpdates; | ||
}; | ||
} | ||
@@ -224,2 +230,6 @@ export declare const SCOPE: unique symbol; | ||
export declare interface ScopeConstructor { | ||
new (): Scope; | ||
} | ||
/** | ||
@@ -268,4 +278,8 @@ * Runs the given function in the given scope so context and error handling continue to work. | ||
export declare type StopFlushUpdates = () => void; | ||
export declare interface StopFlushUpdates { | ||
(): void; | ||
} | ||
export declare const TASKS: unique symbol; | ||
/** | ||
@@ -272,0 +286,0 @@ * By default, signal updates are batched on the microtask queue which is an async process. You can |
@@ -5,3 +5,3 @@ { | ||
"license": "MIT", | ||
"version": "5.2.0", | ||
"version": "5.3.0", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "module": "dist/prod/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
68321
1635