UNPKG

marko

Version:

Optimized runtime for Marko templates.

1,396 lines 120 kB
//#region src/common/attr-tag.ts const empty = []; const rest = Symbol("Attribute Tag"); function attrTag(attrs) { attrs[Symbol.iterator] = attrTagIterator; attrs[rest] = empty; return attrs; } function attrTags(first, attrs) { if (first) { if (first[rest] === empty) first[rest] = [attrs]; else first[rest].push(attrs); return first; } return attrTag(attrs); } function* attrTagIterator() { yield this; yield* this[rest]; } //#endregion //#region src/common/constants/accessor-prefix.debug.ts const BranchScopes = "BranchScopes:"; const ConditionalRenderer = "ConditionalRenderer:"; const ControlledHandler = "ControlledHandler:"; const ControlledType = "ControlledType:"; const ControlledValue = "ControlledValue:"; const EventAttributes = "EventAttributes:"; const BranchAccessor = "#BranchAccessor"; const CatchContent = "#CatchContent"; const ClosestBranchId = "#ClosestBranchId"; const LoopKey = "#LoopKey"; const PlaceholderContent = "#PlaceholderContent"; const Renderer = "#Renderer"; const TagVariable = "#TagVariable"; const Embed = "embed"; //#endregion //#region src/common/helpers.ts const htmlAttrNameReg = /^[^a-z_]|[^a-z0-9._:-]/i; const knownWrongAttrs = { className: "class", classList: "class", htmlFor: "for", acceptCharset: "accept-charset", httpEquiv: "http-equiv", defaultValue: "value", defaultChecked: "checked", dangerouslySetInnerHTML: "$!{html}", key: "<for by>", ref: "<tag/ref>", "v-if": "<if>", "v-else": "<else>", "v-else-if": "<else if>", "v-for": "<for>", "v-show": "<if>", "v-model": "value:=state", "v-bind": "...attrs", "v-html": "$!{html}", "v-text": "${text}" }; function getWrongAttrSuggestion(name) { if (Object.hasOwn(knownWrongAttrs, name)) return knownWrongAttrs[name]; const colon = name.indexOf(":"); if (colon > 0) { const rest = name.slice(colon + 1); switch (name.slice(0, colon)) { case "class": return `class={ ${rest}: condition }`; case "style": return `style={ ${rest}: value }`; case "on": case "v-on": return `on${rest.charAt(0).toUpperCase()}${rest.slice(1)}`; case "bind": case "v-model": return `${rest}:=state`; case "v-bind": return rest; } } } function stringifyClassObject(name, value) { return value ? name : ""; } const warnedStyleKeys = /* @__PURE__ */ new Set(); function stringifyStyleObject(name, value) { if (/[A-Z]/.test(name) && !name.includes("-") && !warnedStyleKeys.has(name)) { warnedStyleKeys.add(name); console.warn(`\`${name}\` is not a CSS property name; \`style\` object keys are written verbatim, so it renders as invalid CSS. Use \`${name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^ms-/, "-ms-")}\`.`); } return value || value === 0 ? escapeStyleAttr(name) + ":" + escapeStyleAttr(value + "") : ""; } const unsafeStyleAttrReg = /[\\;]/g; const replaceUnsafeStyleAttr = (c) => c === ";" ? "\\3B " : "\\\\"; function escapeStyleAttr(str) { return unsafeStyleAttrReg.test(str) ? str.replace(unsafeStyleAttrReg, replaceUnsafeStyleAttr) : str; } function escapeStyleValue(str) { let closers = ""; const result = str.replace(/[\\"'{};<>]|\/(?=\*)/g, (c) => c === "<" ? "\\3C " : c === ";" ? "\\3B " : c === "{" ? "\\7B " : "\\" + c); for (const c of result) if (c === "(") closers = ")" + closers; else if (c === "[") closers = "]" + closers; else if (c === closers[0]) closers = closers.slice(1); return result + closers; } const toDelimitedString = function toDelimitedString(val, delimiter, stringify) { let str = ""; let sep = ""; let part; if (val) if (typeof val !== "object") str += val; else if (Array.isArray(val)) for (const v of val) { part = toDelimitedString(v, delimiter, stringify); if (part) { str += sep + part; sep = delimiter; } } else for (const name in val) { part = stringify(name, val[name]); if (part) { str += sep + part; sep = delimiter; } } return str; }; function isEventHandler(name) { return /^on[A-Z-]/.test(name); } function getEventHandlerName(name) { return name[2] === "-" ? name.slice(3) : name.slice(2).toLowerCase(); } function isVoid(value) { return value == null || value === false; } function isNotVoid(value) { return value != null && value !== false; } function isPromise(value) { return value != null && typeof value.then === "function"; } function normalizeDynamicRenderer(value) { if (value) { if (typeof value === "string") return value; const normalized = value.content || value.default || value; if (!((typeof normalized === "object" || typeof normalized === "function") && "id" in normalized)) { if (value.content) throw new Error(`A dynamic tag must be a string tag name (like \`"div"\`) or a Marko template/component, but received an object whose \`content\` is not a template/component.`); if (typeof value !== "object" && typeof value !== "function") throw new Error(`A dynamic tag must be a string tag name (like \`"div"\`) or a Marko template/component, but received a ${typeof value}.`); } if ("id" in normalized) return normalized; } } //#endregion //#region src/common/errors.ts const lowercaseEventHandlerReg = /^on[a-z]/; function assertValidAttrValue(name, value) { if (value && typeof value !== "string" && lowercaseEventHandlerReg.test(name)) throw new Error(`The \`${name}\` attribute must be a string or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}". To attach an event listener, use the \`on${name[2].toUpperCase()}${name.slice(3)}\` event handler instead.`); if (typeof value === "function") throw new Error(`The \`${name}\` attribute cannot be a function.${/Change$/.test(name) ? " A change handler is only used when its matching controllable attribute combination applies." : ""}`); const unrenderable = describeUnrenderable(value); if (unrenderable) throw new Error(`The \`${name}\` attribute cannot be ${unrenderable}.`); } function assertValidTextValue(value) { const unrenderable = describeUnrenderable(value); if (unrenderable) throw new Error(`Text content cannot be ${unrenderable}.`); } function describeUnrenderable(value) { if (typeof value === "symbol") return "a symbol"; if (typeof value === "object" && value !== null) { let stringified; try { stringified = `${value}`; } catch { stringified = "[object Object]"; } if (/^\[object \w+\]$/.test(stringified)) return stringified === "[object Promise]" ? "a promise (use the `<await>` tag to render its resolved value)" : stringified === "[object Object]" ? "a plain object (it would render as `[object Object]`)" : `a value that renders as \`${stringified}\``; } } function assertValidLoopKey(key, seenKeys) { if (typeof key !== "string" && typeof key !== "number") throw new Error(`A \`<for>\` tag's \`by\` attribute must return a string or number for each item, but received ${key === null ? "null" : `type "${typeof key}"`}.`); if (seenKeys) { if (seenKeys.has(key)) throw new Error(`A \`<for>\` tag's \`by\` attribute must return a unique value for each item, but \`${key}\` was used more than once.`); seenKeys.add(key); } } function assertValidList(value) { if (value && typeof value[Symbol.iterator] !== "function") throw new Error(`A \`<for>\` tag's \`of\` attribute must be an iterable, such as an array, but received ${describeForValue(value)}.`); } function assertValidRangeBound(name, value) { if (!isFinite(value)) throw new Error(`A \`<for>\` tag's \`${name}\` attribute must be a finite number, but received ${describeForValue(value)}.`); } function describeForValue(value) { return typeof value === "number" || typeof value === "bigint" ? `\`${value}\`` : value === null ? "null" : `type "${typeof value}"`; } function assertValidAttrName(name) { if (htmlAttrNameReg.test(name)) throw new Error(`Invalid attribute name: ${JSON.stringify(name)}`); const suggestion = getWrongAttrSuggestion(name); if (suggestion) throw new Error(`\`${name}\` is not a valid attribute, did you mean \`${suggestion}\`?`); } function _el_read_error() { throw new Error("Element references can only be read in scripts and event handlers."); } function _hoist_read_error() { throw new Error("Hoisted values can only be read in scripts and event handlers."); } function _assert_hoist(value) { if (typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`); } function assertExclusiveAttrs(attrs, onError = throwErr) { if (attrs) { let exclusiveAttrs; if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange"); if ("checkedValue" in attrs) { (exclusiveAttrs ||= []).push("checkedValue"); if ("checked" in attrs) exclusiveAttrs.push("checked"); } else if (attrs.checkedValueChange) { (exclusiveAttrs ||= []).push("checkedValueChange"); if ("checked" in attrs) exclusiveAttrs.push("checked"); } if (attrs.valueChange) (exclusiveAttrs ||= []).push("valueChange"); if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`); } } function assertHandlerIsFunction(name, value) { if (value && typeof value !== "function") throw new Error(`The \`${name}\` handler must be a function or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}".`); } function assertValidTagName(tagName) { if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) throw new Error(`Invalid tag name: "${tagName}". Tag names must start with a letter and contain only letters, numbers, periods, hyphens, and underscores.`); } function throwErr(msg) { throw new Error(msg); } function joinWithAnd(a) { switch (a.length) { case 0: return ""; case 1: return a[0]; case 2: return `${a[0]} and ${a[1]}`; default: return `${a.slice(0, -1).join(", ")}, and ${a[a.length - 1]}`; } } //#endregion //#region src/common/meta.ts const DYNAMIC_TAG_SCRIPT_REGISTER_ID = "_dynamicTagScript"; //#endregion //#region src/html/content.ts function _to_text(val) { assertValidTextValue(val); return val || val === 0 ? val + "" : ""; } function _unescaped(val) { assertValidTextValue(val); return val ? val + "" : val === 0 ? "0" : ""; } const unsafeXMLReg = /[<&]/g; const replaceUnsafeXML = (c) => c === "&" ? "&amp;" : "&lt;"; const escapeXMLStr = (str) => unsafeXMLReg.test(str) ? str.replace(unsafeXMLReg, replaceUnsafeXML) : str; function _escape(val) { assertValidTextValue(val); return val ? escapeXMLStr(val + "") : val === 0 ? "0" : ""; } const unsafeScriptReg = /<(\/?script|!--)/gi; const escapeScriptStr = (str) => unsafeScriptReg.test(str) ? str.replace(unsafeScriptReg, "\\x3C$1") : str; function _escape_script(val) { assertValidTextValue(val); return val ? escapeScriptStr(val + "") : val === 0 ? "0" : ""; } const unsafeStyleReg = /<(\/style)/gi; const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str; function _escape_style(val) { assertValidTextValue(val); return val ? escapeStyleStr(val + "") : val === 0 ? "0" : ""; } function _escape_style_value(val) { assertValidTextValue(val); return val || val === 0 ? escapeStyleValue(val + "") : ""; } const unsafeCommentReg = />/g; const escapeCommentStr = (str) => unsafeCommentReg.test(str) ? str.replace(unsafeCommentReg, "&gt;") : str; function _escape_comment(val) { assertValidTextValue(val); return val ? escapeCommentStr(val + "") : val === 0 ? "0" : ""; } //#endregion //#region src/html/serializer.ts const K_SCOPE_ID = Symbol("Scope ID"); const kTouchedIterator = Symbol.for("marko.touchedIterator"); const { hasOwnProperty } = {}; const objectProto = Object.prototype; const arrayProto = Array.prototype; const Generator = (function* () {})().constructor; const AsyncGenerator = (async function* () {})().constructor; patchIteratorNext(Generator.prototype); patchIteratorNext(AsyncGenerator.prototype); const REGISTRY = /* @__PURE__ */ new WeakMap(); const KNOWN_SYMBOLS = (() => { const KNOWN_SYMBOLS = /* @__PURE__ */ new Map(); for (const name of Object.getOwnPropertyNames(Symbol)) { const symbol = Symbol[name]; if (typeof symbol === "symbol") KNOWN_SYMBOLS.set(symbol, "Symbol." + name); } return KNOWN_SYMBOLS; })(); const KNOWN_FUNCTIONS = /* @__PURE__ */ new Map([ [AggregateError, "AggregateError"], [Array, "Array"], [Array.from, "Array.from"], [Array.isArray, "Array.isArray"], [Array.of, "Array.of"], [ArrayBuffer, "ArrayBuffer"], [ArrayBuffer.isView, "ArrayBuffer.isView"], [Atomics.add, "Atomics.add"], [Atomics.and, "Atomics.and"], [Atomics.compareExchange, "Atomics.compareExchange"], [Atomics.exchange, "Atomics.exchange"], [Atomics.isLockFree, "Atomics.isLockFree"], [Atomics.load, "Atomics.load"], [Atomics.notify, "Atomics.notify"], [Atomics.or, "Atomics.or"], [Atomics.store, "Atomics.store"], [Atomics.sub, "Atomics.sub"], [Atomics.wait, "Atomics.wait"], [BigInt, "BigInt"], [BigInt.asIntN, "BigInt.asIntN"], [BigInt.asUintN, "BigInt.asUintN"], [BigInt64Array, "BigInt64Array"], [BigInt64Array.from, "BigInt64Array.from"], [BigInt64Array.of, "BigInt64Array.of"], [BigUint64Array, "BigUint64Array"], [BigUint64Array.from, "BigUint64Array.from"], [BigUint64Array.of, "BigUint64Array.of"], [Boolean, "Boolean"], [console.assert, "console.assert"], [console.clear, "console.clear"], [console.count, "console.count"], [console.countReset, "console.countReset"], [console.debug, "console.debug"], [console.dir, "console.dir"], [console.dirxml, "console.dirxml"], [console.error, "console.error"], [console.group, "console.group"], [console.groupCollapsed, "console.groupCollapsed"], [console.groupEnd, "console.groupEnd"], [console.info, "console.info"], [console.log, "console.log"], [console.table, "console.table"], [console.time, "console.time"], [console.timeEnd, "console.timeEnd"], [console.timeLog, "console.timeLog"], [console.timeStamp, "console.timeStamp"], [console.trace, "console.trace"], [console.warn, "console.warn"], [DataView, "DataView"], [Date, "Date"], [Date.now, "Date.now"], [Date.parse, "Date.parse"], [Date.UTC, "Date.UTC"], [decodeURI, "decodeURI"], [decodeURIComponent, "decodeURIComponent"], [encodeURI, "encodeURI"], [encodeURIComponent, "encodeURIComponent"], [Error, "Error"], [EvalError, "EvalError"], [Float32Array, "Float32Array"], [Float32Array.from, "Float32Array.from"], [Float32Array.of, "Float32Array.of"], [Float64Array, "Float64Array"], [Float64Array.from, "Float64Array.from"], [Float64Array.of, "Float64Array.of"], [Function, "Function"], [globalThis.atob, "atob"], [globalThis.btoa, "btoa"], [globalThis.clearImmediate, "clearImmediate"], [globalThis.clearInterval, "clearInterval"], [globalThis.clearTimeout, "clearTimeout"], [globalThis.crypto?.getRandomValues, "crypto.getRandomValues"], [globalThis.crypto?.randomUUID, "crypto.randomUUID"], [globalThis.fetch, "fetch"], [globalThis.performance?.now, "performance.now"], [globalThis.queueMicrotask, "queueMicrotask"], [globalThis.setImmediate, "setImmediate"], [globalThis.setInterval, "setInterval"], [globalThis.setTimeout, "setTimeout"], [globalThis.structuredClone, "structuredClone"], [globalThis.URL, "URL"], [globalThis.URLSearchParams, "URLSearchParams"], [globalThis.WritableStream, "WritableStream"], [Int16Array, "Int16Array"], [Int16Array.from, "Int16Array.from"], [Int16Array.of, "Int16Array.of"], [Int32Array, "Int32Array"], [Int32Array.from, "Int32Array.from"], [Int32Array.of, "Int32Array.of"], [Int8Array, "Int8Array"], [Int8Array.from, "Int8Array.from"], [Int8Array.of, "Int8Array.of"], [Intl.Collator, "Intl.Collator"], [Intl.DateTimeFormat, "Intl.DateTimeFormat"], [Intl.DisplayNames, "Intl.DisplayNames"], [Intl.getCanonicalLocales, "Intl.getCanonicalLocales"], [Intl.ListFormat, "Intl.ListFormat"], [Intl.Locale, "Intl.Locale"], [Intl.NumberFormat, "Intl.NumberFormat"], [Intl.PluralRules, "Intl.PluralRules"], [Intl.RelativeTimeFormat, "Intl.RelativeTimeFormat"], [Intl.Segmenter, "Intl.Segmenter"], [Intl.supportedValuesOf, "Intl.supportedValuesOf"], [isFinite, "isFinite"], [isNaN, "isNaN"], [JSON.parse, "JSON.parse"], [JSON.stringify, "JSON.stringify"], [Map, "Map"], [Map.groupBy, "Map.groupBy"], [Math.abs, "Math.abs"], [Math.acos, "Math.acos"], [Math.acosh, "Math.acosh"], [Math.asin, "Math.asin"], [Math.asinh, "Math.asinh"], [Math.atan, "Math.atan"], [Math.atan2, "Math.atan2"], [Math.atanh, "Math.atanh"], [Math.cbrt, "Math.cbrt"], [Math.ceil, "Math.ceil"], [Math.clz32, "Math.clz32"], [Math.cos, "Math.cos"], [Math.cosh, "Math.cosh"], [Math.exp, "Math.exp"], [Math.expm1, "Math.expm1"], [Math.floor, "Math.floor"], [Math.fround, "Math.fround"], [Math.hypot, "Math.hypot"], [Math.imul, "Math.imul"], [Math.log, "Math.log"], [Math.log10, "Math.log10"], [Math.log1p, "Math.log1p"], [Math.log2, "Math.log2"], [Math.max, "Math.max"], [Math.min, "Math.min"], [Math.pow, "Math.pow"], [Math.random, "Math.random"], [Math.round, "Math.round"], [Math.sign, "Math.sign"], [Math.sin, "Math.sin"], [Math.sinh, "Math.sinh"], [Math.sqrt, "Math.sqrt"], [Math.tan, "Math.tan"], [Math.tanh, "Math.tanh"], [Math.trunc, "Math.trunc"], [Number, "Number"], [Number.isFinite, "Number.isFinite"], [Number.isInteger, "Number.isInteger"], [Number.isNaN, "Number.isNaN"], [Number.isSafeInteger, "Number.isSafeInteger"], [Number.parseFloat, "Number.parseFloat"], [Number.parseInt, "Number.parseInt"], [Object, "Object"], [Object.assign, "Object.assign"], [Object.create, "Object.create"], [Object.defineProperties, "Object.defineProperties"], [Object.defineProperty, "Object.defineProperty"], [Object.entries, "Object.entries"], [Object.freeze, "Object.freeze"], [Object.fromEntries, "Object.fromEntries"], [Object.getOwnPropertyDescriptor, "Object.getOwnPropertyDescriptor"], [Object.getOwnPropertyDescriptors, "Object.getOwnPropertyDescriptors"], [Object.getOwnPropertyNames, "Object.getOwnPropertyNames"], [Object.getOwnPropertySymbols, "Object.getOwnPropertySymbols"], [Object.getPrototypeOf, "Object.getPrototypeOf"], [Object.is, "Object.is"], [Object.isExtensible, "Object.isExtensible"], [Object.isFrozen, "Object.isFrozen"], [Object.isSealed, "Object.isSealed"], [Object.keys, "Object.keys"], [Object.preventExtensions, "Object.preventExtensions"], [Object.seal, "Object.seal"], [Object.setPrototypeOf, "Object.setPrototypeOf"], [Object.values, "Object.values"], [parseFloat, "parseFloat"], [parseInt, "parseInt"], [Promise, "Promise"], [Proxy, "Proxy"], [RangeError, "RangeError"], [ReferenceError, "ReferenceError"], [Reflect.apply, "Reflect.apply"], [Reflect.construct, "Reflect.construct"], [Reflect.defineProperty, "Reflect.defineProperty"], [Reflect.deleteProperty, "Reflect.deleteProperty"], [Reflect.get, "Reflect.get"], [Reflect.getOwnPropertyDescriptor, "Reflect.getOwnPropertyDescriptor"], [Reflect.getPrototypeOf, "Reflect.getPrototypeOf"], [Reflect.has, "Reflect.has"], [Reflect.isExtensible, "Reflect.isExtensible"], [Reflect.ownKeys, "Reflect.ownKeys"], [Reflect.preventExtensions, "Reflect.preventExtensions"], [Reflect.set, "Reflect.set"], [Reflect.setPrototypeOf, "Reflect.setPrototypeOf"], [RegExp, "RegExp"], [Set, "Set"], [String, "String"], [String.fromCharCode, "String.fromCharCode"], [String.fromCodePoint, "String.fromCodePoint"], [String.raw, "String.raw"], [Symbol, "Symbol"], [Symbol.for, "Symbol.for"], [SyntaxError, "SyntaxError"], [TypeError, "TypeError"], [Uint16Array, "Uint16Array"], [Uint16Array.from, "Uint16Array.from"], [Uint16Array.of, "Uint16Array.of"], [Uint32Array, "Uint32Array"], [Uint32Array.from, "Uint32Array.from"], [Uint32Array.of, "Uint32Array.of"], [Uint8Array, "Uint8Array"], [Uint8Array.from, "Uint8Array.from"], [Uint8Array.of, "Uint8Array.of"], [Uint8ClampedArray, "Uint8ClampedArray"], [Uint8ClampedArray.from, "Uint8ClampedArray.from"], [Uint8ClampedArray.of, "Uint8ClampedArray.of"], [URIError, "URIError"], [WeakMap, "WeakMap"], [WeakSet, "WeakSet"] ]); const KNOWN_OBJECTS = /* @__PURE__ */ new Map([ [Atomics, "Atomics"], [console, "console"], [globalThis, "globalThis"], [globalThis.crypto, "crypto"], [Intl, "Intl"], [JSON, "JSON"], [Math, "Math"], [Reflect, "Reflect"] ]); var State$1 = class { ids = 0; flush = 0; wroteUndefined = false; buf = []; strs = /* @__PURE__ */ new Map(); refs = /* @__PURE__ */ new WeakMap(); assigned = /* @__PURE__ */ new Set(); boundary = void 0; channel = void 0; channelDeps = null; mutated = []; }; var Reference = class { assigns = null; calls = null; scopeId = void 0; channel = void 0; parent; accessor; flush; pos; id; constructor(parent, accessor, flush, pos = null, id = null) { this.parent = parent; this.accessor = accessor; this.flush = flush; this.pos = pos; this.id = id; } }; const DEBUG = /* @__PURE__ */ new WeakMap(); function setDebugInfo(obj, file, loc, vars) { DEBUG.set(obj, { file, loc, vars }); } var Serializer = class { #state = new State$1(); pending(channel) { return hasMatchingMutations(this.#state.mutated, channel?.readyId); } pendingReadyChannel() { for (const mutation of this.#state.mutated) if (mutation.channel?.readyId) return mutation.channel; } stringifyScopes(flushes, boundary, channel) { try { this.#state.boundary = boundary; this.#state.channel = channel; return writeScopesRoot(this.#state, flushes); } finally { this.#state.flush++; this.#state.buf = []; } } written(val) { return this.#state.refs.has(val); } takeChannelDeps() { const deps = this.#state.channelDeps; this.#state.channelDeps = null; return deps; } writeCall(value, object, property, channel) { this.#state.mutated.push({ value, object, property, channel }); } }; function register(id, val, scope) { REGISTRY.set(val, { id, scope, access: "_._" + toAccess(toObjectKey(id)) }); return val; } function getRegistered(val) { const registered = REGISTRY.get(val); if (registered) return { id: registered.id, scope: registered.scope }; } function writeScopesRoot(state, flushes) { const { buf } = state; let nextSlotId = -1; let fillIndex = -1; for (const flush of flushes) { const scopeId = flush[0]; const scope = flush[1]; const ref = state.refs.get(scope) || newScopeReference(state, scope, scopeId); const openIndex = buf.push("") - 1; if (writeObjectProps(state, flush[2], ref)) { buf[openIndex] = nextSlotId === -1 ? "[" + scopeId + ",{" : (scopeId !== nextSlotId ? "," + (scopeId - nextSlotId) : "") + ",{"; if (fillIndex === -1) fillIndex = openIndex; nextSlotId = scopeId + 1; buf.push("}"); } else buf.pop(); } if (nextSlotId !== -1) buf.push("]"); let extras = ""; if (state.assigned.size || hasChannelMutations(state)) { extras = ",0)"; if (fillIndex !== -1) { buf[fillIndex] = "_(" + buf[fillIndex]; buf.push(")"); } writeAssigned(state); } let result = extras && "("; for (const chunk of buf) result += chunk; result += extras; if (!result) return ""; if (state.wroteUndefined) { state.wroteUndefined = false; return "(_,$)=>" + result; } else return "_=>" + result; } function writeAssigned(state) { let sep = state.buf.length ? "," : ""; if (state.assigned.size) { const assigned = state.assigned; state.assigned = /* @__PURE__ */ new Set(); let buf = ""; let hasCalls = false; for (const ref of assigned) { if (ref.assigns) { buf += sep + assignsToString(ref.assigns, ref.id); ref.assigns = null; sep = ","; } hasCalls ||= ref.calls !== null; } if (buf) state.buf.push(buf); if (hasCalls) for (const ref of assigned) { if (!ref.calls) continue; for (const { method, args } of ref.calls) { state.buf.push((state.buf.length ? "," : "") + ref.id + "." + method + "("); for (let a = 0; a < args.length; a++) { if (a) state.buf.push(","); writeCallArg(state, args[a]); } state.buf.push(")"); } ref.calls = null; } } if (hasChannelMutations(state)) { const remaining = []; for (const mutation of state.mutated) { if (!mutationMatchesReadyId(mutation, state.channel?.readyId)) { remaining.push(mutation); continue; } const hasSeen = state.refs.get(mutation.object)?.id; const objectStartIndex = state.buf.push(state.buf.length === 0 ? "" : ","); if (writeProp(state, mutation.object, null, "")) { const objectRef = state.refs.get(mutation.object); if (objectRef && objectRef.scopeId === void 0) { if (!objectRef.id) { objectRef.id = nextRefAccess(state); state.buf[objectStartIndex] = "(" + objectRef.id + "=" + state.buf[objectStartIndex]; state.buf.push(")"); } else if (!hasSeen) { state.buf[objectStartIndex] = "(" + state.buf[objectStartIndex]; state.buf.push(")"); } } } else state.buf.push("void 0"); const valueStartIndex = state.buf.push(toAccess(toObjectKey(mutation.property)) + "("); if (mutation.value === void 0) {} else if (writeProp(state, mutation.value, null, "")) { const valueRef = typeof mutation.value === "string" ? state.strs.get(mutation.value) : state.refs.get(mutation.value); if (valueRef && !valueRef.id && valueRef.scopeId === void 0) { valueRef.id = mutation.valueId || nextRefAccess(state); state.buf[valueStartIndex] = valueRef.id + "=" + state.buf[valueStartIndex]; } } else state.buf.push("void 0"); state.buf.push(")"); } state.mutated = remaining; } if (state.assigned.size) writeAssigned(state); } function writeCallArg(state, val) { if (val === void 0) { state.wroteUndefined = true; state.buf.push("$"); } else if (!writeProp(state, val, null, "")) state.buf.push("void 0"); } function hasChannelMutations(state) { return hasMatchingMutations(state.mutated, state.channel?.readyId); } function hasMatchingMutations(mutated, readyId) { for (const mutation of mutated) if (mutationMatchesReadyId(mutation, readyId)) return true; return false; } function mutationMatchesReadyId(mutation, readyId) { return mutation.channel?.readyId ? mutation.channel.readyId === readyId : !readyId; } function writeProp(state, val, parent, accessor) { switch (typeof val) { case "string": return writeString(state, val, parent, accessor); case "number": return writeNumber(state, val); case "boolean": return writeBoolean(state, val); case "bigint": return writeBigInt(state, val); case "symbol": return writeSymbol(state, val, parent, accessor); case "function": return writeFunction(state, val, parent, accessor); case "object": return writeObject(state, val, parent, accessor); default: throwUnserializable(state, val, parent, accessor); return false; } } function writeReferenceOr(state, write, val, parent, accessor) { let ref = state.refs.get(val); if (ref) { if (!trackChannel(state, ref)) { abortUnreachableChannel(state, val); return false; } if (parent && isCircular(parent, ref)) { ensureId(state, ref); state.assigned.add(ref); addAssignment(ref, accessId(state, parent) + toAccess(accessor)); return false; } state.buf.push(ensureId(state, ref)); return true; } const registered = REGISTRY.get(val); if (registered) return writeRegistered(state, val, parent, accessor, registered); state.refs.set(val, ref = new Reference(parent, accessor, state.flush, state.buf.length)); ref.channel = state.channel; ref.debug = DEBUG.get(val); if (write(state, val, ref)) return true; state.refs.delete(val); return false; } function trackScope(state, val, scopeId) { const ref = state.refs.get(val); if (ref) trackChannel(state, ref); else newScopeReference(state, val, scopeId); } function newScopeReference(state, val, scopeId) { const ref = new Reference(null, null, state.flush); ref.scopeId = scopeId; ref.channel = state.channel; state.refs.set(val, ref); ref.debug = DEBUG.get(val); return ref; } function writeRegistered(state, val, parent, accessor, registered) { const { scope } = registered; if (scope) { const ref = new Reference(parent, accessor, state.flush, state.buf.length); ref.channel = state.channel; state.refs.set(val, ref); ref.debug = DEBUG.get(val); const scopeId = scope[K_SCOPE_ID]; trackScope(state, scope, scopeId); state.buf.push("_(" + scopeId + "," + quote(registered.id, 0) + ")"); } else state.buf.push(registered.access); return true; } const STRING_DEDUP_LENGTH = 12; function writeString(state, val, parent, accessor) { if (val.length > STRING_DEDUP_LENGTH) { const ref = state.strs.get(val); if (ref) { if (trackChannel(state, ref)) { state.buf.push(ensureId(state, ref)); return true; } } else { const ref = new Reference(parent, accessor, state.flush, state.buf.length); ref.channel = state.channel; state.strs.set(val, ref); } } state.buf.push(quote(val, 0)); return true; } function writeNumber(state, val) { state.buf.push(val + ""); return true; } function writeBoolean(state, val) { state.buf.push(val ? "!0" : "!1"); return true; } function writeBigInt(state, val) { state.buf.push(val + "n"); return true; } function writeFunction(state, val, parent, accessor) { const wellKnownFunction = KNOWN_FUNCTIONS.get(val); if (wellKnownFunction) { state.buf.push(wellKnownFunction); return true; } return writeReferenceOr(state, writeNever, val, parent, accessor); } function writeSymbol(state, val, parent, accessor) { const wellKnownSymbol = KNOWN_SYMBOLS.get(val); if (wellKnownSymbol) { state.buf.push(wellKnownSymbol); return true; } const key = Symbol.keyFor(val); if (key !== void 0) { state.buf.push("Symbol.for(" + quote(key, 0) + ")"); return true; } return writeReferenceOr(state, writeUnknownSymbol, val, parent, accessor); } function writeUnknownSymbol(state) { state.buf.push("Symbol()"); return true; } function writeNever(state, val, ref) { throwUnserializable(state, val, ref); return false; } function writeNull(state) { state.buf.push("null"); return true; } function writeObject(state, val, parent, accessor) { if (val === null) return writeNull(state); const scopeId = val[K_SCOPE_ID]; if (scopeId !== void 0) { trackScope(state, val, scopeId); state.buf.push("_(" + scopeId + ")"); return true; } const wellKnownObject = KNOWN_OBJECTS.get(val); if (wellKnownObject) { state.buf.push(wellKnownObject); return true; } return writeReferenceOr(state, writeUnknownObject, val, parent, accessor); } function writeUnknownObject(state, val, ref) { const proto = Object.getPrototypeOf(val); if (proto === objectProto) return writePlainObject(state, val, ref); if (proto === arrayProto) return writeArray(state, val, ref); switch (proto?.constructor) { case void 0: return writeNullObject(state, val, ref); case Object: return writePlainObject(state, val, ref); case Array: return writeArray(state, val, ref); case Date: return writeDate(state, val); case RegExp: return writeRegExp(state, val); case Promise: return writePromise(state, val, ref); case Map: return writeMap(state, val, ref); case Set: return writeSet(state, val, ref); case Generator: return writeGenerator(state, val, ref); case AsyncGenerator: return writeAsyncGenerator(state, val, ref); case Error: case EvalError: case RangeError: case ReferenceError: case SyntaxError: case TypeError: case URIError: return writeError(state, val, ref); case AggregateError: return writeAggregateError(state, val, ref); case ArrayBuffer: return writeArrayBuffer(state, val); case Int8Array: case Uint8Array: case Uint8ClampedArray: case Int16Array: case Uint16Array: case Int32Array: case Uint32Array: case Float32Array: case Float64Array: case BigInt64Array: case BigUint64Array: return writeTypedArray(state, val, ref); case DataView: return writeDataView(state, val, ref); case WeakSet: return writeWeakSet(state); case WeakMap: return writeWeakMap(state); case globalThis.URL: return writeURL(state, val); case globalThis.URLSearchParams: return writeURLSearchParams(state, val); case globalThis.Headers: return writeHeaders(state, val); case globalThis.FormData: return writeFormData(state, val, ref); case globalThis.ReadableStream: return writeReadableStream(state, val, ref); case globalThis.Request: return writeRequest(state, val, ref); case globalThis.Response: return writeResponse(state, val, ref); case globalThis.Intl?.NumberFormat: return writeIntl(state, val, "NumberFormat", ref); case globalThis.Intl?.DateTimeFormat: return writeIntl(state, val, "DateTimeFormat", ref); case globalThis.Intl?.Collator: return writeIntl(state, val, "Collator", ref); case globalThis.Intl?.PluralRules: return writeIntl(state, val, "PluralRules", ref); case globalThis.Intl?.RelativeTimeFormat: return writeIntl(state, val, "RelativeTimeFormat", ref); case globalThis.Intl?.ListFormat: return writeIntl(state, val, "ListFormat", ref); case globalThis.Intl?.DisplayNames: return writeIntl(state, val, "DisplayNames", ref); case globalThis.Intl?.Segmenter: return writeIntl(state, val, "Segmenter", ref); case globalThis.Intl?.DurationFormat: return writeIntl(state, val, "DurationFormat", ref); case globalThis.Intl?.Locale: return writeIntlLocale(state, val); case globalThis.Temporal?.Instant: return writeTemporal(state, val, "Instant"); case globalThis.Temporal?.Duration: return writeTemporal(state, val, "Duration"); case globalThis.Temporal?.PlainDate: return writeTemporal(state, val, "PlainDate"); case globalThis.Temporal?.PlainDateTime: return writeTemporal(state, val, "PlainDateTime"); case globalThis.Temporal?.PlainMonthDay: return writeTemporal(state, val, "PlainMonthDay"); case globalThis.Temporal?.PlainTime: return writeTemporal(state, val, "PlainTime"); case globalThis.Temporal?.PlainYearMonth: return writeTemporal(state, val, "PlainYearMonth"); case globalThis.Temporal?.ZonedDateTime: return writeTemporal(state, val, "ZonedDateTime"); } throwUnserializable(state, val, ref); return false; } function writePlainObject(state, val, ref) { state.buf.push("{"); writeMaybeIterableProps(state, val, ref); state.buf.push("}"); return true; } function writeArray(state, val, ref) { let sep = "["; for (let i = 0; i < val.length; i++) { const item = val[i]; state.buf.push(sep); sep = ","; if (item === void 0) { state.wroteUndefined = true; state.buf.push("$"); } else writeProp(state, item, ref, "" + i); } if (sep === "[") state.buf.push("[]"); else state.buf.push("]"); return true; } function writeDate(state, val) { state.buf.push("new Date(" + +val + ")"); return true; } const unsafeRegExpSourceReg = /\\[\s\S]|[<\0\ud800-\udfff]/gu; const unsafeRegExpSourceDetect = /[<\0\ud800-\udfff]/u; const replaceUnsafeRegExpSourceChar = (match) => { const ch = match.length === 3 ? "" : match[match.length - 1]; if (ch === "<") return "\\x3C"; if (ch === "\0") return "\\x00"; const code = ch.charCodeAt(0); return code >= 55296 && code <= 57343 ? "\\u" + code.toString(16).padStart(4, "0") : match; }; function writeRegExp(state, val) { const { source } = val; state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags); return true; } function writePromise(state, val, ref) { const { boundary, channel } = state; if (!boundary) return false; const pId = nextRefAccess(state); const handle = newAsyncHandle(state, ref, pId); state.buf.push("(p=>p=new Promise((f,r)=>" + pId + "={f,r(e){p.catch(_=>0);r(e)}}))()"); val.then((v) => writeAsyncCall(state, boundary, handle, "f", v, channel, pId), (v) => writeAsyncCall(state, boundary, handle, "r", v, channel, pId)); boundary.startAsync(); return true; } function newAsyncHandle(state, parent, id) { const handle = {}; const handleRef = new Reference(parent, null, state.flush, null, id); handleRef.channel = state.channel; state.refs.set(handle, handleRef); return handle; } function writeMap(state, val, ref) { if (!val.size) { state.buf.push("new Map"); return true; } const items = []; let assigns; let needsId; let deferring = false; let i = 0; if (val.size < 25) { for (let [itemKey, itemValue] of val) { if (!deferring && (itemKey !== val && isAncestorMember(state, ref, itemKey) || itemValue !== val && isAncestorMember(state, ref, itemValue))) deferring = true; if (deferring) { deferCall(state, ref, "set", [itemKey, itemValue]); continue; } if (itemKey === val) { itemKey = void 0; (assigns ||= []).push("a[" + i + "][0]"); } if (itemValue === val) { itemValue = void 0; (assigns ||= []).push("a[" + i + "][1]"); } needsId ||= isDedupedMember(itemKey) || isDedupedMember(itemValue); i = items.push(itemValue === void 0 ? itemKey === void 0 ? [] : [itemKey] : [itemKey, itemValue]); } writeArrayArg(state, ref, items, assigns && "((m,a)=>(" + assignsToString(assigns, "m") + ",a.forEach(i=>m.set(i[0],i[1])),m))(new Map,", "new Map(", needsId); } else { for (let [itemKey, itemValue] of val) { if (!deferring && (itemKey !== val && isAncestorMember(state, ref, itemKey) || itemValue !== val && isAncestorMember(state, ref, itemValue))) deferring = true; if (deferring) { deferCall(state, ref, "set", [itemKey, itemValue]); continue; } if (itemKey === val) { itemKey = 0; (assigns ||= []).push("a[" + i + "]"); } if (itemValue === val) { itemValue = 0; (assigns ||= []).push("a[" + (i + 1) + "]"); } needsId ||= isDedupedMember(itemKey) || isDedupedMember(itemValue); i = items.push(itemKey, itemValue); } writeArrayArg(state, ref, items, assigns && "(a=>a.reduce((m,v,i)=>i%2?m:m.set(v,a[i+1])," + assignsToString(assigns, "new Map") + "))(", "(a=>a.reduce((m,v,i)=>i%2?m:m.set(v,a[i+1]),new Map))(", needsId); } return true; } function writeSet(state, val, ref) { if (!val.size) { state.buf.push("new Set"); return true; } const items = []; let assigns; let needsId; let deferring = false; let i = 0; for (let item of val) { if (!deferring && item !== val && isAncestorMember(state, ref, item)) deferring = true; if (deferring) { deferCall(state, ref, "add", [item]); continue; } if (item === val) { item = 0; (assigns ||= []).push("i[" + i + "]"); } else needsId ||= isDedupedMember(item); i = items.push(item); } writeArrayArg(state, ref, items, assigns && "((s,i)=>(" + assignsToString(assigns, "s") + ",i.forEach(i=>s.add(i)),s))(new Set,", "new Set(", needsId); return true; } function isAncestorMember(state, container, member) { if (member === null || typeof member !== "object" && typeof member !== "function") return false; const ref = state.refs.get(member); return ref !== void 0 && isCircular(container, ref); } function deferCall(state, ref, method, args) { ensureId(state, ref); (ref.calls ||= []).push({ method, args }); state.assigned.add(ref); } function writeArrayArg(state, ref, items, assignsPrefix, plainPrefix, needsId) { if (assignsPrefix || needsId) { const arrayRef = new Reference(ref, null, state.flush, null, nextRefAccess(state)); state.buf.push((assignsPrefix || plainPrefix) + arrayRef.id + "="); writeArray(state, items, arrayRef); } else { state.buf.push(plainPrefix); writeArray(state, items, new Reference(ref, null, state.flush, state.buf.length)); } state.buf.push(")"); } function isDedupedMember(val) { switch (typeof val) { case "object": return val !== null && val[K_SCOPE_ID] === void 0; case "function": case "symbol": return true; case "string": return val.length > STRING_DEDUP_LENGTH; default: return false; } } function canWriteBuffer(state, buffer, ref) { if (Object.getPrototypeOf(buffer)?.constructor === ArrayBuffer) return true; throwUnserializable(state, buffer, ref, "buffer"); return false; } function writeDataView(state, val, ref) { const { buffer } = val; if (!canWriteBuffer(state, buffer, ref)) return false; const needsLength = val.byteOffset + val.byteLength < buffer.byteLength; state.buf.push("new DataView("); writeProp(state, buffer, ref, "buffer"); state.buf.push((val.byteOffset || needsLength ? "," + val.byteOffset + (needsLength ? "," + val.byteLength : "") : "") + ")"); return true; } function writeArrayBuffer(state, val) { let result; if (val.byteLength) { const view = new Int8Array(val); result = hasOnlyZeros(view) ? "new ArrayBuffer(" + val.byteLength + ")" : "new Int8Array(" + typedArrayToInitString(view) + ").buffer"; } else result = "new ArrayBuffer"; state.buf.push(result); return true; } function writeTypedArray(state, val, ref) { if (val.byteOffset || val.byteLength < val.buffer.byteLength || state.refs.has(val.buffer)) { if (!canWriteBuffer(state, val.buffer, ref)) return false; const needsLength = val.byteOffset + val.byteLength < val.buffer.byteLength; state.buf.push("new " + val.constructor.name + "("); writeProp(state, val.buffer, ref, "buffer"); state.buf.push((val.byteOffset || needsLength ? "," + val.byteOffset + (needsLength ? "," + val.length : "") : "") + ")"); } else { state.refs.set(val.buffer, new Reference(ref, "buffer", state.flush, null)); state.buf.push("new " + val.constructor.name + (val.length === 0 ? "" : "(" + (hasOnlyZeros(val) ? val.length : typedArrayToInitString(val)) + ")")); } return true; } function writeWeakSet(state) { state.buf.push("new WeakSet"); return true; } function writeWeakMap(state) { state.buf.push("new WeakMap"); return true; } function writeError(state, val, ref) { const result = "new " + val.constructor.name + "(" + quote(val.message + "", 0); if (val.cause !== void 0) { const pos = state.buf.push(result + ",{cause:") - 1; if (writeProp(state, val.cause, ref, "cause")) state.buf.push("})"); else state.buf[pos] = state.buf[pos].slice(0, -8) + ")"; } else state.buf.push(result + ")"); return true; } function writeAggregateError(state, val, ref) { state.buf.push("new AggregateError("); const inlined = writeProp(state, val.errors, ref, "errors"); if (!inlined) state.buf.push("[]"); if (val.message) state.buf.push("," + quote(val.message + "", 0) + ")"); else state.buf.push(")"); if (inlined) { const errorsRef = state.refs.get(val.errors); if (errorsRef?.id) { state.assigned.add(errorsRef); addAssignment(errorsRef, accessId(state, ref) + toAccess("errors")); } } return true; } function writeURL(state, val) { state.buf.push("new URL(" + quote(val.toString(), 0) + ")"); return true; } function writeURLSearchParams(state, val) { const str = val.toString(); if (str) state.buf.push("new URLSearchParams(" + quote(str, 0) + ")"); else state.buf.push("new URLSearchParams"); return true; } function writeHeaders(state, val) { const headers = stringEntriesToHeadersInit(val); state.buf.push("new Headers" + (headers ? "(" + headers + ")" : "")); return true; } function writeFormData(state, val, ref) { let sep = "["; let valStr = ""; for (const [key, value] of val) { if (typeof value !== "string") { throwUnserializable(state, value, ref, key); return false; } valStr += sep + quote(key, 0) + "," + quote(value, 0); sep = ","; } if (sep === "[") state.buf.push("new FormData"); else state.buf.push(valStr + "].reduce((f,v,i,a)=>i%2&&f.append(a[i-1],v)||f,new FormData)"); return true; } function writeRequest(state, val, ref) { let sep = ""; let bodySerialized = false; const hasBody = val.body && !val.bodyUsed && val.duplex === "half"; state.buf.push("new Request(" + quote(val.url, 0)); if (hasBody) { state.buf.push(",{body:"); if (writeProp(state, val.body, ref, "body")) { state.buf.push(",duplex:\"half\""); sep = ","; bodySerialized = true; } else state.buf.pop(); } let options = ""; if (val.cache !== "default") { options += sep + "cache:" + quote(val.cache, 0); sep = ","; } if (val.credentials !== "same-origin") { options += sep + "credentials:" + quote(val.credentials, 0); sep = ","; } const seenHeaders = state.refs.get(val.headers); if (seenHeaders) { options += sep + "headers:" + ensureId(state, seenHeaders); sep = ","; } else { state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null)); const headers = stringEntriesToHeadersInit(val.headers); if (headers) { options += sep + "headers:" + headers; sep = ","; } } if (val.integrity) { options += sep + "integrity:" + quote(val.integrity, 0); sep = ","; } if (val.keepalive) { options += sep + "keepalive:true"; sep = ","; } if (val.method !== "GET") { options += sep + "method:" + quote(val.method, 0); sep = ","; } if (val.mode !== "cors") { options += sep + "mode:" + quote(val.mode, 0); sep = ","; } if (val.redirect !== "follow") { options += sep + "redirect:" + quote(val.redirect, 0); sep = ","; } if (val.referrer !== "about:client") { options += sep + "referrer:" + quote(val.referrer, 0); sep = ","; } if (val.referrerPolicy) options += sep + "referrerPolicy:" + quote(val.referrerPolicy, 0); state.buf.push(bodySerialized ? options + "})" : options ? ",{" + options + "})" : ")"); return true; } function writeResponse(state, val, ref) { let sep = ""; let options = ""; if (val.status !== 200) { options += "status:" + val.status; sep = ","; } if (val.statusText) { options += sep + "statusText:" + quote(val.statusText, 0); sep = ","; } const seenHeaders = state.refs.get(val.headers); if (seenHeaders) options += sep + "headers:" + ensureId(state, seenHeaders); else { state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null)); const headers = stringEntriesToHeadersInit(val.headers); if (headers) options += sep + "headers:" + headers; } if (!val.body || val.bodyUsed) state.buf.push("new Response" + (options ? "(null,{" + options + "})" : "")); else { state.buf.push("new Response("); state.buf.push((writeProp(state, val.body, ref, "body") ? "" : "null") + (options ? ",{" + options + "})" : ")")); } return true; } function writeIntl(state, val, name, ref) { const { locale, ...options } = val.resolvedOptions(); let needsId = false; for (const key in options) if (isDedupedMember(options[key])) { needsId = true; break; } state.buf.push("new Intl." + name + "(" + quote(locale, 0) + ","); let optionsRef; if (needsId) { optionsRef = new Reference(ref, null, state.flush, null, nextRefAccess(state)); state.buf.push(optionsRef.id + "={"); } else { optionsRef = new Reference(ref, null, state.flush, state.buf.length); state.buf.push("{"); } writeObjectProps(state, options, optionsRef); state.buf.push("})"); return true; } function writeIntlLocale(state, val) { state.buf.push("new Intl.Locale(" + quote(val.toString(), 0) + ")"); return true; } function writeTemporal(state, val, name) { state.buf.push("Temporal." + name + ".from(" + quote(val.toString(), 0) + ")"); return true; } function writeReadableStream(state, val, ref) { const { boundary, channel } = state; if (!boundary || val.locked) return false; const reader = val.getReader(); const iterId = nextRefAccess(state); const handle = newAsyncHandle(state, ref, iterId); const onFulfilled = ({ value, done }) => { if (done) writeAsyncCall(state, boundary, handle, "r", value, channel); else if (!boundary.signal.aborted) { reader.read().then(onFulfilled, onRejected); boundary.startAsync(); writeAsyncCall(state, boundary, handle, "f", value, channel); } }; const onRejected = (reason) => { writeAsyncCall(state, boundary, handle, "j", reason, channel); }; state.buf.push("new ReadableStream({start(c){(async(_,f,v,l,i,p=a=>l=new Promise((r,j)=>{f=_.r=r;_.j=j}),a=((_.f=v=>{f(v);a.push(p())}),[p()]))=>{for(i of a)v=await i,i==l?c.close():c.enqueue(v)})(" + iterId + "={}).catch(e=>c.error(e))}})"); reader.read().then(onFulfilled, onRejected); boundary.startAsync(); return true; } function writeGenerator(state, iter, ref) { if (iter[kTouchedIterator]) { state.buf.push("(function*(){}())"); return true; } const yields = []; let returnValue; let needsId; while (true) { const { value, done } = iter.next(); if (done) { returnValue = value; break; } needsId ||= isDedupedMember(value); yields.push(value); } if (returnValue === void 0 && !yields.length) { state.buf.push("(function*(){})()"); return true; } const heldReturn = returnValue !== void 0 && isAncestorMember(state, ref, returnValue); state.buf.push(returnValue === void 0 ? "(function*(a){yield*a})(" : heldReturn ? "(function*(a,r){yield*a;return r.v})(" : "(function*(a,r){yield*a;return r})("); if (needsId) { const arrayRef = new Reference(ref, null, state.flush, null, nextRefAccess(state)); state.buf.push(arrayRef.id + "="); writeArray(state, yields, arrayRef); } else writeArray(state, yields, new Reference(ref, null, state.flush, state.buf.length)); if (heldReturn) { const holder = new Reference(ref, null, state.flush, null, nextRefAccess(state)); state.buf.push("," + holder.id + "={}"); writeProp(state, returnValue, holder, "v"); } else if (returnValue !== void 0) { const sepIndex = state.buf.push(",") - 1; if (writeProp(state, returnValue, ref, "") && isDedupedMember(returnValue)) { const retRef = typeof returnValue === "string" ? state.strs.get(returnValue) : state.refs.get(returnValue); if (retRef && !retRef.id && retRef.scopeId === void 0) { retRef.id = nextRefAccess(state); state.buf[sepIndex] = "," + retRef.id + "="; } } } state.buf.push(")"); return true; } function writeAsyncGenerator(state, iter, ref) { if (iter[kTouchedIterator]) { state.buf.push("(async function*(){}())"); return true; } const { boundary, channel } = state; if (!boundary) return false; const iterId = nextRefAccess(state); const handle = newAsyncHandle(state, ref, iterId); const onFulfilled = ({ value, done }) => { if (done) writeAsy