Skip to content

Commit

Permalink
feat: destroy a store with $dispose
Browse files Browse the repository at this point in the history
Close #557
  • Loading branch information
posva committed Aug 19, 2021
1 parent 2b3aa5f commit 75db6be
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 1 deletion.
23 changes: 23 additions & 0 deletions packages/pinia/__tests__/store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,27 @@ describe('Store', () => {
expect(One.text()).toBe('1')
expect(Two.text()).toBe('1')
})

it('can be disposed', () => {
const pinia = createPinia()
const useStore = defineStore({
id: 'main',
state: () => ({ n: 0 }),
})

const store = useStore(pinia)
const spy = jest.fn()

store.$subscribe(spy)
pinia.state.value.main.n++
expect(spy).toHaveBeenCalledTimes(1)

expect(useStore()).toBe(store)
store.$dispose()
pinia.state.value.main.n++

expect(spy).toHaveBeenCalledTimes(1)

expect(useStore()).not.toBe(store)
})
})
11 changes: 10 additions & 1 deletion packages/pinia/src/devtools/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,20 @@ function addStoreToDevtools(app: App, store: StoreGeneric) {
api.sendInspectorState(INSPECTOR_ID)
})

const { $dispose } = store
store.$dispose = () => {
$dispose()
api.notifyComponentUpdate()
api.sendInspectorTree(INSPECTOR_ID)
api.sendInspectorState(INSPECTOR_ID)
toastMessage(`Disposed "${store.$id}" store 🗑`)
}

// trigger an update so it can display new registered stores
api.notifyComponentUpdate()
api.sendInspectorTree(INSPECTOR_ID)
api.sendInspectorState(INSPECTOR_ID)
toastMessage(`"${store.$id}" store installed`)
toastMessage(`"${store.$id}" store installed 🆕`)
}
)
}
Expand Down
8 changes: 8 additions & 0 deletions packages/pinia/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,13 @@ function createSetupStore<
}
: noop

function $dispose() {
scope.stop()
subscriptions = []
actionSubscriptions = []
pinia._s.delete($id)
}

/**
* Wraps an action to handle subscriptions.
*
Expand Down Expand Up @@ -448,6 +455,7 @@ function createSetupStore<

return removeSubscription
},
$dispose,
} as StoreWithState<Id, S, G, A>

const store: Store<Id, S, G, A> = reactive(
Expand Down
8 changes: 8 additions & 0 deletions packages/pinia/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,14 @@ export interface StoreWithState<
callback: StoreOnActionListener<Id, S, G, A>,
detached?: boolean
): () => void

/**
* Stops the associated effect scope of the store and remove it from the store
* registry. Plugins can override this method to cleanup any added effects.
* e.g. devtools plugin remove its listeners and stops displaying it from
* devtools.
*/
$dispose(): void
}

/**
Expand Down

0 comments on commit 75db6be

Please sign in to comment.