UNPKG

@builder.io/qwik

Version:

An Open-Source sub-framework designed with a focus on server-side-rendering, lazy-loading, and styling/animation.

1,494 lines (1,276 loc) 221 kB
/** * @license * @builder.io/qwik 1.17.2 * Copyright Builder.io, Inc. All Rights Reserved. * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/QwikDev/qwik/blob/main/LICENSE */ import { isServer, isBrowser, isDev } from "@builder.io/qwik/build"; export { isBrowser, isDev, isServer } from "@builder.io/qwik/build"; import { p } from "@builder.io/qwik/preloader"; const implicit$FirstArg = fn => function(first, ...rest) { return fn.call(null, $(first), ...rest); }; const qDev = !1; const qInspector = !1; const qSerialize = !0; const qDynamicPlatform = !0; const qTest = !1; const qRuntimeQrl = !1; const seal = () => { qDev; }; const isNode$1 = value => value && "number" == typeof value.nodeType; const isDocument = value => 9 === value.nodeType; const isElement$1 = value => 1 === value.nodeType; const isQwikElement = value => { const nodeType = value.nodeType; return 1 === nodeType || 111 === nodeType; }; const isNodeElement = value => { const nodeType = value.nodeType; return 1 === nodeType || 111 === nodeType || 3 === nodeType; }; const isVirtualElement = value => 111 === value.nodeType; const isText = value => 3 === value.nodeType; const isComment = value => 8 === value.nodeType; const STYLE = ""; const logError = (message, ...optionalParams) => createAndLogError(!1, message, ...optionalParams); const throwErrorAndStop = (message, ...optionalParams) => { throw createAndLogError(!1, message, ...optionalParams); }; const logErrorAndStop = (message, ...optionalParams) => createAndLogError(qDev, message, ...optionalParams); const _printed = /*#__PURE__*/ new Set; const logOnceWarn = () => { qDev; }; const logWarn = () => { qDev; }; const logDebug = () => { qDev; }; const tryGetContext$1 = element => element._qc_; const printParams = optionalParams => optionalParams; const printElement = el => { const ctx = tryGetContext$1(el); const isServer = /*#__PURE__*/ (() => "undefined" != typeof process && !!process.versions && !!process.versions.node)(); return { tagName: el.tagName, renderQRL: ctx?.$componentQrl$?.getSymbol(), element: isServer ? void 0 : el, ctx: isServer ? void 0 : ctx }; }; const createAndLogError = (asyncThrow, message, ...optionalParams) => { const err = message instanceof Error ? message : new Error(message); return console.error("%cQWIK ERROR", "", err.message, ...printParams(optionalParams), err.stack), asyncThrow && setTimeout(() => { throw err; }, 0), err; }; const ASSERT_DISCLAIMER = "Internal assert, this is likely caused by a bug in Qwik: "; function assertDefined() { qDev; } function assertEqual() { qDev; } function assertFail() { qDev; } function assertTrue() { qDev; } function assertNumber() { qDev; } function assertString() { qDev; } function assertQwikElement() { qDev; } function assertElement() { qDev; } const codeToText = code => `Code(${code}) https://github.com/QwikDev/qwik/blob/main/packages/qwik/src/core/error/error.ts#L${8 + code}`; const QError_stringifyClassOrStyle = 0; const QError_verifySerializable = 3; const QError_cannotRenderOverExistingContainer = 5; const QError_setProperty = 6; const QError_qrlIsNotFunction = 10; const QError_dynamicImportFailed = 11; const QError_unknownTypeArgument = 12; const QError_notFoundContext = 13; const QError_useMethodOutsideContext = 14; const QError_immutableProps = 17; const QError_useInvokeContext = 20; const QError_containerAlreadyPaused = 21; const QError_invalidJsxNodeType = 25; const QError_trackUseStore = 26; const QError_missingObjectId = 27; const QError_invalidContext = 28; const QError_canNotRenderHTML = 29; const QError_qrlMissingContainer = 30; const QError_qrlMissingChunk = 31; const QError_invalidRefValue = 32; const qError = (code, ...parts) => { const text = codeToText(code, ...parts); return logErrorAndStop(text, ...parts); }; const createPlatform = () => ({ isServer, importSymbol(containerEl, url, symbolName) { if (isServer) { const hash = getSymbolHash(symbolName); const regSym = globalThis.__qwik_reg_symbols?.get(hash); if (regSym) { return regSym; } } if (!url) { throw qError(31, symbolName); } if (!containerEl) { throw qError(30, url, symbolName); } const urlDoc = toUrl(containerEl.ownerDocument, containerEl, url).toString(); const urlCopy = new URL(urlDoc); urlCopy.hash = ""; return import(urlCopy.href).then(mod => mod[symbolName]); }, raf: fn => new Promise(resolve => { requestAnimationFrame(() => { resolve(fn()); }); }), nextTick: fn => new Promise(resolve => { setTimeout(() => { resolve(fn()); }); }), chunkForSymbol: (symbolName, chunk) => [ symbolName, chunk ?? "_" ] }); const toUrl = (doc, containerEl, url) => { const baseURI = doc.baseURI; const base = new URL(containerEl.getAttribute("q:base") ?? baseURI, baseURI); return new URL(url, base); }; let _platform = /*#__PURE__ */ createPlatform(); const setPlatform = plt => _platform = plt; const getPlatform = () => _platform; const isServerPlatform = () => _platform.isServer; const isSerializableObject = v => { const proto = Object.getPrototypeOf(v); return proto === Object.prototype || null === proto; }; const isObject = v => !!v && "object" == typeof v; const isArray = v => Array.isArray(v); const isString = v => "string" == typeof v; const isFunction = v => "function" == typeof v; const isPromise = value => value && "function" == typeof value.then; const safeCall = (call, thenFn, rejectFn) => { try { const promise = call(); return isPromise(promise) ? promise.then(thenFn, rejectFn) : thenFn(promise); } catch (e) { return rejectFn(e); } }; const maybeThen = (promise, thenFn) => isPromise(promise) ? promise.then(thenFn) : thenFn(promise); const promiseAll = promises => promises.some(isPromise) ? Promise.all(promises) : promises; const promiseAllLazy = promises => promises.length > 0 ? Promise.all(promises) : promises; const isNotNullable = v => null != v; const delay = timeout => new Promise(resolve => { setTimeout(resolve, timeout); }); const EMPTY_ARRAY = []; const EMPTY_OBJ = {}; const getDocument = node => { if ("undefined" != typeof document) { return document; } if (9 === node.nodeType) { return node; } const doc = node.ownerDocument; return assertDefined(doc, "doc must be defined"), doc; }; const OnRenderProp = "q:renderFn"; const ComponentStylesPrefixContent = "⭐️"; const QSlot = "q:slot"; const QSlotRef = "q:sref"; const QSlotS = "q:s"; const QStyle = "q:style"; const QScopedStyle = "q:sstyle"; const QInstance = "q:instance"; const QFuncsPrefix = "qFuncs_"; const getQFuncs = (document, hash) => document["qFuncs_" + hash] || []; const QLocaleAttr = "q:locale"; const QContainerAttr = "q:container"; const QContainerSelector = "[q\\:container]"; const ResourceEvent = "qResource"; const ComputedEvent = "qComputed"; const RenderEvent = "qRender"; const TaskEvent = "qTask"; const ELEMENT_ID = "q:id"; const ELEMENT_ID_PREFIX = "#"; const QObjectRecursive = 1; const QObjectImmutable = 2; const QOjectTargetSymbol = Symbol("proxy target"); const QObjectFlagsSymbol = Symbol("proxy flags"); const QObjectManagerSymbol = Symbol("proxy manager"); const _IMMUTABLE = Symbol("IMMUTABLE"); const _IMMUTABLE_PREFIX = "$$"; const VIRTUAL_SYMBOL = "__virtual"; const Q_CTX = "_qc_"; const directSetAttribute = (el, prop, value) => el.setAttribute(prop, value); const directGetAttribute = (el, prop) => el.getAttribute(prop); const directRemoveAttribute = (el, prop) => el.removeAttribute(prop); const fromCamelToKebabCase = text => text.replace(/([A-Z])/g, "-$1").toLowerCase(); const fromKebabToCamelCase = text => text.replace(/-./g, x => x[1].toUpperCase()); const emitEvent$1 = (el, eventName, detail, bubbles) => { (isBrowser || "function" == typeof CustomEvent) && el && el.dispatchEvent(new CustomEvent(eventName, { detail, bubbles, composed: bubbles })); }; const getOrCreateProxy = (target, containerState, flags = 0) => { const proxy = containerState.$proxyMap$.get(target); return proxy || (0 !== flags && setObjectFlags(target, flags), createProxy(target, containerState, void 0)); }; const createProxy = (target, containerState, subs) => { assertEqual(unwrapProxy(target), target, "Unexpected proxy at this location", target), assertTrue(!containerState.$proxyMap$.has(target), "Proxy was already created", target), assertTrue(isObject(target), "Target must be an object"), assertTrue(isSerializableObject(target) || isArray(target), "Target must be a serializable object"); const manager = containerState.$subsManager$.$createManager$(subs); const proxy = new Proxy(target, new ReadWriteProxyHandler(containerState, manager)); return containerState.$proxyMap$.set(target, proxy), proxy; }; const createPropsState = () => { const props = {}; return setObjectFlags(props, 2), props; }; const setObjectFlags = (obj, flags) => { Object.defineProperty(obj, QObjectFlagsSymbol, { value: flags, enumerable: !1 }); }; const _restProps = (props, omit) => { const rest = {}; for (const key in props) { omit.includes(key) || (rest[key] = props[key]); } return rest; }; class ReadWriteProxyHandler { $containerState$; $manager$; constructor($containerState$, $manager$) { this.$containerState$ = $containerState$, this.$manager$ = $manager$; } deleteProperty(target, prop) { if (2 & target[QObjectFlagsSymbol]) { throw qError(17); } return "string" == typeof prop && delete target[prop] && (this.$manager$.$notifySubs$(isArray(target) ? void 0 : prop), !0); } get(target, prop) { if ("symbol" == typeof prop) { return prop === QOjectTargetSymbol ? target : prop === QObjectManagerSymbol ? this.$manager$ : target[prop]; } const flags = target[QObjectFlagsSymbol] ?? 0; assertNumber(flags, "flags must be an number"); const invokeCtx = tryGetInvokeContext(); const recursive = !!(1 & flags); const hiddenSignal = target["$$" + prop]; let subscriber; let value; if (invokeCtx && (subscriber = invokeCtx.$subscriber$), !!!(2 & flags) || prop in target && !immutableValue(target[_IMMUTABLE]?.[prop]) || (subscriber = null), hiddenSignal ? (assertTrue(isSignal(hiddenSignal), "$$ prop must be a signal"), value = hiddenSignal.value, subscriber = null) : value = target[prop], subscriber) { const isA = isArray(target); this.$manager$.$addSub$(subscriber, isA ? void 0 : prop); } return recursive ? wrap(value, this.$containerState$) : value; } set(target, prop, newValue) { if ("symbol" == typeof prop) { return target[prop] = newValue, !0; } const flags = target[QObjectFlagsSymbol] ?? 0; assertNumber(flags, "flags must be an number"); if (!!(2 & flags)) { throw qError(17); } const unwrappedNewValue = !!(1 & flags) ? unwrapProxy(newValue) : newValue; if (isArray(target)) { return target[prop] = unwrappedNewValue, this.$manager$.$notifySubs$(), !0; } const oldValue = target[prop]; return target[prop] = unwrappedNewValue, oldValue !== unwrappedNewValue && this.$manager$.$notifySubs$(prop), !0; } has(target, prop) { if (prop === QOjectTargetSymbol) { return !0; } const invokeCtx = tryGetInvokeContext(); if ("string" == typeof prop && invokeCtx) { const subscriber = invokeCtx.$subscriber$; if (subscriber) { const isA = isArray(target); this.$manager$.$addSub$(subscriber, isA ? void 0 : prop); } } const hasOwnProperty = Object.prototype.hasOwnProperty; return !!hasOwnProperty.call(target, prop) || !("string" != typeof prop || !hasOwnProperty.call(target, "$$" + prop)); } ownKeys(target) { const flags = target[QObjectFlagsSymbol] ?? 0; assertNumber(flags, "flags must be an number"); if (!!!(2 & flags)) { let subscriber = null; const invokeCtx = tryGetInvokeContext(); invokeCtx && (subscriber = invokeCtx.$subscriber$), subscriber && this.$manager$.$addSub$(subscriber); } return isArray(target) ? Reflect.ownKeys(target) : Reflect.ownKeys(target).map(a => "string" == typeof a && a.startsWith("$$") ? a.slice(2) : a); } getOwnPropertyDescriptor(target, prop) { const descriptor = Reflect.getOwnPropertyDescriptor(target, prop); return isArray(target) || "symbol" == typeof prop || descriptor && !descriptor.configurable ? descriptor : { enumerable: !0, configurable: !0 }; } } const immutableValue = value => value === _IMMUTABLE || isSignal(value); const wrap = (value, containerState) => { if (isObject(value)) { if (Object.isFrozen(value)) { return value; } const nakedValue = unwrapProxy(value); if (nakedValue !== value) { return value; } if (fastSkipSerialize(nakedValue)) { return value; } if (isSerializableObject(nakedValue) || isArray(nakedValue)) { const proxy = containerState.$proxyMap$.get(nakedValue); return proxy || getOrCreateProxy(nakedValue, containerState, 1); } } return value; }; const ON_PROP_REGEX = /^(on|window:|document:)/; const PREVENT_DEFAULT = "preventdefault:"; const isOnProp = prop => prop.endsWith("$") && ON_PROP_REGEX.test(prop); const groupListeners = listeners => { if (0 === listeners.length) { return EMPTY_ARRAY; } if (1 === listeners.length) { const listener = listeners[0]; return [ [ listener[0], [ listener[1] ] ] ]; } const keys = []; for (let i = 0; i < listeners.length; i++) { const eventName = listeners[i][0]; keys.includes(eventName) || keys.push(eventName); } return keys.map(eventName => [ eventName, listeners.filter(l => l[0] === eventName).map(a => a[1]) ]); }; const setEvent = (existingListeners, prop, input, containerEl) => { if (assertTrue(prop.endsWith("$"), "render: event property does not end with $", prop), prop = normalizeOnProp(prop.slice(0, -1)), input) { if (isArray(input)) { const processed = input.flat(1 / 0).filter(q => null != q).map(q => [ prop, ensureQrl(q, containerEl) ]); existingListeners.push(...processed); } else { existingListeners.push([ prop, ensureQrl(input, containerEl) ]); } } return prop; }; const PREFIXES = [ "on", "window:on", "document:on" ]; const SCOPED = [ "on", "on-window", "on-document" ]; const normalizeOnProp = prop => { let scope = "on"; for (let i = 0; i < PREFIXES.length; i++) { const prefix = PREFIXES[i]; if (prop.startsWith(prefix)) { scope = SCOPED[i], prop = prop.slice(prefix.length); break; } } return scope + ":" + (prop = prop.startsWith("-") ? fromCamelToKebabCase(prop.slice(1)) : prop.toLowerCase()); }; const ensureQrl = (value, containerEl) => (assertQrl(value), value.$setContainer$(containerEl), value); const getDomListeners = (elCtx, containerEl) => { const attributes = elCtx.$element$.attributes; const listeners = []; for (let i = 0; i < attributes.length; i++) { const {name, value} = attributes.item(i); if (name.startsWith("on:") || name.startsWith("on-window:") || name.startsWith("on-document:")) { const urls = value.split("\n"); for (const url of urls) { const qrl = parseQRL(url, containerEl); qrl.$capture$ && inflateQrl(qrl, elCtx), listeners.push([ name, qrl ]); } } } return listeners; }; const hashCode = (text, hash = 0) => { for (let i = 0; i < text.length; i++) { hash = (hash << 5) - hash + text.charCodeAt(i), hash |= 0; } return Number(Math.abs(hash)).toString(36); }; const styleKey = (qStyles, index) => (assertQrl(qStyles), `${hashCode(qStyles.$hash$)}-${index}`); const styleContent = styleId => "⭐️" + styleId; const serializeSStyle = scopeIds => { const value = scopeIds.join("|"); if (value.length > 0) { return value; } }; const version = "1.17.2"; const useSequentialScope = () => { const iCtx = useInvokeContext(); const elCtx = getContext(iCtx.$hostElement$, iCtx.$renderCtx$.$static$.$containerState$); const seq = elCtx.$seq$ ||= []; const i = iCtx.$i$++; return { val: seq[i], set: value => seq[i] = value, i, iCtx, elCtx }; }; const createContextId = name => (assertTrue(/^[\w/.-]+$/.test(name), "Context name must only contain A-Z,a-z,0-9, _", name), /*#__PURE__*/ Object.freeze({ id: fromCamelToKebabCase(name) })); const useContextProvider = (context, newValue) => { const {val, set, elCtx} = useSequentialScope(); if (void 0 !== val) { return; } const contexts = elCtx.$contexts$ ||= new Map; contexts.set(context.id, newValue), set(!0); }; const useContext = (context, defaultValue) => { const {val, set, iCtx, elCtx} = useSequentialScope(); if (void 0 !== val) { return val; } const value = resolveContext(context, elCtx, iCtx.$renderCtx$.$static$.$containerState$); if ("function" == typeof defaultValue) { return set(invoke(void 0, defaultValue, value)); } if (void 0 !== value) { return set(value); } if (void 0 !== defaultValue) { return set(defaultValue); } throw qError(13, context.id); }; const findParentCtx = (el, containerState) => { let node = el; let stack = 1; for (;node && !node.hasAttribute?.("q:container"); ) { for (;node = node.previousSibling; ) { if (isComment(node)) { const virtual = node.__virtual; if (virtual) { const qtx = virtual[Q_CTX]; if (node === virtual.open) { return qtx ?? getContext(virtual, containerState); } if (qtx?.$parentCtx$) { return qtx.$parentCtx$; } node = virtual; continue; } if ("/qv" === node.data) { stack++; } else if (node.data.startsWith("qv ") && (stack--, 0 === stack)) { return getContext(getVirtualElement(node), containerState); } } } node = el.parentElement, el = node; } return null; }; const getParentProvider = (ctx, containerState) => (void 0 === ctx.$parentCtx$ && (ctx.$parentCtx$ = findParentCtx(ctx.$element$, containerState)), ctx.$parentCtx$); const resolveContext = (context, hostCtx, containerState) => { const contextID = context.id; if (!hostCtx) { return; } let ctx = hostCtx; for (;ctx; ) { const found = ctx.$contexts$?.get(contextID); if (found) { return found; } ctx = getParentProvider(ctx, containerState); } }; const validateContext = context => { if (!isObject(context) || "string" != typeof context.id || 0 === context.id.length) { throw qError(28, context); } }; const ERROR_CONTEXT = /*#__PURE__*/ createContextId("qk-error"); const handleError = (err, hostElement, rCtx) => { const elCtx = tryGetContext(hostElement); if (isServerPlatform()) { throw err; } { const errorStore = resolveContext(ERROR_CONTEXT, elCtx, rCtx.$static$.$containerState$); if (void 0 === errorStore) { throw err; } errorStore.error = err; } }; const isRecoverable = err => !(err && err instanceof Error && "plugin" in err); const unitlessNumbers = new Set([ "animationIterationCount", "aspectRatio", "borderImageOutset", "borderImageSlice", "borderImageWidth", "boxFlex", "boxFlexGroup", "boxOrdinalGroup", "columnCount", "columns", "flex", "flexGrow", "flexShrink", "gridArea", "gridRow", "gridRowEnd", "gridRowStart", "gridColumn", "gridColumnEnd", "gridColumnStart", "fontWeight", "lineClamp", "lineHeight", "opacity", "order", "orphans", "scale", "tabSize", "widows", "zIndex", "zoom", "MozAnimationIterationCount", "MozBoxFlex", "msFlex", "msFlexPositive", "WebkitAnimationIterationCount", "WebkitBoxFlex", "WebkitBoxOrdinalGroup", "WebkitColumnCount", "WebkitColumns", "WebkitFlex", "WebkitFlexGrow", "WebkitFlexShrink", "WebkitLineClamp" ]); const isUnitlessNumber = name => unitlessNumbers.has(name); const executeComponent = (rCtx, elCtx, attempt) => { elCtx.$flags$ &= ~HOST_FLAG_DIRTY, elCtx.$flags$ |= HOST_FLAG_MOUNTED, elCtx.$slots$ = [], elCtx.li.length = 0; const hostElement = elCtx.$element$; const componentQRL = elCtx.$componentQrl$; const props = elCtx.$props$; const iCtx = newInvokeContext(rCtx.$static$.$locale$, hostElement, void 0, "qRender"); const waitOn = iCtx.$waitOn$ = []; assertDefined(componentQRL, "render: host element to render must have a $renderQrl$:", elCtx), assertDefined(props, "render: host element to render must have defined props", elCtx); const newCtx = pushRenderContext(rCtx); newCtx.$cmpCtx$ = elCtx, newCtx.$slotCtx$ = void 0, iCtx.$subscriber$ = [ 0, hostElement ], iCtx.$renderCtx$ = rCtx, componentQRL.$setContainer$(rCtx.$static$.$containerState$.$containerEl$); const componentFn = componentQRL.getFn(iCtx); return safeCall(() => componentFn(props), jsxNode => maybeThen(isServerPlatform() ? maybeThen(promiseAllLazy(waitOn), () => maybeThen(executeSSRTasks(rCtx.$static$.$containerState$, rCtx), () => promiseAllLazy(waitOn))) : promiseAllLazy(waitOn), () => { if (elCtx.$flags$ & HOST_FLAG_DIRTY) { if (!(attempt && attempt > 100)) { return executeComponent(rCtx, elCtx, attempt ? attempt + 1 : 1); } logWarn(`Infinite loop detected. Element: ${elCtx.$componentQrl$?.$symbol$}`); } return { node: jsxNode, rCtx: newCtx }; }), err => { if (err === SignalUnassignedException) { if (!(attempt && attempt > 100)) { return maybeThen(promiseAllLazy(waitOn), () => executeComponent(rCtx, elCtx, attempt ? attempt + 1 : 1)); } logWarn(`Infinite loop detected. Element: ${elCtx.$componentQrl$?.$symbol$}`); } return handleError(err, hostElement, rCtx), { node: SkipRender, rCtx: newCtx }; }); }; const createRenderContext = (doc, containerState) => { const ctx = { $static$: { $doc$: doc, $locale$: containerState.$serverData$.locale, $containerState$: containerState, $hostElements$: new Set, $operations$: [], $postOperations$: [], $roots$: [], $addSlots$: [], $rmSlots$: [], $visited$: [] }, $cmpCtx$: null, $slotCtx$: void 0 }; return seal(), seal(), ctx; }; const pushRenderContext = ctx => ({ $static$: ctx.$static$, $cmpCtx$: ctx.$cmpCtx$, $slotCtx$: ctx.$slotCtx$ }); const serializeClassWithHost = (obj, hostCtx) => hostCtx?.$scopeIds$?.length ? hostCtx.$scopeIds$.join(" ") + " " + serializeClass(obj) : serializeClass(obj); const serializeClass = obj => { if (!obj) { return ""; } if (isString(obj)) { return obj.trim(); } const classes = []; if (isArray(obj)) { for (const o of obj) { const classList = serializeClass(o); classList && classes.push(classList); } } else { for (const [key, value] of Object.entries(obj)) { value && classes.push(key.trim()); } } return classes.join(" "); }; const stringifyStyle = obj => { if (null == obj) { return ""; } if ("object" == typeof obj) { if (isArray(obj)) { throw qError(0, obj, "style"); } { const chunks = []; for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { const value = obj[key]; null != value && "function" != typeof value && (key.startsWith("--") ? chunks.push(key + ":" + value) : chunks.push(fromCamelToKebabCase(key) + ":" + setValueForStyle(key, value))); } } return chunks.join(";"); } } return String(obj); }; const setValueForStyle = (styleName, value) => "number" != typeof value || 0 === value || isUnitlessNumber(styleName) ? value : value + "px"; const getNextIndex = ctx => intToStr(ctx.$static$.$containerState$.$elementIndex$++); const setQId = (rCtx, elCtx) => { const id = getNextIndex(rCtx); elCtx.$id$ = id; }; const jsxToString = data => isSignal(data) ? jsxToString(data.value) : null == data || "boolean" == typeof data ? "" : String(data); function isAriaAttribute(prop) { return prop.startsWith("aria-"); } const shouldWrapFunctional = (res, node) => !!node.key && (!isJSXNode(res) || !isFunction(res.type) && res.key != node.key); const static_listeners = 1; const static_subtree = 2; const dangerouslySetInnerHTML = "dangerouslySetInnerHTML"; const FLUSH_COMMENT = "\x3c!--qkssr-f--\x3e"; const IS_HEAD$1 = 1; const IS_HTML = 4; const IS_TEXT = 8; const IS_INVISIBLE = 16; const IS_PHASING = 32; const IS_ANCHOR = 64; const IS_BUTTON = 128; const IS_TABLE = 256; const IS_PHRASING_CONTAINER = 512; const IS_IMMUTABLE$1 = 1024; class MockElement { nodeType; [Q_CTX]=null; constructor(nodeType) { this.nodeType = nodeType, seal(); } } const createDocument = () => new MockElement(9); const _renderSSR = async (node, opts) => { const root = opts.containerTagName; const containerEl = createMockQContext(1).$element$; const containerState = createContainerState(containerEl, opts.base ?? "/"); containerState.$serverData$.locale = opts.serverData?.locale; const doc = createDocument(); const rCtx = createRenderContext(doc, containerState); const headNodes = opts.beforeContent ?? []; const ssrCtx = { $static$: { $contexts$: [], $headNodes$: "html" === root ? headNodes : [], $locale$: opts.serverData?.locale, $textNodes$: new Map }, $projectedChildren$: void 0, $projectedCtxs$: void 0, $invocationContext$: void 0 }; seal(); const locale = opts.serverData?.locale; const containerAttributes = opts.containerAttributes; const qRender = containerAttributes["q:render"]; containerAttributes["q:container"] = "paused", containerAttributes["q:version"] = "1.17.2", containerAttributes["q:render"] = (qRender ? qRender + "-" : "") + "ssr", containerAttributes["q:base"] = opts.base || "", containerAttributes["q:locale"] = locale, containerAttributes["q:manifest-hash"] = opts.manifestHash, containerAttributes["q:instance"] = hash(); const children = "html" === root ? [ node ] : [ headNodes, node ]; "html" !== root && (containerAttributes.class = "qc📦" + (containerAttributes.class ? " " + containerAttributes.class : "")); const serverData = containerState.$serverData$ = { ...containerState.$serverData$, ...opts.serverData }; serverData.containerAttributes = { ...serverData.containerAttributes, ...containerAttributes }; (ssrCtx.$invocationContext$ = newInvokeContext(locale)).$renderCtx$ = rCtx; const rootNode = _jsxQ(root, null, containerAttributes, children, HOST_FLAG_DIRTY | HOST_FLAG_NEED_ATTACH_LISTENER, null); containerState.$hostsRendering$ = new Set, await Promise.resolve().then(() => renderRoot$1(rootNode, rCtx, ssrCtx, opts.stream, containerState, opts)); }; const hash = () => Math.random().toString(36).slice(2); const renderRoot$1 = async (node, rCtx, ssrCtx, stream, containerState, opts) => { const beforeClose = opts.beforeClose; return await renderNode(node, rCtx, ssrCtx, stream, 0, beforeClose ? stream => { const result = beforeClose(ssrCtx.$static$.$contexts$, containerState, !1, ssrCtx.$static$.$textNodes$); return processData$1(result, rCtx, ssrCtx, stream, 0, void 0); } : void 0), rCtx; }; const renderGenerator = async (node, rCtx, ssrCtx, stream, flags) => { stream.write(FLUSH_COMMENT); const generator = node.props.children; let value; if (isFunction(generator)) { const v = generator({ write(chunk) { stream.write(chunk), stream.write(FLUSH_COMMENT); } }); if (isPromise(v)) { return v; } value = v; } else { value = generator; } for await (const chunk of value) { await processData$1(chunk, rCtx, ssrCtx, stream, flags, void 0), stream.write(FLUSH_COMMENT); } }; const renderNodeVirtual = (node, elCtx, extraNodes, rCtx, ssrCtx, stream, flags, beforeClose) => { const props = node.props; const renderQrl = props["q:renderFn"]; if (renderQrl) { return elCtx.$componentQrl$ = renderQrl, renderSSRComponent(rCtx, ssrCtx, stream, elCtx, node, flags, beforeClose); } let virtualComment = "\x3c!--qv" + renderVirtualAttributes(props); const isSlot = "q:s" in props; const key = null != node.key ? String(node.key) : null; isSlot && (assertDefined(rCtx.$cmpCtx$?.$id$, "hostId must be defined for a slot"), virtualComment += " q:sref=" + rCtx.$cmpCtx$.$id$), null != key && (virtualComment += " q:key=" + key), virtualComment += "--\x3e", stream.write(virtualComment); const html = node.props[dangerouslySetInnerHTML]; if (html) { return stream.write(html), void stream.write(CLOSE_VIRTUAL); } if (extraNodes) { for (const node of extraNodes) { renderNodeElementSync(node.type, node.props, stream); } } const promise = walkChildren(node.children, rCtx, ssrCtx, stream, flags); return maybeThen(promise, () => { if (!isSlot && !beforeClose) { return void stream.write(CLOSE_VIRTUAL); } let promise; if (isSlot) { assertDefined(key, "key must be defined for a slot"); const content = ssrCtx.$projectedChildren$?.[key]; if (content) { const [rCtx, sCtx] = ssrCtx.$projectedCtxs$; const newSlotRctx = pushRenderContext(rCtx); newSlotRctx.$slotCtx$ = elCtx, ssrCtx.$projectedChildren$[key] = void 0, promise = processData$1(content, newSlotRctx, sCtx, stream, flags); } } return beforeClose && (promise = maybeThen(promise, () => beforeClose(stream))), maybeThen(promise, () => { stream.write(CLOSE_VIRTUAL); }); }); }; const CLOSE_VIRTUAL = "\x3c!--/qv--\x3e"; const renderAttributes = attributes => { let text = ""; for (const prop in attributes) { if (prop === dangerouslySetInnerHTML) { continue; } const value = attributes[prop]; null != value && (text += " " + ("" === value ? prop : prop + '="' + value + '"')); } return text; }; const renderVirtualAttributes = attributes => { let text = ""; for (const prop in attributes) { if ("children" === prop || prop === dangerouslySetInnerHTML) { continue; } const value = attributes[prop]; null != value && (text += " " + ("" === value ? prop : prop + "=" + value)); } return text; }; const renderNodeElementSync = (tagName, attributes, stream) => { stream.write("<" + tagName + renderAttributes(attributes) + ">"); if (!!emptyElements[tagName]) { return; } const innerHTML = attributes[dangerouslySetInnerHTML]; null != innerHTML && stream.write(innerHTML), stream.write(`</${tagName}>`); }; const renderSSRComponent = (rCtx, ssrCtx, stream, elCtx, node, flags, beforeClose) => (setComponentProps$1(rCtx, elCtx, node.props.props), maybeThen(executeComponent(rCtx, elCtx), res => { const hostElement = elCtx.$element$; const newRCtx = res.rCtx; const iCtx = newInvokeContext(ssrCtx.$static$.$locale$, hostElement, void 0); iCtx.$subscriber$ = [ 0, hostElement ], iCtx.$renderCtx$ = newRCtx; const newSSrContext = { $static$: ssrCtx.$static$, $projectedChildren$: splitProjectedChildren(node.children, ssrCtx), $projectedCtxs$: [ rCtx, ssrCtx ], $invocationContext$: iCtx }; const extraNodes = []; if (elCtx.$appendStyles$) { const array = !!(4 & flags) ? ssrCtx.$static$.$headNodes$ : extraNodes; for (const style of elCtx.$appendStyles$) { array.push(_jsxQ("style", { [QStyle]: style.styleId, [dangerouslySetInnerHTML]: style.content, hidden: "" }, null, null, 0, null)); } } const newID = getNextIndex(rCtx); const scopeId = elCtx.$scopeIds$ ? serializeSStyle(elCtx.$scopeIds$) : void 0; const processedNode = _jsxC(node.type, { [QScopedStyle]: scopeId, [ELEMENT_ID]: newID, children: res.node }, 0, node.key); return elCtx.$id$ = newID, ssrCtx.$static$.$contexts$.push(elCtx), renderNodeVirtual(processedNode, elCtx, extraNodes, newRCtx, newSSrContext, stream, flags, stream => { if (elCtx.$flags$ & HOST_FLAG_NEED_ATTACH_LISTENER) { const placeholderCtx = createMockQContext(1); const listeners = placeholderCtx.li; listeners.push(...elCtx.li), elCtx.$flags$ &= ~HOST_FLAG_NEED_ATTACH_LISTENER, placeholderCtx.$id$ = getNextIndex(rCtx); const attributes = { hidden: "", "q:id": placeholderCtx.$id$ }; ssrCtx.$static$.$contexts$.push(placeholderCtx); const groups = groupListeners(listeners); for (const listener of groups) { const eventName = normalizeInvisibleEvents(listener[0]); attributes[eventName] = serializeQRLs(listener[1], rCtx.$static$.$containerState$, placeholderCtx), registerQwikEvent$1(eventName, rCtx.$static$.$containerState$); } renderNodeElementSync("script", attributes, stream); } const projectedChildren = newSSrContext.$projectedChildren$; let missingSlotsDone; if (projectedChildren) { const nodes = Object.keys(projectedChildren).map(slotName => { const content = projectedChildren[slotName]; if (content) { return _jsxQ("q:template", { [QSlot]: slotName || !0, hidden: !0, "aria-hidden": "true" }, null, content, 0, null); } }); const [_rCtx, sCtx] = newSSrContext.$projectedCtxs$; const newSlotRctx = pushRenderContext(_rCtx); newSlotRctx.$slotCtx$ = elCtx, missingSlotsDone = processData$1(nodes, newSlotRctx, sCtx, stream, 0, void 0); } return beforeClose ? maybeThen(missingSlotsDone, () => beforeClose(stream)) : missingSlotsDone; }); })); const splitProjectedChildren = (children, ssrCtx) => { const flatChildren = flatVirtualChildren(children, ssrCtx); if (null === flatChildren) { return; } const slotMap = {}; for (const child of flatChildren) { let slotName = ""; isJSXNode(child) && (slotName = child.props[QSlot] || ""), (slotMap[slotName] ||= []).push(child); } return slotMap; }; const createMockQContext = nodeType => { const elm = new MockElement(nodeType); return createContext(elm); }; const renderNode = (node, rCtx, ssrCtx, stream, flags, beforeClose) => { const tagName = node.type; const hostCtx = rCtx.$cmpCtx$; if ("string" == typeof tagName) { const key = node.key; const props = node.props; const immutable = node.immutableProps || EMPTY_OBJ; const elCtx = createMockQContext(1); const elm = elCtx.$element$; const isHead = "head" === tagName; let openingElement = "<" + tagName; let useSignal = !1; let hasRef = !1; let classStr = ""; let htmlStr = null; const handleProp = (rawProp, value, isImmutable) => { if ("ref" === rawProp) { return void (void 0 !== value && (setRef(value, elm), hasRef = !0)); } if (isOnProp(rawProp)) { return void setEvent(elCtx.li, rawProp, value, void 0); } if (isSignal(value) && (assertDefined(hostCtx, "Signals can not be used outside the root"), value = trackSignal(value, isImmutable ? [ 1, elm, value, hostCtx.$element$, rawProp ] : [ 2, hostCtx.$element$, value, elm, rawProp ]), useSignal = !0), rawProp === dangerouslySetInnerHTML) { return void (htmlStr = value); } let attrValue; rawProp.startsWith(PREVENT_DEFAULT) && registerQwikEvent$1(rawProp.slice(15), rCtx.$static$.$containerState$); const prop = "htmlFor" === rawProp ? "for" : rawProp; "class" === prop || "className" === prop ? classStr = serializeClass(value) : "style" === prop ? attrValue = stringifyStyle(value) : isAriaAttribute(prop) || "draggable" === prop || "spellcheck" === prop ? (attrValue = null != value ? String(value) : null, value = attrValue) : attrValue = !1 === value || null == value ? null : String(value), null != attrValue && ("value" === prop && "textarea" === tagName ? htmlStr = escapeHtml(attrValue) : isSSRUnsafeAttr(prop) || (openingElement += " " + (!0 === value ? prop : prop + '="' + escapeHtml(attrValue) + '"'))); }; for (const prop in props) { let isImmutable = !1; let value; prop in immutable ? (isImmutable = !0, value = immutable[prop], value === _IMMUTABLE && (value = props[prop])) : value = props[prop], handleProp(prop, value, isImmutable); } for (const prop in immutable) { if (prop in props) { continue; } const value = immutable[prop]; value !== _IMMUTABLE && handleProp(prop, value, !0); } const listeners = elCtx.li; if (hostCtx) { if (hostCtx.$scopeIds$?.length) { const extra = hostCtx.$scopeIds$.join(" "); classStr = classStr ? `${extra} ${classStr}` : extra; } hostCtx.$flags$ & HOST_FLAG_NEED_ATTACH_LISTENER && (listeners.push(...hostCtx.li), hostCtx.$flags$ &= ~HOST_FLAG_NEED_ATTACH_LISTENER); } if (isHead && (flags |= 1), tagName in invisibleElements && (flags |= 16), tagName in textOnlyElements && (flags |= 8), classStr && (openingElement += ' class="' + escapeHtml(classStr) + '"'), listeners.length > 0) { const groups = groupListeners(listeners); const isInvisible = !!(16 & flags); for (const listener of groups) { const eventName = isInvisible ? normalizeInvisibleEvents(listener[0]) : listener[0]; openingElement += " " + eventName + '="' + serializeQRLs(listener[1], rCtx.$static$.$containerState$, elCtx) + '"', registerQwikEvent$1(eventName, rCtx.$static$.$containerState$); } } if (null != key && (openingElement += ' q:key="' + escapeHtml(key) + '"'), hasRef || useSignal || listeners.length > 0) { if (hasRef || useSignal || listenersNeedId(listeners)) { const newID = getNextIndex(rCtx); openingElement += ' q:id="' + newID + '"', elCtx.$id$ = newID; } ssrCtx.$static$.$contexts$.push(elCtx); } if (1 & flags && (openingElement += " q:head"), openingElement += ">", stream.write(openingElement), tagName in emptyElements) { return; } if (null != htmlStr) { return stream.write(String(htmlStr)), void stream.write(`</${tagName}>`); } "html" === tagName ? flags |= 4 : flags &= -5, 2 & node.flags && (flags |= 1024); const promise = processData$1(node.children, rCtx, ssrCtx, stream, flags); return maybeThen(promise, () => { if (isHead) { for (const node of ssrCtx.$static$.$headNodes$) { renderNodeElementSync(node.type, node.props, stream); } ssrCtx.$static$.$headNodes$.length = 0; } if (beforeClose) { return maybeThen(beforeClose(stream), () => { stream.write(`</${tagName}>`); }); } stream.write(`</${tagName}>`); }); } if (tagName === Virtual) { const elCtx = createMockQContext(111); return rCtx.$slotCtx$ ? (elCtx.$parentCtx$ = rCtx.$slotCtx$, elCtx.$realParentCtx$ = rCtx.$cmpCtx$) : elCtx.$parentCtx$ = rCtx.$cmpCtx$, hostCtx && hostCtx.$flags$ & HOST_FLAG_DYNAMIC && addDynamicSlot(hostCtx, elCtx), renderNodeVirtual(node, elCtx, void 0, rCtx, ssrCtx, stream, flags, beforeClose); } if (tagName === SSRRaw) { return void stream.write(node.props.data); } if (tagName === InternalSSRStream) { return renderGenerator(node, rCtx, ssrCtx, stream, flags); } const res = invoke(ssrCtx.$invocationContext$, tagName, node.props, node.key, node.flags, node.dev); return shouldWrapFunctional(res, node) ? renderNode(_jsxC(Virtual, { children: res }, 0, node.key), rCtx, ssrCtx, stream, flags, beforeClose) : processData$1(res, rCtx, ssrCtx, stream, flags, beforeClose); }; const processData$1 = (node, rCtx, ssrCtx, stream, flags, beforeClose) => { if (null != node && "boolean" != typeof node) { if (!isString(node) && "number" != typeof node) { if (isJSXNode(node)) { return renderNode(node, rCtx, ssrCtx, stream, flags, beforeClose); } if (isArray(node)) { return walkChildren(node, rCtx, ssrCtx, stream, flags); } if (isSignal(node)) { const insideText = 8 & flags; const hostEl = rCtx.$cmpCtx$?.$element$; let value; if (hostEl) { if (!insideText) { const id = getNextIndex(rCtx); if (value = trackSignal(node, 1024 & flags ? [ 3, "#" + id, node, "#" + id ] : [ 4, hostEl, node, "#" + id ]), isString(value)) { const str = jsxToString(value); ssrCtx.$static$.$textNodes$.set(str, id); } return stream.write(`\x3c!--t=${id}--\x3e`), processData$1(value, rCtx, ssrCtx, stream, flags, beforeClose), void stream.write("\x3c!----\x3e"); } value = invoke(ssrCtx.$invocationContext$, () => node.value); } return void stream.write(escapeHtml(jsxToString(value))); } return isPromise(node) ? (stream.write(FLUSH_COMMENT), node.then(node => processData$1(node, rCtx, ssrCtx, stream, flags, beforeClose))) : void logWarn("A unsupported value was passed to the JSX, skipping render. Value:", node); } stream.write(escapeHtml(String(node))); } }; const walkChildren = (children, rCtx, ssrContext, stream, flags) => { if (null == children) { return; } if (!isArray(children)) { return processData$1(children, rCtx, ssrContext, stream, flags); } const len = children.length; if (1 === len) { return processData$1(children[0], rCtx, ssrContext, stream, flags); } if (0 === len) { return; } let currentIndex = 0; const buffers = []; return children.reduce((prevPromise, child, index) => { const buffer = []; buffers.push(buffer); const rendered = processData$1(child, rCtx, ssrContext, prevPromise ? { write(chunk) { currentIndex === index ? stream.write(chunk) : buffer.push(chunk); } } : stream, flags); if (prevPromise || isPromise(rendered)) { const next = () => { currentIndex++, buffers.length > currentIndex && buffers[currentIndex].forEach(chunk => stream.write(chunk)); }; return isPromise(rendered) ? prevPromise ? Promise.all([ rendered, prevPromise ]).then(next) : rendered.then(next) : prevPromise.then(next); } currentIndex++; }, void 0); }; const flatVirtualChildren = (children, ssrCtx) => { if (null == children) { return null; } const result = _flatVirtualChildren(children, ssrCtx); const nodes = isArray(result) ? result : [ result ]; return 0 === nodes.length ? null : nodes; }; const _flatVirtualChildren = (children, ssrCtx) => { if (null == children) { return null; } if (isArray(children)) { return children.flatMap(c => _flatVirtualChildren(c, ssrCtx)); } if (isJSXNode(children) && isFunction(children.type) && children.type !== SSRRaw && children.type !== InternalSSRStream && children.type !== Virtual) { const res = invoke(ssrCtx.$invocationContext$, children.type, children.props, children.key, children.flags); return flatVirtualChildren(res, ssrCtx); } return children; }; const setComponentProps$1 = (rCtx, elCtx, expectProps) => { const keys = Object.keys(expectProps); const target = createPropsState(); if (elCtx.$props$ = createProxy(target, rCtx.$static$.$containerState$), 0 === keys.length) { return; } const immutableMeta = target[_IMMUTABLE] = expectProps[_IMMUTABLE] ?? EMPTY_OBJ; for (const prop of keys) { "children" !== prop && prop !== QSlot && (isSignal(immutableMeta[prop]) ? target["$$" + prop] = immutableMeta[prop] : target[prop] = expectProps[prop]); } }; const invisibleElements = { head: !0, style: !0, script: !0, link: !0, meta: !0 }; const textOnlyElements = { title: !0, style: !0, script: !0, noframes: !0, textarea: !0 }; const emptyElements = { area: !0, base: !0, basefont: !0, bgsound: !0, br: !0, col: !0, embed: !0, frame: !0, hr: !0, img: !0, input: !0, keygen: !0, link: !0, meta: !0, param: !0, source: !0, track: !0, wbr: !0 }; const startPhasingContent = { p: !0, pre: !0 }; const htmlContent = { head: !0, body: !0 }; const tableContent = { tbody: !0, thead: !0, tfoot: !0, caption: !0, colgroup: !0 }; const headContent = { meta: !0, title: !0, link: !0, style: !0, script: !0, noscript: !0, template: !0, base: !0 }; const phasingContent = { a: !0, abbr: !0, area: !0, audio: !0, b: !0, bdi: !0, bdo: !0, br: !0, button: !0, canvas: !0, cite: !0, code: !0, command: !0, data: !0, datalist: !0, del: !0, dfn: !0, em: !0, embed: !0, i: !0, iframe: !0, img: !0, input: !0, ins: !0, itemprop: !0, kbd: !0, keygen: !0, label: !0, link: !0, map: !0, mark: !0, math: !0, meta: !0, meter: !0, noscript: !0, object: !0, option: !0, output: !0, picture: !0, progress: !0, q: !0, ruby: !0, s: !0, samp: !0, script: !0, select: !0, slot: !0, small: !0, span: !0, strong: !0, sub: !0, sup: !0, svg: !0, template: !0, textarea: !0, time: !0, u: !0, var: !0, video: !0, wbr: !0 }; const ESCAPE_HTML = /[&<>'"]/g; const registerQwikEvent$1 = (prop, containerState) => { containerState.$events$.add(getEventName(prop)); }; const escapeHtml = s => s.replace(ESCAPE_HTML, c => { switch (c) { case "&": return "&amp;"; case "<": return "&lt;"; case ">": return "&gt;"; case '"': return "&quot;"; case "'": return "&#39;"; default: return ""; } }); const unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/; const isSSRUnsafeAttr = name => unsafeAttrCharRE.test(name); const listenersNeedId = listeners => listeners.some(l => l[1].$captureRef$ && l[1].$captureRef$.length > 0); const addDynamicSlot = (hostCtx, elCtx) => { const dynamicSlots = hostCtx.$dynamicSlots$ ||=