index.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257
  1. import { clsx as clsx$1 } from "clsx";
  2. import * as devalue from "devalue";
  3. var is_array = Array.isArray;
  4. var index_of = Array.prototype.indexOf;
  5. var includes = Array.prototype.includes;
  6. var array_from = Array.from;
  7. var define_property = Object.defineProperty;
  8. var get_descriptor = Object.getOwnPropertyDescriptor;
  9. var object_prototype = Object.prototype;
  10. var array_prototype = Array.prototype;
  11. var get_prototype_of = Object.getPrototypeOf;
  12. var is_extensible = Object.isExtensible;
  13. var has_own_property = Object.prototype.hasOwnProperty;
  14. const noop = () => {
  15. };
  16. function run_all(arr) {
  17. for (var i = 0; i < arr.length; i++) {
  18. arr[i]();
  19. }
  20. }
  21. function deferred() {
  22. var resolve;
  23. var reject;
  24. var promise = new Promise((res, rej) => {
  25. resolve = res;
  26. reject = rej;
  27. });
  28. return { promise, resolve, reject };
  29. }
  30. const DERIVED = 1 << 1;
  31. const EFFECT = 1 << 2;
  32. const RENDER_EFFECT = 1 << 3;
  33. const MANAGED_EFFECT = 1 << 24;
  34. const BLOCK_EFFECT = 1 << 4;
  35. const BRANCH_EFFECT = 1 << 5;
  36. const ROOT_EFFECT = 1 << 6;
  37. const BOUNDARY_EFFECT = 1 << 7;
  38. const CONNECTED = 1 << 9;
  39. const CLEAN = 1 << 10;
  40. const DIRTY = 1 << 11;
  41. const MAYBE_DIRTY = 1 << 12;
  42. const INERT = 1 << 13;
  43. const DESTROYED = 1 << 14;
  44. const REACTION_RAN = 1 << 15;
  45. const DESTROYING = 1 << 25;
  46. const EFFECT_TRANSPARENT = 1 << 16;
  47. const EAGER_EFFECT = 1 << 17;
  48. const HEAD_EFFECT = 1 << 18;
  49. const EFFECT_PRESERVED = 1 << 19;
  50. const USER_EFFECT = 1 << 20;
  51. const WAS_MARKED = 1 << 16;
  52. const REACTION_IS_UPDATING = 1 << 21;
  53. const ASYNC = 1 << 22;
  54. const ERROR_VALUE = 1 << 23;
  55. const STATE_SYMBOL = Symbol("$state");
  56. const LEGACY_PROPS = Symbol("legacy props");
  57. const STALE_REACTION = new class StaleReactionError extends Error {
  58. name = "StaleReactionError";
  59. message = "The reaction that called `getAbortSignal()` was re-run or destroyed";
  60. }();
  61. const COMMENT_NODE = 8;
  62. function lifecycle_outside_component(name) {
  63. {
  64. throw new Error(`https://svelte.dev/e/lifecycle_outside_component`);
  65. }
  66. }
  67. const HYDRATION_START = "[";
  68. const HYDRATION_START_ELSE = "[!";
  69. const HYDRATION_START_FAILED = "[?";
  70. const HYDRATION_END = "]";
  71. const HYDRATION_ERROR = {};
  72. const ELEMENT_IS_NAMESPACED = 1;
  73. const ELEMENT_PRESERVE_ATTRIBUTE_CASE = 1 << 1;
  74. const ELEMENT_IS_INPUT = 1 << 2;
  75. const UNINITIALIZED = Symbol();
  76. const DOM_BOOLEAN_ATTRIBUTES = [
  77. "allowfullscreen",
  78. "async",
  79. "autofocus",
  80. "autoplay",
  81. "checked",
  82. "controls",
  83. "default",
  84. "disabled",
  85. "formnovalidate",
  86. "indeterminate",
  87. "inert",
  88. "ismap",
  89. "loop",
  90. "multiple",
  91. "muted",
  92. "nomodule",
  93. "novalidate",
  94. "open",
  95. "playsinline",
  96. "readonly",
  97. "required",
  98. "reversed",
  99. "seamless",
  100. "selected",
  101. "webkitdirectory",
  102. "defer",
  103. "disablepictureinpicture",
  104. "disableremoteplayback"
  105. ];
  106. function is_boolean_attribute(name) {
  107. return DOM_BOOLEAN_ATTRIBUTES.includes(name);
  108. }
  109. const PASSIVE_EVENTS = ["touchstart", "touchmove"];
  110. function is_passive_event(name) {
  111. return PASSIVE_EVENTS.includes(name);
  112. }
  113. const ATTR_REGEX = /[&"<]/g;
  114. const CONTENT_REGEX = /[&<]/g;
  115. function escape_html(value, is_attr) {
  116. const str = String(value ?? "");
  117. const pattern = is_attr ? ATTR_REGEX : CONTENT_REGEX;
  118. pattern.lastIndex = 0;
  119. let escaped = "";
  120. let last = 0;
  121. while (pattern.test(str)) {
  122. const i = pattern.lastIndex - 1;
  123. const ch = str[i];
  124. escaped += str.substring(last, i) + (ch === "&" ? "&amp;" : ch === '"' ? "&quot;" : "&lt;");
  125. last = i + 1;
  126. }
  127. return escaped + str.substring(last);
  128. }
  129. const replacements = {
  130. translate: /* @__PURE__ */ new Map([
  131. [true, "yes"],
  132. [false, "no"]
  133. ])
  134. };
  135. function attr(name, value, is_boolean = false) {
  136. if (name === "hidden" && value !== "until-found") {
  137. is_boolean = true;
  138. }
  139. if (value == null || !value && is_boolean) return "";
  140. const normalized = has_own_property.call(replacements, name) && replacements[name].get(value) || value;
  141. const assignment = is_boolean ? `=""` : `="${escape_html(normalized, true)}"`;
  142. return ` ${name}${assignment}`;
  143. }
  144. function clsx(value) {
  145. if (typeof value === "object") {
  146. return clsx$1(value);
  147. } else {
  148. return value ?? "";
  149. }
  150. }
  151. const whitespace = [..." \n\r\f \v\uFEFF"];
  152. function to_class(value, hash, directives) {
  153. var classname = value == null ? "" : "" + value;
  154. if (hash) {
  155. classname = classname ? classname + " " + hash : hash;
  156. }
  157. if (directives) {
  158. for (var key of Object.keys(directives)) {
  159. if (directives[key]) {
  160. classname = classname ? classname + " " + key : key;
  161. } else if (classname.length) {
  162. var len = key.length;
  163. var a = 0;
  164. while ((a = classname.indexOf(key, a)) >= 0) {
  165. var b = a + len;
  166. if ((a === 0 || whitespace.includes(classname[a - 1])) && (b === classname.length || whitespace.includes(classname[b]))) {
  167. classname = (a === 0 ? "" : classname.substring(0, a)) + classname.substring(b + 1);
  168. } else {
  169. a = b;
  170. }
  171. }
  172. }
  173. }
  174. }
  175. return classname === "" ? null : classname;
  176. }
  177. function append_styles(styles, important = false) {
  178. var separator = important ? " !important;" : ";";
  179. var css = "";
  180. for (var key of Object.keys(styles)) {
  181. var value = styles[key];
  182. if (value != null && value !== "") {
  183. css += " " + key + ": " + value + separator;
  184. }
  185. }
  186. return css;
  187. }
  188. function to_css_name(name) {
  189. if (name[0] !== "-" || name[1] !== "-") {
  190. return name.toLowerCase();
  191. }
  192. return name;
  193. }
  194. function to_style(value, styles) {
  195. if (styles) {
  196. var new_style = "";
  197. var normal_styles;
  198. var important_styles;
  199. if (Array.isArray(styles)) {
  200. normal_styles = styles[0];
  201. important_styles = styles[1];
  202. } else {
  203. normal_styles = styles;
  204. }
  205. if (value) {
  206. value = String(value).replaceAll(/\s*\/\*.*?\*\/\s*/g, "").trim();
  207. var in_str = false;
  208. var in_apo = 0;
  209. var in_comment = false;
  210. var reserved_names = [];
  211. if (normal_styles) {
  212. reserved_names.push(...Object.keys(normal_styles).map(to_css_name));
  213. }
  214. if (important_styles) {
  215. reserved_names.push(...Object.keys(important_styles).map(to_css_name));
  216. }
  217. var start_index = 0;
  218. var name_index = -1;
  219. const len = value.length;
  220. for (var i = 0; i < len; i++) {
  221. var c = value[i];
  222. if (in_comment) {
  223. if (c === "/" && value[i - 1] === "*") {
  224. in_comment = false;
  225. }
  226. } else if (in_str) {
  227. if (in_str === c) {
  228. in_str = false;
  229. }
  230. } else if (c === "/" && value[i + 1] === "*") {
  231. in_comment = true;
  232. } else if (c === '"' || c === "'") {
  233. in_str = c;
  234. } else if (c === "(") {
  235. in_apo++;
  236. } else if (c === ")") {
  237. in_apo--;
  238. }
  239. if (!in_comment && in_str === false && in_apo === 0) {
  240. if (c === ":" && name_index === -1) {
  241. name_index = i;
  242. } else if (c === ";" || i === len - 1) {
  243. if (name_index !== -1) {
  244. var name = to_css_name(value.substring(start_index, name_index).trim());
  245. if (!reserved_names.includes(name)) {
  246. if (c !== ";") {
  247. i++;
  248. }
  249. var property = value.substring(start_index, i).trim();
  250. new_style += " " + property + ";";
  251. }
  252. }
  253. start_index = i + 1;
  254. name_index = -1;
  255. }
  256. }
  257. }
  258. }
  259. if (normal_styles) {
  260. new_style += append_styles(normal_styles);
  261. }
  262. if (important_styles) {
  263. new_style += append_styles(important_styles, true);
  264. }
  265. new_style = new_style.trim();
  266. return new_style === "" ? null : new_style;
  267. }
  268. return value == null ? null : String(value);
  269. }
  270. const BLOCK_OPEN = `<!--${HYDRATION_START}-->`;
  271. const BLOCK_CLOSE = `<!--${HYDRATION_END}-->`;
  272. let controller = null;
  273. function abort() {
  274. controller?.abort(STALE_REACTION);
  275. controller = null;
  276. }
  277. function await_invalid() {
  278. const error = new Error(`await_invalid
  279. Encountered asynchronous work while rendering synchronously.
  280. https://svelte.dev/e/await_invalid`);
  281. error.name = "Svelte error";
  282. throw error;
  283. }
  284. function invalid_csp() {
  285. const error = new Error(`invalid_csp
  286. \`csp.nonce\` was set while \`csp.hash\` was \`true\`. These options cannot be used simultaneously.
  287. https://svelte.dev/e/invalid_csp`);
  288. error.name = "Svelte error";
  289. throw error;
  290. }
  291. function server_context_required() {
  292. const error = new Error(`server_context_required
  293. Could not resolve \`render\` context.
  294. https://svelte.dev/e/server_context_required`);
  295. error.name = "Svelte error";
  296. throw error;
  297. }
  298. var ssr_context = null;
  299. function set_ssr_context(v) {
  300. ssr_context = v;
  301. }
  302. function getContext(key) {
  303. const context_map = get_or_init_context_map();
  304. const result = (
  305. /** @type {T} */
  306. context_map.get(key)
  307. );
  308. return result;
  309. }
  310. function setContext(key, context) {
  311. get_or_init_context_map().set(key, context);
  312. return context;
  313. }
  314. function get_or_init_context_map(name) {
  315. if (ssr_context === null) {
  316. lifecycle_outside_component();
  317. }
  318. return ssr_context.c ??= new Map(get_parent_context(ssr_context) || void 0);
  319. }
  320. function push(fn) {
  321. ssr_context = { p: ssr_context, c: null, r: null };
  322. }
  323. function pop() {
  324. ssr_context = /** @type {SSRContext} */
  325. ssr_context.p;
  326. }
  327. function get_parent_context(ssr_context2) {
  328. let parent = ssr_context2.p;
  329. while (parent !== null) {
  330. const context_map = parent.c;
  331. if (context_map !== null) {
  332. return context_map;
  333. }
  334. parent = parent.p;
  335. }
  336. return null;
  337. }
  338. function unresolved_hydratable(key, stack) {
  339. {
  340. console.warn(`https://svelte.dev/e/unresolved_hydratable`);
  341. }
  342. }
  343. function get_render_context() {
  344. const store = als?.getStore();
  345. {
  346. server_context_required();
  347. }
  348. return store;
  349. }
  350. let als = null;
  351. let text_encoder;
  352. let crypto;
  353. const obfuscated_import = (module_name) => import(
  354. /* @vite-ignore */
  355. module_name
  356. );
  357. async function sha256(data) {
  358. text_encoder ??= new TextEncoder();
  359. crypto ??= globalThis.crypto?.subtle?.digest ? globalThis.crypto : (
  360. // @ts-ignore - we don't install node types in the prod build
  361. // don't use import('node:crypto') directly because static analysers will think we rely on node when we don't
  362. (await obfuscated_import("node:crypto")).webcrypto
  363. );
  364. const hash_buffer = await crypto.subtle.digest("SHA-256", text_encoder.encode(data));
  365. return base64_encode(hash_buffer);
  366. }
  367. function base64_encode(bytes) {
  368. if (globalThis.Buffer) {
  369. return globalThis.Buffer.from(bytes).toString("base64");
  370. }
  371. let binary = "";
  372. for (let i = 0; i < bytes.length; i++) {
  373. binary += String.fromCharCode(bytes[i]);
  374. }
  375. return btoa(binary);
  376. }
  377. class Renderer {
  378. /**
  379. * The contents of the renderer.
  380. * @type {RendererItem[]}
  381. */
  382. #out = [];
  383. /**
  384. * Any `onDestroy` callbacks registered during execution of this renderer.
  385. * @type {(() => void)[] | undefined}
  386. */
  387. #on_destroy = void 0;
  388. /**
  389. * Whether this renderer is a component body.
  390. * @type {boolean}
  391. */
  392. #is_component_body = false;
  393. /**
  394. * If set, this renderer is an error boundary. When async collection
  395. * of the children fails, the failed snippet is rendered instead.
  396. * @type {{
  397. * failed: (renderer: Renderer, error: unknown, reset: () => void) => void;
  398. * transformError: (error: unknown) => unknown;
  399. * context: SSRContext | null;
  400. * } | null}
  401. */
  402. #boundary = null;
  403. /**
  404. * The type of string content that this renderer is accumulating.
  405. * @type {RendererType}
  406. */
  407. type;
  408. /** @type {Renderer | undefined} */
  409. #parent;
  410. /**
  411. * Asynchronous work associated with this renderer
  412. * @type {Promise<void> | undefined}
  413. */
  414. promise = void 0;
  415. /**
  416. * State which is associated with the content tree as a whole.
  417. * It will be re-exposed, uncopied, on all children.
  418. * @type {SSRState}
  419. * @readonly
  420. */
  421. global;
  422. /**
  423. * State that is local to the branch it is declared in.
  424. * It will be shallow-copied to all children.
  425. *
  426. * @type {{ select_value: string | undefined }}
  427. */
  428. local;
  429. /**
  430. * @param {SSRState} global
  431. * @param {Renderer | undefined} [parent]
  432. */
  433. constructor(global, parent) {
  434. this.#parent = parent;
  435. this.global = global;
  436. this.local = parent ? { ...parent.local } : { select_value: void 0 };
  437. this.type = parent ? parent.type : "body";
  438. }
  439. /**
  440. * @param {(renderer: Renderer) => void} fn
  441. */
  442. head(fn) {
  443. const head = new Renderer(this.global, this);
  444. head.type = "head";
  445. this.#out.push(head);
  446. head.child(fn);
  447. }
  448. /**
  449. * @param {Array<Promise<void>>} blockers
  450. * @param {(renderer: Renderer) => void} fn
  451. */
  452. async_block(blockers, fn) {
  453. this.#out.push(BLOCK_OPEN);
  454. this.async(blockers, fn);
  455. this.#out.push(BLOCK_CLOSE);
  456. }
  457. /**
  458. * @param {Array<Promise<void>>} blockers
  459. * @param {(renderer: Renderer) => void} fn
  460. */
  461. async(blockers, fn) {
  462. let callback = fn;
  463. if (blockers.length > 0) {
  464. const context = ssr_context;
  465. callback = (renderer) => {
  466. return Promise.all(blockers).then(() => {
  467. const previous_context = ssr_context;
  468. try {
  469. set_ssr_context(context);
  470. return fn(renderer);
  471. } finally {
  472. set_ssr_context(previous_context);
  473. }
  474. });
  475. };
  476. }
  477. this.child(callback);
  478. }
  479. /**
  480. * @param {Array<() => void>} thunks
  481. */
  482. run(thunks) {
  483. const context = ssr_context;
  484. let promise = Promise.resolve(thunks[0]());
  485. const promises = [promise];
  486. for (const fn of thunks.slice(1)) {
  487. promise = promise.then(() => {
  488. const previous_context = ssr_context;
  489. set_ssr_context(context);
  490. try {
  491. return fn();
  492. } finally {
  493. set_ssr_context(previous_context);
  494. }
  495. });
  496. promises.push(promise);
  497. }
  498. promise.catch(noop);
  499. this.promise = promise;
  500. return promises;
  501. }
  502. /**
  503. * @param {(renderer: Renderer) => MaybePromise<void>} fn
  504. */
  505. child_block(fn) {
  506. this.#out.push(BLOCK_OPEN);
  507. this.child(fn);
  508. this.#out.push(BLOCK_CLOSE);
  509. }
  510. /**
  511. * Create a child renderer. The child renderer inherits the state from the parent,
  512. * but has its own content.
  513. * @param {(renderer: Renderer) => MaybePromise<void>} fn
  514. */
  515. child(fn) {
  516. const child = new Renderer(this.global, this);
  517. this.#out.push(child);
  518. const parent = ssr_context;
  519. set_ssr_context({
  520. ...ssr_context,
  521. p: parent,
  522. c: null,
  523. r: child
  524. });
  525. const result = fn(child);
  526. set_ssr_context(parent);
  527. if (result instanceof Promise) {
  528. result.catch(noop);
  529. result.finally(() => set_ssr_context(null)).catch(noop);
  530. if (child.global.mode === "sync") {
  531. await_invalid();
  532. }
  533. child.promise = result;
  534. }
  535. return child;
  536. }
  537. /**
  538. * Render children inside an error boundary. If the children throw and the API-level
  539. * `transformError` transform handles the error (doesn't re-throw), the `failed` snippet is
  540. * rendered instead. Otherwise the error propagates.
  541. *
  542. * @param {{ failed?: (renderer: Renderer, error: unknown, reset: () => void) => void }} props
  543. * @param {(renderer: Renderer) => MaybePromise<void>} children_fn
  544. */
  545. boundary(props, children_fn) {
  546. const child = new Renderer(this.global, this);
  547. this.#out.push(child);
  548. const parent_context = ssr_context;
  549. if (props.failed) {
  550. child.#boundary = {
  551. failed: props.failed,
  552. transformError: this.global.transformError,
  553. context: parent_context
  554. };
  555. }
  556. set_ssr_context({
  557. ...ssr_context,
  558. p: parent_context,
  559. c: null,
  560. r: child
  561. });
  562. try {
  563. const result = children_fn(child);
  564. set_ssr_context(parent_context);
  565. if (result instanceof Promise) {
  566. if (child.global.mode === "sync") {
  567. await_invalid();
  568. }
  569. result.catch(noop);
  570. child.promise = result;
  571. }
  572. } catch (error) {
  573. set_ssr_context(parent_context);
  574. const failed_snippet = props.failed;
  575. if (!failed_snippet) throw error;
  576. const result = this.global.transformError(error);
  577. child.#out.length = 0;
  578. child.#boundary = null;
  579. if (result instanceof Promise) {
  580. if (this.global.mode === "sync") {
  581. await_invalid();
  582. }
  583. child.promise = /** @type {Promise<unknown>} */
  584. result.then((transformed) => {
  585. set_ssr_context(parent_context);
  586. child.#out.push(Renderer.#serialize_failed_boundary(transformed));
  587. failed_snippet(child, transformed, noop);
  588. child.#out.push(BLOCK_CLOSE);
  589. });
  590. child.promise.catch(noop);
  591. } else {
  592. child.#out.push(Renderer.#serialize_failed_boundary(result));
  593. failed_snippet(child, result, noop);
  594. child.#out.push(BLOCK_CLOSE);
  595. }
  596. }
  597. }
  598. /**
  599. * Create a component renderer. The component renderer inherits the state from the parent,
  600. * but has its own content. It is treated as an ordering boundary for ondestroy callbacks.
  601. * @param {(renderer: Renderer) => MaybePromise<void>} fn
  602. * @param {Function} [component_fn]
  603. * @returns {void}
  604. */
  605. component(fn, component_fn) {
  606. push();
  607. const child = this.child(fn);
  608. child.#is_component_body = true;
  609. pop();
  610. }
  611. /**
  612. * @param {Record<string, any>} attrs
  613. * @param {(renderer: Renderer) => void} fn
  614. * @param {string | undefined} [css_hash]
  615. * @param {Record<string, boolean> | undefined} [classes]
  616. * @param {Record<string, string> | undefined} [styles]
  617. * @param {number | undefined} [flags]
  618. * @param {boolean | undefined} [is_rich]
  619. * @returns {void}
  620. */
  621. select(attrs, fn, css_hash, classes, styles, flags, is_rich) {
  622. const { value, ...select_attrs } = attrs;
  623. this.push(`<select${attributes(select_attrs, css_hash, classes, styles, flags)}>`);
  624. this.child((renderer) => {
  625. renderer.local.select_value = value;
  626. fn(renderer);
  627. });
  628. this.push(`${is_rich ? "<!>" : ""}</select>`);
  629. }
  630. /**
  631. * @param {Record<string, any>} attrs
  632. * @param {string | number | boolean | ((renderer: Renderer) => void)} body
  633. * @param {string | undefined} [css_hash]
  634. * @param {Record<string, boolean> | undefined} [classes]
  635. * @param {Record<string, string> | undefined} [styles]
  636. * @param {number | undefined} [flags]
  637. * @param {boolean | undefined} [is_rich]
  638. */
  639. option(attrs, body, css_hash, classes, styles, flags, is_rich) {
  640. this.#out.push(`<option${attributes(attrs, css_hash, classes, styles, flags)}`);
  641. const close = (renderer, value, { head, body: body2 }) => {
  642. if (has_own_property.call(attrs, "value")) {
  643. value = attrs.value;
  644. }
  645. if (value === this.local.select_value) {
  646. renderer.#out.push(' selected=""');
  647. }
  648. renderer.#out.push(`>${body2}${is_rich ? "<!>" : ""}</option>`);
  649. if (head) {
  650. renderer.head((child) => child.push(head));
  651. }
  652. };
  653. if (typeof body === "function") {
  654. this.child((renderer) => {
  655. const r = new Renderer(this.global, this);
  656. body(r);
  657. if (this.global.mode === "async") {
  658. return r.#collect_content_async().then((content) => {
  659. close(renderer, content.body.replaceAll("<!---->", ""), content);
  660. });
  661. } else {
  662. const content = r.#collect_content();
  663. close(renderer, content.body.replaceAll("<!---->", ""), content);
  664. }
  665. });
  666. } else {
  667. close(this, body, { body: escape_html(body) });
  668. }
  669. }
  670. /**
  671. * @param {(renderer: Renderer) => void} fn
  672. */
  673. title(fn) {
  674. const path = this.get_path();
  675. const close = (head) => {
  676. this.global.set_title(head, path);
  677. };
  678. this.child((renderer) => {
  679. const r = new Renderer(renderer.global, renderer);
  680. fn(r);
  681. if (renderer.global.mode === "async") {
  682. return r.#collect_content_async().then((content) => {
  683. close(content.head);
  684. });
  685. } else {
  686. const content = r.#collect_content();
  687. close(content.head);
  688. }
  689. });
  690. }
  691. /**
  692. * @param {string | (() => Promise<string>)} content
  693. */
  694. push(content) {
  695. if (typeof content === "function") {
  696. this.child(async (renderer) => renderer.push(await content()));
  697. } else {
  698. this.#out.push(content);
  699. }
  700. }
  701. /**
  702. * @param {() => void} fn
  703. */
  704. on_destroy(fn) {
  705. (this.#on_destroy ??= []).push(fn);
  706. }
  707. /**
  708. * @returns {number[]}
  709. */
  710. get_path() {
  711. return this.#parent ? [...this.#parent.get_path(), this.#parent.#out.indexOf(this)] : [];
  712. }
  713. /**
  714. * @deprecated this is needed for legacy component bindings
  715. */
  716. copy() {
  717. const copy = new Renderer(this.global, this.#parent);
  718. copy.#out = this.#out.map((item) => item instanceof Renderer ? item.copy() : item);
  719. copy.promise = this.promise;
  720. return copy;
  721. }
  722. /**
  723. * @param {Renderer} other
  724. * @deprecated this is needed for legacy component bindings
  725. */
  726. subsume(other) {
  727. if (this.global.mode !== other.global.mode) {
  728. throw new Error(
  729. "invariant: A renderer cannot switch modes. If you're seeing this, there's a compiler bug. File an issue!"
  730. );
  731. }
  732. this.local = other.local;
  733. this.#out = other.#out.map((item, i) => {
  734. const current = this.#out[i];
  735. if (current instanceof Renderer && item instanceof Renderer) {
  736. current.subsume(item);
  737. return current;
  738. }
  739. return item;
  740. });
  741. this.promise = other.promise;
  742. this.type = other.type;
  743. }
  744. get length() {
  745. return this.#out.length;
  746. }
  747. /**
  748. * Creates the hydration comment that marks the start of a failed boundary.
  749. * The error is JSON-serialized and embedded inside an HTML comment for the client
  750. * to parse during hydration. The JSON is escaped to prevent `-->` or `<!--` sequences
  751. * from breaking out of the comment (XSS). Uses unicode escapes which `JSON.parse()`
  752. * handles transparently.
  753. * @param {unknown} error
  754. * @returns {string}
  755. */
  756. static #serialize_failed_boundary(error) {
  757. var json = JSON.stringify(error);
  758. var escaped = json.replace(/>/g, "\\u003e").replace(/</g, "\\u003c");
  759. return `<!--${HYDRATION_START_FAILED}${escaped}-->`;
  760. }
  761. /**
  762. * Only available on the server and when compiling with the `server` option.
  763. * 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.
  764. * @template {Record<string, any>} Props
  765. * @param {Component<Props>} component
  766. * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} [options]
  767. * @returns {RenderOutput}
  768. */
  769. static render(component, options = {}) {
  770. let sync;
  771. const result = (
  772. /** @type {RenderOutput} */
  773. {}
  774. );
  775. Object.defineProperties(result, {
  776. html: {
  777. get: () => {
  778. return (sync ??= Renderer.#render(component, options)).body;
  779. }
  780. },
  781. head: {
  782. get: () => {
  783. return (sync ??= Renderer.#render(component, options)).head;
  784. }
  785. },
  786. body: {
  787. get: () => {
  788. return (sync ??= Renderer.#render(component, options)).body;
  789. }
  790. },
  791. hashes: {
  792. value: {
  793. script: ""
  794. }
  795. },
  796. then: {
  797. value: (
  798. /**
  799. * this is not type-safe, but honestly it's the best I can do right now, and it's a straightforward function.
  800. *
  801. * @template TResult1
  802. * @template [TResult2=never]
  803. * @param { (value: SyncRenderOutput) => TResult1 } onfulfilled
  804. * @param { (reason: unknown) => TResult2 } onrejected
  805. */
  806. (onfulfilled, onrejected) => {
  807. {
  808. const result2 = sync ??= Renderer.#render(component, options);
  809. const user_result = onfulfilled({
  810. head: result2.head,
  811. body: result2.body,
  812. html: result2.body,
  813. hashes: { script: [] }
  814. });
  815. return Promise.resolve(user_result);
  816. }
  817. }
  818. )
  819. }
  820. });
  821. return result;
  822. }
  823. /**
  824. * Collect all of the `onDestroy` callbacks registered during rendering. In an async context, this is only safe to call
  825. * after awaiting `collect_async`.
  826. *
  827. * Child renderers are "porous" and don't affect execution order, but component body renderers
  828. * create ordering boundaries. Within a renderer, callbacks run in order until hitting a component boundary.
  829. * @returns {Iterable<() => void>}
  830. */
  831. *#collect_on_destroy() {
  832. for (const component of this.#traverse_components()) {
  833. yield* component.#collect_ondestroy();
  834. }
  835. }
  836. /**
  837. * Performs a depth-first search of renderers, yielding the deepest components first, then additional components as we backtrack up the tree.
  838. * @returns {Iterable<Renderer>}
  839. */
  840. *#traverse_components() {
  841. for (const child of this.#out) {
  842. if (typeof child !== "string") {
  843. yield* child.#traverse_components();
  844. }
  845. }
  846. if (this.#is_component_body) {
  847. yield this;
  848. }
  849. }
  850. /**
  851. * @returns {Iterable<() => void>}
  852. */
  853. *#collect_ondestroy() {
  854. if (this.#on_destroy) {
  855. for (const fn of this.#on_destroy) {
  856. yield fn;
  857. }
  858. }
  859. for (const child of this.#out) {
  860. if (child instanceof Renderer && !child.#is_component_body) {
  861. yield* child.#collect_ondestroy();
  862. }
  863. }
  864. }
  865. /**
  866. * Render a component. Throws if any of the children are performing asynchronous work.
  867. *
  868. * @template {Record<string, any>} Props
  869. * @param {Component<Props>} component
  870. * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string }} options
  871. * @returns {AccumulatedContent}
  872. */
  873. static #render(component, options) {
  874. var previous_context = ssr_context;
  875. try {
  876. const renderer = Renderer.#open_render("sync", component, options);
  877. const content = renderer.#collect_content();
  878. return Renderer.#close_render(content, renderer);
  879. } finally {
  880. abort();
  881. set_ssr_context(previous_context);
  882. }
  883. }
  884. /**
  885. * Render a component.
  886. *
  887. * @template {Record<string, any>} Props
  888. * @param {Component<Props>} component
  889. * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp }} options
  890. * @returns {Promise<AccumulatedContent & { hashes: { script: Sha256Source[] } }>}
  891. */
  892. static async #render_async(component, options) {
  893. const previous_context = ssr_context;
  894. try {
  895. const renderer = Renderer.#open_render("async", component, options);
  896. const content = await renderer.#collect_content_async();
  897. const hydratables = await renderer.#collect_hydratables();
  898. if (hydratables !== null) {
  899. content.head = hydratables + content.head;
  900. }
  901. return Renderer.#close_render(content, renderer);
  902. } finally {
  903. set_ssr_context(previous_context);
  904. abort();
  905. }
  906. }
  907. /**
  908. * Collect all of the code from the `out` array and return it as a string, or a promise resolving to a string.
  909. * @param {AccumulatedContent} content
  910. * @returns {AccumulatedContent}
  911. */
  912. #collect_content(content = { head: "", body: "" }) {
  913. for (const item of this.#out) {
  914. if (typeof item === "string") {
  915. content[this.type] += item;
  916. } else if (item instanceof Renderer) {
  917. item.#collect_content(content);
  918. }
  919. }
  920. return content;
  921. }
  922. /**
  923. * Collect all of the code from the `out` array and return it as a string.
  924. * @param {AccumulatedContent} content
  925. * @returns {Promise<AccumulatedContent>}
  926. */
  927. async #collect_content_async(content = { head: "", body: "" }) {
  928. await this.promise;
  929. for (const item of this.#out) {
  930. if (typeof item === "string") {
  931. content[this.type] += item;
  932. } else if (item instanceof Renderer) {
  933. if (item.#boundary) {
  934. const boundary_content = { head: "", body: "" };
  935. try {
  936. await item.#collect_content_async(boundary_content);
  937. content.head += boundary_content.head;
  938. content.body += boundary_content.body;
  939. } catch (error) {
  940. const { context, failed, transformError } = item.#boundary;
  941. set_ssr_context(context);
  942. let transformed = await transformError(error);
  943. const failed_renderer = new Renderer(item.global, item);
  944. failed_renderer.type = item.type;
  945. failed_renderer.#out.push(Renderer.#serialize_failed_boundary(transformed));
  946. failed(failed_renderer, transformed, noop);
  947. failed_renderer.#out.push(BLOCK_CLOSE);
  948. await failed_renderer.#collect_content_async(content);
  949. }
  950. } else {
  951. await item.#collect_content_async(content);
  952. }
  953. }
  954. }
  955. return content;
  956. }
  957. async #collect_hydratables() {
  958. const ctx = get_render_context().hydratable;
  959. for (const [_, key] of ctx.unresolved_promises) {
  960. unresolved_hydratable(key, ctx.lookup.get(key)?.stack ?? "<missing stack trace>");
  961. }
  962. for (const comparison of ctx.comparisons) {
  963. await comparison;
  964. }
  965. return await this.#hydratable_block(ctx);
  966. }
  967. /**
  968. * @template {Record<string, any>} Props
  969. * @param {'sync' | 'async'} mode
  970. * @param {import('svelte').Component<Props>} component
  971. * @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: Csp; transformError?: (error: unknown) => unknown }} options
  972. * @returns {Renderer}
  973. */
  974. static #open_render(mode, component, options) {
  975. var previous_context = ssr_context;
  976. try {
  977. const renderer = new Renderer(
  978. new SSRState(
  979. mode,
  980. options.idPrefix ? options.idPrefix + "-" : "",
  981. options.csp,
  982. options.transformError
  983. )
  984. );
  985. const context = { p: null, c: options.context ?? null, r: renderer };
  986. set_ssr_context(context);
  987. renderer.push(BLOCK_OPEN);
  988. component(renderer, options.props ?? {});
  989. renderer.push(BLOCK_CLOSE);
  990. return renderer;
  991. } finally {
  992. set_ssr_context(previous_context);
  993. }
  994. }
  995. /**
  996. * @param {AccumulatedContent} content
  997. * @param {Renderer} renderer
  998. * @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }}
  999. */
  1000. static #close_render(content, renderer) {
  1001. for (const cleanup of renderer.#collect_on_destroy()) {
  1002. cleanup();
  1003. }
  1004. let head = content.head + renderer.global.get_title();
  1005. let body = content.body;
  1006. for (const { hash, code } of renderer.global.css) {
  1007. head += `<style id="${hash}">${code}</style>`;
  1008. }
  1009. return {
  1010. head,
  1011. body,
  1012. hashes: {
  1013. script: renderer.global.csp.script_hashes
  1014. }
  1015. };
  1016. }
  1017. /**
  1018. * @param {HydratableContext} ctx
  1019. */
  1020. async #hydratable_block(ctx) {
  1021. if (ctx.lookup.size === 0) {
  1022. return null;
  1023. }
  1024. let entries = [];
  1025. let has_promises = false;
  1026. for (const [k, v] of ctx.lookup) {
  1027. if (v.promises) {
  1028. has_promises = true;
  1029. for (const p of v.promises) await p;
  1030. }
  1031. entries.push(`[${devalue.uneval(k)},${v.serialized}]`);
  1032. }
  1033. let prelude = `const h = (window.__svelte ??= {}).h ??= new Map();`;
  1034. if (has_promises) {
  1035. prelude = `const r = (v) => Promise.resolve(v);
  1036. ${prelude}`;
  1037. }
  1038. const body = `
  1039. {
  1040. ${prelude}
  1041. for (const [k, v] of [
  1042. ${entries.join(",\n ")}
  1043. ]) {
  1044. h.set(k, v);
  1045. }
  1046. }
  1047. `;
  1048. let csp_attr = "";
  1049. if (this.global.csp.nonce) {
  1050. csp_attr = ` nonce="${this.global.csp.nonce}"`;
  1051. } else if (this.global.csp.hash) {
  1052. const hash = await sha256(body);
  1053. this.global.csp.script_hashes.push(`sha256-${hash}`);
  1054. }
  1055. return `
  1056. <script${csp_attr}>${body}<\/script>`;
  1057. }
  1058. }
  1059. class SSRState {
  1060. /** @readonly @type {Csp & { script_hashes: Sha256Source[] }} */
  1061. csp;
  1062. /** @readonly @type {'sync' | 'async'} */
  1063. mode;
  1064. /** @readonly @type {() => string} */
  1065. uid;
  1066. /** @readonly @type {Set<{ hash: string; code: string }>} */
  1067. css = /* @__PURE__ */ new Set();
  1068. /**
  1069. * `transformError` passed to `render`. Called when an error boundary catches an error.
  1070. * Throws by default if unset in `render`.
  1071. * @type {(error: unknown) => unknown}
  1072. */
  1073. transformError;
  1074. /** @type {{ path: number[], value: string }} */
  1075. #title = { path: [], value: "" };
  1076. /**
  1077. * @param {'sync' | 'async'} mode
  1078. * @param {string} id_prefix
  1079. * @param {Csp} csp
  1080. * @param {((error: unknown) => unknown) | undefined} [transformError]
  1081. */
  1082. constructor(mode, id_prefix = "", csp = { hash: false }, transformError) {
  1083. this.mode = mode;
  1084. this.csp = { ...csp, script_hashes: [] };
  1085. this.transformError = transformError ?? ((error) => {
  1086. throw error;
  1087. });
  1088. let uid = 1;
  1089. this.uid = () => `${id_prefix}s${uid++}`;
  1090. }
  1091. get_title() {
  1092. return this.#title.value;
  1093. }
  1094. /**
  1095. * Performs a depth-first (lexicographic) comparison using the path. Rejects sets
  1096. * from earlier than or equal to the current value.
  1097. * @param {string} value
  1098. * @param {number[]} path
  1099. */
  1100. set_title(value, path) {
  1101. const current = this.#title.path;
  1102. let i = 0;
  1103. let l = Math.min(path.length, current.length);
  1104. while (i < l && path[i] === current[i]) i += 1;
  1105. if (path[i] === void 0) return;
  1106. if (current[i] === void 0 || path[i] > current[i]) {
  1107. this.#title.path = path;
  1108. this.#title.value = value;
  1109. }
  1110. }
  1111. }
  1112. 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;
  1113. function render(component, options = {}) {
  1114. if (options.csp?.hash && options.csp.nonce) {
  1115. invalid_csp();
  1116. }
  1117. return Renderer.render(
  1118. /** @type {Component<Props>} */
  1119. component,
  1120. options
  1121. );
  1122. }
  1123. function attributes(attrs, css_hash, classes, styles, flags = 0) {
  1124. if (styles) {
  1125. attrs.style = to_style(attrs.style, styles);
  1126. }
  1127. if (attrs.class) {
  1128. attrs.class = clsx(attrs.class);
  1129. }
  1130. if (css_hash || classes) {
  1131. attrs.class = to_class(attrs.class, css_hash, classes);
  1132. }
  1133. let attr_str = "";
  1134. let name;
  1135. const is_html = (flags & ELEMENT_IS_NAMESPACED) === 0;
  1136. const lowercase = (flags & ELEMENT_PRESERVE_ATTRIBUTE_CASE) === 0;
  1137. const is_input = (flags & ELEMENT_IS_INPUT) !== 0;
  1138. for (name of Object.keys(attrs)) {
  1139. if (typeof attrs[name] === "function") continue;
  1140. if (name[0] === "$" && name[1] === "$") continue;
  1141. if (INVALID_ATTR_NAME_CHAR_REGEX.test(name)) continue;
  1142. var value = attrs[name];
  1143. var lower = name.toLowerCase();
  1144. if (lowercase) name = lower;
  1145. if (lower.length > 2 && lower.startsWith("on")) continue;
  1146. if (is_input) {
  1147. if (name === "defaultvalue" || name === "defaultchecked") {
  1148. name = name === "defaultvalue" ? "value" : "checked";
  1149. if (attrs[name]) continue;
  1150. }
  1151. }
  1152. attr_str += attr(name, value, is_html && is_boolean_attribute(name));
  1153. }
  1154. return attr_str;
  1155. }
  1156. function stringify(value) {
  1157. return typeof value === "string" ? value : value == null ? "" : value + "";
  1158. }
  1159. function attr_class(value, hash, directives) {
  1160. var result = to_class(value, hash, directives);
  1161. return result ? ` class="${escape_html(result, true)}"` : "";
  1162. }
  1163. function attr_style(value, directives) {
  1164. var result = to_style(value, directives);
  1165. return result ? ` style="${escape_html(result, true)}"` : "";
  1166. }
  1167. function ensure_array_like(array_like_or_iterator) {
  1168. if (array_like_or_iterator) {
  1169. return array_like_or_iterator.length !== void 0 ? array_like_or_iterator : Array.from(array_like_or_iterator);
  1170. }
  1171. return [];
  1172. }
  1173. function once(get_value) {
  1174. let value = (
  1175. /** @type {V} */
  1176. UNINITIALIZED
  1177. );
  1178. return () => {
  1179. if (value === UNINITIALIZED) {
  1180. value = get_value();
  1181. }
  1182. return value;
  1183. };
  1184. }
  1185. function derived(fn) {
  1186. const get_value = ssr_context === null ? fn : once(fn);
  1187. let updated_value;
  1188. return function(new_value) {
  1189. if (arguments.length === 0) {
  1190. return updated_value ?? get_value();
  1191. }
  1192. updated_value = new_value;
  1193. return updated_value;
  1194. };
  1195. }
  1196. export {
  1197. derived as $,
  1198. ASYNC as A,
  1199. BOUNDARY_EFFECT as B,
  1200. COMMENT_NODE as C,
  1201. DIRTY as D,
  1202. ERROR_VALUE as E,
  1203. get_descriptor as F,
  1204. get_prototype_of as G,
  1205. HYDRATION_ERROR as H,
  1206. INERT as I,
  1207. is_array as J,
  1208. is_extensible as K,
  1209. HEAD_EFFECT as L,
  1210. MAYBE_DIRTY as M,
  1211. DESTROYING as N,
  1212. USER_EFFECT as O,
  1213. REACTION_IS_UPDATING as P,
  1214. index_of as Q,
  1215. REACTION_RAN as R,
  1216. STALE_REACTION as S,
  1217. define_property as T,
  1218. UNINITIALIZED as U,
  1219. array_from as V,
  1220. WAS_MARKED as W,
  1221. is_passive_event as X,
  1222. LEGACY_PROPS as Y,
  1223. render as Z,
  1224. setContext as _,
  1225. HYDRATION_END as a,
  1226. attr_class as a0,
  1227. attr_style as a1,
  1228. ensure_array_like as a2,
  1229. attr as a3,
  1230. stringify as a4,
  1231. HYDRATION_START as b,
  1232. HYDRATION_START_ELSE as c,
  1233. EFFECT as d,
  1234. escape_html as e,
  1235. CONNECTED as f,
  1236. getContext as g,
  1237. CLEAN as h,
  1238. DERIVED as i,
  1239. BLOCK_EFFECT as j,
  1240. DESTROYED as k,
  1241. EAGER_EFFECT as l,
  1242. deferred as m,
  1243. noop as n,
  1244. RENDER_EFFECT as o,
  1245. MANAGED_EFFECT as p,
  1246. ROOT_EFFECT as q,
  1247. run_all as r,
  1248. BRANCH_EFFECT as s,
  1249. includes as t,
  1250. HYDRATION_START_FAILED as u,
  1251. EFFECT_TRANSPARENT as v,
  1252. EFFECT_PRESERVED as w,
  1253. STATE_SYMBOL as x,
  1254. object_prototype as y,
  1255. array_prototype as z
  1256. };