UNPKG

@trifrost/core

Version:

Blazingly fast, runtime-agnostic server framework for modern edge and node environments

65 lines (64 loc) 2.3 kB
/// <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, }; } }