diff --git a/docs/docs/.vitepress/config.ts b/docs/docs/.vitepress/config.ts index 2457f90..54248d2 100644 --- a/docs/docs/.vitepress/config.ts +++ b/docs/docs/.vitepress/config.ts @@ -106,6 +106,36 @@ const config: Partial> = { }, ] }, + { + text: 'Events', + collapsible: true, + collapsed: false, + items: [ + { + text: 'Event Bus', + link: '/events/', + items: [ + {text : 'Global Event Bus', link : '/events/#the-main-event-bus'}, + {text : 'Store Event Bus', link : '/events/#store-event-bus'}, + ] + }, + { + text: 'Typing', + link: '/events/typing', + }, + ] + }, + { + text: 'Testing', + collapsible: true, + collapsed: false, + items: [ + { + text: 'Setup', + link: '/testing/', + }, + ] + }, { text: 'Configuration', link: '/config/stores', diff --git a/docs/docs/core-concepts/extending-stores.md b/docs/docs/core-concepts/extending-stores.md index a7510da..2cd5ea5 100644 --- a/docs/docs/core-concepts/extending-stores.md +++ b/docs/docs/core-concepts/extending-stores.md @@ -44,13 +44,14 @@ Let's create `store_extensions.d.ts` in our project src dir ```typescript declare module '@idevelopthings/vue-class-stores/vue' { - export interface StoreCustomProperties { + interface StoreCustomProperties { apiBaseUrl: string; appVersion: string; getSomething(): string; } } +export {} ``` Now in our store: diff --git a/docs/docs/events/index.md b/docs/docs/events/index.md new file mode 100644 index 0000000..9d054fe --- /dev/null +++ b/docs/docs/events/index.md @@ -0,0 +1,109 @@ +## Event Bus + +### The main event bus + +The `StoreManager` has an event bus, this will allow us to register event listeners for anything, but also we can +dispatch events to all registered stores + +This is used for dispatching the lifecycle hooks, but will also be useful in applications. It can be accessed +via `StoreManager.bus.` + +#### Dispatching events + +```typescript +import {StoreManager} from '@idevelopthings/vue-class-stores/vue'; + +StoreManager.bus.$dispatch('event-name', {my: 'data'}); +``` + +#### Dispatching events to all stores + +```typescript +import {StoreManager} from '@idevelopthings/vue-class-stores/vue'; + +StoreManager.bus.$dispatchToAllStores('event-name', {my: 'data'}); +``` + +#### Listening for events + +```typescript +import {StoreManager} from '@idevelopthings/vue-class-stores/vue'; + +const listener = (message) => console.log(message); + +StoreManager.bus.$on('message', listener); +``` + +#### Removing listeners + +```typescript +import {StoreManager} from '@idevelopthings/vue-class-stores/vue'; + +const listener = (message) => console.log(message); + +// This way requires a reference to the handler function +StoreManager.bus.$off('message', listener); + +// We can also stop it this way +const stopListener = StoreManager.bus.$on('message', listener); +stopListener(); +``` + +### Store event bus + +Each store has their own event bus also, this will allow us to dispatch events to individual stores and more. + +This can be accessed via `myStore.$eventBus` + +#### Dispatching events + +```typescript +myStore.$dispatch('event-name', {my: 'data'}); +``` + +#### Listening for events + +```typescript +const listener = (message) => console.log(message); + +myStore.$on('message', listener); +``` + +We can also define event listeners on our store to handle these, they work very similarly to hooks + +```typescript +import {Store, On} from '@idevelopthings/vue-class-stores/vue'; + +type ITodoStore = { todos: Todo[] }; + +class TodoStore extends Store() { + get state() { + return {todos: []}; + } + + @On('todo:added') + todoAdded(todo: any) { + // this is triggered like a regular listener + } +} + +// We can now dispatch an event to it +todoStore.$dispatch('todo:added', {}) + +// If we had this @On('todo:added') decorator added to other stores +// also, we could call it on all stores via the store manager +StoreManager.bus.$dispatchToAllStores('todo:added', {}) +``` + +#### Removing listeners + +```typescript +const listener = (message) => console.log(message); + +// This way requires a reference to the handler function +myStore.$off('message', listener); + +// We can also stop it this way +const stopListener = myStore.$on('message', listener); +stopListener(); +``` \ No newline at end of file diff --git a/docs/docs/events/typing.md b/docs/docs/events/typing.md new file mode 100644 index 0000000..de05880 --- /dev/null +++ b/docs/docs/events/typing.md @@ -0,0 +1,21 @@ +## Typing events + +We can define a declaration file to provide some type information on the available keys and the event data. + +```typescript +declare module '@idevelopthings/vue-class-stores/vue' { + interface StoreEventsMap { + 'todo:added' : {todo: ITodo} + } +} + +export {}; +``` + +Now when we dispatch an event, we'll get completion: + +```typescript +// This will give type errors because our +// second param isn't `{todo: ITodo}` +store.$dispatch('todo:added', '...'); +``` \ No newline at end of file diff --git a/docs/docs/testing/index.md b/docs/docs/testing/index.md new file mode 100644 index 0000000..6b81d9c --- /dev/null +++ b/docs/docs/testing/index.md @@ -0,0 +1 @@ +# TBD \ No newline at end of file