Simon H 2 days ago committed by GitHub
commit e454952da5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': minor
---
feat: add `isCommitted/isDiscarded/run` to `fork`

@ -372,6 +372,18 @@ export interface Fork {
* Discard the fork
*/
discard(): void;
/**
* Whether the fork has been committed
*/
isCommitted(): boolean;
/**
* Whether the fork has been discarded
*/
isDiscarded(): boolean;
/**
* Run a function within the forked context.
*/
run(fn: () => void): Promise<void>;
}
export * from './index-client.js';

@ -1187,6 +1187,37 @@ export function fork(fn) {
if (!committed && batches.has(batch)) {
batch.discard();
}
},
isCommitted: () => committed,
isDiscarded: () => !committed && !batches.has(batch),
run: async (fn) => {
if (committed) {
// TODO error instead?
await settled;
fn();
} else {
// We want to start with the current state of the world, not the
// state back when the fork was created. Also important to
// correctly revert state changes later
const previous = batch.previous;
batch.previous = new Map();
batch.activate();
flushSync(fn);
// revert state changes
for (var [source, value] of batch.previous) {
source.v = value;
}
// merge 'previous' map
// TODO is this correct?
for (const [source, value] of previous) {
if (!batch.previous.has(source)) {
batch.previous.set(source, value);
}
}
}
}
};
}

@ -371,6 +371,18 @@ declare module 'svelte' {
* Discard the fork
*/
discard(): void;
/**
* Whether the fork has been committed
*/
isCommitted(): boolean;
/**
* Whether the fork has been discarded
*/
isDiscarded(): boolean;
/**
* Run a function within the forked context.
*/
run(fn: () => void): Promise<void>;
}
/**
* Returns an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) that aborts when the current [derived](https://svelte.dev/docs/svelte/$derived) or [effect](https://svelte.dev/docs/svelte/$effect) re-runs or is destroyed.

Loading…
Cancel
Save