Skip to content

Instantly share code, notes, and snippets.

@dimfeld
Last active June 25, 2020 15:54
Show Gist options
  • Save dimfeld/0ff834a2fcd6f7bf575eeb21471c290e to your computer and use it in GitHub Desktop.
Save dimfeld/0ff834a2fcd6f7bf575eeb21471c290e to your computer and use it in GitHub Desktop.
Immer Store
import { writable, Readable } from 'svelte/store';
import { produce, enableAllPlugins } from 'immer';
enableAllPlugins();
export interface ImmerStore<T> {
update: (updateFn: (draft: T) => T | void) => T;
subscribe: Readable<T>['subscribe'];
}
export default function immerStore<T = any>(initialValue: T): ImmerStore<T> {
let store = writable<T>(initialValue);
let update = (updateFn: (draft: T) => T | void) => {
let ret;
store.update((value) => {
ret = produce(value, updateFn) as T;
return ret;
});
return ret;
};
return {
update,
subscribe: store.subscribe,
};
}
@dimfeld
Copy link
Author

dimfeld commented Jun 24, 2020

The idea behind Immer is to keep the objects immutable while retaining the convenience of mutable-style code. If you're ok with mutating then the version with the writable is fine, though I believe you would have to return { ...obj } to make sure that update sees that it actually changed.

As for this:

$i.a.b.c.d.push(newValue)
$i = $i

The immer store as written in the Gist doesn't expose a set method. You could add one. Generally the first line would not work though since once Immer starts using an object it throws an error if you mutate the object outside immer's produce function. That may only happen in development mode though.

@opensas
Copy link

opensas commented Jun 25, 2020

The idea behind Immer is to keep the objects immutable while retaining the convenience of mutable-style code.

Yes, that's exactly what I have in mind. I wish it could be almost transparent to work with stores in an immutable way, that's why I asked about auto-subscription support. Also, getting rid of the $i = $i would be nice, it still brings visual noise to my eyes.

I think that if it gets polished, an immutable store would be a great addition to svelte's arsenal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment