]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
feat: allow empty state option to make it easy to group stores
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 20 Jan 2020 16:40:02 +0000 (17:40 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Mon, 20 Jan 2020 18:21:46 +0000 (19:21 +0100)
README.md
__tests__/store.spec.ts
src/pinia.ts [deleted file]
src/store.ts

index 4b250cb565f3fa00fc349176ef947717efbac2c2..7e35b884ed291a174fd817cc80354321d4ea4f7c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -287,7 +287,6 @@ import { useCartStore } from './cart'
 
 export const useSharedStore = createStore({
   id: 'shared',
-  state: () => ({}),
   getters: {
     summary() {
       const user = useUserStore()
index e2048f70c6c54e3e0a9460a196114a4cd98404a1..a0570ed3fd0e6b5ba8ef61c1e39c2dfb0a16ee6a 100644 (file)
@@ -29,6 +29,29 @@ describe('Store', () => {
     })
   })
 
+  it('can be reset', () => {
+    const store = useStore()
+    store.state.a = false
+    const spy = jest.fn()
+    store.subscribe(spy)
+    store.reset()
+    store.state.nested.foo = 'bar'
+    expect(spy).not.toHaveBeenCalled()
+    expect(store.state).toEqual({
+      a: true,
+      nested: {
+        foo: 'bar',
+        a: { b: 'string' },
+      },
+    })
+  })
+
+  it('can create an empty state if no state option is provided', () => {
+    const store = createStore({ id: 'some' })()
+
+    expect(store.state).toEqual({})
+  })
+
   it('can hydrate the state', () => {
     setActiveReq({})
     const useStore = createStore({
@@ -93,4 +116,39 @@ describe('Store', () => {
     store.state.nested.a.b = 'hey'
     expect(store2.state.nested.a.b).toBe('string')
   })
+
+  it('subscribe to changes', () => {
+    const store = useStore()
+    const spy = jest.fn()
+    store.subscribe(spy)
+
+    store.state.a = false
+
+    expect(spy).toHaveBeenCalledWith(
+      {
+        payload: {},
+        storeName: 'main',
+        type: expect.stringContaining('in place'),
+      },
+      store.state
+    )
+  })
+
+  it('subscribe to changes done via patch', () => {
+    const store = useStore()
+    const spy = jest.fn()
+    store.subscribe(spy)
+
+    const patch = { a: false }
+    store.patch(patch)
+
+    expect(spy).toHaveBeenCalledWith(
+      {
+        payload: patch,
+        storeName: 'main',
+        type: expect.stringContaining('patch'),
+      },
+      store.state
+    )
+  })
 })
diff --git a/src/pinia.ts b/src/pinia.ts
deleted file mode 100644 (file)
index 49907b3..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-import { Store, StoreGetter, StateTree, StoreWithGetters } from './types'
-import { CombinedStore, buildStore } from './store'
-
-export type CombinedState<
-  S extends Record<
-    string,
-    (
-      ...args: any[]
-    ) => CombinedStore<
-      string,
-      StateTree,
-      Record<string, StoreGetter<StateTree>>
-    >
-  >
-> = {
-  [k in keyof S]: S[k] extends (
-    ...args: any[]
-  ) => CombinedStore<
-    string,
-    infer State,
-    Record<string, StoreGetter<infer State>>
-  >
-    ? State
-    : never
-}
-
-export type CombinedGetters<
-  S extends Record<
-    string,
-    (
-      ...args: any[]
-    ) => CombinedStore<
-      string,
-      StateTree,
-      Record<string, StoreGetter<StateTree>>
-    >
-  >
-> = {
-  [k in keyof S]: S[k] extends (
-    ...args: any[]
-  ) => CombinedStore<string, infer State, infer Getters>
-    ? StoreWithGetters<State, Getters>
-    : never
-}
-
-function buildCombinedStore<
-  S extends Record<
-    string,
-    CombinedStore<string, StateTree, Record<string, StoreGetter<StateTree>>>
-  >
->(stores: S): Store<'', CombinedState<S>> & CombinedGetters<S> {
-  const state = {}
-  for (const name in stores) {
-    const store = stores[name]
-    Object.defineProperty(state, name, {
-      get: () => store.state,
-    })
-  }
-
-  // @ts-ignore
-  return {
-    state,
-  }
-}
-
-export function pinia<
-  S extends Record<
-    string,
-    (
-      ...args: any[]
-    ) => CombinedStore<
-      string,
-      StateTree,
-      Record<string, StoreGetter<StateTree>>
-    >
-  >
->(stores: S): Store<'', CombinedState<S>> & CombinedGetters<S> {
-  // TODO: implement if makes sense
-  const state = {}
-  for (const name in stores) {
-    const store = stores[name]()
-    Object.defineProperty(state, name, {
-      get: () => store.state,
-    })
-  }
-
-  // @ts-ignore
-  return {
-    state,
-  }
-}
index 711aef0d8aeab3eac78413acadff89e600f8189e..0c1f59488cfca3cae756fc139a716589a4fc8ebc 100644 (file)
@@ -8,7 +8,6 @@ import {
   StoreWithGetters,
   StoreGetter,
   NonNullObject,
-  StoreReactiveGetters,
 } from './types'
 import { useStoreDevtools } from './devtools'
 
@@ -61,25 +60,6 @@ export type Store<
   A extends Record<string, StoreAction>
 > = StoreWithState<Id, S> & StoreWithGetters<S, G> & StoreWithActions<A>
 
-export type WrapStoreWithId<
-  S extends Store<string, StateTree, any, any>
-> = S extends Store<infer Id, infer S, infer G, infer A>
-  ? {
-      [k in Id]: Store<Id, S, G, A>
-    }
-  : never
-
-export type ExtractGettersFromStore<S> = S extends Store<
-  any,
-  infer S,
-  infer G,
-  any
->
-  ? {
-      [k in keyof G]: ReturnType<G[k]>
-    }
-  : never
-
 export type PiniaStore<
   P extends Record<string, Store<any, any, any, any>>
 > = P extends Record<infer name, any>
@@ -107,7 +87,7 @@ export function buildStore<
   A extends Record<string, StoreAction>
 >(
   id: Id,
-  buildState: () => S,
+  buildState = () => ({} as S),
   getters: G = {} as G,
   actions: A = {} as A,
   initialState?: S | undefined
@@ -281,7 +261,7 @@ export function createStore<
   A extends Record<string, StoreAction>
 >(options: {
   id: Id
-  state: () => S
+  state?: () => S
   getters?: G
   // allow actions use other actions
   actions?: A & ThisType<A & StoreWithState<Id, S> & StoreWithGetters<S, G>>