Commit 12a1dc4e authored by Robert Knight's avatar Robert Knight

Improve `initialState` definitions in store modules

Convert the `initialState` functions in store modules to `const` values
for modules where the state is static (ie. does not depend on
`settings`) and add better type documentation.

Most references to the state are not currently type-checked, but they
will be in future. In the interim this serves as useful documentation
for humans.
parent f5833aeb
......@@ -6,31 +6,33 @@
import { actionTypes } from '../util';
import { createStoreModule } from '../create-store';
function initialState() {
return {
/**
* Annotation `$tag`s that correspond to annotations with active API requests
*/
activeAnnotationSaveRequests: [],
/**
* The number of API requests that have started and not yet completed.
*/
activeApiRequests: 0,
/**
* The number of annotation fetches that have started and not yet completed.
*/
activeAnnotationFetches: 0,
/**
* Have annotations ever been fetched?
*/
hasFetchedAnnotations: false,
/**
* The number of total annotation results the service reported as
* matching the most recent load/search request
*/
annotationResultCount: null,
};
}
const initialState = {
/**
* Annotation `$tag`s that correspond to annotations with active API requests
*
* @type {string[]}
*/
activeAnnotationSaveRequests: [],
/**
* The number of API requests that have started and not yet completed.
*/
activeApiRequests: 0,
/**
* The number of annotation fetches that have started and not yet completed.
*/
activeAnnotationFetches: 0,
/**
* Have annotations ever been fetched?
*/
hasFetchedAnnotations: false,
/**
* The number of total annotation results the service reported as
* matching the most recent load/search request
*
* @type {number|null}
*/
annotationResultCount: null,
};
const reducers = {
API_REQUEST_STARTED(state) {
......
......@@ -89,21 +89,30 @@ function initializeAnnotation(annotation, tag) {
});
}
function initialState() {
return {
/** @type {Annotation[]} */
annotations: [],
// A set of annotations that are currently "focused" — e.g. hovered over in
// the UI
focused: {},
// A map of annotations that should appear as "highlighted", e.g. the
// target of a single-annotation view
highlighted: {},
// The local tag to assign to the next annotation that is loaded into the
// app
nextTag: 1,
};
}
const initialState = {
/**
* Set of all currently loaded annotations.
*
* @type {Annotation[]}
*/
annotations: [],
/**
* A set of annotations that are currently "focused" — e.g. hovered over in
* the UI.
*
* @type {Record<string, boolean>}
*/
focused: {},
/**
* A map of annotations that should appear as "highlighted", e.g. the
* target of a single-annotation view
*
* @type {Record<string, boolean>}
*/
highlighted: {},
/** The local tag to assign to the next annotation that is loaded into the app. */
nextTag: 1,
};
const reducers = {
ADD_ANNOTATIONS: function (state, action) {
......
......@@ -16,18 +16,10 @@ import { createStoreModule } from '../create-store';
* `persistedDefaults` service.
*/
function initialState() {
/**
* Note that the persisted presence of any of these defaults cannot be
* guaranteed, so consumers of said defaults should be prepared to handle
* missing (i.e. `null`) values. As `null` is a sentinal value indicating
* "not set/unavailable", a `null` value for a default is otherwise invalid.
*/
return {
annotationPrivacy: null,
focusedGroup: null,
};
}
const initialState = {
annotationPrivacy: /** @type {'private'|'shared'|null} */ (null),
focusedGroup: /** @type {string|null} */ (null),
};
const reducers = {
SET_DEFAULT: function (state, action) {
......
......@@ -11,9 +11,8 @@ import { createStoreModule } from '../create-store';
* existing annotations.
*/
function initialState() {
return [];
}
/** @type {Draft[]} */
const initialState = [];
/**
* Helper class to encapsulate the draft properties and a few simple methods.
......
......@@ -20,10 +20,8 @@ import { createStoreModule } from '../create-store';
* @prop {string} uri - Current primary URI of the document being displayed
*/
function initialState() {
// The list of frames connected to the sidebar app
return [];
}
/** @type {Frame[]} */
const initialState = [];
const reducers = {
CONNECT_FRAME: function (state, action) {
......
......@@ -9,21 +9,19 @@ import session from './session';
* @typedef {import('../../../types/api').Group} Group
*/
function initialState() {
return {
/**
* List of groups.
* @type {Group[]}
*/
groups: [],
/**
* ID of currently selected group.
* @type {string|null}
*/
focusedGroupId: null,
};
}
const initialState = {
/**
* List of groups.
* @type {Group[]}
*/
groups: [],
/**
* ID of currently selected group.
* @type {string|null}
*/
focusedGroupId: null,
};
const reducers = {
FOCUS_GROUP(state, action) {
......
......@@ -2,9 +2,7 @@ import { actionTypes } from '../util';
import { replaceURLParams } from '../../util/url';
import { createStoreModule } from '../create-store';
function initialState() {
return null;
}
const initialState = /** @type {Record<string, string>|null} */ (null);
const reducers = {
UPDATE_LINKS(state, action) {
......
......@@ -16,17 +16,23 @@ import annotations from './annotations';
import groups from './groups';
import route from './route';
function initialState() {
return {
// Map of ID -> updated annotation for updates that have been received over
// the WebSocket but not yet applied
pendingUpdates: {},
// Set of IDs of annotations which have been deleted but for which the
// deletion has not yet been applied
pendingDeletions: {},
};
}
const initialState = {
/**
* Map of ID -> updated annotation for updates that have been received over
* the WebSocket but not yet applied
*
* @type {Record<string, Annotation>}
*/
pendingUpdates: {},
/**
* Set of IDs of annotations which have been deleted but for which the
* deletion has not yet been applied
*
* @type {Record<string, boolean>}
*/
pendingDeletions: {},
};
const reducers = {
RECEIVE_REAL_TIME_UPDATES(state, action) {
......
......@@ -2,24 +2,29 @@ import { actionTypes } from '../util';
import { createStoreModule } from '../create-store';
function initialState() {
return {
/**
* The current route.
* One of null (if no route active yet), "sidebar", "annotation" or "stream".
*/
name: null,
/**
* @typedef {'annotation'|'notebook'|'sidebar'|'stream'} RouteName
*/
/**
* Parameters of the current route.
*
* - The "annotation" route has an "id" (annotation ID) parameter.
* - The "stream" route has a "q" (query) parameter.
* - The "sidebar" route has no parameters.
*/
params: {},
};
}
const initialState = {
/**
* The current route.
*
* @type {RouteName|null}
*/
name: null,
/**
* Parameters of the current route.
*
* - The "annotation" route has an "id" (annotation ID) parameter.
* - The "stream" route has a "q" (query) parameter.
* - The "sidebar" route has no parameters.
*
* @type {Record<string, string>}
*/
params: {},
};
const reducers = {
CHANGE_ROUTE(state, { name, params }) {
......
......@@ -16,21 +16,20 @@ import * as util from '../util';
import { createStoreModule } from '../create-store';
function initialState() {
return {
/*
* The `panelName` of the currently-active sidebar panel.
* Only one `panelName` may be active at a time, but it is valid (though not
* the standard use case) for multiple `SidebarPanel` components to share
* the same `panelName`—`panelName` is not intended as a unique ID/key.
*
* e.g. If `activePanelName` were `foobar`, all `SidebarPanel` components
* with `panelName` of `foobar` would be active, and thus visible.
*
*/
activePanelName: null,
};
}
const initialState = {
/*
* The `panelName` of the currently-active sidebar panel.
* Only one `panelName` may be active at a time, but it is valid (though not
* the standard use case) for multiple `SidebarPanel` components to share
* the same `panelName`—`panelName` is not intended as a unique ID/key.
*
* e.g. If `activePanelName` were `foobar`, all `SidebarPanel` components
* with `panelName` of `foobar` would be active, and thus visible.
*
* @type {PanelName|null}
*/
activePanelName: null,
};
const reducers = {
OPEN_SIDEBAR_PANEL: function (state, action) {
......
......@@ -16,11 +16,11 @@ import * as util from '../util';
* maintains state only; it's up to other layers to handle the management
* and interactions with these messages.
*/
function initialState() {
return {
messages: [],
};
}
const initialState = {
/** @type {ToastMessage[]} */
messages: [],
};
const reducers = {
ADD_MESSAGE: function (state, action) {
......
......@@ -7,14 +7,14 @@ import { createStoreModule } from '../create-store';
* sidebar.
*/
function initialState() {
return {
// Has the sidebar ever been opened? NB: This is not necessarily the
// current state of the sidebar, but tracks whether it has ever been open
sidebarHasOpened: false,
visibleHighlights: false,
};
}
const initialState = {
/**
* Has the sidebar ever been opened? NB: This is not necessarily the
* current state of the sidebar, but tracks whether it has ever been open
*/
sidebarHasOpened: false,
visibleHighlights: false,
};
const reducers = {
SET_HIGHLIGHTS_VISIBLE: function (state, action) {
......
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