1const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./Index-BRJ0gETR.js","./i18n-CMo5lpzy.js","./i18n-CGFL4PZH.css","./index-Lz7fsHFt.js","./StreamingBar.svelte_svelte_type_style_lang-CdFIGsJa.js","./html-CdUEtR5E.js","./ScrollFade.svelte_svelte_type_style_lang-Xm-PLg9E.js","./snippet-Bl5YVoCg.js","./ScrollFade-BXTrLZiw.css","./index-C7e-J7CF.js","./StreamingBar-M0OJiclA.css","./Clear-Dgs5UhTO.js","./Index-D1pHiZ3X.css","./index-BJk8VOjP.js","./index-DnoGeqVF.js","./utils.svelte-CYLB_jIA.js","./clone-DaB-S2nH.js"])))=>i.map(i=>d[i]); 2true &&(function polyfill() { 3 const relList = document.createElement("link").relList; 4 if (relList && relList.supports && relList.supports("modulepreload")) return; 5 for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link); 6 new MutationObserver((mutations) => { 7 for (const mutation of mutations) { 8 if (mutation.type !== "childList") continue; 9 for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node); 10 } 11 }).observe(document, { 12 childList: true, 13 subtree: true 14 }); 15 function getFetchOpts(link) { 16 const fetchOpts = {}; 17 if (link.integrity) fetchOpts.integrity = link.integrity; 18 if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy; 19 if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include"; 20 else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit"; 21 else fetchOpts.credentials = "same-origin"; 22 return fetchOpts; 23 } 24 function processPreload(link) { 25 if (link.ep) return; 26 link.ep = true; 27 const fetchOpts = getFetchOpts(link); 28 fetch(link.href, fetchOpts); 29 } 30}()); 31 32const scriptRel = 'modulepreload';const assetsURL = function(dep, importerUrl) { return new URL(dep, importerUrl).href };const seen = {};const __vitePreload = function preload(baseModule, deps, importerUrl) { 33 let promise = Promise.resolve(); 34 if (true && deps && deps.length > 0) { 35 const links = document.getElementsByTagName("link"); 36 const cspNonceMeta = document.querySelector("meta[property=csp-nonce]"); 37 const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce"); 38 function allSettled(promises$2) { 39 return Promise.all(promises$2.map((p) => Promise.resolve(p).then((value$1) => ({ 40 status: "fulfilled", 41 value: value$1 42 }), (reason) => ({ 43 status: "rejected", 44 reason 45 })))); 46 } 47 promise = allSettled(deps.map((dep) => { 48 dep = assetsURL(dep, importerUrl); 49 if (dep in seen) return; 50 seen[dep] = true; 51 const isCss = dep.endsWith(".css"); 52 const cssSelector = isCss ? "[rel=\"stylesheet\"]" : ""; 53 if (!!importerUrl) for (let i$1 = links.length - 1; i$1 >= 0; i$1--) { 54 const link$1 = links[i$1]; 55 if (link$1.href === dep && (!isCss || link$1.rel === "stylesheet")) return; 56 } 57 else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return; 58 const link = document.createElement("link"); 59 link.rel = isCss ? "stylesheet" : scriptRel; 60 if (!isCss) link.as = "script"; 61 link.crossOrigin = ""; 62 link.href = dep; 63 if (cspNonce) link.setAttribute("nonce", cspNonce); 64 document.head.appendChild(link); 65 if (isCss) return new Promise((res, rej) => { 66 link.addEventListener("load", res); 67 link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`))); 68 }); 69 })); 70 } 71 function handlePreloadError(err$2) { 72 const e$1 = new Event("vite:preloadError", { cancelable: true }); 73 e$1.payload = err$2; 74 window.dispatchEvent(e$1); 75 if (!e$1.defaultPrevented) throw err$2; 76 } 77 return promise.then((res) => { 78 for (const item of res || []) { 79 if (item.status !== "rejected") continue; 80 handlePreloadError(item.reason); 81 } 82 return baseModule().catch(handlePreloadError); 83 }); 84}; 85 86const HOST_URL = `host`; 87const SSE_URL = `queue/data`; 88const SSE_DATA_URL = `queue/join`; 89const UPLOAD_URL = `upload`; 90const LOGIN_URL = `login`; 91const CONFIG_URL = `config`; 92const API_INFO_URL = `info`; 93const RUNTIME_URL = `runtime`; 94const SLEEPTIME_URL = `sleeptime`; 95const HEARTBEAT_URL = `heartbeat`; 96const COMPONENT_SERVER_URL = `component_server`; 97const RESET_URL = `reset`; 98const CANCEL_URL = `cancel`; 99const APP_ID_URL = `app_id`; 100const QUEUE_FULL_MSG = "This application is currently busy. Please try again. "; 101const BROKEN_CONNECTION_MSG = "Connection errored out. "; 102const CONFIG_ERROR_MSG = "Could not resolve app config. ";
103const SPACE_STATUS_ERROR_MSG = "Could not get space status. "; 104const API_INFO_ERROR_MSG = "Could not get API info. "; 105const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. "; 106const INVALID_URL_MSG = "Invalid URL. A full URL path is required."; 107const UNAUTHORIZED_MSG = "Not authorized to access this space. "; 108const INVALID_CREDENTIALS_MSG = "Invalid credentials. Could not login. "; 109const MISSING_CREDENTIALS_MSG = "Login credentials are required to access this space."; 110const NODEJS_FS_ERROR_MSG = "File system access is only available in Node.js environments"; 111const ROOT_URL_ERROR_MSG = "Root URL not found in client config"; 112const FILE_PROCESSING_ERROR_MSG = "Error uploading file"; 113 114async function get_jwt(space, token, cookies) { 115 try { 116 const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, { 117 headers: { 118 Authorization: `Bearer ${token}`, 119 ...cookies ? { Cookie: cookies } : {} 120 } 121 }); 122 const jwt = (await r.json()).token; 123 return jwt || false; 124 } catch (e) { 125 return false; 126 } 127} 128function map_names_to_ids(fns) { 129 let apis = {}; 130 fns.forEach(({ api_name, id }) => { 131 if (api_name) apis[api_name] = id; 132 }); 133 return apis; 134} 135async function resolve_config(endpoint) { 136 const headers = this.options.token ? { Authorization: `Bearer ${this.options.token}` } : {}; 137 headers["Content-Type"] = "application/json"; 138 if (typeof window !== "undefined" && window.gradio_config && location.origin !== "http://localhost:9876") { 139 if (window.gradio_config.current_page) { 140 endpoint = endpoint.substring(0, endpoint.lastIndexOf("/")); 141 } 142 if (window.gradio_config.dev_mode || typeof window !== "undefined" && window?.BUILD_MODE === "dev") { 143 let config_url = join_urls( 144 endpoint, 145 this.deep_link ? CONFIG_URL + "?deep_link=" + this.deep_link : CONFIG_URL 146 ); 147 const response = await this.fetch(config_url, { 148 headers, 149 credentials: "include" 150 }); 151 const config = await handleConfigResponse(response, !!this.options.auth); 152 config.root = endpoint || config.root; 153 window.gradio_config = { 154 ...config, 155 current_page: window.gradio_config.current_page 156 }; 157 } 158 return { ...window.gradio_config }; 159 } else if (endpoint) { 160 let config_url = join_urls( 161 endpoint, 162 this.deep_link ? CONFIG_URL + "?deep_link=" + this.deep_link : CONFIG_URL 163 ); 164 const response = await this.fetch(config_url, { 165 headers, 166 credentials: "include" 167 }); 168 const config = await handleConfigResponse(response, !!this.options.auth); 169 if (!config.root) { 170 config.root = endpoint; 171 } 172 return config; 173 } 174 throw new Error(CONFIG_ERROR_MSG); 175} 176async function handleConfigResponse(response, authorized) { 177 if (response?.status === 401 && !authorized) { 178 const error_data = await response.json(); 179 const auth_message = error_data?.detail?.auth_message; 180 throw new Error(auth_message || MISSING_CREDENTIALS_MSG); 181 } else if (response?.status === 401 && authorized) { 182 throw new Error(INVALID_CREDENTIALS_MSG); 183 } 184 if (response?.status === 200) {
185 let config = await response.json(); 186 config.dependencies?.forEach((dep, i) => { 187 if (dep.id === void 0) { 188 dep.id = i; 189 } 190 }); 191 return config; 192 } else if (response?.status === 401) { 193 throw new Error(UNAUTHORIZED_MSG); 194 } 195 throw new Error(CONFIG_ERROR_MSG); 196} 197async function resolve_cookies() { 198 const { http_protocol, host } = await process_endpoint( 199 this.app_reference, 200 this.options.token 201 ); 202 try { 203 if (this.options.auth) { 204 const cookie_header = await get_cookie_header( 205 http_protocol, 206 host, 207 this.options.auth, 208 this.fetch, 209 this.options.token 210 ); 211 if (cookie_header) this.set_cookies(cookie_header); 212 } 213 } catch (e) { 214 throw Error(e.message); 215 } 216} 217async function get_cookie_header(http_protocol, host, auth, _fetch, token) { 218 const formData = new FormData(); 219 formData.append("username", auth?.[0]); 220 formData.append("password", auth?.[1]); 221 let headers = {}; 222 if (token) { 223 headers.Authorization = `Bearer ${token}`; 224 } 225 const res = await _fetch(`${http_protocol}//${host}/${LOGIN_URL}`, { 226 headers, 227 method: "POST", 228 body: formData, 229 credentials: "include" 230 }); 231 if (res.status === 200) { 232 return res.headers.get("set-cookie"); 233 } else if (res.status === 401) { 234 throw new Error(INVALID_CREDENTIALS_MSG); 235 } else { 236 throw new Error(SPACE_METADATA_ERROR_MSG); 237 } 238} 239function determine_protocol(endpoint) { 240 if (endpoint.startsWith("http")) { 241 const { protocol, host, pathname } = new URL(endpoint); 242 return { 243 ws_protocol: protocol === "https:" ? "wss" : "ws", 244 http_protocol: protocol, 245 host: host + (pathname !== "/" ? pathname : "") 246 }; 247 } 248 return { 249 ws_protocol: "wss", 250 http_protocol: "https:", 251 host: new URL(endpoint).host 252 }; 253} 254const parse_and_set_cookies = (cookie_header) => { 255 let cookies = []; 256 const parts = cookie_header.split(/,(?=\s*[^\s=;]+=[^\s=;]+)/);
257 parts.forEach((cookie) => { 258 const [cookie_name, cookie_value] = cookie.split(";")[0].split("="); 259 if (cookie_name && cookie_value) { 260 cookies.push(`${cookie_name.trim()}=${cookie_value.trim()}`); 261 } 262 }); 263 return cookies; 264}; 265 266const RE_SPACE_NAME = /^[a-zA-Z0-9_\-\.]+\/[a-zA-Z0-9_\-\.]+$/; 267const RE_SPACE_DOMAIN = /.*hf\.space\/{0,1}.*$/; 268async function process_endpoint(app_reference, token) { 269 const headers = {}; 270 if (token) { 271 headers.Authorization = `Bearer ${token}`; 272 } 273 const _app_reference = app_reference.trim().replace(/\/$/, ""); 274 if (RE_SPACE_NAME.test(_app_reference)) { 275 try { 276 const res = await fetch( 277 `https://huggingface.co/api/spaces/${_app_reference}/${HOST_URL}`, 278 { headers } 279 ); 280 const _host = (await res.json()).host; 281 return { 282 space_id: app_reference, 283 ...determine_protocol(_host) 284 }; 285 } catch (e) { 286 throw new Error(SPACE_METADATA_ERROR_MSG); 287 } 288 } 289 if (RE_SPACE_DOMAIN.test(_app_reference)) { 290 const { ws_protocol, http_protocol, host } = determine_protocol(_app_reference); 291 return { 292 space_id: host.split("/")[0].replace(".hf.space", ""), 293 ws_protocol, 294 http_protocol, 295 host 296 }; 297 } 298 return { 299 space_id: false, 300 ...determine_protocol(_app_reference) 301 }; 302} 303const join_urls = (...urls) => { 304 try { 305 return urls.reduce((base_url, part) => { 306 base_url = base_url.replace(/\/+$/, ""); 307 part = part.replace(/^\/+/, ""); 308 return new URL(part, base_url + "/").toString(); 309 }); 310 } catch (e) { 311 throw new Error(INVALID_URL_MSG); 312 } 313}; 314function transform_api_info(api_info, config, api_map) { 315 const transformed_info = { 316 named_endpoints: {}, 317 unnamed_endpoints: {} 318 }; 319 Object.keys(api_info).forEach((category) => { 320 if (category === "named_endpoints" || category === "unnamed_endpoints") { 321 transformed_info[category] = {}; 322 Object.entries(api_info[category]).forEach( 323 ([endpoint, { parameters, returns }]) => { 324 const dependencyIndex = config.dependencies.find( 325 (dep) => dep.api_name === endpoint || dep.api_name === endpoint.replace("/", "") 326 )?.id || api_map[endpoint.replace("/", "")] || -1; 327 const dependencyTypes = dependencyIndex !== -1 ? config.dependencies.find((dep) => dep.id == dependencyIndex)?.types : { generator: false, cancel: false }; 328 if (dependencyIndex !== -1 && config.dependencies.find((dep) => dep.id == dependencyIndex)?.inputs?.length !== parameters.length) { 329 const components = config.dependencies.find((dep) => dep.id == dependencyIndex).inputs.map( 330 (input) => config.components.find((c) => c.id === input)?.type 331 ); 332 try { 333 components.forEach((comp, idx) => { 334 if (comp === "state") { 335 const new_param = { 336 component: "state", 337 example: null, 338 parameter_default: null, 339 parameter_has_default: true, 340 parameter_name: null, 341 hidden: true 342 }; 343 parameters.splice(idx, 0, new_param); 344 } 345 }); 346 } catch (e) { 347 console.error(e); 348 } 349 } 350 const transform_type = (data, component, serializer, signature_type) => ({ 351 ...data, 352 description: get_description(data?.type, serializer), 353 type: get_type(data?.type, component, serializer, signature_type) || "" 354 }); 355 transformed_info[category][endpoint] = { 356 parameters: parameters.map( 357 (p) => transform_type(p, p?.component, p?.serializer, "parameter") 358 ), 359 returns: returns.map( 360 (r) => transform_type(r, r?.component, r?.serializer, "return") 361 ),
362 type: dependencyTypes 363 }; 364 } 365 ); 366 } 367 }); 368 return transformed_info; 369} 370function get_type(type, component, serializer, signature_type) { 371 if (component === "Api") return type.type; 372 switch (type?.type) { 373 case "string": 374 return "string"; 375 case "boolean": 376 return "boolean"; 377 case "number": 378 return "number"; 379 } 380 if (serializer === "JSONSerializable" || serializer === "StringSerializable") { 381 return "any"; 382 } else if (serializer === "ListStringSerializable") { 383 return "string[]"; 384 } else if (component === "Image") { 385 return signature_type === "parameter" ? "Blob | File | Buffer" : "string"; 386 } else if (serializer === "FileSerializable") { 387 if (type?.type === "array") { 388 return signature_type === "parameter" ? "(Blob | File | Buffer)[]" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`; 389 } 390 return signature_type === "parameter" ? "Blob | File | Buffer" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`; 391 } else if (serializer === "GallerySerializable") { 392 return signature_type === "parameter" ? "[(Blob | File | Buffer), (string | null)][]" : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`; 393 } 394} 395function get_description(type, serializer) { 396 if (serializer === "GallerySerializable") { 397 return "array of [file, label] tuples"; 398 } else if (serializer === "ListStringSerializable") { 399 return "array of strings"; 400 } else if (serializer === "FileSerializable") { 401 return "array of files or single file"; 402 } 403 return type?.description; 404} 405function handle_message(data, last_status) { 406 const queue = true; 407 switch (data.msg) { 408 case "send_data": 409 return { type: "data" }; 410 case "send_hash": 411 return { type: "hash" }; 412 case "queue_full": 413 return { 414 type: "update", 415 status: { 416 queue, 417 message: QUEUE_FULL_MSG, 418 stage: "error", 419 code: data.code, 420 success: data.success 421 } 422 }; 423 case "heartbeat": 424 return { 425 type: "heartbeat" 426 }; 427 case "unexpected_error": 428 return { 429 type: "unexpected_error", 430 status: { 431 queue, 432 message: data.message, 433 session_not_found: data.session_not_found, 434 stage: "error", 435 success: false 436 } 437 }; 438 case "broken_connection": 439 return { 440 type: "broken_connection", 441 status: { 442 queue, 443 message: data.message, 444 stage: "error", 445 success: false 446 } 447 }; 448 case "estimation": 449 return { 450 type: "update", 451 status: { 452 queue, 453 stage: last_status || "pending", 454 code: data.code, 455 size: data.queue_size, 456 position: data.rank, 457 eta: data.rank_eta, 458 success: data.success 459 } 460 }; 461 case "progress": 462 return { 463 type: "update", 464 status: { 465 queue, 466 stage: "pending", 467 code: data.code, 468 progress_data: data.progress_data, 469 success: data.success 470 } 471 }; 472 case "log": 473 return { type: "log", data }; 474 case "process_generating": 475 return { 476 type: "generating", 477 status: { 478 queue, 479 message: !data.success ? data.output.error : null, 480 stage: data.success ? "generating" : "error", 481 code: data.code, 482 progress_data: data.progress_data, 483 eta: data.average_duration, 484 changed_state_ids: data.success ? data.output.changed_state_ids : void 0 485 }, 486 data: data.success ? data.output : null 487 }; 488 case "process_streaming": 489 return { 490 type: "streaming", 491 status: { 492 queue, 493 message: data.output.error, 494 stage: "streaming", 495 time_limit: data.time_limit, 496 code: data.code, 497 progress_data: data.progress_data, 498 eta: data.eta 499 }, 500 data: data.output 501 }; 502 case "process_completed": 503 if ("error" in data.output) { 504 return { 505 type: "update", 506 status: { 507 queue, 508 title: data.output.title ?? "Error", 509 message: data.output.error ?? "An error occurred", 510 visible: data.output.visible, 511 duration: data.output.duration, 512 stage: "error", 513 code: data.code, 514 success: data.success 515 } 516 }; 517 } 518 return { 519 type: "complete", 520 status: { 521 queue, 522 message: !data.success ? data.output.error : void 0, 523 stage: data.success ? "complete" : "error", 524 code: data.code, 525 progress_data: data.progress_data, 526 changed_state_ids: data.success ? data.output.changed_state_ids : void 0 527 }, 528 data: data.success ? data.output : null 529 }; 530 case "process_starts": 531 return { 532 type: "update", 533 status: { 534 queue, 535 stage: "pending", 536 code: data.code, 537 size: data.rank, 538 position: 0, 539 success: data.success, 540 eta: data.eta 541 }, 542 original_msg: "process_starts" 543 }; 544 } 545 return { type: "none", status: { stage: "error", queue } }; 546}
547const map_data_to_params = (data = [], endpoint_info) => { 548 const parameters = endpoint_info ? endpoint_info.parameters : []; 549 if (Array.isArray(data)) { 550 if (endpoint_info && parameters.length > 0 && data.length > parameters.length) { 551 console.warn("Too many arguments provided for the endpoint."); 552 } 553 return data; 554 } 555 const resolved_data = []; 556 const provided_keys = Object.keys(data); 557 parameters.forEach((param, index) => { 558 if (data.hasOwnProperty(param.parameter_name)) { 559 resolved_data[index] = data[param.parameter_name]; 560 } else if (param.parameter_has_default) { 561 resolved_data[index] = param.parameter_default; 562 } else { 563 throw new Error( 564 `No value provided for required parameter: ${param.parameter_name}` 565 ); 566 } 567 }); 568 provided_keys.forEach((key) => { 569 if (!parameters.some((param) => param.parameter_name === key)) { 570 throw new Error( 571 `Parameter \`${key}\` is not a valid keyword argument. Please refer to the API for usage.` 572 ); 573 } 574 }); 575 resolved_data.forEach((value, idx) => { 576 if (value === void 0 && !parameters[idx].parameter_has_default) { 577 throw new Error( 578 `No value provided for required parameter: ${parameters[idx].parameter_name}` 579 ); 580 } 581 }); 582 return resolved_data; 583}; 584 585async function view_api() { 586 if (this.api_info) return this.api_info; 587 const { token } = this.options; 588 const { config } = this; 589 const headers = { "Content-Type": "application/json" }; 590 if (token) { 591 headers.Authorization = `Bearer ${token}`; 592 } 593 if (!config) { 594 return; 595 } 596 try { 597 let response; 598 let api_info; 599 if (typeof window !== "undefined" && window.gradio_api_info) { 600 api_info = window.gradio_api_info; 601 } else { 602 const url = join_urls(config.root, this.api_prefix, API_INFO_URL); 603 response = await this.fetch(url, { 604 headers, 605 credentials: "include" 606 }); 607 if (!response.ok) { 608 throw new Error(BROKEN_CONNECTION_MSG); 609 } 610 api_info = await response.json(); 611 } 612 if ("api" in api_info) { 613 api_info = api_info.api; 614 } 615 if (api_info.named_endpoints["/predict"] && !api_info.unnamed_endpoints["0"]) { 616 api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"]; 617 } 618 return transform_api_info(api_info, config, this.api_map); 619 } catch (e) { 620 throw new Error("Could not get API info. " + e.message); 621 } 622} 623 624async function upload_files(root_url, files, upload_id) { 625 const headers = {}; 626 if (this?.options?.token) { 627 headers.Authorization = `Bearer ${this.options.token}`; 628 } 629 const chunkSize = 1e3; 630 const uploadResponses = []; 631 let response; 632 for (let i = 0; i < files.length; i += chunkSize) { 633 const chunk = files.slice(i, i + chunkSize); 634 const formData = new FormData(); 635 chunk.forEach((file) => { 636 formData.append("files", file); 637 }); 638 try { 639 const upload_url = upload_id ? `${root_url}${this.api_prefix}/${UPLOAD_URL}?upload_id=${upload_id}` : `${root_url}${this.api_prefix}/${UPLOAD_URL}`; 640 response = await this.fetch(upload_url, { 641 method: "POST", 642 body: formData, 643 headers, 644 credentials: "include" 645 }); 646 } catch (e) { 647 throw new Error(BROKEN_CONNECTION_MSG + e.message); 648 } 649 if (!response.ok) { 650 const error_text = await response.text(); 651 return { error: `HTTP ${response.status}: ${error_text}` }; 652 } 653 const output = await response.json(); 654 if (output) { 655 uploadResponses.push(...output); 656 } 657 } 658 return { files: uploadResponses }; 659} 660 661const si = { 662 radix: 1e3, 663 unit: ["b", "kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"] 664}; 665const iec = { 666 radix: 1024, 667 unit: ["b", "Kib", "Mib", "Gib", "Tib", "Pib", "Eib", "Zib", "Yib"] 668}; 669const jedec = { 670 radix: 1024, 671 unit: ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"] 672}; 673const SPECS = { 674 si, 675 iec, 676 jedec 677}; 678function filesize(bytes, fixed = 1, spec = "jedec") { 679 bytes = Math.abs(bytes); 680 const { radix, unit } = SPECS[spec] || SPECS.jedec; 681 let loop = 0; 682 while (bytes >= radix) { 683 bytes /= radix; 684 ++loop; 685 } 686 return `${bytes.toFixed(fixed)} ${unit[loop]}`; 687} 688 689async function upload(file_data, root_url, upload_id, max_file_size) { 690 let files = (Array.isArray(file_data) ? file_data : [file_data]).map( 691 (file_data2) =>
691 file_data2.blob 692 ); 693 const oversized_files = files.filter( 694 (f) => f.size > (max_file_size ?? Infinity) 695 ); 696 if (oversized_files.length) { 697 throw new Error( 698 `File(s) exceed the maximum allowed size of ${filesize(max_file_size || Infinity)}: ${oversized_files.map((f) => `"${f.name}"`).join(", ")}` 699 ); 700 } 701 return await Promise.all( 702 await this.upload_files(root_url, files, upload_id).then( 703 async (response) => { 704 if (response.error) { 705 throw new Error(response.error); 706 } else { 707 if (response.files) { 708 return response.files.map((f, i) => { 709 const file = new FileData({ 710 ...file_data[i], 711 path: f, 712 url: `${root_url}${this.api_prefix}/file=${f}` 713 }); 714 return file; 715 }); 716 } 717 return []; 718 } 719 } 720 ) 721 ); 722} 723async function prepare_files(files, is_stream) { 724 return files.map( 725 (f) => new FileData({ 726 path: f.name, 727 orig_name: f.name, 728 blob: f, 729 size: f.size, 730 mime_type: f.type, 731 is_stream 732 }) 733 ); 734} 735class FileData { 736 path; 737 url; 738 orig_name; 739 size; 740 blob; 741 is_stream; 742 mime_type; 743 alt_text; 744 b64; 745 meta = { _type: "gradio.FileData" }; 746 constructor({ 747 path, 748 url, 749 orig_name, 750 size, 751 blob, 752 is_stream, 753 mime_type, 754 alt_text, 755 b64 756 }) { 757 this.path = path; 758 this.url = url; 759 this.orig_name = orig_name; 760 this.size = size; 761 this.blob = url ? void 0 : blob; 762 this.is_stream = is_stream; 763 this.mime_type = mime_type; 764 this.alt_text = alt_text; 765 this.b64 = b64; 766 } 767} 768 769class Command { 770 type; 771 command; 772 meta; 773 fileData; 774 constructor(command, meta) { 775 this.type = "command"; 776 this.command = command; 777 this.meta = meta; 778 } 779} 780 781typeof process !== "undefined" && process.versions && process.versions.node; 782function update_object(object, newValue, stack) { 783 while (stack.length > 1) { 784 const key2 = stack.shift(); 785 if (typeof key2 === "string" || typeof key2 === "number") { 786 object = object[key2]; 787 } else { 788 throw new Error("Invalid key type"); 789 } 790 } 791 const key = stack.shift(); 792 if (typeof key === "string" || typeof key === "number") { 793 object[key] = newValue; 794 } else { 795 throw new Error("Invalid key type"); 796 } 797} 798async function walk_and_store_blobs(data, type = void 0, path = [], root = false, endpoint_info = void 0) { 799 if (Array.isArray(data)) { 800 let blob_refs = []; 801 await Promise.all( 802 data.map(async (_, index) => { 803 let new_path = path.slice(); 804 new_path.push(String(index)); 805 const array_refs = await walk_and_store_blobs( 806 data[index], 807 root ? endpoint_info?.parameters[index]?.component || void 0 : type, 808 new_path, 809 false, 810 endpoint_info 811 ); 812 blob_refs = blob_refs.concat(array_refs); 813 }) 814 ); 815 return blob_refs; 816 } else if (globalThis.Buffer && data instanceof globalThis.Buffer || data instanceof Blob) { 817 return [ 818 { 819 path, 820 blob: new Blob([data]), 821 type 822 } 823 ]; 824 } else if (typeof data === "object" && data !== null) { 825 let blob_refs = []; 826 for (const key of Object.keys(data)) { 827 const new_path = [...path, key]; 828 const value = data[key]; 829 blob_refs = blob_refs.concat( 830 await walk_and_store_blobs( 831 value, 832 void 0, 833 new_path, 834 false, 835 endpoint_info 836 ) 837 ); 838 } 839 return blob_refs; 840 } 841 return []; 842} 843function skip_queue(id, config) { 844 let fn_queue = config?.dependencies?.find((dep) => dep.id == id)?.queue; 845 if (fn_queue != null) { 846 return !fn_queue; 847 } 848 return !config.enable_queue; 849} 850function post_message(message, origin) { 851 return new Promise((res, _rej) => { 852 const channel = new MessageChannel(); 853 channel.port1.onmessage = (({ data }) => { 854 channel.port1.close(); 855 res(data); 856 }); 857 window.parent.postMessage(message, origin, [channel.port2]); 858 }); 859} 860function handle_payload(resolved_payload, dependency, components, type, with_null_state = false) { 861 if (type === "input" && !with_null_state) { 862 throw new Error("Invalid code path. Cannot skip state inputs for input."); 863 } 864 if (type === "output" && with_null_state) { 865 return resolved_payload; 866 } 867 let updated_payload = []; 868 let payload_index = 0;
869 const deps = type === "input" ? dependency.inputs : dependency.outputs; 870 for (let i = 0; i < deps.length; i++) { 871 const input_id = deps[i]; 872 const component = components.find((c) => c.id === input_id); 873 if (component?.type === "state") { 874 if (with_null_state) { 875 if (resolved_payload.length === deps.length) { 876 const value = resolved_payload[payload_index]; 877 updated_payload.push(value); 878 payload_index++; 879 } else { 880 updated_payload.push(null); 881 } 882 } else { 883 payload_index++; 884 continue; 885 } 886 continue; 887 } else { 888 const value = resolved_payload[payload_index]; 889 updated_payload.push(value); 890 payload_index++; 891 } 892 } 893 return updated_payload; 894} 895 896async function handle_blob(endpoint, data, api_info) { 897 const self = this; 898 await process_local_file_commands(self, data); 899 const blobRefs = await walk_and_store_blobs( 900 data, 901 void 0, 902 [], 903 true, 904 api_info 905 ); 906 const results = await Promise.all( 907 blobRefs.map(async ({ path, blob, type }) => { 908 if (!blob) return { path, type }; 909 const response = await self.upload_files(endpoint, [blob]); 910 const file_url = response.files && response.files[0]; 911 return { 912 path, 913 file_url, 914 type, 915 name: typeof File !== "undefined" && blob instanceof File ? blob?.name : void 0 916 }; 917 }) 918 ); 919 results.forEach(({ path, file_url, type, name }) => { 920 if (type === "Gallery") { 921 update_object(data, file_url, path); 922 } else if (file_url) { 923 const file = new FileData({ path: file_url, orig_name: name }); 924 update_object(data, file, path); 925 } 926 }); 927 return data; 928} 929async function process_local_file_commands(client, data) { 930 const root = client.config?.root || client.config?.root_url; 931 if (!root) { 932 throw new Error(ROOT_URL_ERROR_MSG); 933 } 934 await recursively_process_commands(client, data); 935} 936async function recursively_process_commands(client, data, path = []) { 937 for (const key in data) { 938 if (data[key] instanceof Command) { 939 await process_single_command(client, data, key); 940 } else if (typeof data[key] === "object" && data[key] !== null) { 941 await recursively_process_commands(client, data[key], [...path, key]); 942 } 943 } 944} 945async function process_single_command(client, data, key) { 946 let cmd_item = data[key]; 947 const root = client.config?.root || client.config?.root_url; 948 if (!root) { 949 throw new Error(ROOT_URL_ERROR_MSG); 950 } 951 try { 952 let fileBuffer; 953 let fullPath; 954 if (typeof process !== "undefined" && process.versions && process.versions.node) { 955 const fs = await __vitePreload(() => import('./__vite-browser-external-CVaeKfQx.js').then(n => n._),true ?[]:void 0,import.meta.url); 956 const path = await __vitePreload(() => import('./__vite-browser-external-CVaeKfQx.js').then(n => n._),true ?[]:void 0,import.meta.url); 957 fullPath = path.resolve(process.cwd(), cmd_item.meta.path); 958 fileBuffer = await fs.readFile(fullPath); 959 } else { 960 throw new Error(NODEJS_FS_ERROR_MSG); 961 } 962 const file = new Blob([fileBuffer], { 963 type: "application/octet-stream" 964 }); 965 const response = await client.upload_files(root, [file]); 966 const file_url = response.files && response.files[0]; 967 if (file_url) { 968 const fileData = new FileData({ 969 path: file_url, 970 orig_name: cmd_item.meta.name || "" 971 }); 972 data[key] = fileData; 973 } 974 } catch (error) { 975 console.error(FILE_PROCESSING_ERROR_MSG, error); 976 } 977} 978 979async function post_data(url, body, additional_headers) { 980 const headers = { "Content-Type": "application/json" }; 981 if (this.options.token) { 982 headers.Authorization = `Bearer ${this.options.token}`; 983 } 984 try { 985 var response = await this.fetch(url, { 986 method: "POST", 987 body: JSON.stringify(body), 988 headers: { ...headers, ...additional_headers }, 989 credentials: "include" 990 }); 991 } catch (e) { 992 return [{ error: BROKEN_CONNECTION_MSG }, 500]; 993 } 994 let output; 995 let status; 996 try { 997 output = await response.json(); 998 status = response.status; 999 } catch (e) { 1000 output = { error: `Could not parse server response: ${e}` }; 1001 status = 500; 1002 } 1003 return [output, status]; 1004} 1005 1006async function predict(endpoint, data = {}) { 1007 let data_returned = false;
1008 let status_complete = false; 1009 if (!this.config) { 1010 throw new Error("Could not resolve app config"); 1011 } 1012 if (typeof endpoint === "number") { 1013 this.config.dependencies.find((dep) => dep.id == endpoint); 1014 } else { 1015 const trimmed_endpoint = endpoint.replace(/^\//, ""); 1016 this.config.dependencies.find( 1017 (dep) => dep.id == this.api_map[trimmed_endpoint] 1018 ); 1019 } 1020 return new Promise(async (resolve, reject) => { 1021 const app = this.submit(endpoint, data, null, null, true); 1022 let result; 1023 for await (const message of app) { 1024 if (message.type === "data") { 1025 if (status_complete) { 1026 resolve(result); 1027 } 1028 data_returned = true; 1029 result = message; 1030 } 1031 if (message.type === "status") { 1032 if (message.stage === "error") reject(message); 1033 if (message.stage === "complete") { 1034 status_complete = true; 1035 if (data_returned) { 1036 resolve(result); 1037 } 1038 } 1039 } 1040 } 1041 }); 1042} 1043 1044async function check_space_status(id, type, status_callback) { 1045 let endpoint = type === "subdomain" ? `https://huggingface.co/api/spaces/by-subdomain/${id}` : `https://huggingface.co/api/spaces/${id}`; 1046 let response; 1047 let _status; 1048 try { 1049 response = await fetch(endpoint); 1050 _status = response.status; 1051 if (_status !== 200) { 1052 throw new Error(); 1053 } 1054 response = await response.json(); 1055 } catch (e) { 1056 status_callback({ 1057 status: "error", 1058 load_status: "error", 1059 message: SPACE_STATUS_ERROR_MSG, 1060 detail: "NOT_FOUND" 1061 }); 1062 return; 1063 } 1064 if (!response || _status !== 200) return; 1065 const { 1066 runtime: { stage }, 1067 id: space_name 1068 } = response; 1069 switch (stage) { 1070 case "STOPPED": 1071 case "SLEEPING": 1072 status_callback({ 1073 status: "sleeping", 1074 load_status: "pending", 1075 message: "Space is asleep. Waking it up...", 1076 detail: stage 1077 }); 1078 setTimeout(() => { 1079 check_space_status(id, type, status_callback); 1080 }, 1e3); 1081 break; 1082 case "PAUSED": 1083 status_callback({ 1084 status: "paused", 1085 load_status: "error", 1086 message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.", 1087 detail: stage, 1088 discussions_enabled: await discussions_enabled(space_name) 1089 }); 1090 break; 1091 case "RUNNING": 1092 case "RUNNING_BUILDING": 1093 status_callback({ 1094 status: "running", 1095 load_status: "complete", 1096 message: "Space is running.", 1097 detail: stage 1098 }); 1099 break; 1100 case "BUILDING": 1101 status_callback({ 1102 status: "building", 1103 load_status: "pending", 1104 message: "Space is building...", 1105 detail: stage 1106 }); 1107 setTimeout(() => { 1108 check_space_status(id, type, status_callback); 1109 }, 1e3); 1110 break; 1111 case "APP_STARTING": 1112 status_callback({ 1113 status: "starting", 1114 load_status: "pending", 1115 message: "Space is starting...", 1116 detail: stage 1117 }); 1118 setTimeout(() => { 1119 check_space_status(id, type, status_callback); 1120 }, 1e3); 1121 break; 1122 default: 1123 status_callback({ 1124 status: "space_error", 1125 load_status: "error", 1126 message: "This space is experiencing an issue.", 1127 detail: stage, 1128 discussions_enabled: await discussions_enabled(space_name) 1129 }); 1130 break; 1131 } 1132} 1133const check_and_wake_space = async (space_id, status_callback) => { 1134 let retries = 0; 1135 const max_retries = 12; 1136 const check_interval = 5e3; 1137 return new Promise((resolve) => { 1138 check_space_status( 1139 space_id, 1140 RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain", 1141 (status) => { 1142 status_callback(status); 1143 if (status.status === "running") { 1144 resolve(); 1145 } else if (status.status === "error" || status.status === "paused" || status.status === "space_error") { 1146 resolve(); 1147 } else if (status.status === "sleeping" || status.status === "building") { 1148 if (retries < max_retries) { 1149 retries++; 1150 setTimeout(() => { 1151 check_and_wake_space(space_id, status_callback).then(resolve); 1152 }, check_interval); 1153 } else { 1154 resolve(); 1155 } 1156 } 1157 } 1158 ); 1159 }); 1160}; 1161const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/; 1162async function discussions_enabled(space_id) { 1163 try { 1164 const r = await fetch( 1165 `https://huggingface.co/api/spaces/${space_id}/discussions`, 1166 { 1167 method: "HEAD" 1168 } 1169 ); 1170 const error = r.headers.get("x-error-message"); 1171 if (!r.ok || error && RE_DISABLED_DISCUSSION.test(error)) return false;
1172 return true; 1173 } catch (e) { 1174 return false; 1175 } 1176} 1177async function get_space_hardware(space_id, token) { 1178 const headers = {}; 1179 if (token) { 1180 headers.Authorization = `Bearer ${token}`; 1181 } 1182 try { 1183 const res = await fetch( 1184 `https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`, 1185 { headers } 1186 ); 1187 if (res.status !== 200) 1188 throw new Error("Space hardware could not be obtained."); 1189 const { hardware } = await res.json(); 1190 return hardware.current; 1191 } catch (e) { 1192 throw new Error(e.message); 1193 } 1194} 1195async function set_space_timeout(space_id, timeout, token) { 1196 const headers = {}; 1197 if (token) { 1198 headers.Authorization = `Bearer ${token}`; 1199 } 1200 const body = { 1201 seconds: timeout 1202 }; 1203 try { 1204 const res = await fetch( 1205 `https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`, 1206 { 1207 method: "POST", 1208 headers: { "Content-Type": "application/json", ...headers }, 1209 body: JSON.stringify(body) 1210 } 1211 ); 1212 if (res.status !== 200) { 1213 throw new Error( 1214 "Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges." 1215 ); 1216 } 1217 const response = await res.json(); 1218 return response; 1219 } catch (e) { 1220 throw new Error(e.message); 1221 } 1222} 1223const hardware_types = [ 1224 "cpu-basic", 1225 "cpu-upgrade", 1226 "cpu-xl", 1227 "t4-small", 1228 "t4-medium", 1229 "a10g-small", 1230 "a10g-large", 1231 "a10g-largex2", 1232 "a10g-largex4", 1233 "a100-large", 1234 "zero-a10g", 1235 "h100", 1236 "h100x8" 1237]; 1238 1239async function duplicate(app_reference, options) { 1240 const { token, private: _private, hardware, timeout, auth } = options; 1241 if (hardware && !hardware_types.includes(hardware)) { 1242 throw new Error( 1243 `Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.` 1244 ); 1245 } 1246 const { http_protocol, host } = await process_endpoint(app_reference, token); 1247 let cookies = null; 1248 if (auth) { 1249 const cookie_header = await get_cookie_header( 1250 http_protocol, 1251 host, 1252 auth, 1253 fetch 1254 ); 1255 if (cookie_header) cookies = parse_and_set_cookies(cookie_header); 1256 } 1257 const headers = { 1258 Authorization: `Bearer ${token}`, 1259 "Content-Type": "application/json", 1260 ...cookies ? { Cookie: cookies.join("; ") } : {} 1261 }; 1262 const user = (await (await fetch(`https://huggingface.co/api/whoami-v2`, { 1263 headers 1264 })).json()).name; 1265 const space_name = app_reference.split("/")[1]; 1266 const body = { 1267 repository: `${user}/${space_name}` 1268 }; 1269 if (_private) { 1270 body.private = true; 1271 } 1272 let original_hardware; 1273 try { 1274 if (!hardware) { 1275 original_hardware = await get_space_hardware(app_reference, token); 1276 } 1277 } catch (e) { 1278 throw Error(SPACE_METADATA_ERROR_MSG + e.message); 1279 } 1280 const requested_hardware = hardware || original_hardware || "cpu-basic"; 1281 body.hardware = requested_hardware; 1282 try { 1283 const response = await fetch( 1284 `https://huggingface.co/api/spaces/${app_reference}/duplicate`, 1285 { 1286 method: "POST", 1287 headers, 1288 body: JSON.stringify(body) 1289 } 1290 ); 1291 if (response.status === 409) { 1292 try { 1293 const client = await Client.connect(`${user}/${space_name}`, options); 1294 return client; 1295 } catch (error) { 1296 console.error("Failed to connect Client instance:", error); 1297 throw error; 1298 } 1299 } else if (response.status !== 200) { 1300 throw new Error(response.statusText); 1301 } 1302 const duplicated_space = await response.json(); 1303 await set_space_timeout(`${user}/${space_name}`, timeout || 300, token); 1304 return await Client.connect( 1305 get_space_reference(duplicated_space.url), 1306 options 1307 ); 1308 } catch (e) { 1309 throw new Error(e); 1310 } 1311} 1312function get_space_reference(url) { 1313 const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/; 1314 const match = url.match(regex); 1315 if (match) { 1316 return match[1]; 1317 } 1318} 1319 1320// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. 1321// This module is browser compatible. 1322/** 1323 * Transform a stream into a stream where each chunk is divided by a newline, 1324 * be it `\n` or `\r\n`. `\r` can be enabled via the `allowCR` option. 1325 * 1326 * @example 1327 * ```ts 1328 * import { TextLineStream } from "@std/streams/text-line-stream"; 1329 * 1330 * const res = await fetch("https://example.com"); 1331 * const lines = res.body! 1332 * .pipeThrough(new TextDecoderStream()) 1333 * .pipeThrough(new TextLineStream()); 1334 * ``` 1335 */ 1336class TextLineStream extends TransformStream { 1337 #currentLine = ""; 1338 /** Constructs a new instance. */ 1339 constructor(options = { allowCR: false }) { 1340 super({ 1341 transform: (chars, controller) => { 1342 chars = this.#currentLine + chars; 1343 while (true) { 1344 const lfIndex = chars.indexOf("\n"); 1345 const crIndex = options.allowCR ? chars.indexOf("\r") : -1; 1346 if (crIndex !== -1 && crIndex !== (chars.length - 1) && 1347 (lfIndex === -1 || (lfIndex - 1) > crIndex)) { 1348 controller.enqueue(chars.slice(0, crIndex)); 1349 chars = chars.slice(crIndex + 1); 1350 continue; 1351 } 1352 if (lfIndex === -1) 1353 break; 1354 const endIndex = chars[lfIndex - 1] === "\r" ? lfIndex - 1 : lfIndex; 1355 controller.enqueue(chars.slice(0, endIndex)); 1356 chars = chars.slice(lfIndex + 1); 1357 } 1358 this.#currentLine = chars; 1359 }, 1360 flush: (controller) => { 1361 if (this.#currentLine === "") 1362 return; 1363 const currentLine = options.allowCR && this.#currentLine.endsWith("\r") 1364 ? this.#currentLine.slice(0, -1) 1365 : this.#currentLine; 1366 controller.enqueue(currentLine); 1367 }, 1368 }); 1369 } 1370} 1371 1372function stream$1(input) { 1373 let decoder = new TextDecoderStream(); 1374 let split = new TextLineStream({ allowCR: true }); 1375 return input.pipeThrough(decoder).pipeThrough(split); 1376} 1377function split(input) { 1378 let rgx = /[:]\s*/; 1379 let match = rgx.exec(input); 1380 // ": comment" -> index=0 -> ignore 1381 let idx = match && match.index; 1382 if (idx) { 1383 return [ 1384 input.substring(0, idx), 1385 input.substring(idx + match[0].length), 1386 ]; 1387 } 1388} 1389function fallback(headers, key, value) { 1390 let tmp = headers.get(key); 1391 if (!tmp) 1392 headers.set(key, value); 1393} 1394 1395/** 1396 * Convert a `Response` body containing Server Sent Events (SSE) into an Async Iterator that yields {@linkcode ServerSentEventMessage} objects. 1397 * 1398 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events} 1399 * 1400 * @example 1401 * ```js 1402 * // Optional 1403 * let abort = new AbortController; 1404 * 1405 * // Manually fetch a Response 1406 * let res = await fetch('https://...', { 1407 * method: 'POST', 1408 * signal: abort.signal, 1409 * headers: { 1410 * 'api-key': 'token <value>', 1411 * 'content-type': 'application/json', 1412 * }, 1413 * body: JSON.stringify({ 1414 * stream: true, // <- hypothetical 1415 * // ... 1416 * }) 1417 * }); 1418 * 1419 * if (res.ok) { 1420 * let stream = events(res, abort.signal); 1421 * for await (let event of stream) { 1422 * console.log('<<', event.data); 1423 * } 1424 * } 1425 * ``` 1426 */ 1427async function* events(res, signal) { 1428 // TODO: throw error? 1429 if (!res.body) 1430 return; 1431 let iter = stream$1(res.body); 1432 let line, reader = iter.getReader(); 1433 let event; 1434 for (;;) { 1435 if (signal && signal.aborted) { 1436 return reader.cancel(); 1437 } 1438 line = await reader.read(); 1439 if (line.done) 1440 return; 1441 if (!line.value) { 1442 if (event) 1443 yield event; 1444 event = undefined; 1445 continue; 1446 } 1447 let [field, value] = (split(line.value) || []); 1448 if (field === 'data') { 1449 event ||= {}; 1450 event[field] = event[field] ? (event[field] + '\n' + value) : value; 1451 } 1452 else if (field === 'event') { 1453 event ||= {}; 1454 event[field] = value; 1455 }
1456 else if (field === 'id') { 1457 event ||= {}; 1458 event[field] = String(+value) === value ? +value : value; 1459 } 1460 else if (field === 'retry') { 1461 event ||= {}; 1462 event[field] = +value || undefined; 1463 } 1464 } 1465} 1466/** 1467 * Convenience function that will `fetch` with the given arguments and, if ok, will return the {@linkcode events} async iterator. 1468 * 1469 * If the response is not ok (status 200-299), the `Response` is thrown. 1470 * 1471 * @example 1472 * ```js 1473 * // NOTE: throws `Response` if not 2xx status 1474 * let events = await stream('https://api.openai.com/...', { 1475 * method: 'POST', 1476 * headers: { 1477 * 'Authorization': 'Bearer <token>', 1478 * 'Content-Type': 'application/json', 1479 * }, 1480 * body: JSON.stringify({ 1481 * stream: true, 1482 * // ... 1483 * }) 1484 * }); 1485 * 1486 * for await (let event of events) { 1487 * console.log('<<', JSON.parse(event.data)); 1488 * } 1489 * ``` 1490 */ 1491async function stream(input, init) { 1492 let req = new Request(input, init); 1493 fallback(req.headers, 'Accept', 'text/event-stream'); 1494 fallback(req.headers, 'Content-Type', 'application/json'); 1495 let r = await fetch(req); 1496 if (!r.ok) 1497 throw r; 1498 return events(r, req.signal); 1499} 1500 1501async function open_stream() { 1502 let { 1503 event_callbacks, 1504 unclosed_events, 1505 pending_stream_messages, 1506 stream_status, 1507 config, 1508 jwt 1509 } = this; 1510 const that = this; 1511 if (!config) { 1512 throw new Error("Could not resolve app config"); 1513 } 1514 stream_status.open = true; 1515 let stream2 = null; 1516 let params = new URLSearchParams({ 1517 session_hash: this.session_hash 1518 }).toString(); 1519 let url = new URL(`${config.root}${this.api_prefix}/${SSE_URL}?${params}`); 1520 if (jwt) { 1521 url.searchParams.set("__sign", jwt); 1522 } 1523 stream2 = this.stream(url); 1524 if (!stream2) { 1525 console.warn("Cannot connect to SSE endpoint: " + url.toString()); 1526 return; 1527 } 1528 stream2.onmessage = async function(event) { 1529 let _data = JSON.parse(event.data); 1530 if (_data.msg === "close_stream") { 1531 close_stream(stream_status, that.abort_controller); 1532 return; 1533 } 1534 const event_id = _data.event_id; 1535 if (!event_id) { 1536 await Promise.all( 1537 Object.keys(event_callbacks).map( 1538 (event_id2) => event_callbacks[event_id2](_data) 1539 ) 1540 ); 1541 } else if (event_callbacks[event_id] && config) { 1542 if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1", "sse_v3"].includes( 1543 config.protocol 1544 )) { 1545 unclosed_events.delete(event_id); 1546 } 1547 let fn = event_callbacks[event_id]; 1548 if (typeof window !== "undefined" && typeof document !== "undefined") { 1549 setTimeout(fn, 0, _data); 1550 } else { 1551 fn(_data); 1552 } 1553 } else { 1554 if (!pending_stream_messages[event_id]) { 1555 pending_stream_messages[event_id] = []; 1556 } 1557 pending_stream_messages[event_id].push(_data); 1558 } 1559 }; 1560 stream2.onerror = async function(e) { 1561 console.error(e); 1562 await Promise.all( 1563 Object.keys(event_callbacks).map( 1564 (event_id) => event_callbacks[event_id]({ 1565 msg: "broken_connection", 1566 message: BROKEN_CONNECTION_MSG 1567 }) 1568 ) 1569 ); 1570 }; 1571} 1572function close_stream(stream_status, abort_controller) { 1573 if (stream_status) { 1574 stream_status.open = false; 1575 abort_controller?.abort(); 1576 } 1577} 1578function apply_diff_stream(pending_diff_streams, event_id, data) { 1579 let is_first_generation = !pending_diff_streams[event_id]; 1580 if (is_first_generation) { 1581 pending_diff_streams[event_id] = []; 1582 data.data.forEach((value, i) => { 1583 pending_diff_streams[event_id][i] = value; 1584 }); 1585 } else { 1586 data.data.forEach((value, i) => { 1587 let new_data = apply_diff(pending_diff_streams[event_id][i], value); 1588 pending_diff_streams[event_id][i] = new_data; 1589 data.data[i] = new_data; 1590 }); 1591 } 1592} 1593function apply_diff(obj, diff) { 1594 diff.forEach(([action, path, value]) => { 1595 obj = apply_edit(obj, path, action, value); 1596 }); 1597 return obj; 1598} 1599function apply_edit(target, path, action, value) { 1600 if (path.length === 0) { 1601 if (action === "replace") { 1602 return value; 1603 } else if (action === "append") { 1604 return target + value; 1605 } 1606 throw new Error(`Unsupported action: ${action}`); 1607 } 1608 let current = target; 1609 for (let i = 0; i < path.length - 1; i++) { 1610 current = current[path[i]]; 1611 } 1612 const last_path = path[path.length - 1]; 1613 switch (action) { 1614 case "replace": 1615 current[last_path] = value; 1616 break; 1617 case "append": 1618 current[last_path] += value; 1619 break; 1620 case "add": 1621 if (Array.isArray(current)) { 1622 current.splice(Number(last_path), 0, value); 1623 } else { 1624 current[last_path] = value; 1625 } 1626 break; 1627 case "delete": 1628 if (Array.isArray(current)) {
1629 current.splice(Number(last_path), 1); 1630 } else { 1631 delete current[last_path]; 1632 } 1633 break; 1634 default: 1635 throw new Error(`Unknown action: ${action}`); 1636 } 1637 return target; 1638} 1639function readable_stream(input, init = {}) { 1640 const instance = { 1641 close: () => { 1642 console.warn("Method not implemented."); 1643 }, 1644 onerror: null, 1645 onmessage: null, 1646 onopen: null, 1647 readyState: 0, 1648 url: input.toString(), 1649 withCredentials: false, 1650 CONNECTING: 0, 1651 OPEN: 1, 1652 CLOSED: 2, 1653 addEventListener: () => { 1654 throw new Error("Method not implemented."); 1655 }, 1656 dispatchEvent: () => { 1657 throw new Error("Method not implemented."); 1658 }, 1659 removeEventListener: () => { 1660 throw new Error("Method not implemented."); 1661 } 1662 }; 1663 stream(input, init).then(async (res) => { 1664 instance.readyState = instance.OPEN; 1665 try { 1666 for await (const chunk of res) { 1667 instance.onmessage && instance.onmessage(chunk); 1668 } 1669 instance.readyState = instance.CLOSED; 1670 } catch (e) { 1671 instance.onerror && instance.onerror(e); 1672 instance.readyState = instance.CLOSED; 1673 } 1674 }).catch((e) => { 1675 console.error(e); 1676 instance.onerror && instance.onerror(e); 1677 instance.readyState = instance.CLOSED; 1678 }); 1679 return instance; 1680} 1681 1682function submit(endpoint, data = {}, event_data, trigger_id, all_events, additional_headers) { 1683 try { 1684 let fire_event = function(event) { 1685 if (all_events || events_to_publish[event.type]) { 1686 push_event(event); 1687 } 1688 }, close = function() { 1689 done = true; 1690 while (resolvers.length > 0) 1691 resolvers.shift()({ 1692 value: void 0, 1693 done: true 1694 }); 1695 }, push = function(data2) { 1696 if (resolvers.length > 0) { 1697 resolvers.shift()(data2); 1698 } else { 1699 values.push(data2); 1700 } 1701 }, push_error = function(error) { 1702 push(thenable_reject(error)); 1703 close(); 1704 }, push_event = function(event) { 1705 push({ value: event, done: false }); 1706 }, next = function() { 1707 if (values.length > 0) { 1708 return Promise.resolve(values.shift()); 1709 } 1710 return new Promise((resolve) => resolvers.push(resolve)); 1711 }; 1712 const { token } = this.options; 1713 const { 1714 fetch, 1715 app_reference, 1716 config, 1717 session_hash, 1718 api_info, 1719 api_map, 1720 stream_status, 1721 pending_stream_messages, 1722 pending_diff_streams, 1723 event_callbacks, 1724 unclosed_events, 1725 post_data, 1726 options, 1727 api_prefix 1728 } = this; 1729 const addt_headers = additional_headers || { "x-gradio-user": "api" }; 1730 const that = this; 1731 if (!api_info) throw new Error("No API found"); 1732 if (!config) throw new Error("Could not resolve app config"); 1733 let { fn_index, endpoint_info, dependency } = get_endpoint_info( 1734 api_info, 1735 endpoint, 1736 api_map, 1737 config 1738 ); 1739 let resolved_data = map_data_to_params(data, endpoint_info); 1740 let stream; 1741 let protocol = config.protocol ?? "ws"; 1742 if (protocol === "ws") { 1743 throw new Error("WebSocket protocol is not supported in this version"); 1744 } 1745 let event_id_final = ""; 1746 let event_id_cb = () => event_id_final; 1747 const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint; 1748 let payload; 1749 let event_id = null; 1750 let complete = false; 1751 let last_status = {}; 1752 let url_params = typeof window !== "undefined" && typeof document !== "undefined" ? new URLSearchParams(window.location.search).toString() : ""; 1753 const events_to_publish = options?.events?.reduce( 1754 (acc, event) => { 1755 acc[event] = true; 1756 return acc; 1757 }, 1758 {} 1759 ) || {}; 1760 async function cancel() { 1761 let reset_request = {}; 1762 let cancel_request = {}; 1763 reset_request = { event_id }; 1764 cancel_request = { event_id, session_hash, fn_index };
1765 try { 1766 if (!config) { 1767 throw new Error("Could not resolve app config"); 1768 } 1769 if ("event_id" in cancel_request) { 1770 await fetch(`${config.root}${api_prefix}/${CANCEL_URL}`, { 1771 headers: { "Content-Type": "application/json" }, 1772 method: "POST", 1773 body: JSON.stringify(cancel_request) 1774 }); 1775 } 1776 await fetch(`${config.root}${api_prefix}/${RESET_URL}`, { 1777 headers: { "Content-Type": "application/json" }, 1778 method: "POST", 1779 body: JSON.stringify(reset_request) 1780 }); 1781 } catch (e) { 1782 console.warn( 1783 "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable." 1784 ); 1785 } 1786 } 1787 const resolve_heartbeat = async (config2) => { 1788 await this._resolve_heartbeat(config2); 1789 }; 1790 async function handle_render_config(render_config) { 1791 if (!config) return; 1792 let render_id = render_config.render_id; 1793 config.components = [ 1794 ...config.components.filter((c) => c.props.rendered_in !== render_id), 1795 ...render_config.components 1796 ]; 1797 config.dependencies = [ 1798 ...config.dependencies.filter((d) => d.rendered_in !== render_id), 1799 ...render_config.dependencies 1800 ]; 1801 const any_state = config.components.some((c) => c.type === "state"); 1802 const any_unload = config.dependencies.some( 1803 (d) => d.targets.some((t) => t[1] === "unload") 1804 ); 1805 config.connect_heartbeat = any_state || any_unload; 1806 await resolve_heartbeat(config); 1807 fire_event({ 1808 type: "render", 1809 data: render_config, 1810 endpoint: _endpoint, 1811 fn_index 1812 }); 1813 } 1814 const job = this.handle_blob( 1815 config.root, 1816 resolved_data, 1817 endpoint_info 1818 ).then(async (_payload) => { 1819 let input_data = handle_payload( 1820 _payload, 1821 dependency, 1822 config.components, 1823 "input", 1824 true 1825 ); 1826 payload = { 1827 data: input_data || [], 1828 event_data, 1829 fn_index, 1830 trigger_id 1831 }; 1832 if (skip_queue(fn_index, config)) { 1833 fire_event({ 1834 type: "status", 1835 endpoint: _endpoint, 1836 stage: "pending", 1837 queue: false, 1838 fn_index, 1839 time: /* @__PURE__ */ new Date() 1840 }); 1841 post_data( 1842 `${config.root}${api_prefix}/run${_endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`}${url_params ? "?" + url_params : ""}`, 1843 { 1844 ...payload, 1845 session_hash 1846 }, 1847 addt_headers 1848 ).then(async ([output, status_code]) => { 1849 const data2 = output.data; 1850 if (status_code == 200) { 1851 fire_event({ 1852 type: "data", 1853 endpoint: _endpoint, 1854 fn_index, 1855 data: handle_payload( 1856 data2, 1857 dependency, 1858 config.components, 1859 "output", 1860 options.with_null_state 1861 ), 1862 time: /* @__PURE__ */ new Date(), 1863 event_data, 1864 trigger_id 1865 }); 1866 if (output.render_config) { 1867 await handle_render_config(output.render_config); 1868 } 1869 fire_event({ 1870 type: "status", 1871 endpoint: _endpoint, 1872 fn_index, 1873 stage: "complete", 1874 eta: output.average_duration, 1875 queue: false, 1876 time: /* @__PURE__ */ new Date() 1877 }); 1878 } else { 1879 const is_connection_error = output?.error === BROKEN_CONNECTION_MSG; 1880 fire_event({ 1881 type: "status", 1882 stage: "error", 1883 endpoint: _endpoint, 1884 fn_index, 1885 message: output.error, 1886 broken: is_connection_error, 1887 queue: false, 1888 time: /* @__PURE__ */ new Date() 1889 }); 1890 } 1891 }).catch((e) => { 1892 fire_event({ 1893 type: "status", 1894 stage: "error", 1895 message: e.message, 1896 endpoint: _endpoint, 1897 fn_index, 1898 queue: false, 1899 time: /* @__PURE__ */ new Date() 1900 }); 1901 }); 1902 } else if (protocol == "sse") { 1903 fire_event({ 1904 type: "status", 1905 stage: "pending", 1906 queue: true, 1907 endpoint: _endpoint, 1908 fn_index, 1909 time: /* @__PURE__ */ new Date() 1910 }); 1911 var params = new URLSearchParams({ 1912 fn_index: fn_index.toString(), 1913 session_hash 1914 }).toString(); 1915 let url = new URL( 1916 `${config.root}${api_prefix}/${SSE_URL}?${url_params ? url_params + "&" : ""}${params}` 1917 ); 1918 if (this.jwt) { 1919 url.searchParams.set("__sign", this.jwt); 1920 } 1921 stream = this.stream(url); 1922 if (!stream) { 1923 return Promise.reject( 1924 new Error("Cannot connect to SSE endpoint: " + url.toString()) 1925 ); 1926 } 1927 stream.onmessage = async function(event) { 1928 const _data = JSON.parse(event.data); 1929 const { type, status, data: data2 } = handle_message( 1930 _data, 1931 last_status[fn_index] 1932 ); 1933 if (type === "update" && status && !complete) { 1934 fire_event({ 1935 type: "status", 1936 endpoint: _endpoint, 1937 fn_index, 1938 time: /* @__PURE__ */ new Date(), 1939 ...status 1940 }); 1941 if (status.stage === "error") { 1942 stream?.close(); 1943 close(); 1944 } 1945 } else if (type === "data") { 1946 let [_, status2] = await post_data( 1947 `${config.root}${api_prefix}/queue/data`, 1948 { 1949 ...payload, 1950 session_hash, 1951 event_id 1952 } 1953 ); 1954 if (status2 !== 200) { 1955 fire_event({ 1956 type: "status", 1957 stage: "error", 1958 message: BROKEN_CONNECTION_MSG, 1959 queue: true, 1960 endpoint: _endpoint, 1961 fn_index, 1962 time: /* @__PURE__ */ new Date() 1963 }); 1964 stream?.close(); 1965 close(); 1966 } 1967 } else if (type === "complete") { 1968 complete = status; 1969 } else if (type === "log") { 1970 fire_event({ 1971 type: "log", 1972 title: data2.title, 1973 log: data2.log, 1974 level: data2.level, 1975 endpoint: _endpoint, 1976 duration: data2.duration, 1977 visible: data2.visible, 1978 fn_index 1979 }); 1980 } else if (type === "generating" || type === "streaming") { 1981 fire_event({ 1982 type: "status", 1983 time: /* @__PURE__ */ new Date(), 1984 ...status, 1985 stage: status?.stage, 1986 queue: true, 1987 endpoint: _endpoint, 1988 fn_index 1989 }); 1990 } 1991 if (data2) { 1992 fire_event({ 1993 type: "data", 1994 time: /* @__PURE__ */ new Date(), 1995 data: handle_payload( 1996 data2.data, 1997 dependency, 1998 config.components, 1999 "output", 2000 options.with_null_state 2001 ), 2002 endpoint: _endpoint, 2003 fn_index, 2004 event_data, 2005 trigger_id 2006 }); 2007 if (complete) { 2008 fire_event({ 2009 type: "status", 2010 time: /* @__PURE__ */ new Date(), 2011 ...complete, 2012 stage: status?.stage, 2013 queue: true, 2014 endpoint: _endpoint, 2015 fn_index 2016 }); 2017 stream?.close(); 2018 close(); 2019 } 2020 } 2021 }; 2022 } else if (protocol == "sse_v1" || protocol == "sse_v2" || protocol == "sse_v2.1" || protocol == "sse_v3") { 2023 fire_event({ 2024 type: "status", 2025 stage: "pending", 2026 queue: true, 2027 endpoint: _endpoint, 2028 fn_index, 2029 time: /* @__PURE__ */ new Date() 2030 }); 2031 let hostname = ""; 2032 if (typeof window !== "undefined" && typeof document !== "undefined") { 2033 hostname = window?.location?.hostname; 2034 } 2035 let hfhubdev = "dev.spaces.huggingface.tech"; 2036 const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`; 2037 const is_zerogpu_iframe = typeof window !== "undefined" && typeof document !== "undefined" && window.parent != window && window.supports_zerogpu_headers; 2038 const zerogpu_auth_promise = is_zerogpu_iframe ? post_message("zerogpu-headers", origin) : Promise.resolve(null); 2039 const post_data_promise = zerogpu_auth_promise.then((headers) => { 2040 const combined_headers = { ...addt_headers, ...headers || {} }; 2041 return post_data( 2042 `${config.root}${api_prefix}/${SSE_DATA_URL}?${url_params}`, 2043 { 2044 ...payload, 2045 session_hash 2046 }, 2047 combined_headers 2048 ); 2049 }); 2050 return post_data_promise.then(async ([response, status]) => { 2051 if (response.event_id) { 2052 event_id_final = response.event_id; 2053 } 2054 if (status === 503) { 2055 fire_event({ 2056 type: "status", 2057 stage: "error", 2058 message: QUEUE_FULL_MSG, 2059 queue: true, 2060 endpoint: _endpoint, 2061 fn_index, 2062 time: /* @__PURE__ */ new Date(), 2063 visible: true 2064 }); 2065 } else if (status === 422) { 2066 fire_event({ 2067 type: "status", 2068 stage: "error", 2069 message: response.detail, 2070 queue: true, 2071 endpoint: _endpoint, 2072 fn_index, 2073 code: "validation_error", 2074 time: /* @__PURE__ */ new Date(), 2075 visible: true 2076 }); 2077 close(); 2078 } else if (status !== 200) { 2079 const is_connection_error = response?.error === BROKEN_CONNECTION_MSG; 2080 fire_event({ 2081 type: "status", 2082 stage: "error", 2083 broken: is_connection_error, 2084 message: is_connection_error ? BROKEN_CONNECTION_MSG : response.detail || response.error, 2085 queue: true, 2086 endpoint: _endpoint, 2087 fn_index, 2088 time: /* @__PURE__ */ new Date(), 2089 visible: true 2090 }); 2091 } else { 2092 event_id = response.event_id; 2093 event_id_final = event_id; 2094 let callback = async function(_data) { 2095 try { 2096 const { type, status: status2, data: data2, original_msg } = handle_message( 2097 _data, 2098 last_status[fn_index] 2099 ); 2100 if (type == "heartbeat") { 2101 return; 2102 } 2103 if (type === "update" && status2 && !complete) { 2104 fire_event({ 2105 type: "status", 2106 endpoint: _endpoint, 2107 fn_index, 2108 time: /* @__PURE__ */ new Date(), 2109 original_msg, 2110 ...status2 2111 }); 2112 } else if (type === "complete") { 2113 complete = status2; 2114 } else if (type == "unexpected_error" || type == "broken_connection") { 2115 console.error("Unexpected error", status2?.message); 2116 const broken = type === "broken_connection"; 2117 fire_event({ 2118 type: "status", 2119 stage: "error", 2120 message: status2?.message || "An Unexpected Error Occurred!", 2121 queue: true, 2122 endpoint: _endpoint, 2123 broken, 2124 session_not_found: status2?.session_not_found, 2125 fn_index, 2126 time: /* @__PURE__ */ new Date() 2127 }); 2128 } else if (type === "log") { 2129 fire_event({ 2130 type: "log", 2131 title: data2.title, 2132 log: data2.log, 2133 level: data2.level, 2134 endpoint: _endpoint, 2135 duration: data2.duration, 2136 visible: data2.visible, 2137 fn_index 2138 }); 2139 return; 2140 } else if (type === "generating" || type === "streaming") { 2141 fire_event({ 2142 type: "status", 2143 time: /* @__PURE__ */ new Date(), 2144 ...status2, 2145 stage: status2?.stage, 2146 queue: true, 2147 endpoint: _endpoint, 2148 fn_index 2149 });
2150 if (data2 && dependency.connection !== "stream" && ["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) { 2151 apply_diff_stream(pending_diff_streams, event_id, data2); 2152 } 2153 } 2154 if (data2) { 2155 fire_event({ 2156 type: "data", 2157 time: /* @__PURE__ */ new Date(), 2158 data: handle_payload( 2159 data2.data, 2160 dependency, 2161 config.components, 2162 "output", 2163 options.with_null_state 2164 ), 2165 endpoint: _endpoint, 2166 fn_index 2167 }); 2168 if (data2.render_config) { 2169 await handle_render_config(data2.render_config); 2170 } 2171 if (complete) { 2172 fire_event({ 2173 type: "status", 2174 time: /* @__PURE__ */ new Date(), 2175 ...complete, 2176 stage: status2?.stage, 2177 queue: true, 2178 endpoint: _endpoint, 2179 fn_index 2180 }); 2181 close(); 2182 } 2183 } 2184 if (status2?.stage === "complete" || status2?.stage === "error") { 2185 if (event_callbacks[event_id]) { 2186 delete event_callbacks[event_id]; 2187 } 2188 if (event_id in pending_diff_streams) { 2189 delete pending_diff_streams[event_id]; 2190 } 2191 } 2192 } catch (e) { 2193 console.error("Unexpected client exception", e); 2194 fire_event({ 2195 type: "status", 2196 stage: "error", 2197 message: "An Unexpected Error Occurred!", 2198 queue: true, 2199 endpoint: _endpoint, 2200 fn_index, 2201 time: /* @__PURE__ */ new Date() 2202 }); 2203 if (["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) { 2204 close_stream(stream_status, that.abort_controller); 2205 stream_status.open = false; 2206 close(); 2207 } 2208 } 2209 }; 2210 if (event_id in pending_stream_messages) { 2211 pending_stream_messages[event_id].forEach((msg) => callback(msg)); 2212 delete pending_stream_messages[event_id]; 2213 } 2214 event_callbacks[event_id] = callback; 2215 unclosed_events.add(event_id); 2216 if (!stream_status.open) { 2217 await this.open_stream(); 2218 } 2219 } 2220 }); 2221 } 2222 }); 2223 let done = false; 2224 const values = []; 2225 const resolvers = []; 2226 const iterator = { 2227 [Symbol.asyncIterator]: () => iterator, 2228 next, 2229 throw: async (value) => { 2230 push_error(value); 2231 return next(); 2232 }, 2233 return: async () => { 2234 close(); 2235 return { value: void 0, done: true }; 2236 }, 2237 cancel, 2238 send_chunk: (payload2) => { 2239 this.post_data(`${config.root}${api_prefix}/stream/${event_id_final}`, { 2240 ...payload2, 2241 session_hash: this.session_hash 2242 }); 2243 }, 2244 close_stream: () => { 2245 this.post_data( 2246 `${config.root}${api_prefix}/stream/${event_id_final}/close`, 2247 {} 2248 ); 2249 close(); 2250 }, 2251 event_id: () => event_id_final, 2252 wait_for_id: async () => { 2253 await job; 2254 return event_id; 2255 } 2256 }; 2257 return iterator; 2258 } catch (error) { 2259 console.error("Submit function encountered an error:", error); 2260 throw error; 2261 } 2262} 2263function thenable_reject(error) { 2264 return { 2265 then: (resolve, reject) => reject(error) 2266 }; 2267} 2268function get_endpoint_info(api_info, endpoint, api_map, config) { 2269 let fn_index; 2270 let endpoint_info; 2271 let dependency; 2272 if (typeof endpoint === "number") { 2273 fn_index = endpoint; 2274 endpoint_info = api_info.unnamed_endpoints[fn_index]; 2275 dependency = config.dependencies.find((dep) => dep.id == endpoint); 2276 } else { 2277 const trimmed_endpoint = endpoint.replace(/^\//, ""); 2278 fn_index = api_map[trimmed_endpoint]; 2279 endpoint_info = api_info.named_endpoints[endpoint.trim()]; 2280 dependency = config.dependencies.find( 2281 (dep) => dep.id == api_map[trimmed_endpoint] 2282 ); 2283 } 2284 if (typeof fn_index !== "number") { 2285 throw new Error( 2286 "There is no endpoint matching that name of fn_index matching that number." 2287 ); 2288 } 2289 return { fn_index, endpoint_info, dependency }; 2290} 2291 2292class Client { 2293 app_reference; 2294 options; 2295 deep_link = null; 2296 config; 2297 api_prefix = ""; 2298 api_info; 2299 api_map = {}; 2300 session_hash = Math.random().toString(36).substring(2); 2301 jwt = false;
2302 last_status = {}; 2303 cookies = null; 2304 // streaming 2305 stream_status = { open: false }; 2306 closed = false; 2307 pending_stream_messages = {}; 2308 pending_diff_streams = {}; 2309 event_callbacks = {}; 2310 unclosed_events = /* @__PURE__ */ new Set(); 2311 heartbeat_event = null; 2312 abort_controller = null; 2313 stream_instance = null; 2314 current_payload; 2315 get_url_config(url = null) { 2316 if (!this.config) { 2317 throw new Error(CONFIG_ERROR_MSG); 2318 } 2319 if (url === null) { 2320 url = window.location.href; 2321 } 2322 const stripSlashes = (str) => str.replace(/^\/+|\/+$/g, ""); 2323 let root_path = stripSlashes(new URL(this.config.root).pathname); 2324 let url_path = stripSlashes(new URL(url).pathname); 2325 let page; 2326 if (!url_path.startsWith(root_path)) { 2327 page = ""; 2328 } else { 2329 page = stripSlashes(url_path.substring(root_path.length)); 2330 } 2331 return this.get_page_config(page); 2332 } 2333 get_page_config(page) { 2334 if (!this.config) { 2335 throw new Error(CONFIG_ERROR_MSG); 2336 } 2337 let config = this.config; 2338 if (!(page in config.page)) { 2339 page = ""; 2340 } 2341 return { 2342 ...config, 2343 current_page: page, 2344 layout: config.page[page].layout, 2345 components: config.components.filter( 2346 (c) => config.page[page].components.includes(c.id) 2347 ), 2348 dependencies: this.config.dependencies.filter( 2349 (d) => config.page[page].dependencies.includes(d.id) 2350 ) 2351 }; 2352 } 2353 fetch(input, init) { 2354 const headers = new Headers(init?.headers || {}); 2355 if (this && this.cookies) { 2356 headers.append("Cookie", this.cookies); 2357 } 2358 if (this && this.options.headers) { 2359 let additional_headers = new Headers(this.options.headers); 2360 additional_headers.forEach((value, name) => { 2361 headers.append(name, value); 2362 }); 2363 } 2364 return fetch(input, { ...init, headers }); 2365 } 2366 stream(url) { 2367 const headers = new Headers(); 2368 if (this && this.cookies) { 2369 headers.append("Cookie", this.cookies); 2370 } 2371 if (this && this.options.headers) { 2372 let additional_headers = new Headers(this.options.headers); 2373 additional_headers.forEach((value, name) => { 2374 headers.append(name, value); 2375 }); 2376 } 2377 if (this && this.options.token) { 2378 headers.append("Authorization", `Bearer ${this.options.token}`); 2379 } 2380 this.abort_controller = new AbortController(); 2381 this.stream_instance = readable_stream(url.toString(), { 2382 credentials: "include", 2383 headers, 2384 signal: this.abort_controller.signal 2385 }); 2386 return this.stream_instance; 2387 } 2388 view_api; 2389 upload_files; 2390 upload; 2391 handle_blob; 2392 post_data; 2393 submit; 2394 predict; 2395 open_stream; 2396 resolve_config; 2397 resolve_cookies; 2398 constructor(app_reference, options = { events: ["data"] }) { 2399 this.app_reference = app_reference; 2400 this.deep_link = options.query_params?.deep_link || null; 2401 if (!options.events) { 2402 options.events = ["data"]; 2403 } 2404 this.options = options; 2405 this.current_payload = {}; 2406 if (options.cookies) { 2407 this.cookies = options.cookies; 2408 } 2409 this.view_api = view_api.bind(this); 2410 this.upload_files = upload_files.bind(this); 2411 this.handle_blob = handle_blob.bind(this); 2412 this.post_data = post_data.bind(this); 2413 this.submit = submit.bind(this); 2414 this.predict = predict.bind(this); 2415 this.open_stream = open_stream.bind(this); 2416 this.resolve_config = resolve_config.bind(this); 2417 this.resolve_cookies = resolve_cookies.bind(this); 2418 this.upload = upload.bind(this); 2419 this.fetch = this.fetch.bind(this); 2420 this.handle_space_success = this.handle_space_success.bind(this); 2421 this.stream = this.stream.bind(this); 2422 } 2423 async init() { 2424 if (this.options.auth) { 2425 await this.resolve_cookies(); 2426 } 2427 await this._resolve_config().then( 2428 ({ config }) => this._resolve_heartbeat(config) 2429 ); 2430 this.api_info = await this.view_api(); 2431 this.api_map = map_names_to_ids(this.config?.dependencies || []); 2432 } 2433 async _resolve_heartbeat(_config) { 2434 if (_config) { 2435 this.config = _config; 2436 this.api_prefix = _config.api_prefix || ""; 2437 if (this.config && this.config.connect_heartbeat) { 2438 if (this.config.space_id && this.options.token) { 2439 this.jwt = await get_jwt( 2440 this.config.space_id, 2441 this.options.token, 2442 this.cookies 2443 ); 2444 } 2445 } 2446 } 2447 if (_config.space_id && this.options.token) { 2448 this.jwt = await get_jwt(_config.space_id, this.options.token); 2449 } 2450 if (this.config && this.config.connect_heartbeat) { 2451 const heartbeat_url = new URL( 2452 `${this.config.root}${this.api_prefix}/${HEARTBEAT_URL}/${this.session_hash}` 2453 ); 2454 if (this.jwt) { 2455 heartbeat_url.searchParams.set("__sign", this.jwt); 2456 } 2457 if (!this.heartbeat_event) { 2458 this.heartbeat_event = this.stream(heartbeat_url); 2459 } 2460 } 2461 } 2462 static async connect(app_reference, options = { 2463 events: ["data"] 2464 }) { 2465 const client2 = new this(app_reference, options); 2466 if (options.session_hash) { 2467 client2.session_hash = options.session_hash; 2468 } 2469 await client2.init(); 2470 return client2; 2471 } 2472 async reconnect() { 2473 const app_id_url = new URL( 2474 `${this.config.root}${this.api_prefix}/${APP_ID_URL}` 2475 ); 2476 let app_id; 2477 try { 2478 const response = await this.fetch(app_id_url); 2479 if (!response.ok) { 2480 throw new Error(); 2481 } 2482 app_id = (await response.json()).app_id; 2483 } catch (e) { 2484 return "broken"; 2485 } 2486 if (app_id !== this.config.app_id) { 2487 return "changed"; 2488 } 2489 return "connected"; 2490 } 2491 close() { 2492 this.closed = true; 2493 close_stream(this.stream_status, this.abort_controller); 2494 } 2495 set_current_payload(payload) { 2496 this.current_payload = payload; 2497 } 2498 static async duplicate(app_reference, options = { 2499 events: ["data"] 2500 }) { 2501 return duplicate(app_reference, options); 2502 } 2503 async _resolve_config() { 2504 const { http_protocol, host, space_id } = await process_endpoint( 2505 this.app_reference, 2506 this.options.token 2507 ); 2508 const { status_callback } = this.options; 2509 if (space_id && status_callback) { 2510 await check_and_wake_space(space_id, status_callback); 2511 }
2512 let config; 2513 try { 2514 let configUrl = `${http_protocol}//${host}`; 2515 config = await this.resolve_config(configUrl); 2516 if (!config) { 2517 throw new Error(CONFIG_ERROR_MSG); 2518 } 2519 return this.config_success(config); 2520 } catch (e) { 2521 if (space_id && status_callback) { 2522 check_space_status( 2523 space_id, 2524 RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain", 2525 this.handle_space_success 2526 ); 2527 } else { 2528 if (status_callback) 2529 status_callback({ 2530 status: "error", 2531 message: "Could not load this space.", 2532 load_status: "error", 2533 detail: "NOT_FOUND" 2534 }); 2535 throw Error(e); 2536 } 2537 } 2538 } 2539 async config_success(_config) { 2540 this.config = _config; 2541 this.api_prefix = _config.api_prefix || ""; 2542 if (this.config.auth_required) { 2543 return this.prepare_return_obj(); 2544 } 2545 try { 2546 this.api_info = await this.view_api(); 2547 } catch (e) { 2548 console.error(API_INFO_ERROR_MSG + e.message); 2549 } 2550 return this.prepare_return_obj(); 2551 } 2552 async handle_space_success(status) { 2553 if (!this) { 2554 throw new Error(CONFIG_ERROR_MSG); 2555 } 2556 const { status_callback } = this.options; 2557 if (status_callback) status_callback(status); 2558 if (status.status === "running") { 2559 try { 2560 this.config = await this._resolve_config(); 2561 this.api_prefix = this?.config?.api_prefix || ""; 2562 if (!this.config) { 2563 throw new Error(CONFIG_ERROR_MSG); 2564 } 2565 const _config = await this.config_success(this.config); 2566 return _config; 2567 } catch (e) { 2568 if (status_callback) { 2569 status_callback({ 2570 status: "error", 2571 message: "Could not load this space.", 2572 load_status: "error", 2573 detail: "NOT_FOUND" 2574 }); 2575 } 2576 throw e; 2577 } 2578 } 2579 } 2580 async component_server(component_id, fn_name, data) { 2581 if (!this.config) { 2582 throw new Error(CONFIG_ERROR_MSG); 2583 } 2584 const headers = {}; 2585 const { token } = this.options; 2586 const { session_hash } = this; 2587 if (token) { 2588 headers.Authorization = `Bearer ${this.options.token}`; 2589 } 2590 let root_url;
2591 let component = this.config.components.find( 2592 (comp) => comp.id === component_id 2593 ); 2594 if (component?.props?.root_url) { 2595 root_url = component.props.root_url; 2596 } else { 2597 root_url = this.config.root; 2598 } 2599 let body; 2600 if (typeof data === "object" && data !== null && "binary" in data) { 2601 const _data = data; 2602 body = new FormData(); 2603 for (const key in _data.data) { 2604 if (key === "binary") continue; 2605 body.append(key, _data.data[key]); 2606 } 2607 body.set("component_id", component_id.toString()); 2608 body.set("fn_name", fn_name); 2609 body.set("session_hash", session_hash); 2610 } else { 2611 body = JSON.stringify({ 2612 data, 2613 component_id, 2614 fn_name, 2615 session_hash 2616 }); 2617 headers["Content-Type"] = "application/json"; 2618 } 2619 if (token) { 2620 headers.Authorization = `Bearer ${token}`; 2621 } 2622 try { 2623 const response = await this.fetch( 2624 `${root_url}${this.api_prefix}/${COMPONENT_SERVER_URL}/`, 2625 { 2626 method: "POST", 2627 body, 2628 headers, 2629 credentials: "include" 2630 } 2631 ); 2632 if (!response.ok) { 2633 throw new Error( 2634 "Could not connect to component server: " + response.statusText 2635 ); 2636 } 2637 const output = await response.json(); 2638 return output; 2639 } catch (e) { 2640 console.warn(e); 2641 } 2642 } 2643 set_cookies(raw_cookies) { 2644 this.cookies = parse_and_set_cookies(raw_cookies).join("; "); 2645 } 2646 prepare_return_obj() { 2647 return { 2648 config: this.config, 2649 predict: this.predict, 2650 submit: this.submit, 2651 view_api: this.view_api, 2652 component_server: this.component_server 2653 }; 2654 } 2655} 2656 2657const node_env = "production"; 2658const DEV = !node_env.toLowerCase().startsWith("prod"); 2659 2660// Store the references to globals in case someone tries to monkey patch these, causing the below 2661// to de-opt (this occurs often when using popular extensions). 2662var is_array = Array.isArray; 2663var index_of = Array.prototype.indexOf; 2664var array_from = Array.from; 2665var define_property = Object.defineProperty; 2666var get_descriptor = Object.getOwnPropertyDescriptor; 2667var get_descriptors = Object.getOwnPropertyDescriptors; 2668var object_prototype = Object.prototype; 2669var array_prototype = Array.prototype; 2670var get_prototype_of = Object.getPrototypeOf; 2671var is_extensible = Object.isExtensible; 2672 2673/** 2674 * @param {any} thing 2675 * @returns {thing is Function} 2676 */ 2677function is_function(thing) { 2678 return typeof thing === 'function'; 2679} 2680 2681const noop = () => {}; 2682 2683// Adapted from https://github.com/then/is-promise/blob/master/index.js 2684// Distributed under MIT License https://github.com/then/is-promise/blob/master/LICENSE 2685 2686/** 2687 * @template [T=any] 2688 * @param {any} value 2689 * @returns {value is PromiseLike<T>} 2690 */ 2691function is_promise(value) { 2692 return typeof value?.then === 'function'; 2693} 2694 2695/** @param {Function} fn */ 2696function run$1(fn) { 2697 return fn(); 2698} 2699 2700/** @param {Array<() => void>} arr */ 2701function run_all(arr) { 2702 for (var i = 0; i < arr.length; i++) { 2703 arr[i](); 2704 } 2705} 2706 2707/** 2708 * TODO replace with Promise.withResolvers once supported widely enough 2709 * @template [T=void] 2710 */ 2711function deferred() { 2712 /** @type {(value: T) => void} */ 2713 var resolve; 2714 2715 /** @type {(reason: any) => void} */ 2716 var reject; 2717 2718 /** @type {Promise<T>} */ 2719 var promise = new Promise((res, rej) => { 2720 resolve = res; 2721 reject = rej; 2722 }); 2723 2724 // @ts-expect-error 2725 return { promise, resolve, reject }; 2726} 2727 2728/** 2729 * When encountering a situation like `let [a, b, c] = $derived(blah())`, 2730 * we need to stash an intermediate value that `a`, `b`, and `c` derive 2731 * from, in case it's an iterable 2732 * @template T 2733 * @param {ArrayLike<T> | Iterable<T>} value 2734 * @param {number} [n] 2735 * @returns {Array<T>} 2736 */ 2737function to_array(value, n) { 2738 // return arrays unchanged 2739 if (Array.isArray(value)) { 2740 return value; 2741 } 2742 2743 // if value is not iterable, or `n` is unspecified (indicates a rest 2744 // element, which means we're not concerned about unbounded iterables) 2745 // convert to an array with `Array.from` 2746 if (n === undefined || !(Symbol.iterator in value)) { 2747 return Array.from(value); 2748 } 2749 2750 // otherwise, populate an array with `n` values 2751 2752 /** @type {T[]} */ 2753 const array = []; 2754 2755 for (const element of value) { 2756 array.push(element); 2757 if (array.length === n) break; 2758 } 2759 2760 return array; 2761} 2762 2763// General flags 2764const DERIVED = 1 << 1; 2765const EFFECT = 1 << 2; 2766const RENDER_EFFECT = 1 << 3; 2767/** 2768 * An effect that does not destroy its child effects when it reruns. 2769 * Runs as part of render effects, i.e. not eagerly as part of tree traversal or effect flushing. 2770 */ 2771const MANAGED_EFFECT = 1 << 24; 2772/** 2773 * An effect that does not destroy its child effects when it reruns (like MANAGED_EFFECT). 2774 * Runs eagerly as part of tree traversal or effect flushing. 2775 */ 2776const BLOCK_EFFECT = 1 << 4; 2777const BRANCH_EFFECT = 1 << 5; 2778const ROOT_EFFECT = 1 << 6; 2779const BOUNDARY_EFFECT = 1 << 7; 2780/** 2781 * Indicates that a reaction is connected to an effect root â either it is an effect, 2782 * or it is a derived that is depended on by at least one effect. If a derived has
2783 * no dependents, we can disconnect it from the graph, allowing it to either be 2784 * GC'd or reconnected later if an effect comes to depend on it again 2785 */ 2786const CONNECTED = 1 << 9; 2787const CLEAN = 1 << 10; 2788const DIRTY = 1 << 11; 2789const MAYBE_DIRTY = 1 << 12; 2790const INERT = 1 << 13; 2791const DESTROYED = 1 << 14; 2792 2793// Flags exclusive to effects 2794/** Set once an effect that should run synchronously has run */ 2795const EFFECT_RAN = 1 << 15; 2796/** 2797 * 'Transparent' effects do not create a transition boundary. 2798 * This is on a block effect 99% of the time but may also be on a branch effect if its parent block effect was pruned 2799 */ 2800const EFFECT_TRANSPARENT = 1 << 16; 2801const EAGER_EFFECT = 1 << 17; 2802const HEAD_EFFECT = 1 << 18; 2803const EFFECT_PRESERVED = 1 << 19; 2804const USER_EFFECT = 1 << 20; 2805const EFFECT_OFFSCREEN = 1 << 25; 2806 2807// Flags exclusive to deriveds 2808/** 2809 * Tells that we marked this derived and its reactions as visited during the "mark as (maybe) dirty"-phase. 2810 * Will be lifted during execution of the derived and during checking its dirty state (both are necessary 2811 * because a derived might be checked but not executed). 2812 */ 2813const WAS_MARKED = 1 << 15; 2814 2815// Flags used for async 2816const REACTION_IS_UPDATING = 1 << 21; 2817const ASYNC = 1 << 22; 2818 2819const ERROR_VALUE = 1 << 23; 2820 2821const STATE_SYMBOL = Symbol('$state'); 2822const LEGACY_PROPS = Symbol('legacy props'); 2823const LOADING_ATTR_SYMBOL = Symbol(''); 2824const PROXY_PATH_SYMBOL = Symbol('proxy path'); 2825 2826/** allow users to ignore aborted signal errors if `reason.name === 'StaleReactionError` */ 2827const STALE_REACTION = new (class StaleReactionError extends Error { 2828 name = 'StaleReactionError'; 2829 message = 'The reaction that called `getAbortSignal()` was re-run or destroyed'; 2830})(); 2831 2832const ELEMENT_NODE = 1; 2833const TEXT_NODE = 3; 2834const COMMENT_NODE = 8; 2835 2836/* This file is generated by scripts/process-messages/index.js. Do not edit! */ 2837 2838 2839/** 2840 * `%name%(...)` can only be used during component initialisation 2841 * @param {string} name 2842 * @returns {never} 2843 */ 2844function lifecycle_outside_component(name) { 2845 if (DEV) { 2846 const error = new Error(`lifecycle_outside_component\n\`${name}(...)\` can only be used during component initialisation\nhttps://svelte.dev/e/lifecycle_outside_component`); 2847 2848 error.name = 'Svelte error'; 2849 2850 throw error; 2851 } else { 2852 throw new Error(`https://svelte.dev/e/lifecycle_outside_component`); 2853 } 2854} 2855 2856/* This file is generated by scripts/process-messages/index.js. Do not edit! */ 2857 2858 2859/** 2860 * Cannot create a `$derived(...)` with an `await` expression outside of an effect tree 2861 * @returns {never} 2862 */ 2863function async_derived_orphan() { 2864 if (DEV) { 2865 const error = new Error(`async_derived_orphan\nCannot create a \`$derived(...)\` with an \`await\` expression outside of an effect tree\nhttps://svelte.dev/e/async_derived_orphan`); 2866 2867 error.name = 'Svelte error'; 2868 2869 throw error; 2870 } else { 2871 throw new Error(`https://svelte.dev/e/async_derived_orphan`); 2872 } 2873} 2874 2875/** 2876 * Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead 2877 * @returns {never} 2878 */ 2879function bind_invalid_checkbox_value() { 2880 if (DEV) { 2881 const error = new Error(`bind_invalid_checkbox_value\nUsing \`bind:value\` together with a checkbox input is not allowed. Use \`bind:checked\` instead\nhttps://svelte.dev/e/bind_invalid_checkbox_value`); 2882 2883 error.name = 'Svelte error'; 2884 2885 throw error; 2886 } else { 2887 throw new Error(`https://svelte.dev/e/bind_invalid_checkbox_value`); 2888 } 2889} 2890 2891/** 2892 * A derived value cannot reference itself recursively 2893 * @returns {never} 2894 */ 2895function derived_references_self() { 2896 if (DEV) { 2897 const error = new Error(`derived_references_self\nA derived value cannot reference itself recursively\nhttps://svelte.dev/e/derived_references_self`); 2898 2899 error.name = 'Svelte error'; 2900 2901 throw error; 2902 } else { 2903 throw new Error(`https://svelte.dev/e/derived_references_self`); 2904 } 2905} 2906 2907/** 2908 * `%rune%` cannot be used inside an effect cleanup function 2909 * @param {string} rune 2910 * @returns {never} 2911 */ 2912function effect_in_teardown(rune) { 2913 if (DEV) { 2914 const error = new Error(`effect_in_teardown\n\`${rune}\` cannot be used inside an effect cleanup function\nhttps://svelte.dev/e/effect_in_teardown`); 2915 2916 error.name = 'Svelte error'; 2917 2918 throw error; 2919 } else { 2920 throw new Error(`https://svelte.dev/e/effect_in_teardown`); 2921 } 2922} 2923 2924/** 2925 * Effect cannot be created inside a `$derived` value that was not itself created inside an effect 2926 * @returns {never} 2927 */ 2928function effect_in_unowned_derived() { 2929 if (DEV) { 2930 const error = new Error(`effect_in_unowned_derived\nEffect cannot be created inside a \`$derived\` value that was not itself created inside an effect\nhttps://svelte.dev/e/effect_in_unowned_derived`); 2931 2932 error.name = 'Svelte error'; 2933 2934 throw error; 2935 } else { 2936 throw new Error(`https://svelte.dev/e/effect_in_unowned_derived`); 2937 } 2938} 2939 2940/** 2941 * `%rune%` can only be used inside an effect (e.g. during component initialisation) 2942 * @param {string} rune 2943 * @returns {never} 2944 */ 2945function effect_orphan(rune) { 2946 if (DEV) { 2947 const error = new Error(`effect_orphan\n\`${rune}\` can only be used inside an effect (e.g. during component initialisation)\nhttps://svelte.dev/e/effect_orphan`); 2948 2949 error.name = 'Svelte error'; 2950 2951 throw error; 2952 } else { 2953 throw new Error(`https://svelte.dev/e/effect_orphan`); 2954 } 2955} 2956 2957/** 2958 * Maximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state 2959 * @returns {never} 2960 */ 2961function effect_update_depth_exceeded() { 2962 if (DEV) { 2963 const error = new Error(`effect_update_depth_exceeded\nMaximum update depth exceeded. This typically indicates that an effect reads and writes the same piece of state\nhttps://svelte.dev/e/effect_update_depth_exceeded`); 2964 2965 error.name = 'Svelte error'; 2966 2967 throw error; 2968 } else { 2969 throw new Error(`https://svelte.dev/e/effect_update_depth_exceeded`); 2970 } 2971} 2972 2973/** 2974 * Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}` 2975 * @returns {never} 2976 */
2977function invalid_snippet() { 2978 if (DEV) { 2979 const error = new Error(`invalid_snippet\nCould not \`{@render}\` snippet due to the expression being \`null\` or \`undefined\`. Consider using optional chaining \`{@render snippet?.()}\`\nhttps://svelte.dev/e/invalid_snippet`); 2980 2981 error.name = 'Svelte error'; 2982 2983 throw error; 2984 } else { 2985 throw new Error(`https://svelte.dev/e/invalid_snippet`); 2986 } 2987} 2988 2989/** 2990 * `%name%(...)` cannot be used in runes mode 2991 * @param {string} name 2992 * @returns {never} 2993 */ 2994function lifecycle_legacy_only(name) { 2995 if (DEV) { 2996 const error = new Error(`lifecycle_legacy_only\n\`${name}(...)\` cannot be used in runes mode\nhttps://svelte.dev/e/lifecycle_legacy_only`); 2997 2998 error.name = 'Svelte error'; 2999 3000 throw error; 3001 } else { 3002 throw new Error(`https://svelte.dev/e/lifecycle_legacy_only`); 3003 } 3004} 3005 3006/** 3007 * Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value 3008 * @param {string} key 3009 * @returns {never} 3010 */ 3011function props_invalid_value(key) { 3012 if (DEV) { 3013 const error = new Error(`props_invalid_value\nCannot do \`bind:${key}={undefined}\` when \`${key}\` has a fallback value\nhttps://svelte.dev/e/props_invalid_value`); 3014 3015 error.name = 'Svelte error'; 3016 3017 throw error; 3018 } else { 3019 throw new Error(`https://svelte.dev/e/props_invalid_value`); 3020 } 3021} 3022 3023/** 3024 * Rest element properties of `$props()` such as `%property%` are readonly 3025 * @param {string} property 3026 * @returns {never} 3027 */ 3028function props_rest_readonly(property) { 3029 if (DEV) { 3030 const error = new Error(`props_rest_readonly\nRest element properties of \`$props()\` such as \`${property}\` are readonly\nhttps://svelte.dev/e/props_rest_readonly`); 3031 3032 error.name = 'Svelte error'; 3033 3034 throw error; 3035 } else { 3036 throw new Error(`https://svelte.dev/e/props_rest_readonly`); 3037 } 3038} 3039 3040/** 3041 * The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files 3042 * @param {string} rune 3043 * @returns {never} 3044 */ 3045function rune_outside_svelte(rune) { 3046 if (DEV) { 3047 const error = new Error(`rune_outside_svelte\nThe \`${rune}\` rune is only available inside \`.svelte\` and \`.svelte.js/ts\` files\nhttps://svelte.dev/e/rune_outside_svelte`); 3048 3049 error.name = 'Svelte error'; 3050 3051 throw error; 3052 } else { 3053 throw new Error(`https://svelte.dev/e/rune_outside_svelte`); 3054 } 3055} 3056 3057/** 3058 * `setContext` must be called when a component first initializes, not in a subsequent effect or after an `await` expression 3059 * @returns {never} 3060 */ 3061function set_context_after_init() { 3062 if (DEV) { 3063 const error = new Error(`set_context_after_init\n\`setContext\` must be called when a component first initializes, not in a subsequent effect or after an \`await\` expression\nhttps://svelte.dev/e/set_context_after_init`); 3064 3065 error.name = 'Svelte error'; 3066 3067 throw error; 3068 } else { 3069 throw new Error(`https://svelte.dev/e/set_context_after_init`); 3070 } 3071} 3072 3073/** 3074 * Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`. 3075 * @returns {never} 3076 */ 3077function state_descriptors_fixed() { 3078 if (DEV) { 3079 const error = new Error(`state_descriptors_fixed\nProperty descriptors defined on \`$state\` objects must contain \`value\` and always be \`enumerable\`, \`configurable\` and \`writable\`.\nhttps://svelte.dev/e/state_descriptors_fixed`); 3080 3081 error.name = 'Svelte error'; 3082 3083 throw error; 3084 } else { 3085 throw new Error(`https://svelte.dev/e/state_descriptors_fixed`); 3086 } 3087} 3088 3089/** 3090 * Cannot set prototype of `$state` object 3091 * @returns {never} 3092 */ 3093function state_prototype_fixed() { 3094 if (DEV) { 3095 const error = new Error(`state_prototype_fixed\nCannot set prototype of \`$state\` object\nhttps://svelte.dev/e/state_prototype_fixed`); 3096 3097 error.name = 'Svelte error'; 3098 3099 throw error; 3100 } else { 3101 throw new Error(`https://svelte.dev/e/state_prototype_fixed`); 3102 } 3103} 3104 3105/** 3106 * Updating state inside `$derived(...)`, `$inspect(...)` or a template expression is forbidden. If the value should not be reactive, declare it without `$state` 3107 * @returns {never} 3108 */ 3109function state_unsafe_mutation() { 3110 if (DEV) { 3111 const error = new Error(`state_unsafe_mutation\nUpdating state inside \`$derived(...)\`, \`$inspect(...)\` or a template expression is forbidden. If the value should not be reactive, declare it without \`$state\`\nhttps://svelte.dev/e/state_unsafe_mutation`); 3112 3113 error.name = 'Svelte error'; 3114 3115 throw error; 3116 } else { 3117 throw new Error(`https://svelte.dev/e/state_unsafe_mutation`); 3118 } 3119} 3120 3121/** 3122 * A `<svelte:boundary>` `reset` function cannot be called while an error is still being handled 3123 * @returns {never} 3124 */
3125function svelte_boundary_reset_onerror() { 3126 if (DEV) { 3127 const error = new Error(`svelte_boundary_reset_onerror\nA \`<svelte:boundary>\` \`reset\` function cannot be called while an error is still being handled\nhttps://svelte.dev/e/svelte_boundary_reset_onerror`); 3128 3129 error.name = 'Svelte error'; 3130 3131 throw error; 3132 } else { 3133 throw new Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`); 3134 } 3135} 3136 3137const EACH_ITEM_REACTIVE = 1; 3138const EACH_INDEX_REACTIVE = 1 << 1; 3139/** See EachBlock interface metadata.is_controlled for an explanation what this is */ 3140const EACH_IS_CONTROLLED = 1 << 2; 3141const EACH_IS_ANIMATED = 1 << 3; 3142const EACH_ITEM_IMMUTABLE = 1 << 4; 3143 3144const PROPS_IS_IMMUTABLE = 1; 3145const PROPS_IS_RUNES = 1 << 1; 3146const PROPS_IS_UPDATED = 1 << 2; 3147const PROPS_IS_BINDABLE = 1 << 3; 3148const PROPS_IS_LAZY_INITIAL = 1 << 4; 3149 3150const TRANSITION_IN = 1; 3151const TRANSITION_OUT = 1 << 1; 3152const TRANSITION_GLOBAL = 1 << 2; 3153 3154const TEMPLATE_FRAGMENT = 1; 3155const TEMPLATE_USE_IMPORT_NODE = 1 << 1; 3156 3157const HYDRATION_START = '['; 3158/** used to indicate that an `{:else}...` block was rendered */ 3159const HYDRATION_START_ELSE = '[!'; 3160const HYDRATION_END = ']'; 3161const HYDRATION_ERROR = {}; 3162 3163const UNINITIALIZED = Symbol(); 3164 3165// Dev-time component properties 3166const FILENAME = Symbol('filename'); 3167 3168const NAMESPACE_HTML = 'http://www.w3.org/1999/xhtml'; 3169const NAMESPACE_SVG = 'http://www.w3.org/2000/svg'; 3170 3171const ATTACHMENT_KEY = '@attach'; 3172 3173/* This file is generated by scripts/process-messages/index.js. Do not edit! */ 3174 3175 3176var bold = 'font-weight: bold'; 3177var normal = 'font-weight: normal'; 3178 3179/** 3180 * The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value 3181 * @param {string} attribute 3182 * @param {string} html 3183 * @param {string} value 3184 */ 3185function hydration_attribute_changed(attribute, html, value) { 3186 if (DEV) { 3187 console.warn(`%c[svelte] hydration_attribute_changed\n%cThe \`${attribute}\` attribute on \`${html}\` changed its value between server and client renders. The client value, \`${value}\`, will be ignored in favour of the server value\nhttps://svelte.dev/e/hydration_attribute_changed`, bold, normal); 3188 } else { 3189 console.warn(`https://svelte.dev/e/hydration_attribute_changed`); 3190 } 3191} 3192 3193/** 3194 * The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value 3195 * @param {string | undefined | null} [location] 3196 */ 3197function hydration_html_changed(location) { 3198 if (DEV) { 3199 console.warn( 3200 `%c[svelte] hydration_html_changed\n%c${location 3201 ? `The value of an \`{@html ...}\` block ${location} changed between server and client renders. The client value will be ignored in favour of the server value` 3202 : 'The value of an `{@html ...}` block changed between server and client renders. The client value will be ignored in favour of the server value'}\nhttps://svelte.dev/e/hydration_html_changed`, 3203 bold, 3204 normal 3205 ); 3206 } else { 3207 console.warn(`https://svelte.dev/e/hydration_html_changed`); 3208 } 3209} 3210 3211/** 3212 * Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location% 3213 * @param {string | undefined | null} [location] 3214 */ 3215function hydration_mismatch(location) { 3216 if (DEV) { 3217 console.warn( 3218 `%c[svelte] hydration_mismatch\n%c${'Hydration failed because the initial UI does not match what was rendered on the server'}\nhttps://svelte.dev/e/hydration_mismatch`, 3219 bold, 3220 normal 3221 ); 3222 } else { 3223 console.warn(`https://svelte.dev/e/hydration_mismatch`); 3224 } 3225} 3226 3227/** 3228 * Tried to unmount a component that was not mounted 3229 */ 3230function lifecycle_double_unmount() { 3231 if (DEV) { 3232 console.warn(`%c[svelte] lifecycle_double_unmount\n%cTried to unmount a component that was not mounted\nhttps://svelte.dev/e/lifecycle_double_unmount`, bold, normal); 3233 } else { 3234 console.warn(`https://svelte.dev/e/lifecycle_double_unmount`); 3235 } 3236} 3237 3238/** 3239 * The `value` property of a `<select multiple>` element should be an array, but it received a non-array value. The selection will be kept as is. 3240 */ 3241function select_multiple_invalid_value() { 3242 if (DEV) { 3243 console.warn(`%c[svelte] select_multiple_invalid_value\n%cThe \`value\` property of a \`<select multiple>\` element should be an array, but it received a non-array value. The selection will be kept as is.\nhttps://svelte.dev/e/select_multiple_invalid_value`, bold, normal); 3244 } else { 3245 console.warn(`https://svelte.dev/e/select_multiple_invalid_value`); 3246 } 3247} 3248 3249/** 3250 * Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results 3251 * @param {string} operator
3252 */ 3253function state_proxy_equality_mismatch(operator) { 3254 if (DEV) { 3255 console.warn(`%c[svelte] state_proxy_equality_mismatch\n%cReactive \`$state(...)\` proxies and the values they proxy have different identities. Because of this, comparisons with \`${operator}\` will produce unexpected results\nhttps://svelte.dev/e/state_proxy_equality_mismatch`, bold, normal); 3256 } else { 3257 console.warn(`https://svelte.dev/e/state_proxy_equality_mismatch`); 3258 } 3259} 3260 3261/** 3262 * Tried to unmount a state proxy, rather than a component 3263 */ 3264function state_proxy_unmount() { 3265 if (DEV) { 3266 console.warn(`%c[svelte] state_proxy_unmount\n%cTried to unmount a state proxy, rather than a component\nhttps://svelte.dev/e/state_proxy_unmount`, bold, normal); 3267 } else { 3268 console.warn(`https://svelte.dev/e/state_proxy_unmount`); 3269 } 3270} 3271 3272/** 3273 * A `<svelte:boundary>` `reset` function only resets the boundary the first time it is called 3274 */ 3275function svelte_boundary_reset_noop() { 3276 if (DEV) { 3277 console.warn(`%c[svelte] svelte_boundary_reset_noop\n%cA \`<svelte:boundary>\` \`reset\` function only resets the boundary the first time it is called\nhttps://svelte.dev/e/svelte_boundary_reset_noop`, bold, normal); 3278 } else { 3279 console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`); 3280 } 3281} 3282 3283/** 3284 * The `slide` transition does not work correctly for elements with `display: %value%` 3285 * @param {string} value 3286 */ 3287function transition_slide_display(value) { 3288 if (DEV) { 3289 console.warn(`%c[svelte] transition_slide_display\n%cThe \`slide\` transition does not work correctly for elements with \`display: ${value}\`\nhttps://svelte.dev/e/transition_slide_display`, bold, normal); 3290 } else { 3291 console.warn(`https://svelte.dev/e/transition_slide_display`); 3292 } 3293} 3294 3295/** @import { TemplateNode } from '#client' */ 3296 3297 3298/** 3299 * Use this variable to guard everything related to hydration code so it can be treeshaken out 3300 * if the user doesn't use the `hydrate` method and these code paths are therefore not needed. 3301 */ 3302let hydrating = false; 3303 3304/** @param {boolean} value */ 3305function set_hydrating(value) { 3306 hydrating = value; 3307} 3308 3309/** 3310 * The node that is currently being hydrated. This starts out as the first node inside the opening 3311 * <!--[--> comment, and updates each time a component calls `$.child(...)` or `$.sibling(...)`. 3312 * When entering a block (e.g. `{#if ...}`), `hydrate_node` is the block opening comment; by the 3313 * time we leave the block it is the closing comment, which serves as the block's anchor. 3314 * @type {TemplateNode} 3315 */ 3316let hydrate_node; 3317 3318/** @param {TemplateNode | null} node */ 3319function set_hydrate_node(node) { 3320 if (node === null) { 3321 hydration_mismatch(); 3322 throw HYDRATION_ERROR; 3323 } 3324 3325 return (hydrate_node = node); 3326} 3327 3328function hydrate_next() { 3329 return set_hydrate_node(get_next_sibling(hydrate_node)); 3330} 3331 3332/** @param {TemplateNode} node */ 3333function reset(node) { 3334 if (!hydrating) return; 3335 3336 // If the node has remaining siblings, something has gone wrong 3337 if (get_next_sibling(hydrate_node) !== null) { 3338 hydration_mismatch(); 3339 throw HYDRATION_ERROR; 3340 } 3341 3342 hydrate_node = node; 3343} 3344 3345function next(count = 1) { 3346 if (hydrating) { 3347 var i = count; 3348 var node = hydrate_node; 3349 3350 while (i--) { 3351 node = /** @type {TemplateNode} */ (get_next_sibling(node)); 3352 } 3353 3354 hydrate_node = node; 3355 } 3356} 3357 3358/** 3359 * Skips or removes (depending on {@link remove}) all nodes starting at `hydrate_node` up until the next hydration end comment 3360 * @param {boolean} remove 3361 */ 3362function skip_nodes(remove = true) { 3363 var depth = 0; 3364 var node = hydrate_node; 3365 3366 while (true) { 3367 if (node.nodeType === COMMENT_NODE) { 3368 var data = /** @type {Comment} */ (node).data; 3369 3370 if (data === HYDRATION_END) { 3371 if (depth === 0) return node; 3372 depth -= 1; 3373 } else if (data === HYDRATION_START || data === HYDRATION_START_ELSE) { 3374 depth += 1; 3375 } 3376 } 3377 3378 var next = /** @type {TemplateNode} */ (get_next_sibling(node)); 3379 if (remove) node.remove(); 3380 node = next; 3381 } 3382} 3383 3384/** 3385 * 3386 * @param {TemplateNode} node 3387 */ 3388function read_hydration_instruction(node) { 3389 if (!node || node.nodeType !== COMMENT_NODE) { 3390 hydration_mismatch(); 3391 throw HYDRATION_ERROR; 3392 } 3393 3394 return /** @type {Comment} */ (node).data; 3395} 3396 3397/** @import { Equals } from '#client' */ 3398 3399/** @type {Equals} */ 3400function equals(value) { 3401 return value === this.v; 3402} 3403 3404/** 3405 * @param {unknown} a 3406 * @param {unknown} b 3407 * @returns {boolean} 3408 */ 3409function safe_not_equal(a, b) { 3410 return a != a 3411 ? b == b 3412 : a !== b || (a !== null && typeof a === 'object') || typeof a === 'function'; 3413} 3414 3415/** @type {Equals} */ 3416function safe_equals(value) { 3417 return !safe_not_equal(value, this.v); 3418} 3419 3420/** True if experimental.async=true */ 3421let async_mode_flag = false;
3422/** True if we're not certain that we only have Svelte 5 code in the compilation */ 3423let legacy_mode_flag = false; 3424/** True if $inspect.trace is used */ 3425let tracing_mode_flag = false; 3426 3427function enable_async_mode_flag() { 3428 async_mode_flag = true; 3429} 3430 3431function enable_legacy_mode_flag() { 3432 legacy_mode_flag = true; 3433} 3434 3435/** @import { Derived, Reaction, Value } from '#client' */ 3436 3437/** 3438 * @param {Value} source 3439 * @param {string} label 3440 */ 3441function tag(source, label) { 3442 source.label = label; 3443 tag_proxy(source.v, label); 3444 3445 return source; 3446} 3447 3448/** 3449 * @param {unknown} value 3450 * @param {string} label 3451 */ 3452function tag_proxy(value, label) { 3453 // @ts-expect-error 3454 value?.[PROXY_PATH_SYMBOL]?.(label); 3455 return value; 3456} 3457 3458/** 3459 * @param {string} label 3460 * @returns {Error & { stack: string } | null} 3461 */ 3462function get_error(label) { 3463 const error = new Error(); 3464 const stack = get_stack(); 3465 3466 if (stack.length === 0) { 3467 return null; 3468 } 3469 3470 stack.unshift('\n'); 3471 3472 define_property(error, 'stack', { 3473 value: stack.join('\n') 3474 }); 3475 3476 define_property(error, 'name', { 3477 value: label 3478 }); 3479 3480 return /** @type {Error & { stack: string }} */ (error); 3481} 3482 3483/** 3484 * @returns {string[]} 3485 */ 3486function get_stack() { 3487 // @ts-ignore - doesn't exist everywhere 3488 const limit = Error.stackTraceLimit; 3489 // @ts-ignore - doesn't exist everywhere 3490 Error.stackTraceLimit = Infinity; 3491 const stack = new Error().stack; 3492 // @ts-ignore - doesn't exist everywhere 3493 Error.stackTraceLimit = limit; 3494 3495 if (!stack) return []; 3496 3497 const lines = stack.split('\n'); 3498 const new_lines = []; 3499 3500 for (let i = 0; i < lines.length; i++) { 3501 const line = lines[i]; 3502 const posixified = line.replaceAll('\\', '/'); 3503 3504 if (line.trim() === 'Error') { 3505 continue; 3506 } 3507 3508 if (line.includes('validate_each_keys')) { 3509 return []; 3510 } 3511 3512 if (posixified.includes('svelte/src/internal') || posixified.includes('node_modules/.vite')) { 3513 continue; 3514 } 3515 3516 new_lines.push(line); 3517 } 3518 3519 return new_lines; 3520} 3521 3522/** @import { ComponentContext, DevStackEntry, Effect } from '#client' */ 3523 3524/** @type {ComponentContext | null} */ 3525let component_context = null; 3526 3527/** @param {ComponentContext | null} context */ 3528function set_component_context(context) { 3529 component_context = context; 3530} 3531 3532/** @type {DevStackEntry | null} */ 3533let dev_stack = null; 3534 3535/** @param {DevStackEntry | null} stack */ 3536function set_dev_stack(stack) { 3537 dev_stack = stack; 3538} 3539 3540/** 3541 * The current component function. Different from current component context: 3542 * ```html 3543 * <!-- App.svelte --> 3544 * <Foo> 3545 * <Bar /> <!-- context == Foo.svelte, function == App.svelte --> 3546 * </Foo> 3547 * ``` 3548 * @type {ComponentContext['function']} 3549 */ 3550let dev_current_component_function = null; 3551 3552/** @param {ComponentContext['function']} fn */ 3553function set_dev_current_component_function(fn) { 3554 dev_current_component_function = fn; 3555} 3556 3557/** 3558 * Retrieves the context that belongs to the closest parent component with the specified `key`. 3559 * Must be called during component initialisation. 3560 * 3561 * [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative. 3562 * 3563 * @template T 3564 * @param {any} key 3565 * @returns {T} 3566 */ 3567function getContext(key) { 3568 const context_map = get_or_init_context_map('getContext'); 3569 const result = /** @type {T} */ (context_map.get(key)); 3570 return result; 3571} 3572 3573/** 3574 * Associates an arbitrary `context` object with the current component and the specified `key` 3575 * and returns that object. The context is then available to children of the component 3576 * (including slotted content) with `getContext`. 3577 * 3578 * Like lifecycle functions, this must be called during component initialisation. 3579 * 3580 * [`createContext`](https://svelte.dev/docs/svelte/svelte#createContext) is a type-safe alternative. 3581 * 3582 * @template T 3583 * @param {any} key 3584 * @param {T} context 3585 * @returns {T} 3586 */ 3587function setContext(key, context) { 3588 const context_map = get_or_init_context_map('setContext'); 3589 3590 if (async_mode_flag) { 3591 var flags = /** @type {Effect} */ (active_effect).f; 3592 var valid = 3593 !active_reaction && 3594 (flags & BRANCH_EFFECT) !== 0 && 3595 // pop() runs synchronously, so this indicates we're setting context after an await 3596 !(/** @type {ComponentContext} */ (component_context).i); 3597 3598 if (!valid) { 3599 set_context_after_init(); 3600 } 3601 } 3602 3603 context_map.set(key, context); 3604 return context; 3605} 3606 3607/** 3608 * @param {Record<string, unknown>} props 3609 * @param {any} runes 3610 * @param {Function}
3610 [fn] 3611 * @returns {void} 3612 */ 3613function push(props, runes = false, fn) { 3614 component_context = { 3615 p: component_context, 3616 i: false, 3617 c: null, 3618 e: null, 3619 s: props, 3620 x: null, 3621 l: legacy_mode_flag && !runes ? { s: null, u: null, $: [] } : null 3622 }; 3623 3624 if (DEV) { 3625 // component function 3626 component_context.function = fn; 3627 dev_current_component_function = fn; 3628 } 3629} 3630 3631/** 3632 * @template {Record<string, any>} T 3633 * @param {T} [component] 3634 * @returns {T} 3635 */ 3636function pop(component) { 3637 var context = /** @type {ComponentContext} */ (component_context); 3638 var effects = context.e; 3639 3640 if (effects !== null) { 3641 context.e = null; 3642 3643 for (var fn of effects) { 3644 create_user_effect(fn); 3645 } 3646 } 3647 3648 if (component !== undefined) { 3649 context.x = component; 3650 } 3651 3652 context.i = true; 3653 3654 component_context = context.p; 3655 3656 if (DEV) { 3657 dev_current_component_function = component_context?.function ?? null; 3658 } 3659 3660 return component ?? /** @type {T} */ ({}); 3661} 3662 3663/** @returns {boolean} */ 3664function is_runes() { 3665 return !legacy_mode_flag || (component_context !== null && component_context.l === null); 3666} 3667 3668/** 3669 * @param {string} name 3670 * @returns {Map<unknown, unknown>} 3671 */ 3672function get_or_init_context_map(name) { 3673 if (component_context === null) { 3674 lifecycle_outside_component(name); 3675 } 3676 3677 return (component_context.c ??= new Map(get_parent_context(component_context) || undefined)); 3678} 3679 3680/** 3681 * @param {ComponentContext} component_context 3682 * @returns {Map<unknown, unknown> | null} 3683 */ 3684function get_parent_context(component_context) { 3685 let parent = component_context.p; 3686 while (parent !== null) { 3687 const context_map = parent.c; 3688 if (context_map !== null) { 3689 return context_map; 3690 } 3691 parent = parent.p; 3692 } 3693 return null; 3694} 3695 3696/** @type {Array<() => void>} */ 3697let micro_tasks = []; 3698 3699function run_micro_tasks() { 3700 var tasks = micro_tasks; 3701 micro_tasks = []; 3702 run_all(tasks); 3703} 3704 3705/** 3706 * @param {() => void} fn 3707 */ 3708function queue_micro_task(fn) { 3709 if (micro_tasks.length === 0 && !is_flushing_sync) { 3710 var tasks = micro_tasks; 3711 queueMicrotask(() => { 3712 // If this is false, a flushSync happened in the meantime. Do _not_ run new scheduled microtasks in that case 3713 // as the ordering of microtasks would be broken at that point - consider this case: 3714 // - queue_micro_task schedules microtask A to flush task X 3715 // - synchronously after, flushSync runs, processing task X 3716 // - synchronously after, some other microtask B is scheduled, but not through queue_micro_task but for example a Promise.resolve() in user code 3717 // - synchronously after, queue_micro_task schedules microtask C to flush task Y 3718 // - one tick later, microtask A now resolves, flushing task Y before microtask B, which is incorrect 3719 // This if check prevents that race condition (that realistically will only happen in tests) 3720 if (tasks === micro_tasks) run_micro_tasks(); 3721 }); 3722 } 3723 3724 micro_tasks.push(fn); 3725} 3726 3727/** 3728 * Synchronously run any queued tasks. 3729 */ 3730function flush_tasks() { 3731 while (micro_tasks.length > 0) { 3732 run_micro_tasks(); 3733 } 3734} 3735 3736/** @import { Derived, Effect } from '#client' */ 3737/** @import { Boundary } from './dom/blocks/boundary.js' */ 3738 3739const adjustments = new WeakMap(); 3740 3741/** 3742 * @param {unknown} error 3743 */ 3744function handle_error(error) { 3745 var effect = active_effect; 3746 3747 // for unowned deriveds, don't throw until we read the value 3748 if (effect === null) { 3749 /** @type {Derived} */ (active_reaction).f |= ERROR_VALUE; 3750 return error; 3751 } 3752 3753 if (DEV && error instanceof Error && !adjustments.has(error)) { 3754 adjustments.set(error, get_adjustments(error, effect)); 3755 } 3756 3757 if ((effect.f & EFFECT_RAN) === 0) { 3758 // if the error occurred while creating this subtree, we let it 3759 // bubble up until it hits a boundary that can handle it 3760 if ((effect.f & BOUNDARY_EFFECT) === 0) { 3761 if (DEV && !effect.parent && error instanceof Error) { 3762 apply_adjustments(error); 3763 } 3764 3765 throw error; 3766 } 3767 3768 /** @type {Boundary} */ (effect.b).error(error); 3769 } else { 3770 // otherwise we bubble up the effect tree ourselves 3771 invoke_error_boundary(error, effect); 3772 } 3773} 3774 3775/** 3776 * @param {unknown} error 3777 * @param {Effect | null} effect 3778 */ 3779function invoke_error_boundary(error, effect) { 3780 while (effect !== null) { 3781 if ((effect.f & BOUNDARY_EFFECT) !== 0) { 3782 try { 3783 /** @type {Boundary} */ (effect.b).error(error); 3784 return; 3785 } catch (e) { 3786 error = e; 3787 } 3788 } 3789 3790 effect = effect.parent; 3791 } 3792 3793 if (DEV && error instanceof Error) { 3794 apply_adjustments(error); 3795 } 3796 3797 throw error; 3798} 3799
3800/** 3801 * Add useful information to the error message/stack in development 3802 * @param {Error} error 3803 * @param {Effect} effect 3804 */ 3805function get_adjustments(error, effect) { 3806 const message_descriptor = get_descriptor(error, 'message'); 3807 3808 // if the message was already changed and it's not configurable we can't change it 3809 // or it will throw a different error swallowing the original error 3810 if (message_descriptor && !message_descriptor.configurable) return; 3811 3812 var indent = is_firefox ? ' ' : '\t'; 3813 var component_stack = `\n${indent}in ${effect.fn?.name || '<unknown>'}`; 3814 var context = effect.ctx; 3815 3816 while (context !== null) { 3817 component_stack += `\n${indent}in ${context.function?.[FILENAME].split('/').pop()}`; 3818 context = context.p; 3819 } 3820 3821 return { 3822 message: error.message + `\n${component_stack}\n`, 3823 stack: error.stack 3824 ?.split('\n') 3825 .filter((line) => !line.includes('svelte/src/internal')) 3826 .join('\n') 3827 }; 3828} 3829 3830/** 3831 * @param {Error} error 3832 */ 3833function apply_adjustments(error) { 3834 const adjusted = adjustments.get(error); 3835 3836 if (adjusted) { 3837 define_property(error, 'message', { 3838 value: adjusted.message 3839 }); 3840 3841 define_property(error, 'stack', { 3842 value: adjusted.stack 3843 }); 3844 } 3845} 3846 3847/** @import { Derived, Signal } from '#client' */ 3848 3849const STATUS_MASK = -7169; 3850 3851/** 3852 * @param {Signal} signal 3853 * @param {number} status 3854 */ 3855function set_signal_status(signal, status) { 3856 signal.f = (signal.f & STATUS_MASK) | status; 3857} 3858 3859/** 3860 * Set a derived's status to CLEAN or MAYBE_DIRTY based on its connection state. 3861 * @param {Derived} derived 3862 */ 3863function update_derived_status(derived) { 3864 // Only mark as MAYBE_DIRTY if disconnected and has dependencies. 3865 if ((derived.f & CONNECTED) !== 0 || derived.deps === null) { 3866 set_signal_status(derived, CLEAN); 3867 } else { 3868 set_signal_status(derived, MAYBE_DIRTY); 3869 } 3870} 3871 3872/** @import { Derived, Effect, Value } from '#client' */ 3873 3874/** 3875 * @param {Value[] | null} deps 3876 */ 3877function clear_marked(deps) { 3878 if (deps === null) return; 3879 3880 for (const dep of deps) { 3881 if ((dep.f & DERIVED) === 0 || (dep.f & WAS_MARKED) === 0) { 3882 continue; 3883 } 3884 3885 dep.f ^= WAS_MARKED; 3886 3887 clear_marked(/** @type {Derived} */ (dep).deps); 3888 } 3889} 3890 3891/** 3892 * @param {Effect} effect 3893 * @param {Set<Effect>} dirty_effects 3894 * @param {Set<Effect>} maybe_dirty_effects 3895 */ 3896function defer_effect(effect, dirty_effects, maybe_dirty_effects) { 3897 if ((effect.f & DIRTY) !== 0) { 3898 dirty_effects.add(effect); 3899 } else if ((effect.f & MAYBE_DIRTY) !== 0) { 3900 maybe_dirty_effects.add(effect); 3901 } 3902 3903 // Since we're not executing these effects now, we need to clear any WAS_MARKED flags
3904 // so that other batches can correctly reach these effects during their own traversal 3905 clear_marked(effect.deps); 3906 3907 // mark as clean so they get scheduled if they depend on pending async state 3908 set_signal_status(effect, CLEAN); 3909} 3910 3911/** @import { Fork } from 'svelte' */ 3912/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */ 3913/** @import { Boundary } from '../dom/blocks/boundary' */ 3914 3915/** @type {Set<Batch>} */ 3916const batches = new Set(); 3917 3918/** @type {Batch | null} */ 3919let current_batch = null; 3920 3921/** 3922 * This is needed to avoid overwriting inputs in non-async mode 3923 * TODO 6.0 remove this, as non-async mode will go away 3924 * @type {Batch | null} 3925 */ 3926let previous_batch = null; 3927 3928/** 3929 * When time travelling (i.e. working in one batch, while other batches 3930 * still have ongoing work), we ignore the real values of affected 3931 * signals in favour of their values within the batch 3932 * @type {Map<Value, any> | null} 3933 */ 3934let batch_values = null; 3935 3936// TODO this should really be a property of `batch` 3937/** @type {Effect[]} */ 3938let queued_root_effects = []; 3939 3940/** @type {Effect | null} */ 3941let last_scheduled_effect = null; 3942 3943let is_flushing = false; 3944let is_flushing_sync = false; 3945 3946class Batch { 3947 committed = false; 3948 3949 /** 3950 * The current values of any sources that are updated in this batch 3951 * They keys of this map are identical to `this.#previous` 3952 * @type {Map<Source, any>} 3953 */ 3954 current = new Map(); 3955 3956 /** 3957 * The values of any sources that are updated in this batch _before_ those updates took place. 3958 * They keys of this map are identical to `this.#current` 3959 * @type {Map<Source, any>} 3960 */ 3961 previous = new Map(); 3962 3963 /** 3964 * When the batch is committed (and the DOM is updated), we need to remove old branches 3965 * and append new ones by calling the functions added inside (if/each/key/etc) blocks 3966 * @type {Set<() => void>} 3967 */ 3968 #commit_callbacks = new Set(); 3969 3970 /** 3971 * If a fork is discarded, we need to destroy any effects that are no longer needed 3972 * @type {Set<(batch: Batch) => void>} 3973 */ 3974 #discard_callbacks = new Set(); 3975 3976 /** 3977 * The number of async effects that are currently in flight 3978 */ 3979 #pending = 0; 3980 3981 /** 3982 * The number of async effects that are currently in flight, _not_ inside a pending boundary 3983 */ 3984 #blocking_pending = 0; 3985 3986 /** 3987 * A deferred that resolves when the batch is committed, used with `settled()` 3988 * TODO replace with Promise.withResolvers once supported widely enough 3989 * @type {{ promise: Promise<void>, resolve: (value?: any) => void, reject: (reason: unknown) => void } | null} 3990 */ 3991 #deferred = null; 3992 3993 /** 3994 * Deferred effects (which run after async work has completed) that are DIRTY 3995 * @type {Set<Effect>} 3996 */ 3997 #dirty_effects = new Set(); 3998 3999 /** 4000 * Deferred effects that are MAYBE_DIRTY 4001 * @type {Set<Effect>} 4002 */ 4003 #maybe_dirty_effects = new Set(); 4004 4005 /** 4006 * A set of branches that still exist, but will be destroyed when this batch 4007 * is committed â we skip over these during `process` 4008 * @type {Set<Effect>} 4009 */ 4010 skipped_effects = new Set(); 4011 4012 is_fork = false; 4013 4014 is_deferred() { 4015 return this.is_fork || this.#blocking_pending > 0; 4016 } 4017 4018 /** 4019 * 4020 * @param {Effect[]} root_effects 4021 */ 4022 process(root_effects) { 4023 queued_root_effects = []; 4024 4025 previous_batch = null; 4026 4027 this.apply(); 4028 4029 /** @type {Effect[]} */ 4030 var effects = []; 4031 4032 /** @type {Effect[]} */ 4033 var render_effects = []; 4034 4035 for (const root of root_effects) { 4036 this.#traverse_effect_tree(root, effects, render_effects); 4037 // Note: #traverse_effect_tree runs block effects eagerly, which can schedule effects, 4038 // which means queued_root_effects now may be filled again. 4039 4040 // Helpful for debugging reactivity loss that has to do with branches being skipped: 4041 // log_inconsistent_branches(root); 4042 } 4043 4044 if (!this.is_fork) { 4045 this.#resolve(); 4046 } 4047 4048 if (this.is_deferred()) { 4049 this.#defer_effects(render_effects); 4050 this.#defer_effects(effects); 4051 } else { 4052 // If sources are written to, then work needs to happen in a separate batch, else prior sources would be mixed with 4053 // newly updated sources, which could lead to infinite loops when effects run over and over again. 4054 previous_batch = this; 4055 current_batch = null; 4056 4057 flush_queued_effects(render_effects); 4058 flush_queued_effects(effects); 4059 4060 previous_batch = null; 4061 4062 this.#deferred?.resolve(); 4063 } 4064 4065 batch_values = null; 4066 } 4067 4068 /** 4069 * Traverse the effect tree, executing effects or stashing 4070 * them for later execution as appropriate 4071 * @param {Effect} root 4072 * @param {Effect[]} effects 4073 * @param {Effect[]} render_effects 4074 */ 4075 #traverse_effect_tree(root, effects, render_effects) { 4076 root.f ^= CLEAN; 4077 4078 var effect = root.first; 4079 4080 /** @type {Effect | null} */
4081 var pending_boundary = null; 4082 4083 while (effect !== null) { 4084 var flags = effect.f; 4085 var is_branch = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) !== 0; 4086 var is_skippable_branch = is_branch && (flags & CLEAN) !== 0; 4087 4088 var skip = is_skippable_branch || (flags & INERT) !== 0 || this.skipped_effects.has(effect); 4089 4090 // Inside a `<svelte:boundary>` with a pending snippet, 4091 // all effects are deferred until the boundary resolves 4092 // (except block/async effects, which run immediately) 4093 if ( 4094 async_mode_flag && 4095 pending_boundary === null && 4096 (flags & BOUNDARY_EFFECT) !== 0 && 4097 effect.b?.is_pending 4098 ) { 4099 pending_boundary = effect; 4100 } 4101 4102 if (!skip && effect.fn !== null) { 4103 if (is_branch) { 4104 effect.f ^= CLEAN; 4105 } else if ( 4106 pending_boundary !== null && 4107 (flags & (EFFECT | RENDER_EFFECT | MANAGED_EFFECT)) !== 0 4108 ) { 4109 /** @type {Boundary} */ (pending_boundary.b).defer_effect(effect); 4110 } else if ((flags & EFFECT) !== 0) { 4111 effects.push(effect); 4112 } else if (async_mode_flag && (flags & (RENDER_EFFECT | MANAGED_EFFECT)) !== 0) { 4113 render_effects.push(effect); 4114 } else if (is_dirty(effect)) { 4115 if ((flags & BLOCK_EFFECT) !== 0) this.#dirty_effects.add(effect); 4116 update_effect(effect); 4117 } 4118 4119 var child = effect.first; 4120 4121 if (child !== null) { 4122 effect = child; 4123 continue; 4124 } 4125 } 4126 4127 var parent = effect.parent; 4128 effect = effect.next; 4129 4130 while (effect === null && parent !== null) { 4131 if (parent === pending_boundary) { 4132 pending_boundary = null; 4133 } 4134 4135 effect = parent.next; 4136 parent = parent.parent; 4137 } 4138 } 4139 } 4140 4141 /** 4142 * @param {Effect[]} effects 4143 */ 4144 #defer_effects(effects) { 4145 for (var i = 0; i < effects.length; i += 1) { 4146 defer_effect(effects[i], this.#dirty_effects, this.#maybe_dirty_effects); 4147 } 4148 } 4149 4150 /** 4151 * Associate a change to a given source with the current 4152 * batch, noting its previous and current values 4153 * @param {Source} source 4154 * @param {any} value 4155 */ 4156 capture(source, value) { 4157 if (value !== UNINITIALIZED && !this.previous.has(source)) { 4158 this.previous.set(source, value); 4159 } 4160 4161 // Don't save errors in `batch_values`, or they won't be thrown in `runtime.js#get` 4162 if ((source.f & ERROR_VALUE) === 0) { 4163 this.current.set(source, source.v); 4164 batch_values?.set(source, source.v); 4165 } 4166 } 4167 4168 activate() { 4169 current_batch = this; 4170 this.apply(); 4171 } 4172 4173 deactivate() { 4174 // If we're not the current batch, don't deactivate, 4175 // else we could create zombie batches that are never flushed 4176 if (current_batch !== this) return; 4177 4178 current_batch = null; 4179 batch_values = null; 4180 } 4181 4182 flush() { 4183 this.activate(); 4184 4185 if (queued_root_effects.length > 0) { 4186 flush_effects(); 4187 4188 if (current_batch !== null && current_batch !== this) { 4189 // this can happen if a new batch was created during `flush_effects()` 4190 return; 4191 } 4192 } else if (this.#pending === 0) { 4193 this.process([]); // TODO this feels awkward 4194 } 4195 4196 this.deactivate(); 4197 } 4198 4199 discard() { 4200 for (const fn of this.#discard_callbacks) fn(this); 4201 this.#discard_callbacks.clear(); 4202 } 4203 4204 #resolve() { 4205 if (this.#blocking_pending === 0) { 4206 // append/remove branches 4207 for (const fn of this.#commit_callbacks) fn(); 4208 this.#commit_callbacks.clear(); 4209 } 4210 4211 if (this.#pending === 0) { 4212 this.#commit(); 4213 } 4214 } 4215 4216 #commit() { 4217 // If there are other pending batches, they now need to be 'rebased' â 4218 // in other words, we re-run block/async effects with the newly 4219 // committed state, unless the batch in question has a more 4220 // recent value for a given source 4221 if (batches.size > 1) { 4222 this.previous.clear(); 4223 4224 var previous_batch_values = batch_values; 4225 var is_earlier = true; 4226 4227 for (const batch of batches) { 4228 if (batch === this) { 4229 is_earlier = false;
4230 continue; 4231 } 4232 4233 /** @type {Source[]} */ 4234 const sources = []; 4235 4236 for (const [source, value] of this.current) { 4237 if (batch.current.has(source)) { 4238 if (is_earlier && value !== batch.current.get(source)) { 4239 // bring the value up to date 4240 batch.current.set(source, value); 4241 } else { 4242 // same value or later batch has more recent value, 4243 // no need to re-run these effects 4244 continue; 4245 } 4246 } 4247 4248 sources.push(source); 4249 } 4250 4251 if (sources.length === 0) { 4252 continue; 4253 } 4254 4255 // Re-run async/block effects that depend on distinct values changed in both batches 4256 const others = [...batch.current.keys()].filter((s) => !this.current.has(s)); 4257 if (others.length > 0) { 4258 // Avoid running queued root effects on the wrong branch 4259 var prev_queued_root_effects = queued_root_effects; 4260 queued_root_effects = []; 4261 4262 /** @type {Set<Value>} */ 4263 const marked = new Set(); 4264 /** @type {Map<Reaction, boolean>} */ 4265 const checked = new Map(); 4266 for (const source of sources) { 4267 mark_effects(source, others, marked, checked); 4268 } 4269 4270 if (queued_root_effects.length > 0) { 4271 current_batch = batch; 4272 batch.apply(); 4273 4274 for (const root of queued_root_effects) { 4275 batch.#traverse_effect_tree(root, [], []); 4276 } 4277 4278 // TODO do we need to do anything with the dummy effect arrays? 4279 4280 batch.deactivate(); 4281 } 4282 4283 queued_root_effects = prev_queued_root_effects; 4284 } 4285 } 4286 4287 current_batch = null; 4288 batch_values = previous_batch_values; 4289 } 4290 4291 this.committed = true; 4292 batches.delete(this); 4293 } 4294 4295 /** 4296 * 4297 * @param {boolean} blocking 4298 */ 4299 increment(blocking) { 4300 this.#pending += 1; 4301 if (blocking) this.#blocking_pending += 1; 4302 } 4303 4304 /** 4305 * 4306 * @param {boolean} blocking 4307 */ 4308 decrement(blocking) { 4309 this.#pending -= 1; 4310 if (blocking) this.#blocking_pending -= 1; 4311 4312 this.revive(); 4313 } 4314 4315 revive() { 4316 for (const e of this.#dirty_effects) { 4317 this.#maybe_dirty_effects.delete(e); 4318 set_signal_status(e, DIRTY); 4319 schedule_effect(e); 4320 } 4321 4322 for (const e of this.#maybe_dirty_effects) { 4323 set_signal_status(e, MAYBE_DIRTY); 4324 schedule_effect(e); 4325 } 4326 4327 this.flush(); 4328 } 4329 4330 /** @param {() => void} fn */ 4331 oncommit(fn) { 4332 this.#commit_callbacks.add(fn); 4333 } 4334 4335 /** @param {(batch: Batch) => void} fn */ 4336 ondiscard(fn) { 4337 this.#discard_callbacks.add(fn); 4338 } 4339 4340 settled() { 4341 return (this.#deferred ??= deferred()).promise; 4342 } 4343 4344 static ensure() { 4345 if (current_batch === null) { 4346 const batch = (current_batch = new Batch()); 4347 batches.add(current_batch); 4348 4349 if (!is_flushing_sync) { 4350 Batch.enqueue(() => { 4351 if (current_batch !== batch) { 4352 // a flushSync happened in the meantime 4353 return; 4354 } 4355 4356 batch.flush(); 4357 }); 4358 } 4359 } 4360 4361 return current_batch; 4362 } 4363 4364 /** @param {() => void} task */ 4365 static enqueue(task) { 4366 queue_micro_task(task); 4367 } 4368 4369 apply() { 4370 if (!async_mode_flag || (!this.is_fork && batches.size === 1)) return; 4371 4372 // if there are multiple batches, we are 'time travelling' â 4373 // we need to override values with the ones in this batch... 4374 batch_values = new Map(this.current); 4375 4376 // ...and undo changes belonging to other batches 4377 for (const batch of batches) { 4378 if (batch === this) continue; 4379 4380 for (const [source, previous] of batch.previous) { 4381 if (!batch_values.has(source)) { 4382 batch_values.set(source, previous); 4383 } 4384 } 4385 } 4386 } 4387} 4388 4389/** 4390 * Synchronously flush any pending updates. 4391 * Returns void if no callback is provided, otherwise returns the result of calling the callback. 4392 * @template [T=void] 4393 * @param {(() => T) | undefined} [fn] 4394 * @returns {T} 4395 */ 4396function flushSync(fn) { 4397 var was_flushing_sync = is_flushing_sync; 4398 is_flushing_sync = true; 4399 4400 try { 4401 var result; 4402 4403 if (fn) ; 4404 4405 while (true) { 4406 flush_tasks(); 4407 4408 if (queued_root_effects.length === 0) { 4409 current_batch?.flush(); 4410 4411 // we need to check again, in case we just updated an `$effect.pending()` 4412 if (queued_root_effects.length === 0) { 4413 // this would be reset in `flush_effects()` but since we are early returning here, 4414 // we need to reset it here as well in case the first time there's 0 queued root effects 4415 last_scheduled_effect = null; 4416 4417 return /** @type {T} */ (result); 4418 } 4419 } 4420 4421 flush_effects(); 4422 } 4423 } finally { 4424 is_flushing_sync = was_flushing_sync; 4425 } 4426} 4427 4428function flush_effects() { 4429 var was_updating_effect = is_updating_effect; 4430 is_flushing = true; 4431 4432 var source_stacks = DEV ? new Set() : null; 4433 4434 try { 4435 var flush_count = 0; 4436 set_is_updating_effect(true); 4437 4438 while (queued_root_effects.length > 0) { 4439 var batch = Batch.ensure(); 4440 4441 if (flush_count++ > 1000) { 4442 if (DEV) { 4443 var updates = new Map(); 4444 4445 for (const source of batch.current.keys()) { 4446 for (const [stack, update] of source.updated ?? []) { 4447 var entry = updates.get(stack); 4448 4449 if (!entry) { 4450 entry = { error: update.error, count: 0 }; 4451 updates.set(stack, entry); 4452 } 4453 4454 entry.count += update.count; 4455 } 4456 } 4457 4458 for (const update of updates.values()) { 4459 if (update.error) { 4460 // eslint-disable-next-line no-console 4461 console.error(update.error); 4462 } 4463 } 4464 } 4465 4466 infinite_loop_guard(); 4467 } 4468 4469 batch.process(queued_root_effects); 4470 old_values.clear(); 4471 4472 if (DEV) { 4473 for (const source of batch.current.keys()) { 4474 /** @type {Set<Source>} */ (source_stacks).add(source); 4475 } 4476 } 4477 } 4478 } finally { 4479 is_flushing = false;
4480 set_is_updating_effect(was_updating_effect); 4481 4482 last_scheduled_effect = null; 4483 4484 if (DEV) { 4485 for (const source of /** @type {Set<Source>} */ (source_stacks)) { 4486 source.updated = null; 4487 } 4488 } 4489 } 4490} 4491 4492function infinite_loop_guard() { 4493 try { 4494 effect_update_depth_exceeded(); 4495 } catch (error) { 4496 if (DEV) { 4497 // stack contains no useful information, replace it 4498 define_property(error, 'stack', { value: '' }); 4499 } 4500 4501 // Best effort: invoke the boundary nearest the most recent 4502 // effect and hope that it's relevant to the infinite loop 4503 invoke_error_boundary(error, last_scheduled_effect); 4504 } 4505} 4506 4507/** @type {Set<Effect> | null} */ 4508let eager_block_effects = null; 4509 4510/** 4511 * @param {Array<Effect>} effects 4512 * @returns {void} 4513 */ 4514function flush_queued_effects(effects) { 4515 var length = effects.length; 4516 if (length === 0) return; 4517 4518 var i = 0; 4519 4520 while (i < length) { 4521 var effect = effects[i++]; 4522 4523 if ((effect.f & (DESTROYED | INERT)) === 0 && is_dirty(effect)) { 4524 eager_block_effects = new Set(); 4525 4526 update_effect(effect); 4527 4528 // Effects with no dependencies or teardown do not get added to the effect tree. 4529 // Deferred effects (e.g. `$effect(...)`) _are_ added to the tree because we 4530 // don't know if we need to keep them until they are executed. Doing the check 4531 // here (rather than in `update_effect`) allows us to skip the work for 4532 // immediate effects. 4533 if (effect.deps === null && effect.first === null && effect.nodes === null) { 4534 // if there's no teardown or abort controller we completely unlink 4535 // the effect from the graph 4536 if (effect.teardown === null && effect.ac === null) { 4537 // remove this effect from the graph 4538 unlink_effect(effect); 4539 } else { 4540 // keep the effect in the graph, but free up some memory 4541 effect.fn = null; 4542 } 4543 } 4544 4545 // If update_effect() has a flushSync() in it, we may have flushed another flush_queued_effects(), 4546 // which already handled this logic and did set eager_block_effects to null. 4547 if (eager_block_effects?.size > 0) { 4548 old_values.clear(); 4549 4550 for (const e of eager_block_effects) { 4551 // Skip eager effects that have already been unmounted 4552 if ((e.f & (DESTROYED | INERT)) !== 0) continue; 4553 4554 // Run effects in order from ancestor to descendant, else we could run into nullpointers 4555 /** @type {Effect[]} */ 4556 const ordered_effects = [e]; 4557 let ancestor = e.parent; 4558 while (ancestor !== null) { 4559 if (eager_block_effects.has(ancestor)) { 4560 eager_block_effects.delete(ancestor); 4561 ordered_effects.push(ancestor); 4562 } 4563 ancestor = ancestor.parent; 4564 } 4565 4566 for (let j = ordered_effects.length - 1; j >= 0; j--) { 4567 const e = ordered_effects[j]; 4568 // Skip eager effects that have already been unmounted 4569 if ((e.f & (DESTROYED | INERT)) !== 0) continue; 4570 update_effect(e); 4571 } 4572 } 4573 4574 eager_block_effects.clear(); 4575 } 4576 } 4577 } 4578 4579 eager_block_effects = null; 4580} 4581 4582/** 4583 * This is similar to `mark_reactions`, but it only marks async/block effects 4584 * depending on `value` and at least one of the other `sources`, so that 4585 * these effects can re-run after another batch has been committed 4586 * @param {Value} value 4587 * @param {Source[]} sources 4588 * @param {Set<Value>} marked 4589 * @param {Map<Reaction, boolean>} checked 4590 */ 4591function mark_effects(value, sources, marked, checked) { 4592 if (marked.has(value)) return; 4593 marked.add(value); 4594 4595 if (value.reactions !== null) { 4596 for (const reaction of value.reactions) { 4597 const flags = reaction.f; 4598 4599 if ((flags & DERIVED) !== 0) { 4600 mark_effects(/** @type {Derived} */ (reaction), sources, marked, checked); 4601 } else if ( 4602 (flags & (ASYNC | BLOCK_EFFECT)) !== 0 && 4603 (flags & DIRTY) === 0 && 4604 depends_on(reaction, sources, checked) 4605 ) { 4606 set_signal_status(reaction, DIRTY); 4607 schedule_effect(/** @type {Effect} */ (reaction)); 4608 } 4609 } 4610 } 4611} 4612 4613/** 4614 * @param {Reaction} reaction 4615 * @param {Source[]} sources 4616 * @param {Map<Reaction, boolean>} checked 4617 */ 4618function depends_on(reaction, sources, checked) { 4619 const depends = checked.get(reaction);
4620 if (depends !== undefined) return depends; 4621 4622 if (reaction.deps !== null) { 4623 for (const dep of reaction.deps) { 4624 if (sources.includes(dep)) { 4625 return true; 4626 } 4627 4628 if ((dep.f & DERIVED) !== 0 && depends_on(/** @type {Derived} */ (dep), sources, checked)) { 4629 checked.set(/** @type {Derived} */ (dep), true); 4630 return true; 4631 } 4632 } 4633 } 4634 4635 checked.set(reaction, false); 4636 4637 return false; 4638} 4639 4640/** 4641 * @param {Effect} signal 4642 * @returns {void} 4643 */ 4644function schedule_effect(signal) { 4645 var effect = (last_scheduled_effect = signal); 4646 4647 while (effect.parent !== null) { 4648 effect = effect.parent; 4649 var flags = effect.f; 4650 4651 // if the effect is being scheduled because a parent (each/await/etc) block 4652 // updated an internal source, bail out or we'll cause a second flush 4653 if ( 4654 is_flushing && 4655 effect === active_effect && 4656 (flags & BLOCK_EFFECT) !== 0 && 4657 (flags & HEAD_EFFECT) === 0 4658 ) { 4659 return; 4660 } 4661 4662 if ((flags & (ROOT_EFFECT | BRANCH_EFFECT)) !== 0) { 4663 if ((flags & CLEAN) === 0) return; 4664 effect.f ^= CLEAN; 4665 } 4666 } 4667 4668 queued_root_effects.push(effect); 4669} 4670 4671/** 4672 * Returns a `subscribe` function that integrates external event-based systems with Svelte's reactivity. 4673 * It's particularly useful for integrating with web APIs like `MediaQuery`, `IntersectionObserver`, or `WebSocket`. 4674 * 4675 * If `subscribe` is called inside an effect (including indirectly, for example inside a getter), 4676 * the `start` callback will be called with an `update` function. Whenever `update` is called, the effect re-runs. 4677 * 4678 * If `start` returns a cleanup function, it will be called when the effect is destroyed. 4679 * 4680 * If `subscribe` is called in multiple effects, `start` will only be called once as long as the effects 4681 * are active, and the returned teardown function will only be called when all effects are destroyed. 4682 * 4683 * It's best understood with an example. Here's an implementation of [`MediaQuery`](https://svelte.dev/docs/svelte/svelte-reactivity#MediaQuery): 4684 * 4685 * ```js 4686 * import { createSubscriber } from 'svelte/reactivity'; 4687 * import { on } from 'svelte/events'; 4688 * 4689 * export class MediaQuery { 4690 * #query; 4691 * #subscribe; 4692 * 4693 * constructor(query) { 4694 * this.#query = window.matchMedia(`(${query})`); 4695 * 4696 * this.#subscribe = createSubscriber((update) => { 4697 * // when the `change` event occurs, re-run any effects that read `this.current` 4698 * const off = on(this.#query, 'change', update); 4699 * 4700 * // stop listening when all the effects are destroyed 4701 * return () => off(); 4702 * }); 4703 * } 4704 * 4705 * get current() { 4706 * // This makes the getter reactive, if read in an effect 4707 * this.#subscribe(); 4708 * 4709 * // Return the current state of the query, whether or not we're in an effect 4710 * return this.#query.matches; 4711 * } 4712 * } 4713 * ``` 4714 * @param {(update: () => void) => (() => void) | void} start 4715 * @since 5.7.0 4716 */ 4717function createSubscriber(start) { 4718 let subscribers = 0; 4719 let version = source(0); 4720 /** @type {(() => void) | void} */ 4721 let stop; 4722 4723 if (DEV) { 4724 tag(version, 'createSubscriber version'); 4725 } 4726 4727 return () => { 4728 if (effect_tracking()) { 4729 get(version); 4730 4731 render_effect(() => { 4732 if (subscribers === 0) { 4733 stop = untrack(() => start(() => increment(version))); 4734 } 4735 4736 subscribers += 1; 4737 4738 return () => { 4739 queue_micro_task(() => { 4740 // Only count down after a microtask, else we would reach 0 before our own render effect reruns, 4741 // but reach 1 again when the tick callback of the prior teardown runs. That would mean we 4742 // re-subcribe unnecessarily and create a memory leak because the old subscription is never cleaned up. 4743 subscribers -= 1; 4744 4745 if (subscribers === 0) { 4746 stop?.(); 4747 stop = undefined; 4748 // Increment the version to ensure any dependent deriveds are marked dirty when the subscription is picked up again later. 4749 // If we didn't do this then the comparison of write versions would determine that the derived has a later version than 4750 // the subscriber, and it would not be re-run. 4751 increment(version); 4752 } 4753 }); 4754 }; 4755 }); 4756 } 4757 }; 4758} 4759 4760/** @import { Effect, Source, TemplateNode, } from '#client' */ 4761 4762/** 4763 * @typedef {{ 4764 * onerror?: (error: unknown, reset: () => void) => void; 4765 * failed?: (anchor: Node, error: () => unknown, reset: () => () => void) => void; 4766 * pending?: (anchor: Node) => void; 4767 * }} BoundaryProps 4768 */ 4769 4770var flags = EFFECT_TRANSPARENT | EFFECT_PRESERVED | BOUNDARY_EFFECT; 4771 4772/** 4773 * @param {TemplateNode} node 4774 * @param {BoundaryProps} props 4775 * @param {((anchor: Node) => void)} children 4776 * @returns {void} 4777 */ 4778function boundary(node, props, children) { 4779 new Boundary(node, props, children); 4780} 4781 4782class Boundary { 4783 /** @type {Boundary | null} */ 4784 parent; 4785 4786 is_pending = false;
4787 4788 /** @type {TemplateNode} */ 4789 #anchor; 4790 4791 /** @type {TemplateNode | null} */ 4792 #hydrate_open = hydrating ? hydrate_node : null; 4793 4794 /** @type {BoundaryProps} */ 4795 #props; 4796 4797 /** @type {((anchor: Node) => void)} */ 4798 #children; 4799 4800 /** @type {Effect} */ 4801 #effect; 4802 4803 /** @type {Effect | null} */ 4804 #main_effect = null; 4805 4806 /** @type {Effect | null} */ 4807 #pending_effect = null; 4808 4809 /** @type {Effect | null} */ 4810 #failed_effect = null; 4811 4812 /** @type {DocumentFragment | null} */ 4813 #offscreen_fragment = null; 4814 4815 /** @type {TemplateNode | null} */ 4816 #pending_anchor = null; 4817 4818 #local_pending_count = 0; 4819 #pending_count = 0; 4820 4821 #is_creating_fallback = false; 4822 4823 /** @type {Set<Effect>} */ 4824 #dirty_effects = new Set(); 4825 4826 /** @type {Set<Effect>} */ 4827 #maybe_dirty_effects = new Set(); 4828 4829 /** 4830 * A source containing the number of pending async deriveds/expressions. 4831 * Only created if `$effect.pending()` is used inside the boundary, 4832 * otherwise updating the source results in needless `Batch.ensure()` 4833 * calls followed by no-op flushes 4834 * @type {Source<number> | null} 4835 */ 4836 #effect_pending = null; 4837 4838 #effect_pending_subscriber = createSubscriber(() => { 4839 this.#effect_pending = source(this.#local_pending_count); 4840 4841 if (DEV) { 4842 tag(this.#effect_pending, '$effect.pending()'); 4843 } 4844 4845 return () => { 4846 this.#effect_pending = null; 4847 }; 4848 }); 4849 4850 /** 4851 * @param {TemplateNode} node 4852 * @param {BoundaryProps} props 4853 * @param {((anchor: Node) => void)} children 4854 */ 4855 constructor(node, props, children) { 4856 this.#anchor = node; 4857 this.#props = props; 4858 this.#children = children; 4859 4860 this.parent = /** @type {Effect} */ (active_effect).b; 4861 4862 this.is_pending = !!this.#props.pending; 4863 4864 this.#effect = block(() => { 4865 /** @type {Effect} */ (active_effect).b = this; 4866 4867 if (hydrating) { 4868 const comment = this.#hydrate_open; 4869 hydrate_next(); 4870 4871 const server_rendered_pending = 4872 /** @type {Comment} */ (comment).nodeType === COMMENT_NODE && 4873 /** @type {Comment} */ (comment).data === HYDRATION_START_ELSE; 4874 4875 if (server_rendered_pending) { 4876 this.#hydrate_pending_content(); 4877 } else { 4878 this.#hydrate_resolved_content(); 4879 4880 if (this.#pending_count === 0) { 4881 this.is_pending = false; 4882 } 4883 } 4884 } else { 4885 var anchor = this.#get_anchor(); 4886 4887 try { 4888 this.#main_effect = branch(() => children(anchor)); 4889 } catch (error) { 4890 this.error(error); 4891 } 4892 4893 if (this.#pending_count > 0) { 4894 this.#show_pending_snippet(); 4895 } else { 4896 this.is_pending = false; 4897 } 4898 } 4899 4900 return () => { 4901 this.#pending_anchor?.remove(); 4902 }; 4903 }, flags); 4904 4905 if (hydrating) { 4906 this.#anchor = hydrate_node; 4907 } 4908 } 4909 4910 #hydrate_resolved_content() { 4911 try { 4912 this.#main_effect = branch(() => this.#children(this.#anchor)); 4913 } catch (error) { 4914 this.error(error); 4915 } 4916 } 4917 4918 #hydrate_pending_content() { 4919 const pending = this.#props.pending; 4920 if (!pending) { 4921 return; 4922 } 4923 this.#pending_effect = branch(() => pending(this.#anchor)); 4924 4925 Batch.enqueue(() => { 4926 var anchor = this.#get_anchor(); 4927 4928 this.#main_effect = this.#run(() => { 4929 Batch.ensure(); 4930 return branch(() => this.#children(anchor)); 4931 }); 4932 4933 if (this.#pending_count > 0) { 4934 this.#show_pending_snippet(); 4935 } else { 4936 pause_effect(/** @type {Effect} */ (this.#pending_effect), () => { 4937 this.#pending_effect = null; 4938 }); 4939 4940 this.is_pending = false; 4941 } 4942 }); 4943 } 4944 4945 #get_anchor() { 4946 var anchor = this.#anchor; 4947 4948 if (this.is_pending) { 4949 this.#pending_anchor = create_text(); 4950 this.#anchor.before(this.#pending_anchor); 4951 4952 anchor = this.#pending_anchor; 4953 } 4954 4955 return anchor; 4956 } 4957 4958 /** 4959 * Defer an effect inside a pending boundary until the boundary resolves 4960 * @param {Effect} effect 4961 */ 4962 defer_effect(effect) { 4963 defer_effect(effect, this.#dirty_effects, this.#maybe_dirty_effects); 4964 } 4965 4966 /** 4967 * Returns `false` if the effect exists inside a boundary whose pending snippet is shown 4968 * @returns {boolean} 4969 */ 4970 is_rendered() { 4971 return !this.is_pending && (!this.parent || this.parent.is_rendered()); 4972 } 4973 4974 has_pending_snippet() { 4975 return !!this.#props.pending; 4976 } 4977 4978 /** 4979 * @param {() => Effect | null} fn 4980 */ 4981 #run(fn) { 4982 var previous_effect = active_effect; 4983 var previous_reaction = active_reaction; 4984 var previous_ctx = component_context; 4985 4986 set_active_effect(this.#effect); 4987 set_active_reaction(this.#effect); 4988 set_component_context(this.#effect.ctx); 4989 4990 try { 4991 return fn(); 4992 } catch (e) { 4993 handle_error(e); 4994 return null; 4995 } finally { 4996 set_active_effect(previous_effect); 4997 set_active_reaction(previous_reaction); 4998 set_component_context(previous_ctx); 4999 } 5000 } 5001 5002 #show_pending_snippet() { 5003 const pending = /** @type {(anchor: Node) => void} */ (this.#props.pending); 5004 5005 if (this.#main_effect !== null) { 5006 this.#offscreen_fragment = document.createDocumentFragment(); 5007 this.#offscreen_fragment.append(/** @type {TemplateNode} */ (this.#pending_anchor)); 5008 move_effect(this.#main_effect, this.#offscreen_fragment); 5009 } 5010 5011 if (this.#pending_effect === null) { 5012 this.#pending_effect = branch(() => pending(this.#anchor)); 5013 } 5014 } 5015
5016 /** 5017 * Updates the pending count associated with the currently visible pending snippet, 5018 * if any, such that we can replace the snippet with content once work is done 5019 * @param {1 | -1} d 5020 */ 5021 #update_pending_count(d) { 5022 if (!this.has_pending_snippet()) { 5023 if (this.parent) { 5024 this.parent.#update_pending_count(d); 5025 } 5026 5027 // if there's no parent, we're in a scope with no pending snippet 5028 return; 5029 } 5030 5031 this.#pending_count += d; 5032 5033 if (this.#pending_count === 0) { 5034 this.is_pending = false; 5035 5036 // any effects that were encountered and deferred during traversal 5037 // should be rescheduled â after the next traversal (which will happen 5038 // immediately, due to the same update that brought us here) 5039 // the effects will be flushed 5040 for (const e of this.#dirty_effects) { 5041 set_signal_status(e, DIRTY); 5042 schedule_effect(e); 5043 } 5044 5045 for (const e of this.#maybe_dirty_effects) { 5046 set_signal_status(e, MAYBE_DIRTY); 5047 schedule_effect(e); 5048 } 5049 5050 this.#dirty_effects.clear(); 5051 this.#maybe_dirty_effects.clear(); 5052 5053 if (this.#pending_effect) { 5054 pause_effect(this.#pending_effect, () => { 5055 this.#pending_effect = null; 5056 }); 5057 } 5058 5059 if (this.#offscreen_fragment) { 5060 this.#anchor.before(this.#offscreen_fragment); 5061 this.#offscreen_fragment = null; 5062 } 5063 } 5064 } 5065 5066 /** 5067 * Update the source that powers `$effect.pending()` inside this boundary, 5068 * and controls when the current `pending` snippet (if any) is removed. 5069 * Do not call from inside the class 5070 * @param {1 | -1} d 5071 */ 5072 update_pending_count(d) { 5073 this.#update_pending_count(d); 5074 5075 this.#local_pending_count += d; 5076 5077 if (this.#effect_pending) { 5078 internal_set(this.#effect_pending, this.#local_pending_count); 5079 } 5080 } 5081 5082 get_effect_pending() { 5083 this.#effect_pending_subscriber(); 5084 return get(/** @type {Source<number>} */ (this.#effect_pending)); 5085 } 5086 5087 /** @param {unknown} error */ 5088 error(error) { 5089 var onerror = this.#props.onerror; 5090 let failed = this.#props.failed; 5091 5092 // If we have nothing to capture the error, or if we hit an error while 5093 // rendering the fallback, re-throw for another boundary to handle 5094 if (this.#is_creating_fallback || (!onerror && !failed)) { 5095 throw error; 5096 } 5097 5098 if (this.#main_effect) { 5099 destroy_effect(this.#main_effect); 5100 this.#main_effect = null; 5101 } 5102 5103 if (this.#pending_effect) { 5104 destroy_effect(this.#pending_effect); 5105 this.#pending_effect = null; 5106 } 5107 5108 if (this.#failed_effect) { 5109 destroy_effect(this.#failed_effect); 5110 this.#failed_effect = null; 5111 } 5112 5113 if (hydrating) { 5114 set_hydrate_node(/** @type {TemplateNode} */ (this.#hydrate_open)); 5115 next(); 5116 set_hydrate_node(skip_nodes()); 5117 } 5118 5119 var did_reset = false; 5120 var calling_on_error = false; 5121 5122 const reset = () => { 5123 if (did_reset) { 5124 svelte_boundary_reset_noop(); 5125 return; 5126 } 5127 5128 did_reset = true; 5129 5130 if (calling_on_error) { 5131 svelte_boundary_reset_onerror(); 5132 } 5133 5134 // If the failure happened while flushing effects, current_batch can be null 5135 Batch.ensure(); 5136 5137 this.#local_pending_count = 0; 5138 5139 if (this.#failed_effect !== null) { 5140 pause_effect(this.#failed_effect, () => { 5141 this.#failed_effect = null; 5142 }); 5143 } 5144 5145 // we intentionally do not try to find the nearest pending boundary. If this boundary has one, we'll render it on reset 5146 // but it would be really weird to show the parent's boundary on a child reset. 5147 this.is_pending = this.has_pending_snippet(); 5148 5149 this.#main_effect = this.#run(() => { 5150 this.#is_creating_fallback = false; 5151 return branch(() => this.#children(this.#anchor)); 5152 }); 5153 5154 if (this.#pending_count > 0) { 5155 this.#show_pending_snippet(); 5156 } else { 5157 this.is_pending = false; 5158 } 5159 }; 5160 5161 var previous_reaction = active_reaction; 5162 5163 try { 5164 set_active_reaction(null); 5165 calling_on_error = true; 5166 onerror?.(error, reset); 5167 calling_on_error = false; 5168 } catch (error) { 5169 invoke_error_boundary(error, this.#effect && this.#effect.parent); 5170 } finally { 5171 set_active_reaction(previous_reaction); 5172 } 5173 5174 if (failed) { 5175 queue_micro_task(() => { 5176 this.#failed_effect = this.#run(() => { 5177 Batch.ensure(); 5178 this.#is_creating_fallback = true; 5179 5180 try { 5181 return branch(() => { 5182 failed( 5183 this.#anchor, 5184 () => error, 5185 () => reset 5186 ); 5187 }); 5188 } catch (error) { 5189 invoke_error_boundary(error, /** @type {Effect} */ (this.#effect.parent)); 5190 return null; 5191 } finally { 5192 this.#is_creating_fallback = false;
5193 } 5194 }); 5195 }); 5196 } 5197 } 5198} 5199 5200function get_boundary() { 5201 return /** @type {Boundary} */ (/** @type {Effect} */ (active_effect).b); 5202} 5203 5204/** @import { Effect, TemplateNode, Value } from '#client' */ 5205 5206/** 5207 * @param {Array<Promise<void>>} blockers 5208 * @param {Array<() => any>} sync 5209 * @param {Array<() => Promise<any>>} async 5210 * @param {(values: Value[]) => any} fn 5211 */ 5212function flatten(blockers, sync, async, fn) { 5213 const d = is_runes() ? derived : derived_safe_equal; 5214 5215 if (async.length === 0 && blockers.length === 0) { 5216 fn(sync.map(d)); 5217 return; 5218 } 5219 5220 var batch = current_batch; 5221 var parent = /** @type {Effect} */ (active_effect); 5222 5223 var restore = capture(); 5224 5225 function run() { 5226 Promise.all(async.map((expression) => async_derived(expression))) 5227 .then((result) => { 5228 restore(); 5229 5230 try { 5231 fn([...sync.map(d), ...result]); 5232 } catch (error) { 5233 // ignore errors in blocks that have already been destroyed 5234 if ((parent.f & DESTROYED) === 0) { 5235 invoke_error_boundary(error, parent); 5236 } 5237 } 5238 5239 batch?.deactivate(); 5240 unset_context(); 5241 }) 5242 .catch((error) => { 5243 invoke_error_boundary(error, parent); 5244 }); 5245 } 5246 5247 if (blockers.length > 0) { 5248 Promise.all(blockers).then(() => { 5249 restore(); 5250 5251 try { 5252 return run(); 5253 } finally { 5254 batch?.deactivate(); 5255 unset_context(); 5256 } 5257 }); 5258 } else { 5259 run(); 5260 } 5261} 5262 5263/** 5264 * @param {Array<Promise<void>>} blockers 5265 * @param {(values: Value[]) => any} fn 5266 */ 5267function run_after_blockers(blockers, fn) { 5268 flatten(blockers, [], [], fn); 5269} 5270 5271/** 5272 * Captures the current effect context so that we can restore it after 5273 * some asynchronous work has happened (so that e.g. `await a + b` 5274 * causes `b` to be registered as a dependency). 5275 */ 5276function capture() { 5277 var previous_effect = active_effect; 5278 var previous_reaction = active_reaction; 5279 var previous_component_context = component_context; 5280 var previous_batch = current_batch; 5281 5282 if (DEV) { 5283 var previous_dev_stack = dev_stack; 5284 } 5285 5286 return function restore(activate_batch = true) { 5287 set_active_effect(previous_effect); 5288 set_active_reaction(previous_reaction); 5289 set_component_context(previous_component_context); 5290 if (activate_batch) previous_batch?.activate(); 5291 5292 if (DEV) { 5293 set_dev_stack(previous_dev_stack); 5294 } 5295 }; 5296} 5297 5298function unset_context() { 5299 set_active_effect(null); 5300 set_active_reaction(null); 5301 set_component_context(null); 5302 5303 if (DEV) { 5304 set_dev_stack(null); 5305 } 5306} 5307 5308/** 5309 * @param {Array<() => void | Promise<void>>} thunks 5310 */ 5311function run(thunks) { 5312 const restore = capture(); 5313 5314 var boundary = get_boundary(); 5315 var batch = /** @type {Batch} */ (current_batch); 5316 var blocking = boundary.is_rendered(); 5317 5318 boundary.update_pending_count(1); 5319 batch.increment(blocking); 5320 5321 var active = /** @type {Effect} */ (active_effect); 5322 5323 /** @type {null | { error: any }} */ 5324 var errored = null; 5325 5326 /** @param {any} error */ 5327 const handle_error = (error) => { 5328 errored = { error }; // wrap in object in case a promise rejects with a falsy value 5329 5330 if (!aborted(active)) { 5331 invoke_error_boundary(error, active); 5332 } 5333 }; 5334 5335 var promise = Promise.resolve(thunks[0]()).catch(handle_error); 5336 5337 var promises = [promise]; 5338 5339 for (const fn of thunks.slice(1)) { 5340 promise = promise 5341 .then(() => { 5342 if (errored) { 5343 throw errored.error; 5344 } 5345 5346 if (aborted(active)) { 5347 throw STALE_REACTION; 5348 } 5349 5350 restore(); 5351 return fn(); 5352 }) 5353 .catch(handle_error) 5354 .finally(() => { 5355 unset_context(); 5356 current_batch?.deactivate(); 5357 }); 5358 5359 promises.push(promise); 5360 } 5361 5362 promise 5363 // wait one more tick, so that template effects are 5364 // guaranteed to run before `$effect(...)` 5365 .then(() => Promise.resolve()) 5366 .finally(() => { 5367 boundary.update_pending_count(-1); 5368 batch.decrement(blocking); 5369 }); 5370 5371 return promises; 5372} 5373 5374/** @import { Derived, Effect, Source } from '#client' */ 5375/** @import { Batch } from './batch.js'; */ 5376 5377const recent_async_deriveds = new Set(); 5378 5379/** 5380 * @template V 5381 * @param {() => V} fn 5382 * @returns {Derived<V>} 5383 */ 5384/*#__NO_SIDE_EFFECTS__*/ 5385function derived(fn) { 5386 var flags = DERIVED | DIRTY; 5387 var parent_derived = 5388 active_reaction !== null && (active_reaction.f & DERIVED) !== 0 5389 ? /** @type {Derived} */ (active_reaction) 5390 : null; 5391 5392 if (active_effect !== null) { 5393 // Since deriveds are evaluated lazily, any effects created inside them are 5394 // created too late to ensure that the parent effect is added to the tree 5395 active_effect.f |= EFFECT_PRESERVED; 5396 } 5397 5398 /** @type {Derived<V>} */ 5399 const signal = { 5400 ctx: component_context, 5401 deps: null, 5402 effects: null, 5403 equals, 5404 f: flags, 5405 fn, 5406 reactions: null, 5407 rv: 0, 5408 v: /** @type {V} */ (UNINITIALIZED), 5409 wv: 0, 5410 parent: parent_derived ?? active_effect, 5411 ac: null 5412 }; 5413 5414 return signal; 5415} 5416 5417/** 5418 * @template V 5419 * @param {() => V | Promise<V>} fn 5420 * @param {string} [label] 5421 * @param {string} [location] If provided, print a warning if the value is not read immediately after update 5422 * @returns {Promise<Source<V>>} 5423 */ 5424/*#__NO_SIDE_EFFECTS__*/ 5425function async_derived(fn, label, location) { 5426 let parent = /** @type {Effect | null} */ (active_effect); 5427 5428 if (parent === null) { 5429 async_derived_orphan(); 5430 } 5431 5432 var boundary = /** @type {Boundary} */ (parent.b); 5433 5434 var promise = /** @type {Promise<V>} */ (/** @type {unknown} */ (undefined)); 5435 var signal = source(/** @type {V} */ (UNINITIALIZED)); 5436 5437 if (DEV) signal.label = label; 5438 5439 // only suspend in async deriveds created on initialisation 5440 var should_suspend = !active_reaction; 5441 5442 /** @type {Map<Batch, ReturnType<typeof deferred<V>>>} */ 5443 var deferreds = new Map(); 5444 5445 async_effect(() => { 5446 5447 /** @type {ReturnType<typeof deferred<V>>} */ 5448 var d = deferred(); 5449 promise = d.promise; 5450 5451 try { 5452 // If this code is changed at some point, make sure to still access the then property 5453 // of fn() to read any signals it might access, so that we track them as dependencies. 5454 // We call `unset_context` to undo any `save` calls that happen inside `fn()` 5455 Promise.resolve(fn()) 5456 .then(d.resolve, d.reject) 5457 .then(() => { 5458 if (batch === current_batch && batch.committed) { 5459 // if the batch was rejected as stale, we need to cleanup 5460 // after any `$.save(...)` calls inside `fn()` 5461 batch.deactivate(); 5462 } 5463 5464 unset_context(); 5465 }); 5466 } catch (error) { 5467 d.reject(error); 5468 unset_context(); 5469 } 5470 5471 var batch = /** @type {Batch} */ (current_batch); 5472 5473 if (should_suspend) { 5474 var blocking = boundary.is_rendered(); 5475 5476 boundary.update_pending_count(1); 5477 batch.increment(blocking); 5478 5479 deferreds.get(batch)?.reject(STALE_REACTION); 5480 deferreds.delete(batch); // delete to ensure correct order in Map iteration below 5481 deferreds.set(batch, d); 5482 } 5483 5484 /** 5485 * @param {any} value 5486 * @param {unknown} error 5487 */ 5488 const handler = (value, error = undefined) => { 5489 5490 batch.activate(); 5491 5492 if (error) { 5493 if (error !== STALE_REACTION) { 5494 signal.f |= ERROR_VALUE; 5495 5496 // @ts-expect-error the error is the wrong type, but we don't care 5497 internal_set(signal, error); 5498 } 5499 } else { 5500 if ((signal.f & ERROR_VALUE) !== 0) { 5501 signal.f ^= ERROR_VALUE; 5502 } 5503 5504 internal_set(signal, value); 5505 5506 // All prior async derived runs are now stale 5507 for (const [b, d] of deferreds) { 5508 deferreds.delete(b); 5509 if (b === batch) break; 5510 d.reject(STALE_REACTION); 5511 } 5512 } 5513 5514 if (should_suspend) { 5515 boundary.update_pending_count(-1);
5516 batch.decrement(blocking); 5517 } 5518 }; 5519 5520 d.promise.then(handler, (e) => handler(null, e || 'unknown')); 5521 }); 5522 5523 teardown(() => { 5524 for (const d of deferreds.values()) { 5525 d.reject(STALE_REACTION); 5526 } 5527 }); 5528 5529 if (DEV) { 5530 // add a flag that lets this be printed as a derived 5531 // when using `$inspect.trace()` 5532 signal.f |= ASYNC; 5533 } 5534 5535 return new Promise((fulfil) => { 5536 /** @param {Promise<V>} p */ 5537 function next(p) { 5538 function go() { 5539 if (p === promise) { 5540 fulfil(signal); 5541 } else { 5542 // if the effect re-runs before the initial promise 5543 // resolves, delay resolution until we have a value 5544 next(promise); 5545 } 5546 } 5547 5548 p.then(go, go); 5549 } 5550 5551 next(promise); 5552 }); 5553} 5554 5555/** 5556 * @template V 5557 * @param {() => V} fn 5558 * @returns {Derived<V>} 5559 */ 5560/*#__NO_SIDE_EFFECTS__*/ 5561function user_derived(fn) { 5562 const d = derived(fn); 5563 5564 if (!async_mode_flag) push_reaction_value(d); 5565 5566 return d; 5567} 5568 5569/** 5570 * @template V 5571 * @param {() => V} fn 5572 * @returns {Derived<V>} 5573 */ 5574/*#__NO_SIDE_EFFECTS__*/ 5575function derived_safe_equal(fn) { 5576 const signal = derived(fn); 5577 signal.equals = safe_equals; 5578 return signal; 5579} 5580 5581/** 5582 * @param {Derived} derived 5583 * @returns {void} 5584 */ 5585function destroy_derived_effects(derived) { 5586 var effects = derived.effects; 5587 5588 if (effects !== null) { 5589 derived.effects = null; 5590 5591 for (var i = 0; i < effects.length; i += 1) { 5592 destroy_effect(/** @type {Effect} */ (effects[i])); 5593 } 5594 } 5595} 5596 5597/** 5598 * The currently updating deriveds, used to detect infinite recursion 5599 * in dev mode and provide a nicer error than 'too much recursion' 5600 * @type {Derived[]} 5601 */ 5602let stack = []; 5603 5604/** 5605 * @param {Derived} derived 5606 * @returns {Effect | null} 5607 */ 5608function get_derived_parent_effect(derived) { 5609 var parent = derived.parent; 5610 while (parent !== null) { 5611 if ((parent.f & DERIVED) === 0) { 5612 // The original parent effect might've been destroyed but the derived 5613 // is used elsewhere now - do not return the destroyed effect in that case 5614 return (parent.f & DESTROYED) === 0 ? /** @type {Effect} */ (parent) : null; 5615 } 5616 parent = parent.parent; 5617 } 5618 return null; 5619} 5620 5621/** 5622 * @template T 5623 * @param {Derived} derived 5624 * @returns {T} 5625 */ 5626function execute_derived(derived) { 5627 var value; 5628 var prev_active_effect = active_effect; 5629 5630 set_active_effect(get_derived_parent_effect(derived)); 5631 5632 if (DEV) { 5633 let prev_eager_effects = eager_effects; 5634 set_eager_effects(new Set()); 5635 try { 5636 if (stack.includes(derived)) { 5637 derived_references_self(); 5638 } 5639 5640 stack.push(derived); 5641 5642 derived.f &= ~WAS_MARKED; 5643 destroy_derived_effects(derived); 5644 value = update_reaction(derived); 5645 } finally { 5646 set_active_effect(prev_active_effect); 5647 set_eager_effects(prev_eager_effects); 5648 stack.pop(); 5649 } 5650 } else { 5651 try { 5652 derived.f &= ~WAS_MARKED; 5653 destroy_derived_effects(derived); 5654 value = update_reaction(derived); 5655 } finally { 5656 set_active_effect(prev_active_effect); 5657 } 5658 } 5659 5660 return value; 5661} 5662 5663/** 5664 * @param {Derived} derived 5665 * @returns {void} 5666 */ 5667function update_derived(derived) { 5668 var value = execute_derived(derived); 5669 5670 if (!derived.equals(value)) { 5671 derived.wv = increment_write_version(); 5672 5673 // in a fork, we don't update the underlying value, just `batch_values`. 5674 // the underlying value will be updated when the fork is committed. 5675 // otherwise, the next time we get here after a 'real world' state 5676 // change, `derived.equals` may incorrectly return `true` 5677 if (!current_batch?.is_fork || derived.deps === null) { 5678 derived.v = value; 5679 5680 // deriveds without dependencies should never be recomputed 5681 if (derived.deps === null) { 5682 set_signal_status(derived, CLEAN); 5683 return; 5684 } 5685 } 5686 } 5687 5688 // don't mark derived clean if we're reading it inside a 5689 // cleanup function, or it will cache a stale value 5690 if (is_destroying_effect) { 5691 return; 5692 } 5693 5694 // During time traveling we don't want to reset the status so that 5695 // traversal of the graph in the other batches still happens 5696 if (batch_values !== null) { 5697 // only cache the value if we're in a tracking context, otherwise we won't 5698 // clear the cache in `mark_reactions` when dependencies are updated 5699 if (effect_tracking() || current_batch?.is_fork) { 5700 batch_values.set(derived, value); 5701 } 5702 } else { 5703 update_derived_status(derived); 5704 } 5705} 5706 5707/** @import { Derived, Effect, Source, Value } from '#client' */ 5708 5709/** @type {Set<any>} */ 5710let eager_effects = new Set(); 5711 5712/** @type {Map<Source, any>} */ 5713const old_values = new Map(); 5714 5715/** 5716 * @param {Set<any>} v 5717 */ 5718function set_eager_effects(v) { 5719 eager_effects = v; 5720} 5721 5722let eager_effects_deferred = false;
5723 5724function set_eager_effects_deferred() { 5725 eager_effects_deferred = true; 5726} 5727 5728/** 5729 * @template V 5730 * @param {V} v 5731 * @param {Error | null} [stack] 5732 * @returns {Source<V>} 5733 */ 5734// TODO rename this to `state` throughout the codebase 5735function source(v, stack) { 5736 /** @type {Value} */ 5737 var signal = { 5738 f: 0, // TODO ideally we could skip this altogether, but it causes type errors 5739 v, 5740 reactions: null, 5741 equals, 5742 rv: 0, 5743 wv: 0 5744 }; 5745 5746 return signal; 5747} 5748 5749/** 5750 * @template V 5751 * @param {V} v 5752 * @param {Error | null} [stack] 5753 */ 5754/*#__NO_SIDE_EFFECTS__*/ 5755function state(v, stack) { 5756 const s = source(v); 5757 5758 push_reaction_value(s); 5759 5760 return s; 5761} 5762 5763/** 5764 * @template V 5765 * @param {V} initial_value 5766 * @param {boolean} [immutable] 5767 * @returns {Source<V>} 5768 */ 5769/*#__NO_SIDE_EFFECTS__*/ 5770function mutable_source(initial_value, immutable = false, trackable = true) { 5771 const s = source(initial_value); 5772 if (!immutable) { 5773 s.equals = safe_equals; 5774 } 5775 5776 // bind the signal to the component context, in case we need to 5777 // track updates to trigger beforeUpdate/afterUpdate callbacks 5778 if (legacy_mode_flag && trackable && component_context !== null && component_context.l !== null) { 5779 (component_context.l.s ??= []).push(s); 5780 } 5781 5782 return s; 5783} 5784 5785/** 5786 * @template V 5787 * @param {Value<V>}
5787 source 5788 * @param {V} value 5789 */ 5790function mutate(source, value) { 5791 set( 5792 source, 5793 untrack(() => get(source)) 5794 ); 5795 return value; 5796} 5797 5798/** 5799 * @template V 5800 * @param {Source<V>} source 5801 * @param {V} value 5802 * @param {boolean} [should_proxy] 5803 * @returns {V} 5804 */ 5805function set(source, value, should_proxy = false) { 5806 if ( 5807 active_reaction !== null && 5808 // since we are untracking the function inside `$inspect.with` we need to add this check 5809 // to ensure we error if state is set inside an inspect effect 5810 (!untracking || (active_reaction.f & EAGER_EFFECT) !== 0) && 5811 is_runes() && 5812 (active_reaction.f & (DERIVED | BLOCK_EFFECT | ASYNC | EAGER_EFFECT)) !== 0 && 5813 !current_sources?.includes(source) 5814 ) { 5815 state_unsafe_mutation(); 5816 } 5817 5818 let new_value = should_proxy ? proxy(value) : value; 5819 5820 if (DEV) { 5821 tag_proxy(new_value, /** @type {string} */ (source.label)); 5822 } 5823 5824 return internal_set(source, new_value); 5825} 5826 5827/** 5828 * @template V 5829 * @param {Source<V>} source 5830 * @param {V} value 5831 * @returns {V} 5832 */ 5833function internal_set(source, value) { 5834 if (!source.equals(value)) { 5835 var old_value = source.v; 5836 5837 if (is_destroying_effect) { 5838 old_values.set(source, value); 5839 } else { 5840 old_values.set(source, old_value); 5841 } 5842 5843 source.v = value; 5844 5845 var batch = Batch.ensure(); 5846 batch.capture(source, old_value); 5847 5848 if (DEV) { 5849 if (active_effect !== null) { 5850 source.updated ??= new Map(); 5851 5852 // For performance reasons, when not using $inspect.trace, we only start collecting stack traces 5853 // after the same source has been updated more than 5 times in the same flush cycle. 5854 const count = (source.updated.get('')?.count ?? 0) + 1; 5855 source.updated.set('', { error: /** @type {any} */ (null), count }); 5856 5857 if (count > 5) { 5858 const error = get_error('updated at'); 5859 5860 if (error !== null) { 5861 let entry = source.updated.get(error.stack); 5862 5863 if (!entry) { 5864 entry = { error, count: 0 }; 5865 source.updated.set(error.stack, entry); 5866 } 5867 5868 entry.count++; 5869 } 5870 } 5871 } 5872 5873 if (active_effect !== null) { 5874 source.set_during_effect = true; 5875 } 5876 } 5877 5878 if ((source.f & DERIVED) !== 0) { 5879 const derived = /** @type {Derived} */ (source); 5880 5881 // if we are assigning to a dirty derived we set it to clean/maybe dirty but we also eagerly execute it to track the dependencies 5882 if ((source.f & DIRTY) !== 0) { 5883 execute_derived(derived); 5884 } 5885 5886 update_derived_status(derived); 5887 } 5888 5889 source.wv = increment_write_version(); 5890 5891 // For debugging, in case you want to know which reactions are being scheduled: 5892 // log_reactions(source); 5893 mark_reactions(source, DIRTY); 5894 5895 // It's possible that the current reaction might not have up-to-date dependencies 5896 // whilst it's actively running. So in the case of ensuring it registers the reaction 5897 // properly for itself, we need to ensure the current effect actually gets 5898 // scheduled. i.e: `$effect(() => x++)` 5899 if ( 5900 is_runes() && 5901 active_effect !== null && 5902 (active_effect.f & CLEAN) !== 0 && 5903 (active_effect.f & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 5904 ) { 5905 if (untracked_writes === null) { 5906 set_untracked_writes([source]); 5907 } else { 5908 untracked_writes.push(source); 5909 } 5910 } 5911 5912 if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) { 5913 flush_eager_effects(); 5914 } 5915 } 5916 5917 return value; 5918} 5919 5920function flush_eager_effects() { 5921 eager_effects_deferred = false; 5922 var prev_is_updating_effect = is_updating_effect; 5923 set_is_updating_effect(true); 5924 5925 const inspects = Array.from(eager_effects); 5926 5927 try { 5928 for (const effect of inspects) { 5929 // Mark clean inspect-effects as maybe dirty and then check their dirtiness 5930 // instead of just updating the effects - this way we avoid overfiring. 5931 if ((effect.f & CLEAN) !== 0) { 5932 set_signal_status(effect, MAYBE_DIRTY); 5933 } 5934 5935 if (is_dirty(effect)) { 5936 update_effect(effect); 5937 } 5938 } 5939 } finally { 5940 set_is_updating_effect(prev_is_updating_effect); 5941 } 5942 5943 eager_effects.clear(); 5944} 5945 5946/** 5947 * @template {number | bigint} T 5948 * @param {Source<T>} source 5949 * @param {1 | -1} [d] 5950 * @returns {T} 5951 */ 5952function update(source, d = 1) { 5953 var value = get(source); 5954 var result = d === 1 ? value++ : value--; 5955 5956 set(source, value); 5957 5958 // @ts-expect-error 5959 return result; 5960} 5961 5962/** 5963 * Silently (without using `get`) increment a source 5964 * @param {Source<number>} source 5965 */ 5966function increment(source) { 5967 set(source, source.v + 1); 5968} 5969 5970/** 5971 * @param {Value} signal 5972 * @param {number} status should be DIRTY or MAYBE_DIRTY 5973 * @returns {void} 5974 */ 5975function mark_reactions(signal, status) { 5976 var reactions = signal.reactions; 5977 if (reactions === null) return; 5978 5979 var runes = is_runes(); 5980 var length = reactions.length; 5981 5982 for (var i = 0; i < length; i++) { 5983 var reaction = reactions[i]; 5984 var flags = reaction.f; 5985 5986 // In legacy mode, skip the current effect to prevent infinite loops 5987 if (!runes && reaction === active_effect) continue; 5988 5989 // Inspect effects need to run immediately, so that the stack trace makes sense 5990 if (DEV && (flags & EAGER_EFFECT) !== 0) { 5991 eager_effects.add(reaction); 5992 continue; 5993 } 5994 5995 var not_dirty = (flags & DIRTY) === 0; 5996 5997 // don't set a DIRTY reaction to MAYBE_DIRTY 5998 if (not_dirty) { 5999 set_signal_status(reaction, status); 6000 } 6001 6002 if ((flags & DERIVED) !== 0) { 6003 var derived = /** @type {Derived} */ (reaction); 6004 6005 batch_values?.delete(derived); 6006 6007 if ((flags & WAS_MARKED) === 0) { 6008 // Only connected deriveds can be reliably unmarked right away 6009 if (flags & CONNECTED) { 6010 reaction.f |= WAS_MARKED; 6011 } 6012 6013 mark_reactions(derived, MAYBE_DIRTY); 6014 } 6015 } else if (not_dirty) { 6016 if ((flags & BLOCK_EFFECT) !== 0 && eager_block_effects !== null) { 6017 eager_block_effects.add(/** @type {Effect} */ (reaction)); 6018 } 6019 6020 schedule_effect(/** @type {Effect} */ (reaction)); 6021 } 6022 } 6023} 6024 6025/** @import { Source } from '#client' */ 6026 6027// TODO move all regexes into shared module? 6028const regex_is_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; 6029 6030/** 6031 * @template T 6032 * @param {T} value 6033 * @returns {T} 6034 */ 6035function proxy(value) { 6036 // if non-proxyable, or is already a proxy, return `value` 6037 if (typeof value !== 'object' || value === null || STATE_SYMBOL in value) { 6038 return value; 6039 } 6040 6041 const prototype = get_prototype_of(value); 6042 6043 if (prototype !== object_prototype && prototype !== array_prototype) { 6044 return value; 6045 } 6046 6047 /** @type {Map<any, Source<any>>} */ 6048 var sources = new Map(); 6049 var is_proxied_array = is_array(value); 6050 var version = state(0); 6051 var parent_version = update_version; 6052 6053 /** 6054 * Executes the proxy in the context of the reaction it was originally created in, if any 6055 * @template T 6056 * @param {() => T} fn 6057 */ 6058 var with_parent = (fn) => { 6059 if (update_version === parent_version) { 6060 return fn(); 6061 } 6062 6063 // child source is being created after the initial proxy â 6064 // prevent it from being associated with the current reaction 6065 var reaction = active_reaction; 6066 var version = update_version; 6067 6068 set_active_reaction(null);
6069 set_update_version(parent_version); 6070 6071 var result = fn(); 6072 6073 set_active_reaction(reaction); 6074 set_update_version(version); 6075 6076 return result; 6077 }; 6078 6079 if (is_proxied_array) { 6080 // We need to create the length source eagerly to ensure that 6081 // mutations to the array are properly synced with our proxy 6082 sources.set('length', state(/** @type {any[]} */ (value).length)); 6083 if (DEV) { 6084 value = /** @type {any} */ (inspectable_array(/** @type {any[]} */ (value))); 6085 } 6086 } 6087 6088 /** Used in dev for $inspect.trace() */ 6089 var path = ''; 6090 let updating = false; 6091 /** @param {string} new_path */ 6092 function update_path(new_path) { 6093 if (updating) return; 6094 updating = true; 6095 path = new_path; 6096 6097 tag(version, `${path} version`); 6098 6099 // rename all child sources and child proxies 6100 for (const [prop, source] of sources) { 6101 tag(source, get_label(path, prop)); 6102 } 6103 updating = false; 6104 } 6105 6106 return new Proxy(/** @type {any} */ (value), { 6107 defineProperty(_, prop, descriptor) { 6108 if ( 6109 !('value' in descriptor) || 6110 descriptor.configurable === false || 6111 descriptor.enumerable === false || 6112 descriptor.writable === false 6113 ) { 6114 // we disallow non-basic descriptors, because unless they are applied to the 6115 // target object â which we avoid, so that state can be forked â we will run 6116 // afoul of the various invariants 6117 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor#invariants 6118 state_descriptors_fixed(); 6119 } 6120 var s = sources.get(prop); 6121 if (s === undefined) { 6122 s = with_parent(() => { 6123 var s = state(descriptor.value); 6124 sources.set(prop, s); 6125 if (DEV && typeof prop === 'string') { 6126 tag(s, get_label(path, prop)); 6127 } 6128 return s; 6129 }); 6130 } else { 6131 set(s, descriptor.value, true); 6132 } 6133 6134 return true; 6135 }, 6136 6137 deleteProperty(target, prop) { 6138 var s = sources.get(prop); 6139 6140 if (s === undefined) { 6141 if (prop in target) { 6142 const s = with_parent(() => state(UNINITIALIZED)); 6143 sources.set(prop, s); 6144 increment(version); 6145 6146 if (DEV) { 6147 tag(s, get_label(path, prop)); 6148 } 6149 } 6150 } else { 6151 set(s, UNINITIALIZED); 6152 increment(version); 6153 } 6154 6155 return true; 6156 }, 6157 6158 get(target, prop, receiver) { 6159 if (prop === STATE_SYMBOL) { 6160 return value; 6161 } 6162 6163 if (DEV && prop === PROXY_PATH_SYMBOL) { 6164 return update_path; 6165 } 6166 6167 var s = sources.get(prop); 6168 var exists = prop in target; 6169 6170 // create a source, but only if it's an own property and not a prototype property 6171 if (s === undefined && (!exists || get_descriptor(target, prop)?.writable)) { 6172 s = with_parent(() => { 6173 var p = proxy(exists ? target[prop] : UNINITIALIZED); 6174 var s = state(p); 6175 6176 if (DEV) { 6177 tag(s, get_label(path, prop)); 6178 } 6179 6180 return s; 6181 }); 6182 6183 sources.set(prop, s); 6184 } 6185 6186 if (s !== undefined) { 6187 var v = get(s); 6188 return v === UNINITIALIZED ? undefined : v; 6189 } 6190 6191 return Reflect.get(target, prop, receiver); 6192 }, 6193 6194 getOwnPropertyDescriptor(target, prop) { 6195 var descriptor = Reflect.getOwnPropertyDescriptor(target, prop); 6196 6197 if (descriptor && 'value' in descriptor) { 6198 var s = sources.get(prop); 6199 if (s) descriptor.value = get(s); 6200 } else if (descriptor === undefined) { 6201 var source = sources.get(prop); 6202 var value = source?.v; 6203 6204 if (source !== undefined && value !== UNINITIALIZED) { 6205 return { 6206 enumerable: true, 6207 configurable: true, 6208 value, 6209 writable: true 6210 }; 6211 } 6212 } 6213 6214 return descriptor; 6215 }, 6216 6217 has(target, prop) { 6218 if (prop === STATE_SYMBOL) { 6219 return true; 6220 } 6221 6222 var s = sources.get(prop); 6223 var has = (s !== undefined && s.v !== UNINITIALIZED) || Reflect.has(target, prop); 6224 6225 if ( 6226 s !== undefined || 6227 (active_effect !== null && (!has || get_descriptor(target, prop)?.writable)) 6228 ) { 6229 if (s === undefined) { 6230 s = with_parent(() => { 6231 var p = has ? proxy(target[prop]) : UNINITIALIZED; 6232 var s = state(p); 6233 6234 if (DEV) { 6235 tag(s, get_label(path, prop)); 6236 } 6237 6238 return s; 6239 }); 6240 6241 sources.set(prop, s); 6242 } 6243 6244 var value = get(s); 6245 if (value === UNINITIALIZED) { 6246 return false;
6247 } 6248 } 6249 6250 return has; 6251 }, 6252 6253 set(target, prop, value, receiver) { 6254 var s = sources.get(prop); 6255 var has = prop in target; 6256 6257 // variable.length = value -> clear all signals with index >= value 6258 if (is_proxied_array && prop === 'length') { 6259 for (var i = value; i < /** @type {Source<number>} */ (s).v; i += 1) { 6260 var other_s = sources.get(i + ''); 6261 if (other_s !== undefined) { 6262 set(other_s, UNINITIALIZED); 6263 } else if (i in target) { 6264 // If the item exists in the original, we need to create an uninitialized source, 6265 // else a later read of the property would result in a source being created with 6266 // the value of the original item at that index. 6267 other_s = with_parent(() => state(UNINITIALIZED)); 6268 sources.set(i + '', other_s); 6269 6270 if (DEV) { 6271 tag(other_s, get_label(path, i)); 6272 } 6273 } 6274 } 6275 } 6276 6277 // If we haven't yet created a source for this property, we need to ensure 6278 // we do so otherwise if we read it later, then the write won't be tracked and 6279 // the heuristics of effects will be different vs if we had read the proxied 6280 // object property before writing to that property. 6281 if (s === undefined) { 6282 if (!has || get_descriptor(target, prop)?.writable) { 6283 s = with_parent(() => state(undefined)); 6284 6285 if (DEV) { 6286 tag(s, get_label(path, prop)); 6287 } 6288 set(s, proxy(value)); 6289 6290 sources.set(prop, s); 6291 } 6292 } else { 6293 has = s.v !== UNINITIALIZED; 6294 6295 var p = with_parent(() => proxy(value)); 6296 set(s, p); 6297 } 6298 6299 var descriptor = Reflect.getOwnPropertyDescriptor(target, prop); 6300 6301 // Set the new value before updating any signals so that any listeners get the new value 6302 if (descriptor?.set) { 6303 descriptor.set.call(receiver, value); 6304 } 6305 6306 if (!has) { 6307 // If we have mutated an array directly, we might need to 6308 // signal that length has also changed. Do it before updating metadata 6309 // to ensure that iterating over the array as a result of a metadata update 6310 // will not cause the length to be out of sync. 6311 if (is_proxied_array && typeof prop === 'string') { 6312 var ls = /** @type {Source<number>} */ (sources.get('length')); 6313 var n = Number(prop); 6314 6315 if (Number.isInteger(n) && n >= ls.v) { 6316 set(ls, n + 1); 6317 } 6318 } 6319 6320 increment(version); 6321 } 6322 6323 return true; 6324 }, 6325 6326 ownKeys(target) { 6327 get(version); 6328 6329 var own_keys = Reflect.ownKeys(target).filter((key) => { 6330 var source = sources.get(key); 6331 return source === undefined || source.v !== UNINITIALIZED; 6332 }); 6333 6334 for (var [key, source] of sources) { 6335 if (source.v !== UNINITIALIZED && !(key in target)) { 6336 own_keys.push(key); 6337 } 6338 } 6339 6340 return own_keys; 6341 }, 6342 6343 setPrototypeOf() { 6344 state_prototype_fixed(); 6345 } 6346 }); 6347} 6348 6349/** 6350 * @param {string} path 6351 * @param {string | symbol} prop 6352 */ 6353function get_label(path, prop) { 6354 if (typeof prop === 'symbol') return `${path}[Symbol(${prop.description ?? ''})]`; 6355 if (regex_is_valid_identifier.test(prop)) return `${path}.${prop}`; 6356 return /^\d+$/.test(prop) ? `${path}[${prop}]` : `${path}['${prop}']`; 6357} 6358 6359/** 6360 * @param {any} value 6361 */ 6362function get_proxied_value(value) { 6363 try { 6364 if (value !== null && typeof value === 'object' && STATE_SYMBOL in value) { 6365 return value[STATE_SYMBOL]; 6366 } 6367 } catch { 6368 // the above if check can throw an error if the value in question 6369 // is the contentWindow of an iframe on another domain, in which 6370 // case we want to just return the value (because it's definitely 6371 // not a proxied value) so we don't break any JavaScript interacting 6372 // with that iframe (such as various payment companies client side 6373 // JavaScript libraries interacting with their iframes on the same 6374 // domain) 6375 } 6376 6377 return value; 6378} 6379 6380/** 6381 * @param {any} a 6382 * @param {any} b 6383 */ 6384function is(a, b) { 6385 return Object.is(get_proxied_value(a), get_proxied_value(b)); 6386} 6387 6388const ARRAY_MUTATING_METHODS = new Set([ 6389 'copyWithin', 6390 'fill', 6391 'pop', 6392 'push', 6393 'reverse', 6394 'shift', 6395 'sort', 6396 'splice', 6397 'unshift' 6398]); 6399 6400/** 6401 * Wrap array mutating methods so $inspect is triggered only once and 6402 * to prevent logging an array in intermediate state (e.g. with an empty slot) 6403 * @param {any[]} array 6404 */ 6405function inspectable_array(array) { 6406 return new Proxy(array, { 6407 get(target, prop, receiver) { 6408 var value = Reflect.get(target, prop, receiver); 6409 if (!ARRAY_MUTATING_METHODS.has(/** @type {string} */ (prop))) { 6410 return value; 6411 } 6412 6413 /** 6414 * @this {any[]} 6415 * @param {any[]} args 6416 */ 6417 return function (...args) { 6418 set_eager_effects_deferred();
6419 var result = value.apply(this, args); 6420 flush_eager_effects(); 6421 return result; 6422 }; 6423 } 6424 }); 6425} 6426 6427function init_array_prototype_warnings() { 6428 const array_prototype = Array.prototype; 6429 // The REPL ends up here over and over, and this prevents it from adding more and more patches 6430 // of the same kind to the prototype, which would slow down everything over time. 6431 // @ts-expect-error 6432 const cleanup = Array.__svelte_cleanup; 6433 if (cleanup) { 6434 cleanup(); 6435 } 6436 6437 const { indexOf, lastIndexOf, includes } = array_prototype; 6438 6439 array_prototype.indexOf = function (item, from_index) { 6440 const index = indexOf.call(this, item, from_index); 6441 6442 if (index === -1) { 6443 for (let i = from_index ?? 0; i < this.length; i += 1) { 6444 if (get_proxied_value(this[i]) === item) { 6445 state_proxy_equality_mismatch('array.indexOf(...)'); 6446 break; 6447 } 6448 } 6449 } 6450 6451 return index; 6452 }; 6453 6454 array_prototype.lastIndexOf = function (item, from_index) { 6455 // we need to specify this.length - 1 because it's probably using something like 6456 // `arguments` inside so passing undefined is different from not passing anything 6457 const index = lastIndexOf.call(this, item, from_index ?? this.length - 1); 6458 6459 if (index === -1) { 6460 for (let i = 0; i <= (from_index ?? this.length - 1); i += 1) { 6461 if (get_proxied_value(this[i]) === item) { 6462 state_proxy_equality_mismatch('array.lastIndexOf(...)'); 6463 break; 6464 } 6465 } 6466 } 6467 6468 return index; 6469 }; 6470 6471 array_prototype.includes = function (item, from_index) { 6472 const has = includes.call(this, item, from_index); 6473 6474 if (!has) { 6475 for (let i = 0; i < this.length; i += 1) { 6476 if (get_proxied_value(this[i]) === item) { 6477 state_proxy_equality_mismatch('array.includes(...)'); 6478 break; 6479 } 6480 } 6481 } 6482 6483 return has; 6484 }; 6485 6486 // @ts-expect-error 6487 Array.__svelte_cleanup = () => { 6488 array_prototype.indexOf = indexOf; 6489 array_prototype.lastIndexOf = lastIndexOf; 6490 array_prototype.includes = includes; 6491 }; 6492} 6493 6494/** @import { Effect, TemplateNode } from '#client' */ 6495 6496// export these for reference in the compiled code, making global name deduplication unnecessary 6497/** @type {Window} */ 6498var $window; 6499 6500/** @type {Document} */ 6501var $document; 6502 6503/** @type {boolean} */ 6504var is_firefox; 6505 6506/** @type {() => Node | null} */ 6507var first_child_getter; 6508/** @type {() => Node | null} */ 6509var next_sibling_getter; 6510 6511/** 6512 * Initialize these lazily to avoid issues when using the runtime in a server context 6513 * where these globals are not available while avoiding a separate server entry point 6514 */ 6515function init_operations() { 6516 if ($window !== undefined) { 6517 return; 6518 } 6519 6520 $window = window; 6521 $document = document; 6522 is_firefox = /Firefox/.test(navigator.userAgent); 6523 6524 var element_prototype = Element.prototype; 6525 var node_prototype = Node.prototype; 6526 var text_prototype = Text.prototype; 6527 6528 // @ts-ignore 6529 first_child_getter = get_descriptor(node_prototype, 'firstChild').get; 6530 // @ts-ignore 6531 next_sibling_getter = get_descriptor(node_prototype, 'nextSibling').get; 6532 6533 if (is_extensible(element_prototype)) { 6534 // the following assignments improve perf of lookups on DOM nodes 6535 // @ts-expect-error 6536 element_prototype.__click = undefined; 6537 // @ts-expect-error 6538 element_prototype.__className = undefined; 6539 // @ts-expect-error 6540 element_prototype.__attributes = null; 6541 // @ts-expect-error 6542 element_prototype.__style = undefined; 6543 // @ts-expect-error 6544 element_prototype.__e = undefined; 6545 } 6546 6547 if (is_extensible(text_prototype)) { 6548 // @ts-expect-error 6549 text_prototype.__t = undefined; 6550 } 6551 6552 if (DEV) { 6553 // @ts-expect-error 6554 element_prototype.__svelte_meta = null; 6555 6556 init_array_prototype_warnings(); 6557 } 6558} 6559 6560/** 6561 * @param {string} value 6562 * @returns {Text} 6563 */ 6564function create_text(value = '') { 6565 return document.createTextNode(value); 6566} 6567 6568/** 6569 * @template {Node} N 6570 * @param {N} node 6571 */ 6572/*@__NO_SIDE_EFFECTS__*/ 6573function get_first_child(node) { 6574 return /** @type {TemplateNode | null} */ (first_child_getter.call(node)); 6575} 6576 6577/** 6578 * @template {Node} N 6579 * @param {N} node 6580 */ 6581/*@__NO_SIDE_EFFECTS__*/ 6582function get_next_sibling(node) { 6583 return /** @type {TemplateNode | null} */ (next_sibling_getter.call(node)); 6584} 6585 6586/** 6587 * Don't mark this as side-effect-free, hydration needs to walk all nodes 6588 * @template {Node} N 6589 * @param {N} node 6590 * @param {boolean} is_text 6591 * @returns {TemplateNode | null} 6592 */ 6593function child(node, is_text) { 6594 if (!hydrating) { 6595 return get_first_child(node); 6596 } 6597 6598 var child = get_first_child(hydrate_node); 6599 6600 // Child can be null if we have an element with a single child, like `<p>{text}</p>`, where `text` is empty 6601 if (child === null) { 6602 child = hydrate_node.appendChild(create_text()); 6603 } else if (is_text && child.nodeType !== TEXT_NODE) { 6604 var text = create_text(); 6605 child?.before(text); 6606 set_hydrate_node(text); 6607 return text; 6608 } 6609 6610 set_hydrate_node(child); 6611 return child; 6612} 6613 6614/** 6615 * Don't mark this as side-effect-free, hydration needs to walk all nodes 6616 * @param {TemplateNode} node 6617 * @param {boolean} [is_text] 6618 * @returns {TemplateNode | null} 6619 */ 6620function first_child(node, is_text = false) { 6621 if (!hydrating) { 6622 var first = get_first_child(node); 6623 6624 // TODO prevent user comments with the empty string when preserveComments is true 6625 if (first instanceof Comment && first.data === '') return get_next_sibling(first); 6626 6627 return first; 6628 } 6629 6630 // if an {expression} is empty during SSR, there might be no 6631 // text node to hydrate â we must therefore create one
6632 if (is_text && hydrate_node?.nodeType !== TEXT_NODE) { 6633 var text = create_text(); 6634 6635 hydrate_node?.before(text); 6636 set_hydrate_node(text); 6637 return text; 6638 } 6639 6640 return hydrate_node; 6641} 6642 6643/** 6644 * Don't mark this as side-effect-free, hydration needs to walk all nodes 6645 * @param {TemplateNode} node 6646 * @param {number} count 6647 * @param {boolean} is_text 6648 * @returns {TemplateNode | null} 6649 */ 6650function sibling(node, count = 1, is_text = false) { 6651 let next_sibling = hydrating ? hydrate_node : node; 6652 var last_sibling; 6653 6654 while (count--) { 6655 last_sibling = next_sibling; 6656 next_sibling = /** @type {TemplateNode} */ (get_next_sibling(next_sibling)); 6657 } 6658 6659 if (!hydrating) { 6660 return next_sibling; 6661 } 6662 6663 // if a sibling {expression} is empty during SSR, there might be no 6664 // text node to hydrate â we must therefore create one 6665 if (is_text && next_sibling?.nodeType !== TEXT_NODE) { 6666 var text = create_text(); 6667 // If the next sibling is `null` and we're handling text then it's because 6668 // the SSR content was empty for the text, so we need to generate a new text 6669 // node and insert it after the last sibling 6670 if (next_sibling === null) { 6671 last_sibling?.after(text); 6672 } else { 6673 next_sibling.before(text); 6674 } 6675 set_hydrate_node(text); 6676 return text; 6677 } 6678 6679 set_hydrate_node(next_sibling); 6680 return next_sibling; 6681} 6682 6683/** 6684 * @template {Node} N 6685 * @param {N} node 6686 * @returns {void} 6687 */ 6688function clear_text_content(node) { 6689 node.textContent = ''; 6690} 6691 6692/** 6693 * Returns `true` if we're updating the current block, for example `condition` in 6694 * an `{#if condition}` block just changed. In this case, the branch should be 6695 * appended (or removed) at the same time as other updates within the 6696 * current `<svelte:boundary>` 6697 */ 6698function should_defer_append() { 6699 if (!async_mode_flag) return false; 6700 if (eager_block_effects !== null) return false; 6701 6702 var flags = /** @type {Effect} */ (active_effect).f; 6703 return (flags & EFFECT_RAN) !== 0; 6704} 6705 6706/** 6707 * @param {HTMLElement} dom 6708 * @param {boolean} value 6709 * @returns {void} 6710 */ 6711function autofocus(dom, value) { 6712 if (value) { 6713 const body = document.body; 6714 dom.autofocus = true; 6715 6716 queue_micro_task(() => { 6717 if (document.activeElement === body) { 6718 dom.focus(); 6719 } 6720 }); 6721 } 6722} 6723 6724/** 6725 * The child of a textarea actually corresponds to the defaultValue property, so we need 6726 * to remove it upon hydration to avoid a bug when someone resets the form value. 6727 * @param {HTMLTextAreaElement} dom 6728 * @returns {void} 6729 */ 6730function remove_textarea_child(dom) { 6731 if (hydrating && get_first_child(dom) !== null) { 6732 clear_text_content(dom); 6733 } 6734} 6735 6736let listening_to_form_reset = false; 6737 6738function add_form_reset_listener() { 6739 if (!listening_to_form_reset) { 6740 listening_to_form_reset = true; 6741 document.addEventListener( 6742 'reset', 6743 (evt) => { 6744 // Needs to happen one tick later or else the dom properties of the form 6745 // elements have not updated to their reset values yet 6746 Promise.resolve().then(() => { 6747 if (!evt.defaultPrevented) { 6748 for (const e of /**@type {HTMLFormElement} */ (evt.target).elements) { 6749 // @ts-expect-error 6750 e.__on_r?.(); 6751 } 6752 } 6753 }); 6754 }, 6755 // In the capture phase to guarantee we get noticed of it (no possibility of stopPropagation) 6756 { capture: true } 6757 ); 6758 } 6759} 6760 6761/** 6762 * Fires the handler once immediately (unless corresponding arg is set to `false`), 6763 * then listens to the given events until the render effect context is destroyed 6764 * @param {EventTarget} target 6765 * @param {Array<string>} events 6766 * @param {(event?: Event) => void} handler 6767 * @param {any} call_handler_immediately 6768 */ 6769function listen(target, events, handler, call_handler_immediately = true) { 6770 if (call_handler_immediately) { 6771 handler(); 6772 } 6773 6774 for (var name of events) { 6775 target.addEventListener(name, handler); 6776 } 6777 6778 teardown(() => { 6779 for (var name of events) { 6780 target.removeEventListener(name, handler); 6781 } 6782 }); 6783} 6784 6785/** 6786 * @template T 6787 * @param {() => T} fn 6788 */ 6789function without_reactive_context(fn) { 6790 var previous_reaction = active_reaction; 6791 var previous_effect = active_effect; 6792 set_active_reaction(null); 6793 set_active_effect(null); 6794 try { 6795 return fn(); 6796 } finally { 6797 set_active_reaction(previous_reaction); 6798 set_active_effect(previous_effect); 6799 } 6800} 6801 6802/** 6803 * Listen to the given event, and then instantiate a global form reset listener if not already done, 6804 * to notify all bindings when the form is reset 6805 * @param {HTMLElement} element 6806 * @param {string} event 6807 * @param {(is_reset?: true) => void} handler 6808 * @param {(is_reset?: true) => void} [on_reset] 6809 */ 6810function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) { 6811 element.addEventListener(event, () => without_reactive_context(handler)); 6812 // @ts-expect-error 6813 const prev = element.__on_r; 6814 if (prev) { 6815 // special case for checkbox that can have multiple binds (group & checked) 6816 // @ts-expect-error 6817 element.__on_r = () => { 6818 prev(); 6819 on_reset(true); 6820 }; 6821 } else { 6822 // @ts-expect-error 6823 element.__on_r = () => on_reset(true); 6824 } 6825 6826 add_form_reset_listener(); 6827} 6828 6829/** @import { ComponentContext, ComponentContextLegacy, Derived, Effect, TemplateNode, TransitionManager } from '#client' */ 6830 6831/** 6832 * @param {'$effect' | '$effect.pre' | '$inspect'} rune 6833 */ 6834function validate_effect(rune) { 6835 if (active_effect === null) { 6836 if (active_reaction === null) { 6837 effect_orphan(rune); 6838 } 6839 6840 effect_in_unowned_derived(); 6841 } 6842
6843 if (is_destroying_effect) { 6844 effect_in_teardown(rune); 6845 } 6846} 6847 6848/** 6849 * @param {Effect} effect 6850 * @param {Effect} parent_effect 6851 */ 6852function push_effect(effect, parent_effect) { 6853 var parent_last = parent_effect.last; 6854 if (parent_last === null) { 6855 parent_effect.last = parent_effect.first = effect; 6856 } else { 6857 parent_last.next = effect; 6858 effect.prev = parent_last; 6859 parent_effect.last = effect; 6860 } 6861} 6862 6863/** 6864 * @param {number} type 6865 * @param {null | (() => void | (() => void))} fn 6866 * @param {boolean} sync 6867 * @returns {Effect} 6868 */ 6869function create_effect(type, fn, sync) { 6870 var parent = active_effect; 6871 6872 if (DEV) { 6873 // Ensure the parent is never an inspect effect 6874 while (parent !== null && (parent.f & EAGER_EFFECT) !== 0) { 6875 parent = parent.parent; 6876 } 6877 } 6878 6879 if (parent !== null && (parent.f & INERT) !== 0) { 6880 type |= INERT; 6881 } 6882 6883 /** @type {Effect} */ 6884 var effect = { 6885 ctx: component_context, 6886 deps: null, 6887 nodes: null, 6888 f: type | DIRTY | CONNECTED, 6889 first: null, 6890 fn, 6891 last: null, 6892 next: null, 6893 parent, 6894 b: parent && parent.b, 6895 prev: null, 6896 teardown: null, 6897 wv: 0, 6898 ac: null 6899 }; 6900 6901 if (DEV) { 6902 effect.component_function = dev_current_component_function; 6903 } 6904 6905 if (sync) { 6906 try { 6907 update_effect(effect); 6908 effect.f |= EFFECT_RAN; 6909 } catch (e) { 6910 destroy_effect(effect); 6911 throw e; 6912 } 6913 } else if (fn !== null) { 6914 schedule_effect(effect); 6915 } 6916 6917 /** @type {Effect | null} */ 6918 var e = effect; 6919 6920 // if an effect has already ran and doesn't need to be kept in the tree 6921 // (because it won't re-run, has no DOM, and has no teardown etc) 6922 // then we skip it and go to its child (if any) 6923 if ( 6924 sync && 6925 e.deps === null && 6926 e.teardown === null && 6927 e.nodes === null && 6928 e.first === e.last && // either `null`, or a singular child 6929 (e.f & EFFECT_PRESERVED) === 0 6930 ) { 6931 e = e.first; 6932 if ((type & BLOCK_EFFECT) !== 0 && (type & EFFECT_TRANSPARENT) !== 0 && e !== null) { 6933 e.f |= EFFECT_TRANSPARENT; 6934 } 6935 } 6936 6937 if (e !== null) { 6938 e.parent = parent; 6939 6940 if (parent !== null) { 6941 push_effect(e, parent); 6942 } 6943 6944 // if we're in a derived, add the effect there too 6945 if ( 6946 active_reaction !== null && 6947 (active_reaction.f & DERIVED) !== 0 && 6948 (type & ROOT_EFFECT) === 0 6949 ) { 6950 var derived = /** @type {Derived} */ (active_reaction); 6951 (derived.effects ??= []).push(e); 6952 } 6953 } 6954 6955 return effect; 6956} 6957 6958/** 6959 * Internal representation of `$effect.tracking()` 6960 * @returns {boolean} 6961 */ 6962function effect_tracking() { 6963 return active_reaction !== null && !untracking; 6964} 6965 6966/** 6967 * @param {() => void} fn 6968 */ 6969function teardown(fn) { 6970 const effect = create_effect(RENDER_EFFECT, null, false); 6971 set_signal_status(effect, CLEAN); 6972 effect.teardown = fn; 6973 return effect; 6974} 6975 6976/** 6977 * Internal representation of `$effect(...)` 6978 * @param {() => void | (() => void)} fn 6979 */ 6980function user_effect(fn) { 6981 validate_effect('$effect'); 6982 6983 if (DEV) { 6984 define_property(fn, 'name', { 6985 value: '$effect' 6986 }); 6987 } 6988 6989 // Non-nested `$effect(...)` in a component should be deferred 6990 // until the component is mounted 6991 var flags = /** @type {Effect} */ (active_effect).f; 6992 var defer = !active_reaction && (flags & BRANCH_EFFECT) !== 0 && (flags & EFFECT_RAN) === 0; 6993 6994 if (defer) { 6995 // Top-level `$effect(...)` in an unmounted component â defer until mount 6996 var context = /** @type {ComponentContext} */ (component_context); 6997 (context.e ??= []).push(fn); 6998 } else { 6999 // Everything else â create immediately 7000 return create_user_effect(fn); 7001 } 7002} 7003 7004/** 7005 * @param {() => void | (() => void)} fn 7006 */ 7007function create_user_effect(fn) { 7008 return create_effect(EFFECT | USER_EFFECT, fn, false); 7009} 7010 7011/** 7012 * Internal representation of `$effect.pre(...)` 7013 * @param {() => void | (() => void)} fn 7014 * @returns {Effect} 7015 */ 7016function user_pre_effect(fn) { 7017 validate_effect('$effect.pre'); 7018 if (DEV) { 7019 define_property(fn, 'name', { 7020 value: '$effect.pre' 7021 }); 7022 } 7023 return create_effect(RENDER_EFFECT | USER_EFFECT, fn, true); 7024} 7025 7026/** 7027 * An effect root whose children can transition out 7028 * @param {() => void} fn 7029 * @returns {(options?: { outro?: boolean }) => Promise<void>} 7030 */ 7031function component_root(fn) { 7032 Batch.ensure(); 7033 const effect = create_effect(ROOT_EFFECT | EFFECT_PRESERVED, fn, true); 7034 7035 return (options = {}) => { 7036 return new Promise((fulfil) => { 7037 if (options.outro) { 7038 pause_effect(effect, () => { 7039 destroy_effect(effect); 7040 fulfil(undefined); 7041 }); 7042 } else { 7043 destroy_effect(effect); 7044 fulfil(undefined); 7045 } 7046 }); 7047 }; 7048} 7049 7050/** 7051 * @param {() => void | (() => void)} fn 7052 * @returns {Effect} 7053 */ 7054function effect(fn) { 7055 return create_effect(EFFECT, fn, false); 7056} 7057 7058/** 7059 * Internal representation of `$: ..` 7060 * @param {() => any} deps 7061 * @param {() => void | (() => void)} fn 7062 */ 7063function legacy_pre_effect(deps, fn) { 7064 var context = /** @type {ComponentContextLegacy} */ (component_context); 7065 7066 /** @type {{ effect: null | Effect, ran: boolean, deps: () => any }} */
7067 var token = { effect: null, ran: false, deps }; 7068 7069 context.l.$.push(token); 7070 7071 token.effect = render_effect(() => { 7072 deps(); 7073 7074 // If this legacy pre effect has already run before the end of the reset, then 7075 // bail out to emulate the same behavior. 7076 if (token.ran) return; 7077 7078 token.ran = true; 7079 untrack(fn); 7080 }); 7081} 7082 7083function legacy_pre_effect_reset() { 7084 var context = /** @type {ComponentContextLegacy} */ (component_context); 7085 7086 render_effect(() => { 7087 // Run dirty `$:` statements 7088 for (var token of context.l.$) { 7089 token.deps(); 7090 7091 var effect = token.effect; 7092 7093 // If the effect is CLEAN, then make it MAYBE_DIRTY. This ensures we traverse through 7094 // the effects dependencies and correctly ensure each dependency is up-to-date. 7095 if ((effect.f & CLEAN) !== 0 && effect.deps !== null) { 7096 set_signal_status(effect, MAYBE_DIRTY); 7097 } 7098 7099 if (is_dirty(effect)) { 7100 update_effect(effect); 7101 } 7102 7103 token.ran = false; 7104 } 7105 }); 7106} 7107 7108/** 7109 * @param {() => void | (() => void)} fn 7110 * @returns {Effect} 7111 */ 7112function async_effect(fn) { 7113 return create_effect(ASYNC | EFFECT_PRESERVED, fn, true); 7114} 7115 7116/** 7117 * @param {() => void | (() => void)} fn 7118 * @returns {Effect} 7119 */ 7120function render_effect(fn, flags = 0) { 7121 return create_effect(RENDER_EFFECT | flags, fn, true); 7122} 7123 7124/** 7125 * @param {(...expressions: any) => void | (() => void)} fn 7126 * @param {Array<() => any>} sync 7127 * @param {Array<() => Promise<any>>} async 7128 * @param {Array<Promise<void>>} blockers 7129 */ 7130function template_effect(fn, sync = [], async = [], blockers = []) { 7131 flatten(blockers, sync, async, (values) => { 7132 create_effect(RENDER_EFFECT, () => fn(...values.map(get)), true); 7133 }); 7134} 7135 7136/** 7137 * Like `template_effect`, but with an effect which is deferred until the batch commits 7138 * @param {(...expressions: any) => void | (() => void)} fn 7139 * @param {Array<() => any>} sync 7140 * @param {Array<() => Promise<any>>} async 7141 * @param {Array<Promise<void>>} blockers 7142 */ 7143function deferred_template_effect(fn, sync = [], async = [], blockers = []) { 7144 var batch = /** @type {Batch} */ (current_batch); 7145 var is_async = async.length > 0 || blockers.length > 0; 7146 7147 if (is_async) batch.increment(true); 7148 7149 flatten(blockers, sync, async, (values) => { 7150 create_effect(EFFECT, () => fn(...values.map(get)), false); 7151 if (is_async) batch.decrement(true); 7152 }); 7153} 7154 7155/** 7156 * @param {(() => void)} fn 7157 * @param {number} flags 7158 */ 7159function block(fn, flags = 0) { 7160 var effect = create_effect(BLOCK_EFFECT | flags, fn, true); 7161 if (DEV) { 7162 effect.dev_stack = dev_stack; 7163 } 7164 return effect; 7165} 7166 7167/** 7168 * @param {(() => void)} fn 7169 * @param {number} flags 7170 */ 7171function managed(fn, flags = 0) { 7172 var effect = create_effect(MANAGED_EFFECT | flags, fn, true); 7173 if (DEV) { 7174 effect.dev_stack = dev_stack; 7175 } 7176 return effect; 7177} 7178 7179/** 7180 * @param {(() => void)} fn 7181 */ 7182function branch(fn) { 7183 return create_effect(BRANCH_EFFECT | EFFECT_PRESERVED, fn, true); 7184} 7185 7186/** 7187 * @param {Effect} effect 7188 */ 7189function execute_effect_teardown(effect) { 7190 var teardown = effect.teardown; 7191 if (teardown !== null) { 7192 const previously_destroying_effect = is_destroying_effect; 7193 const previous_reaction = active_reaction; 7194 set_is_destroying_effect(true); 7195 set_active_reaction(null); 7196 try { 7197 teardown.call(null); 7198 } finally { 7199 set_is_destroying_effect(previously_destroying_effect); 7200 set_active_reaction(previous_reaction); 7201 } 7202 } 7203} 7204 7205/** 7206 * @param {Effect} signal 7207 * @param {boolean} remove_dom 7208 * @returns {void} 7209 */ 7210function destroy_effect_children(signal, remove_dom = false) { 7211 var effect = signal.first; 7212 signal.first = signal.last = null; 7213 7214 while (effect !== null) { 7215 const controller = effect.ac; 7216 7217 if (controller !== null) { 7218 without_reactive_context(() => { 7219 controller.abort(STALE_REACTION); 7220 }); 7221 } 7222 7223 var next = effect.next; 7224 7225 if ((effect.f & ROOT_EFFECT) !== 0) { 7226 // this is now an independent root 7227 effect.parent = null; 7228 } else { 7229 destroy_effect(effect, remove_dom); 7230 } 7231 7232 effect = next; 7233 } 7234} 7235 7236/** 7237 * @param {Effect} signal 7238 * @returns {void} 7239 */ 7240function destroy_block_effect_children(signal) { 7241 var effect = signal.first; 7242 7243 while (effect !== null) { 7244 var next = effect.next; 7245 if ((effect.f & BRANCH_EFFECT) === 0) { 7246 destroy_effect(effect); 7247 } 7248 effect = next; 7249 } 7250} 7251 7252/** 7253 * @param {Effect} effect 7254 * @param {boolean} [remove_dom] 7255 * @returns {void} 7256 */ 7257function destroy_effect(effect, remove_dom = true) { 7258 var removed = false;
7259 7260 if ( 7261 (remove_dom || (effect.f & HEAD_EFFECT) !== 0) && 7262 effect.nodes !== null && 7263 effect.nodes.end !== null 7264 ) { 7265 remove_effect_dom(effect.nodes.start, /** @type {TemplateNode} */ (effect.nodes.end)); 7266 removed = true; 7267 } 7268 7269 destroy_effect_children(effect, remove_dom && !removed); 7270 remove_reactions(effect, 0); 7271 set_signal_status(effect, DESTROYED); 7272 7273 var transitions = effect.nodes && effect.nodes.t; 7274 7275 if (transitions !== null) { 7276 for (const transition of transitions) { 7277 transition.stop(); 7278 } 7279 } 7280 7281 execute_effect_teardown(effect); 7282 7283 var parent = effect.parent; 7284 7285 // If the parent doesn't have any children, then skip this work altogether 7286 if (parent !== null && parent.first !== null) { 7287 unlink_effect(effect); 7288 } 7289 7290 if (DEV) { 7291 effect.component_function = null; 7292 } 7293 7294 // `first` and `child` are nulled out in destroy_effect_children 7295 // we don't null out `parent` so that error propagation can work correctly 7296 effect.next = 7297 effect.prev = 7298 effect.teardown = 7299 effect.ctx = 7300 effect.deps = 7301 effect.fn = 7302 effect.nodes = 7303 effect.ac = 7304 null; 7305} 7306 7307/** 7308 * 7309 * @param {TemplateNode | null} node 7310 * @param {TemplateNode} end 7311 */ 7312function remove_effect_dom(node, end) { 7313 while (node !== null) { 7314 /** @type {TemplateNode | null} */ 7315 var next = node === end ? null : get_next_sibling(node); 7316 7317 node.remove(); 7318 node = next; 7319 } 7320} 7321 7322/** 7323 * Detach an effect from the effect tree, freeing up memory and 7324 * reducing the amount of work that happens on subsequent traversals 7325 * @param {Effect} effect 7326 */ 7327function unlink_effect(effect) { 7328 var parent = effect.parent; 7329 var prev = effect.prev; 7330 var next = effect.next; 7331 7332 if (prev !== null) prev.next = next; 7333 if (next !== null) next.prev = prev; 7334 7335 if (parent !== null) { 7336 if (parent.first === effect) parent.first = next; 7337 if (parent.last === effect) parent.last = prev; 7338 } 7339} 7340 7341/** 7342 * When a block effect is removed, we don't immediately destroy it or yank it 7343 * out of the DOM, because it might have transitions. Instead, we 'pause' it. 7344 * It stays around (in memory, and in the DOM) until outro transitions have 7345 * completed, and if the state change is reversed then we _resume_ it. 7346 * A paused effect does not update, and the DOM subtree becomes inert. 7347 * @param {Effect} effect 7348 * @param {() => void} [callback] 7349 * @param {boolean} [destroy] 7350 */ 7351function pause_effect(effect, callback, destroy = true) { 7352 /** @type {TransitionManager[]} */ 7353 var transitions = []; 7354 7355 pause_children(effect, transitions, true); 7356 7357 var fn = () => { 7358 if (destroy) destroy_effect(effect); 7359 if (callback) callback(); 7360 }; 7361 7362 var remaining = transitions.length; 7363 if (remaining > 0) { 7364 var check = () => --remaining || fn(); 7365 for (var transition of transitions) { 7366 transition.out(check); 7367 } 7368 } else { 7369 fn(); 7370 } 7371} 7372 7373/** 7374 * @param {Effect} effect 7375 * @param {TransitionManager[]} transitions 7376 * @param {boolean} local 7377 */ 7378function pause_children(effect, transitions, local) { 7379 if ((effect.f & INERT) !== 0) return; 7380 effect.f ^= INERT; 7381 7382 var t = effect.nodes && effect.nodes.t; 7383 7384 if (t !== null) { 7385 for (const transition of t) { 7386 if (transition.is_global || local) { 7387 transitions.push(transition); 7388 } 7389 } 7390 } 7391 7392 var child = effect.first; 7393 7394 while (child !== null) { 7395 var sibling = child.next; 7396 var transparent = 7397 (child.f & EFFECT_TRANSPARENT) !== 0 || 7398 // If this is a branch effect without a block effect parent, 7399 // it means the parent block effect was pruned. In that case, 7400 // transparency information was transferred to the branch effect. 7401 ((child.f & BRANCH_EFFECT) !== 0 && (effect.f & BLOCK_EFFECT) !== 0); 7402 // TODO we don't need to call pause_children recursively with a linked list in place 7403 // it's slightly more involved though as we have to account for `transparent` changing 7404 // through the tree. 7405 pause_children(child, transitions, transparent ? local : false); 7406 child = sibling; 7407 } 7408} 7409 7410/** 7411 * The opposite of `pause_effect`. We call this if (for example) 7412 * `x` becomes falsy then truthy: `{#if x}...{/if}` 7413 * @param {Effect} effect 7414 */ 7415function resume_effect(effect) { 7416 resume_children(effect, true); 7417} 7418 7419/** 7420 * @param {Effect} effect 7421 * @param {boolean} local 7422 */ 7423function resume_children(effect, local) { 7424 if ((effect.f & INERT) === 0) return; 7425 effect.f ^= INERT; 7426 7427 // If a dependency of this effect changed while it was paused, 7428 // schedule the effect to update. we don't use `is_dirty` 7429 // here because we don't want to eagerly recompute a derived like 7430 // `{#if foo}{foo.bar()}{/if}` if `foo` is now `undefined 7431 if ((effect.f & CLEAN) === 0) { 7432 set_signal_status(effect, DIRTY); 7433 schedule_effect(effect); 7434 } 7435 7436 var child = effect.first; 7437 7438 while (child !== null) { 7439 var sibling = child.next; 7440 var transparent = (child.f & EFFECT_TRANSPARENT) !== 0 || (child.f & BRANCH_EFFECT) !== 0; 7441 // TODO we don't need to call resume_children recursively with a linked list in place 7442 // it's slightly more involved though as we have to account for `transparent` changing 7443 // through the tree. 7444 resume_children(child, transparent ? local : false); 7445 child = sibling; 7446 } 7447 7448 var t = effect.nodes && effect.nodes.t; 7449 7450 if (t !== null) { 7451 for (const transition of t) { 7452 if (transition.is_global || local) { 7453 transition.in(); 7454 } 7455 } 7456 } 7457} 7458 7459function aborted(effect = /** @type {Effect} */ (active_effect)) { 7460 return (effect.f & DESTROYED) !== 0; 7461} 7462 7463/** 7464 * @param {Effect} effect 7465 * @param {DocumentFragment} fragment 7466 */ 7467function move_effect(effect, fragment) { 7468 if (!effect.nodes) return; 7469 7470 /** @type {TemplateNode | null} */ 7471 var node = effect.nodes.start; 7472 var end = effect.nodes.end; 7473 7474 while (node !== null) { 7475 /** @type {TemplateNode | null} */ 7476 var next = node === end ? null : get_next_sibling(node); 7477 7478 fragment.append(node); 7479 node = next; 7480 } 7481} 7482 7483/** @import { Value } from '#client' */ 7484 7485/** 7486 * @type {Set<Value> | null} 7487 * @deprecated 7488 */ 7489let captured_signals = null; 7490 7491/** 7492 * Capture an array of all the signals that are read when `fn` is called 7493 * @template T 7494 * @param {() => T} fn 7495 */ 7496function capture_signals(fn) { 7497 var previous_captured_signals = captured_signals; 7498 7499 try { 7500 captured_signals = new Set(); 7501 7502 untrack(fn); 7503 7504 if (previous_captured_signals !== null) { 7505 for (var signal of captured_signals) { 7506 previous_captured_signals.add(signal); 7507 } 7508 } 7509 7510 return captured_signals; 7511 } finally { 7512 captured_signals = previous_captured_signals; 7513 } 7514} 7515 7516/** 7517 * Invokes a function and captures all signals that are read during the invocation, 7518 * then invalidates them. 7519 * @param {() => any} fn 7520 * @deprecated 7521 */
7522function invalidate_inner_signals(fn) { 7523 for (var signal of capture_signals(fn)) { 7524 internal_set(signal, signal.v); 7525 } 7526} 7527 7528/** @import { Derived, Effect, Reaction, Source, Value } from '#client' */ 7529 7530let is_updating_effect = false; 7531 7532/** @param {boolean} value */ 7533function set_is_updating_effect(value) { 7534 is_updating_effect = value; 7535} 7536 7537let is_destroying_effect = false; 7538 7539/** @param {boolean} value */ 7540function set_is_destroying_effect(value) { 7541 is_destroying_effect = value; 7542} 7543 7544/** @type {null | Reaction} */ 7545let active_reaction = null; 7546 7547let untracking = false; 7548 7549/** @param {null | Reaction} reaction */ 7550function set_active_reaction(reaction) { 7551 active_reaction = reaction; 7552} 7553 7554/** @type {null | Effect} */ 7555let active_effect = null; 7556 7557/** @param {null | Effect} effect */ 7558function set_active_effect(effect) { 7559 active_effect = effect; 7560} 7561 7562/** 7563 * When sources are created within a reaction, reading and writing 7564 * them within that reaction should not cause a re-run 7565 * @type {null | Source[]} 7566 */ 7567let current_sources = null; 7568 7569/** @param {Value} value */ 7570function push_reaction_value(value) { 7571 if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & DERIVED) !== 0)) { 7572 if (current_sources === null) { 7573 current_sources = [value]; 7574 } else { 7575 current_sources.push(value); 7576 } 7577 } 7578} 7579 7580/** 7581 * The dependencies of the reaction that is currently being executed. In many cases, 7582 * the dependencies are unchanged between runs, and so this will be `null` unless
7583 * and until a new dependency is accessed â we track this via `skipped_deps` 7584 * @type {null | Value[]} 7585 */ 7586let new_deps = null; 7587 7588let skipped_deps = 0; 7589 7590/** 7591 * Tracks writes that the effect it's executed in doesn't listen to yet, 7592 * so that the dependency can be added to the effect later on if it then reads it 7593 * @type {null | Source[]} 7594 */ 7595let untracked_writes = null; 7596 7597/** @param {null | Source[]} value */ 7598function set_untracked_writes(value) { 7599 untracked_writes = value; 7600} 7601 7602/** 7603 * @type {number} Used by sources and deriveds for handling updates. 7604 * Version starts from 1 so that unowned deriveds differentiate between a created effect and a run one for tracing 7605 **/ 7606let write_version = 1; 7607 7608/** @type {number} Used to version each read of a source of derived to avoid duplicating depedencies inside a reaction */ 7609let read_version = 0; 7610 7611let update_version = read_version; 7612 7613/** @param {number} value */ 7614function set_update_version(value) { 7615 update_version = value; 7616} 7617 7618function increment_write_version() { 7619 return ++write_version; 7620} 7621 7622/** 7623 * Determines whether a derived or effect is dirty. 7624 * If it is MAYBE_DIRTY, will set the status to CLEAN 7625 * @param {Reaction} reaction 7626 * @returns {boolean} 7627 */ 7628function is_dirty(reaction) { 7629 var flags = reaction.f; 7630 7631 if ((flags & DIRTY) !== 0) { 7632 return true; 7633 } 7634 7635 if (flags & DERIVED) { 7636 reaction.f &= ~WAS_MARKED; 7637 } 7638 7639 if ((flags & MAYBE_DIRTY) !== 0) { 7640 var dependencies = /** @type {Value[]} */ (reaction.deps); 7641 var length = dependencies.length; 7642 7643 for (var i = 0; i < length; i++) { 7644 var dependency = dependencies[i]; 7645 7646 if (is_dirty(/** @type {Derived} */ (dependency))) { 7647 update_derived(/** @type {Derived} */ (dependency)); 7648 } 7649 7650 if (dependency.wv > reaction.wv) { 7651 return true; 7652 } 7653 } 7654 7655 if ( 7656 (flags & CONNECTED) !== 0 && 7657 // During time traveling we don't want to reset the status so that 7658 // traversal of the graph in the other batches still happens 7659 batch_values === null 7660 ) { 7661 set_signal_status(reaction, CLEAN); 7662 } 7663 } 7664 7665 return false; 7666} 7667 7668/** 7669 * @param {Value} signal 7670 * @param {Effect} effect 7671 * @param {boolean} [root] 7672 */ 7673function schedule_possible_effect_self_invalidation(signal, effect, root = true) { 7674 var reactions = signal.reactions; 7675 if (reactions === null) return; 7676 7677 if (!async_mode_flag && current_sources?.includes(signal)) { 7678 return; 7679 } 7680 7681 for (var i = 0; i < reactions.length; i++) { 7682 var reaction = reactions[i]; 7683 7684 if ((reaction.f & DERIVED) !== 0) { 7685 schedule_possible_effect_self_invalidation(/** @type {Derived} */ (reaction), effect, false); 7686 } else if (effect === reaction) { 7687 if (root) { 7688 set_signal_status(reaction, DIRTY); 7689 } else if ((reaction.f & CLEAN) !== 0) { 7690 set_signal_status(reaction, MAYBE_DIRTY); 7691 } 7692 schedule_effect(/** @type {Effect} */ (reaction)); 7693 } 7694 } 7695} 7696 7697/** @param {Reaction} reaction */ 7698function update_reaction(reaction) { 7699 var previous_deps = new_deps; 7700 var previous_skipped_deps = skipped_deps; 7701 var previous_untracked_writes = untracked_writes; 7702 var previous_reaction = active_reaction; 7703 var previous_sources = current_sources; 7704 var previous_component_context = component_context; 7705 var previous_untracking = untracking; 7706 var previous_update_version = update_version; 7707 7708 var flags = reaction.f; 7709 7710 new_deps = /** @type {null | Value[]} */ (null); 7711 skipped_deps = 0; 7712 untracked_writes = null; 7713 active_reaction = (flags & (BRANCH_EFFECT | ROOT_EFFECT)) === 0 ? reaction : null; 7714 7715 current_sources = null; 7716 set_component_context(reaction.ctx); 7717 untracking = false; 7718 update_version = ++read_version; 7719 7720 if (reaction.ac !== null) { 7721 without_reactive_context(() => { 7722 /** @type {AbortController} */ (reaction.ac).abort(STALE_REACTION); 7723 }); 7724 7725 reaction.ac = null; 7726 } 7727 7728 try { 7729 reaction.f |= REACTION_IS_UPDATING; 7730 var fn = /** @type {Function} */ (reaction.fn); 7731 var result = fn(); 7732 var deps = reaction.deps; 7733 7734 if (new_deps !== null) { 7735 var i; 7736 7737 remove_reactions(reaction, skipped_deps); 7738 7739 if (deps !== null && skipped_deps > 0) { 7740 deps.length = skipped_deps + new_deps.length; 7741 for (i = 0; i < new_deps.length; i++) { 7742 deps[skipped_deps + i] = new_deps[i]; 7743 } 7744 } else { 7745 reaction.deps = deps = new_deps; 7746 } 7747 7748 if (effect_tracking() && (reaction.f & CONNECTED) !== 0) { 7749 for (i = skipped_deps; i < deps.length; i++) { 7750 (deps[i].reactions ??= []).push(reaction); 7751 } 7752 } 7753 } else if (deps !== null && skipped_deps < deps.length) { 7754 remove_reactions(reaction, skipped_deps); 7755 deps.length = skipped_deps; 7756 } 7757 7758 // If we're inside an effect and we have untracked writes, then we need to 7759 // ensure that if any of those untracked writes result in re-invalidation 7760 // of the current effect, then that happens accordingly 7761 if ( 7762 is_runes() && 7763 untracked_writes !== null && 7764 !untracking && 7765 deps !== null && 7766 (reaction.f & (DERIVED | MAYBE_DIRTY | DIRTY)) === 0 7767 ) { 7768 for (i = 0; i < /** @type {Source[]} */ (untracked_writes).length; i++) { 7769 schedule_possible_effect_self_invalidation( 7770 untracked_writes[i], 7771 /** @type {Effect} */ (reaction) 7772 ); 7773 } 7774 } 7775 7776 // If we are returning to an previous reaction then 7777 // we need to increment the read version to ensure that 7778 // any dependencies in this reaction aren't marked with 7779 // the same version 7780 if (previous_reaction !== null && previous_reaction !== reaction) { 7781 read_version++; 7782 7783 // update the `rv` of the previous reaction's deps â both existing and new â 7784 // so that they are not added again 7785 if (previous_reaction.deps !== null) { 7786 for (let i = 0; i < previous_skipped_deps; i += 1) { 7787 previous_reaction.deps[i].rv = read_version; 7788 } 7789 } 7790 7791 if (previous_deps !== null) { 7792 for (const dep of previous_deps) { 7793 dep.rv = read_version; 7794 } 7795 } 7796 7797 if (untracked_writes !== null) { 7798 if (previous_untracked_writes === null) { 7799 previous_untracked_writes = untracked_writes; 7800 } else { 7801 previous_untracked_writes.push(.../** @type {Source[]} */ (untracked_writes)); 7802 } 7803 } 7804 } 7805 7806 if ((reaction.f & ERROR_VALUE) !== 0) { 7807 reaction.f ^= ERROR_VALUE; 7808 } 7809 7810 return result; 7811 } catch (error) { 7812 return handle_error(error); 7813 } finally { 7814 reaction.f ^= REACTION_IS_UPDATING; 7815 new_deps = previous_deps; 7816 skipped_deps = previous_skipped_deps; 7817 untracked_writes = previous_untracked_writes; 7818 active_reaction = previous_reaction; 7819 current_sources = previous_sources; 7820 set_component_context(previous_component_context); 7821 untracking = previous_untracking; 7822 update_version = previous_update_version; 7823 } 7824} 7825 7826/** 7827 * @template V 7828 * @param {Reaction} signal 7829 * @param {Value<V>} dependency 7830 * @returns {void} 7831 */ 7832function remove_reaction(signal, dependency) {
7833 let reactions = dependency.reactions; 7834 if (reactions !== null) { 7835 var index = index_of.call(reactions, signal); 7836 if (index !== -1) { 7837 var new_length = reactions.length - 1; 7838 if (new_length === 0) { 7839 reactions = dependency.reactions = null; 7840 } else { 7841 // Swap with last element and then remove. 7842 reactions[index] = reactions[new_length]; 7843 reactions.pop(); 7844 } 7845 } 7846 } 7847 7848 // If the derived has no reactions, then we can disconnect it from the graph, 7849 // allowing it to either reconnect in the future, or be GC'd by the VM. 7850 if ( 7851 reactions === null && 7852 (dependency.f & DERIVED) !== 0 && 7853 // Destroying a child effect while updating a parent effect can cause a dependency to appear 7854 // to be unused, when in fact it is used by the currently-updating parent. Checking `new_deps` 7855 // allows us to skip the expensive work of disconnecting and immediately reconnecting it 7856 (new_deps === null || !new_deps.includes(dependency)) 7857 ) { 7858 var derived = /** @type {Derived} */ (dependency); 7859 7860 // If we are working with a derived that is owned by an effect, then mark it as being 7861 // disconnected and remove the mark flag, as it cannot be reliably removed otherwise 7862 if ((derived.f & CONNECTED) !== 0) { 7863 derived.f ^= CONNECTED; 7864 derived.f &= ~WAS_MARKED; 7865 } 7866 7867 update_derived_status(derived); 7868 7869 // Disconnect any reactions owned by this reaction 7870 destroy_derived_effects(derived); 7871 remove_reactions(derived, 0); 7872 } 7873} 7874 7875/** 7876 * @param {Reaction} signal 7877 * @param {number} start_index 7878 * @returns {void} 7879 */ 7880function remove_reactions(signal, start_index) { 7881 var dependencies = signal.deps; 7882 if (dependencies === null) return; 7883 7884 for (var i = start_index; i < dependencies.length; i++) { 7885 remove_reaction(signal, dependencies[i]); 7886 } 7887} 7888 7889/** 7890 * @param {Effect} effect 7891 * @returns {void} 7892 */ 7893function update_effect(effect) { 7894 var flags = effect.f; 7895 7896 if ((flags & DESTROYED) !== 0) { 7897 return; 7898 } 7899 7900 set_signal_status(effect, CLEAN); 7901 7902 var previous_effect = active_effect; 7903 var was_updating_effect = is_updating_effect; 7904 7905 active_effect = effect; 7906 is_updating_effect = true; 7907 7908 if (DEV) { 7909 var previous_component_fn = dev_current_component_function; 7910 set_dev_current_component_function(effect.component_function); 7911 var previous_stack = /** @type {any} */ (dev_stack); 7912 // only block effects have a dev stack, keep the current one otherwise 7913 set_dev_stack(effect.dev_stack ?? dev_stack); 7914 } 7915 7916 try { 7917 if ((flags & (BLOCK_EFFECT | MANAGED_EFFECT)) !== 0) { 7918 destroy_block_effect_children(effect); 7919 } else { 7920 destroy_effect_children(effect); 7921 } 7922 7923 execute_effect_teardown(effect); 7924 var teardown = update_reaction(effect); 7925 effect.teardown = typeof teardown === 'function' ? teardown : null; 7926 effect.wv = write_version; 7927 7928 // In DEV, increment versions of any sources that were written to during the effect, 7929 // so that they are correctly marked as dirty when the effect re-runs 7930 var dep; if (DEV && tracing_mode_flag && (effect.f & DIRTY) !== 0 && effect.deps !== null) ; 7931 } finally { 7932 is_updating_effect = was_updating_effect; 7933 active_effect = previous_effect; 7934 7935 if (DEV) { 7936 set_dev_current_component_function(previous_component_fn); 7937 set_dev_stack(previous_stack); 7938 } 7939 } 7940} 7941 7942/** 7943 * Returns a promise that resolves once any pending state changes have been applied. 7944 * @returns {Promise<void>} 7945 */ 7946async function tick() { 7947 if (async_mode_flag) { 7948 return new Promise((f) => { 7949 // Race them against each other - in almost all cases requestAnimationFrame will fire first, 7950 // but e.g. in case the window is not focused or a view transition happens, requestAnimationFrame 7951 // will be delayed and setTimeout helps us resolve fast enough in that case 7952 requestAnimationFrame(() => f()); 7953 setTimeout(() => f()); 7954 }); 7955 } 7956 7957 await Promise.resolve(); 7958 7959 // By calling flushSync we guarantee that any pending state changes are applied after one tick. 7960 // TODO look into whether we can make flushing subsequent updates synchronously in the future. 7961 flushSync(); 7962} 7963 7964/** 7965 * @template V 7966 * @param {Value<V>} signal 7967 * @returns {V} 7968 */ 7969function get(signal) { 7970 var flags = signal.f; 7971 var is_derived = (flags & DERIVED) !== 0; 7972 7973 captured_signals?.add(signal); 7974 7975 // Register the dependency on the current reaction signal. 7976 if (active_reaction !== null && !untracking) { 7977 // if we're in a derived that is being read inside an _async_ derived, 7978 // it's possible that the effect was already destroyed. In this case, 7979 // we don't add the dependency, because that would create a memory leak 7980 var destroyed = active_effect !== null && (active_effect.f & DESTROYED) !== 0; 7981 7982 if (!destroyed && !current_sources?.includes(signal)) { 7983 var deps = active_reaction.deps; 7984 7985 if ((active_reaction.f & REACTION_IS_UPDATING) !== 0) { 7986 // we're in the effect init/update cycle 7987 if (signal.rv < read_version) { 7988 signal.rv = read_version; 7989 7990 // If the signal is accessing the same dependencies in the same 7991 // order as it did last time, increment `skipped_deps` 7992 // rather than updating `new_deps`, which creates GC cost 7993 if (new_deps === null && deps !== null && deps[skipped_deps] === signal) { 7994 skipped_deps++; 7995 } else if (new_deps === null) { 7996 new_deps = [signal]; 7997 } else { 7998 new_deps.push(signal); 7999 } 8000 } 8001 } else { 8002 // we're adding a dependency outside the init/update cycle 8003 // (i.e. after an `await`) 8004 (active_reaction.deps ??= []).push(signal); 8005 8006 var reactions = signal.reactions; 8007 8008 if (reactions === null) { 8009 signal.reactions = [active_reaction]; 8010 } else if (!reactions.includes(active_reaction)) { 8011 reactions.push(active_reaction); 8012 } 8013 } 8014 } 8015 } 8016 8017 if (DEV) { 8018 // TODO reinstate this, but make it actually work 8019 // if (current_async_effect) { 8020 // var tracking = (current_async_effect.f & REACTION_IS_UPDATING) !== 0; 8021 // var was_read = current_async_effect.deps?.includes(signal); 8022 8023 // if (!tracking && !untracking && !was_read) { 8024 // w.await_reactivity_loss(/** @type {string} */ (signal.label)); 8025 8026 // var trace = get_error('traced at'); 8027 // // eslint-disable-next-line no-console 8028 // if (trace) console.warn(trace); 8029 // } 8030 // } 8031 8032 recent_async_deriveds.delete(signal); 8033 } 8034
8035 if (is_destroying_effect && old_values.has(signal)) { 8036 return old_values.get(signal); 8037 } 8038 8039 if (is_derived) { 8040 var derived = /** @type {Derived} */ (signal); 8041 8042 if (is_destroying_effect) { 8043 var value = derived.v; 8044 8045 // if the derived is dirty and has reactions, or depends on the values that just changed, re-execute 8046 // (a derived can be maybe_dirty due to the effect destroy removing its last reaction) 8047 if ( 8048 ((derived.f & CLEAN) === 0 && derived.reactions !== null) || 8049 depends_on_old_values(derived) 8050 ) { 8051 value = execute_derived(derived); 8052 } 8053 8054 old_values.set(derived, value); 8055 8056 return value; 8057 } 8058 8059 // connect disconnected deriveds if we are reading them inside an effect, 8060 // or inside another derived that is already connected 8061 var should_connect = 8062 (derived.f & CONNECTED) === 0 && 8063 !untracking && 8064 active_reaction !== null && 8065 (is_updating_effect || (active_reaction.f & CONNECTED) !== 0); 8066 8067 var is_new = derived.deps === null; 8068 8069 if (is_dirty(derived)) { 8070 if (should_connect) { 8071 // set the flag before `update_derived`, so that the derived 8072 // is added as a reaction to its dependencies 8073 derived.f |= CONNECTED; 8074 } 8075 8076 update_derived(derived); 8077 } 8078 8079 if (should_connect && !is_new) { 8080 reconnect(derived); 8081 } 8082 } 8083 8084 if (batch_values?.has(signal)) { 8085 return batch_values.get(signal); 8086 } 8087 8088 if ((signal.f & ERROR_VALUE) !== 0) { 8089 throw signal.v; 8090 } 8091 8092 return signal.v; 8093} 8094 8095/** 8096 * (Re)connect a disconnected derived, so that it is notified 8097 * of changes in `mark_reactions` 8098 * @param {Derived} derived 8099 */ 8100function reconnect(derived) { 8101 if (derived.deps === null) return; 8102 8103 derived.f |= CONNECTED; 8104 8105 for (const dep of derived.deps) { 8106 (dep.reactions ??= []).push(derived); 8107 8108 if ((dep.f & DERIVED) !== 0 && (dep.f & CONNECTED) === 0) {
8109 reconnect(/** @type {Derived} */ (dep)); 8110 } 8111 } 8112} 8113 8114/** @param {Derived} derived */ 8115function depends_on_old_values(derived) { 8116 if (derived.v === UNINITIALIZED) return true; // we don't know, so assume the worst 8117 if (derived.deps === null) return false; 8118 8119 for (const dep of derived.deps) { 8120 if (old_values.has(dep)) { 8121 return true; 8122 } 8123 8124 if ((dep.f & DERIVED) !== 0 && depends_on_old_values(/** @type {Derived} */ (dep))) { 8125 return true; 8126 } 8127 } 8128 8129 return false; 8130} 8131 8132/** 8133 * When used inside a [`$derived`](https://svelte.dev/docs/svelte/$derived) or [`$effect`](https://svelte.dev/docs/svelte/$effect), 8134 * any state read inside `fn` will not be treated as a dependency. 8135 * 8136 * ```ts 8137 * $effect(() => { 8138 * // this will run when `data` changes, but not when `time` changes 8139 * save(data, { 8140 * timestamp: untrack(() => time) 8141 * }); 8142 * }); 8143 * ``` 8144 * @template T 8145 * @param {() => T} fn 8146 * @returns {T} 8147 */ 8148function untrack(fn) { 8149 var previous_untracking = untracking; 8150 try { 8151 untracking = true; 8152 return fn(); 8153 } finally { 8154 untracking = previous_untracking; 8155 } 8156} 8157 8158/** 8159 * Possibly traverse an object and read all its properties so that they're all reactive in case this is `$state`. 8160 * Does only check first level of an object for performance reasons (heuristic should be good for 99% of all cases). 8161 * @param {any} value 8162 * @returns {void} 8163 */ 8164function deep_read_state(value) { 8165 if (typeof value !== 'object' || !value || value instanceof EventTarget) { 8166 return; 8167 } 8168 8169 if (STATE_SYMBOL in value) { 8170 deep_read(value); 8171 } else if (!Array.isArray(value)) { 8172 for (let key in value) { 8173 const prop = value[key]; 8174 if (typeof prop === 'object' && prop && STATE_SYMBOL in prop) { 8175 deep_read(prop); 8176 } 8177 } 8178 } 8179} 8180 8181/** 8182 * Deeply traverse an object and read all its properties 8183 * so that they're all reactive in case this is `$state` 8184 * @param {any} value 8185 * @param {Set<any>} visited 8186 * @returns {void} 8187 */ 8188function deep_read(value, visited = new Set()) { 8189 if ( 8190 typeof value === 'object' && 8191 value !== null && 8192 // We don't want to traverse DOM elements 8193 !(value instanceof EventTarget) && 8194 !visited.has(value) 8195 ) { 8196 visited.add(value); 8197 // When working with a possible SvelteDate, this 8198 // will ensure we capture changes to it. 8199 if (value instanceof Date) { 8200 value.getTime(); 8201 } 8202 for (let key in value) { 8203 try { 8204 deep_read(value[key], visited); 8205 } catch (e) { 8206 // continue 8207 } 8208 } 8209 const proto = get_prototype_of(value); 8210 if ( 8211 proto !== Object.prototype && 8212 proto !== Array.prototype && 8213 proto !== Map.prototype && 8214 proto !== Set.prototype && 8215 proto !== Date.prototype 8216 ) { 8217 const descriptors = get_descriptors(proto); 8218 for (let key in descriptors) { 8219 const get = descriptors[key].get; 8220 if (get) { 8221 try { 8222 get.call(value); 8223 } catch (e) { 8224 // continue 8225 } 8226 } 8227 } 8228 } 8229 } 8230} 8231 8232const regex_return_characters = /\r/g; 8233 8234/** 8235 * @param {string} str 8236 * @returns {string} 8237 */ 8238function hash(str) { 8239 str = str.replace(regex_return_characters, ''); 8240 let hash = 5381; 8241 let i = str.length; 8242 8243 while (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i); 8244 return (hash >>> 0).toString(36); 8245} 8246 8247/** 8248 * @param {string} name 8249 */ 8250function is_capture_event(name) { 8251 return name.endsWith('capture') && name !== 'gotpointercapture' && name !== 'lostpointercapture'; 8252} 8253 8254/** List of Element events that will be delegated */ 8255const DELEGATED_EVENTS = [ 8256 'beforeinput', 8257 'click', 8258 'change', 8259 'dblclick', 8260 'contextmenu', 8261 'focusin', 8262 'focusout', 8263 'input', 8264 'keydown', 8265 'keyup', 8266 'mousedown', 8267 'mousemove', 8268 'mouseout', 8269 'mouseover', 8270 'mouseup', 8271 'pointerdown', 8272 'pointermove', 8273 'pointerout', 8274 'pointerover', 8275 'pointerup', 8276 'touchend', 8277 'touchmove', 8278 'touchstart' 8279]; 8280 8281/** 8282 * Returns `true` if `event_name` is a delegated event 8283 * @param {string} event_name 8284 */ 8285function can_delegate_event(event_name) { 8286 return DELEGATED_EVENTS.includes(event_name); 8287} 8288 8289/** 8290 * @type {Record<string, string>} 8291 * List of attribute names that should be aliased to their property names 8292 * because they behave differently between setting them as an attribute and 8293 * setting them as a property. 8294 */ 8295const ATTRIBUTE_ALIASES = { 8296 // no `class: 'className'` because we handle that separately 8297 formnovalidate: 'formNoValidate', 8298 ismap: 'isMap', 8299 nomodule: 'noModule',
8300 playsinline: 'playsInline', 8301 readonly: 'readOnly', 8302 defaultvalue: 'defaultValue', 8303 defaultchecked: 'defaultChecked', 8304 srcobject: 'srcObject', 8305 novalidate: 'noValidate', 8306 allowfullscreen: 'allowFullscreen', 8307 disablepictureinpicture: 'disablePictureInPicture', 8308 disableremoteplayback: 'disableRemotePlayback' 8309}; 8310 8311/** 8312 * @param {string} name 8313 */ 8314function normalize_attribute(name) { 8315 name = name.toLowerCase(); 8316 return ATTRIBUTE_ALIASES[name] ?? name; 8317} 8318 8319/** 8320 * Subset of delegated events which should be passive by default. 8321 * These two are already passive via browser defaults on window, document and body. 8322 * But since 8323 * - we're delegating them 8324 * - they happen often 8325 * - they apply to mobile which is generally less performant 8326 * we're marking them as passive by default for other elements, too. 8327 */ 8328const PASSIVE_EVENTS = ['touchstart', 'touchmove']; 8329 8330/** 8331 * Returns `true` if `name` is a passive event 8332 * @param {string} name 8333 */ 8334function is_passive_event(name) { 8335 return PASSIVE_EVENTS.includes(name); 8336} 8337 8338/** List of elements that require raw contents and should not have SSR comments put in them */ 8339const RAW_TEXT_ELEMENTS = /** @type {const} */ (['textarea', 'script', 'style', 'title']); 8340 8341/** @param {string} name */ 8342function is_raw_text_element(name) { 8343 return RAW_TEXT_ELEMENTS.includes(/** @type {typeof RAW_TEXT_ELEMENTS[number]} */ (name)); 8344} 8345 8346/** 8347 * Prevent devtools trying to make `location` a clickable link by inserting a zero-width space 8348 * @template {string | undefined} T 8349 * @param {T} location 8350 * @returns {T}; 8351 */ 8352function sanitize_location(location) { 8353 return /** @type {T} */ (location?.replace(/\//g, '/\u200b')); 8354} 8355 8356/** @type {Set<string>} */ 8357const all_registered_events = new Set(); 8358 8359/** @type {Set<(events: Array<string>) => void>} */ 8360const root_event_handles = new Set(); 8361 8362/** 8363 * SSR adds onload and onerror attributes to catch those events before the hydration. 8364 * This function detects those cases, removes the attributes and replays the events. 8365 * @param {HTMLElement} dom 8366 */ 8367function replay_events(dom) { 8368 if (!hydrating) return; 8369 8370 dom.removeAttribute('onload'); 8371 dom.removeAttribute('onerror'); 8372 // @ts-expect-error 8373 const event = dom.__e; 8374 if (event !== undefined) { 8375 // @ts-expect-error 8376 dom.__e = undefined; 8377 queueMicrotask(() => { 8378 if (dom.isConnected) { 8379 dom.dispatchEvent(event); 8380 } 8381 }); 8382 } 8383} 8384 8385/** 8386 * @param {string} event_name 8387 * @param {EventTarget} dom 8388 * @param {EventListener} [handler] 8389 * @param {AddEventListenerOptions} [options] 8390 */ 8391function create_event(event_name, dom, handler, options = {}) { 8392 /** 8393 * @this {EventTarget} 8394 */ 8395 function target_handler(/** @type {Event} */ event) { 8396 if (!options.capture) { 8397 // Only call in the bubble phase, else delegated events would be called before the capturing events 8398 handle_event_propagation.call(dom, event); 8399 } 8400 if (!event.cancelBubble) { 8401 return without_reactive_context(() => { 8402 return handler?.call(this, event); 8403 }); 8404 } 8405 } 8406 8407 // Chrome has a bug where pointer events don't work when attached to a DOM element that has been cloned 8408 // with cloneNode() and the DOM element is disconnected from the document. To ensure the event works, we 8409 // defer the attachment till after it's been appended to the document. TODO: remove this once Chrome fixes 8410 // this bug. The same applies to wheel events and touch events. 8411 if ( 8412 event_name.startsWith('pointer') || 8413 event_name.startsWith('touch') || 8414 event_name === 'wheel' 8415 ) { 8416 queue_micro_task(() => { 8417 dom.addEventListener(event_name, target_handler, options); 8418 }); 8419 } else { 8420 dom.addEventListener(event_name, target_handler, options); 8421 } 8422 8423 return target_handler; 8424} 8425 8426/** 8427 * @param {string} event_name 8428 * @param {Element} dom 8429 * @param {EventListener} [handler] 8430 * @param {boolean} [capture] 8431 * @param {boolean} [passive] 8432 * @returns {void} 8433 */ 8434function event(event_name, dom, handler, capture, passive) { 8435 var options = { capture, passive }; 8436 var target_handler = create_event(event_name, dom, handler, options); 8437 8438 if ( 8439 dom === document.body || 8440 // @ts-ignore 8441 dom === window || 8442 // @ts-ignore 8443 dom === document || 8444 // Firefox has quirky behavior, it can happen that we still get "canplay" events when the element is already removed 8445 dom instanceof HTMLMediaElement 8446 ) { 8447 teardown(() => { 8448 dom.removeEventListener(event_name, target_handler, options); 8449 }); 8450 } 8451} 8452 8453/** 8454 * @param {Array<string>} events 8455 * @returns {void} 8456 */ 8457function delegate(events) { 8458 for (var i = 0; i < events.length; i++) { 8459 all_registered_events.add(events[i]); 8460 } 8461 8462 for (var fn of root_event_handles) { 8463 fn(events); 8464 } 8465} 8466 8467// used to store the reference to the currently propagated event 8468// to prevent garbage collection between microtasks in Firefox 8469// If the event object is GCed too early, the expando __root property 8470// set on the event object is lost, causing the event delegation 8471// to process the event twice 8472let last_propagated_event = null; 8473 8474/** 8475 * @this {EventTarget} 8476 * @param {Event} event 8477 * @returns {void} 8478 */ 8479function handle_event_propagation(event) { 8480 var handler_element = this; 8481 var owner_document = /** @type {Node} */ (handler_element).ownerDocument; 8482 var event_name = event.type; 8483 var path = event.composedPath?.() || []; 8484 var current_target = /** @type {null | Element} */ (path[0] || event.target); 8485 8486 last_propagated_event = event; 8487 8488 // composedPath contains list of nodes the event has propagated through. 8489 // We check __root to skip all nodes below it in case this is a 8490 // parent of the __root node, which indicates that there's nested 8491 // mounted apps. In this case we don't want to trigger events multiple times. 8492 var path_idx = 0; 8493 8494 // the `last_propagated_event === event` check is redundant, but 8495 // without it the variable will be DCE'd and things will 8496 // fail mysteriously in Firefox 8497 // @ts-expect-error is added below 8498 var handled_at = last_propagated_event === event && event.__root; 8499 8500 if (handled_at) { 8501 var at_idx = path.indexOf(handled_at); 8502 if ( 8503 at_idx !== -1 && 8504 (handler_element === document || handler_element === /** @type {any} */ (window)) 8505 ) { 8506 // This is the fallback document listener or a window listener, but the event was already handled 8507 // -> ignore, but set handle_at to document/window so that we're resetting the event 8508 // chain in case someone manually dispatches the same event object again. 8509 // @ts-expect-error 8510 event.__root = handler_element; 8511 return; 8512 } 8513 8514 // We're deliberately not skipping if the index is higher, because 8515 // someone could create an event programmatically and emit it multiple times, 8516 // in which case we want to handle the whole propagation chain properly each time. 8517 // (this will only be a false negative if the event is dispatched multiple times and 8518 // the fallback document listener isn't reached in between, but that's super rare) 8519 var handler_idx = path.indexOf(handler_element); 8520 if (handler_idx === -1) { 8521 // handle_idx can theoretically be -1 (happened in some JSDOM testing scenarios with an event listener on the window object) 8522 // so guard against that, too, and assume that everything was handled at this point. 8523 return; 8524 } 8525 8526 if (at_idx <= handler_idx) { 8527 path_idx = at_idx; 8528 } 8529 } 8530 8531 current_target = /** @type {Element} */ (path[path_idx] || event.target); 8532 // there can only be one delegated event per element, and we either already handled the current target,
8533 // or this is the very first target in the chain which has a non-delegated listener, in which case it's safe 8534 // to handle a possible delegated event on it later (through the root delegation listener for example). 8535 if (current_target === handler_element) return; 8536 8537 // Proxy currentTarget to correct target 8538 define_property(event, 'currentTarget', { 8539 configurable: true, 8540 get() { 8541 return current_target || owner_document; 8542 } 8543 }); 8544 8545 // This started because of Chromium issue https://chromestatus.com/feature/5128696823545856, 8546 // where removal or moving of of the DOM can cause sync `blur` events to fire, which can cause logic 8547 // to run inside the current `active_reaction`, which isn't what we want at all. However, on reflection, 8548 // it's probably best that all event handled by Svelte have this behaviour, as we don't really want 8549 // an event handler to run in the context of another reaction or effect. 8550 var previous_reaction = active_reaction; 8551 var previous_effect = active_effect; 8552 set_active_reaction(null); 8553 set_active_effect(null); 8554 8555 try { 8556 /** 8557 * @type {unknown} 8558 */ 8559 var throw_error; 8560 /** 8561 * @type {unknown[]} 8562 */ 8563 var other_errors = []; 8564 8565 while (current_target !== null) { 8566 /** @type {null | Element} */ 8567 var parent_element = 8568 current_target.assignedSlot || 8569 current_target.parentNode || 8570 /** @type {any} */ (current_target).host || 8571 null; 8572 8573 try { 8574 // @ts-expect-error 8575 var delegated = current_target['__' + event_name]; 8576 8577 if ( 8578 delegated != null && 8579 (!(/** @type {any} */ (current_target).disabled) || 8580 // DOM could've been updated already by the time this is reached, so we check this as well 8581 // -> the target could not have been disabled because it emits the event in the first place 8582 event.target === current_target) 8583 ) { 8584 delegated.call(current_target, event); 8585 } 8586 } catch (error) { 8587 if (throw_error) { 8588 other_errors.push(error); 8589 } else { 8590 throw_error = error; 8591 } 8592 } 8593 if (event.cancelBubble || parent_element === handler_element || parent_element === null) { 8594 break; 8595 } 8596 current_target = parent_element; 8597 } 8598 8599 if (throw_error) { 8600 for (let error of other_errors) { 8601 // Throw the rest of the errors, one-by-one on a microtask 8602 queueMicrotask(() => { 8603 throw error; 8604 }); 8605 } 8606 throw throw_error; 8607 } 8608 } finally { 8609 // @ts-expect-error is used above 8610 event.__root = handler_element; 8611 // @ts-ignore remove proxy on currentTarget 8612 delete event.currentTarget; 8613 set_active_reaction(previous_reaction); 8614 set_active_effect(previous_effect); 8615 } 8616} 8617 8618/** @param {string} html */ 8619function create_fragment_from_html(html) { 8620 var elem = document.createElement('template'); 8621 elem.innerHTML = html.replaceAll('<!>', '<!---->'); // XHTML compliance 8622 return elem.content; 8623} 8624 8625/** @import { Effect, EffectNodes, TemplateNode } from '#client' */ 8626/** @import { TemplateStructure } from './types' */ 8627 8628/** 8629 * @param {TemplateNode} start 8630 * @param {TemplateNode | null} end 8631 */ 8632function assign_nodes(start, end) { 8633 var effect = /** @type {Effect} */ (active_effect); 8634 if (effect.nodes === null) { 8635 effect.nodes = { start, end, a: null, t: null }; 8636 } 8637} 8638 8639/** 8640 * @param {string} content 8641 * @param {number} flags 8642 * @returns {() => Node | Node[]} 8643 */ 8644/*#__NO_SIDE_EFFECTS__*/ 8645function from_html(content, flags) { 8646 var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0; 8647 var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0; 8648 8649 /** @type {Node} */ 8650 var node; 8651 8652 /** 8653 * Whether or not the first item is a text/element node. If not, we need to 8654 * create an additional comment node to act as `effect.nodes.start` 8655 */ 8656 var has_start = !content.startsWith('<!>'); 8657 8658 return () => { 8659 if (hydrating) { 8660 assign_nodes(hydrate_node, null); 8661 return hydrate_node; 8662 } 8663 8664 if (node === undefined) { 8665 node = create_fragment_from_html(has_start ? content : '<!>' + content); 8666 if (!is_fragment) node = /** @type {TemplateNode} */ (get_first_child(node)); 8667 } 8668 8669 var clone = /** @type {TemplateNode} */ ( 8670 use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true) 8671 ); 8672 8673 if (is_fragment) { 8674 var start = /** @type {TemplateNode} */ (get_first_child(clone)); 8675 var end = /** @type {TemplateNode}
8675 */ (clone.lastChild); 8676 8677 assign_nodes(start, end); 8678 } else { 8679 assign_nodes(clone, clone); 8680 } 8681 8682 return clone; 8683 }; 8684} 8685 8686/** 8687 * @param {string} content 8688 * @param {number} flags 8689 * @param {'svg' | 'math'} ns 8690 * @returns {() => Node | Node[]} 8691 */ 8692/*#__NO_SIDE_EFFECTS__*/ 8693function from_namespace(content, flags, ns = 'svg') { 8694 /** 8695 * Whether or not the first item is a text/element node. If not, we need to 8696 * create an additional comment node to act as `effect.nodes.start` 8697 */ 8698 var has_start = !content.startsWith('<!>'); 8699 var wrapped = `<${ns}>${has_start ? content : '<!>' + content}</${ns}>`; 8700 8701 /** @type {Element | DocumentFragment} */ 8702 var node; 8703 8704 return () => { 8705 if (hydrating) { 8706 assign_nodes(hydrate_node, null); 8707 return hydrate_node; 8708 } 8709 8710 if (!node) { 8711 var fragment = /** @type {DocumentFragment} */ (create_fragment_from_html(wrapped)); 8712 var root = /** @type {Element} */ (get_first_child(fragment)); 8713 8714 { 8715 node = /** @type {Element} */ (get_first_child(root)); 8716 } 8717 } 8718 8719 var clone = /** @type {TemplateNode} */ (node.cloneNode(true)); 8720 8721 { 8722 assign_nodes(clone, clone); 8723 } 8724 8725 return clone; 8726 }; 8727} 8728 8729/** 8730 * @param {string} content 8731 * @param {number} flags 8732 */ 8733/*#__NO_SIDE_EFFECTS__*/ 8734function from_svg(content, flags) { 8735 return from_namespace(content, flags, 'svg'); 8736} 8737 8738/** 8739 * Don't mark this as side-effect-free, hydration needs to walk all nodes 8740 * @param {any} value 8741 */ 8742function text(value = '') { 8743 if (!hydrating) { 8744 var t = create_text(value + ''); 8745 assign_nodes(t, t); 8746 return t; 8747 } 8748 8749 var node = hydrate_node; 8750 8751 if (node.nodeType !== TEXT_NODE) { 8752 // if an {expression} is empty during SSR, we need to insert an empty text node 8753 node.before((node = create_text())); 8754 set_hydrate_node(node); 8755 } 8756 8757 assign_nodes(node, node); 8758 return node; 8759} 8760 8761/** 8762 * @returns {TemplateNode | DocumentFragment} 8763 */ 8764function comment() { 8765 // we're not delegating to `template` here for performance reasons 8766 if (hydrating) { 8767 assign_nodes(hydrate_node, null); 8768 return hydrate_node; 8769 } 8770 8771 var frag = document.createDocumentFragment(); 8772 var start = document.createComment(''); 8773 var anchor = create_text(); 8774 frag.append(start, anchor); 8775 8776 assign_nodes(start, anchor); 8777 8778 return frag; 8779} 8780 8781/** 8782 * Assign the created (or in hydration mode, traversed) dom elements to the current block 8783 * and insert the elements into the dom (in client mode). 8784 * @param {Text | Comment | Element} anchor 8785 * @param {DocumentFragment | Element} dom 8786 */ 8787function append(anchor, dom) { 8788 if (hydrating) { 8789 var effect = /** @type {Effect & { nodes: EffectNodes }} */ (active_effect); 8790 8791 // When hydrating and outer component and an inner component is async, i.e. blocked on a promise, 8792 // then by the time the inner resolves we have already advanced to the end of the hydrated nodes 8793 // of the parent component. Check for defined for that reason to avoid rewinding the parent's end marker. 8794 if ((effect.f & EFFECT_RAN) === 0 || effect.nodes.end === null) { 8795 effect.nodes.end = hydrate_node; 8796 } 8797 8798 hydrate_next(); 8799 return; 8800 } 8801 8802 if (anchor === null) { 8803 // edge case â void `<svelte:element>` with content 8804 return; 8805 } 8806 8807 anchor.before(/** @type {Node} */ (dom)); 8808} 8809 8810/** @import { ComponentContext, Effect, EffectNodes, TemplateNode } from '#client' */ 8811/** @import { Component, ComponentType, SvelteComponent, MountOptions } from '../../index.js' */ 8812 8813/** 8814 * This is normally true â block effects should run their intro transitions â 8815 * but is false during hydration (unless `options.intro` is `true`) and 8816 * when creating the children of a `<svelte:element>` that just changed tag 8817 */ 8818let should_intro = true; 8819 8820/** @param {boolean} value */ 8821function set_should_intro(value) { 8822 should_intro = value; 8823} 8824 8825/** 8826 * @param {Element} text 8827 * @param {string} value 8828 * @returns {void} 8829 */ 8830function set_text(text, value) { 8831 // For objects, we apply string coercion (which might make things like $state array references in the template reactive) before diffing 8832 var str = value == null ? '' : typeof value === 'object' ? value + '' : value; 8833 // @ts-expect-error 8834 if (str !== (text.__t ??= text.nodeValue)) { 8835 // @ts-expect-error 8836 text.__t = str; 8837 text.nodeValue = str + ''; 8838 } 8839} 8840 8841/** 8842 * Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component. 8843 * Transitions will play during the initial render unless the `intro` option is set to `false`. 8844 * 8845 * @template {Record<string, any>} Props 8846 * @template {Record<string, any>} Exports 8847 * @param {ComponentType<SvelteComponent<Props>> | Component<Props, Exports, any>} component 8848 * @param {MountOptions<Props>} options 8849 * @returns {Exports} 8850 */ 8851function mount(component, options) { 8852 return _mount(component, options); 8853} 8854 8855/** @type {Map<string, number>} */ 8856const document_listeners = new Map(); 8857 8858/** 8859 * @template {Record<string, any>} Exports 8860 * @param {ComponentType<SvelteComponent<any>> | Component<any>} Component 8861 * @param {MountOptions} options 8862 * @returns {Exports} 8863 */ 8864function _mount(Component, { target, anchor, props = {}, events, context, intro = true }) { 8865 init_operations(); 8866 8867 /** @type {Set<string>} */ 8868 var registered_events = new Set(); 8869 8870 /** @param {Array<string>} events */ 8871 var event_handle = (events) => { 8872 for (var i = 0; i < events.length; i++) { 8873 var event_name = events[i]; 8874 8875 if (registered_events.has(event_name)) continue; 8876 registered_events.add(event_name); 8877 8878 var passive = is_passive_event(event_name); 8879 8880 // Add the event listener to both the container and the document. 8881 // The container listener ensures we catch events from within in case 8882 // the outer content stops propagation of the event. 8883 target.addEventListener(event_name, handle_event_propagation, { passive }); 8884 8885 var n = document_listeners.get(event_name); 8886 8887 if (n === undefined) { 8888 // The document listener ensures we catch events that originate from elements that were 8889 // manually moved outside of the container (e.g. via manual portals). 8890 document.addEventListener(event_name, handle_event_propagation, { passive }); 8891 document_listeners.set(event_name, 1); 8892 } else { 8893 document_listeners.set(event_name, n + 1); 8894 } 8895 } 8896 }; 8897 8898 event_handle(array_from(all_registered_events)); 8899 root_event_handles.add(event_handle); 8900 8901 /** @type {Exports} */ 8902 // @ts-expect-error will be defined because the render effect runs synchronously 8903 var component = undefined; 8904 8905 var unmount = component_root(() => { 8906 var anchor_node = anchor ?? target.appendChild(create_text()); 8907 8908 boundary( 8909 /** @type {TemplateNode} */ (anchor_node), 8910 { 8911 pending: () => {} 8912 }, 8913 (anchor_node) => { 8914 if (context) { 8915 push({}); 8916 var ctx = /** @type {ComponentContext} */ (component_context); 8917 ctx.c = context; 8918 } 8919 8920 if (events) { 8921 // We can't spread the object or else we'd lose the state proxy stuff, if it is one 8922 /** @type {any} */ (props).$$events = events; 8923 } 8924 8925 if (hydrating) { 8926 assign_nodes(/** @type {TemplateNode} */ (anchor_node), null); 8927 } 8928
8929 should_intro = intro; 8930 // @ts-expect-error the public typings are not what the actual function looks like 8931 component = Component(anchor_node, props) || {}; 8932 should_intro = true; 8933 8934 if (hydrating) { 8935 /** @type {Effect & { nodes: EffectNodes }} */ (active_effect).nodes.end = hydrate_node; 8936 8937 if ( 8938 hydrate_node === null || 8939 hydrate_node.nodeType !== COMMENT_NODE || 8940 /** @type {Comment} */ (hydrate_node).data !== HYDRATION_END 8941 ) { 8942 hydration_mismatch(); 8943 throw HYDRATION_ERROR; 8944 } 8945 } 8946 8947 if (context) { 8948 pop(); 8949 } 8950 } 8951 ); 8952 8953 return () => { 8954 for (var event_name of registered_events) { 8955 target.removeEventListener(event_name, handle_event_propagation); 8956 8957 var n = /** @type {number} */ (document_listeners.get(event_name)); 8958 8959 if (--n === 0) { 8960 document.removeEventListener(event_name, handle_event_propagation); 8961 document_listeners.delete(event_name); 8962 } else { 8963 document_listeners.set(event_name, n); 8964 } 8965 } 8966 8967 root_event_handles.delete(event_handle); 8968 8969 if (anchor_node !== anchor) { 8970 anchor_node.parentNode?.removeChild(anchor_node); 8971 } 8972 }; 8973 }); 8974 8975 mounted_components.set(component, unmount); 8976 return component; 8977} 8978 8979/** 8980 * References of the components that were mounted or hydrated. 8981 * Uses a `WeakMap` to avoid memory leaks. 8982 */ 8983let mounted_components = new WeakMap(); 8984 8985/** 8986 * Unmounts a component that was previously mounted using `mount` or `hydrate`. 8987 * 8988 * Since 5.13.0, if `options.outro` is `true`, [transitions](https://svelte.dev/docs/svelte/transition) will play before the component is removed from the DOM. 8989 * 8990 * Returns a `Promise` that resolves after transitions have completed if `options.outro` is true, or immediately otherwise (prior to 5.13.0, returns `void`). 8991 * 8992 * ```js 8993 * import { mount, unmount } from 'svelte'; 8994 * import App from './App.svelte'; 8995 * 8996 * const app = mount(App, { target: document.body }); 8997 * 8998 * // later... 8999 * unmount(app, { outro: true }); 9000 * ``` 9001 * @param {Record<string, any>} component 9002 * @param {{ outro?: boolean }} [options] 9003 * @returns {Promise<void>} 9004 */ 9005function unmount(component, options) { 9006 const fn = mounted_components.get(component); 9007 9008 if (fn) { 9009 mounted_components.delete(component); 9010 return fn(options); 9011 } 9012 9013 if (DEV) { 9014 if (STATE_SYMBOL in component) { 9015 state_proxy_unmount(); 9016 } else { 9017 lifecycle_double_unmount(); 9018 } 9019 } 9020 9021 return Promise.resolve(); 9022} 9023 9024/** @import { ComponentContext, ComponentContextLegacy } from '#client' */ 9025/** @import { EventDispatcher } from './index.js' */ 9026/** @import { NotFunction } from './internal/types.js' */ 9027 9028if (DEV) { 9029 /** 9030 * @param {string} rune 9031 */ 9032 function throw_rune_error(rune) { 9033 if (!(rune in globalThis)) { 9034 // TODO if people start adjusting the "this can contain runes" config through v-p-s more, adjust this message 9035 /** @type {any} */ 9036 let value; // let's hope noone modifies this global, but belts and braces 9037 Object.defineProperty(globalThis, rune, { 9038 configurable: true, 9039 // eslint-disable-next-line getter-return 9040 get: () => { 9041 if (value !== undefined) { 9042 return value; 9043 } 9044 9045 rune_outside_svelte(rune); 9046 }, 9047 set: (v) => { 9048 value = v; 9049 } 9050 }); 9051 } 9052 } 9053 9054 throw_rune_error('$state'); 9055 throw_rune_error('$effect'); 9056 throw_rune_error('$derived'); 9057 throw_rune_error('$inspect'); 9058 throw_rune_error('$props'); 9059 throw_rune_error('$bindable'); 9060} 9061 9062/** 9063 * `onMount`, like [`$effect`](https://svelte.dev/docs/svelte/$effect), schedules a function to run as soon as the component has been mounted to the DOM. 9064 * Unlike `$effect`, the provided function only runs once. 9065 * 9066 * It must be called during the component's initialisation (but doesn't need to live _inside_ the component; 9067 * it can be called from an external module). If a function is returned _synchronously_ from `onMount`, 9068 * it will be called when the component is unmounted. 9069 * 9070 * `onMount` functions do not run during [server-side rendering](https://svelte.dev/docs/svelte/svelte-server#render). 9071 * 9072 * @template T 9073 * @param {() => NotFunction<T> | Promise<NotFunction<T>> | (() => any)} fn 9074 * @returns {void} 9075 */ 9076function onMount(fn) { 9077 if (component_context === null) { 9078 lifecycle_outside_component('onMount'); 9079 } 9080 9081 if (legacy_mode_flag && component_context.l !== null) { 9082 init_update_callbacks(component_context).m.push(fn); 9083 } else { 9084 user_effect(() => { 9085 const cleanup = untrack(fn); 9086 if (typeof cleanup === 'function') return /** @type {() => void} */ (cleanup); 9087 }); 9088 } 9089} 9090 9091/** 9092 * Schedules a callback to run immediately before the component is unmounted. 9093 * 9094 * Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the 9095 * only one that runs inside a server-side component. 9096 * 9097 * @param {() => any} fn 9098 * @returns {void} 9099 */ 9100function onDestroy(fn) { 9101 if (component_context === null) { 9102 lifecycle_outside_component('onDestroy'); 9103 } 9104 9105 onMount(() => () => untrack(fn)); 9106} 9107 9108/** 9109 * @template [T=any] 9110 * @param {string} type 9111 * @param {T} [detail] 9112 * @param {any}params_0 9113 * @returns {CustomEvent<T>} 9114 */ 9115function create_custom_event(type, detail, { bubbles = false, cancelable = false } = {}) {
9116 return new CustomEvent(type, { detail, bubbles, cancelable }); 9117} 9118 9119/** 9120 * Creates an event dispatcher that can be used to dispatch [component events](https://svelte.dev/docs/svelte/legacy-on#Component-events). 9121 * Event dispatchers are functions that can take two arguments: `name` and `detail`. 9122 * 9123 * Component events created with `createEventDispatcher` create a 9124 * [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). 9125 * These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture). 9126 * The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) 9127 * property and can contain any type of data. 9128 * 9129 * The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument: 9130 * ```ts 9131 * const dispatch = createEventDispatcher<{ 9132 * loaded: null; // does not take a detail argument 9133 * change: string; // takes a detail argument of type string, which is required 9134 * optional: number | null; // takes an optional detail argument of type number 9135 * }>(); 9136 * ``` 9137 * 9138 * @deprecated Use callback props and/or the `$host()` rune instead â see [migration guide](https://svelte.dev/docs/svelte/v5-migration-guide#Event-changes-Component-events) 9139 * @template {Record<string, any>} [EventMap = any] 9140 * @returns {EventDispatcher<EventMap>} 9141 */ 9142function createEventDispatcher() { 9143 const active_component_context = component_context; 9144 if (active_component_context === null) { 9145 lifecycle_outside_component('createEventDispatcher'); 9146 } 9147 9148 /** 9149 * @param [detail] 9150 * @param [options] 9151 */ 9152 return (type, detail, options) => { 9153 const events = /** @type {Record<string, Function | Function[]>} */ ( 9154 active_component_context.s.$$events 9155 )?.[/** @type {string} */ (type)]; 9156 9157 if (events) { 9158 const callbacks = is_array(events) ? events.slice() : [events]; 9159 // TODO are there situations where events could be dispatched 9160 // in a server (non-DOM) environment? 9161 const event = create_custom_event(/** @type {string} */ (type), detail, options); 9162 for (const fn of callbacks) { 9163 fn.call(active_component_context.x, event); 9164 } 9165 return !event.defaultPrevented; 9166 } 9167 9168 return true; 9169 }; 9170} 9171 9172/** 9173 * Schedules a callback to run immediately after the component has been updated. 9174 * 9175 * The first time the callback runs will be after the initial `onMount`. 9176 * 9177 * In runes mode use `$effect` instead. 9178 * 9179 * @deprecated Use [`$effect`](https://svelte.dev/docs/svelte/$effect) instead 9180 * @param {() => void} fn 9181 * @returns {void} 9182 */ 9183function afterUpdate(fn) { 9184 if (component_context === null) { 9185 lifecycle_outside_component('afterUpdate'); 9186 } 9187 9188 if (component_context.l === null) { 9189 lifecycle_legacy_only('afterUpdate'); 9190 } 9191 9192 init_update_callbacks(component_context).a.push(fn); 9193} 9194 9195/** 9196 * Legacy-mode: Init callbacks object for onMount/beforeUpdate/afterUpdate 9197 * @param {ComponentContext} context 9198 */ 9199function init_update_callbacks(context) { 9200 var l = /** @type {ComponentContextLegacy} */ (context).l; 9201 return (l.u ??= { a: [], b: [], m: [] }); 9202} 9203 9204const ENTRY_CSS = "./assets/index-CrbFh6qt.css"; 9205let FONTS; 9206FONTS = []; 9207let IndexComponent; 9208let mount_css; 9209let _res; 9210let pending = new Promise((res) => { 9211 _res = res; 9212}); 9213globalThis.__MODE__ ??= "_NORMAL_"; 9214const mode = globalThis.__MODE__; 9215async function get_index() { 9216 if (mode === "_CC_") { 9217 await __vitePreload(() => import('virtual:cc-init'),true ?[]:void 0,import.meta.url); 9218 } 9219 const modules = await Promise.all([ 9220 __vitePreload(() => import('./Index-BRJ0gETR.js'),true ?__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12]):void 0,import.meta.url), 9221 __vitePreload(() => import('./index-BJk8VOjP.js'),true ?__vite__mapDeps([13,1,2,14,15,16]):void 0,import.meta.url) 9222 ]); 9223 IndexComponent = modules[0].default; 9224 mount_css = modules[1].mount_css; 9225 _res(); 9226} 9227function create_custom_element() { 9228 class GradioApp extends HTMLElement { 9229 control_page_title; 9230 initial_height; 9231 is_embed; 9232 container; 9233 info; 9234 autoscroll; 9235 eager; 9236 theme_mode; 9237 host; 9238 space; 9239 src; 9240 app; 9241 loading; 9242 updating; 9243 constructor() { 9244 super(); 9245 this.host = this.getAttribute("host"); 9246 this.space = this.getAttribute("space"); 9247 this.src = this.getAttribute("src"); 9248 this.control_page_title = this.getAttribute("control_page_title"); 9249 this.initial_height = this.getAttribute("initial_height") ?? "300px"; 9250 this.is_embed = this.getAttribute("embed") ?? "true"; 9251 this.container = this.getAttribute("container") ?? "true"; 9252 this.info = this.getAttribute("info") ?? true; 9253 this.autoscroll = this.getAttribute("autoscroll"); 9254 this.eager = this.getAttribute("eager"); 9255 this.theme_mode = this.getAttribute("theme_mode"); 9256 this.updating = false;
9257 this.loading = false; 9258 } 9259 async connectedCallback() { 9260 await get_index(); 9261 this.loading = true; 9262 if (this.app) { 9263 this.app.$destroy(); 9264 } 9265 if (typeof FONTS !== "string") { 9266 FONTS.forEach((f) => mount_css(f, document.head)); 9267 } 9268 await mount_css(ENTRY_CSS, document.head); 9269 const event = new CustomEvent("domchange", { 9270 bubbles: true, 9271 cancelable: false, 9272 composed: true 9273 }); 9274 const observer = new MutationObserver((mutations) => { 9275 this.dispatchEvent(event); 9276 }); 9277 observer.observe(this, { childList: true }); 9278 const opts = { 9279 target: this, 9280 props: { 9281 // embed source 9282 space: this.space ? this.space.trim() : this.space, 9283 src: this.src ? this.src.trim() : this.src, 9284 // embed info 9285 info: this.info === "false" ? false : true, 9286 container: this.container === "false" ? false : true, 9287 is_embed: this.is_embed === "false" ? false : true, 9288 initial_height: this.initial_height, 9289 eager: this.eager === "true" ? true : false, 9290 // gradio meta info 9291 version: "6-11-0", 9292 theme_mode: this.theme_mode, 9293 // misc global behaviour 9294 autoscroll: this.autoscroll === "true" ? true : false, 9295 control_page_title: this.control_page_title === "true" ? true : false, 9296 // injectables 9297 Client, 9298 // for gradio docs 9299 // TODO: Remove -- i think this is just for autoscroll behavhiour, app vs embeds 9300 app_mode: window.__gradio_mode__ === "app" 9301 } 9302 }; 9303 this.app = mount(IndexComponent, opts); 9304 if (this.updating) { 9305 this.setAttribute(this.updating.name, this.updating.value); 9306 } 9307 this.loading = false; 9308 } 9309 static get observedAttributes() { 9310 return ["src", "space", "host"]; 9311 } 9312 async attributeChangedCallback(name, old_val, new_val) { 9313 await pending; 9314 if ((name === "host" || name === "space" || name === "src") && new_val !== old_val) { 9315 this.updating = { name, value: new_val }; 9316 if (this.loading) return; 9317 if (this.app) { 9318 unmount(this.app); 9319 } 9320 this.space = null; 9321 this.host = null; 9322 this.src = null; 9323 if (name === "host") { 9324 this.host = new_val; 9325 } else if (name === "space") { 9326 this.space = new_val; 9327 } else if (name === "src") { 9328 this.src = new_val; 9329 } 9330 const opts = { 9331 target: this, 9332 props: { 9333 // embed source 9334 space: this.space ? this.space.trim() : this.space, 9335 src: this.src ? this.src.trim() : this.src, 9336 // embed info 9337 info: this.info === "false" ? false : true, 9338 container: this.container === "false" ? false : true, 9339 is_embed: this.is_embed === "false" ? false : true, 9340 initial_height: this.initial_height, 9341 eager: this.eager === "true" ? true : false, 9342 // gradio meta info 9343 version: "6-11-0", 9344 theme_mode: this.theme_mode, 9345 // misc global behaviour 9346 autoscroll: this.autoscroll === "true" ? true : false, 9347 control_page_title: this.control_page_title === "true" ? true : false, 9348 // injectables 9349 Client, 9350 // for gradio docs 9351 // TODO: Remove -- i think this is just for autoscroll behavhiour, app vs embeds 9352 app_mode: window.__gradio_mode__ === "app" 9353 } 9354 }; 9355 this.app = mount(IndexComponent, opts); 9356 this.updating = false; 9357 } 9358 } 9359 } 9360 if (!customElements.get("gradio-app")) 9361 customElements.define("gradio-app", GradioApp); 9362} 9363create_custom_element(); 9364 9365export { is_array as $, effect as A, render_effect as B, COMMENT_NODE as C, DEV as D, EFFECT_TRANSPARENT as E, FILENAME as F, deep_read_state as G, HYDRATION_ERROR as H, safe_not_equal as I, listen_to_event_and_reset_event as J, bind_invalid_checkbox_value as K, current_batch as L, tick as M, teardown as N, queue_micro_task as O, previous_batch as P, is as Q, push as R, first_child as S, pop as T, flushSync as U, child as V, from_html as W, sibling as X, reset as Y, event as Z, replay_events as _, append as a, TRANSITION_OUT as a$, set_text as a0, legacy_pre_effect as a1, legacy_pre_effect_reset as a2, mutable_source as a3, createEventDispatcher as a4, user_derived as a5, comment as a6, text as a7, next as a8, is_runes as a9, is_promise as aA, internal_set as aB, Batch as aC, unset_context as aD, is_flushing_sync as aE, source as aF, UNINITIALIZED as aG, capture as aH, HYDRATION_START_ELSE as aI, skip_nodes as aJ, mount as aK, unmount as aL, get_descriptor as aM, update as aN, get_boundary as aO, flatten as aP, HEAD_EFFECT as aQ, run as aR, async_derived as aS, run_after_blockers as aT, deferred_template_effect as aU, $document as aV, should_intro as aW, BLOCK_EFFECT as aX, EFFECT_RAN as aY, TRANSITION_G
9365LOBAL as aZ, TRANSITION_IN as a_, onMount as aa, listen as ab, without_reactive_context as ac, derived_safe_equal as ad, onDestroy as ae, __vitePreload as af, get_prototype_of as ag, object_prototype as ah, user_pre_effect as ai, delegate as aj, remove_textarea_child as ak, autofocus as al, set_should_intro as am, NAMESPACE_SVG as an, create_text as ao, ELEMENT_NODE as ap, is_raw_text_element as aq, set_hydrating as ar, mutate as as, to_array as at, prepare_files as au, FileData as av, $window as aw, setContext as ax, getContext as ay, afterUpdate as az, active_effect as b, is_function as b0, noop as b1, transition_slide_display as b2, invalidate_inner_signals as b3, resume_effect as b4, destroy_effect as b5, pause_effect as b6, branch as b7, move_effect as b8, should_defer_append as b9, run$1 as bA, derived as bB, define_property as bC, props_invalid_value as bD, PROPS_IS_UPDATED as bE, DESTROYED as bF, PROPS_IS_BINDABLE as bG, PROPS_IS_IMMUTABLE as bH, PROPS_IS_LAZY_INITIAL as bI, is_destroying_effect as bJ, LEGACY_PROPS as bK, set_active_effect as bL, props_rest_readonly as bM, legacy_mode_flag as bN, PROPS_IS_RUNES as bO, enable_legacy_mode_flag as bP, enable_async_mode_flag as bQ, read_hydration_instruction as ba, EACH_IS_CONTROLLED as bb, array_from as bc, EACH_ITEM_REACTIVE as bd, EACH_ITEM_IMMUTABLE as be, EACH_INDEX_REACTIVE as bf, EFFECT_OFFSCREEN as bg, INERT as bh, EACH_IS_ANIMATED as bi, clear_text_content as bj, HYDRATION_END as bk, managed as bl, select_multiple_invalid_value as bm, LOADING_ATTR_SYMBOL as bn, ATTACHMENT_KEY as bo, NAMESPACE_HTML as bp, is_capture_event as bq, create_event as br, normalize_attribute as bs, can_delegate_event as bt, get_descriptors as bu, add_form_reset_listener as bv, hydration_attribute_changed as bw, STATE_SYMBOL as bx, component_context as by, run_all as bz, create_fragment_from_html as c, assign_nodes as d, hydrate_next as e, from_svg as f, get_first_child as g, hydrating as h, hydrate_node as i, get_next_sibling as j, hydration_mismatch as k, hash as l, dev_current_component_function as m, hydration_html_changed as n, sanitize_location as o, block as p, invalid_snippet as q, remove_effect_dom as r, set_hydrate_node as s, template_effect as t, state as u, proxy as v, get as w, set as x, user_effect as y, untrack as z }; 9366//# sourceMappingURL=index-BvBk1Iap.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.