UNPKG

@craftercms/studio-ui

Version:

Services, components, models & utils to build CrafterCMS authoring extensions.

178 lines (176 loc) 6.9 kB
/* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright (C) 2007-2022 Crafter Software Corporation. All Rights Reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === 'function') for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { configureStore } from '@reduxjs/toolkit'; import reducer from './reducers/root'; import { createEpicMiddleware } from 'redux-observable'; import epic from './epics/root'; import { BehaviorSubject, forkJoin, fromEvent, Observable, of } from 'rxjs'; import { filter, map, pluck, switchMap, take, tap } from 'rxjs/operators'; import { fetchGlobalProperties, me } from '../services/users'; import { exists, fetchAll } from '../services/sites'; import { getCurrentIntl } from '../utils/i18n'; import { getSiteCookie, removeSiteCookie, setJwt } from '../utils/auth'; import { storeInitialized } from './actions/system'; import { sharedWorkerConnect, sharedWorkerDisconnect, sharedWorkerToken, sharedWorkerUnauthenticated } from './actions/auth'; import { SHARED_WORKER_NAME } from '../utils/constants'; import { fetchActiveEnvironment } from '../services/environment'; let store$; export function getStore() { if (store$) { return store$.pipe( filter((store) => store !== null), take(1) ); } else { store$ = new BehaviorSubject(null); return registerSharedWorker().pipe( tap(({ token }) => setJwt(token)), switchMap((_a) => { var { worker } = _a, auth = __rest(_a, ['worker']); return of(createStoreSync({ dependencies: { worker } })).pipe( switchMap((store) => fetchStateInitialization().pipe( tap((requirements) => { worker.port.onmessage = (e) => { var _a; if ((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) { store.dispatch(e.data); } }; store.dispatch(storeInitialized(Object.assign({ auth }, requirements))); store$.next(store); }) ) ) ); }), switchMap(() => store$.pipe(take(1))) ); } } function registerSharedWorker() { if ('SharedWorker' in window) { const worker = new SharedWorker(`${process.env.PUBLIC_URL}/shared-worker.js`, { name: SHARED_WORKER_NAME, credentials: 'same-origin' }); worker.port.start(); worker.port.postMessage(sharedWorkerConnect()); window.addEventListener('beforeunload', function () { worker.port.postMessage(sharedWorkerDisconnect()); }); return fromEvent(worker.port, 'message').pipe( tap((e) => { var _a; if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) === sharedWorkerUnauthenticated.type) { const elem = document.createElement('div'); elem.style.textAlign = 'center'; elem.style.margin = '20px 0'; elem.innerHTML = 'User not authenticated.'; setTimeout(() => { window.location.reload(); }, 800); throw new Error('User not authenticated.'); } }), filter((e) => { var _a; return ((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) === sharedWorkerToken.type; }), take(1), pluck('data', 'payload'), map((response) => Object.assign(Object.assign({}, response), { worker })) ); } else { return new Observable((observer) => { observer.error( ['iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod'].includes(navigator.platform) ? 'iOS is not supported as it lacks essential features. Please use Chrome or Firefox browsers on your desktop.' : 'Your browser is not supported as it lacks essential features. Please use Chrome or Firefox.' ); }); } } export function getStoreSync() { return store$ === null || store$ === void 0 ? void 0 : store$.value; } export function createStoreSync(args = {}) { const { preloadedState, dependencies } = args; const epicMiddleware = createEpicMiddleware({ dependencies: Object.assign({ getIntl: getCurrentIntl }, dependencies) }); const store = configureStore({ reducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware({ thunk: false }).concat(epicMiddleware), preloadedState, devTools: { name: 'Studio Store' } // devTools: process.env.NODE_ENV === 'production' ? false : { name: 'Studio Store' } }); epicMiddleware.run(epic); return store; } export function fetchStateInitialization() { const siteCookieValue = getSiteCookie(); return forkJoin({ user: me(), sites: fetchAll(), properties: fetchGlobalProperties(), activeSiteId: // A site cookie may be set but the site may have been deleted. // If there is a cookie with a site name, verify that it still exists. siteCookieValue ? exists(siteCookieValue).pipe( // If the site doesn't exist, delete the cookie so it doesn't cause further issues tap((siteExists) => !siteExists && removeSiteCookie()), map((siteExists) => (siteExists ? siteCookieValue : null)) ) : of(null), activeEnvironment: fetchActiveEnvironment() }); } export default getStore;