Unverified Commit 6c76613c authored by Kyle Keating's avatar Kyle Keating Committed by GitHub

Improve typechecking for Stores (#2347)

Add SidebarStore type. This is an aggregation of the base ReduxStore + each one of our stores baked in. The fist store added here is simply the Activity store (as a first example)

There are some assumptions when making store types:

1. It is assumed they are transformed in `createStore` where the selectors and actions are flattened.

2. Some meta data (namely, the init method, namespace and update method) are refactored or removed.

These transformations are implied through the typing which explicitly ignores these methods and structure of the raw store before the transformation in create-store.
parent e94657f0
......@@ -24,7 +24,7 @@ import { createReducer, bindSelectors } from './util';
*
* @param {Object[]} modules
* @param {any[]} [initArgs] - Arguments to pass to each state module's `init` function
* @param {any[]} [middleware] - List of additional Redux middlewares to use.
* @param {any[]} [middleware] - List of additional Redux middlewares to use
*/
export default function createStore(modules, initArgs = [], middleware = []) {
// Create the initial state and state update function.
......
......@@ -47,6 +47,18 @@ import sidebarPanels from './modules/sidebar-panels';
import toastMessages from './modules/toast-messages';
import viewer from './modules/viewer';
/**
* // Base redux store
* @typedef {import("redux").Store} ReduxStore
*
* // Custom stores
* @typedef {import("./modules/activity").ActivityStore} ActivityStore
* // TODO: add more stores
*
* // Combine all stores
* @typedef {ReduxStore & ActivityStore} SidebarStore
*/
/**
* Factory which creates the sidebar app's state store.
*
......@@ -54,6 +66,9 @@ import viewer from './modules/viewer';
* the individual state modules. ie. `store.actionName(args)` dispatches an
* action through the store and `store.selectorName(args)` invokes a selector
* passing the current state of the store.
*
* @param {import('../../types/config').SidebarConfig} settings
* @return {SidebarStore}
*/
// @ngInject
export default function store(settings) {
......@@ -76,5 +91,9 @@ export default function store(settings) {
toastMessages,
viewer,
];
return createStore(modules, [settings], middleware);
return /** @type {SidebarStore} */ (createStore(
modules,
[settings],
middleware
));
}
......@@ -167,6 +167,26 @@ function isSavingAnnotation(state, annotation) {
return state.activeAnnotationSaveRequests.includes(annotation.$tag);
}
/** @typedef {import('../../../types/api').Annotation} Annotation */
/**
* @typedef ActivityStore
*
* // Actions
* @prop {typeof annotationFetchStarted} annotationFetchStarted
* @prop {typeof annotationFetchFinished} annotationFetchFinished
* @prop {typeof annotationSaveStarted} annotationSaveStarted
* @prop {typeof annotationSaveFinished} annotationSaveFinished
* @prop {typeof apiRequestStarted} apiRequestStarted
* @prop {typeof apiRequestFinished} apiRequestFinished
*
* // Selectors
* @prop {() => boolean} hasFetchedAnnotations
* @prop {() => boolean} isLoading
* @prop {() => boolean} isFetchingAnnotations
* @prop {(a: Annotation) => boolean} isSavingAnnotation
*/
export default {
init,
update,
......
......@@ -6,14 +6,14 @@ import shallowEqual from 'shallowequal';
import warnOnce from '../../shared/warn-once';
import { useService } from '../util/service-context';
/**
* @typedef {import("redux").Store} Store
*/
/** @typedef {import("redux").Store} Store */
/** @typedef {import("./index").SidebarStore} SidebarStore */
/**
* @template T
* @callback StoreCallback
* @param {Store} store
* @param {SidebarStore} store
* @return {T}
*/
......
......@@ -22,13 +22,7 @@
"sidebar/store/modules/*.js",
"sidebar/services/*.js",
"sidebar/util/*.js",
// TODO replace these with sidebar/store/* when all modules are converted
"sidebar/store/create-store.js",
"sidebar/store/debug-middleware.js",
"sidebar/store/use-store.js",
"sidebar/store/utils.js",
"sidebar/store/*.js",
],
"exclude": [
// Enable this once the rest of `src/sidebar` is checked.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment