xstate-helpers
Version:
A collection of helpers for XState (with React).
193 lines (166 loc) • 5.81 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var ReactDOM = require('react-dom');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var React__default = /*#__PURE__*/_interopDefault(React);
var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM);
const LOCAL_STORAGE_KEY_IS_ENABLED = 'xstate-helpers::isEnabled';
const LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS = 'xstate-helpers::overrideOptions'; // declare global {
const XStateInspectLoader = ({
children,
initialIsEnabled = false,
options,
wrapperElement,
forceEnabled,
styles,
stylesIframe
}) => {
const [loading, setLoading] = React__default["default"].useState(true);
const [overrideOptions, _setOverrideOptions] = React__default["default"].useState(() => getItem(LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS, {}));
const setOverrideOptions = value => {
_setOverrideOptions(value);
setItem(LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS, value);
};
const [isEnabled, _setIsEnabled] = React__default["default"].useState(() => forceEnabled != null ? forceEnabled : getItem(LOCAL_STORAGE_KEY_IS_ENABLED, initialIsEnabled));
const setIsEnabled = value => {
_setIsEnabled(value);
setItem(LOCAL_STORAGE_KEY_IS_ENABLED, value);
};
React__default["default"].useEffect(() => {
if (forceEnabled !== undefined) {
setIsEnabled(forceEnabled);
}
}, [forceEnabled]);
const optionsRef = React__default["default"].useRef(options);
React__default["default"].useEffect(() => {
// expose an interface for setting open/closed directly on console
const XStateInspector = {
enable: () => {
setIsEnabled(true);
},
disable: () => {
setIsEnabled(false);
},
overrideOptions: (overrideOptions = {}) => {
setOverrideOptions(overrideOptions);
return { ...optionsRef.current,
...overrideOptions
};
}
};
window.XStateInspector = XStateInspector;
}, []);
const finalOptions = { ...options,
...overrideOptions
};
React__default["default"].useEffect(() => {
let active = true; // keep track if this effect was cleaned up
Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@xstate/inspect')); }).then(({
inspect
}) => {
if (!active || !isEnabled) {
return;
}
if (wrapperElement) {
if (typeof wrapperElement === 'string') {
// eslint-disable-next-line
wrapperElement = document.querySelector(wrapperElement);
if (!wrapperElement) {
console.error('Cannot initialize XStateInspectorLoader, invalid wrapperElement selector given');
return;
}
}
} else {
// no wrapper given, we make our own
wrapperElement = document.createElement('div');
document.body.insertBefore(wrapperElement, document.body.firstChild);
}
ReactDOM__default["default"].render( /*#__PURE__*/React__default["default"].createElement(XStateInspector, {
styles,
stylesIframe,
inspect,
options: finalOptions
}, null), wrapperElement);
setLoading(false);
});
return () => {
active = false;
if (wrapperElement && typeof wrapperElement !== 'string') {
ReactDOM__default["default"].unmountComponentAtNode(wrapperElement);
}
};
}, [isEnabled, JSON.stringify(finalOptions)]);
return isEnabled && loading ? null : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, children);
};
const defaultStyles = {
height: '600px',
overflow: 'hidden',
overflowY: 'scroll'
};
const defaultStylesIframe = {
width: '100%',
height: '5000px'
};
const XStateInspector = ({
inspect,
options,
styles = defaultStyles,
stylesIframe = defaultStylesIframe
}) => {
const ref = /*#__PURE__*/React__default["default"].createRef();
React__default["default"].useLayoutEffect(() => {
const inspector = inspect({
iframe: options !== null && options !== void 0 && options.iframe ? options.iframe : () => ref.current,
...options
});
return () => inspector === null || inspector === void 0 ? void 0 : inspector.disconnect(); // eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify(options)]);
if ((options === null || options === void 0 ? void 0 : options.iframe) === false) {
return null;
}
return /*#__PURE__*/React__default["default"].createElement('div', {
style: styles
}, /*#__PURE__*/React__default["default"].createElement('iframe', {
ref,
title: 'xstate-inspector',
style: stylesIframe,
'data-xstate': true
}, null));
};
function getItem(key, defaultValue) {
let initialValue = undefined;
try {
initialValue = JSON.parse(localStorage.getItem(key));
} catch {}
if (typeof initialValue === 'undefined' || initialValue === null) {
return defaultValue;
} else {
return initialValue;
}
}
function setItem(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch {}
}
exports.LOCAL_STORAGE_KEY_IS_ENABLED = LOCAL_STORAGE_KEY_IS_ENABLED;
exports.LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS = LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS;
exports.XStateInspectLoader = XStateInspectLoader;