UNPKG

react-render-props-script-loader

Version:
79 lines 2.16 kB
/* eslint-env browser */ let nonce; function getNonce() { if (nonce === undefined) { const node = document.querySelector('meta[property="csp-nonce"], meta[name="csp-nonce"]'); nonce = node ? node.getAttribute('content') ?? null : null; } return nonce ?? null; } const loadScript = async ({ scriptsRegistry, onLoad, onError, children, // eslint-disable-next-line no-unused-vars act, ...props }) => { const { src } = props; if (scriptsRegistry) { scriptsRegistry.results[src] = { error: undefined }; scriptsRegistry.scripts.push(props); return; } if (typeof document === 'undefined') { throw new Error('you must pass a scriptsRegistry if calling on the server side'); } if (typeof document.querySelector === 'function') { if (document.querySelector(`script[src="${src}"]`)) { results[src] = { error: undefined }; return; } } return new Promise((resolve, reject) => { const script = document.createElement('script'); script.src = src; script.nonce = getNonce(); Object.keys(props).forEach(key => script.setAttribute(key, props[key])); script.onload = resolve; script.onerror = reject; if (document.body) document.body.appendChild(script); }); }; const results = {}; const promises = {}; export default (props => { const { scriptsRegistry } = props; const _promises = scriptsRegistry ? scriptsRegistry.promises : promises; const _results = scriptsRegistry ? scriptsRegistry.results : results; return _promises[props.src] || (_promises[props.src] = loadScript(props).then(() => _results[props.src] = { error: null }, (error = new Error(`failed to load ${props.src}`)) => { _results[props.src] = { error }; throw error; })); }); export function getState({ src, scriptsRegistry }) { const result = scriptsRegistry ? scriptsRegistry.results[src] : results[src]; const promise = scriptsRegistry ? scriptsRegistry.promises[src] : promises[src]; return { loading: result == null, loaded: result ? !result.error : false, error: result && result.error, promise }; }