blob: f4603b7fbb529fb9ce5536e81fcec6cba9901d00 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001// Copyright 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import {connect} from 'pwa-helpers/connect-mixin.js';
6import {applyMiddleware, combineReducers, compose, createStore} from 'redux';
7import thunk from 'redux-thunk';
8import {hotlists} from './hotlists.js';
9import * as issueV0 from './issueV0.js';
10import * as permissions from './permissions.js';
11import * as projects from './projects.js';
12import * as projectV0 from './projectV0.js';
13import * as sitewide from './sitewide.js';
14import {stars} from './stars.js';
15import * as users from './users.js';
16import * as userV0 from './userV0.js';
17import * as ui from './ui.js';
18
19/** @typedef {import('redux').AnyAction} AnyAction */
20
21// Actions
22const RESET_STATE = 'RESET_STATE';
23
24/* State Shape
25{
26 hotlists: Object,
27 permissions: Object,
28 projects: Object,
29 sitewide: Object,
30 users: Object,
31
32 ui: Object,
33
34 // To be deprecated
35 issue: Object,
36 projectV0: Object,
37 userV0: Object,
38}
39*/
40
41// Reducers
42const reducer = combineReducers({
43 hotlists: hotlists.reducer,
44 issue: issueV0.reducer,
45 permissions: permissions.reducer,
46 projects: projects.reducer,
47 projectV0: projectV0.reducer,
48 users: users.reducer,
49 userV0: userV0.reducer,
50 sitewide: sitewide.reducer,
51 stars: stars.reducer,
52
53 ui: ui.reducer,
54});
55
56/**
57 * The top level reducer function that all actions pass through.
58 * @param {any} state
59 * @param {AnyAction} action
60 * @return {any}
61 */
62export function rootReducer(state, action) {
63 if (action.type === RESET_STATE) {
64 state = undefined;
65 }
66 return reducer(state, action);
67}
68
69// Selectors
70
71// Action Creators
72
73/**
74 * Changes Redux state back to its default initial state. Primarily
75 * used in testing.
76 * @return {AnyAction} An action to reset Redux state to default.
77 */
78export const resetState = () => ({type: RESET_STATE});
79
80// Store
81
82// For debugging with the Redux Devtools extension:
83// https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd/
84const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
85export const store = createStore(rootReducer, composeEnhancers(
86 applyMiddleware(thunk),
87));
88
89/**
90 * Class mixin function that connects a given HTMLElement class to our
91 * store instance.
92 * @link https://pwa-starter-kit.polymer-project.org/redux-and-state-management#connecting-an-element-to-the-store
93 * @param {typeof HTMLElement} class
94 * @return {function} New class type with connected features.
95 */
96export const connectStore = connect(store);
97
98/**
99 * Promise to allow waiting for a state update. Useful in testing.
100 * @example
101 * store.dispatch(updateState());
102 * await stateUpdated;
103 * doThingWithUpdatedState();
104 *
105 * @type {Promise}
106 */
107export const stateUpdated = new Promise((resolve) => {
108 store.subscribe(resolve);
109});