@trifrost/core
Version:
Blazingly fast, runtime-agnostic server framework for modern edge and node environments
65 lines (64 loc) • 2.3 kB
JavaScript
/// <reference lib="dom" />
import { nonce } from '../ctx/nonce';
import { getActiveScriptEngine } from './use';
import { atomicMinify } from './util';
export const SCRIPT_MARKER = '__TRIFROST_HYDRATED_SCRIPT__';
const RGX_DATA_SCRIPT = /<\/script>/gi;
export function Script(options) {
if (!options || Object.prototype.toString.call(options) !== '[object Object]')
return null;
/* Source */
if (typeof options.src === 'string' && options.src.length) {
const { src, async, defer, type = 'text/javascript' } = options;
/* Formulate props */
const props = { type };
props.src = src;
/* Add async */
if (async === true)
props.async = true;
/* Add defer */
if (defer)
props.defer = true;
/* Nonce */
let n_nonce = options.nonce || null;
if (!n_nonce)
n_nonce = nonce();
if (typeof n_nonce === 'string' && n_nonce.length)
props.nonce = n_nonce;
return { type: 'script', props, key: null };
}
/* If at this point we dont have a function, do nothing */
if (typeof options.children !== 'function')
return null;
const raw = options.children.toString().trim();
/* If pure (no args), execute eagerly (inline) as we dont need to atomify the method */
if (options.children.length === 0) {
const open_idx = raw.indexOf('{');
const close_idx = raw.lastIndexOf('}');
const body = open_idx >= 0 && close_idx >= 0 ? atomicMinify(raw.slice(open_idx + 1, close_idx)) : '';
if (!body)
return null;
return {
type: 'script',
props: {
dangerouslySetInnerHTML: {
__html: '(function(){' + body + '})();',
},
nonce: options.nonce || nonce(),
},
key: null,
};
}
else {
const engine = getActiveScriptEngine();
if (!engine)
return null;
/* Get data */
const data = options.data ? JSON.stringify(options.data).replace(RGX_DATA_SCRIPT, '<\\/script>') : null;
return {
type: SCRIPT_MARKER,
props: engine.register(raw, data),
key: null,
};
}
}