pull/17217/merge
Simon H 13 hours ago committed by GitHub
commit 5f5ce0a56f
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`

@ -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';

@ -1016,6 +1016,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);
}
}
}
}
};
}

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