UNPKG

@trifrost/core

Version:

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

179 lines (178 loc) 5.62 kB
const encoder = new TextEncoder(); const decoder = new TextDecoder(); /* Fast-path ASCII identifier check */ const isIdentChar = new Uint8Array(128); for (let i = 48; i <= 57; i++) isIdentChar[i] = 1; for (let i = 65; i <= 90; i++) isIdentChar[i] = 1; for (let i = 97; i <= 122; i++) isIdentChar[i] = 1; isIdentChar[95] = 1; // _ isIdentChar[36] = 1; // $ const isIdent = (c) => (c < 128 && isIdentChar[c] === 1) || (c > 127 && ((c >= 0x00a0 && c <= 0x10ffff) || c >= 0x3000)); // accept wide char identifier chunks export function atomicMinify(raw, apply_sentinel = true) { const bytes = encoder.encode( /* Inject a sentinel token */ apply_sentinel ? raw.replace(/(?<!\.)\b(return|throw|typeof|instanceof|delete|void|new)\b\s*(?=[[{("'`a-zA-Z0-9_$!])/g, '$1\u0001') : raw); const out = new Uint8Array(bytes.length); let o = 0; let i = 0; let inStr = 0; /* 0 = none, 1 = ", 2 = ' */ let inTpl = false; let prevIsIdent = false; let spaceNeeded = false; while (i < bytes.length) { const ch = bytes[i]; const next = bytes[i + 1]; /* Sentinel check */ if (ch === 1) { out[o++] = 32; i++; continue; } /* Escape handling in strings and templates */ if ((inStr || inTpl) && ch === 92 /* \ */) { out[o++] = ch; out[o++] = bytes[++i]; i++; continue; } if (inTpl) { if (ch === 36 && next === 123) { /* Template expression entry: ${ */ out[o++] = ch; out[o++] = bytes[++i]; i++; // Inline minify inside ${...} let depth = 1; const exprStart = i; while (i < bytes.length && depth > 0) { if (bytes[i] === 123) depth++; else if (bytes[i] === 125) depth--; i++; } const minified = encoder.encode(atomicMinify(decoder.decode(bytes.subarray(exprStart, i - 1)), false)); for (let j = 0; j < minified.length; j++) out[o++] = minified[j]; out[o++] = 125; continue; } else if (ch === 96) { inTpl = false; } out[o++] = ch; i++; continue; } /* Start of template */ if (ch === 96) { inTpl = true; out[o++] = ch; i++; continue; } /* Quoted strings */ if (ch === 34 || ch === 39) { if (!inStr) inStr = ch === 34 ? 1 : 2; else if ((inStr === 1 && ch === 34) || (inStr === 2 && ch === 39)) inStr = 0; out[o++] = ch; i++; continue; } if (inStr) { out[o++] = ch; i++; continue; } /* Comment stripping */ if (ch === 47) { if (next === 47) { i += 2; while (i < bytes.length && bytes[i] !== 10) i++; continue; } if (next === 42) { i += 2; while (i + 1 < bytes.length && !(bytes[i] === 42 && bytes[i + 1] === 47)) i++; i += 2; continue; } /* Heuristic regex literal detection */ const prevCh = out[o - 1]; if (prevCh === 40 || prevCh === 61 || prevCh === 58 || prevCh === 44 || prevCh === 123) { out[o++] = ch; i++; while (i < bytes.length) { const rc = bytes[i]; out[o++] = rc; if (rc === 47 && bytes[i - 1] !== 92) { i++; break; } i++; } while (i < bytes.length && ((bytes[i] >= 97 && bytes[i] <= 122) || bytes[i] === 103)) { out[o++] = bytes[i++]; } continue; } } /* Whitespace */ if (ch <= 32) { spaceNeeded = true; i++; continue; } const currIsIdent = isIdent(ch); if (spaceNeeded && prevIsIdent && currIsIdent) { out[o++] = 32; } spaceNeeded = false; switch (ch) { case 59: // ; if (next === 59) { i++; continue; } /* intentional fallthrough */ case 123: // { case 125: // } case 40: // ( case 41: // ) case 61: // = case 43: // + case 45: // - case 42: // * case 47: // / case 58: // : case 44: // , case 60: // < case 62: // > case 91: // [ case 93: // ] case 33: // ! case 63: // ? case 38: // & case 124: // ` out[o++] = ch; i++; while (bytes[i] <= 32 && i < bytes.length) i++; prevIsIdent = false; continue; } out[o++] = ch; prevIsIdent = currIsIdent; i++; } return decoder.decode(out.subarray(0, o)); }