UNPKG

@qwik.dev/core

Version:

An open source framework for building instant loading web apps at any scale, without the extra effort.

1,467 lines (1,241 loc) 249 kB
/** * @license * @qwik.dev/core 2.0.0-alpha.9-dev+56ed5bd * Copyright QwikDev. 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 { isDev, isServer } from "@qwik.dev/core/build"; export { isBrowser, isDev, isServer } from "@qwik.dev/core/build"; const qDev = !1; const qInspector = !1; const qSerialize = !0; const qDynamicPlatform = !0; const qTest = !1; const qRuntimeQrl = !1; const seal = () => { qDev; }; const STYLE = ""; const logError = (message, ...optionalParams) => createAndLogError(!1, message, ...optionalParams); const throwErrorAndStop = (message, ...optionalParams) => { throw createAndLogError(!1, message, ...optionalParams); }; const logErrorAndStop = (message, ...optionalParams) => createAndLogError(!0, message, ...optionalParams); const _printed = /*#__PURE__*/ new Set; const logOnceWarn = () => { qDev; }; const logWarn = () => { qDev; }; const createAndLogError = (asyncThrow, message, ...optionalParams) => { const err = message instanceof Error ? message : new Error(message); return console.error("%cQWIK ERROR", "", err.message, ...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 assertTrue() { qDev; } function assertFalse() { qDev; } function assertNumber() { qDev; } const codeToText = code => `Code(Q${code}) https://github.com/QwikDev/qwik/blob/main/packages/qwik/src/core/error/error.ts#L${8 + code}`; const qError = (code, errorMessageArgs = []) => { const text = codeToText(code, ...errorMessageArgs); return logErrorAndStop(text, ...errorMessageArgs); }; const SYNC_QRL = "<sync>"; const isSyncQrl = value => isQrl$1(value) && "<sync>" == value.$symbol$; const isQrl$1 = value => "function" == typeof value && "function" == typeof value.getSymbol; function assertQrl(qrl) { if (isDev && !isQrl$1(qrl)) { throw new Error("Not a QRL"); } } const getSymbolHash = symbolName => { const index = symbolName.lastIndexOf("_"); return index > -1 ? symbolName.slice(index + 1) : symbolName; }; const OnRenderProp = "q:renderFn"; const ComponentStylesPrefixContent = "⚡️"; const QSlot = "q:slot"; const QSlotParent = "q:sparent"; const QSlotS = "q:s"; const QStyle = "q:style"; const QStyleSelector = "style[q\\:style]"; const QStyleSSelector = "style[q\\:sstyle]"; const QStylesAllSelector = "style[q\\:style],style[q\\:sstyle]"; const QScopedStyle = "q:sstyle"; const QCtxAttr = "q:ctx"; const QBackRefs = "q:brefs"; const QFuncsPrefix = "qFuncs_"; const getQFuncs = (document, hash) => document["qFuncs_" + hash] || []; const QBaseAttr = "q:base"; const QLocaleAttr = "q:locale"; const QManifestHashAttr = "q:manifest-hash"; const QInstanceAttr = "q:instance"; const QContainerIsland = "q:container-island"; const QContainerIslandEnd = "/" + QContainerIsland; const QIgnore = "q:ignore"; const QIgnoreEnd = "/q:ignore"; const QContainerAttr = "q:container"; const QContainerAttrEnd = "/q:container"; const QTemplate = "q:template"; const QContainerSelector = "[q\\:container]:not([q\\:container=html]):not([q\\:container=text])"; const HTML_NS = "http://www.w3.org/1999/xhtml"; const SVG_NS = "http://www.w3.org/2000/svg"; const MATH_NS = "http://www.w3.org/1998/Math/MathML"; const ResourceEvent = "qResource"; const RenderEvent = "qRender"; const TaskEvent = "qTask"; const QDefaultSlot = ""; const ELEMENT_ID = "q:id"; const ELEMENT_KEY = "q:key"; const ELEMENT_PROPS = "q:props"; const ELEMENT_SEQ = "q:seq"; const ELEMENT_SEQ_IDX = "q:seqIdx"; const Q_PREFIX = "q:"; const NON_SERIALIZABLE_MARKER_PREFIX = ":"; const USE_ON_LOCAL = ":on"; const USE_ON_LOCAL_SEQ_IDX = ":onIdx"; const USE_ON_LOCAL_FLAGS = ":onFlags"; const FLUSH_COMMENT = "qkssr-f"; const STREAM_BLOCK_START_COMMENT = "qkssr-pu"; const STREAM_BLOCK_END_COMMENT = "qkssr-po"; const Q_PROPS_SEPARATOR = ":"; const dangerouslySetInnerHTML = "dangerouslySetInnerHTML"; const qwikInspectorAttr = "data-qwik-inspector"; 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 isNode = value => value && "number" == typeof value.nodeType; const isDocument = value => 9 === value.nodeType; const isElement$1 = value => 1 === value.nodeType; const MAX_RETRY_ON_PROMISE_COUNT = 100; const isPromise = value => !!value && "object" == typeof value && "function" == typeof value.then; const safeCall = (call, thenFn, rejectFn) => { try { const result = call(); return isPromise(result) ? result.then(thenFn, rejectFn) : thenFn(result); } catch (e) { return rejectFn(e); } }; const maybeThen = (valueOrPromise, thenFn) => isPromise(valueOrPromise) ? valueOrPromise.then(thenFn, shouldNotError) : thenFn(valueOrPromise); const shouldNotError = reason => { throwErrorAndStop(reason); }; const delay = timeout => new Promise((resolve => { setTimeout(resolve, timeout); })); function retryOnPromise(fn, retryCount = 0) { const retryOrThrow = e => { if (isPromise(e) && retryCount < 100) { return e.then(retryOnPromise.bind(null, fn, retryCount++)); } throw e; }; try { const result = fn(); return isPromise(result) ? result.catch((e => retryOrThrow(e))) : result; } catch (e) { return retryOrThrow(e); } } const isSerializableObject = v => { const proto = Object.getPrototypeOf(v); return proto === Object.prototype || proto === Array.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 isQrl = value => "function" == typeof value && "function" == typeof value.getSymbol; const EMPTY_ARRAY = []; const EMPTY_OBJ = {}; Object.freeze(EMPTY_ARRAY), Object.freeze(EMPTY_OBJ); const EXTRACT_IMPORT_PATH = /\(\s*(['"])([^\1]+)\1\s*\)/; const EXTRACT_SELF_IMPORT = /Promise\s*\.\s*resolve/; const EXTRACT_FILE_NAME = /[\\/(]([\w\d.\-_]+\.(js|ts)x?):/; const announcedQRL = /*#__PURE__*/ new Set; const qrl = (chunkOrFn, symbol, lexicalScopeCapture = EMPTY_ARRAY, stackOffset = 0) => { let chunk = null; let symbolFn = null; if (isFunction(chunkOrFn)) { symbolFn = chunkOrFn; { let match; const srcCode = String(chunkOrFn); if ((match = srcCode.match(EXTRACT_IMPORT_PATH)) && match[2]) { chunk = match[2]; } else { if (!(match = srcCode.match(EXTRACT_SELF_IMPORT))) { throw qError(11, [ srcCode ]); } { const ref = "QWIK-SELF"; const frames = new Error(ref).stack.split("\n"); const start = frames.findIndex((f => f.includes(ref))); match = frames[start + 2 + stackOffset].match(EXTRACT_FILE_NAME), chunk = match ? match[1] : "main"; } } } } else { if (!isString(chunkOrFn)) { throw qError(12, [ chunkOrFn ]); } chunk = chunkOrFn; } return announcedQRL.has(symbol) || (announcedQRL.add(symbol), emitEvent("qprefetch", { symbols: [ symbol ], bundles: chunk && [ chunk ] })), createQRL(chunk, symbol, null, symbolFn, null, lexicalScopeCapture); }; const inlinedQrl = (symbol, symbolName, lexicalScopeCapture = EMPTY_ARRAY) => createQRL(null, symbolName, symbol, null, null, lexicalScopeCapture); const _noopQrl = (symbolName, lexicalScopeCapture = EMPTY_ARRAY) => createQRL(null, symbolName, null, null, null, lexicalScopeCapture); const _noopQrlDEV = (symbolName, opts, lexicalScopeCapture = EMPTY_ARRAY) => { const newQrl = _noopQrl(symbolName, lexicalScopeCapture); return newQrl.dev = opts, newQrl; }; const qrlDEV = (chunkOrFn, symbol, opts, lexicalScopeCapture = EMPTY_ARRAY) => { const newQrl = qrl(chunkOrFn, symbol, lexicalScopeCapture, 1); return newQrl.dev = opts, newQrl; }; const inlinedQrlDEV = (symbol, symbolName, opts, lexicalScopeCapture = EMPTY_ARRAY) => { const qrl = inlinedQrl(symbol, symbolName, lexicalScopeCapture); return qrl.dev = opts, qrl; }; const _regSymbol = (symbol, hash) => (void 0 === globalThis.__qwik_reg_symbols && (globalThis.__qwik_reg_symbols = new Map), globalThis.__qwik_reg_symbols.set(hash, symbol), symbol); let _locale; function getLocale(defaultLocale) { if (void 0 === _locale) { const ctx = tryGetInvokeContext(); if (ctx && ctx.$locale$) { return ctx.$locale$; } if (void 0 !== defaultLocale) { return defaultLocale; } throw new Error("Reading `locale` outside of context."); } return _locale; } function withLocale(locale, fn) { const previousLang = _locale; try { return _locale = locale, fn(); } finally { _locale = previousLang; } } function setLocale(locale) { _locale = locale; } const useSequentialScope = () => { const iCtx = useInvokeContext(); const host = iCtx.$hostElement$; let seq = iCtx.$container$.getHostProp(host, "q:seq"); null === seq && (seq = [], iCtx.$container$.setHostProp(host, "q:seq", seq)); let seqIdx = iCtx.$container$.getHostProp(host, "q:seqIdx"); for (null === seqIdx && (seqIdx = 0), iCtx.$container$.setHostProp(host, "q:seqIdx", seqIdx + 1); seq.length <= seqIdx; ) { seq.push(void 0); } return { val: seq[seqIdx], set: value => seq[seqIdx] = value, i: seqIdx, iCtx }; }; const EVENT_SUFFIX = "$"; const DOMContentLoadedEvent = "DOMContentLoaded"; const isJsxPropertyAnEventName = name => (name.startsWith("on") || name.startsWith("window:on") || name.startsWith("document:on")) && name.endsWith("$"); const isHtmlAttributeAnEventName = name => name.startsWith("on:") || name.startsWith("on-window:") || name.startsWith("on-document:"); function jsxEventToHtmlAttribute(jsxEvent) { if (jsxEvent.endsWith("$")) { const [prefix, idx] = getEventScopeDataFromJsxEvent(jsxEvent); if (-1 !== idx) { const eventName = getEventNameFromJsxEvent(jsxEvent); return prefix + fromCamelToKebabCase(eventName); } } return null; } function eventNameToJsxEvent(eventName, prefix) { return prefix + (eventName = eventName.charAt(0).toUpperCase() + eventName.substring(1)) + "$"; } function getEventNameFromJsxEvent(jsxEvent) { if (jsxEvent.endsWith("$")) { const [, idx] = getEventScopeDataFromJsxEvent(jsxEvent); if (-1 != idx) { return jsxEventToEventName(jsxEvent, idx); } } return null; } function jsxEventToEventName(jsxEvent, startIdx = 0) { let lastIdx = startIdx; const isCaseSensitive = isDash(jsxEvent.charCodeAt(startIdx)); isCaseSensitive && lastIdx++; let eventName = ""; const chunk = jsxEvent.substring(lastIdx, jsxEvent.length - 1); return "DOMContentLoaded" === chunk ? "DOMContentLoaded" : (eventName += isCaseSensitive ? chunk : chunk.toLowerCase(), eventName); } function getEventScopeDataFromJsxEvent(eventName) { let prefix = null; let idx = -1; return eventName.startsWith("on") ? (prefix = "on:", idx = 2) : eventName.startsWith("window:on") ? (prefix = "on-window:", idx = 9) : eventName.startsWith("document:on") && (prefix = "on-document:", idx = 11), [ prefix, idx ]; } const isDash = charCode => 45 === charCode; const getEventNameScopeFromJsxEvent = name => { const index = name.indexOf(":"); return -1 !== index ? name.substring(0, index) : ""; }; function isPreventDefault(key) { return key.startsWith("preventdefault:"); } const fromCamelToKebabCase = text => text.replace(/([A-Z-])/g, "-$1").toLowerCase(); 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, iCtx} = useSequentialScope(); void 0 === val && (iCtx.$container$.setContext(iCtx.$hostElement$, context, newValue), set(1)); }; const useContext = (context, defaultValue) => { const {val, set, iCtx} = useSequentialScope(); if (void 0 !== val) { return val; } const value = iCtx.$container$.resolveContext(iCtx.$hostElement$, context); 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 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 isRecoverable = err => !(err && err instanceof Error && "plugin" in err); const version = "2.0.0-alpha.9-dev+56ed5bd"; const Slot = props => _jsxSorted(Virtual, null, { [QSlotS]: "" }, props.children, 0, props.name ?? ""); const SkipRender = Symbol("skip render"); const SSRRaw = () => null; const SSRComment = () => null; const SSRStreamBlock = props => [ jsx(SSRComment, { data: "qkssr-pu" }), props.children, jsx(SSRComment, { data: "qkssr-po" }) ]; const SSRStream = (props, key) => jsx(RenderOnce, { children: jsx(InternalSSRStream, props) }, key); const InternalSSRStream = () => null; const NEEDS_COMPUTATION = Symbol("invalid"); const _EFFECT_BACK_REF = Symbol("backRef"); function getSubscriber(effect, prop, data) { effect[_EFFECT_BACK_REF] || (isServer && isSsrNode(effect) ? effect.setProp("q:brefs", new Map) : effect[_EFFECT_BACK_REF] = new Map); const subMap = effect[_EFFECT_BACK_REF]; let sub = subMap.get(prop); return sub || (sub = [ effect, prop ], subMap.set(prop, sub)), data && (sub[3] = data), sub; } function isSsrNode(value) { return "__brand__" in value && "currentComponentNode" in value; } const DEBUG$1 = !1; const log = (...args) => console.log("SIGNAL", ...args.map(qwikDebugToString)); const throwIfQRLNotResolved = qrl => { if (!qrl.resolved) { throw qrl.resolve(); } }; const isSignal = value => value instanceof SignalImpl; class SubscriptionData { data; constructor(data) { this.data = data; } } class SignalImpl { $untrackedValue$; $effects$=null; $container$=null; constructor(container, value) { this.$container$ = container, this.$untrackedValue$ = value; } get untrackedValue() { return this.$untrackedValue$; } set untrackedValue(value) { this.$untrackedValue$ = value; } get value() { const ctx = tryGetInvokeContext(); if (ctx) { if (null === this.$container$) { if (!ctx.$container$) { return this.untrackedValue; } this.$container$ = ctx.$container$; } else { assertTrue(!ctx.$container$ || ctx.$container$ === this.$container$, "Do not use signals across containers"); } const effectSubscriber = ctx.$effectSubscriber$; if (effectSubscriber) { const effects = this.$effects$ ||= new Set; ensureContainsSubscription(effects, effectSubscriber), ensureContainsBackRef(effectSubscriber, this), addQrlToSerializationCtx(effectSubscriber, this.$container$); } } return this.untrackedValue; } set value(value) { value !== this.$untrackedValue$ && (this.$untrackedValue$ = value, triggerEffects(this.$container$, this, this.$effects$)); } valueOf() { qDev; } toString() { return isDev ? `[${this.constructor.name}${1 & this.$flags$ ? " INVALID" : ""} ${String(this.$untrackedValue$)}]` + (Array.from(this.$effects$ || []).map((e => "\n -> " + pad(qwikDebugToString(e[0]), " "))).join("\n") || "") : this.constructor.name; } toJSON() { return { value: this.$untrackedValue$ }; } } const ensureContainsSubscription = (array, effectSubscription) => { array.add(effectSubscription); }; const ensureContainsBackRef = (array, value) => { array[2] ||= new Set, array[2].add(value); }; const addQrlToSerializationCtx = (effectSubscriber, container) => { if (container && !isDomContainer(container)) { const effect = effectSubscriber[0]; const property = effectSubscriber[1]; let qrl = null; isTask(effect) ? qrl = effect.$qrl$ : effect instanceof ComputedSignalImpl ? qrl = effect.$computeQrl$ : ":" === property && (qrl = container.getHostProp(effect, "q:renderFn")), qrl && container.serializationCtx.$eventQrls$.add(qrl); } }; const triggerEffects = (container, signal, effects) => { const isBrowser = isDomContainer(container); if (effects) { const scheduleEffect = effectSubscription => { const consumer = effectSubscription[0]; const property = effectSubscription[1]; if (assertDefined(container, "Container must be defined."), isTask(consumer)) { consumer.$flags$ |= 8; let choreType = 3; 1 & consumer.$flags$ && (choreType = 32), container.$scheduler$(choreType, consumer); } else if (consumer instanceof SignalImpl) { consumer instanceof ComputedSignalImpl && (consumer.$computeQrl$.resolved || container.$scheduler$(1, null, consumer.$computeQrl$)), consumer.$invalidate$(); } else if (":" === property) { const host = consumer; const qrl = container.getHostProp(host, "q:renderFn"); assertDefined(qrl, "Component must have QRL"); const props = container.getHostProp(host, "q:props"); container.$scheduler$(6, host, qrl, props); } else if (isBrowser) { if ("." === property) { container.$scheduler$(4, consumer, consumer, signal); } else { const effectData = effectSubscription[3]; if (effectData instanceof SubscriptionData) { const payload = { ...effectData.data, $value$: signal }; container.$scheduler$(5, consumer, property, payload); } } } }; for (const effect of effects) { scheduleEffect(effect); } } }; class ComputedSignalImpl extends SignalImpl { $computeQrl$; $flags$; $forceRunEffects$=!1; [_EFFECT_BACK_REF]=null; constructor(container, fn, flags = 1) { super(container, NEEDS_COMPUTATION), this.$computeQrl$ = fn, this.$flags$ = flags; } $invalidate$() { this.$flags$ |= 1, this.$forceRunEffects$ = !1, this.$container$?.$scheduler$(7, null, this); } force() { this.$forceRunEffects$ = !0, this.$container$?.$scheduler$(7, null, this); } get untrackedValue() { const didChange = this.$computeIfNeeded$(); return didChange && (this.$forceRunEffects$ = didChange), assertFalse(this.$untrackedValue$ === NEEDS_COMPUTATION, "Invalid state"), this.$untrackedValue$; } $computeIfNeeded$() { if (!(1 & this.$flags$)) { return !1; } const computeQrl = this.$computeQrl$; throwIfQRLNotResolved(computeQrl); const ctx = tryGetInvokeContext(); const previousEffectSubscription = ctx?.$effectSubscriber$; ctx && (ctx.$effectSubscriber$ = getSubscriber(this, ".")); try { const untrackedValue = computeQrl.getFn(ctx)(); if (isPromise(untrackedValue)) { throw qError(46, [ computeQrl.dev ? computeQrl.dev.file : "", computeQrl.$hash$ ]); } this.$flags$ &= -2; const didChange = untrackedValue !== this.$untrackedValue$; return didChange && (this.$untrackedValue$ = untrackedValue), didChange; } finally { ctx && (ctx.$effectSubscriber$ = previousEffectSubscription); } } set value(_) { throw qError(47); } get value() { return super.value; } } class WrappedSignal extends SignalImpl { $args$; $func$; $funcStr$; $flags$; $hostElement$=null; $forceRunEffects$=!1; [_EFFECT_BACK_REF]=null; constructor(container, fn, args, fnStr, flags = 3) { super(container, NEEDS_COMPUTATION), this.$args$ = args, this.$func$ = fn, this.$funcStr$ = fnStr, this.$flags$ = flags; } $invalidate$() { this.$flags$ |= 1, this.$forceRunEffects$ = !1, this.$container$?.$scheduler$(7, this.$hostElement$, this); } force() { this.$flags$ |= 1, this.$forceRunEffects$ = !1, triggerEffects(this.$container$, this, this.$effects$); } get untrackedValue() { const didChange = this.$computeIfNeeded$(); return didChange && (this.$forceRunEffects$ = didChange), assertFalse(this.$untrackedValue$ === NEEDS_COMPUTATION, "Invalid state"), this.$untrackedValue$; } $computeIfNeeded$() { if (!(1 & this.$flags$)) { return !1; } const untrackedValue = trackSignal((() => this.$func$(...this.$args$)), this, ".", this.$container$); const didChange = untrackedValue !== this.$untrackedValue$; return didChange && (this.$untrackedValue$ = untrackedValue), didChange; } set value(_) { throw qError(48); } get value() { return super.value; } } class SerializerSignalImpl extends ComputedSignalImpl { constructor(container, argQrl) { super(container, argQrl); } $didInitialize$=!1; $computeIfNeeded$() { if (!(1 & this.$flags$)) { return !1; } throwIfQRLNotResolved(this.$computeQrl$); let arg = this.$computeQrl$.resolved; "function" == typeof arg && (arg = arg()); const {deserialize, initial} = arg; const update = arg.update; const currentValue = this.$untrackedValue$ === NEEDS_COMPUTATION ? initial : this.$untrackedValue$; const untrackedValue = trackSignal((() => this.$didInitialize$ ? update?.(currentValue) : deserialize(currentValue)), this, ".", this.$container$); const didChange = this.$didInitialize$ && "undefined" !== untrackedValue || untrackedValue !== this.$untrackedValue$; return this.$flags$ &= -2, this.$didInitialize$ = !0, didChange && (this.$untrackedValue$ = untrackedValue), didChange; } } const isSerializerObj = obj => "object" == typeof obj && null !== obj && "function" == typeof obj[SerializerSymbol]; const STORE_TARGET = Symbol("store.target"); const STORE_HANDLER = Symbol("store.handler"); const STORE_ALL_PROPS = Symbol("store.all"); const getStoreHandler = value => value[STORE_HANDLER]; const getStoreTarget = value => value?.[STORE_TARGET] || null; const unwrapStore = value => getStoreTarget(value) || value; const isStore = value => STORE_TARGET in value; function createStore(container, obj, flags) { return new Proxy(obj, new StoreHandler(flags, container || null)); } const getOrCreateStore = (obj, flags, container) => { if (isSerializableObject(obj) && container) { let store = container.$storeProxyMap$.get(obj); return store || (store = createStore(container, obj, flags), container.$storeProxyMap$.set(obj, store)), store; } return obj; }; class StoreHandler { $flags$; $container$; $effects$=null; constructor($flags$, $container$) { this.$flags$ = $flags$, this.$container$ = $container$; } toString() { return "[Store]"; } get(target, prop) { if ("symbol" == typeof prop) { return prop === STORE_TARGET ? target : prop === STORE_HANDLER ? this : target[prop]; } const ctx = tryGetInvokeContext(); const value = target[prop]; if (ctx) { if (null === this.$container$) { if (!ctx.$container$) { return value; } this.$container$ = ctx.$container$; } else { assertTrue(!ctx.$container$ || ctx.$container$ === this.$container$, "Do not use signals across containers"); } const effectSubscriber = ctx.$effectSubscriber$; effectSubscriber && addStoreEffect(target, Array.isArray(target) ? STORE_ALL_PROPS : prop, this, effectSubscriber); } if ("toString" === prop && value === Object.prototype.toString) { return this.toString; } return 1 & this.$flags$ && "object" == typeof value && null !== value && !Object.isFrozen(value) && !isStore(value) && !Object.isFrozen(target) ? getOrCreateStore(value, this.$flags$, this.$container$) : value; } set(target, prop, value) { if ("symbol" == typeof prop) { return target[prop] = value, !0; } const newValue = 1 & this.$flags$ ? unwrapStore(value) : value; if (prop in target) { newValue !== target[prop] && setNewValueAndTriggerEffects(prop, newValue, target, this); } else { setNewValueAndTriggerEffects(prop, newValue, target, this); } return !0; } deleteProperty(target, prop) { return "string" == typeof prop && delete target[prop] && (triggerEffects(this.$container$, this, getEffects(target, prop, this.$effects$)), !0); } has(target, prop) { if (prop === STORE_TARGET) { return !0; } if ("string" == typeof prop) { const ctx = tryGetInvokeContext(); if (ctx) { const effectSubscriber = ctx.$effectSubscriber$; effectSubscriber && addStoreEffect(target, Array.isArray(target) ? STORE_ALL_PROPS : prop, this, effectSubscriber); } } return Object.prototype.hasOwnProperty.call(target, prop); } ownKeys(target) { const ctx = tryGetInvokeContext(); const effectSubscriber = ctx?.$effectSubscriber$; return effectSubscriber && addStoreEffect(target, STORE_ALL_PROPS, this, effectSubscriber), Reflect.ownKeys(target); } getOwnPropertyDescriptor(target, prop) { const descriptor = Reflect.getOwnPropertyDescriptor(target, prop); return Array.isArray(target) || "symbol" == typeof prop || descriptor && !descriptor.configurable ? descriptor : { enumerable: !0, configurable: !0 }; } } function addStoreEffect(target, prop, store, effectSubscription) { const effectsMap = store.$effects$ ||= new Map; let effects = effectsMap.get(prop); effects || (effects = new Set, effectsMap.set(prop, effects)), ensureContainsSubscription(effects, effectSubscription), ensureContainsBackRef(effectSubscription, target), addQrlToSerializationCtx(effectSubscription, store.$container$); } function setNewValueAndTriggerEffects(prop, value, target, currentStore) { target[prop] = value, triggerEffects(currentStore.$container$, currentStore, getEffects(target, prop, currentStore.$effects$)); } function getEffects(target, prop, storeEffects) { let effectsToTrigger; if (storeEffects) { if (Array.isArray(target)) { for (const effects of storeEffects.values()) { effectsToTrigger ||= new Set; for (const effect of effects) { effectsToTrigger.add(effect); } } } else { effectsToTrigger = storeEffects.get(prop); } } const storeArrayValue = storeEffects?.get(STORE_ALL_PROPS); if (storeArrayValue) { effectsToTrigger ||= new Set; for (const effect of storeArrayValue) { effectsToTrigger.add(effect); } } return effectsToTrigger || null; } class BackRef { [_EFFECT_BACK_REF]=null; } function clearAllEffects(container, consumer) { vnode_isVNode(consumer) && vnode_isElementVNode(consumer) && ensureMaterialized(consumer); const effects = consumer[_EFFECT_BACK_REF]; if (effects) { for (const [, effect] of effects) { const backRefs = effect[2]; if (!backRefs) { return; } for (const producer of backRefs) { if (producer instanceof SignalImpl) { clearSignal(container, producer, effect); } else if (container.$storeProxyMap$.has(producer)) { const target = container.$storeProxyMap$.get(producer); clearStore(getStoreHandler(target), effect); } } } } } function clearSignal(container, producer, effect) { const effects = producer.$effects$; effects && effects.delete(effect), producer instanceof WrappedSignal && (producer.$hostElement$ = null, clearAllEffects(container, producer)); } function clearStore(producer, effect) { const effects = producer?.$effects$; if (effects) { for (const propEffects of effects.values()) { propEffects.delete(effect); } } } const useLexicalScope = () => { const context = getInvokeContext(); let qrl = context.$qrl$; if (qrl) { assertQrl(qrl), assertDefined(qrl.$captureRef$, "invoke: qrl $captureRef$ must be defined inside useLexicalScope()", qrl); } else { const el = context.$element$; assertDefined(el, "invoke: element must be defined inside useLexicalScope()", context); const containerElement = _getQContainerElement(el); assertDefined(containerElement, "invoke: cant find parent q:container of", el); qrl = getDomContainer(containerElement).parseQRL(decodeURIComponent(String(context.$url$))); } return qrl.$captureRef$; }; const useTaskQrl = qrl => { const {val, set, iCtx, i} = useSequentialScope(); if (val) { return; } assertQrl(qrl), set(1); const task = new Task(10, i, iCtx.$hostElement$, qrl, void 0, null); set(task); const promise = iCtx.$container$.$scheduler$(3, task); isPromise(promise) && promise.catch((() => {})); }; const runTask = (task, container, host) => { task.$flags$ &= -9, cleanupTask(task); const iCtx = newInvokeContext(container.$locale$, host, void 0, "qTask"); iCtx.$container$ = container; const taskFn = task.$qrl$.getFn(iCtx, (() => clearAllEffects(container, task))); let cleanupFns = null; const cleanup = fn => { "function" == typeof fn && (cleanupFns || (cleanupFns = [], task.$destroy$ = noSerialize((() => { task.$destroy$ = null, cleanupFns.forEach((fn => { try { fn(); } catch (err) { container.handleError(err, host); } })); }))), cleanupFns.push(fn)); }; const taskApi = { track: (obj, prop) => { const ctx = newInvokeContext(); return ctx.$effectSubscriber$ = getSubscriber(task, ":"), ctx.$container$ = container, invoke(ctx, (() => { if (isFunction(obj)) { return obj(); } if (prop) { return obj[prop]; } if (isSignal(obj)) { return obj.value; } if (isStore(obj)) { return addStoreEffect(getStoreTarget(obj), STORE_ALL_PROPS, getStoreHandler(obj), ctx.$effectSubscriber$), obj; } throw qError(2); })); }, cleanup }; return safeCall((() => taskFn(taskApi)), cleanup, (err => { if (isPromise(err)) { return err.then((() => runTask(task, container, host))); } throw err; })); }; const cleanupTask = task => { const destroy = task.$destroy$; if (destroy) { task.$destroy$ = null; try { destroy(); } catch (err) { logError(err); } } }; class Task extends BackRef { $flags$; $index$; $el$; $qrl$; $state$; $destroy$; constructor($flags$, $index$, $el$, $qrl$, $state$, $destroy$) { super(), this.$flags$ = $flags$, this.$index$ = $index$, this.$el$ = $el$, this.$qrl$ = $qrl$, this.$state$ = $state$, this.$destroy$ = $destroy$; } } const isTask = value => value instanceof Task; const scheduleTask = (_event, element) => { const [task] = useLexicalScope(); const type = 1 & task.$flags$ ? 32 : 3; getDomContainer(element).$scheduler$(type, task); }; const styleContent = styleId => "⚡️" + styleId; function hasClassAttr(props) { for (const key in props) { if (Object.prototype.hasOwnProperty.call(props, key) && isClassAttr(key)) { return !0; } } return !1; } function isClassAttr(key) { return "class" === key || "className" === key; } function convertScopedStyleIdsToArray(scopedStyleIds) { return scopedStyleIds?.split(" ") ?? null; } function convertStyleIdsToString(scopedStyleIds) { return Array.from(scopedStyleIds).join(" "); } const addComponentStylePrefix = styleId => { if (styleId) { let idx = 0; do { styleId = styleId.substring(0, idx) + styleContent(styleId.substring(idx)); } while (0 !== (idx = styleId.indexOf(" ", idx) + 1)); } return styleId || null; }; const DEBUG_TYPE = "q:type"; const START = ""; const END = ""; const VirtualTypeName = { V: "Virtual", F: "Fragment", S: "Signal", A: "Awaited", C: "Component", I: "InlineComponent", P: "Projection" }; const mapApp_findIndx = (array, key, start) => { assertTrue(start % 2 == 0, "Expecting even number."); let bottom = start >> 1; let top = array.length - 2 >> 1; for (;bottom <= top; ) { const mid = bottom + (top - bottom >> 1); const midKey = array[mid << 1]; if (midKey === key) { return mid << 1; } midKey < key ? bottom = mid + 1 : top = mid - 1; } return ~(bottom << 1); }; const mapArray_set = (array, key, value, start) => { const indx = mapApp_findIndx(array, key, start); indx >= 0 ? null == value ? array.splice(indx, 2) : array[indx + 1] = value : null != value && array.splice(~indx, 0, key, value); }; const mapArray_get = (array, key, start) => { const indx = mapApp_findIndx(array, key, start); return indx >= 0 ? array[indx + 1] : null; }; const isForeignObjectElement = elementName => isDev ? "foreignobject" === elementName.toLowerCase() : "foreignObject" === elementName; const isSvgElement = elementName => "svg" === elementName || isForeignObjectElement(elementName); const isMathElement = elementName => "math" === elementName; const vnode_isDefaultNamespace = vnode => !(192 & vnode[0]); const vnode_getElementNamespaceFlags = element => { switch (fastNamespaceURI(element)) { case SVG_NS: return 64; case MATH_NS: return 128; default: return 0; } }; function vnode_getDomChildrenWithCorrectNamespacesToInsert(journal, domParentVNode, newChild) { const {elementNamespace, elementNamespaceFlag} = getNewElementNamespaceData(domParentVNode, newChild); let domChildren = []; if (elementNamespace === HTML_NS) { domChildren = vnode_getDOMChildNodes(journal, newChild); } else { const children = vnode_getDOMChildNodes(journal, newChild, !0); for (let i = 0; i < children.length; i++) { const childVNode = children[i]; if (vnode_isTextVNode(childVNode)) { domChildren.push(childVNode[4]); continue; } if ((192 & childVNode[0]) == (192 & domParentVNode[0])) { domChildren.push(childVNode[6]); continue; } const newChildElement = vnode_cloneElementWithNamespace(childVNode, domParentVNode, elementNamespace, elementNamespaceFlag); newChildElement && domChildren.push(newChildElement); } } return domChildren; } function cloneElementWithNamespace(element, elementName, namespace) { const newElement = element.ownerDocument.createElementNS(namespace, elementName); const attributes = element.attributes; for (const attribute of attributes) { const name = attribute.name; name && ":" !== name && newElement.setAttribute(name, attribute.value); } return newElement; } function vnode_cloneElementWithNamespace(elementVNode, parentVNode, namespace, namespaceFlag) { ensureElementVNode(elementVNode); let vCursor = elementVNode; let vParent = null; let rootElement = null; let parentElement = null; for (;vCursor; ) { let childElement = null; let newChildElement = null; if (vnode_isElementVNode(vCursor)) { childElement = vCursor[6]; const childElementTag = vnode_getElementName(vCursor); const vCursorParent = vnode_getParent(vCursor); const vCursorDomParent = null == rootElement ? parentVNode : vCursorParent && vnode_getDomParentVNode(vCursorParent); if (vCursorDomParent) { const namespaceData = getNewElementNamespaceData(vCursorDomParent, vnode_getElementName(vCursor)); namespace = namespaceData.elementNamespace, namespaceFlag = namespaceData.elementNamespaceFlag; } newChildElement = cloneElementWithNamespace(childElement, childElementTag, namespace), childElement.remove(), null == rootElement && (rootElement = newChildElement), parentElement && parentElement.appendChild(newChildElement); const vFirstChild = vnode_getFirstChild(vCursor); if (vCursor[6] = newChildElement, vCursor[0] &= -193, vCursor[0] |= namespaceFlag, vFirstChild) { vCursor = vFirstChild, parentElement = newChildElement; continue; } if (shouldIgnoreChildren(childElement)) { const container = getDomContainerFromQContainerElement(childElement); if (container) { const innerContainerFirstVNode = vnode_getFirstChild(container.rootVNode); if (innerContainerFirstVNode) { vCursor = innerContainerFirstVNode, parentElement = newChildElement; continue; } } } } if (vCursor === elementVNode) { return rootElement; } const vNextSibling = vnode_getNextSibling(vCursor); if (vNextSibling) { vCursor = vNextSibling; } else { for (vParent = vnode_getParent(vCursor); vParent; ) { if (vParent === elementVNode) { return rootElement; } const vNextParentSibling = vnode_getNextSibling(vParent); if (vNextParentSibling) { return vCursor = vNextParentSibling, rootElement; } vParent = vnode_getParent(vParent); } if (null == vParent) { return rootElement; } } } return rootElement; } function isSvg(tagOrVNode) { return "string" == typeof tagOrVNode ? isSvgElement(tagOrVNode) : !!(64 & tagOrVNode[0]); } function isMath(tagOrVNode) { return "string" == typeof tagOrVNode ? isMathElement(tagOrVNode) : !!(128 & tagOrVNode[0]); } function getNewElementNamespaceData(domParentVNode, tagOrVNode) { const parentIsDefaultNamespace = !domParentVNode || !!vnode_getElementName(domParentVNode) && vnode_isDefaultNamespace(domParentVNode); const parentIsForeignObject = !parentIsDefaultNamespace && isForeignObjectElement(vnode_getElementName(domParentVNode)); let elementNamespace = HTML_NS; let elementNamespaceFlag = 0; const isElementVNodeOrString = "string" == typeof tagOrVNode || vnode_isElementVNode(tagOrVNode); if (isElementVNodeOrString && isSvg(tagOrVNode)) { elementNamespace = SVG_NS, elementNamespaceFlag = 64; } else if (isElementVNodeOrString && isMath(tagOrVNode)) { elementNamespace = MATH_NS, elementNamespaceFlag = 128; } else if (domParentVNode && !parentIsForeignObject && !parentIsDefaultNamespace) { elementNamespace = !!(64 & domParentVNode[0]) ? SVG_NS : !!(128 & domParentVNode[0]) ? MATH_NS : HTML_NS, elementNamespaceFlag = 192 & domParentVNode[0]; } return { elementNamespace, elementNamespaceFlag }; } const executeComponent = (container, renderHost, subscriptionHost, componentQRL, props) => { const iCtx = newInvokeContext(container.$locale$, subscriptionHost || void 0, void 0, "qRender"); let componentFn; subscriptionHost && (iCtx.$effectSubscriber$ = getSubscriber(subscriptionHost, ":"), iCtx.$container$ = container), container.ensureProjectionResolved(renderHost); let isInlineComponent = !1; if (null === componentQRL && assertDefined(componentQRL = container.getHostProp(renderHost, "q:renderFn"), "No Component found at this location"), isQrl$1(componentQRL)) { (props = props || container.getHostProp(renderHost, "q:props") || EMPTY_OBJ).children && delete props.children, componentFn = componentQRL.getFn(iCtx); } else if (isQwikComponent(componentQRL)) { const qComponentFn = componentQRL; componentFn = () => invokeApply(iCtx, qComponentFn, [ props || EMPTY_OBJ, null, 0 ]); } else { isInlineComponent = !0; const inlineComponent = componentQRL; componentFn = () => invokeApply(iCtx, inlineComponent, [ props || EMPTY_OBJ ]); } const executeComponentWithPromiseExceptionRetry = (retryCount = 0) => safeCall((() => (isInlineComponent || (container.setHostProp(renderHost, "q:seqIdx", null), container.setHostProp(renderHost, ":onIdx", null), container.setHostProp(renderHost, "q:props", props)), vnode_isVNode(renderHost) && clearAllEffects(container, renderHost), componentFn(props))), (jsx => { const useOnEvents = container.getHostProp(renderHost, ":on"); return useOnEvents ? addUseOnEvents(jsx, useOnEvents) : jsx; }), (err => { if (isPromise(err) && retryCount < 100) { return err.then((() => executeComponentWithPromiseExceptionRetry(retryCount++))); } throw err; })); return executeComponentWithPromiseExceptionRetry(); }; function addUseOnEvents(jsx, useOnEvents) { const jsxElement = findFirstStringJSX(jsx); let jsxResult = jsx; return maybeThen(jsxElement, (jsxElement => { let isInvisibleComponent = !1; jsxElement || (isInvisibleComponent = !0); for (const key in useOnEvents) { if (Object.prototype.hasOwnProperty.call(useOnEvents, key)) { if (isInvisibleComponent) { if ("onQvisible$" === key) { const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult); jsxResult = jsx, jsxElement && addUseOnEvent(jsxElement, "document:onQinit$", useOnEvents[key]); } else if (key.startsWith("document:") || key.startsWith("window:")) { const [jsxElement, jsx] = addScriptNodeForInvisibleComponents(jsxResult); jsxResult = jsx, jsxElement && addUseOnEvent(jsxElement, key, useOnEvents[key]); } else { isDev && logWarn('You are trying to add an event "' + key + '" using `useOn` hook, but a node to which you can add an event is not found. Please make sure that the component has a valid element node. '); } } else { jsxElement && addUseOnEvent(jsxElement, key, useOnEvents[key]); } } } return jsxResult; })); } function addUseOnEvent(jsxElement, key, value) { let props = jsxElement.props; props === EMPTY_OBJ && (props = jsxElement.props = {}); let propValue = props[key]; void 0 === propValue ? propValue = [] : Array.isArray(propValue) || (propValue = [ propValue ]), propValue.push(...value), props[key] = propValue; } function findFirstStringJSX(jsx) { const queue = [ jsx ]; for (;queue.length; ) { const jsx = queue.shift(); if (isJSXNode(jsx)) { if ("string" == typeof jsx.type) { return jsx; } queue.push(jsx.children); } else if (Array.isArray(jsx)) { queue.push(...jsx); } else { if (isPromise(jsx)) { return maybeThen(jsx, (jsx => findFirstStringJSX(jsx))); } if (isSignal(jsx)) { return findFirstStringJSX(untrack((() => jsx.value))); } } } return null; } function addScriptNodeForInvisibleComponents(jsx) { if (isJSXNode(jsx)) { const jsxElement = new JSXNodeImpl("script", {}, { type: "placeholder", hidden: "" }, null, 3); return jsx.type === Slot ? [ jsxElement, _jsxSorted(Fragment, null, null, [ jsx, jsxElement ], 0, null) ] : (null == jsx.children ? jsx.children = jsxElement : Array.isArray(jsx.children) ? jsx.children.push(jsxElement) : jsx.children = [ jsx.children, jsxElement ], [ jsxElement, jsx ]); } if (Array.isArray(jsx) && jsx.length) { const [jsxElement, _] = addScriptNodeForInvisibleComponents(jsx[0]); return [ jsxElement, jsx ]; } return [ null, null ]; } const _CONST_PROPS = Symbol("CONST"); const _VAR_PROPS = Symbol("VAR"); const _IMMUTABLE = Symbol("IMMUTABLE"); function isSlotProp(prop) { return !prop.startsWith("q:") && !prop.startsWith(":"); } const _restProps = (props, omit, target = {}) => { let constPropsTarget = null; const constProps = props[_CONST_PROPS]; if (constProps) { for (const key in constProps) { omit.includes(key) || (constPropsTarget ||= {}, constPropsTarget[key] = constProps[key]); } } const varPropsTarget = target; const varProps = props[_VAR_PROPS]; for (const key in varProps) { omit.includes(key) || (varPropsTarget[key] = varProps[key]); } return createPropsProxy(varPropsTarget, constPropsTarget); }; function escapeHTML(html) { let escapedHTML = ""; const length = html.length; let idx = 0; let lastIdx = idx; for (;idx < length; idx++) { const ch = html.charCodeAt(idx); if (60 === ch) { escapedHTML += html.substring(lastIdx, idx) + "&lt;"; } else if (62 === ch) { escapedHTML += html.substring(lastIdx, idx) + "&gt;"; } else if (38 === ch) { escapedHTML += html.substring(lastIdx, idx) + "&amp;"; } else if (34 === ch) { escapedHTML += html.substring(lastIdx, idx) + "&quot;"; } else { if (39 !== ch) { continue; } escapedHTML += html.substring(lastIdx, idx) + "&#39;"; } lastIdx = idx + 1; } return 0 === lastIdx ? html : escapedHTML + html.substring(lastIdx); } const unitlessNumbers = new Set([ "animationIterationCount", "aspectRatio", "borderImageOutset", "borderImageSlice", "borderImageWidth", "boxFlex",