cp500 commited on
Commit
5505540
·
verified ·
1 Parent(s): 56fcc3f

Upload js/src/hub.ts with huggingface_hub

Browse files
Files changed (1) hide show
  1. js/src/hub.ts +76 -0
js/src/hub.ts ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Hugging Face Hub fetcher with browser caching.
3
+ *
4
+ * We don't pull in @huggingface/hub: it's a heavy dep with a lot of
5
+ * upload-side machinery we don't need for a read-only inference
6
+ * client. The hub URL pattern is stable enough to inline.
7
+ *
8
+ * URL pattern:
9
+ * https://huggingface.co/<repo>/resolve/<revision>/<filename>
10
+ *
11
+ * The ``main`` revision is fine for everyone except library authors;
12
+ * pin to a commit SHA for reproducibility once the model lands.
13
+ */
14
+
15
+ const HF_BASE = 'https://huggingface.co';
16
+
17
+ export interface HubFile {
18
+ /** Repo identifier, e.g. ``cp500/infon-coref-pointer``. */
19
+ repo: string;
20
+ /** Path inside the repo, e.g. ``onnx/backbone_bio_fp16.onnx``. */
21
+ path: string;
22
+ /** Branch, tag, or commit SHA. */
23
+ revision?: string;
24
+ }
25
+
26
+ /** Build a downloadable URL for a file in an HF repo. */
27
+ export function hubUrl({ repo, path, revision = 'main' }: HubFile): string {
28
+ return `${HF_BASE}/${repo}/resolve/${revision}/${path}`;
29
+ }
30
+
31
+ /**
32
+ * Fetch a file from the Hub as an ``ArrayBuffer``.
33
+ *
34
+ * Browsers automatically cache by URL via the HTTP cache, so repeated
35
+ * loads in the same session reuse the disk copy. For longer-term
36
+ * caching we use ``caches.open`` (Cache API) when available — that
37
+ * survives reloads and works offline.
38
+ */
39
+ export async function fetchHubFile(
40
+ file: HubFile,
41
+ opts?: { cacheName?: string },
42
+ ): Promise<ArrayBuffer> {
43
+ const url = hubUrl(file);
44
+ const cacheName = opts?.cacheName ?? 'infon-coref-v1';
45
+
46
+ // Browser Cache API path.
47
+ if (typeof caches !== 'undefined') {
48
+ try {
49
+ const cache = await caches.open(cacheName);
50
+ const cached = await cache.match(url);
51
+ if (cached) return await cached.arrayBuffer();
52
+ const r = await fetch(url);
53
+ if (!r.ok) throw new Error(`hub fetch ${url}: ${r.status}`);
54
+ // Clone before consuming so we can stash it in the cache.
55
+ cache.put(url, r.clone()).catch(() => {
56
+ /* cache failures are non-fatal */
57
+ });
58
+ return await r.arrayBuffer();
59
+ } catch (err) {
60
+ // Cache API exists but write failed (e.g. quota). Fall through
61
+ // to plain fetch.
62
+ if (!(err instanceof TypeError)) throw err;
63
+ }
64
+ }
65
+
66
+ // Plain fetch (Node 18+ has it; older Node needs polyfill).
67
+ const r = await fetch(url);
68
+ if (!r.ok) throw new Error(`hub fetch ${url}: ${r.status}`);
69
+ return await r.arrayBuffer();
70
+ }
71
+
72
+ /** Fetch a file as JSON. */
73
+ export async function fetchHubJson<T = unknown>(file: HubFile): Promise<T> {
74
+ const buf = await fetchHubFile(file);
75
+ return JSON.parse(new TextDecoder().decode(buf)) as T;
76
+ }