describe('createStore', () => {
it('sets the initial state', () => {
- const state = {
+ const state = () => ({
a: true,
nested: {
a: { b: 'string' },
},
- }
+ })
+
const store = createStore('main', state)
expect(store.state).toEqual({
a: true,
--- /dev/null
+import { createStore } from '../src'
+
+describe('store.patch', () => {
+ function buildStore() {
+ return createStore('main', () => ({
+ // TODO: the boolean cas shouldn't be necessary
+ // https://www.typescriptlang.org/play/#code/MYewdgzgLgBCMF4YG8CwAoGWYEMBcMUATgK4CmGAvhhiAHQ6IwBmOANhBehqJLMETI4oZJgAoAlIgB8MMclwFi5GJQk10vaDGBMBQkZI3AGTVhzJA
+ a: true as boolean,
+ nested: {
+ foo: 'foo',
+ a: { b: 'string' },
+ },
+ }))
+ }
+
+ it('patches a property without touching the rest', () => {
+ const store = buildStore()
+ store.patch({ a: false })
+ expect(store.state).toEqual({
+ a: false,
+ nested: {
+ foo: 'foo',
+ a: { b: 'string' },
+ },
+ })
+ })
+
+ it('patches a nested property without touching the rest', () => {
+ const store = buildStore()
+ store.patch({ nested: { foo: 'bar' } })
+ expect(store.state).toEqual({
+ a: true,
+ nested: {
+ foo: 'bar',
+ a: { b: 'string' },
+ },
+ })
+ store.patch({ nested: { a: { b: 'hello' } } })
+ expect(store.state).toEqual({
+ a: true,
+ nested: {
+ foo: 'bar',
+ a: { b: 'hello' },
+ },
+ })
+ })
+
+ it('patches multiple properties at the same time', () => {
+ const store = buildStore()
+ store.patch({ a: false, nested: { foo: 'hello' } })
+ expect(store.state).toEqual({
+ a: false,
+ nested: {
+ foo: 'hello',
+ a: { b: 'string' },
+ },
+ })
+ })
+})
} from './types'
import { devtoolPlugin } from './devtools'
-function createState<S extends StateTree>(initialState: S) {
- const state: Ref<S> = ref(initialState)
-
- // type State = UnwrapRef<typeof state>
-
- function replaceState(newState: S) {
- state.value = newState
- }
-
- return {
- state,
- replaceState,
- }
-}
-
function innerPatch<T extends StateTree>(
target: T,
patchToApply: DeepPartial<T>
export function createStore<Id extends string, S extends StateTree>(
id: Id,
- initialState: S
+ buildState: () => S
// methods: Record<string | symbol, StoreMethod>
): Store<Id, S> {
- const { state, replaceState } = createState(initialState)
+ const state: Ref<S> = ref(buildState())
+ function replaceState(newState: S) {
+ state.value = newState
+ }
let isListening = true
const subscriptions: SubscriptionCallback<S>[] = []
function makeStore<Id extends string, S extends StateTree>(
id: Id,
- initialState: S
+ buildState: () => S
) {
let store: Store<Id, S> | undefined
function useStore(): Store<Id, S> {
- if (!store) store = createStore(id, initialState)
+ if (!store) store = createStore(id, buildState)
return store
}