| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257 |
- import { clsx as clsx$1 } from "clsx";
- import * as devalue from "devalue";
- var is_array = Array.isArray;
- var index_of = Array.prototype.indexOf;
- var includes = Array.prototype.includes;
- var array_from = Array.from;
- var define_property = Object.defineProperty;
- var get_descriptor = Object.getOwnPropertyDescriptor;
- var object_prototype = Object.prototype;
- var array_prototype = Array.prototype;
- var get_prototype_of = Object.getPrototypeOf;
- var is_extensible = Object.isExtensible;
- var has_own_property = Object.prototype.hasOwnProperty;
- const noop = () => {
- };
- function run_all(arr) {
- for (var i = 0; i < arr.length; i++) {
- arr[i]();
- }
- }
- function deferred() {
- var resolve;
- var reject;
- var promise = new Promise((res, rej) => {
- resolve = res;
- reject = rej;
- });
- return { promise, resolve, reject };
- }
- const DERIVED = 1 << 1;
- const EFFECT = 1 << 2;
- const RENDER_EFFECT = 1 << 3;
- const MANAGED_EFFECT = 1 << 24;
- const BLOCK_EFFECT = 1 << 4;
- const BRANCH_EFFECT = 1 << 5;
- const ROOT_EFFECT = 1 << 6;
- const BOUNDARY_EFFECT = 1 << 7;
- const CONNECTED = 1 << 9;
- const CLEAN = 1 << 10;
- const DIRTY = 1 << 11;
- const MAYBE_DIRTY = 1 << 12;
- const INERT = 1 << 13;
- const DESTROYED = 1 << 14;
- const REACTION_RAN = 1 << 15;
- const DESTROYING = 1 << 25;
- const EFFECT_TRANSPARENT = 1 << 16;
- const EAGER_EFFECT = 1 << 17;
- const HEAD_EFFECT = 1 << 18;
- const EFFECT_PRESERVED = 1 << 19;
- const USER_EFFECT = 1 << 20;
- const WAS_MARKED = 1 << 16;
- const REACTION_IS_UPDATING = 1 << 21;
- const ASYNC = 1 << 22;
- const ERROR_VALUE = 1 << 23;
- const STATE_SYMBOL = Symbol("$state");
- const LEGACY_PROPS = Symbol("legacy props");
- const STALE_REACTION = new class StaleReactionError extends Error {
- name = "StaleReactionError";
- message = "The reaction that called `getAbortSignal()` was re-run or destroyed";
- }();
- const COMMENT_NODE = 8;
- function lifecycle_outside_component(name) {
- {
- throw new Error(`https://svelte.dev/e/lifecycle_outside_component`);
- }
- }
- const HYDRATION_START = "[";
- const HYDRATION_START_ELSE = "[!";
- const HYDRATION_START_FAILED = "[?";
- const HYDRATION_END = "]";
- const HYDRATION_ERROR = {};
- const ELEMENT_IS_NAMESPACED = 1;
- const ELEMENT_PRESERVE_ATTRIBUTE_CASE = 1 << 1;
- const ELEMENT_IS_INPUT = 1 << 2;
- const UNINITIALIZED = Symbol();
- const DOM_BOOLEAN_ATTRIBUTES = [
- "allowfullscreen",
- "async",
- "autofocus",
- "autoplay",
- "checked",
- "controls",
- "default",
- "disabled",
- "formnovalidate",
- "indeterminate",
- "inert",
- "ismap",
- "loop",
- "multiple",
- "muted",
- "nomodule",
- "novalidate",
- "open",
- "playsinline",
- "readonly",
- "required",
- "reversed",
- "seamless",
- "selected",
- "webkitdirectory",
- "defer",
- "disablepictureinpicture",
- "disableremoteplayback"
- ];
- function is_boolean_attribute(name) {
- return DOM_BOOLEAN_ATTRIBUTES.includes(name);
- }
- const PASSIVE_EVENTS = ["touchstart", "touchmove"];
- function is_passive_event(name) {
- return PASSIVE_EVENTS.includes(name);
- }
- const ATTR_REGEX = /[&"<]/g;
- const CONTENT_REGEX = /[&<]/g;
- function escape_html(value, is_attr) {
- const str = String(value ?? "");
- const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX;
- pattern.lastIndex = 0;
- let escaped = "";
- let last = 0;
- while (pattern.test(str)) {
- const i = pattern.lastIndex - 1;
- const ch = str[i];
- escaped += str.substring(last, i) + (ch === "&" ? "&" : ch === '"' ? """ : "<");
- last = i + 1;
- }
- return escaped + str.substring(last);
- }
- const replacements = {
- translate: /* @__PURE__ */ new Map([
- [true, "yes"],
- [false, "no"]
- ])
- };
- function attr(name, value, is_boolean = false) {
- if (name === "hidden" && value !== "until-found") {
- is_boolean = true;
- }
- if (value == null || !value && is_boolean) return "";
- const normalized = has_own_property.call(replacements, name) && replacements[name].get(value) || value;
- const assignment = is_boolean ? `=""` : `="${escape_html(normalized, true)}"`;
- return ` ${name}${assignment}`;
- }
- function clsx(value) {
- if (typeof value === "object") {
- return clsx$1(value);
- } else {
- return value ?? "";
- }
- }
- const whitespace = [..." \n\r\f \v\uFEFF"];
- function to_class(value, hash, directives) {
- var classname = value == null ? "" : "" + value;
- if (hash) {
- classname = classname ? classname + " " + hash : hash;
- }
- if (directives) {
- for (var key of Object.keys(directives)) {
- if (directives[key]) {
- classname = classname ? classname + " " + key : key;
- } else if (classname.length) {
- var len = key.length;
- var a = 0;
- while ((a = classname.indexOf(key, a)) >= 0) {
- var b = a + len;
- if ((a === 0 || whitespace.includes(classname[a - 1])) && (b === classname.length || whitespace.includes(classname[b]))) {
- classname = (a === 0 ? "" : classname.substring(0, a)) + classname.substring(b + 1);
- } else {
- a = b;
- }
- }
- }
- }
- }
- return classname === "" ? null : classname;
- }
- function append_styles(styles, important = false) {
- var separator = important ? " !important;" : ";";
- var css = "";
- for (var key of Object.keys(styles)) {
- var value = styles[key];
- if (value != null && value !== "") {
- css += " " + key + ": " + value + separator;
- }
- }
- return css;
- }
- function to_css_name(name) {
- if (name[0] !== "-" || name[1] !== "-") {
- return name.toLowerCase();
- }
- return name;
- }
- function to_style(value, styles) {
- if (styles) {
- var new_style = "";
- var normal_styles;
- var important_styles;
- if (Array.isArray(styles)) {
- normal_styles = styles[0];
- important_styles = styles[1];
- } else {
- normal_styles = styles;
- }
- if (value) {
- value = String(value).replaceAll(/\s*\/\*.*?\*\/\s*/g, "").trim();
- var in_str = false;
- var in_apo = 0;
- var in_comment = false;
- var reserved_names = [];
- if (normal_styles) {
- reserved_names.push(...Object.keys(normal_styles).map(to_css_name));
- }
- if (important_styles) {
- reserved_names.push(...Object.keys(important_styles).map(to_css_name));
- }
- var start_index = 0;
- var name_index = -1;
- const len = value.length;
- for (var i = 0; i < len; i++) {
- var c = value[i];
- if (in_comment) {
- if (c === "/" && value[i - 1] === "*") {
- in_comment = false;
- }
- } else if (in_str) {
- if (in_str === c) {
- in_str = false;
- }
- } else if (c === "/" && value[i + 1] === "*") {
- in_comment = true;
- } else if (c === '"' || c === "'") {
- in_str = c;
- } else if (c === "(") {
- in_apo++;
- } else if (c === ")") {
- in_apo--;
- }
- if (!in_comment && in_str === false && in_apo === 0) {
- if (c === ":" && name_index === -1) {
- name_index = i;
- } else if (c === ";" || i === len - 1) {
- if (name_index !== -1) {
- var name = to_css_name(value.substring(start_index, name_index).trim());
- if (!reserved_names.includes(name)) {
- if (c !== ";") {
- i++;
- }
- var property = value.substring(start_index, i).trim();
- new_style += " " + property + ";";
- }
- }
- start_index = i + 1;
- name_index = -1;
- }
- }
- }
- }
- if (normal_styles) {
- new_style += append_styles(normal_styles);
- }
- if (important_styles) {
- new_style += append_styles(important_styles, true);
- }
- new_style = new_style.trim();
- return new_style === "" ? null : new_style;
- }
- return value == null ? null : String(value);
- }
- const BLOCK_OPEN = `<!--${HYDRATION_START}-->`;
- const BLOCK_CLOSE = `<!--${HYDRATION_END}-->`;
- let controller = null;
- function abort() {
- controller?.abort(STALE_REACTION);
- controller = null;
- }
- function await_invalid() {
- const error = new Error(`await_invalid
- Encountered asynchronous work while rendering synchronously.
- https://svelte.dev/e/await_invalid`);
- error.name = "Svelte error";
- throw error;
- }
- function invalid_csp() {
- const error = new Error(`invalid_csp
- \`csp.nonce\` was set while \`csp.hash\` was \`true\`. These options cannot be used simultaneously.
- https://svelte.dev/e/invalid_csp`);
- error.name = "Svelte error";
- throw error;
- }
- function server_context_required() {
- const error = new Error(`server_context_required
- Could not resolve \`render\` context.
- https://svelte.dev/e/server_context_required`);
- error.name = "Svelte error";
- throw error;
- }
- var ssr_context = null;
- function set_ssr_context(v) {
- ssr_context = v;
- }
- function getContext(key) {
- const context_map = get_or_init_context_map();
- const result = (
- /** @type {T} */
- context_map.get(key)
- );
- return result;
- }
- function setContext(key, context) {
- get_or_init_context_map().set(key, context);
- return context;
- }
- function get_or_init_context_map(name) {
- if (ssr_context === null) {
- lifecycle_outside_component();
- }
- return ssr_context.c ??= new Map(get_parent_context(ssr_context) || void 0);
- }
- function push(fn) {
- ssr_context = { p: ssr_context, c: null, r: null };
- }
- function pop() {
- ssr_context = /** @type {SSRContext} */
- ssr_context.p;
- }
- function get_parent_context(ssr_context2) {
- let parent = ssr_context2.p;
- while (parent !== null) {
- const context_map = parent.c;
- if (context_map !== null) {
- return context_map;
- }
- parent = parent.p;
- }
- return null;
- }
- function unresolved_hydratable(key, stack) {
- {
- console.warn(`https://svelte.dev/e/unresolved_hydratable`);
- }
- }
- function get_render_context() {
- const store = als?.getStore();
- {
- server_context_required();
- }
- return store;
- }
- let als = null;
- let text_encoder;
- let crypto;
- const obfuscated_import = (module_name) => import(
- /* @vite-ignore */
- module_name
- );
- async function sha256(data) {
- text_encoder ??= new TextEncoder();
- crypto ??= globalThis.crypto?.subtle?.digest ? globalThis.crypto : (
- // @ts-ignore - we don't install node types in the prod build
- // don't use import('node:crypto') directly because static analysers will think we rely on node when we don't
- (await obfuscated_import("node:crypto")).webcrypto
- );
- const hash_buffer = await crypto.subtle.digest("SHA-256", text_encoder.encode(data));
- return base64_encode(hash_buffer);
- }
- function base64_encode(bytes) {
- if (globalThis.Buffer) {
- return globalThis.Buffer.from(bytes).toString("base64");
- }
- let binary = "";
- for (let i = 0; i < bytes.length; i++) {
- binary += String.fromCharCode(bytes[i]);
- }
- return btoa(binary);
- }
- class Renderer {
- /**
- * The contents of the renderer.
- * @type {RendererItem[]}
- */
- #out = [];
- /**
- * Any `onDestroy` callbacks registered during execution of this renderer.
- * @type {(() => void)[] | undefined}
- */
- #on_destroy = void 0;
- /**
- * Whether this renderer is a component body.
- * @type {boolean}
- */
- #is_component_body = false;
- /**
- * If set, this renderer is an error boundary. When async collection
- * of the children fails, the failed snippet is rendered instead.
- * @type {{
- * failed: (renderer: Renderer, error: unknown, reset: () => void) => void;
- * transformError: (error: unknown) => unknown;
- * context: SSRContext | null;
- * } | null}
- */
- #boundary = null;
- /**
- * The type of string content that this renderer is accumulating.
- * @type {RendererType}
- */
- type;
- /** @type {Renderer | undefined} */
- #parent;
- /**
- * Asynchronous work associated with this renderer
- * @type {Promise<void> | undefined}
- */
- promise = void 0;
- /**
- * State which is associated with the content tree as a whole.
- * It will be re-exposed, uncopied, on all children.
- * @type {SSRState}
- * @readonly
- */
- global;
- /**
- * State that is local to the branch it is declared in.
- * It will be shallow-copied to all children.
- *
- * @type {{ select_value: string | undefined }}
- */
- local;
- /**
- * @param {SSRState} global
- * @param {Renderer | undefined} [parent]
- */
- constructor(global, parent) {
- this.#parent = parent;
- this.global = global;
- this.local = parent ? { ...parent.local } : { select_value: void 0 };
- this.type = parent ? parent.type : "body";
- }
- /**
- * @param {(renderer: Renderer) => void} fn
- */
- head(fn) {
- const head = new Renderer(this.global, this);
- head.type = "head";
- this.#out.push(head);
- head.child(fn);
- }
- /**
- * @param {Array<Promise<void>>} blockers
- * @param {(renderer: Renderer) => void} fn
- */
- async_block(blockers, fn) {
- this.#out.push(BLOCK_OPEN);
- this.async(blockers, fn);
- this.#out.push(BLOCK_CLOSE);
- }
- /**
- * @param {Array<Promise<void>>} blockers
- * @param {(renderer: Renderer) => void} fn
- */
- async(blockers, fn) {
- let callback = fn;
- if (blockers.length > 0) {
- const context = ssr_context;
- callback = (renderer) => {
- return Promise.all(blockers).then(() => {
- const previous_context = ssr_context;
- try {
- set_ssr_context(context);
- return fn(renderer);
- } finally {
- set_ssr_context(previous_context);
- }
- });
- };
- }
- this.child(callback);
- }
- /**
- * @param {Array<() => void>} thunks
- */
- run(thunks) {
- const context = ssr_context;
- let promise = Promise.resolve(thunks[0]());
- const promises = [promise];
- for (const fn of thunks.slice(1)) {
- promise = promise.then(() => {
- const previous_context = ssr_context;
- set_ssr_context(context);
- try {
- return fn();
- } finally {
- set_ssr_context(previous_context);
- }
- });
- promises.push(promise);
- }
- promise.catch(noop);
- this.promise = promise;
- return promises;
- }
- /**
- * @param {(renderer: Renderer) => MaybePromise<void>} fn
- */
- child_block(fn) {
- this.#out.push(BLOCK_OPEN);
- this.child(fn);
- this.#out.push(BLOCK_CLOSE);
- }
- /**
- * Create a child renderer. The child renderer inherits the state from the parent,
- * but has its own content.
- * @param {(renderer: Renderer) => MaybePromise<void>} fn
- */
- child(fn) {
- const child = new Renderer(this.global, this);
- this.#out.push(child);
- const parent = ssr_context;
- set_ssr_context({
- ...ssr_context,
- p: parent,
- c: null,
- r: child
- });
- const result = fn(child);
- set_ssr_context(parent);
- if (result instanceof Promise) {
- result.catch(noop);
- result.finally(() => set_ssr_context(null)).catch(noop);
- if (child.global.mode === "sync") {
- await_invalid();
- }
- child.promise = result;
- }
- return child;
- }
- /**
- * Render children inside an error boundary. If the children throw and the API-level
- * `transformError` transform handles the error (doesn't re-throw), the `failed` snippet is
- * rendered instead. Otherwise the error propagates.
- *
- * @param {{ failed?: (renderer: Renderer, error: unknown, reset: () => void) => void }} props
- * @param {(renderer: Renderer) => MaybePromise<void>} children_fn
- */
- boundary(props, children_fn) {
- const child = new Renderer(this.global, this);
- this.#out.push(child);
- const parent_context = ssr_context;
- if (props.failed) {
- child.#boundary = {
- failed: props.failed,
- transformError: this.global.transformError,
- context: parent_context
- };
- }
- set_ssr_context({
- ...ssr_context,
- p: parent_context,
- c: null,
- r: child
- });
- try {
- const result = children_fn(child);
- set_ssr_context(parent_context);
- if (result instanceof Promise) {
- if (child.global.mode === "sync") {
- await_invalid();
- }
- result.catch(noop);
- child.promise = result;
- }
- } catch (error) {
- set_ssr_context(parent_context);
- const failed_snippet = props.failed;
- if (!failed_snippet) throw error;
- const result = this.global.transformError(error);
- child.#out.length = 0;
- child.#boundary = null;
- if (result instanceof Promise) {
- if (this.global.mode === "sync") {
- await_invalid();
- }
- child.promise = /** @type {Promise<unknown>} */
- result.then((transformed) => {
- set_ssr_context(parent_context);
- child.#out.push(Renderer.#serialize_failed_boundary(transformed));
- failed_snippet(child, transformed, noop);
- child.#out.push(BLOCK_CLOSE);
- });
- child.promise.catch(noop);
- } else {
- child.#out.push(Renderer.#serialize_failed_boundary(result));
- failed_snippet(child, result, noop);
- child.#out.push(BLOCK_CLOSE);
- }
- }
- }
- /**
- * Create a component renderer. The component renderer inherits the state from the parent,
- * but has its own content. It is treated as an ordering boundary for ondestroy callbacks.
- * @param {(renderer: Renderer) => MaybePromise<void>} fn
- * @param {Function} [component_fn]
- * @returns {void}
- */
- component(fn, component_fn) {
- push();
- const child = this.child(fn);
- child.#is_component_body = true;
- pop();
- }
- /**
- * @param {Record<string, any>} attrs
- * @param {(renderer: Renderer) => void} fn
- * @param {string | undefined} [css_hash]
- * @param {Record<string, boolean> | undefined} [classes]
- * @param {Record<string, string> | undefined} [styles]
- * @param {number | undefined} [flags]
- * @param {boolean | undefined} [is_rich]
- * @returns {void}
- */
- select(attrs, fn, css_hash, classes, styles, flags, is_rich) {
- const { value, ...select_attrs } = attrs;
- this.push(`<select${attributes(select_attrs, css_hash, classes, styles, flags)}>`);
- this.child((renderer) => {
- renderer.local.select_value = value;
- fn(renderer);
- });
- this.push(`${is_rich ? "<!>" : ""}</select>`);
- }
- /**
- * @param {Record<string, any>} attrs
- * @param {string | number | boolean | ((renderer: Renderer) => void)} body
- * @param {string | undefined} [css_hash]
- * @param {Record<string, boolean> | undefined} [classes]
- * @param {Record<string, string> | undefined} [styles]
- * @param {number | undefined} [flags]
- * @param {boolean | undefined} [is_rich]
- */
- option(attrs, body, css_hash, classes, styles, flags, is_rich) {
- this.#out.push(`<option${attributes(attrs, css_hash, classes, styles, flags)}`);
- const close = (renderer, value, { head, body: body2 }) => {
- if (has_own_property.call(attrs, "value")) {
- value = attrs.value;
- }
- if (value === this.local.select_value) {
- renderer.#out.push(' selected=""');
- }
- renderer.#out.push(`>${body2}${is_rich ? "<!>" : ""}</option>`);
- if (head) {
- renderer.head((child) => child.push(head));
- }
- };
- if (typeof body === "function") {
- this.child((renderer) => {
- const r = new Renderer(this.global, this);
- body(r);
- if (this.global.mode === "async") {
- return r.#collect_content_async().then((content) => {
- close(renderer, content.body.replaceAll("<!---->", ""), content);
- });
- } else {
- const content = r.#collect_content();
- close(renderer, content.body.replaceAll("<!---->", ""), content);
- }
- });
- } else {
- close(this, body, { body: escape_html(body) });
- }
- }
- /**
- * @param {(renderer: Renderer) => void} fn
- */
- title(fn) {
- const path = this.get_path();
- const close = (head) => {
- this.global.set_title(head, path);
- };
- this.child((renderer) => {
- const r = new Renderer(renderer.global, renderer);
- fn(r);
- if (renderer.global.mode === "async") {
- return r.#collect_content_async().then((content) => {
- close(content.head);
- });
- } else {
- const content = r.#collect_content();
- close(content.head);
- }
- });
- }
- /**
- * @param {string | (() => Promise<string>)} content
- */
- push(content) {
- if (typeof content === "function") {
- this.child(async (renderer) => renderer.push(await content()));
- } else {
- this.#out.push(content);
- }
- }
- /**
- * @param {() => void} fn
- */
- on_destroy(fn) {
- (this.#on_destroy ??= []).push(fn);
- }
- /**
- * @returns {number[]}
- */
- get_path() {
- return this.#parent ? [...this.#parent.get_path(), this.#parent.#out.indexOf(this)] : [];
- }
- /**
- * @deprecated this is needed for legacy component bindings
- */
- copy() {
- const copy = new Renderer(this.global, this.#parent);
- copy.#out = this.#out.map((item) => item instanceof Renderer ? item.copy() : item);
- copy.promise = this.promise;
- return copy;
- }
- /**
- * @param {Renderer} other
- * @deprecated this is needed for legacy component bindings
- */
- subsume(other) {
- if (this.global.mode !== other.global.mode) {
- throw new Error(
- "invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
- );
- }
- this.local = other.local;
- this.#out = other.#out.map((item, i) => {
- const current = this.#out[i];
- if (current instanceof Renderer && item instanceof Renderer) {
- current.subsume(item);
- return current;
- }
- return item;
- });
- this.promise = other.promise;
- this.type = other.type;
- }
- get length() {
- return this.#out.length;
- }
- /**
- * Creates the hydration comment that marks the start of a failed boundary.
- * The error is JSON-serialized and embedded inside an HTML comment for the client
- * to parse during hydration. The JSON is escaped to prevent `-->` or `<!--` sequences
- * from breaking out of the comment (XSS). Uses unicode escapes which `JSON.parse()`
- * handles transparently.
- * @param {unknown} error
- * @returns {string}
- */
- static #serialize_failed_boundary(error) {
- var json = JSON.stringify(error);
- var escaped = json.replace(/>/g, "\\u003e").replace(/</g, "\\u003c");
- return `<!--${HYDRATION_START_FAILED}${escaped}-->`;
- }
- /**
- * Only available on the server and when compiling with the `server` option.
- * Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app.
- * @template {Record<string, any>} Props
- * @param {Component<Props>} component
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} [options]
- * @returns {RenderOutput}
- */
- static render(component, options = {}) {
- let sync;
- const result = (
- /** @type {RenderOutput} */
- {}
- );
- Object.defineProperties(result, {
- html: {
- get: () => {
- return (sync ??= Renderer.#render(component, options)).body;
- }
- },
- head: {
- get: () => {
- return (sync ??= Renderer.#render(component, options)).head;
- }
- },
- body: {
- get: () => {
- return (sync ??= Renderer.#render(component, options)).body;
- }
- },
- hashes: {
- value: {
- script: ""
- }
- },
- then: {
- value: (
- /**
- * this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
- *
- * @template TResult1
- * @template [TResult2=never]
- * @param { (value: SyncRenderOutput) => TResult1 } onfulfilled
- * @param { (reason: unknown) => TResult2 } onrejected
- */
- (onfulfilled, onrejected) => {
- {
- const result2 = sync ??= Renderer.#render(component, options);
- const user_result = onfulfilled({
- head: result2.head,
- body: result2.body,
- html: result2.body,
- hashes: { script: [] }
- });
- return Promise.resolve(user_result);
- }
- }
- )
- }
- });
- return result;
- }
- /**
- * Collect all of the `onDestroy` callbacks registered during rendering. In an async context, this is only safe to call
- * after awaiting `collect_async`.
- *
- * Child renderers are "porous" and don't affect execution order, but component body renderers
- * create ordering boundaries. Within a renderer, callbacks run in order until hitting a component boundary.
- * @returns {Iterable<() => void>}
- */
- *#collect_on_destroy() {
- for (const component of this.#traverse_components()) {
- yield* component.#collect_ondestroy();
- }
- }
- /**
- * Performs a depth-first search of renderers, yielding the deepest components first, then additional components as we backtrack up the tree.
- * @returns {Iterable<Renderer>}
- */
- *#traverse_components() {
- for (const child of this.#out) {
- if (typeof child !== "string") {
- yield* child.#traverse_components();
- }
- }
- if (this.#is_component_body) {
- yield this;
- }
- }
- /**
- * @returns {Iterable<() => void>}
- */
- *#collect_ondestroy() {
- if (this.#on_destroy) {
- for (const fn of this.#on_destroy) {
- yield fn;
- }
- }
- for (const child of this.#out) {
- if (child instanceof Renderer && !child.#is_component_body) {
- yield* child.#collect_ondestroy();
- }
- }
- }
- /**
- * Render a component. Throws if any of the children are performing asynchronous work.
- *
- * @template {Record<string, any>} Props
- * @param {Component<Props>} component
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
- * @returns {AccumulatedContent}
- */
- static #render(component, options) {
- var previous_context = ssr_context;
- try {
- const renderer = Renderer.#open_render("sync", component, options);
- const content = renderer.#collect_content();
- return Renderer.#close_render(content, renderer);
- } finally {
- abort();
- set_ssr_context(previous_context);
- }
- }
- /**
- * Render a component.
- *
- * @template {Record<string, any>} Props
- * @param {Component<Props>} component
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} options
- * @returns {Promise<AccumulatedContent & { hashes: { script: Sha256Source[] } }>}
- */
- static async #render_async(component, options) {
- const previous_context = ssr_context;
- try {
- const renderer = Renderer.#open_render("async", component, options);
- const content = await renderer.#collect_content_async();
- const hydratables = await renderer.#collect_hydratables();
- if (hydratables !== null) {
- content.head = hydratables + content.head;
- }
- return Renderer.#close_render(content, renderer);
- } finally {
- set_ssr_context(previous_context);
- abort();
- }
- }
- /**
- * Collect all of the code from the `out` array and return it as a string, or a promise resolving to a string.
- * @param {AccumulatedContent} content
- * @returns {AccumulatedContent}
- */
- #collect_content(content = { head: "", body: "" }) {
- for (const item of this.#out) {
- if (typeof item === "string") {
- content[this.type] += item;
- } else if (item instanceof Renderer) {
- item.#collect_content(content);
- }
- }
- return content;
- }
- /**
- * Collect all of the code from the `out` array and return it as a string.
- * @param {AccumulatedContent} content
- * @returns {Promise<AccumulatedContent>}
- */
- async #collect_content_async(content = { head: "", body: "" }) {
- await this.promise;
- for (const item of this.#out) {
- if (typeof item === "string") {
- content[this.type] += item;
- } else if (item instanceof Renderer) {
- if (item.#boundary) {
- const boundary_content = { head: "", body: "" };
- try {
- await item.#collect_content_async(boundary_content);
- content.head += boundary_content.head;
- content.body += boundary_content.body;
- } catch (error) {
- const { context, failed, transformError } = item.#boundary;
- set_ssr_context(context);
- let transformed = await transformError(error);
- const failed_renderer = new Renderer(item.global, item);
- failed_renderer.type = item.type;
- failed_renderer.#out.push(Renderer.#serialize_failed_boundary(transformed));
- failed(failed_renderer, transformed, noop);
- failed_renderer.#out.push(BLOCK_CLOSE);
- await failed_renderer.#collect_content_async(content);
- }
- } else {
- await item.#collect_content_async(content);
- }
- }
- }
- return content;
- }
- async #collect_hydratables() {
- const ctx = get_render_context().hydratable;
- for (const [_, key] of ctx.unresolved_promises) {
- unresolved_hydratable(key, ctx.lookup.get(key)?.stack ?? "<missing stack trace>");
- }
- for (const comparison of ctx.comparisons) {
- await comparison;
- }
- return await this.#hydratable_block(ctx);
- }
- /**
- * @template {Record<string, any>} Props
- * @param {'sync' | 'async'} mode
- * @param {import('svelte').Component<Props>} component
- * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp; transformError?: (error: unknown) => unknown }} options
- * @returns {Renderer}
- */
- static #open_render(mode, component, options) {
- var previous_context = ssr_context;
- try {
- const renderer = new Renderer(
- new SSRState(
- mode,
- options.idPrefix ? options.idPrefix + "-" : "",
- options.csp,
- options.transformError
- )
- );
- const context = { p: null, c: options.context ?? null, r: renderer };
- set_ssr_context(context);
- renderer.push(BLOCK_OPEN);
- component(renderer, options.props ?? {});
- renderer.push(BLOCK_CLOSE);
- return renderer;
- } finally {
- set_ssr_context(previous_context);
- }
- }
- /**
- * @param {AccumulatedContent} content
- * @param {Renderer} renderer
- * @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }}
- */
- static #close_render(content, renderer) {
- for (const cleanup of renderer.#collect_on_destroy()) {
- cleanup();
- }
- let head = content.head + renderer.global.get_title();
- let body = content.body;
- for (const { hash, code } of renderer.global.css) {
- head += `<style id="${hash}">${code}</style>`;
- }
- return {
- head,
- body,
- hashes: {
- script: renderer.global.csp.script_hashes
- }
- };
- }
- /**
- * @param {HydratableContext} ctx
- */
- async #hydratable_block(ctx) {
- if (ctx.lookup.size === 0) {
- return null;
- }
- let entries = [];
- let has_promises = false;
- for (const [k, v] of ctx.lookup) {
- if (v.promises) {
- has_promises = true;
- for (const p of v.promises) await p;
- }
- entries.push(`[${devalue.uneval(k)},${v.serialized}]`);
- }
- let prelude = `const h = (window.__svelte ??= {}).h ??= new Map();`;
- if (has_promises) {
- prelude = `const r = (v) => Promise.resolve(v);
- ${prelude}`;
- }
- const body = `
- {
- ${prelude}
- for (const [k, v] of [
- ${entries.join(",\n ")}
- ]) {
- h.set(k, v);
- }
- }
- `;
- let csp_attr = "";
- if (this.global.csp.nonce) {
- csp_attr = ` nonce="${this.global.csp.nonce}"`;
- } else if (this.global.csp.hash) {
- const hash = await sha256(body);
- this.global.csp.script_hashes.push(`sha256-${hash}`);
- }
- return `
- <script${csp_attr}>${body}<\/script>`;
- }
- }
- class SSRState {
- /** @readonly @type {Csp & { script_hashes: Sha256Source[] }} */
- csp;
- /** @readonly @type {'sync' | 'async'} */
- mode;
- /** @readonly @type {() => string} */
- uid;
- /** @readonly @type {Set<{ hash: string; code: string }>} */
- css = /* @__PURE__ */ new Set();
- /**
- * `transformError` passed to `render`. Called when an error boundary catches an error.
- * Throws by default if unset in `render`.
- * @type {(error: unknown) => unknown}
- */
- transformError;
- /** @type {{ path: number[], value: string }} */
- #title = { path: [], value: "" };
- /**
- * @param {'sync' | 'async'} mode
- * @param {string} id_prefix
- * @param {Csp} csp
- * @param {((error: unknown) => unknown) | undefined} [transformError]
- */
- constructor(mode, id_prefix = "", csp = { hash: false }, transformError) {
- this.mode = mode;
- this.csp = { ...csp, script_hashes: [] };
- this.transformError = transformError ?? ((error) => {
- throw error;
- });
- let uid = 1;
- this.uid = () => `${id_prefix}s${uid++}`;
- }
- get_title() {
- return this.#title.value;
- }
- /**
- * Performs a depth-first (lexicographic) comparison using the path. Rejects sets
- * from earlier than or equal to the current value.
- * @param {string} value
- * @param {number[]} path
- */
- set_title(value, path) {
- const current = this.#title.path;
- let i = 0;
- let l = Math.min(path.length, current.length);
- while (i < l && path[i] === current[i]) i += 1;
- if (path[i] === void 0) return;
- if (current[i] === void 0 || path[i] > current[i]) {
- this.#title.path = path;
- this.#title.value = value;
- }
- }
- }
- const INVALID_ATTR_NAME_CHAR_REGEX = /[\s'">/=\u{FDD0}-\u{FDEF}\u{FFFE}\u{FFFF}\u{1FFFE}\u{1FFFF}\u{2FFFE}\u{2FFFF}\u{3FFFE}\u{3FFFF}\u{4FFFE}\u{4FFFF}\u{5FFFE}\u{5FFFF}\u{6FFFE}\u{6FFFF}\u{7FFFE}\u{7FFFF}\u{8FFFE}\u{8FFFF}\u{9FFFE}\u{9FFFF}\u{AFFFE}\u{AFFFF}\u{BFFFE}\u{BFFFF}\u{CFFFE}\u{CFFFF}\u{DFFFE}\u{DFFFF}\u{EFFFE}\u{EFFFF}\u{FFFFE}\u{FFFFF}\u{10FFFE}\u{10FFFF}]/u;
- function render(component, options = {}) {
- if (options.csp?.hash && options.csp.nonce) {
- invalid_csp();
- }
- return Renderer.render(
- /** @type {Component<Props>} */
- component,
- options
- );
- }
- function attributes(attrs, css_hash, classes, styles, flags = 0) {
- if (styles) {
- attrs.style = to_style(attrs.style, styles);
- }
- if (attrs.class) {
- attrs.class = clsx(attrs.class);
- }
- if (css_hash || classes) {
- attrs.class = to_class(attrs.class, css_hash, classes);
- }
- let attr_str = "";
- let name;
- const is_html = (flags & ELEMENT_IS_NAMESPACED) === 0;
- const lowercase = (flags & ELEMENT_PRESERVE_ATTRIBUTE_CASE) === 0;
- const is_input = (flags & ELEMENT_IS_INPUT) !== 0;
- for (name of Object.keys(attrs)) {
- if (typeof attrs[name] === "function") continue;
- if (name[0] === "$" && name[1] === "$") continue;
- if (INVALID_ATTR_NAME_CHAR_REGEX.test(name)) continue;
- var value = attrs[name];
- var lower = name.toLowerCase();
- if (lowercase) name = lower;
- if (lower.length > 2 && lower.startsWith("on")) continue;
- if (is_input) {
- if (name === "defaultvalue" || name === "defaultchecked") {
- name = name === "defaultvalue" ? "value" : "checked";
- if (attrs[name]) continue;
- }
- }
- attr_str += attr(name, value, is_html && is_boolean_attribute(name));
- }
- return attr_str;
- }
- function stringify(value) {
- return typeof value === "string" ? value : value == null ? "" : value + "";
- }
- function attr_class(value, hash, directives) {
- var result = to_class(value, hash, directives);
- return result ? ` class="${escape_html(result, true)}"` : "";
- }
- function attr_style(value, directives) {
- var result = to_style(value, directives);
- return result ? ` style="${escape_html(result, true)}"` : "";
- }
- function ensure_array_like(array_like_or_iterator) {
- if (array_like_or_iterator) {
- return array_like_or_iterator.length !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator);
- }
- return [];
- }
- function once(get_value) {
- let value = (
- /** @type {V} */
- UNINITIALIZED
- );
- return () => {
- if (value === UNINITIALIZED) {
- value = get_value();
- }
- return value;
- };
- }
- function derived(fn) {
- const get_value = ssr_context === null ? fn : once(fn);
- let updated_value;
- return function(new_value) {
- if (arguments.length === 0) {
- return updated_value ?? get_value();
- }
- updated_value = new_value;
- return updated_value;
- };
- }
- export {
- derived as $,
- ASYNC as A,
- BOUNDARY_EFFECT as B,
- COMMENT_NODE as C,
- DIRTY as D,
- ERROR_VALUE as E,
- get_descriptor as F,
- get_prototype_of as G,
- HYDRATION_ERROR as H,
- INERT as I,
- is_array as J,
- is_extensible as K,
- HEAD_EFFECT as L,
- MAYBE_DIRTY as M,
- DESTROYING as N,
- USER_EFFECT as O,
- REACTION_IS_UPDATING as P,
- index_of as Q,
- REACTION_RAN as R,
- STALE_REACTION as S,
- define_property as T,
- UNINITIALIZED as U,
- array_from as V,
- WAS_MARKED as W,
- is_passive_event as X,
- LEGACY_PROPS as Y,
- render as Z,
- setContext as _,
- HYDRATION_END as a,
- attr_class as a0,
- attr_style as a1,
- ensure_array_like as a2,
- attr as a3,
- stringify as a4,
- HYDRATION_START as b,
- HYDRATION_START_ELSE as c,
- EFFECT as d,
- escape_html as e,
- CONNECTED as f,
- getContext as g,
- CLEAN as h,
- DERIVED as i,
- BLOCK_EFFECT as j,
- DESTROYED as k,
- EAGER_EFFECT as l,
- deferred as m,
- noop as n,
- RENDER_EFFECT as o,
- MANAGED_EFFECT as p,
- ROOT_EFFECT as q,
- run_all as r,
- BRANCH_EFFECT as s,
- includes as t,
- HYDRATION_START_FAILED as u,
- EFFECT_TRANSPARENT as v,
- EFFECT_PRESERVED as w,
- STATE_SYMBOL as x,
- object_prototype as y,
- array_prototype as z
- };
|