jq79 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dev/vite.ts +152 -10
- package/dist/dom.d.ts +22 -4
- package/dist/html.d.ts +9 -0
- package/dist/jq79-sw.js +32 -0
- package/dist/jq79.cjs +18 -14
- package/dist/jq79.cjs.map +1 -1
- package/dist/jq79.d.ts +27 -13
- package/dist/jq79.global.js +18 -14
- package/dist/jq79.global.js.map +1 -1
- package/dist/jq79.js +18 -14
- package/dist/jq79.js.map +1 -1
- package/dist/precompile.cjs +24 -0
- package/dist/precompile.cjs.map +1 -0
- package/dist/precompile.d.ts +3 -0
- package/dist/precompile.js +24 -0
- package/dist/precompile.js.map +1 -0
- package/dist/reactive.d.ts +10 -0
- package/dist/source.d.ts +65 -0
- package/dist/vite.cjs +85 -4
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.ts +3 -0
- package/dist/vite.js +86 -5
- package/dist/vite.js.map +1 -1
- package/package.json +12 -2
- package/src/dom.ts +28 -4
- package/src/html.ts +289 -0
- package/src/jq79.ts +705 -363
- package/src/precompile.ts +238 -0
- package/src/reactive.ts +178 -9
- package/src/source.ts +389 -0
- package/src/sw.ts +87 -0
- package/src/transform.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/html.ts","../src/transform.ts","../src/source.ts","../src/precompile.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// an HTML tree without a DOM\n//\n// precompile() has to read a component where there is no DOMParser - on node,\n// for the Vite plugin, and in a service worker - and find every attribute and\n// every text node the runtime's own parse finds. This builds that tree:\n// elements with their attributes and children, and text decoded the way the\n// HTML parser decodes it.\n//\n// It is not a conforming HTML parser and doesn't try to be. What precompile\n// reads is *which* attributes and texts exist, and wherever the real parser\n// would put one somewhere else - an implied end tag, a table's foster parent -\n// it still exists. The places where it would read a different *value* are the\n// ones that matter, and those it follows:\n// - newlines normalized first (CRLF and a lone CR are LF), as the input stream is\n// - character references decoded in text and attribute values, with the\n// attribute rule for a legacy reference with no semicolon\n// - <html>, <head> and <body> dropped, as a template drops them\n// - attribute names lowercased, and the first of two duplicates kept\n// - <script>/<style> (and the other raw text elements) read verbatim to their\n// end tag, <textarea>/<title> decoded but never parsed for tags\n// - comments dropped, and the text on either side kept as two texts\n//\n// tests/precompile.test.ts holds it against DOMParser, tree for tree\n// ---------------------------------------------------------------------------\n\nexport type HTMLElementNode = { tag: string; attrs: Record<string, string>; children: HTMLNode[] }\nexport type HTMLNode = HTMLElementNode | string\n\nconst VOID_TAGS = new Set([\n \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\",\n \"link\", \"meta\", \"param\", \"source\", \"track\", \"wbr\",\n])\n\n// the document's own structure, which a template can't hold: inside one the\n// parser drops these tags, start and end, and keeps what they wrapped\nconst DOCUMENT_TAGS = new Set([\"html\", \"head\", \"body\"])\n\n// read verbatim up to their end tag - and, for the escapable two, decoded\nconst RAW_TEXT_TAGS = new Set([\"script\", \"style\", \"xmp\", \"iframe\", \"noembed\", \"noframes\"])\nconst ESCAPABLE_RAW_TEXT_TAGS = new Set([\"textarea\", \"title\"])\n\n// the named references a component plausibly writes. The HTML table has over\n// two thousand; one missing here leaves its text undecoded, and that is a\n// precompiled function under a key the runtime never asks for - which safe\n// mode reports by name, rather than a wrong function running\nconst NAMED_REFERENCES: Record<string, string> = {\n apos: \"'\", trade: \"\\u2122\", hellip: \"\\u2026\", mdash: \"\\u2014\", ndash: \"\\u2013\",\n lsquo: \"\\u2018\", rsquo: \"\\u2019\", ldquo: \"\\u201c\", rdquo: \"\\u201d\", bull: \"\\u2022\", euro: \"\\u20ac\",\n larr: \"\\u2190\", rarr: \"\\u2192\", uarr: \"\\u2191\", darr: \"\\u2193\", check: \"\\u2713\",\n lbrace: \"{\", rbrace: \"}\", lcub: \"{\", rcub: \"}\", lpar: \"(\", rpar: \")\", lsqb: \"[\", rsqb: \"]\",\n colon: \":\", comma: \",\", period: \".\", semi: \";\", excl: \"!\", quest: \"?\", num: \"#\", dollar: \"$\",\n percnt: \"%\", ast: \"*\", plus: \"+\", equals: \"=\", sol: \"/\", bsol: \"\\\\\", verbar: \"|\", vert: \"|\",\n grave: \"`\", Hat: \"^\", lowbar: \"_\", commat: \"@\", Tab: \"\\t\", NewLine: \"\\n\",\n}\n\n// the references that also decode without their semicolon - the web before\n// HTML required one - which is the whole of this list, from the standard: the\n// five markup ones in both cases, and Latin-1's 96, U+00A0 to U+00FF in order.\n// A name that isn't a reference is read as the longest of these it starts\n// with (`¬areference;` is `¬areference;`), so all of them are needed to\n// read what the parser reads\nconst LATIN_1 = (\n \"nbsp iexcl cent pound curren yen brvbar sect uml copy ordf laquo not shy reg macr deg plusmn sup2 sup3 \" +\n \"acute micro para middot cedil sup1 ordm raquo frac14 frac12 frac34 iquest Agrave Aacute Acirc Atilde Auml \" +\n \"Aring AElig Ccedil Egrave Eacute Ecirc Euml Igrave Iacute Icirc Iuml ETH Ntilde Ograve Oacute Ocirc Otilde \" +\n \"Ouml times Oslash Ugrave Uacute Ucirc Uuml Yacute THORN szlig agrave aacute acirc atilde auml aring aelig \" +\n \"ccedil egrave eacute ecirc euml igrave iacute icirc iuml eth ntilde ograve oacute ocirc otilde ouml divide \" +\n \"oslash ugrave uacute ucirc uuml yacute thorn yuml\"\n).split(\" \")\nconst LEGACY_REFERENCES: Record<string, string> = {\n amp: \"&\", AMP: \"&\", lt: \"<\", LT: \"<\", gt: \">\", GT: \">\", quot: \"\\\"\", QUOT: \"\\\"\", COPY: \"\\u00a9\", REG: \"\\u00ae\",\n ...Object.fromEntries(LATIN_1.map((name, i) => [name, String.fromCharCode(0xa0 + i)])),\n}\n// longest first, so `²` is ² and not \"sup\" plus a 2\nconst LEGACY_NAMES = Object.keys(LEGACY_REFERENCES).sort((a, b) => b.length - a.length)\n\nconst has = (table: Record<string, string>, name: string) => Object.prototype.hasOwnProperty.call(table, name)\n\nconst fromCodePoint = (code: number): string =>\n code === 0 || code > 0x10ffff || (code >= 0xd800 && code <= 0xdfff) ? \"�\" : String.fromCodePoint(code)\n\nexport const CHARACTER_REFERENCE_RE = /&(#[0-9]+;?|#[xX][0-9a-fA-F]+;?|[A-Za-z][A-Za-z0-9]*;?)/g\nconst ALPHANUMERIC_RE = /[A-Za-z0-9]/\n\n// what one match of CHARACTER_REFERENCE_RE in `text`, at `offset`, decodes to.\n// In an attribute a legacy reference with no semicolon stays literal when the\n// next character is `=` or alphanumeric - `?a=1©=2` is a query string, not\n// a copyright sign. In text it decodes, and what follows the name stays.\n// Exported for the editor extension, which decodes an attribute value while\n// keeping where each character came from (editors/vscode/src/entities.ts)\nexport const decodeReference = (text: string, whole: string, ref: string, offset: number, inAttribute: boolean): string => {\n if (ref[0] === \"#\") {\n const hex = ref[1] === \"x\" || ref[1] === \"X\"\n const digits = ref.slice(hex ? 2 : 1).replace(/;$/, \"\")\n return fromCodePoint(parseInt(digits, hex ? 16 : 10))\n }\n const semicolon = ref.endsWith(\";\")\n const name = semicolon ? ref.slice(0, -1) : ref\n if (semicolon && has(LEGACY_REFERENCES, name)) return LEGACY_REFERENCES[name]\n if (semicolon && has(NAMED_REFERENCES, name)) return NAMED_REFERENCES[name]\n const legacy = LEGACY_NAMES.find(candidate => name.startsWith(candidate))\n if (legacy === undefined) return whole\n const after = name.length > legacy.length ? name[legacy.length] : semicolon ? \";\" : text[offset + whole.length]\n if (inAttribute && after !== undefined && (after === \"=\" || ALPHANUMERIC_RE.test(after))) return whole\n return LEGACY_REFERENCES[legacy] + ref.slice(legacy.length)\n}\n\nconst decode = (text: string, inAttribute: boolean): string => {\n if (!text.includes(\"&\")) return text\n return text.replace(CHARACTER_REFERENCE_RE, (whole: string, ref: string, offset: number) =>\n decodeReference(text, whole, ref, offset, inAttribute))\n}\n\nconst TAG_NAME_RE = /[^\\s/>]*/y\nconst ATTRIBUTE_NAME_RE = /[^\\s/>][^\\s/>=]*/y\nconst WHITESPACE_RE = /\\s*/y\nconst UNQUOTED_VALUE_RE = /[^\\s>]*/y\nconst END_TAG_RE = /<\\/([A-Za-z][^\\s/>]*)[^>]*>/y\n\n// runs a sticky pattern at `at` and answers with the match (or \"\")\nconst readAt = (re: RegExp, src: string, at: number): string => {\n re.lastIndex = at\n return re.exec(src)?.[0] ?? \"\"\n}\n\n// where a raw text element's content ends: its own end tag, whatever the case,\n// followed by what can end a tag name\nconst rawTextEnd = (src: string, from: number, tag: string): number => {\n const re = new RegExp(`</${tag}(?=[\\\\s/>])`, \"gi\")\n re.lastIndex = from\n const match = re.exec(src)\n return match ? match.index : src.length\n}\n\n// the element children of a comment are nothing, and the texts on either side\n// of it stay two texts - a comment is a node in the DOM, which is what keeps\n// them apart. A marker holds its place while the tree is built\nconst COMMENT = null\n\ntype BuildNode = { tag: string; attrs: Record<string, string>; children: (BuildNode | string | null)[] }\n\nconst finish = (node: BuildNode): HTMLElementNode => ({\n tag: node.tag,\n attrs: node.attrs,\n children: node.children.flatMap((child): HTMLNode[] =>\n child === COMMENT ? [] : typeof child === \"string\" ? (child ? [child] : []) : [finish(child)]\n ),\n})\n\nexport const parseHTML = (input: string): HTMLNode[] => {\n const src = input.replace(/\\r\\n?/g, \"\\n\")\n const root: BuildNode = { tag: \"#root\", attrs: {}, children: [] }\n const stack: BuildNode[] = [root]\n const current = () => stack[stack.length - 1]\n // inside <svg> or <math> a `/>` closes the element - in HTML it is ignored\n let foreignDepth = 0\n\n const appendText = (text: string) => {\n if (!text) return\n const children = current().children\n const last = children[children.length - 1]\n if (typeof last === \"string\") children[children.length - 1] = last + text\n else children.push(text)\n }\n\n const close = (tag: string) => {\n for (let depth = stack.length - 1; depth > 0; depth--) {\n if (stack[depth].tag !== tag) continue\n for (let popped = stack.length - 1; popped >= depth; popped--) {\n if (stack[popped].tag === \"svg\" || stack[popped].tag === \"math\") foreignDepth--\n }\n stack.length = depth\n return\n }\n }\n\n let at = 0\n while (at < src.length) {\n const lt = src.indexOf(\"<\", at)\n if (lt === -1) {\n appendText(decode(src.slice(at), false))\n break\n }\n appendText(decode(src.slice(at, lt), false))\n at = lt\n\n // a comment - `<!-->` and `<!--->` are complete, empty ones\n if (src.startsWith(\"<!--\", at)) {\n current().children.push(COMMENT)\n if (src.startsWith(\">\", at + 4)) at += 5\n else if (src.startsWith(\"->\", at + 4)) at += 6\n else {\n const end = src.indexOf(\"-->\", at + 4)\n at = end === -1 ? src.length : end + 3\n }\n continue\n }\n // a doctype leaves no node at all - so the texts around it are one text -\n // and a CDATA section or a processing instruction is a (bogus) comment\n if (src[at + 1] === \"!\" || src[at + 1] === \"?\") {\n const end = src.indexOf(\">\", at)\n if (!/^<!doctype/i.test(src.slice(at, at + 9))) current().children.push(COMMENT)\n at = end === -1 ? src.length : end + 1\n continue\n }\n if (src[at + 1] === \"/\") {\n END_TAG_RE.lastIndex = at\n const end = END_TAG_RE.exec(src)\n if (end) {\n if (!DOCUMENT_TAGS.has(end[1].toLowerCase())) close(end[1].toLowerCase())\n at = END_TAG_RE.lastIndex\n } else {\n // `</>` is dropped, and `</ anything>` is a bogus comment\n const gt = src.indexOf(\">\", at)\n at = gt === -1 ? src.length : gt + 1\n }\n continue\n }\n if (!/[A-Za-z]/.test(src[at + 1] ?? \"\")) {\n appendText(\"<\")\n at++\n continue\n }\n\n // a start tag\n const tag = readAt(TAG_NAME_RE, src, at + 1).toLowerCase()\n const ignored = DOCUMENT_TAGS.has(tag)\n let cursor = at + 1 + tag.length\n const attrs: Record<string, string> = {}\n let selfClosing = false\n let complete = false\n while (cursor < src.length) {\n cursor += readAt(WHITESPACE_RE, src, cursor).length\n const char = src[cursor]\n if (char === \">\") { cursor++; complete = true; break }\n if (char === \"/\") {\n if (src[cursor + 1] === \">\") { selfClosing = true; cursor += 2; complete = true; break }\n cursor++\n continue\n }\n if (char === undefined) break\n const name = readAt(ATTRIBUTE_NAME_RE, src, cursor)\n cursor += name.length\n let value = \"\"\n const afterName = cursor + readAt(WHITESPACE_RE, src, cursor).length\n if (src[afterName] === \"=\") {\n cursor = afterName + 1\n cursor += readAt(WHITESPACE_RE, src, cursor).length\n const quote = src[cursor]\n if (quote === \"\\\"\" || quote === \"'\") {\n const close = src.indexOf(quote, cursor + 1)\n const end = close === -1 ? src.length : close\n value = src.slice(cursor + 1, end)\n cursor = end + 1\n } else {\n value = readAt(UNQUOTED_VALUE_RE, src, cursor)\n cursor += value.length\n }\n value = decode(value, true)\n }\n const key = name.toLowerCase()\n if (!(key in attrs)) attrs[key] = value\n }\n // a tag cut off by the end of the input is dropped, as the parser drops it\n if (!complete) break\n at = cursor\n if (ignored) continue\n\n const node: BuildNode = { tag, attrs, children: [] }\n current().children.push(node)\n if (VOID_TAGS.has(tag)) continue\n if (selfClosing && foreignDepth > 0) continue\n\n if (foreignDepth === 0 && (RAW_TEXT_TAGS.has(tag) || ESCAPABLE_RAW_TEXT_TAGS.has(tag))) {\n const end = rawTextEnd(src, at, tag)\n const text = src.slice(at, end)\n node.children.push(ESCAPABLE_RAW_TEXT_TAGS.has(tag) ? decode(text, false) : text)\n const gt = src.indexOf(\">\", end)\n at = end === src.length || gt === -1 ? src.length : gt + 1\n continue\n }\n\n if (tag === \"svg\" || tag === \"math\") foreignDepth++\n stack.push(node)\n }\n\n return finish(root).children\n}\n","// ---------------------------------------------------------------------------\n// :setup script transform\n//\n// setup scripts are written like Svelte components:\n//\n// let firstName = null\n// $: fullName = `${firstName} ${lastName}`\n// fetchUser().then(user => { firstName = user.firstName })\n//\n// and are executed inside `with ($scope)` against the component's reactive\n// store, so plain assignments (even from async callbacks) go through the\n// proxy's set trap and re-render whatever depends on them. To make that work\n// the source is lightly rewritten - no full JS parser, just a scanner that is\n// string/comment-aware and only touches code at brace/paren depth 0:\n// - `let/var/const x = ...` at the top level loses its keyword, becoming a\n// scope assignment (the name is pre-declared on the store so the `with`\n// lookup resolves it)\n// - `$: x = expr` becomes `$__effect(() => { x = expr })`, re-running when a\n// dependency read inside expr changes ($__effect is deliberately NOT a\n// property of the scope, so `with` falls through to the function parameter)\n// ---------------------------------------------------------------------------\n\ntype SetupTransform = { vars: string[]; code: string }\n\n// a declaration whose target is an identifier (`let x`), an object pattern\n// (`let { a }`, space optional) or an array pattern (`let [x]`)\nconst DECLARATION_START_RE = /(?:let|var|const)(?:\\s+(?=[A-Za-z_$])|\\s*(?=[{[]))/y\nconst REACTIVE_LABEL_RE = /\\$:\\s*/y\nconst IMPORT_CALL_RE = /import(?=\\s*\\()/y\nconst REACTIVE_ASSIGN_RE = /\\$:\\s*([A-Za-z_$][\\w$]*)\\s*=(?!=)/y\n\nconst skipString = (src: string, start: number): number => {\n const quote = src[start]\n let i = start + 1\n while (i < src.length) {\n if (src[i] === \"\\\\\") { i += 2; continue }\n if (src[i] === quote) return i + 1\n i++\n }\n return src.length\n}\n\nconst skipLineComment = (src: string, start: number): number => {\n const end = src.indexOf(\"\\n\", start)\n return end === -1 ? src.length : end\n}\n\nconst skipBlockComment = (src: string, start: number): number => {\n const end = src.indexOf(\"*/\", start + 2)\n return end === -1 ? src.length : end + 2\n}\n\n// index of the next thing that isn't whitespace or a comment\nconst skipToToken = (src: string, start: number): number => {\n let i = start\n while (i < src.length) {\n if (/\\s/.test(src[i])) { i++; continue }\n if (src[i] === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (src[i] === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n break\n }\n return i\n}\n\n// ---------------------------------------------------------------------------\n// regex literals. The scanners walk the source counting bracket depth, and a\n// regex walked as if it were code poisons that count: `split(/\\//)` puts two\n// slashes side by side (a line comment, as far as a scanner knows) and the\n// `)` after them is skipped uncounted; `/[(]/` inflates the depth for good.\n// So a `/` that opens a regex is consumed whole - and whether it opens one is\n// the classic lexer call, made the way every tokenizer makes it: by what came\n// before. Division needs a completed expression on its left; everywhere else\n// a `/` can only be a regex.\n// ---------------------------------------------------------------------------\n\n// reserved words a regex can follow. Reserved only - `of` is not (`const of\n// = 4; of / 2` is legal division), so `for (x of /re/)` stays unrescued\n// rather than risking real code\nconst REGEX_AFTER_WORD = new Set([\n \"return\", \"typeof\", \"case\", \"in\", \"instanceof\", \"new\", \"delete\", \"void\", \"do\", \"else\", \"yield\", \"await\",\n])\n\n// whether a `/` at `at` opens a regex literal rather than a division: looks\n// backward past whitespace and block comments for the last meaningful thing.\n// A completed expression - identifier, number, closing quote or bracket,\n// postfix ++/-- - takes division; a reserved word or any other punctuator\n// admits a regex. Only consulted for the rare `/` that is neither `//` nor\n// `/*`, so the scanners pay nothing on the common path\nconst regexAllowed = (src: string, at: number): boolean => {\n let i = at - 1\n while (i >= 0) {\n const ch = src[i]\n if (/\\s/.test(ch)) { i--; continue }\n if (ch === \"/\" && src[i - 1] === \"*\") {\n const open = src.lastIndexOf(\"/*\", i - 2)\n if (open === -1) return true // an unopened comment tail: malformed input\n i = open - 1\n continue\n }\n break\n }\n if (i < 0) return true // the start of the source starts an expression\n const ch = src[i]\n if (/[\\w$]/.test(ch)) {\n let start = i\n while (start > 0 && /[\\w$]/.test(src[start - 1])) start--\n return REGEX_AFTER_WORD.has(src.slice(start, i + 1))\n }\n if ((ch === \"+\" || ch === \"-\") && src[i - 1] === ch) return false // postfix ++/--\n return !\")]}\\\"'`.\".includes(ch)\n}\n\n// consumes a regex literal (with its flags): backslash escapes, and character\n// classes, where an unescaped `/` doesn't close the literal (`/[/]/` is one\n// regex). A literal can't contain an unescaped newline, so hitting one means\n// the classification was wrong or the input malformed - stop there, bounding\n// any damage to a single line\nconst skipRegex = (src: string, start: number): number => {\n let i = start + 1\n let inClass = false\n while (i < src.length) {\n const ch = src[i]\n if (ch === \"\\\\\") { i += 2; continue }\n if (ch === \"\\n\") return i\n if (ch === \"[\") inClass = true\n else if (ch === \"]\") inClass = false\n else if (ch === \"/\" && !inClass) {\n i++\n while (i < src.length && /[a-z]/i.test(src[i])) i++ // flags\n return i\n }\n i++\n }\n return src.length\n}\n\n// tokens that can't *start* a statement, so a line beginning with one is\n// continuing the previous expression rather than opening a new statement -\n// the same call JS's automatic semicolon insertion makes. Unary-only forms\n// (!, ~, ++, --) are deliberately absent: those do start a statement, and JS\n// inserts the semicolon before them\nconst CONTINUATION_RE = /^(\\?\\.|\\?\\?|&&|\\|\\||\\*\\*|[.,+\\-*/%&|^<>=?:([])/\n\n// the last meaningful character before `at`: walks back past whitespace and\n// block comments, the way regexAllowed does. A line comment can't be skipped\n// from behind (its start is only findable forwards), so a line ending in one\n// reports the comment's text instead - callers treat that as \"not the char I\n// was looking for\", which degrades to ending the statement, exactly as\n// before this helper existed\nconst lastMeaningfulBefore = (src: string, at: number): string => {\n let i = at - 1\n while (i >= 0) {\n const ch = src[i]\n if (/\\s/.test(ch)) { i--; continue }\n if (ch === \"/\" && src[i - 1] === \"*\") {\n const open = src.lastIndexOf(\"/*\", i - 2)\n if (open === -1) return \"\"\n i = open - 1\n continue\n }\n return ch\n }\n return \"\"\n}\n\n// end of a statement starting at `start`: the first `;` or line break that\n// isn't inside a string/comment or unbalanced brackets. A line break only\n// ends the statement if the next line can't continue it, so leading-dot\n// method chains and multi-line operator chains stay in one piece:\n//\n// $: total = items\n// .filter(item => item.active) <- still the same statement\n// .length\n//\n// ...and only if the current line *can* end it: a line whose last meaningful\n// character is `,` or `=` left its expression incomplete (a multi-line\n// declarator list writes exactly this), so the statement continues - the\n// same ASI call as the leading-token check, made from the other side\nconst findStatementEnd = (src: string, start: number): number => {\n let depth = 0\n let i = start\n while (i < src.length) {\n const ch = src[i]\n if (ch === \"'\" || ch === '\"' || ch === \"`\") { i = skipString(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n if (ch === \"/\" && regexAllowed(src, i)) { i = skipRegex(src, i); continue }\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch)) depth--\n else if (depth <= 0 && ch === \";\") return i\n else if (depth <= 0 && ch === \"\\n\") {\n const next = skipToToken(src, i + 1)\n const continues =\n next < src.length &&\n (CONTINUATION_RE.test(src.slice(next, next + 2)) || [\",\", \"=\"].includes(lastMeaningfulBefore(src, i)))\n if (!continues) return i\n i = next\n continue\n }\n i++\n }\n return src.length\n}\n\n// ---------------------------------------------------------------------------\n// top-level declarations. `let x = 1` loses its keyword and becomes a scope\n// assignment (x pre-declared on the store). A destructuring declarator\n// becomes an *assignment pattern*: inside `with`, `({ a, b } = obj)` writes\n// every binding through the reactive proxy - which is what makes it reactive.\n// The parens keep the `{` from opening a block, and a leading `;` keeps the\n// `(` from gluing onto the previous line as a call. Multi-declarator\n// statements (`let a = 1, b = 2`) register every binding, not just the first.\n// These lean on the pattern helpers defined with the props signature below\n// (splitTopLevel, indexOfTopLevel, defaultAssignIndex); the scanner only\n// runs long after the module evaluates, so the order is cosmetic\n// ---------------------------------------------------------------------------\n\ntype Declarator = { raw: string; codeEnd: number }\n\n// splits a declarator list at top-level commas, keeping each segment's raw\n// text (layout and comments included) and where its last meaningful token\n// ends - the spot a closing paren must go, so a trailing comment can't\n// swallow it\nconst splitDeclarators = (src: string): Declarator[] => {\n const parts: Declarator[] = []\n let depth = 0\n let start = 0\n let lastEnd = 0\n const flush = (end: number) => {\n parts.push({ raw: src.slice(start, end), codeEnd: Math.max(0, lastEnd - start) })\n start = end + 1\n lastEnd = start\n }\n let i = 0\n while (i < src.length) {\n const ch = src[i]\n if (ch === \"'\" || ch === '\"' || ch === \"`\") { i = skipString(src, i); lastEnd = i; continue }\n if (ch === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n if (ch === \"/\" && regexAllowed(src, i)) { i = skipRegex(src, i); lastEnd = i; continue }\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch)) depth--\n else if (ch === \",\" && depth <= 0) { flush(i); i++; continue }\n if (!/\\s/.test(ch)) lastEnd = i + 1\n i++\n }\n flush(src.length)\n return parts\n}\n\n// the *binding* names a destructuring pattern declares - unlike\n// parsePropsPattern, which answers \"which props\" (the keys), this answers\n// \"which variables\": `{ a: x }` binds x, `{ a: { b } }` binds b,\n// `[x, ...rest]` binds x and rest. Defaults are stripped; what remains is a\n// nested pattern (recurse) or the bound identifier\nconst patternBindings = (src: string): string[] => {\n const pattern = src.trim()\n if (!pattern.startsWith(\"{\") && !pattern.startsWith(\"[\")) {\n return IDENTIFIER_RE.test(pattern) ? [pattern] : []\n }\n const names: string[] = []\n for (let part of splitTopLevel(pattern.slice(1, patternCloseIndex(pattern)))) {\n if (part.startsWith(\"...\")) part = part.slice(3).trim()\n const assign = defaultAssignIndex(part)\n if (assign !== -1) part = part.slice(0, assign).trim()\n if (pattern.startsWith(\"{\")) {\n const colon = indexOfTopLevel(part, \":\")\n if (colon !== -1) {\n names.push(...patternBindings(part.slice(colon + 1)))\n continue\n }\n }\n names.push(...patternBindings(part))\n }\n return names\n}\n\n// one `let/var/const` declarator list, rewritten to scope assignments.\n// Each segment's initializer is re-scanned so an `import()` inside it is\n// rewritten like anywhere else - nothing else can match in there, since a\n// nested top-level declaration inside a declarator is a SyntaxError in JS\nconst rewriteDeclarators = (src: string): SetupTransform => {\n const vars: string[] = []\n const rewritten = splitDeclarators(src).map(({ raw, codeEnd }) => {\n const lead = raw.match(/^\\s*/)![0]\n if (codeEnd <= lead.length) return { text: raw, empty: true }\n const body = raw.slice(lead.length, codeEnd)\n const tail = raw.slice(codeEnd)\n const assign = defaultAssignIndex(body)\n const target = (assign === -1 ? body : body.slice(0, assign)).trim()\n const isPattern = body[0] === \"{\" || body[0] === \"[\"\n if (isPattern) vars.push(...patternBindings(target))\n else if (IDENTIFIER_RE.test(target)) vars.push(target)\n const code = transformSetupScript(body).code\n return { text: `${lead}${isPattern ? `(${code})` : code}${tail}`, empty: false }\n })\n\n // a trailing comment-only segment (`let a = 1, // note` cut at its line\n // end) is re-attached without its comma, so the output stays a statement\n const tail: string[] = []\n while (rewritten.length && rewritten[rewritten.length - 1].empty) tail.unshift(rewritten.pop()!.text)\n let code = rewritten.map(part => part.text).join(\",\") + tail.join(\"\")\n if (code.trimStart().startsWith(\"(\")) code = `;${code}`\n return { vars, code }\n}\n\nexport const transformSetupScript = (src: string): SetupTransform => {\n const vars: string[] = []\n let out = \"\"\n let i = 0\n let depth = 0\n let atStatementStart = true\n\n while (i < src.length) {\n const ch = src[i]\n const next = src[i + 1]\n\n if (ch === \"'\" || ch === '\"' || ch === \"`\") {\n const end = skipString(src, i)\n out += src.slice(i, end)\n i = end\n atStatementStart = false\n continue\n }\n if (ch === \"/\" && (next === \"/\" || next === \"*\")) {\n const end = next === \"/\" ? skipLineComment(src, i) : skipBlockComment(src, i)\n out += src.slice(i, end)\n i = end\n continue\n }\n if (ch === \"/\" && regexAllowed(src, i)) {\n const end = skipRegex(src, i)\n out += src.slice(i, end)\n i = end\n atStatementStart = false\n continue\n }\n\n // `import(...)` is a keyword form, so it can't be intercepted through the\n // scope - rewrite the identifier to the injected $__import (which loads\n // .html URLs as components via Component79.fetch and delegates the rest to\n // native import). The `(` is left for the scanner so depth stays balanced\n if (ch === \"i\" && (i === 0 || !/[\\w$.]/.test(src[i - 1]))) {\n IMPORT_CALL_RE.lastIndex = i\n if (IMPORT_CALL_RE.test(src)) {\n out += \"$__import\"\n i += \"import\".length\n atStatementStart = false\n continue\n }\n }\n\n if (depth === 0 && atStatementStart) {\n DECLARATION_START_RE.lastIndex = i\n const decl = DECLARATION_START_RE.exec(src)\n if (decl) {\n const start = i + decl[0].length\n const end = findStatementEnd(src, start)\n const { vars: names, code } = rewriteDeclarators(src.slice(start, end))\n vars.push(...names)\n out += code\n i = end\n atStatementStart = false\n continue\n }\n\n REACTIVE_LABEL_RE.lastIndex = i\n const label = REACTIVE_LABEL_RE.exec(src)\n if (label) {\n REACTIVE_ASSIGN_RE.lastIndex = i\n const assign = REACTIVE_ASSIGN_RE.exec(src)\n if (assign) vars.push(assign[1])\n const start = i + label[0].length\n const end = findStatementEnd(src, start)\n // the body is re-scanned rather than sliced raw, so an `import()`\n // inside it gets the $__import rewrite like anywhere else. Safe to\n // recurse: strings/comments/regexes copy through unchanged, and a\n // depth-0 declaration inside a labeled statement is a SyntaxError\n // in JS anyway, so nothing else can rewrite\n out += `$__effect(() => { ${transformSetupScript(src.slice(start, end)).code} });`\n i = end\n continue\n }\n }\n\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch)) depth = Math.max(0, depth - 1)\n\n if (ch === \"\\n\" || ch === \";\" || ch === \"}\") atStatementStart = true\n else if (!/\\s/.test(ch)) atStatementStart = false\n\n out += ch\n i++\n }\n\n return { vars, code: out }\n}\n\n// ---------------------------------------------------------------------------\n// factory scripts - a <script> whose top level has `export default` runs as a\n// plain lexical module instead of a `with`-scoped setup script: no implicit\n// reactivity, no `$:` labels - standard JS that editors and type-checkers\n// understand. The default export is called with the instance context\n// ({ $data, $effect, $emit, $mounted, $destroyed, $attached, $detached, $computed, $self, $$self }) and a returned object\n// is merged into the reactive store for the template to use.\n// Detection is backwards-safe: `export default` is a SyntaxError inside a\n// setup script, so no previously-working component can change behavior.\n// The same scanner rewrites the module-only syntax into a Function body:\n// - `export default X` -> `$__exports.default = X`\n// - `import d from \"m\"` -> `const d = $__default(await $__import(\"m\"))`\n// (and the other static clause forms), so imports resolve through the same\n// $__import as setup scripts: bundler map first, then fetch/native import\n// ---------------------------------------------------------------------------\n\nconst EXPORT_DEFAULT_RE = /export\\s+default(?![\\w$])/y\n// clause (default/namespace/named, no quotes or parens) + specifier; the\n// no-clause alternative requires the specifier right away, so dynamic\n// `import(...)` and `import.meta` never match\nconst STATIC_IMPORT_RE = /import\\s*(?:([\\w$\\s,{}*]+?)\\s*from\\s*)?([\"'])([^\"'\\n]+)\\2/y\n\n// splits an import clause on top-level commas: `d, { a, b as c }` keeps the\n// braced group together\nconst splitImportClause = (clause: string): string[] => {\n const parts: string[] = []\n let depth = 0\n let start = 0\n for (let i = 0; i <= clause.length; i++) {\n const ch = clause[i]\n if (ch === \"{\") depth++\n else if (ch === \"}\") depth--\n else if (i === clause.length || (ch === \",\" && depth === 0)) {\n const part = clause.slice(start, i).trim()\n if (part) parts.push(part)\n start = i + 1\n }\n }\n return parts\n}\n\n// one static import statement -> const bindings from the awaited module\nconst staticImportToAwait = (clause: string | undefined, spec: string, n: number): string => {\n const source = `await $__import(${JSON.stringify(spec)})`\n if (clause === undefined) return source // side-effect import\n const parts = splitImportClause(clause)\n const bindings: string[] = []\n let ref = source\n if (parts.length > 1) {\n const tmp = `$__mod${n}`\n bindings.push(`${tmp} = ${source}`)\n ref = tmp\n }\n for (const part of parts) {\n if (part.startsWith(\"{\")) bindings.push(`${part.replace(/\\s+as\\s+/g, \": \")} = ${ref}`)\n else if (part.startsWith(\"*\")) bindings.push(`${part.replace(/^\\*\\s*as\\s+/, \"\")} = ${ref}`)\n else bindings.push(`${part} = $__default(${ref})`)\n }\n return `const ${bindings.join(\", \")}`\n}\n\n// ---------------------------------------------------------------------------\n// the component's prop signature\n//\n// A component declares the props it takes as a destructuring pattern, in the\n// place each script mode already puts its inputs: the `:setup` attribute's\n// value, or the factory's *first* parameter (the ctx moved to the second).\n// Position is fixed, so the signature is read straight from the source string -\n// no parser, no execution - and the runtime can seed the defaults on the store\n// before the first render, which is what makes them reach the template even in\n// factory mode (where JS would only apply them inside the function body).\n//\n// <script :setup=\"{ label = 'Total', step = 1 }\">\n// export default ({ label = \"Total\" }, { $data }) => {}\n//\n// An object pattern *is* the declaration; anything else (`_`, a plain\n// identifier, no attribute at all) declares nothing and stays permissive.\n// ---------------------------------------------------------------------------\n\n// `as` is the local name the pattern binds the key to, when it isn't the key\n// itself (`{ item: row }`). A prop signature has no use for it - what the\n// store holds is the key - but the slot binder (`:slot=\"{ item: row }\"`) is\n// the same pattern read for the other half: which names the content uses\nexport type PropDecl = { name: string; default?: string; as?: string }\n\nconst IDENTIFIER_RE = /^[A-Za-z_$][\\w$]*$/\n\n// index of the bracket that closes the one opening at src[0], skipping\n// strings, comments and regex literals; src.length when unbalanced\nconst patternCloseIndex = (src: string): number => {\n let depth = 0\n let i = 0\n while (i < src.length) {\n const ch = src[i]\n if (ch === \"'\" || ch === '\"' || ch === \"`\") { i = skipString(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n if (ch === \"/\" && regexAllowed(src, i)) { i = skipRegex(src, i); continue }\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch) && --depth === 0) return i\n i++\n }\n return src.length\n}\n\n// index of the first `ch` at bracket depth 0, skipping strings and comments\nconst indexOfTopLevel = (src: string, ch: string): number => {\n let depth = 0\n let i = 0\n while (i < src.length) {\n const c = src[i]\n if (c === \"'\" || c === '\"' || c === \"`\") { i = skipString(src, i); continue }\n if (c === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (c === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n if (c === \"/\" && c !== ch && regexAllowed(src, i)) { i = skipRegex(src, i); continue }\n if (\"([{\".includes(c)) depth++\n else if (\")]}\".includes(c)) depth--\n else if (depth === 0 && c === ch) return i\n i++\n }\n return -1\n}\n\nconst splitTopLevel = (src: string): string[] => {\n const parts: string[] = []\n let depth = 0\n let start = 0\n let i = 0\n while (i <= src.length) {\n const ch = src[i]\n if (ch === \"'\" || ch === '\"' || ch === \"`\") { i = skipString(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n if (ch === \"/\" && regexAllowed(src, i)) { i = skipRegex(src, i); continue }\n if (ch !== undefined && \"([{\".includes(ch)) depth++\n else if (ch !== undefined && \")]}\".includes(ch)) depth--\n else if (i === src.length || (ch === \",\" && depth === 0)) {\n const part = src.slice(start, i).trim()\n if (part) parts.push(part)\n start = i + 1\n }\n i++\n }\n return parts\n}\n\n// the `=` that opens a default value: the first one at depth 0 that isn't part\n// of `==`/`===` or an arrow's `=>` (so `{ format = a => a }` keeps its default)\nconst defaultAssignIndex = (src: string): number => {\n let from = 0\n while (from < src.length) {\n const at = indexOfTopLevel(src.slice(from), \"=\")\n if (at === -1) return -1\n const i = from + at\n if (src[i + 1] !== \"=\" && src[i + 1] !== \">\" && src[i - 1] !== \"=\" && src[i - 1] !== \"!\") return i\n from = i + 1\n }\n return -1\n}\n\n// a destructuring pattern -> the props it declares. null means \"no signature\":\n// the pattern isn't an object one (`_`, `props`, nothing at all), so the\n// component declares nothing and keeps the permissive, undeclared behavior.\n// `{}` parses to [] - a closed signature that declares zero props\nexport const parsePropsPattern = (pattern: string | undefined): PropDecl[] | null => {\n const src = (pattern ?? \"\").trim()\n if (!src.startsWith(\"{\")) return null\n\n // to the `}` that closes the pattern, so a parameter's own default value\n // (`({ label } = {})`) is left out of it\n const close = patternCloseIndex(src)\n if (close >= src.length) return null // unbalanced: not a pattern we can read\n\n const props: PropDecl[] = []\n for (const part of splitTopLevel(src.slice(1, close))) {\n if (part.startsWith(\"...\")) continue // a rest element names no prop\n const assign = defaultAssignIndex(part)\n const named = assign === -1 ? part : part.slice(0, assign)\n const fallback = assign === -1 ? undefined : part.slice(assign + 1).trim()\n // `{ user: { id } }` and `{ user: renamed }` both declare `user`: what the\n // store holds is the key, whatever the pattern binds it to\n const colon = indexOfTopLevel(named, \":\")\n const name = (colon === -1 ? named : named.slice(0, colon)).trim()\n if (!IDENTIFIER_RE.test(name)) continue\n const decl: PropDecl = { name }\n if (fallback !== undefined) decl.default = fallback\n // only a plain rename is kept: `{ user: { id } }` binds no single name, so\n // there is nothing to record - the prop is still declared under its key\n const local = colon === -1 ? \"\" : named.slice(colon + 1).trim()\n if (IDENTIFIER_RE.test(local)) decl.as = local\n props.push(decl)\n }\n return props\n}\n\n// index just past a top-level `export default`, or -1\nconst findExportDefault = (src: string): number => {\n let i = 0\n let depth = 0\n let atStatementStart = true\n while (i < src.length) {\n const ch = src[i]\n if (ch === \"'\" || ch === '\"' || ch === \"`\") { i = skipString(src, i); atStatementStart = false; continue }\n if (ch === \"/\" && src[i + 1] === \"/\") { i = skipLineComment(src, i); continue }\n if (ch === \"/\" && src[i + 1] === \"*\") { i = skipBlockComment(src, i); continue }\n if (ch === \"/\" && regexAllowed(src, i)) { i = skipRegex(src, i); atStatementStart = false; continue }\n\n if (ch === \"e\" && depth === 0 && atStatementStart && (i === 0 || !/[\\w$.]/.test(src[i - 1]))) {\n EXPORT_DEFAULT_RE.lastIndex = i\n const found = EXPORT_DEFAULT_RE.exec(src)\n if (found) return i + found[0].length\n }\n\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch)) depth = Math.max(0, depth - 1)\n if (ch === \"\\n\" || ch === \";\" || ch === \"}\") atStatementStart = true\n else if (!/\\s/.test(ch)) atStatementStart = false\n i++\n }\n return -1\n}\n\nconst ASYNC_RE = /^async(?![\\w$])/\nconst FUNCTION_RE = /^function(?![\\w$])\\s*\\*?\\s*[A-Za-z_$][\\w$]*|^function(?![\\w$])\\s*\\*?/\n\n// source text of the exported function's first parameter, or null when there\n// is no parameter list to read (`export default Factory`, `export default\n// props => ...`, an exported object) - all of which declare nothing\nconst firstParameterSource = (src: string): string | null => {\n const start = findExportDefault(src)\n if (start === -1) return null\n\n let i = skipToToken(src, start)\n const rest = src.slice(i)\n if (ASYNC_RE.test(rest)) i = skipToToken(src, i + \"async\".length)\n const fn = FUNCTION_RE.exec(src.slice(i))\n if (fn) i = skipToToken(src, i + fn[0].length)\n if (src[i] !== \"(\") return null\n\n // the parameter list runs to the `)` that closes this `(`\n let depth = 0\n let end = i\n while (end < src.length) {\n const ch = src[end]\n if (ch === \"'\" || ch === '\"' || ch === \"`\") { end = skipString(src, end); continue }\n if (ch === \"/\" && src[end + 1] === \"/\") { end = skipLineComment(src, end); continue }\n if (ch === \"/\" && src[end + 1] === \"*\") { end = skipBlockComment(src, end); continue }\n if (ch === \"/\" && regexAllowed(src, end)) { end = skipRegex(src, end); continue }\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch) && --depth === 0) break\n end++\n }\n return splitTopLevel(src.slice(i + 1, end))[0] ?? \"\"\n}\n\n// the props declared by a factory script's first parameter. Throws the\n// migration error when it finds the pre-0.4 signature there - the ctx used to\n// be the first parameter, and the change is silent otherwise ($data would just\n// come back undefined). `$` is what tells them apart: what carries one comes\n// from the library, what doesn't comes from the parent, everywhere in jq79\nexport const parseFactoryProps = (src: string): PropDecl[] | null => {\n const first = firstParameterSource(src)\n if (first === null) return null\n const props = parsePropsPattern(first)\n const ctxName = props?.find(prop => prop.name.startsWith(\"$\"))?.name\n if (ctxName) {\n throw new Error(\n `jq79: the factory signature is (props, ctx), so \\`${ctxName}\\` can't be destructured from the first parameter. ` +\n `Write \\`export default (props, { ${ctxName} }) => …\\`, or \\`_\\` in place of props if the component takes none.`\n )\n }\n return props\n}\n\n// rewrites a factory script into a Function body, or returns null when the\n// script has no top-level `export default` (i.e. it's a regular setup script)\nexport const transformFactoryScript = (src: string): string | null => {\n let out = \"\"\n let i = 0\n let depth = 0\n let atStatementStart = true\n let isFactory = false\n let modCount = 0\n\n while (i < src.length) {\n const ch = src[i]\n const next = src[i + 1]\n const atWordBoundary = i === 0 || !/[\\w$.]/.test(src[i - 1])\n\n if (ch === \"'\" || ch === '\"' || ch === \"`\") {\n const end = skipString(src, i)\n out += src.slice(i, end)\n i = end\n atStatementStart = false\n continue\n }\n if (ch === \"/\" && (next === \"/\" || next === \"*\")) {\n const end = next === \"/\" ? skipLineComment(src, i) : skipBlockComment(src, i)\n out += src.slice(i, end)\n i = end\n continue\n }\n if (ch === \"/\" && regexAllowed(src, i)) {\n const end = skipRegex(src, i)\n out += src.slice(i, end)\n i = end\n atStatementStart = false\n continue\n }\n\n if (ch === \"i\" && atWordBoundary) {\n // dynamic import() -> $__import, same rewrite as setup scripts\n IMPORT_CALL_RE.lastIndex = i\n if (IMPORT_CALL_RE.test(src)) {\n out += \"$__import\"\n i += \"import\".length\n atStatementStart = false\n continue\n }\n if (depth === 0 && atStatementStart) {\n STATIC_IMPORT_RE.lastIndex = i\n const staticImport = STATIC_IMPORT_RE.exec(src)\n if (staticImport) {\n out += staticImportToAwait(staticImport[1], staticImport[3], modCount++)\n i += staticImport[0].length\n atStatementStart = false\n continue\n }\n }\n }\n\n if (ch === \"e\" && atWordBoundary && depth === 0 && atStatementStart) {\n EXPORT_DEFAULT_RE.lastIndex = i\n const exportDefault = EXPORT_DEFAULT_RE.exec(src)\n if (exportDefault) {\n isFactory = true\n out += \"$__exports.default =\"\n i += exportDefault[0].length\n atStatementStart = false\n continue\n }\n }\n\n if (\"([{\".includes(ch)) depth++\n else if (\")]}\".includes(ch)) depth = Math.max(0, depth - 1)\n\n if (ch === \"\\n\" || ch === \";\" || ch === \"}\") atStatementStart = true\n else if (!/\\s/.test(ch)) atStatementStart = false\n\n out += ch\n i++\n }\n\n return isFactory ? out : null\n}\n\n\n// ---------------------------------------------------------------------------\n// free identifiers in a template expression\n//\n// What a compiled expression reads from the scope, so it can be resolved by\n// name instead of by `with ($scope)` - which is 60% of an evaluation over a\n// store proxy, because it resolves every mention through [[HasProperty]] (the\n// proxy's `has` trap as well as its `get`) and consults Symbol.unscopables\n// besides. See RECORD/2026-08-27.name-resolution-without-with.md\n//\n// This is a scanner, not a parser, and it is deliberately conservative: `null`\n// means \"keep `with`\", and every shape that binds a name, assigns to one or\n// resolves one dynamically returns it. The caller falls back rather than\n// guesses, so a name this misses costs a slower evaluation, never a wrong one.\n// ---------------------------------------------------------------------------\n\n// words that scan as an identifier and are never a free variable read\nconst NOT_A_FREE_NAME = new Set([\n \"true\", \"false\", \"null\", \"undefined\", \"this\", \"typeof\", \"instanceof\", \"in\", \"new\", \"void\",\n \"delete\", \"of\", \"await\", \"yield\", \"NaN\", \"Infinity\", \"arguments\", \"case\", \"do\", \"else\", \"return\",\n])\n\n// anything that introduces a binding or reaches the scope by another route.\n// A dynamic `import(...)` is absent deliberately: naming it here would put the\n// word next to a quote in the bundle, which is what tests/no-bundle.test.ts\n// greps for. It needs no entry - `import` is collected as a free name, the\n// prologue's `const import = …` will not compile, and compileScoped falls back\nconst BINDS_A_NAME = new Set([\"function\", \"class\", \"let\", \"const\", \"var\", \"eval\", \"with\"])\n\n// the compiled function's own parameters and temporary: an expression that\n// mentions one would be reading the codegen's variable, not the author's\nconst CODEGEN_NAMES = new Set([\"$scope\", \"$r\", \"$t\"])\n\n// operators that write, or bind - any of them and the expression keeps `with`\nconst WRITES_RE = /^(?:\\+\\+|--|=>|\\*\\*=|<<=|>>>=|>>=|&&=|\\|\\|=|\\?\\?=|[+\\-*/%&|^]=(?!=))/\n// operators that merely read, longest first so `===` is never read as `==` + `=`\nconst READS_RE = /^(?:>>>|===|!==|\\*\\*|<<|>>|==|!=|<=|>=|&&|\\|\\||\\?\\?|\\?\\.)/\n\nconst isIdentifierStart = (ch: string): boolean => /[A-Za-z_$]/.test(ch)\n\n// a numeric literal, consumed whole so `1e5` does not scan as the name `e5`\nconst NUMBER_RE = /^(?:0[xXbBoO][\\da-fA-F_]+|\\d[\\d_]*(?:\\.[\\d_]*)?(?:[eE][+-]?\\d+)?)n?/\n\nexport const freeIdentifiers = (expr: string): string[] | null => {\n const names = new Set<string>()\n // one entry per open bracket, counting the `?`s waiting for their `:` at that\n // depth - which is what tells `{ danger: x }`'s key from `a ? b : c`'s colon\n const ternaries: number[] = [0]\n const brackets: string[] = []\n let shortCircuits = false\n let prev = \"\" // the last meaningful token: \"name\", \"value\", \".\" or \"?.\" or a punctuator\n let i = 0\n\n while (i < expr.length) {\n const ch = expr[i]\n if (/\\s/.test(ch)) { i++; continue }\n if (ch === \"/\" && expr[i + 1] === \"/\") { i = skipLineComment(expr, i); continue }\n if (ch === \"/\" && expr[i + 1] === \"*\") { i = skipBlockComment(expr, i); continue }\n if (ch === \"/\" && regexAllowed(expr, i)) { i = skipRegex(expr, i); prev = \"value\"; continue }\n if (ch === '\"' || ch === \"'\") { i = skipString(expr, i); prev = \"value\"; continue }\n\n if (ch === \"`\") {\n // a template literal reads names inside every ${...}, and nothing else\n let j = i + 1\n while (j < expr.length) {\n if (expr[j] === \"\\\\\") { j += 2; continue }\n if (expr[j] === \"`\") { j++; break }\n if (expr[j] === \"$\" && expr[j + 1] === \"{\") {\n let depth = 1\n const start = (j += 2)\n while (j < expr.length && depth > 0) {\n if (expr[j] === \"{\") depth++\n else if (expr[j] === \"}\") depth--\n j++\n }\n const inner = freeIdentifiers(expr.slice(start, j - 1))\n if (inner === null) return null\n inner.forEach(name => names.add(name))\n continue\n }\n j++\n }\n i = j\n prev = \"value\"\n continue\n }\n\n if (/\\d/.test(ch) && prev !== \".\" && prev !== \"?.\") {\n const match = NUMBER_RE.exec(expr.slice(i))\n i += match ? match[0].length : 1\n prev = \"value\"\n continue\n }\n\n if (isIdentifierStart(ch)) {\n let end = i\n while (end < expr.length && /[\\w$]/.test(expr[end])) end++\n const word = expr.slice(i, end)\n i = end\n if (BINDS_A_NAME.has(word)) return null\n if (prev === \".\" || prev === \"?.\") { prev = \"value\"; continue } // a property, not a name\n if (NOT_A_FREE_NAME.has(word)) { prev = word === \"this\" ? \"value\" : \"op\"; continue }\n if (CODEGEN_NAMES.has(word)) return null\n let after = i\n while (after < expr.length && /\\s/.test(expr[after])) after++\n // A free name that is CALLED is called with the with-object as its\n // receiver: `add()` inside `with ($scope)` runs with `this === $scope`,\n // and a factory component's `{ items: [], add() { this.items… } }`\n // depends on it. A `const` cannot reproduce that - the call would get\n // `undefined` - so a called name keeps `with`. Measured at 11 of this\n // repository's 239 resolvable expressions, and 8 of those are handlers\n if (expr[after] === \"(\") return null\n // `{ danger: … }` names a key; `a ? b : c` names a value\n const isKey = expr[after] === \":\" && expr[after + 1] !== \":\" &&\n brackets[brackets.length - 1] === \"{\" && ternaries[ternaries.length - 1] === 0\n if (!isKey) names.add(word)\n prev = \"value\"\n continue\n }\n\n const rest = expr.slice(i)\n if (WRITES_RE.test(rest)) return null\n const reads = READS_RE.exec(rest)\n if (reads) {\n if (reads[0] === \"&&\" || reads[0] === \"||\" || reads[0] === \"??\") shortCircuits = true\n prev = reads[0] === \"?.\" ? \"?.\" : \"op\"\n i += reads[0].length\n continue\n }\n if (ch === \"=\") return null // a bare `=` left after READS_RE is an assignment\n\n if (ch === \"(\" || ch === \"[\" || ch === \"{\") { brackets.push(ch); ternaries.push(0) }\n else if (ch === \")\" || ch === \"]\" || ch === \"}\") { brackets.pop(); if (ternaries.length > 1) ternaries.pop() }\n else if (ch === \"?\") { ternaries[ternaries.length - 1]++; shortCircuits = true }\n else if (ch === \":\" && ternaries[ternaries.length - 1] > 0) ternaries[ternaries.length - 1]--\n\n prev = ch\n i++\n }\n\n // every name is resolved before the expression runs, so a branch that would\n // not have been taken is read anyway: one more dep than `with` would track,\n // and a ReferenceError for a name only the dead branch mentions. With one\n // name there is no branch to be wrong about\n if (shortCircuits && names.size > 1) return null\n return [...names]\n}\n","// ---------------------------------------------------------------------------\n// what a component's text says, before there is a DOM\n//\n// The half of the runtime that reads a component as text: the rewrites that\n// run before the HTML parser sees it, the directive grammar the renderer reads\n// out of attributes and texts, and the exact text each expression and script\n// compiles to. Nothing here touches a document, which is what lets it serve\n// two entries - the runtime (jq79.ts), and precompile (precompile.ts), which\n// has to read a component as the runtime reads it, on node or in a worker, and\n// produce exactly what the runtime compiles. Moved out of jq79.ts verbatim, so\n// that sharing the code is what keeps the two in step - and so a page that\n// never precompiles doesn't carry the generator (RECORD/2026-09-23.no-unsafe-eval.md)\n// ---------------------------------------------------------------------------\n\nimport { freeIdentifiers, parsePropsPattern, parseFactoryProps, type PropDecl } from \"./transform\"\n\nexport type TemplateNode = {\n tag: string\n attrs: Record<string, string>\n children: (TemplateNode | string)[]\n // the tag as the author capitalized it, present only when they wrote it\n // uppercase-initial - i.e. when they meant a component. `tag` cannot answer\n // this: the HTML parser lowercases it, so the claim is captured before the\n // parse (see stampComponentTag) and lifted off attrs here, where it stops\n // looking like an attribute to every loop downstream\n component?: string\n // the element's namespace, present only when it is NOT HTML - an <svg>\n // subtree, or MathML. Read straight off the parsed tree, because the HTML\n // parser has already run the foreign-content algorithm over it and knows\n // things a tag name cannot say: whether this <title> is SVG's or HTML's, and\n // where a <foreignObject> hands the namespace back. Absent is the common\n // case and means HTML, so an ordinary node is exactly the shape it was\n ns?: string\n}\n\nexport type TagBlock = {\n attrs: Record<string, string>\n content: string\n // <style scoped> only: `content` rewritten to require the component's scope\n // attribute. Kept beside the original rather than replacing it, because a\n // shadow root doesn't want it - see headStyle()\n scoped?: string\n}\n\nexport const kebabToCamel = (name: string) => name.replace(/-(\\w)/g, (_, c: string) => c.toUpperCase())\n\n// the inverse, used only by the pre-parse name rewrite (see expandNameCase):\n// uppercase ASCII letters only, never digits - `:props.0` is a generated\n// attribute name and splitting on digits would mangle it. Round-trips through\n// kebabToCamel, acronyms included: userID -> user-i-d -> userID\nexport const camelToKebab = (name: string) => name.replace(/[A-Z]/g, c => `-${c.toLowerCase()}`)\n\nexport const VOID_ELEMENTS = new Set([\n \"area\", \"base\", \"br\", \"col\", \"embed\", \"hr\", \"img\", \"input\",\n \"link\", \"meta\", \"param\", \"source\", \"track\", \"wbr\",\n])\n\n// a self-closing tag with its attributes; quoted attribute values are matched\n// as whole chunks so a \"/>\" inside one doesn't end the tag early. The tag name\n// admits a dot for the named forms of a tag - <slot.header /> - which is a\n// legal HTML tag name (the tokenizer reads to the first space, \"/\" or \">\")\nexport const SELF_CLOSING_RE = /<([A-Za-z][\\w.-]*)((?:\"[^\"]*\"|'[^']*'|[^>\"'])*?)\\/>/g\nexport const RAW_BLOCK_RE = /(<script[\\s\\S]*?<\\/script\\s*>|<style[\\s\\S]*?<\\/style\\s*>)/gi\n\n// expands self-closing tags (<MyComponent />, <div />) into explicit\n// open+close pairs BEFORE DOM parsing. The HTML parser ignores the slash and\n// would treat them as unclosed, swallowing the following siblings. Void\n// elements keep their native behavior, and <script>/<style> contents are\n// passed through untouched so code inside them is never rewritten\nexport const expandSelfClosingTags = (src: string): string =>\n src\n .split(RAW_BLOCK_RE)\n .map((chunk, i) =>\n i % 2 === 1 // odd chunks are the captured script/style blocks\n ? chunk\n : chunk.replace(SELF_CLOSING_RE, (match, tag: string, attrs: string) =>\n VOID_ELEMENTS.has(tag.toLowerCase()) ? match : `<${tag}${attrs}></${tag}>`\n )\n )\n .join(\"\")\n\n// a start tag with its attributes, quote-aware so a \">\" inside a value doesn't\n// end it early; and a single spread attribute in name position (preceded by\n// start-or-whitespace), its expression an identifier or member path\nexport const OPEN_TAG_RE = /<([A-Za-z][\\w.-]*)((?:\"[^\"]*\"|'[^']*'|[^>\"'])*)>/g\nexport const ATTR_SPREAD_RE = /\"[^\"]*\"|'[^']*'|(^|\\s)\\.\\.\\.([A-Za-z_$][\\w$.]*)/g\n\n// `...expr` as an attribute is sugar for :props=\"expr\" (spread an object's\n// properties as props - see renderNestedComponent). Rewritten BEFORE DOM\n// parsing, into a value-based :props.<n>, because the HTML parser lowercases\n// attribute *names*: with the expression in the name, `...userData` would arrive\n// as `...userdata` and resolve to nothing. Moving it into a value - which the\n// parser leaves untouched - keeps camelCase intact. Same pre-parse string move\n// as expandSelfClosingTags, with the same defenses against rewriting code that\n// only looks like a spread: <script>/<style> bodies are split out (a JS `...rest`\n// there is not an attribute), only a start tag's interior is scanned (text\n// between tags is safe), and quoted values are consumed whole so a genuine JS\n// spread in a value (@click=\"f(...args)\", :x=\"{ ...a }\") is skipped. The <n>\n// suffix (per tag) only keeps several spreads' attribute names distinct. A call\n// (`...getProps()`) stops at the paren and is left alone - use :props=\"expr()\"\nexport const expandPropsSpread = (src: string): string =>\n src\n .split(RAW_BLOCK_RE)\n .map((chunk, i) =>\n i % 2 === 1\n ? chunk\n : chunk.replace(OPEN_TAG_RE, (_match, tag: string, attrs: string) => {\n let n = 0\n const rewritten = attrs.replace(ATTR_SPREAD_RE, (whole, space: string | undefined, expr: string | undefined) =>\n expr === undefined ? whole : `${space}:props.${n++}=\"${expr}\"`\n )\n return `<${tag}${rewritten}>`\n })\n )\n .join(\"\")\n\n// a `:`-prefixed attribute name in name position, and a </slot.name> closing\n// tag. Both quote-aware for the same reason ATTR_SPREAD_RE is: a colon inside\n// a value (@click=\"a ? b : c\", style=\"color: red\") is not an attribute name\nexport const ATTR_NAME_RE = /\"[^\"]*\"|'[^']*'|(^|\\s)(:[\\w.$-]+)/g\nexport const CLOSE_SLOT_RE = /<\\/slot\\.([\\w.$-]+)(\\s*)>/gi\nexport const SLOT_TAG_RE = /^slot\\./i\n\n// camelCase -> kebab-case for every name the HTML parser would lowercase,\n// BEFORE it gets the chance: `:firstName` would arrive as `:firstname` and\n// kebabToCamel (which is what reads these names back out) would have nothing\n// to un-kebab, so the prop, model or slot would silently land under the wrong\n// key. Rewriting to `:first-name` here means both spellings converge on the\n// same camelCase name downstream - the author picks, the runtime doesn't care.\n//\n// Runs FIRST among the pre-parse passes, which is what keeps it simple: it\n// never sees the `:props.<n>` that expandPropsSpread generates, and a\n// <slot.firstName /> is still one occurrence rather than the open+close pair\n// expandSelfClosingTags turns it into. Same defenses as the passes after it -\n// <script>/<style> bodies split out, only start-tag interiors scanned, quoted\n// values consumed whole.\n//\n// Three name positions, not one: attribute names (`:model.firstName`), the\n// dotted tag names (`<slot.firstName>`) and component tags (`<UserCard>`,\n// renamed by componentTagName below). The last two have closing halves that are\n// rewritten too, or the parser sees a mismatched pair\nexport const kebabTagName = (tag: string): string =>\n SLOT_TAG_RE.test(tag) ? `slot.${camelToKebab(tag.slice(\"slot.\".length))}` : tag\n\n// the same pass records what it declined to rewrite. An uppercase-initial tag\n// is a claim about a component: HTML's own elements are matched\n// case-insensitively but nobody writes <DIV> by accident, and a custom element\n// may not be spelled that way at all. So <UserCard> is a name the author\n// expected to resolve - which is what lets renderNode throw when it doesn't\n// (see unresolvedComponent).\n//\n// Carried in a *value* rather than left in the tag name, because the value is\n// the one place the HTML parser preserves case - the same move expandPropsSpread\n// makes for `...userData`, and for the same reason. elementToAST lifts it\n// straight off attrs into a field, so no attribute loop downstream ever sees\n// it - and since that lift is unconditional, the name has to be one no author\n// would write: a plain `:component` would eat the prop of that name off\n// <Card :component=\"Widget\" />\nexport const COMPONENT_TAG_ATTR = \":jq79-component\"\nexport const COMPONENT_TAG_RE = /^[A-Z]/\n\n// A component tag is renamed to a name the HTML parser cannot resolve to an\n// element, because a PascalCase tag is lowercased by the parser and what comes\n// out is *the native element of that name*: <Circle /> inside an <svg> is a\n// circle, <Tr /> is a row placed inside its <tbody>, and 70 of 90 ordinary\n// one-word component names collide the same way. The claim the author made -\n// this is a component - survives in the stamp, and the tag stops being a name\n// anything downstream can mistake for an element's.\n//\n// <Circle /> -> <c79-circle :jq79-component=\"Circle\" />\n// </UserCard> -> </c79-user-card>\n//\n// Hyphenated, and that is not cosmetic: `c79-circle` is a valid custom element\n// name, so the parser builds an HTMLElement for it, where `c79circle` would be\n// an HTMLUnknownElement. The hyphen is the shape the platform reserves for what\n// is not native, which is the principle this rests on applied to our own tags -\n// and it reads for itself in the inspector, where a component that resolves to\n// nothing leaves <c79-circle> rather than a plausible-looking <circle>.\n//\n// Every capitalized tag, not only the colliding ones: today's safe name is\n// tomorrow's element. See RECORD/2026-08-25.component-tag-prefix.md\nexport const COMPONENT_TAG_PREFIX = \"c79-\"\n\nexport const componentTagName = (tag: string): string =>\n `${COMPONENT_TAG_PREFIX}${camelToKebab(tag[0].toLowerCase() + tag.slice(1))}`\n\nexport const rewriteTagName = (tag: string): string =>\n COMPONENT_TAG_RE.test(tag) ? componentTagName(tag) : kebabTagName(tag)\n\n// the closing half of the rename. OPEN_TAG_RE matches open tags only, which was\n// fine while both ends lowercased to the same name; rename one end and not the\n// other and `<c79-circle>` gets closed by `</circle>`, nesting everything that\n// follows inside it. </slot.x> keeps its own pass - it is lowercase and\n// unaffected by this one\nexport const CLOSE_COMPONENT_RE = /<\\/([A-Z][\\w.-]*)(\\s*)>/g\n\n// appends the stamp inside the tag, *before* a self-closing slash: this pass\n// runs first and expandSelfClosingTags still has to recognize the `/>` that\n// OPEN_TAG_RE swept into the attributes. A slash inside a quoted value can't be\n// mistaken for it - only a trailing one is matched\nexport const TRAILING_SLASH_RE = /\\/\\s*$/\n\nexport const stampComponentTag = (tag: string, attrs: string): string => {\n if (!COMPONENT_TAG_RE.test(tag)) return attrs\n const stamp = ` ${COMPONENT_TAG_ATTR}=\"${tag}\"`\n const slash = TRAILING_SLASH_RE.exec(attrs)\n return slash ? `${attrs.slice(0, slash.index)}${stamp}${slash[0]}` : `${attrs}${stamp}`\n}\n\nexport const expandNameCase = (src: string): string =>\n src\n .split(RAW_BLOCK_RE)\n .map((chunk, i) =>\n i % 2 === 1\n ? chunk\n : chunk\n .replace(OPEN_TAG_RE, (_match, tag: string, attrs: string) => {\n const rewritten = attrs.replace(ATTR_NAME_RE, (whole, space: string | undefined, name: string | undefined) =>\n name === undefined ? whole : `${space}${camelToKebab(name)}`\n )\n return `<${rewriteTagName(tag)}${stampComponentTag(tag, rewritten)}>`\n })\n .replace(CLOSE_SLOT_RE, (_match, suffix: string, space: string) => `</slot.${camelToKebab(suffix)}${space}>`)\n .replace(CLOSE_COMPONENT_RE, (_match, tag: string, space: string) => `</${componentTagName(tag)}${space}>`)\n )\n .join(\"\")\n\n// all three pre-parse rewrites, in their load-bearing order (see\n// parseComponentString) - shared with precompile, which reads the same text\nexport const prepareSource = (component: string): string => expandSelfClosingTags(expandPropsSpread(expandNameCase(component)))\n\n// a component name has to be PascalCase to be usable: findComponentKey only\n// ever considers capitalized scope keys, so a lowercase name would declare a\n// component no tag could reference. It is also what keeps the named exports\n// from colliding with a definition's own fields, which are all lowercase\nexport const COMPONENT_NAME_RE = /^[A-Z][A-Za-z0-9]*$/\n\n// [\\s\\S] rather than `.` so an expression can span lines, like the ones in\n// directive attributes (which reach evalExpr wrapped in parens either way)\nexport const INTERPOLATION_RE = /{{\\s*([\\s\\S]+?)\\s*}}/g\n\n// A text template split once into its literal and expression parts. The split\n// used to happen on every run of every instance - `String.replace` over the\n// whole text, a fresh match object and a callback per expression - and a\n// :each over 1,000 rows runs it 1,000 times per text node to reach the same\n// answer about the same string. Keyed by the template text, like compileExpr's\n// cache and bounded the same way: by how many distinct texts the source holds\n//\n// An expression part is boxed so a literal `\"x\"` and an expression `x` stay\n// distinguishable without a second array\nexport type TextPart = string | { expr: string }\n\nexport const textParts = new Map<string, TextPart[]>()\n\nexport const splitText = (template: string): TextPart[] => {\n const cached = textParts.get(template)\n if (cached) return cached\n const parts: TextPart[] = []\n let at = 0\n INTERPOLATION_RE.lastIndex = 0\n for (let match = INTERPOLATION_RE.exec(template); match; match = INTERPOLATION_RE.exec(template)) {\n if (match.index > at) parts.push(template.slice(at, match.index))\n parts.push({ expr: match[1] })\n at = match.index + match[0].length\n }\n if (at < template.length) parts.push(template.slice(at))\n textParts.set(template, parts)\n return parts\n}\n\nexport const CONTROL_ATTRS = new Set([\":class\", \":value\", \":checked\", \":selected\", \":if\", \":elseif\", \":else\", \":each\", \":key\", \":with\", \":text\", \":html\", \":html.allowed\", \":props\"])\n\n// a control attribute is one the static-attr loop and nested-component prop\n// collection must skip. The set holds the fixed names; `:class.<name>` (the\n// single-flag shorthand) and `:props.<n>` (one spread among several) are\n// open-ended, so they're matched by prefix - they can't be enumerated into the set\nexport const isControlAttr = (attr: string): boolean =>\n CONTROL_ATTRS.has(attr) || attr.startsWith(\":class.\") || attr.startsWith(\":props.\") ||\n attr === \":slot\" || attr.startsWith(\":slot.\")\n// `item in items`, `item, i in items`, `(value, key) in props` - the second\n// binding is the array index or the object key, parens optional (Vue-style).\n// The list expression can span lines, so it matches [\\s\\S] rather than `.`\nexport const EACH_PATTERN = /^\\s*\\(?\\s*(\\w+)\\s*(?:,\\s*(\\w+))?\\s*\\)?\\s+in\\s+([\\s\\S]+)$/\n\n// <slot>, <slot.header-bar>: the hole and its name. Names arrive kebab-case\n// whichever way they were authored (the HTML parser lowercases tag names and\n// attribute modifiers alike, so expandNameCase normalizes camelCase to kebab\n// before parsing) and are camelCase where read - <slot.header-bar> and\n// <slot.headerBar> are :slot.header-bar is $slots.headerBar\nexport const isSlotTag = (tag: string): boolean => tag === \"slot\" || tag.startsWith(\"slot.\")\n\nexport const slotName = (suffix: string): string => (suffix ? kebabToCamel(suffix) : \"default\")\n\n// a :model's way back up: its expression as an assignment target. The newline\n// keeps `= $value` out of a trailing line comment in the expression\n// (:model=\"uname // the username\") - glued on the same line, the assignment\n// would vanish into the comment and compile as a bare read, dropping every\n// update without a word\nexport const assignment = (expr: string) => `${expr}\\n= $value`\n\n// the newline before `)` ends a trailing line comment in the expression\n// ({{ msg // greeting }}); ASI doesn't apply inside parens, so everything else\n// is untouched. Without it the comment eats the rest of this single-line body\n// and the expression never compiles\n// the text of the two forms an expression compiles to, and the parameters in\n// front of its extras - one place, because precompile has to produce exactly\n// what the runtime hands makeFunction, or its functions are never looked up\nexport const EXPR_PARAMS = [\"$scope\", \"$r\"]\n\nexport const withBody = (expr: string): string => `with ($scope) { return (${expr}\\n); }`\n\n// the scoped form: each free name read off the scope in a `const` prologue -\n// see compileScoped (jq79.ts) for what it buys and what it risks. null where\n// freeIdentifiers won't vouch for the names - the `with` form's case\nexport const scopedBody = (expr: string, params: string[]): string | null => {\n const free = freeIdentifiers(expr)\n if (free === null) return null\n // an extra is already a parameter of this function: declaring it again would\n // shadow the value the caller passed in\n const names = free.filter(name => !params.includes(name))\n const prologue = names.length === 0 ? \"\" : `let $t; ${names.map(name =>\n `const ${name} = ($t = $scope.${name}) !== undefined ? $t : $r($scope, ${JSON.stringify(name)});`).join(\" \")}`\n return `${prologue} return (${expr}\\n);`\n}\n\n// a parameter name can't contain a newline, so the key is unambiguous\nexport const functionKey = (params: string[], body: string): string => `${params.join(\",\")}\\n${body}`\n\n// a `:mounted` script is deferred by prepending the await on the code's own\n// first line, so deferring doesn't shift the lines devtools reports for it\nexport const defer = (code: string) => `await $mounted();${code}`\n\n// what the two kinds of script compile to, shared with precompile for the\n// reason the expression forms are\nexport const setupParams = (helperNames: string[]): string[] => [\"$scope\", \"$__effect\", \"$__import\", \"$__state\", ...helperNames]\nexport const setupBody = (code: string): string => `return (async () => { with ($scope) { ${code} }\\n;$__state.done = true })()`\nexport const factoryParams = (helperNames: string[]): string[] => [\"$__exports\", \"$__default\", \"$__import\", ...helperNames]\nexport const factoryBody = (code: string): string => `return (async () => { \"use strict\";\\n${code}\\n;$__exports.done = true })()`\n\n// the same answer without the warning - what precompile reads, which has\n// nobody to warn and would otherwise say it once per build\nexport const readSetupSignature = (script: TagBlock): PropDecl[] | null => {\n const pattern = script.attrs[\":setup\"]\n if (pattern === undefined) return null\n if (pattern.trim() === \"\") return []\n return parsePropsPattern(pattern)\n}\n\n// every prop name a component's scripts declare, across both script modes.\n// Read before the store exists, because what a component declares decides\n// which of its file's sibling components it can still see: declaring a name\n// says it comes from the parent, so the file's own definition of that name is\n// deliberately not in this component's scope. The runtime reads the setup\n// signatures with setupSignature, which warns; precompile, with readSetupSignature\nexport const declaredPropNames = (scripts: TagBlock[], signature: (script: TagBlock) => PropDecl[] | null): Set<string> => {\n const names = new Set<string>()\n scripts.forEach(script => {\n const declarations = parseFactoryProps(script.content) ?? signature(script)\n declarations?.forEach(({ name }) => names.add(name))\n })\n return names\n}\n\n// the names every setup and factory script is compiled with, in the order\n// renderWith passes them: SETUP_HELPERS (whose values live in jq79.ts, beside\n// the functions they are) and then the per-instance ones it builds -\n// $mounted, $destroyed, $attached, $detached, $computed, $self and $$self,\n// then the injected\n// $emit, $updateModel and $slots. They are positional parameters, so the order is part of what\n// precompile has to reproduce; change one side and precompiled scripts stop\n// matching, which tests/precompile.test.ts and `npm run check:precompile` catch\nexport const SETUP_HELPER_NAMES = [\"$\", \"$$\", \"$create\", \"$reactive\", \"$toRaw\", \"Component79\"]\nexport const INSTANCE_HELPER_NAMES = [\"$mounted\", \"$destroyed\", \"$attached\", \"$detached\", \"$computed\", \"$self\", \"$$self\", \"$emit\", \"$updateModel\", \"$slots\"]\n\n// the global a precompiled script leaves its functions on, for the runtime to\n// drain: (self.__jq79precompiled = self.__jq79precompiled || []).push([params,\n// body, fn], ...) - a global rather than a call, so the script can load before\n// the library or after it, and serve either build of it\nexport const PRECOMPILED_QUEUE = \"__jq79precompiled\"\n\n// the query parameter that asks safe mode's service worker for a component's\n// precompiled script rather than the component: /Card.html?jq79-precompiled\nexport const PRECOMPILED_PARAM = \"jq79-precompiled\"\n\n// a function's text laid out as `new Function` lays it out, so that a\n// precompiled or nonce-built function is named as eval's was, and devtools\n// reports the same line numbers for it\nexport const functionText = (params: string[], body: string): string =>\n `function anonymous(${params.join(\",\")}\\n) {\\n${body}\\n}`\n","import { parseHTML, type HTMLNode, type HTMLElementNode } from \"./html\"\nimport { transformSetupScript, transformFactoryScript, parsePropsPattern, parseFactoryProps } from \"./transform\"\nimport {\n COMPONENT_NAME_RE, COMPONENT_TAG_ATTR, EACH_PATTERN, EXPR_PARAMS, INSTANCE_HELPER_NAMES, PRECOMPILED_QUEUE,\n SETUP_HELPER_NAMES, functionText,\n assignment, declaredPropNames, defer, factoryBody, factoryParams, functionKey, isControlAttr, isSlotTag,\n kebabToCamel, prepareSource, readSetupSignature, scopedBody, setupBody, setupParams, splitText, withBody,\n type TagBlock, type TemplateNode,\n} from \"./source\"\n\n// ---------------------------------------------------------------------------\n// precompile\n//\n// Every function the runtime would build for a component, found without\n// rendering it: each expression in its template, each of its scripts, each\n// prop default - as the [params, body] pairs makeFunction would be handed, so\n// a table of them answers its lookups (see \"safe eval\" in jq79.ts). What renders\n// nothing still counts: a branch not taken, a handler never clicked, a :each\n// over an empty list are all here because each *could* run.\n//\n// It reads a file the way parseComponentString does - the same pre-parse\n// rewrites, the same split into the file's own component and its named\n// <template>s - with parseHTML standing in for DOMParser, which node and a\n// worker don't have. It reads a template the way the renderer does, directive\n// by directive, and builds each body with the same functions the runtime\n// compiles with (withBody, scopedBody, setupBody, factoryBody), so a key can\n// only match. Where the renderer's answer depends on the page - which scope\n// key a component tag resolves to - it takes every plausible one: an extra\n// function is an entry nobody looks up. What it can't see is a miss, and safe\n// mode reports a miss by name. tests/precompile.test.ts holds it against what\n// the runtime actually compiles\n// ---------------------------------------------------------------------------\n\nexport type Precompiled = [params: string[], body: string]\n\nconst isElementNode = (node: HTMLNode): node is HTMLElementNode => typeof node !== \"string\"\n\n// mirrors elementToAST: the component stamp lifted off attrs into a field\nconst toTemplateNode = (el: HTMLElementNode): TemplateNode => {\n const { [COMPONENT_TAG_ATTR]: component, ...attrs } = el.attrs\n return {\n tag: el.tag,\n attrs,\n ...(component === undefined ? {} : { component }),\n children: el.children.map(child => (typeof child === \"string\" ? child : toTemplateNode(child))),\n }\n}\n\nconst textOf = (el: HTMLElementNode): string => el.children.map(child => (typeof child === \"string\" ? child : textOf(child))).join(\"\")\n\n// the scope keys a tag can resolve to. findComponentKey matches any\n// capitalized key that equals the tag once dashes and case are gone, so the\n// key itself comes from the page; these are the spellings the file offers -\n// the tag as written, its PascalCase, and every capitalized name the file\n// declares that matches\nconst componentKeyCandidates = (node: TemplateNode, known: string[]): string[] => {\n const tag = node.component ?? node.tag\n const normalized = tag.replace(/-/g, \"\").toLowerCase()\n const keys = new Set(known.filter(name => /^[A-Z]/.test(name) && name.replace(/-/g, \"\").toLowerCase() === normalized))\n keys.add(node.component ?? kebabToCamel(node.tag).replace(/^./, c => c.toUpperCase()))\n return [...keys]\n}\n\ntype AddExpression = (expr: string, extras?: string[]) => void\n\n// every expression a template can evaluate, walked as renderNodes, renderNode,\n// renderEach, renderConditional, renderSlot and renderNestedComponent would\n// walk it - each clause names the one it follows\nconst collectExpressions = (nodes: (TemplateNode | string)[], known: string[], add: AddExpression) => {\n for (const node of nodes) {\n // renderNodes: text with an interpolation in it\n if (typeof node === \"string\") {\n if (node.includes(\"{{\")) splitText(node).forEach(part => { if (typeof part !== \"string\") add(part.expr) })\n continue\n }\n const attrs = node.attrs\n // renderConditional (chainOf), renderEach, and :with in renderNode - on any node\n if (\":if\" in attrs) add(attrs[\":if\"])\n if (\":elseif\" in attrs) add(attrs[\":elseif\"])\n if (\":each\" in attrs) {\n const match = attrs[\":each\"].match(EACH_PATTERN)\n if (match) add(match[3])\n if (\":key\" in attrs) add(attrs[\":key\"])\n }\n if (\":with\" in attrs) add(attrs[\":with\"])\n // bindSlotProps: a :slot binder's defaults, on a component tag or its <template>\n for (const attr in attrs) {\n if (attr === \":slot\" || attr.startsWith(\":slot.\")) {\n parsePropsPattern(attrs[attr] || undefined)?.forEach(({ default: fallback }) => { if (fallback !== undefined) add(fallback) })\n }\n }\n\n if (isSlotTag(node.tag)) {\n // renderSlot: a <slot>'s props - read by name, not camelCased\n for (const attr in attrs) {\n if (isControlAttr(attr) || attr.startsWith(\"@\") || !attr.startsWith(\":\")) continue\n add(attrs[attr] || attr.slice(1))\n }\n } else {\n // renderNestedComponent, for a tag that is or may become a component: the\n // key it resolves through, its props, spreads, models and tag events\n if (node.component !== undefined || node.tag.includes(\"-\")) {\n componentKeyCandidates(node, known).forEach(key => add(key))\n for (const attr in attrs) {\n const value = attrs[attr]\n if (attr === \":props\" || attr.startsWith(\":props.\")) add(value)\n else if (isControlAttr(attr)) continue\n else if (attr.startsWith(\"@\")) add(value, [\"$event\"])\n else if (attr === \":model\" || attr.startsWith(\":model.\")) {\n const expr = value || (attr === \":model\" ? \"model\" : kebabToCamel(attr.slice(\":model.\".length)))\n add(expr)\n add(assignment(expr), [\"$value\"])\n } else if (attr.startsWith(\":\")) add(value || kebabToCamel(attr.slice(1)))\n else add(JSON.stringify(value))\n }\n }\n // renderNode, for the element it renders as (and a component tag renders\n // as, until it resolves): events, bindings, and the control directives\n for (const attr in attrs) {\n const value = attrs[attr]\n if (attr.startsWith(\"@\")) add(value, [\"$event\"])\n else if (attr === \":model\" || attr.startsWith(\":model.\")) continue\n else if (attr === \":class\" || attr.startsWith(\":class.\") || attr === \":text\" || attr === \":html\" ||\n attr === \":html.allowed\" || attr === \":value\" || attr === \":checked\" || attr === \":selected\") add(value)\n else if (isControlAttr(attr)) continue\n else if (attr.startsWith(\":\")) add(value || kebabToCamel(attr.slice(1)))\n }\n }\n collectExpressions(node.children, known, add)\n }\n}\n\n// every function the runtime would build for the component in `source`, as\n// the [params, body] makeFunction would be handed - see the note above\nexport const precompile = (source: string): Precompiled[] => {\n const found = new Map<string, Precompiled>()\n const add = (params: string[], body: string) => { found.set(functionKey(params, body), [params, body]) }\n // an expression compiles to its scoped form first, and falls back to (or is\n // demoted to) the `with` form - both, where the scoped one exists\n const addExpression: AddExpression = (expr, extras = []) => {\n const params = [...EXPR_PARAMS, ...extras]\n const scoped = scopedBody(expr, extras)\n if (scoped !== null) add(params, scoped)\n add(params, withBody(expr))\n }\n\n // parseComponentString's split: a top-level <template> declares another\n // component of the file (a valid name, first one wins), everything else is\n // the file's own\n const top = parseHTML(prepareSource(source)).filter(isElementNode)\n const siblings: string[] = []\n const components: HTMLElementNode[][] = [top.filter(el => el.tag !== \"template\")]\n top.filter(el => el.tag === \"template\").forEach(el => {\n const name = el.attrs.name\n if (name === undefined || !COMPONENT_NAME_RE.test(name) || siblings.includes(name)) return\n siblings.push(name)\n components.push(el.children.filter(isElementNode))\n })\n\n components.forEach(elements => precompileComponent(elements, siblings, add, addExpression))\n\n return [...found.values()]\n}\n\nconst precompileComponent = (\n elements: HTMLElementNode[],\n siblings: string[],\n add: (params: string[], body: string) => void,\n addExpression: AddExpression\n) => {\n const scripts: TagBlock[] = elements\n .filter(el => el.tag === \"script\")\n .map(el => ({ attrs: el.attrs, content: textOf(el) }))\n const template = elements.filter(el => el.tag !== \"script\" && el.tag !== \"style\").map(toTemplateNode)\n\n // the helper names a script is compiled with: renderWith's\n // { ...SETUP_HELPERS, ...instanceHelpers }, where instanceHelpers is\n // { $mounted, $destroyed, $attached, $detached, $computed, $self, $$self,\n // ...injected, ...siblingScope } - key order included, because the\n // parameters are positional (built as objects, so a sibling named like a\n // helper keeps the helper's place, as it does there)\n //\n // Reading the signatures is also the first thing renderWith does, and where\n // it refuses a component - a factory destructuring a ctx name out of props\n // throws there, before anything compiles. Such a component has nothing to\n // precompile, and returning here leaves its error to the runtime, which is\n // where the page sees it, rather than failing the build (or the worker) on\n // its behalf\n let declared: Set<string>\n try {\n declared = declaredPropNames(scripts, readSetupSignature)\n } catch {\n return\n }\n const siblingScope = Object.fromEntries(siblings.filter(name => !declared.has(name)).map(name => [name, true]))\n const helperNames = Object.keys({\n ...Object.fromEntries(SETUP_HELPER_NAMES.map(name => [name, true])),\n ...Object.fromEntries(INSTANCE_HELPER_NAMES.map(name => [name, true])),\n ...siblingScope,\n })\n\n // the names the file declares, for the component tags that resolve to one\n const known = [...siblings]\n scripts.forEach(script => {\n const deferred = \":mounted\" in script.attrs\n const factoryCode = transformFactoryScript(script.content)\n if (factoryCode !== null) {\n const props = parseFactoryProps(script.content)\n props?.forEach(({ name, default: fallback }) => { known.push(name); if (fallback !== undefined) addExpression(fallback) })\n add(factoryParams(helperNames), factoryBody(deferred ? defer(factoryCode) : factoryCode))\n } else {\n const { vars, code } = transformSetupScript(script.content)\n known.push(...vars)\n readSetupSignature(script)?.forEach(({ name, default: fallback }) => { known.push(name); if (fallback !== undefined) addExpression(fallback) })\n add(setupParams(helperNames), setupBody(deferred ? defer(code) : code))\n }\n })\n\n collectExpressions(template, known, addExpression)\n}\n\n// a component's precompiled functions as the classic script that registers\n// them - classic, because they compile under `with`, which is a SyntaxError in\n// strict code and every module is strict.\n//\n// `parses` says whether a function's text parses as that one function: `new\n// Function` where eval is at hand (the Vite plugin, on node), a JavaScript\n// parser where it isn't (the service worker). One that doesn't parse ships as\n// null - the runtime's cached syntax error, which renders nothing, as it does\n// under eval. And because only text that parses as a single function is ever\n// written, no expression can close its function early and run what follows\n// when the script loads\nexport const precompiledScript = (entries: Precompiled[], parses: (params: string[], body: string) => boolean): string => {\n const items = entries.map(([params, body]) =>\n `[${JSON.stringify(params)}, ${JSON.stringify(body)}, ${parses(params, body) ? functionText(params, body) : \"null\"}]`\n )\n return `(self.${PRECOMPILED_QUEUE} = self.${PRECOMPILED_QUEUE} || []).push(\\n${items.join(\",\\n\")}\\n)\\n`\n}\n"],"mappings":"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","names":["VOID_TAGS","DOCUMENT_TAGS","RAW_TEXT_TAGS","ESCAPABLE_RAW_TEXT_TAGS","NAMED_REFERENCES","LATIN_1","LEGACY_REFERENCES","name","i","LEGACY_NAMES","a","b","has","table","fromCodePoint","code","CHARACTER_REFERENCE_RE","ALPHANUMERIC_RE","decodeReference","text","whole","ref","offset","inAttribute","hex","digits","semicolon","legacy","candidate","after","decode","TAG_NAME_RE","ATTRIBUTE_NAME_RE","WHITESPACE_RE","UNQUOTED_VALUE_RE","END_TAG_RE","readAt","re","src","at","rawTextEnd","from","tag","match","COMMENT","finish","node","child","parseHTML","input","root","stack","current","foreignDepth","appendText","children","last","close","depth","popped","lt","end","gt","ignored","cursor","attrs","selfClosing","complete","char","value","afterName","quote","key","DECLARATION_START_RE","REACTIVE_LABEL_RE","IMPORT_CALL_RE","REACTIVE_ASSIGN_RE","skipString","src","start","quote","i","skipLineComment","end","skipBlockComment","skipToToken","REGEX_AFTER_WORD","regexAllowed","at","ch","open","skipRegex","inClass","CONTINUATION_RE","lastMeaningfulBefore","findStatementEnd","depth","next","splitDeclarators","parts","lastEnd","flush","patternBindings","pattern","IDENTIFIER_RE","names","part","splitTopLevel","patternCloseIndex","assign","defaultAssignIndex","colon","indexOfTopLevel","rewriteDeclarators","vars","rewritten","raw","codeEnd","lead","body","tail","target","isPattern","code","transformSetupScript","out","atStatementStart","decl","label","EXPORT_DEFAULT_RE","STATIC_IMPORT_RE","splitImportClause","clause","staticImportToAwait","spec","n","source","bindings","ref","tmp","c","from","parsePropsPattern","close","props","named","fallback","name","local","findExportDefault","found","ASYNC_RE","FUNCTION_RE","firstParameterSource","rest","fn","parseFactoryProps","first","ctxName","prop","transformFactoryScript","isFactory","modCount","atWordBoundary","staticImport","exportDefault","NOT_A_FREE_NAME","BINDS_A_NAME","CODEGEN_NAMES","WRITES_RE","READS_RE","isIdentifierStart","NUMBER_RE","freeIdentifiers","expr","ternaries","brackets","shortCircuits","prev","j","inner","match","word","after","reads","kebabToCamel","name","_","c","camelToKebab","VOID_ELEMENTS","SELF_CLOSING_RE","RAW_BLOCK_RE","expandSelfClosingTags","src","chunk","i","match","tag","attrs","OPEN_TAG_RE","ATTR_SPREAD_RE","expandPropsSpread","_match","n","rewritten","whole","space","expr","ATTR_NAME_RE","CLOSE_SLOT_RE","SLOT_TAG_RE","kebabTagName","COMPONENT_TAG_ATTR","COMPONENT_TAG_RE","COMPONENT_TAG_PREFIX","componentTagName","rewriteTagName","CLOSE_COMPONENT_RE","TRAILING_SLASH_RE","stampComponentTag","stamp","slash","expandNameCase","suffix","prepareSource","component","COMPONENT_NAME_RE","INTERPOLATION_RE","textParts","splitText","template","cached","parts","at","CONTROL_ATTRS","isControlAttr","attr","EACH_PATTERN","isSlotTag","assignment","expr","EXPR_PARAMS","withBody","scopedBody","params","free","freeIdentifiers","names","name","functionKey","body","defer","code","setupParams","helperNames","setupBody","factoryParams","factoryBody","readSetupSignature","script","pattern","parsePropsPattern","declaredPropNames","scripts","signature","parseFactoryProps","SETUP_HELPER_NAMES","INSTANCE_HELPER_NAMES","PRECOMPILED_QUEUE","functionText","params","body","isElementNode","node","toTemplateNode","el","COMPONENT_TAG_ATTR","component","attrs","child","textOf","componentKeyCandidates","known","normalized","keys","name","kebabToCamel","c","collectExpressions","nodes","add","splitText","part","match","EACH_PATTERN","attr","parsePropsPattern","fallback","isSlotTag","isControlAttr","key","value","expr","assignment","precompile","source","found","params","body","functionKey","addExpression","extras","EXPR_PARAMS","scoped","scopedBody","withBody","top","parseHTML","prepareSource","siblings","components","COMPONENT_NAME_RE","elements","precompileComponent","scripts","template","declared","declaredPropNames","readSetupSignature","siblingScope","helperNames","SETUP_HELPER_NAMES","INSTANCE_HELPER_NAMES","script","deferred","factoryCode","transformFactoryScript","parseFactoryProps","factoryParams","factoryBody","defer","vars","code","transformSetupScript","setupParams","setupBody","precompiledScript","entries","parses","items","functionText","PRECOMPILED_QUEUE"]}
|
package/dist/reactive.d.ts
CHANGED
|
@@ -37,14 +37,24 @@ export type Effect = {
|
|
|
37
37
|
reindex: Set<(deps: Set<string>) => void>;
|
|
38
38
|
deep: boolean;
|
|
39
39
|
order: number;
|
|
40
|
+
home: Set<Effect>;
|
|
41
|
+
adopted: Map<Set<Effect>, Unsubscribe> | null;
|
|
42
|
+
read: Set<Set<Effect>> | null;
|
|
40
43
|
};
|
|
41
44
|
export declare const ALSO_WAKEN_BY: unique symbol;
|
|
45
|
+
export declare const OWNER: unique symbol;
|
|
42
46
|
export declare const $reactive: <T extends Record<string, any>>(data: T) => ReactiveDeepData<T>;
|
|
43
47
|
export type EffectScope = {
|
|
44
48
|
effect: (run: () => void) => void;
|
|
45
49
|
onDispose: (fn: Unsubscribe) => void;
|
|
46
50
|
refresh: () => void;
|
|
51
|
+
rerun: () => void;
|
|
52
|
+
ownedBy: (scope: Record<string, any>) => void;
|
|
47
53
|
dispose: () => void;
|
|
48
54
|
};
|
|
49
55
|
export declare const createEffectScope: (scope: Record<string, any>, deep?: boolean) => EffectScope;
|
|
56
|
+
export type Computed<T> = ReactiveDeepData<{
|
|
57
|
+
readonly value: T;
|
|
58
|
+
}>;
|
|
59
|
+
export declare const $computed: <T>(get: () => T) => Computed<T>;
|
|
50
60
|
export {};
|
package/dist/source.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type PropDecl } from "./transform";
|
|
2
|
+
export type TemplateNode = {
|
|
3
|
+
tag: string;
|
|
4
|
+
attrs: Record<string, string>;
|
|
5
|
+
children: (TemplateNode | string)[];
|
|
6
|
+
component?: string;
|
|
7
|
+
ns?: string;
|
|
8
|
+
};
|
|
9
|
+
export type TagBlock = {
|
|
10
|
+
attrs: Record<string, string>;
|
|
11
|
+
content: string;
|
|
12
|
+
scoped?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const kebabToCamel: (name: string) => string;
|
|
15
|
+
export declare const camelToKebab: (name: string) => string;
|
|
16
|
+
export declare const VOID_ELEMENTS: Set<string>;
|
|
17
|
+
export declare const SELF_CLOSING_RE: RegExp;
|
|
18
|
+
export declare const RAW_BLOCK_RE: RegExp;
|
|
19
|
+
export declare const expandSelfClosingTags: (src: string) => string;
|
|
20
|
+
export declare const OPEN_TAG_RE: RegExp;
|
|
21
|
+
export declare const ATTR_SPREAD_RE: RegExp;
|
|
22
|
+
export declare const expandPropsSpread: (src: string) => string;
|
|
23
|
+
export declare const ATTR_NAME_RE: RegExp;
|
|
24
|
+
export declare const CLOSE_SLOT_RE: RegExp;
|
|
25
|
+
export declare const SLOT_TAG_RE: RegExp;
|
|
26
|
+
export declare const kebabTagName: (tag: string) => string;
|
|
27
|
+
export declare const COMPONENT_TAG_ATTR = ":jq79-component";
|
|
28
|
+
export declare const COMPONENT_TAG_RE: RegExp;
|
|
29
|
+
export declare const COMPONENT_TAG_PREFIX = "c79-";
|
|
30
|
+
export declare const componentTagName: (tag: string) => string;
|
|
31
|
+
export declare const rewriteTagName: (tag: string) => string;
|
|
32
|
+
export declare const CLOSE_COMPONENT_RE: RegExp;
|
|
33
|
+
export declare const TRAILING_SLASH_RE: RegExp;
|
|
34
|
+
export declare const stampComponentTag: (tag: string, attrs: string) => string;
|
|
35
|
+
export declare const expandNameCase: (src: string) => string;
|
|
36
|
+
export declare const prepareSource: (component: string) => string;
|
|
37
|
+
export declare const COMPONENT_NAME_RE: RegExp;
|
|
38
|
+
export declare const INTERPOLATION_RE: RegExp;
|
|
39
|
+
export type TextPart = string | {
|
|
40
|
+
expr: string;
|
|
41
|
+
};
|
|
42
|
+
export declare const textParts: Map<string, TextPart[]>;
|
|
43
|
+
export declare const splitText: (template: string) => TextPart[];
|
|
44
|
+
export declare const CONTROL_ATTRS: Set<string>;
|
|
45
|
+
export declare const isControlAttr: (attr: string) => boolean;
|
|
46
|
+
export declare const EACH_PATTERN: RegExp;
|
|
47
|
+
export declare const isSlotTag: (tag: string) => boolean;
|
|
48
|
+
export declare const slotName: (suffix: string) => string;
|
|
49
|
+
export declare const assignment: (expr: string) => string;
|
|
50
|
+
export declare const EXPR_PARAMS: string[];
|
|
51
|
+
export declare const withBody: (expr: string) => string;
|
|
52
|
+
export declare const scopedBody: (expr: string, params: string[]) => string | null;
|
|
53
|
+
export declare const functionKey: (params: string[], body: string) => string;
|
|
54
|
+
export declare const defer: (code: string) => string;
|
|
55
|
+
export declare const setupParams: (helperNames: string[]) => string[];
|
|
56
|
+
export declare const setupBody: (code: string) => string;
|
|
57
|
+
export declare const factoryParams: (helperNames: string[]) => string[];
|
|
58
|
+
export declare const factoryBody: (code: string) => string;
|
|
59
|
+
export declare const readSetupSignature: (script: TagBlock) => PropDecl[] | null;
|
|
60
|
+
export declare const declaredPropNames: (scripts: TagBlock[], signature: (script: TagBlock) => PropDecl[] | null) => Set<string>;
|
|
61
|
+
export declare const SETUP_HELPER_NAMES: string[];
|
|
62
|
+
export declare const INSTANCE_HELPER_NAMES: string[];
|
|
63
|
+
export declare const PRECOMPILED_QUEUE = "__jq79precompiled";
|
|
64
|
+
export declare const PRECOMPILED_PARAM = "jq79-precompiled";
|
|
65
|
+
export declare const functionText: (params: string[], body: string) => string;
|
package/dist/vite.cjs
CHANGED
|
@@ -36,7 +36,55 @@ module.exports = __toCommonJS(vite_exports);
|
|
|
36
36
|
var import_promises = require("fs/promises");
|
|
37
37
|
var import_node_path = require("path");
|
|
38
38
|
var import_vite = require("vite");
|
|
39
|
+
var import_precompile = require("jq79/precompile");
|
|
39
40
|
var COMPONENT_QUERY = "?jq79";
|
|
41
|
+
var SAFE_EVAL_ID = "virtual:jq79/safe-eval";
|
|
42
|
+
var RESOLVED_SAFE_EVAL_ID = `\0${SAFE_EVAL_ID}`;
|
|
43
|
+
var safeEvalModule = (options) => `
|
|
44
|
+
let started = null
|
|
45
|
+
const loading = new Map()
|
|
46
|
+
const pageNonce = () => {
|
|
47
|
+
for (const script of document.querySelectorAll("script[nonce]")) {
|
|
48
|
+
const nonce = script.nonce || script.getAttribute("nonce")
|
|
49
|
+
if (nonce) return nonce
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export const safeEval = (Component79, url) => {
|
|
53
|
+
if (!started) started = Component79.safeEval(${JSON.stringify(options)}).catch(error => console.error(error))
|
|
54
|
+
let loaded = loading.get(url)
|
|
55
|
+
if (!loaded) {
|
|
56
|
+
loaded = new Promise((resolve, reject) => {
|
|
57
|
+
const script = document.createElement("script")
|
|
58
|
+
const nonce = pageNonce()
|
|
59
|
+
if (nonce) script.setAttribute("nonce", nonce)
|
|
60
|
+
script.src = url
|
|
61
|
+
script.onload = () => { script.remove(); resolve() }
|
|
62
|
+
script.onerror = () => {
|
|
63
|
+
script.remove()
|
|
64
|
+
reject(new Error("jq79: the precompiled functions at " + url + " did not load, and safeEval can't render without them"))
|
|
65
|
+
}
|
|
66
|
+
document.head.append(script)
|
|
67
|
+
})
|
|
68
|
+
loading.set(url, loaded)
|
|
69
|
+
}
|
|
70
|
+
return loaded
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
var PRECOMPILED_PATH = "/@jq79/precompiled.js";
|
|
74
|
+
var safeEvalOptions = (option) => {
|
|
75
|
+
if (option === void 0 || option === false) return null;
|
|
76
|
+
return typeof option === "object" && option !== null && option.nonce === true ? { nonce: true } : {};
|
|
77
|
+
};
|
|
78
|
+
var SCOPED_BODY_RE = /^(?:let \$t;| return \()/;
|
|
79
|
+
var componentScript = (source, warn) => (0, import_precompile.precompiledScript)((0, import_precompile.precompile)(source), (params, body) => {
|
|
80
|
+
try {
|
|
81
|
+
new Function(...params, body);
|
|
82
|
+
return true;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (!SCOPED_BODY_RE.test(body)) warn(`${error.message}, in: ${body.length > 120 ? `${body.slice(0, 120)}\u2026` : body}`);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
40
88
|
var SCRIPT_BLOCK_RE = /<script((?:"[^"]*"|'[^']*'|[^>"'])*)>([\s\S]*?)<\/script\s*>/gi;
|
|
41
89
|
var IMPORT_CALL_RE = /import\s*\(\s*(["'])([^"'\n]+?)\1\s*\)/y;
|
|
42
90
|
var STATIC_IMPORT_RE = /import\s*(?:[\w$\s,{}*]+?\s*from\s*)?(["'])([^"'\n]+)\1/y;
|
|
@@ -223,15 +271,19 @@ var compileScriptBlocks = async (source, file) => {
|
|
|
223
271
|
});
|
|
224
272
|
return out + source.slice(last);
|
|
225
273
|
};
|
|
226
|
-
var componentModule = (source, include, filename) => {
|
|
274
|
+
var componentModule = (source, include, filename, precompiled) => {
|
|
227
275
|
const hoisted = hoistableImports(source, include);
|
|
228
276
|
const imports = hoisted.map(
|
|
229
277
|
(spec, i) => include.test(spec) ? `import __jq79_${i} from ${JSON.stringify(spec)}` : `import * as __jq79_${i} from ${JSON.stringify(spec)}`
|
|
230
278
|
).join("\n");
|
|
231
279
|
const modulesMap = `{ ${hoisted.map((spec, i) => `${JSON.stringify(spec)}: __jq79_${i}`).join(", ")} }`;
|
|
280
|
+
const safeEvalImport = precompiled ? `
|
|
281
|
+
import { safeEval } from "${SAFE_EVAL_ID}"` : "";
|
|
282
|
+
const safeEvalCall = precompiled ? `
|
|
283
|
+
await safeEval(Component79, ${precompiled})` : "";
|
|
232
284
|
return `
|
|
233
|
-
import { Component79 } from "jq79"
|
|
234
|
-
${imports}
|
|
285
|
+
import { Component79 } from "jq79"${safeEvalImport}
|
|
286
|
+
${imports}${safeEvalCall}
|
|
235
287
|
|
|
236
288
|
const src = ${JSON.stringify(source)}
|
|
237
289
|
const modules = ${modulesMap}
|
|
@@ -264,6 +316,9 @@ ${declaredComponents(source).map((name) => `export const ${name} = component.${n
|
|
|
264
316
|
function jq79(options = {}) {
|
|
265
317
|
const include = options.include ?? /\.html$/;
|
|
266
318
|
const { exclude } = options;
|
|
319
|
+
const safeEval = safeEvalOptions(options.safeEval);
|
|
320
|
+
const devScripts = /* @__PURE__ */ new Map();
|
|
321
|
+
const devIds = /* @__PURE__ */ new Map();
|
|
267
322
|
let config = null;
|
|
268
323
|
return {
|
|
269
324
|
name: "jq79",
|
|
@@ -271,7 +326,20 @@ function jq79(options = {}) {
|
|
|
271
326
|
configResolved(resolved) {
|
|
272
327
|
config = resolved;
|
|
273
328
|
},
|
|
329
|
+
configureServer(server) {
|
|
330
|
+
if (!safeEval) return;
|
|
331
|
+
server.middlewares.use((req, res, next) => {
|
|
332
|
+
const url = new URL(req.url ?? "/", "http://localhost");
|
|
333
|
+
if (!url.pathname.endsWith(PRECOMPILED_PATH)) return next();
|
|
334
|
+
const script = devScripts.get(url.searchParams.get("id") ?? "");
|
|
335
|
+
if (script === void 0) return next();
|
|
336
|
+
res.setHeader("Content-Type", "text/javascript");
|
|
337
|
+
res.setHeader("Cache-Control", "no-cache");
|
|
338
|
+
res.end(script);
|
|
339
|
+
});
|
|
340
|
+
},
|
|
274
341
|
async resolveId(source, importer) {
|
|
342
|
+
if (source === SAFE_EVAL_ID) return RESOLVED_SAFE_EVAL_ID;
|
|
275
343
|
if (!importer) return null;
|
|
276
344
|
if (source.includes("?")) return null;
|
|
277
345
|
if (!include.test(source)) return null;
|
|
@@ -281,13 +349,26 @@ function jq79(options = {}) {
|
|
|
281
349
|
return resolved.id + COMPONENT_QUERY;
|
|
282
350
|
},
|
|
283
351
|
async load(id) {
|
|
352
|
+
if (id === RESOLVED_SAFE_EVAL_ID) return safeEvalModule({ ...safeEval, worker: false });
|
|
284
353
|
if (!id.endsWith(COMPONENT_QUERY)) return null;
|
|
285
354
|
const file = id.slice(0, -COMPONENT_QUERY.length);
|
|
286
355
|
let source = await (0, import_promises.readFile)(file, "utf8");
|
|
287
356
|
source = await compileScriptBlocks(source, file);
|
|
288
357
|
if (config) source = await compileStyleBlocks(source, file, config, (dep) => this.addWatchFile(dep));
|
|
289
358
|
const filename = config ? (0, import_node_path.relative)(config.root, file) : file;
|
|
290
|
-
return { code: componentModule(source, include, filename), map: null };
|
|
359
|
+
if (!safeEval) return { code: componentModule(source, include, filename), map: null };
|
|
360
|
+
const script = componentScript(source, (message) => this.warn(`jq79: ${filename}: ${message}`));
|
|
361
|
+
let url;
|
|
362
|
+
if (config?.command === "serve") {
|
|
363
|
+
let devId = devIds.get(file);
|
|
364
|
+
if (devId === void 0) devIds.set(file, devId = devIds.size);
|
|
365
|
+
devScripts.set(String(devId), script);
|
|
366
|
+
url = JSON.stringify(`${config.base}${PRECOMPILED_PATH.slice(1)}?id=${devId}&v=${Date.now()}`);
|
|
367
|
+
} else {
|
|
368
|
+
const ref = this.emitFile({ type: "asset", name: `${(0, import_node_path.basename)(file)}.jq79.js`, source: script });
|
|
369
|
+
url = `import.meta.ROLLUP_FILE_URL_${ref}`;
|
|
370
|
+
}
|
|
371
|
+
return { code: componentModule(source, include, filename, url), map: null };
|
|
291
372
|
}
|
|
292
373
|
};
|
|
293
374
|
}
|