@gradio/client 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,7 +21,7 @@ export declare function get_jwt(space: string, token: `hf_${string}`, cookies?:
21
21
  */
22
22
  export declare function normalise_token_option(options: ClientOptions): void;
23
23
  export declare function map_names_to_ids(fns: Config["dependencies"]): Record<string, number>;
24
- export declare function resolve_config_root(root: string, current_location: string): string;
24
+ export declare function resolve_config_root(root: string, current_location: string, prioritize_current_location?: boolean): string;
25
25
  export declare function resolve_config(this: Client, endpoint: string, strip_current_page?: boolean): Promise<Config | undefined>;
26
26
  export declare function resolve_cookies(this: Client): Promise<void>;
27
27
  export declare function get_cookie_header(http_protocol: string, host: string, auth: [string, string], _fetch: typeof fetch, token?: `hf_${string}`, credentials?: RequestCredentials): Promise<string | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"init_helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/init_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWtD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAG5B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,GACtB,MAAM,CAKR;AAED,wBAAsB,OAAO,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAezB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAOnE;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,GACtB,MAAM,CAUR;AAED,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,kBAAkB,UAAO,GACvB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+D7B;AAsCD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBjE;AAGD,wBAAsB,iBAAiB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EACtB,MAAM,EAAE,OAAO,KAAK,EACpB,KAAK,CAAC,EAAE,MAAM,MAAM,EAAE,EACtB,WAAW,CAAC,EAAE,kBAAkB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACb,CAkBA;AAED,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,KAAG,MAAM,EAUnE,CAAC"}
1
+ {"version":3,"file":"init_helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/init_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAWtD,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAG5B;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,GACtB,MAAM,CAKR;AAED,wBAAsB,OAAO,CAC5B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,CAezB;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAOnE;AAED,wBAAgB,gBAAgB,CAC/B,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EACxB,2BAA2B,UAAQ,GACjC,MAAM,CAqBR;AAED,wBAAsB,cAAc,CACnC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,kBAAkB,UAAO,GACvB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAoE7B;AAsCD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBjE;AAGD,wBAAsB,iBAAiB,CACtC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EACtB,MAAM,EAAE,OAAO,KAAK,EACpB,KAAK,CAAC,EAAE,MAAM,MAAM,EAAE,EACtB,WAAW,CAAC,EAAE,kBAAkB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG;IACrD,WAAW,EAAE,IAAI,GAAG,KAAK,CAAC;IAC1B,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACb,CAkBA;AAED,eAAO,MAAM,qBAAqB,GAAI,eAAe,MAAM,KAAG,MAAM,EAUnE,CAAC"}
package/dist/index.cjs CHANGED
@@ -63,9 +63,11 @@ function map_names_to_ids(fns) {
63
63
  });
64
64
  return apis;
65
65
  }
