@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
JavaScript
/**
* @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 "&";
case "<":
return "<";
case ">":
return ">";
case '"':
return """;
case "'":
return "'";
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$ ||=