@gradio/client 2.5.1 → 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));
@@ -1616,6 +1648,7 @@ function apply_run_history_replay_impl(config) {
1616
1648
  return run ? restore_run_impl(config, run) : false;
1617
1649
  }
1618
1650
  function start_run_history_impl(options) {
1651
+ if (read_run_history_storage_impl(options).type === "bucket") return null;
1619
1652
  const key = storage_key(options);
1620
1653
  if (!key) return null;
1621
1654
  prune_apps(key);
@@ -1695,6 +1728,12 @@ function mark_complete(run, event) {
1695
1728
  function read_run_history(scope) {
1696
1729
  return safely(() => read_run_history_impl(scope), []);
1697
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
+ }
1698
1737
  function clear_run_history(scope) {
1699
1738
  safely(() => clear_run_history_impl(scope), void 0);
1700
1739
  }
@@ -1735,7 +1774,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1735
1774
  try {
1736
1775
  const { token } = this.options;
1737
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;
1738
- const addt_headers = additional_headers || { "x-gradio-user": "api" };
1777
+ const base_headers = additional_headers || { "x-gradio-user": "api" };
1739
1778
  const that = this;
1740
1779
  if (!api_info) throw new Error(NO_API_INFO_MSG);
1741
1780
  if (!config) throw new Error("Could not resolve app config");
@@ -1760,6 +1799,11 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1760
1799
  app_id: config.app_id,
1761
1800
  username: config.username
1762
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
+ };
1763
1807
  const history_run_id = !history_enabled || !is_documented_endpoint ? null : start_run_history({
1764
1808
  ...history_scope,
1765
1809
  endpoint: history_endpoint,
@@ -1933,7 +1977,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1933
1977
  ...payload,
1934
1978
  session_hash,
1935
1979
  event_id
1936
- });
1980
+ }, addt_headers);
1937
1981
  if (status !== 200) {
1938
1982
  fire_event({
1939
1983
  type: "status",
@@ -2595,21 +2639,115 @@ async function duplicate_space(app_reference, options) {
2595
2639
  return await Client.duplicate(app_reference, options);
2596
2640
  }
2597
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
2598
2729
  exports.Client = Client;
2599
2730
  exports.FileData = FileData;
2600
2731
  exports.MISSING_CREDENTIALS_MSG = MISSING_CREDENTIALS_MSG;
2601
2732
  exports.apply_run_history_replay = apply_run_history_replay;
2733
+ exports.asset_url = asset_url;
2602
2734
  exports.clear_run_history = clear_run_history;
2603
2735
  exports.client = client;
2736
+ exports.connect_bucket = connect_bucket;
2604
2737
  exports.consume_run_history_replay = consume_run_history_replay;
2605
2738
  exports.delete_run_history = delete_run_history;
2606
2739
  exports.duplicate = duplicate_space;
2607
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;
2608
2744
  exports.on_run_history_change = on_run_history_change;
2609
2745
  exports.predict = predict;
2610
2746
  exports.prepare_files = prepare_files;
2611
2747
  exports.read_run_history = read_run_history;
2748
+ exports.read_run_history_storage = read_run_history_storage;
2612
2749
  exports.run_history_url = run_history_url;
2750
+ exports.set_run_history_storage = set_run_history_storage;
2613
2751
  exports.stage_run_history_replay = stage_run_history_replay;
2614
2752
  exports.submit = submit;
2615
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 { apply_run_history_replay, 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 ReplayTarget, 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,wBAAwB,EACxB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,wBAAwB,EACxB,KAAK,YAAY,EACjB,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));
@@ -1615,6 +1647,7 @@ function apply_run_history_replay_impl(config) {
1615
1647
  return run ? restore_run_impl(config, run) : false;
1616
1648
  }
1617
1649
  function start_run_history_impl(options) {
1650
+ if (read_run_history_storage_impl(options).type === "bucket") return null;
1618
1651
  const key = storage_key(options);
1619
1652
  if (!key) return null;
1620
1653
  prune_apps(key);
@@ -1694,6 +1727,12 @@ function mark_complete(run, event) {
1694
1727
  function read_run_history(scope) {
1695
1728
  return safely(() => read_run_history_impl(scope), []);
1696
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
+ }
1697
1736
  function clear_run_history(scope) {
1698
1737
  safely(() => clear_run_history_impl(scope), void 0);
1699
1738
  }
@@ -1734,7 +1773,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1734
1773
  try {
1735
1774
  const { token } = this.options;
1736
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;
1737
- const addt_headers = additional_headers || { "x-gradio-user": "api" };
1776
+ const base_headers = additional_headers || { "x-gradio-user": "api" };
1738
1777
  const that = this;
1739
1778
  if (!api_info) throw new Error(NO_API_INFO_MSG);
1740
1779
  if (!config) throw new Error("Could not resolve app config");
@@ -1759,6 +1798,11 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1759
1798
  app_id: config.app_id,
1760
1799
  username: config.username
1761
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
+ };
1762
1806
  const history_run_id = !history_enabled || !is_documented_endpoint ? null : start_run_history({
1763
1807
  ...history_scope,
1764
1808
  endpoint: history_endpoint,
@@ -1932,7 +1976,7 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1932
1976
  ...payload,
1933
1977
  session_hash,
1934
1978
  event_id
1935
- });
1979
+ }, addt_headers);
1936
1980
  if (status !== 200) {
1937
1981
  fire_event({
1938
1982
  type: "status",
@@ -2594,4 +2638,91 @@ async function duplicate_space(app_reference, options) {
2594
2638
  return await Client.duplicate(app_reference, options);
2595
2639
  }
2596
2640
  //#endregion
2597
- export { Client, FileData, MISSING_CREDENTIALS_MSG, apply_run_history_replay, 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 };