66
- function resolve_config_root(root, current_location) {
67
- const root_url = new URL(root, current_location);
66
+ function resolve_config_root(root, current_location, prioritize_current_location = false) {
68
67
  const current_url = new URL(current_location);
68
+ const root_url = new URL(root, current_url);
69
+ const is_colab_runtime = root_url.hostname.endsWith(".colab-user-runtimes.internal") || root_url.hostname.endsWith(".codatalab-user-runtimes.internal");
70
+ if (prioritize_current_location || is_colab_runtime) return new URL(new URL(root, current_url).pathname, current_url).toString().replace(/\/$/, "");
69
71
  if (root_url.hostname !== current_url.hostname) return root;
70
72
  root_url.protocol = current_url.protocol;
71
73
  root_url.host = current_url.host;
@@ -88,7 +90,7 @@ async function resolve_config(endpoint, strip_current_page = true) {
88
90
  };
89
91
  }
90
92
  const config = { ...window.gradio_config };
91
- config.root = resolve_config_root(config.root, location.href);
93
+ config.root = resolve_config_root(config.root, location.href, config.is_colab);
92
94
  return config;
93
95
  } else if (endpoint) {
94
96
  let config_url = join_urls(endpoint, this.deep_link ? CONFIG_URL + "?deep_link=" + this.deep_link : CONFIG_URL);
@@ -610,10 +612,11 @@ async function upload(file_data, root_url, upload_id, max_file_size) {
610
612
  if (response.error) throw new Error(response.error);
611
613
  else {
612
614
  if (response.files) return response.files.map((f, i) => {
615
+ const encoded_path = f.split("/").map((segment) => encodeURIComponent(segment)).join("/");
613
616
  return new FileData({
614
617
  ...file_data[i],
615
618
  path: f,
616
- url: `${root_url}${this.api_prefix}/file=${f}`
619
+ url: `${root_url}${this.api_prefix}/file=${encoded_path}`
617
620
  });
618
621
  });
619
622
  return [];
@@ -1433,6 +1436,7 @@ function readable_stream(input, init = {}) {
1433
1436
  var KEY_ROOT = "gradio:run-history:";
1434
1437
  var STORAGE_PREFIX = `${KEY_ROOT}v2:`;
1435
1438
  var REPLAY_PREFIX = `${KEY_ROOT}replay:v2:`;
1439
+ var DESTINATION_PREFIX = `${KEY_ROOT}destination:v1:`;
1436
1440
  var MAX_RUNS = 100;
1437
1441
  var MAX_APPS = 8;
1438
1442
  /**
@@ -1470,6 +1474,34 @@ function replay_key(scope) {
1470
1474
  const key = storage_key(scope);
1471
1475
  return key ? key.replace(STORAGE_PREFIX, REPLAY_PREFIX) : null;
1472
1476
  }
1477
+ function destination_key(scope) {
1478
+ const key = storage_key(scope);
1479
+ return key ? key.replace(STORAGE_PREFIX, DESTINATION_PREFIX) : null;
1480
+ }
1481
+ function read_run_history_storage_impl(scope) {
1482
+ const key = destination_key(scope);
1483
+ if (!key) return { type: "browser" };
1484
+ try {
1485
+ const value = JSON.parse(window.localStorage.getItem(key) || "null");
1486
+ if (typeof value?.bucket_id === "string") return value.type === "bucket" ? {
1487
+ type: "bucket",
1488
+ bucket_id: value.bucket_id
1489
+ } : {
1490
+ type: "browser",
1491
+ bucket_id: value.bucket_id
1492
+ };
1493
+ return { type: "browser" };
1494
+ } catch {
1495
+ return { type: "browser" };
1496
+ }
1497
+ }
1498
+ function set_run_history_storage_impl(scope, storage) {
1499
+ const key = destination_key(scope);
1500
+ if (!key) return;
1501
+ if (storage.type === "browser" && !storage.bucket_id) window.localStorage.removeItem(key);
1502
+ else window.localStorage.setItem(key, JSON.stringify(storage));
1503
+ notify_run_history_change();
1504
+ }
1473
1505
  /** When a run was most recently saved under a key, for deciding what to drop. */
1474
1506
  function last_saved_at(key) {
1475
1507
  try {
@@ -1486,7 +1518,7 @@ function last_saved_at(key) {
1486
1518
  */
1487
1519
  function prune_apps(current_key) {
1488
1520
  const keys = Object.keys(window.localStorage).filter((key) => key.startsWith(KEY_ROOT));
1489
- const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
1521
+ const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX) && !key.startsWith(DESTINATION_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
1490
1522
  for (const key of stale) try {
1491
1523
  window.localStorage.removeItem(key);
1492
1524
  window.sessionStorage.removeItem(key.replace(STORAGE_PREFIX, REPLAY_PREFIX));
@@ -1594,7 +1626,29 @@ function consume_run_history_replay_impl(scope) {
1594
1626
  return null;
1595
1627
  }
1596
1628
  }
1629
+ function restore_run_impl(config, run) {
1630
+ const dependency = config.dependencies.find((item) => item.id === run.fn_index || typeof item.api_name === "string" && `/${item.api_name.replace(/^\//, "")}` === run.api_name);
1631
+ if (!dependency) return false;
1632
+ const inputs = Array.isArray(run.inputs) ? run.inputs : Object.values(run.inputs ?? {});
1633
+ const outputs = Array.isArray(run.outputs) ? run.outputs : run.outputs === null || run.outputs === void 0 ? [] : [run.outputs];
1634
+ const restore = (ids, saved) => {
1635
+ for (const [index, id] of ids.entries()) {
1636
+ const component = config.components.find((item) => item.id === id);
1637
+ if (!component || index >= saved.length) continue;
1638
+ if (component.type === "state") continue;
1639
+ component.props.value = saved[index];
1640
+ }
1641
+ };
1642
+ restore(dependency.inputs, inputs);
1643
+ restore(dependency.outputs, outputs);
1644
+ return true;
1645
+ }
1646
+ function apply_run_history_replay_impl(config) {
1647
+ const run = consume_run_history_replay_impl(config);
1648
+ return run ? restore_run_impl(config, run) : false;
1649
+ }
1597
1650
  function start_run_history_impl(options) {
1651
+ if (read_run_history_storage_impl(options).type === "bucket") return null;
1598
1652
  const key = storage_key(options);
1599
1653
  if (!key) return null;
1600
1654
  prune_apps(key);
@@ -1674,6 +1728,12 @@ function mark_complete(run, event) {
1674
1728
  function read_run_history(scope) {
1675
1729
  return safely(() => read_run_history_impl(scope), []);
1676
1730
  }
1731
+ function read_run_history_storage(scope) {
1732
+ return safely(() => read_run_history_storage_impl(scope), { type: "browser" });
1733
+ }
1734
+ function set_run_history_storage(scope, storage) {
1735
+ safely(() => set_run_history_storage_impl(scope, storage), void 0);
1736
+ }
1677
1737
  function clear_run_history(scope) {
1678
1738
  safely(() => clear_run_history_impl(scope), void 0);
1679
1739
  }
@@ -1686,6 +1746,16 @@ function stage_run_history_replay(scope, run) {
1686
1746
  function consume_run_history_replay(scope) {
1687
1747
  return safely(() => consume_run_history_replay_impl(scope), null);
1688
1748
  }
1749
+ /**
1750
+ * Applies the run staged by the history page, if this page load is the one it
1751
+ * was staged for. Every entry point that renders an app has to call this, or
1752
+ * "Load run" silently does nothing on that entry point.
1753
+ *
1754
+ * @returns whether a staged run was found and applied.
1755
+ */
1756
+ function apply_run_history_replay(config) {
1757
+ return safely(() => apply_run_history_replay_impl(config), false);
1758
+ }
1689
1759
  function start_run_history(options) {
1690
1760
  return safely(() => start_run_history_impl(options), null);
1691
1761
  }
@@ -1704,7 +1774,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1704
1774
  try {
1705
1775
  const { token } = this.options;
1706
1776
  const { fetch, app_reference, config, session_hash, api_info, api_map, stream_status, pending_stream_messages, pending_diff_streams, event_callbacks, unclosed_events, post_data, options, api_prefix } = this;
1707
- const addt_headers = additional_headers || { "x-gradio-user": "api" };
1777
+ const base_headers = additional_headers || { "x-gradio-user": "api" };
1708
1778
  const that = this;
1709
1779
  if (!api_info) throw new Error(NO_API_INFO_MSG);
1710
1780
  if (!config) throw new Error("Could not resolve app config");
@@ -1729,6 +1799,11 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1729
1799
  app_id: config.app_id,
1730
1800
  username: config.username
1731
1801
  };
1802
+ const history_storage = read_run_history_storage(history_scope);
1803
+ const addt_headers = {
1804
+ ...base_headers,
1805
+ ...history_enabled && history_storage.type === "bucket" ? { "x-gradio-history-bucket": history_storage.bucket_id } : {}
1806
+ };
1732
1807
  const history_run_id = !history_enabled || !is_documented_endpoint ? null : start_run_history({
1733
1808
  ...history_scope,
1734
1809
  endpoint: history_endpoint,
@@ -1902,7 +1977,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1902
1977
  ...payload,
1903
1978
  session_hash,
1904
1979
  event_id
1905
- });
1980
+ }, addt_headers);
1906
1981
  if (status !== 200) {
1907
1982
  fire_event({
1908
1983
  type: "status",
@@ -2564,20 +2639,115 @@ async function duplicate_space(app_reference, options) {
2564
2639
  return await Client.duplicate(app_reference, options);
2565
2640
  }
2566
2641
  //#endregion
2642
+ //#region src/utils/bucket_sync.ts
2643
+ /**
2644
+ * Client for the durable run history in an HF Hub bucket
2645
+ * (`/gradio_api/run-history/*`).
2646
+ *
2647
+ * Read-only by design. Records are written by the server from the run it
2648
+ * actually executed — there is no push function here, and nothing in this
2649
+ * module can create a record.
2650
+ *
2651
+ * Every call names the bucket it is talking about. The server holds no
2652
+ * per-session binding, so two tabs (or two apps on one origin) cannot end up
2653
+ * reading each other's history.
2654
+ */
2655
+ var BUCKET_ID_RE = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-][a-zA-Z0-9_./-]*$/;
2656
+ function is_valid_bucket_id(id) {
2657
+ if (!BUCKET_ID_RE.test(id)) return false;
2658
+ return !id.split("/").some((seg) => seg === "" || seg === "." || seg === "..");
2659
+ }
2660
+ function url(root, path, params) {
2661
+ const query = params ? `?${new URLSearchParams(params)}` : "";
2662
+ const base = root.replace(/\/+$/, "");
2663
+ if (base) return `${base}/gradio_api/run-history/${path}${query}`;
2664
+ if (typeof document !== "undefined" && document.baseURI) return new URL(`gradio_api/run-history/${path}${query}`, document.baseURI).toString();
2665
+ return `gradio_api/run-history/${path}${query}`;
2666
+ }
2667
+ async function parse_error(res) {
2668
+ try {
2669
+ const j = await res.json();
2670
+ return typeof j?.detail === "string" ? j.detail : `${res.status}`;
2671
+ } catch {
2672
+ return `${res.status}`;
2673
+ }
2674
+ }
2675
+ async function request(input, init, fallback, pick) {
2676
+ try {
2677
+ const res = await fetch(input, {
2678
+ credentials: "include",
2679
+ ...init
2680
+ });
2681
+ if (!res.ok) return {
2682
+ ok: false,
2683
+ status: res.status,
2684
+ data: fallback,
2685
+ detail: await parse_error(res)
2686
+ };
2687
+ return {
2688
+ ok: true,
2689
+ status: res.status,
2690
+ data: pick(await res.json())
2691
+ };
2692
+ } catch (e) {
2693
+ return {
2694
+ ok: false,
2695
+ status: 0,
2696
+ data: fallback,
2697
+ detail: String(e)
2698
+ };
2699
+ }
2700
+ }
2701
+ /**
2702
+ * Create the bucket if it does not exist and confirm it is writable. Stores
2703
+ * nothing server-side — the caller keeps its own choice and names it on every
2704
+ * later request.
2705
+ */
2706
+ async function connect_bucket(root, bucket_id) {
2707
+ if (!is_valid_bucket_id(bucket_id)) return {
2708
+ ok: false,
2709
+ status: 422,
2710
+ data: null,
2711
+ detail: "invalid bucket id"
2712
+ };
2713
+ return request(url(root, "connect"), {
2714
+ method: "POST",
2715
+ headers: { "Content-Type": "application/json" },
2716
+ body: JSON.stringify({ bucket_id })
2717
+ }, null, () => null);
2718
+ }
2719
+ async function list_user_buckets(root) {
2720
+ return request(url(root, "buckets"), {}, [], (b) => Array.isArray(b?.buckets) ? b.buckets : []);
2721
+ }
2722
+ async function list_bucket_records(root, bucket) {
2723
+ return request(url(root, "records", { bucket }), {}, [], (b) => Array.isArray(b?.records) ? b.records : []);
2724
+ }
2725
+ function asset_url(root, bucket, endpoint, record_id, filename) {
2726
+ return url(root, `records/${encodeURIComponent(endpoint)}/${encodeURIComponent(record_id)}/assets/${encodeURIComponent(filename)}`, { bucket });
2727
+ }
2728
+ //#endregion
2567
2729
  exports.Client = Client;
2568
2730
  exports.FileData = FileData;
2569
2731
  exports.MISSING_CREDENTIALS_MSG = MISSING_CREDENTIALS_MSG;
2732
+ exports.apply_run_history_replay = apply_run_history_replay;
2733
+ exports.asset_url = asset_url;
2570
2734
  exports.clear_run_history = clear_run_history;
2571
2735
  exports.client = client;
2736
+ exports.connect_bucket = connect_bucket;
2572
2737
  exports.consume_run_history_replay = consume_run_history_replay;
2573
2738
  exports.delete_run_history = delete_run_history;
2574
2739
  exports.duplicate = duplicate_space;
2575
2740
  exports.handle_file = handle_file;
2741
+ exports.is_valid_bucket_id = is_valid_bucket_id;
2742
+ exports.list_bucket_records = list_bucket_records;
2743
+ exports.list_user_buckets = list_user_buckets;
2576
2744
  exports.on_run_history_change = on_run_history_change;
2577
2745
  exports.predict = predict;
2578
2746
  exports.prepare_files = prepare_files;
2579
2747
  exports.read_run_history = read_run_history;
2748
+ exports.read_run_history_storage = read_run_history_storage;
2580
2749
  exports.run_history_url = run_history_url;
2750
+ exports.set_run_history_storage = set_run_history_storage;
2581
2751
  exports.stage_run_history_replay = stage_run_history_replay;
2582
2752
  exports.submit = submit;
2583
2753
  exports.upload = upload;
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ export { submit } from "./utils/submit";
4
4
  export { upload_files } from "./utils/upload_files";
5
5
  export { FileData, upload, prepare_files } from "./upload";
6
6
  export { handle_file } from "./helpers/data";
7
- export { clear_run_history, consume_run_history_replay, delete_run_history, on_run_history_change, read_run_history, run_history_url, stage_run_history_replay, type RunHistoryScope, type StoredRunComponent, type StoredRun } from "./utils/run_history";
7
+ export { apply_run_history_replay, clear_run_history, consume_run_history_replay, delete_run_history, on_run_history_change, read_run_history, read_run_history_storage, run_history_url, set_run_history_storage, stage_run_history_replay, type ReplayTarget, type RunHistoryStorage, type RunHistoryScope, type StoredRunComponent, type StoredRun } from "./utils/run_history";
8
+ export { asset_url, connect_bucket, is_valid_bucket_id, list_bucket_records, list_user_buckets, type HistoryRecord, type HistoryResult } from "./utils/bucket_sync";
8
9
  export type { SpaceStatus, StatusMessage, Status, client_return, UploadResponse, RenderMessage, LogMessage, Payload, Config, ValidationError } from "./types";
9
10
  export { MISSING_CREDENTIALS_MSG } from "./constants";
10
11
  export { client } from "./client";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACN,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACX,WAAW,EACX,aAAa,EACb,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,EACN,eAAe,EACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,wBAAwB,EACxB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACX,WAAW,EACX,aAAa,EACb,MAAM,EACN,aAAa,EACb,cAAc,EACd,aAAa,EACb,UAAU,EACV,OAAO,EACP,MAAM,EACN,eAAe,EACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAGtD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,eAAe,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -62,9 +62,11 @@ function map_names_to_ids(fns) {
62
62
  });
63
63
  return apis;
64
64
  }
65
- function resolve_config_root(root, current_location) {
66
- const root_url = new URL(root, current_location);
65
+ function resolve_config_root(root, current_location, prioritize_current_location = false) {
67
66
  const current_url = new URL(current_location);
67
+ const root_url = new URL(root, current_url);
68
+ const is_colab_runtime = root_url.hostname.endsWith(".colab-user-runtimes.internal") || root_url.hostname.endsWith(".codatalab-user-runtimes.internal");
69
+ if (prioritize_current_location || is_colab_runtime) return new URL(new URL(root, current_url).pathname, current_url).toString().replace(/\/$/, "");
68
70
  if (root_url.hostname !== current_url.hostname) return root;
69
71
  root_url.protocol = current_url.protocol;
70
72
  root_url.host = current_url.host;
@@ -87,7 +89,7 @@ async function resolve_config(endpoint, strip_current_page = true) {
87
89
  };
88
90
  }
89
91
  const config = { ...window.gradio_config };
90
- config.root = resolve_config_root(config.root, location.href);
92
+ config.root = resolve_config_root(config.root, location.href, config.is_colab);
91
93
  return config;
92
94
  } else if (endpoint) {
93
95
  let config_url = join_urls(endpoint, this.deep_link ? CONFIG_URL + "?deep_link=" + this.deep_link : CONFIG_URL);
@@ -609,10 +611,11 @@ async function upload(file_data, root_url, upload_id, max_file_size) {
609
611
  if (response.error) throw new Error(response.error);
610
612
  else {
611
613
  if (response.files) return response.files.map((f, i) => {
614
+ const encoded_path = f.split("/").map((segment) => encodeURIComponent(segment)).join("/");
612
615
  return new FileData({
613
616
  ...file_data[i],
614
617
  path: f,
615
- url: `${root_url}${this.api_prefix}/file=${f}`
618
+ url: `${root_url}${this.api_prefix}/file=${encoded_path}`
616
619
  });
617
620
  });
618
621
  return [];
@@ -1432,6 +1435,7 @@ function readable_stream(input, init = {}) {
1432
1435
  var KEY_ROOT = "gradio:run-history:";
1433
1436
  var STORAGE_PREFIX = `${KEY_ROOT}v2:`;
1434
1437
  var REPLAY_PREFIX = `${KEY_ROOT}replay:v2:`;
1438
+ var DESTINATION_PREFIX = `${KEY_ROOT}destination:v1:`;
1435
1439
  var MAX_RUNS = 100;
1436
1440
  var MAX_APPS = 8;
1437
1441
  /**
@@ -1469,6 +1473,34 @@ function replay_key(scope) {
1469
1473
  const key = storage_key(scope);
1470
1474
  return key ? key.replace(STORAGE_PREFIX, REPLAY_PREFIX) : null;
1471
1475
  }
1476
+ function destination_key(scope) {
1477
+ const key = storage_key(scope);
1478
+ return key ? key.replace(STORAGE_PREFIX, DESTINATION_PREFIX) : null;
1479
+ }
1480
+ function read_run_history_storage_impl(scope) {
1481
+ const key = destination_key(scope);
1482
+ if (!key) return { type: "browser" };
1483
+ try {
1484
+ const value = JSON.parse(window.localStorage.getItem(key) || "null");
1485
+ if (typeof value?.bucket_id === "string") return value.type === "bucket" ? {
1486
+ type: "bucket",
1487
+ bucket_id: value.bucket_id
1488
+ } : {
1489
+ type: "browser",
1490
+ bucket_id: value.bucket_id
1491
+ };
1492
+ return { type: "browser" };
1493
+ } catch {
1494
+ return { type: "browser" };
1495
+ }
1496
+ }
1497
+ function set_run_history_storage_impl(scope, storage) {
1498
+ const key = destination_key(scope);
1499
+ if (!key) return;
1500
+ if (storage.type === "browser" && !storage.bucket_id) window.localStorage.removeItem(key);
1501
+ else window.localStorage.setItem(key, JSON.stringify(storage));
1502
+ notify_run_history_change();
1503
+ }
1472
1504
  /** When a run was most recently saved under a key, for deciding what to drop. */
1473
1505
  function last_saved_at(key) {
1474
1506
  try {
@@ -1485,7 +1517,7 @@ function last_saved_at(key) {
1485
1517
  */
1486
1518
  function prune_apps(current_key) {
1487
1519
  const keys = Object.keys(window.localStorage).filter((key) => key.startsWith(KEY_ROOT));
1488
- const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
1520
+ const stale = [...keys.filter((key) => !key.startsWith(STORAGE_PREFIX) && !key.startsWith(REPLAY_PREFIX) && !key.startsWith(DESTINATION_PREFIX)), ...keys.filter((key) => key.startsWith(STORAGE_PREFIX) && key !== current_key).sort((a, b) => last_saved_at(b) - last_saved_at(a)).slice(MAX_APPS - 1)];
1489
1521
  for (const key of stale) try {
1490
1522
  window.localStorage.removeItem(key);
1491
1523
  window.sessionStorage.removeItem(key.replace(STORAGE_PREFIX, REPLAY_PREFIX));
@@ -1593,7 +1625,29 @@ function consume_run_history_replay_impl(scope) {
1593
1625
  return null;
1594
1626
  }
1595
1627
  }
1628
+ function restore_run_impl(config, run) {
1629
+ const dependency = config.dependencies.find((item) => item.id === run.fn_index || typeof item.api_name === "string" && `/${item.api_name.replace(/^\//, "")}` === run.api_name);
1630
+ if (!dependency) return false;
1631
+ const inputs = Array.isArray(run.inputs) ? run.inputs : Object.values(run.inputs ?? {});
1632
+ const outputs = Array.isArray(run.outputs) ? run.outputs : run.outputs === null || run.outputs === void 0 ? [] : [run.outputs];
1633
+ const restore = (ids, saved) => {
1634
+ for (const [index, id] of ids.entries()) {
1635
+ const component = config.components.find((item) => item.id === id);
1636
+ if (!component || index >= saved.length) continue;
1637
+ if (component.type === "state") continue;
1638
+ component.props.value = saved[index];
1639
+ }
1640
+ };
1641
+ restore(dependency.inputs, inputs);
1642
+ restore(dependency.outputs, outputs);
1643
+ return true;
1644
+ }
1645
+ function apply_run_history_replay_impl(config) {
1646
+ const run = consume_run_history_replay_impl(config);
1647
+ return run ? restore_run_impl(config, run) : false;
1648
+ }
1596
1649
  function start_run_history_impl(options) {
1650
+ if (read_run_history_storage_impl(options).type === "bucket") return null;
1597
1651
  const key = storage_key(options);
1598
1652
  if (!key) return null;
1599
1653
  prune_apps(key);
@@ -1673,6 +1727,12 @@ function mark_complete(run, event) {
1673
1727
  function read_run_history(scope) {
1674
1728
  return safely(() => read_run_history_impl(scope), []);
1675
1729
  }
1730
+ function read_run_history_storage(scope) {
1731
+ return safely(() => read_run_history_storage_impl(scope), { type: "browser" });
1732
+ }
1733
+ function set_run_history_storage(scope, storage) {
1734
+ safely(() => set_run_history_storage_impl(scope, storage), void 0);
1735
+ }
1676
1736
  function clear_run_history(scope) {
1677
1737
  safely(() => clear_run_history_impl(scope), void 0);
1678
1738
  }
@@ -1685,6 +1745,16 @@ function stage_run_history_replay(scope, run) {
1685
1745
  function consume_run_history_replay(scope) {
1686
1746
  return safely(() => consume_run_history_replay_impl(scope), null);
1687
1747
  }
1748
+ /**
1749
+ * Applies the run staged by the history page, if this page load is the one it
1750
+ * was staged for. Every entry point that renders an app has to call this, or
1751
+ * "Load run" silently does nothing on that entry point.
1752
+ *
1753
+ * @returns whether a staged run was found and applied.
1754
+ */
1755
+ function apply_run_history_replay(config) {
1756
+ return safely(() => apply_run_history_replay_impl(config), false);
1757
+ }
1688
1758
  function start_run_history(options) {
1689
1759
  return safely(() => start_run_history_impl(options), null);
1690
1760
  }
@@ -1703,7 +1773,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1703
1773
  try {
1704
1774
  const { token } = this.options;
1705
1775
  const { fetch, app_reference, config, session_hash, api_info, api_map, stream_status, pending_stream_messages, pending_diff_streams, event_callbacks, unclosed_events, post_data, options, api_prefix } = this;
1706
- const addt_headers = additional_headers || { "x-gradio-user": "api" };
1776
+ const base_headers = additional_headers || { "x-gradio-user": "api" };
1707
1777
  const that = this;
1708
1778
  if (!api_info) throw new Error(NO_API_INFO_MSG);
1709
1779
  if (!config) throw new Error("Could not resolve app config");
@@ -1728,6 +1798,11 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1728
1798
  app_id: config.app_id,
1729
1799
  username: config.username
1730
1800
  };
1801
+ const history_storage = read_run_history_storage(history_scope);
1802
+ const addt_headers = {
1803
+ ...base_headers,
1804
+ ...history_enabled && history_storage.type === "bucket" ? { "x-gradio-history-bucket": history_storage.bucket_id } : {}
1805
+ };
1731
1806
  const history_run_id = !history_enabled || !is_documented_endpoint ? null : start_run_history({
1732
1807
  ...history_scope,
1733
1808
  endpoint: history_endpoint,
@@ -1901,7 +1976,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1901
1976
  ...payload,
1902
1977
  session_hash,
1903
1978
  event_id
1904
- });
1979
+ }, addt_headers);
1905
1980
  if (status !== 200) {
1906
1981
  fire_event({
1907
1982
  type: "status",
@@ -2563,4 +2638,91 @@ async function duplicate_space(app_reference, options) {
2563
2638
  return await Client.duplicate(app_reference, options);
2564
2639
  }
2565
2640
  //#endregion
2566
- export { Client, FileData, MISSING_CREDENTIALS_MSG, clear_run_history, client, consume_run_history_replay, delete_run_history, duplicate_space as duplicate, handle_file, on_run_history_change, predict, prepare_files, read_run_history, run_history_url, stage_run_history_replay, submit, upload, upload_files };
2641
+ //#region src/utils/bucket_sync.ts
2642
+ /**
2643
+ * Client for the durable run history in an HF Hub bucket
2644
+ * (`/gradio_api/run-history/*`).
2645
+ *
2646
+ * Read-only by design. Records are written by the server from the run it
2647
+ * actually executed — there is no push function here, and nothing in this
2648
+ * module can create a record.
2649
+ *
2650
+ * Every call names the bucket it is talking about. The server holds no
2651
+ * per-session binding, so two tabs (or two apps on one origin) cannot end up
2652
+ * reading each other's history.
2653
+ */
2654
+ var BUCKET_ID_RE = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-][a-zA-Z0-9_./-]*$/;
2655
+ function is_valid_bucket_id(id) {
2656
+ if (!BUCKET_ID_RE.test(id)) return false;
2657
+ return !id.split("/").some((seg) => seg === "" || seg === "." || seg === "..");
2658
+ }
2659
+ function url(root, path, params) {
2660
+ const query = params ? `?${new URLSearchParams(params)}` : "";
2661
+ const base = root.replace(/\/+$/, "");
2662
+ if (base) return `${base}/gradio_api/run-history/${path}${query}`;
2663
+ if (typeof document !== "undefined" && document.baseURI) return new URL(`gradio_api/run-history/${path}${query}`, document.baseURI).toString();
2664
+ return `gradio_api/run-history/${path}${query}`;
2665
+ }
2666
+ async function parse_error(res) {
2667
+ try {
2668
+ const j = await res.json();
2669
+ return typeof j?.detail === "string" ? j.detail : `${res.status}`;
2670
+ } catch {
2671
+ return `${res.status}`;
2672
+ }
2673
+ }
2674
+ async function request(input, init, fallback, pick) {
2675
+ try {
2676
+ const res = await fetch(input, {
2677
+ credentials: "include",
2678
+ ...init
2679
+ });
2680
+ if (!res.ok) return {
2681
+ ok: false,
2682
+ status: res.status,
2683
+ data: fallback,
2684
+ detail: await parse_error(res)
2685
+ };
2686
+ return {
2687
+ ok: true,
2688
+ status: res.status,
2689
+ data: pick(await res.json())
2690
+ };
2691
+ } catch (e) {
2692
+ return {
2693
+ ok: false,
2694
+ status: 0,
2695
+ data: fallback,
2696
+ detail: String(e)
2697
+ };
2698
+ }
2699
+ }
2700
+ /**
2701
+ * Create the bucket if it does not exist and confirm it is writable. Stores
2702
+ * nothing server-side — the caller keeps its own choice and names it on every
2703
+ * later request.
2704
+ */
2705
+ async function connect_bucket(root, bucket_id) {
2706
+ if (!is_valid_bucket_id(bucket_id)) return {
2707
+ ok: false,
2708
+ status: 422,
2709
+ data: null,
2710
+ detail: "invalid bucket id"
2711
+ };
2712
+ return request(url(root, "connect"), {
2713
+ method: "POST",
2714
+ headers: { "Content-Type": "application/json" },
2715
+ body: JSON.stringify({ bucket_id })
2716
+ }, null, () => null);
2717
+ }
2718
+ async function list_user_buckets(root) {
2719
+ return request(url(root, "buckets"), {}, [], (b) => Array.isArray(b?.buckets) ? b.buckets : []);
2720
+ }
2721
+ async function list_bucket_records(root, bucket) {
2722
+ return request(url(root, "records", { bucket }), {}, [], (b) => Array.isArray(b?.records) ? b.records : []);
2723
+ }
2724
+ function asset_url(root, bucket, endpoint, record_id, filename) {
2725
+ return url(root, `records/${encodeURIComponent(endpoint)}/${encodeURIComponent(record_id)}/assets/${encodeURIComponent(filename)}`, { bucket });
2726
+ }
2727
+ //#endregion
2728
+ export { Client, FileData, MISSING_CREDENTIALS_MSG, apply_run_history_replay, asset_url, clear_run_history, client, connect_bucket, consume_run_history_replay, delete_run_history, duplicate_space as duplicate, handle_file, is_valid_bucket_id, list_bucket_records, list_user_buckets, on_run_history_change, predict, prepare_files, read_run_history, read_run_history_storage, run_history_url, set_run_history_storage, stage_run_history_replay, submit, upload, upload_files };