]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
refactor: use id instead of name
authorEduardo San Martin Morote <posva13@gmail.com>
Sat, 23 Nov 2019 12:05:53 +0000 (13:05 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Sat, 23 Nov 2019 12:05:55 +0000 (13:05 +0100)
src/devtools.ts
src/index.ts
src/types.ts
src/useStore.ts [new file with mode: 0644]

index 926239d7ffea47e084e3cf50f01f2eb19ae847a2..d2b92347102f43175ea9a2379c95a6d4e9ab4cab 100644 (file)
@@ -29,7 +29,7 @@ interface RootState {
 
 let rootStore: RootState
 
-export function devtoolPlugin<S extends StateTree>(store: Store<S>) {
+export function devtoolPlugin(store: Store<string, StateTree>) {
   if (!devtoolHook) return
 
   if (!rootStore) {
@@ -57,26 +57,26 @@ export function devtoolPlugin<S extends StateTree>(store: Store<S>) {
     devtoolHook.emit('vuex:init', rootStore)
   }
 
-  rootStore.state[store.name] = store.state
+  rootStore.state[store.id] = store.state
 
   // tell the devtools we added a module
-  rootStore.registerModule(store.name, store)
+  rootStore.registerModule(store.id, store)
 
-  Object.defineProperty(rootStore.state, store.name, {
+  Object.defineProperty(rootStore.state, store.id, {
     get: () => store.state,
     set: state => store.replaceState(state),
   })
 
   // Vue.set(rootStore.state, store.name, store.state)
   // the trailing slash is removed by the devtools
-  rootStore._modulesNamespaceMap[store.name + '/'] = true
+  rootStore._modulesNamespaceMap[store.id + '/'] = true
 
   devtoolHook.on('vuex:travel-to-state', targetState => {
-    store.replaceState(targetState[store.name] as S)
+    store.replaceState(targetState[store.id])
   })
 
   store.subscribe((mutation, state) => {
-    rootStore.state[store.name] = state
+    rootStore.state[store.id] = state
     devtoolHook.emit(
       'vuex:mutation',
       {
index a23671fea6828445195ae4418eea6d642cd111f7..bca3d75b022d6664e058b5de1feda60d69b41df3 100644 (file)
@@ -43,11 +43,22 @@ function innerPatch<T extends StateTree>(
   return target
 }
 
-export function createStore<S extends StateTree>(
-  name: string,
+/**
+ * NOTE: by allowing users to name stores correctly, they can nest them the way
+ * they want, no? like user/cart
+ */
+
+/**
+ * Creates a store instance
+ * @param id unique identifier of the store, like a name. eg: main, cart, user
+ * @param initialState initial state applied to the store, Must be correctly typed to infer typings
+ */
+
+export function createStore<Id extends string, S extends StateTree>(
+  id: Id,
   initialState: S
   // methods: Record<string | symbol, StoreMethod>
-): Store<S> {
+): Store<Id, S> {
   const { state, replaceState } = createState(initialState)
 
   let isListening = true
@@ -58,7 +69,7 @@ export function createStore<S extends StateTree>(
     state => {
       if (isListening) {
         subscriptions.forEach(callback => {
-          callback({ storeName: name, type: '🧩 in place', payload: {} }, state)
+          callback({ storeName: id, type: '🧩 in place', payload: {} }, state)
         })
       }
     },
@@ -74,7 +85,7 @@ export function createStore<S extends StateTree>(
     isListening = true
     subscriptions.forEach(callback => {
       callback(
-        { storeName: name, type: '⤵️ patch', payload: partialState },
+        { storeName: id, type: '⤵️ patch', payload: partialState },
         state.value
       )
     })
@@ -85,8 +96,8 @@ export function createStore<S extends StateTree>(
     // TODO: return function to remove subscription
   }
 
-  const store: Store<S> = {
-    name,
+  const store: Store<Id, S> = {
+    id,
     // it is replaced below by a getter
     state: state.value,
 
@@ -110,6 +121,28 @@ export function createStore<S extends StateTree>(
   return store
 }
 
+function makeStore<Id extends string, S extends StateTree>(
+  id: Id,
+  initialState: S
+) {
+  let store: Store<Id, S> | undefined
+
+  function useStore(): Store<Id, S> {
+    if (!store) store = createStore(id, initialState)
+
+    return store
+  }
+
+  function clear(): void {
+    store = undefined
+  }
+
+  return {
+    useStore,
+    clear,
+  }
+}
+
 // export const store = createStore('main', initialState)
 // export const cartStore = createStore('cart', {
 //   items: ['thing 1'],
index ff717369668c61735794bdcb31c8d402a6fd2b28..76cce8eb61fc4b2fbd5f707b055f6b977804f915 100644 (file)
@@ -50,18 +50,39 @@ export type SubscriptionCallback<S> = (
   state: S
 ) => void
 
-export interface Store<S extends StateTree> {
-  name: string
+export interface Store<Id extends string, S extends StateTree> {
+  /**
+   * Unique identifier of the store
+   */
+  id: Id
 
+  /**
+   * State of the Store
+   */
   state: S
+  /**
+   * Applies a state patch to current state. Allows passing nested values
+   * @param partialState patch to apply to the state
+   */
   patch(partialState: DeepPartial<S>): void
 
+  /**
+   * Replaces current state with a completely new version.
+   * @param newState state object to replace current state
+   */
   replaceState(newState: S): void
+  /**
+   * Setups a callback to be called whenever the state changes.
+   * @param callback callback that is called whenever the state changes
+   */
   subscribe(callback: SubscriptionCallback<S>): void
 }
 
 export interface DevtoolHook {
-  on(event: string, callback: (targetState: StateTree) => void): void
+  on(
+    event: string,
+    callback: (targetState: Record<string, StateTree>) => void
+  ): void
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
   emit(event: string, ...payload: any[]): void
 }
diff --git a/src/useStore.ts b/src/useStore.ts
new file mode 100644 (file)
index 0000000..e69de29