async-another-try
Simon Holthausen 4 days ago
parent b08aeee3cf
commit 3b92502f00
No known key found for this signature in database

@ -121,7 +121,7 @@ export class Batch {
/** True as soon as `#process` was called */
started = false;
linked = true;
linked = false;
/** @type {Batch | null} */
merged_into = null;
@ -253,35 +253,16 @@ export class Batch {
#decrement_queued = false;
constructor() {
// link batch
if (last_batch === null) {
first_batch = last_batch = this;
} else {
// Put the new batch before the first forked batch
let batch = first_batch;
while (batch && !batch.is_fork) {
batch = batch.next;
}
// Put the new batch before the first forked batch
let batch = first_batch;
while (batch && !batch.is_fork) {
batch = batch.next;
}
if (batch) {
const prev = batch.prev;
this.next = batch;
batch.prev = this;
if (prev) {
prev.next = this;
this.prev = prev;
} else {
first_batch = this;
}
while (batch) {
batch.id = uid++;
batch = batch.next;
}
} else {
last_batch.next = this;
this.prev = last_batch;
last_batch = this;
}
this.insert_before(batch);
while (batch) {
batch.id = uid++;
batch = batch.next;
}
}
@ -633,16 +614,10 @@ export class Batch {
#find_earlier_batch() {
if (this.is_eager) return null;
var batch = this.prev;
while (batch !== null) {
if (!batch.is_fork) {
if (this.dependent.has(batch)) {
return batch;
}
for (var batch = this.prev; batch !== null; batch = batch.prev) {
if (!batch.is_fork && this.dependent.has(batch)) {
return batch;
}
batch = batch.prev;
}
return null;
@ -865,16 +840,20 @@ export class Batch {
))
) {
batch.current.delete(source);
const b = batch;
queue_micro_task(() => {
if (b.linked && b.mark(source, DIRTY)) {
b.flush();
}
});
batch.queue_revalidation(source);
}
}
}
/** @param {Value} source */
queue_revalidation(source) {
queue_micro_task(() => {
if (this.linked && this.mark(source, DIRTY)) {
this.flush();
}
});
}
/**
* Activate batch - could be merged into another batch in the meantime,
* in which case that other batch becomes the active batch.
@ -1106,6 +1085,21 @@ export class Batch {
this.#scheduled.push(effect);
}
/** @param {Batch | null} next `null` appends to the end of the list */
insert_before(next) {
this.#unlink();
this.prev = next === null ? last_batch : next.prev;
this.next = next;
if (this.prev === null) first_batch = this;
else this.prev.next = this;
if (next === null) last_batch = this;
else next.prev = this;
this.linked = true;
}
#unlink() {
// #merge calls #unlink, discard later on does it again - prevent
// running it multiple times to not corrupt the linked list
@ -1526,21 +1520,16 @@ export function fork(fn) {
batch.is_fork = false;
// Reorder the batches such that there's no forks before this one
while (batch.prev && batch.prev.is_fork) {
let prev = /** @type {Batch} */ (batch.prev);
// Keep IDs in order, then move the batch before all remaining forks
let before = batch;
while (before.prev?.is_fork) {
const prev = before.prev;
const id = batch.id;
batch.id = prev.id;
prev.id = id;
prev.next = batch.next;
if (prev.next) prev.next.prev = prev;
else last_batch = prev;
batch.prev = prev.prev;
if (batch.prev) batch.prev.next = batch;
else first_batch = batch;
batch.next = prev;
prev.prev = batch;
before = prev;
}
if (before !== batch) batch.insert_before(before);
// Apply changes and update write versions so deriveds see the change. Everything still
// in `batch.current` at this point is the latest value: sources that the real world has
@ -1602,12 +1591,7 @@ export function fork(fn) {
if (next_batch.current.has(source)) {
batch.notify_fork(next_batch, source, is_derived, value);
} else if (!is_derived) {
const b = next_batch;
queue_micro_task(() => {
if (b.linked && b.mark(source, DIRTY)) {
b.flush();
}
});
next_batch.queue_revalidation(source);
}
}
next_batch = next_batch.next;

Loading…
Cancel
Save