diff --git a/src/utils/index.js b/src/utils/index.js index 546bd78..45f7afe 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -3,7 +3,7 @@ import compose from './compose'; import deepMerge from './deepMerge'; import makeCancelable from './makeCancelable'; -import store from './store'; +import createStore from './store'; import monaco from './monaco'; -export { noop, compose, deepMerge, makeCancelable, store, monaco }; +export { noop, compose, deepMerge, makeCancelable, createStore, monaco }; diff --git a/src/utils/monaco.js b/src/utils/monaco.js index 1cbf67b..058baf6 100644 --- a/src/utils/monaco.js +++ b/src/utils/monaco.js @@ -3,10 +3,10 @@ import { compose, deepMerge, makeCancelable, - store, + createStore, } from '../utils'; -const { state, setState } = store({ +const [getState, setState] = createStore({ config: defaultConfig, isInitialized: false, configScriptSrc: null, @@ -17,16 +17,18 @@ const { state, setState } = store({ const MONACO_INIT = 'monaco_init'; function config({ src, ...config }) { - setState({ + setState(state => ({ configScriptSrc: src, config: deepMerge( - defaultConfig, + state.config, validateConfig(config), ), - }); + })); } function init() { + const state = getState(({ isInitialized }) => ({ isInitialized })); + if (!state.isInitialized) { if (window.monaco && window.monaco.editor) { return Promise.resolve(window.monaco); @@ -67,11 +69,15 @@ function createScript(src) { } function handleConfigScriptLoad() { + const state = getState(({ resolve }) => ({ resolve })); + document.removeEventListener(MONACO_INIT, handleConfigScriptLoad); state.resolve(window.monaco); } function createMonacoLoaderScript(configScript) { + const state = getState(({ config, reject }) => ({ config, reject })); + const loaderScript = createScript(`${state.config.paths.vs}/loader.js`); loaderScript.onload = () => injectScriptsIntoBody(configScript); @@ -81,6 +87,10 @@ function createMonacoLoaderScript(configScript) { } function createConfigScript() { + const state = getState( + ({ configScriptSrc, config, reject }) => ({ configScriptSrc, config, reject }) + ); + const configScript = createScript(); if (state.configScriptSrc) { diff --git a/src/utils/store.js b/src/utils/store.js index 62e4603..a8a998a 100644 --- a/src/utils/store.js +++ b/src/utils/store.js @@ -1,21 +1,26 @@ -function store(initial, handlers = {}) { +function createStore(initial, handlers = {}) { if (!initial) { throw new Error('initial state is required'); } - const _ = { - state: initial, - setState, - }; + const state = { current: initial }; + + function getState(selector = state => state) { + return selector(state.current); + } + + function setState(causedChanges) { + const changes = typeof causedChanges === 'function' + ? causedChanges(state.current) + : causedChanges; - function setState(changes) { // check only in development validateChanges(initial, changes); - Object.assign(_.state, changes); + Object.assign(state.current, changes); Object.keys(changes).forEach(field => handlers[field] && handlers[field](changes[field])); } - return _; + return [getState, setState]; } function validateChanges(initial, changes) { @@ -24,8 +29,8 @@ function validateChanges(initial, changes) { } if (Object.keys(changes).some(field => !initial.hasOwnProperty(field))) { - throw new Error('It seams you want to change a field in the state that is not specified in the "initial" state'); + throw new Error('It seams you want to change a field in the store which is not specified in the "initial" state'); } } -export default store; +export default createStore;