feat: add `isCommitted/isDiscarded/run` to `fork`

This gives more insight into the state of a fork and also gives you the ability to run another function in the context of the fork. SvelteKit needs this
fork-methods
Simon Holthausen 8 months ago
parent 1aafbc47ff
commit 824b3f41a4

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

@ -366,6 +366,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';

@ -1014,6 +1014,37 @@ export function fork(fn) {
batches.delete(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);
}
}
}
}
};
}

@ -363,6 +363,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