@runappsai/sdk 0.7.9 → 0.8.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.
- package/README.md +7 -3
- package/dist/client.d.ts +7 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -2
- package/dist/client.js.map +1 -1
- package/dist/files.d.ts +22 -2
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +62 -15
- package/dist/files.js.map +1 -1
- package/dist/sdk.umd.js +3 -3
- package/dist/sdk.umd.js.map +1 -1
- package/dist/transport.d.ts +7 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +19 -2
- package/dist/transport.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +9 -2
- package/src/files.ts +60 -17
- package/src/transport.ts +19 -2
package/dist/transport.d.ts
CHANGED
|
@@ -40,6 +40,13 @@ export declare class Transport {
|
|
|
40
40
|
private readonly onUnauthorized;
|
|
41
41
|
private readonly fetchImpl;
|
|
42
42
|
constructor(opts: TransportOptions);
|
|
43
|
+
/** Absolute URLs pass through; paths are joined to the base. The files
|
|
44
|
+
* service uses this to send file calls to the files host. */
|
|
45
|
+
private resolve;
|
|
46
|
+
/** A short, non-secret fingerprint of the current token, so a service
|
|
47
|
+
* can notice that the signed-in user changed and drop per-user state
|
|
48
|
+
* (the files base is derived from the user). */
|
|
49
|
+
tokenFingerprint(): Promise<string>;
|
|
43
50
|
/** Resolve the bearer token for the next request. */
|
|
44
51
|
private resolveToken;
|
|
45
52
|
/** The current bearer token, for connections fetch can't make (WebSocket). */
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/dist/transport.js
CHANGED
|
@@ -21,6 +21,23 @@ export class Transport {
|
|
|
21
21
|
// for any binding their wrapper needs.
|
|
22
22
|
this.fetchImpl = opts.fetchImpl ?? fetch.bind(globalThis);
|
|
23
23
|
}
|
|
24
|
+
/** Absolute URLs pass through; paths are joined to the base. The files
|
|
25
|
+
* service uses this to send file calls to the files host. */
|
|
26
|
+
resolve(path) {
|
|
27
|
+
return /^https?:\/\//i.test(path) ? path : this.baseURL + path;
|
|
28
|
+
}
|
|
29
|
+
/** A short, non-secret fingerprint of the current token, so a service
|
|
30
|
+
* can notice that the signed-in user changed and drop per-user state
|
|
31
|
+
* (the files base is derived from the user). */
|
|
32
|
+
async tokenFingerprint() {
|
|
33
|
+
const t = await this.resolveToken();
|
|
34
|
+
if (!t)
|
|
35
|
+
return "";
|
|
36
|
+
let h = 0;
|
|
37
|
+
for (let i = 0; i < t.length; i++)
|
|
38
|
+
h = (h * 31 + t.charCodeAt(i)) | 0;
|
|
39
|
+
return (h >>> 0).toString(36) + ":" + t.length;
|
|
40
|
+
}
|
|
24
41
|
/** Resolve the bearer token for the next request. */
|
|
25
42
|
async resolveToken() {
|
|
26
43
|
if (this.apiKeyResolver)
|
|
@@ -40,7 +57,7 @@ export class Transport {
|
|
|
40
57
|
* `onUnauthorized` is absent or already retried.
|
|
41
58
|
*/
|
|
42
59
|
async fetchWithAuthRetry(path, build) {
|
|
43
|
-
const url = this.
|
|
60
|
+
const url = this.resolve(path);
|
|
44
61
|
let resp = await this.fetchImpl(url, await this.buildInit(build));
|
|
45
62
|
if (resp.status !== 401 || !this.onUnauthorized)
|
|
46
63
|
return resp;
|
|
@@ -100,7 +117,7 @@ export class Transport {
|
|
|
100
117
|
* token — in browser sign-in mode that would send a signed-out user to
|
|
101
118
|
* the sign-in page just to read the model catalogue. */
|
|
102
119
|
async getPublicJSON(path, init) {
|
|
103
|
-
const resp = await this.fetchImpl(this.
|
|
120
|
+
const resp = await this.fetchImpl(this.resolve(path), {
|
|
104
121
|
method: "GET",
|
|
105
122
|
cache: "no-store",
|
|
106
123
|
...(init?.signal ? { signal: init.signal } : {}),
|
package/dist/transport.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAsCvC,MAAM,OAAO,SAAS;IACX,OAAO,CAAS;IACR,MAAM,CAAqB;IAC3B,cAAc,CAA+C;IAC7D,cAAc,CAA2C;IACzD,SAAS,CAAe;IAEzC,YAAY,IAAsB;QAChC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,6DAA6D;QAC7D,6DAA6D;QAC7D,wDAAwD;QACxD,yDAAyD;QACzD,kEAAkE;QAClE,uCAAuC;QACvC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC5D,CAAC;IAED,qDAAqD;IAC7C,KAAK,CAAC,YAAY;QACxB,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,8EAA8E;IAC9E,WAAW;QACT,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,kBAAkB,CAC9B,IAAY,EACZ,KAAiC;QAEjC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -99,6 +99,13 @@ export interface ClientOptions {
|
|
|
99
99
|
* pair.
|
|
100
100
|
*/
|
|
101
101
|
project?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Where file calls go. By default the SDK asks the gateway for a
|
|
104
|
+
* per-user base on the files host (`https://files.runapps.ai/u/<hash>`)
|
|
105
|
+
* and falls back to the classic `/v1/files` paths on older gateways.
|
|
106
|
+
* `false` keeps the classic paths; a URL overrides the base.
|
|
107
|
+
*/
|
|
108
|
+
filesBase?: string | false;
|
|
102
109
|
/** Override the default base URL, `https://www.runapps.ai` (the
|
|
103
110
|
* platform: personal keys and app tokens are both accepted there). */
|
|
104
111
|
baseURL?: string;
|
|
@@ -260,7 +267,7 @@ export class RunApps {
|
|
|
260
267
|
// `project` also scopes the file URLs (/v1/p/<project>/files/...),
|
|
261
268
|
// so two apps never issue byte-identical file requests. Omitted →
|
|
262
269
|
// legacy unscoped /v1/files/... paths.
|
|
263
|
-
this.files = new FilesService(transport, options.project, this.events);
|
|
270
|
+
this.files = new FilesService(transport, options.project, this.events, options.filesBase);
|
|
264
271
|
this.embeddings = new EmbeddingsService(transport, this.events);
|
|
265
272
|
this.realtime = new RealtimeService(transport, this.events);
|
|
266
273
|
|
|
@@ -274,7 +281,7 @@ export class RunApps {
|
|
|
274
281
|
{
|
|
275
282
|
// Its own file service, without the event bus: sync traffic
|
|
276
283
|
// must not spin the badge every minute.
|
|
277
|
-
remote: new FilesRemote(new FilesService(transport, options.project)),
|
|
284
|
+
remote: new FilesRemote(new FilesService(transport, options.project, undefined, options.filesBase)),
|
|
278
285
|
events: this.events,
|
|
279
286
|
userId: () => auth.ownerId(),
|
|
280
287
|
onAuthChange: (cb) => auth.onTokenChange(() => cb()),
|
package/src/files.ts
CHANGED
|
@@ -118,7 +118,11 @@ export class FilesService {
|
|
|
118
118
|
* rejects a scope that disagrees with it, so this is a correctness
|
|
119
119
|
* measure, not a permission one.
|
|
120
120
|
*/
|
|
121
|
-
private readonly
|
|
121
|
+
private readonly legacyBase: string;
|
|
122
|
+
private readonly project: string | undefined;
|
|
123
|
+
private readonly filesBase: string | false | undefined;
|
|
124
|
+
private baseCache: { fp: string; base: string } | null = null;
|
|
125
|
+
private basePending: Promise<string> | null = null;
|
|
122
126
|
|
|
123
127
|
constructor(
|
|
124
128
|
private readonly transport: Transport,
|
|
@@ -127,12 +131,51 @@ export class FilesService {
|
|
|
127
131
|
* badge can show it in flight; the sync engine's own file traffic
|
|
128
132
|
* uses a service without one. */
|
|
129
133
|
private readonly events?: SDKEvents,
|
|
134
|
+
/** `false`: stay on the classic /v1 paths; a string: use this as the
|
|
135
|
+
* per-user base instead of asking the gateway. */
|
|
136
|
+
filesBase?: string | false,
|
|
130
137
|
) {
|
|
131
|
-
this.
|
|
138
|
+
this.project = project;
|
|
139
|
+
this.filesBase = filesBase;
|
|
140
|
+
this.legacyBase = project
|
|
132
141
|
? "/v1/p/" + encodeURIComponent(project) + "/files"
|
|
133
142
|
: "/v1/files";
|
|
134
143
|
}
|
|
135
144
|
|
|
145
|
+
/**
|
|
146
|
+
* The URL prefix for file calls, resolved once per signed-in user.
|
|
147
|
+
*
|
|
148
|
+
* Newer gateways answer `GET /v1/files-base` with a per-user base on
|
|
149
|
+
* the files host — `https://files.runapps.ai/u/<hash>` — so every
|
|
150
|
+
* file URL is unique to its user as well as to its app, and file
|
|
151
|
+
* traffic leaves the main site. The `/files` or `/p/<app>/files` tail
|
|
152
|
+
* is appended here. A gateway without that endpoint, or a failure to
|
|
153
|
+
* reach it, falls back to the classic path on the main base. The
|
|
154
|
+
* result is cached against a fingerprint of the token: a different
|
|
155
|
+
* user signing in gets their own base.
|
|
156
|
+
*/
|
|
157
|
+
private async base(): Promise<string> {
|
|
158
|
+
if (this.filesBase === false) return this.legacyBase;
|
|
159
|
+
const tail = this.project ? "/p/" + encodeURIComponent(this.project) + "/files" : "/files";
|
|
160
|
+
if (typeof this.filesBase === "string") return this.filesBase.replace(/\/+$/, "") + tail;
|
|
161
|
+
const fp = await this.transport.tokenFingerprint();
|
|
162
|
+
if (this.baseCache && this.baseCache.fp === fp) return this.baseCache.base;
|
|
163
|
+
if (!this.basePending) {
|
|
164
|
+
this.basePending = (async () => {
|
|
165
|
+
let base = this.legacyBase;
|
|
166
|
+
try {
|
|
167
|
+
const r = await this.transport.getJSON<{ base?: string }>("/v1/files-base");
|
|
168
|
+
if (r && typeof r.base === "string" && /^https?:\/\//i.test(r.base)) base = r.base.replace(/\/+$/, "") + tail;
|
|
169
|
+
} catch {
|
|
170
|
+
// Older gateway or a transient failure: the classic path still works.
|
|
171
|
+
}
|
|
172
|
+
this.baseCache = { fp, base };
|
|
173
|
+
return base;
|
|
174
|
+
})().finally(() => { this.basePending = null; });
|
|
175
|
+
}
|
|
176
|
+
return this.basePending;
|
|
177
|
+
}
|
|
178
|
+
|
|
136
179
|
/** Run one file call, with badge events when the service has a bus. */
|
|
137
180
|
private run<T>(op: string, fn: () => Promise<T>): Promise<T> {
|
|
138
181
|
return this.events ? wrapEvents(this.events, { model: op, capability: "files" }, fn) : fn();
|
|
@@ -154,7 +197,7 @@ export class FilesService {
|
|
|
154
197
|
const headers: Record<string, string> = {};
|
|
155
198
|
if (opts?.ifNoneMatch) headers["If-None-Match"] = "*";
|
|
156
199
|
if (opts?.ifMatch) headers["If-Match"] = `"${cleanETag(opts.ifMatch)}"`;
|
|
157
|
-
return this.run("files.put", () => this.transport.putBytes<FileObject>(pathToURL(this.base, path), body, {
|
|
200
|
+
return this.run("files.put", async () => this.transport.putBytes<FileObject>(pathToURL(await this.base(), path), body, {
|
|
158
201
|
contentType: opts?.contentType,
|
|
159
202
|
headers: Object.keys(headers).length ? headers : undefined,
|
|
160
203
|
signal: opts?.signal,
|
|
@@ -193,7 +236,7 @@ export class FilesService {
|
|
|
193
236
|
}
|
|
194
237
|
|
|
195
238
|
private async readRaw(path: string, init?: { signal?: AbortSignal; ifNoneMatch?: string }): Promise<FileRead> {
|
|
196
|
-
const { data, contentType, etag, notModified } = await this.transport.getRaw(pathToURL(this.base, path), init);
|
|
239
|
+
const { data, contentType, etag, notModified } = await this.transport.getRaw(pathToURL(await this.base(), path), init);
|
|
197
240
|
return {
|
|
198
241
|
blob: new Blob([new Uint8Array(data)], { type: contentType || "application/octet-stream" }),
|
|
199
242
|
contentType,
|
|
@@ -227,7 +270,7 @@ export class FilesService {
|
|
|
227
270
|
|
|
228
271
|
/** Stat: HEAD-only object metadata. */
|
|
229
272
|
async stat(path: string, init?: { signal?: AbortSignal }): Promise<FileObject> {
|
|
230
|
-
const { status, headers } = await this.run("files.stat", () => this.transport.head(pathToURL(this.base, path), init));
|
|
273
|
+
const { status, headers } = await this.run("files.stat", async () => this.transport.head(pathToURL(await this.base(), path), init));
|
|
231
274
|
if (status === 404) {
|
|
232
275
|
throw Object.assign(new Error("not found"), { status: 404 });
|
|
233
276
|
}
|
|
@@ -246,13 +289,13 @@ export class FilesService {
|
|
|
246
289
|
|
|
247
290
|
/** Returns true iff the path resolves to an existing object. */
|
|
248
291
|
async exists(path: string, init?: { signal?: AbortSignal }): Promise<boolean> {
|
|
249
|
-
const { status } = await this.run("files.exists", () => this.transport.head(pathToURL(this.base, path), init));
|
|
292
|
+
const { status } = await this.run("files.exists", async () => this.transport.head(pathToURL(await this.base(), path), init));
|
|
250
293
|
return status >= 200 && status < 400;
|
|
251
294
|
}
|
|
252
295
|
|
|
253
296
|
/** Delete the object at `path`. Idempotent. */
|
|
254
297
|
async del(path: string, init?: { signal?: AbortSignal }): Promise<void> {
|
|
255
|
-
await this.run("files.del", () => this.transport.deletePath<{ ok: boolean }>(pathToURL(this.base, path), init));
|
|
298
|
+
await this.run("files.del", async () => this.transport.deletePath<{ ok: boolean }>(pathToURL(await this.base(), path), init));
|
|
256
299
|
}
|
|
257
300
|
|
|
258
301
|
/** List objects. Pass an empty / omitted prefix for the root. */
|
|
@@ -263,8 +306,8 @@ export class FilesService {
|
|
|
263
306
|
if (opts?.limit) params.set("limit", String(opts.limit));
|
|
264
307
|
if (opts?.glob) params.set("glob", opts.glob);
|
|
265
308
|
const qs = params.toString();
|
|
266
|
-
return this.run("files.list", () => this.transport.getJSON<FileListResult>(
|
|
267
|
-
this.base + (qs ? "?" + qs : ""),
|
|
309
|
+
return this.run("files.list", async () => this.transport.getJSON<FileListResult>(
|
|
310
|
+
(await this.base()) + (qs ? "?" + qs : ""),
|
|
268
311
|
opts?.signal ? { signal: opts.signal } : undefined,
|
|
269
312
|
));
|
|
270
313
|
}
|
|
@@ -283,8 +326,8 @@ export class FilesService {
|
|
|
283
326
|
opts: { prefix?: string; glob?: string },
|
|
284
327
|
init?: { signal?: AbortSignal },
|
|
285
328
|
): Promise<{ deleted: number }> {
|
|
286
|
-
return this.run("files.deleteMany", () => this.transport.postJSON<{ deleted: number }>(
|
|
287
|
-
this.base + "/delete",
|
|
329
|
+
return this.run("files.deleteMany", async () => this.transport.postJSON<{ deleted: number }>(
|
|
330
|
+
(await this.base()) + "/delete",
|
|
288
331
|
{ prefix: opts.prefix ?? "", glob: opts.glob ?? "" },
|
|
289
332
|
init,
|
|
290
333
|
));
|
|
@@ -292,12 +335,12 @@ export class FilesService {
|
|
|
292
335
|
|
|
293
336
|
/** Atomic rename (copy + delete server-side). */
|
|
294
337
|
async move(from: string, to: string, init?: { signal?: AbortSignal }): Promise<FileObject> {
|
|
295
|
-
return this.run("files.move", () => this.transport.postJSON<FileObject>(this.base + "/move", { from, to }, init));
|
|
338
|
+
return this.run("files.move", async () => this.transport.postJSON<FileObject>((await this.base()) + "/move", { from, to }, init));
|
|
296
339
|
}
|
|
297
340
|
|
|
298
341
|
/** Server-side copy. */
|
|
299
342
|
async copy(from: string, to: string, init?: { signal?: AbortSignal }): Promise<FileObject> {
|
|
300
|
-
return this.run("files.copy", () => this.transport.postJSON<FileObject>(this.base + "/copy", { from, to }, init));
|
|
343
|
+
return this.run("files.copy", async () => this.transport.postJSON<FileObject>((await this.base()) + "/copy", { from, to }, init));
|
|
301
344
|
}
|
|
302
345
|
|
|
303
346
|
/**
|
|
@@ -310,8 +353,8 @@ export class FilesService {
|
|
|
310
353
|
srcURL: string,
|
|
311
354
|
opts?: PutFromURLOptions,
|
|
312
355
|
): Promise<FileObject> {
|
|
313
|
-
return this.run("files.putFromURL", () => this.transport.postJSON<FileObject>(
|
|
314
|
-
this.base + "/put-url",
|
|
356
|
+
return this.run("files.putFromURL", async () => this.transport.postJSON<FileObject>(
|
|
357
|
+
(await this.base()) + "/put-url",
|
|
315
358
|
{
|
|
316
359
|
path,
|
|
317
360
|
src_url: srcURL,
|
|
@@ -347,7 +390,7 @@ export class FilesService {
|
|
|
347
390
|
const chunkSize = 30;
|
|
348
391
|
if (ops.length <= chunkSize) {
|
|
349
392
|
const resp = await this.transport.postJSON<{ results: BatchResult[] }>(
|
|
350
|
-
this.base + "/batch",
|
|
393
|
+
(await this.base()) + "/batch",
|
|
351
394
|
{ ops },
|
|
352
395
|
init,
|
|
353
396
|
);
|
|
@@ -357,7 +400,7 @@ export class FilesService {
|
|
|
357
400
|
for (let i = 0; i < ops.length; i += chunkSize) {
|
|
358
401
|
const chunk = ops.slice(i, i + chunkSize);
|
|
359
402
|
const resp = await this.transport.postJSON<{ results: BatchResult[] }>(
|
|
360
|
-
this.base + "/batch",
|
|
403
|
+
(await this.base()) + "/batch",
|
|
361
404
|
{ ops: chunk },
|
|
362
405
|
init,
|
|
363
406
|
);
|
package/src/transport.ts
CHANGED
|
@@ -62,6 +62,23 @@ export class Transport {
|
|
|
62
62
|
this.fetchImpl = opts.fetchImpl ?? fetch.bind(globalThis);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
/** Absolute URLs pass through; paths are joined to the base. The files
|
|
66
|
+
* service uses this to send file calls to the files host. */
|
|
67
|
+
private resolve(path: string): string {
|
|
68
|
+
return /^https?:\/\//i.test(path) ? path : this.baseURL + path;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A short, non-secret fingerprint of the current token, so a service
|
|
72
|
+
* can notice that the signed-in user changed and drop per-user state
|
|
73
|
+
* (the files base is derived from the user). */
|
|
74
|
+
async tokenFingerprint(): Promise<string> {
|
|
75
|
+
const t = await this.resolveToken();
|
|
76
|
+
if (!t) return "";
|
|
77
|
+
let h = 0;
|
|
78
|
+
for (let i = 0; i < t.length; i++) h = (h * 31 + t.charCodeAt(i)) | 0;
|
|
79
|
+
return (h >>> 0).toString(36) + ":" + t.length;
|
|
80
|
+
}
|
|
81
|
+
|
|
65
82
|
/** Resolve the bearer token for the next request. */
|
|
66
83
|
private async resolveToken(): Promise<string> {
|
|
67
84
|
if (this.apiKeyResolver) return await this.apiKeyResolver();
|
|
@@ -85,7 +102,7 @@ export class Transport {
|
|
|
85
102
|
path: string,
|
|
86
103
|
build: () => Promise<RequestInit>,
|
|
87
104
|
): Promise<Response> {
|
|
88
|
-
const url = this.
|
|
105
|
+
const url = this.resolve(path);
|
|
89
106
|
let resp = await this.fetchImpl(url, await this.buildInit(build));
|
|
90
107
|
if (resp.status !== 401 || !this.onUnauthorized) return resp;
|
|
91
108
|
try {
|
|
@@ -157,7 +174,7 @@ export class Transport {
|
|
|
157
174
|
path: string,
|
|
158
175
|
init?: { signal?: AbortSignal },
|
|
159
176
|
): Promise<T> {
|
|
160
|
-
const resp = await this.fetchImpl(this.
|
|
177
|
+
const resp = await this.fetchImpl(this.resolve(path), {
|
|
161
178
|
method: "GET",
|
|
162
179
|
cache: "no-store",
|
|
163
180
|
...(init?.signal ? { signal: init.signal } : {}),
|