@eyepop.ai/eyepop 0.9.1 → 0.9.2
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/dist/index.d.mts +41 -31
- package/dist/index.d.ts +41 -31
- package/dist/index.js +298 -84
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +297 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -8585,9 +8585,9 @@ var require_mime_types = __commonJS({
|
|
|
8585
8585
|
return false;
|
|
8586
8586
|
}
|
|
8587
8587
|
var match = EXTRACT_TYPE_REGEXP.exec(type);
|
|
8588
|
-
var
|
|
8589
|
-
if (
|
|
8590
|
-
return
|
|
8588
|
+
var mime = match && db[match[1].toLowerCase()];
|
|
8589
|
+
if (mime && mime.charset) {
|
|
8590
|
+
return mime.charset;
|
|
8591
8591
|
}
|
|
8592
8592
|
if (match && TEXT_TYPE_REGEXP.test(match[1])) {
|
|
8593
8593
|
return "UTF-8";
|
|
@@ -8598,16 +8598,16 @@ var require_mime_types = __commonJS({
|
|
|
8598
8598
|
if (!str || typeof str !== "string") {
|
|
8599
8599
|
return false;
|
|
8600
8600
|
}
|
|
8601
|
-
var
|
|
8602
|
-
if (!
|
|
8601
|
+
var mime = str.indexOf("/") === -1 ? exports.lookup(str) : str;
|
|
8602
|
+
if (!mime) {
|
|
8603
8603
|
return false;
|
|
8604
8604
|
}
|
|
8605
|
-
if (
|
|
8606
|
-
var charset2 = exports.charset(
|
|
8605
|
+
if (mime.indexOf("charset") === -1) {
|
|
8606
|
+
var charset2 = exports.charset(mime);
|
|
8607
8607
|
if (charset2)
|
|
8608
|
-
|
|
8608
|
+
mime += "; charset=" + charset2.toLowerCase();
|
|
8609
8609
|
}
|
|
8610
|
-
return
|
|
8610
|
+
return mime;
|
|
8611
8611
|
}
|
|
8612
8612
|
function extension(type) {
|
|
8613
8613
|
if (!type || typeof type !== "string") {
|
|
@@ -8633,8 +8633,8 @@ var require_mime_types = __commonJS({
|
|
|
8633
8633
|
function populateMaps(extensions, types) {
|
|
8634
8634
|
var preference = ["nginx", "apache", void 0, "iana"];
|
|
8635
8635
|
Object.keys(db).forEach(function forEachMimeType(type) {
|
|
8636
|
-
var
|
|
8637
|
-
var exts =
|
|
8636
|
+
var mime = db[type];
|
|
8637
|
+
var exts = mime.extensions;
|
|
8638
8638
|
if (!exts || !exts.length) {
|
|
8639
8639
|
return;
|
|
8640
8640
|
}
|
|
@@ -8643,7 +8643,7 @@ var require_mime_types = __commonJS({
|
|
|
8643
8643
|
var extension2 = exts[i];
|
|
8644
8644
|
if (types[extension2]) {
|
|
8645
8645
|
var from = preference.indexOf(db[types[extension2]].source);
|
|
8646
|
-
var to = preference.indexOf(
|
|
8646
|
+
var to = preference.indexOf(mime.source);
|
|
8647
8647
|
if (types[extension2] !== "application/octet-stream" && (from > to || from === to && types[extension2].substr(0, 12) === "application/")) {
|
|
8648
8648
|
continue;
|
|
8649
8649
|
}
|
|
@@ -8908,13 +8908,13 @@ function readableStreamAsyncIterable(stream) {
|
|
|
8908
8908
|
|
|
8909
8909
|
// src/jobs.ts
|
|
8910
8910
|
var _AbstractJob = class _AbstractJob {
|
|
8911
|
-
constructor(baseUrl, pipelineId, authorizationHeader,
|
|
8911
|
+
constructor(baseUrl, pipelineId, authorizationHeader, client, requestLogger) {
|
|
8912
8912
|
this._responseStream = null;
|
|
8913
8913
|
this._controller = new AbortController();
|
|
8914
8914
|
this._baseUrl = baseUrl.replace(/\/+$/, "");
|
|
8915
8915
|
this._pipelineId = pipelineId;
|
|
8916
8916
|
this._authorizationHeader = authorizationHeader;
|
|
8917
|
-
this.
|
|
8917
|
+
this._client = client;
|
|
8918
8918
|
this._requestLogger = requestLogger;
|
|
8919
8919
|
this.i = _AbstractJob.n++;
|
|
8920
8920
|
}
|
|
@@ -8924,19 +8924,19 @@ var _AbstractJob = class _AbstractJob {
|
|
|
8924
8924
|
}
|
|
8925
8925
|
return Stream.iterFromReadableStream(this._responseStream, this._controller);
|
|
8926
8926
|
}
|
|
8927
|
-
async
|
|
8927
|
+
async startJob() {
|
|
8928
8928
|
return Promise.reject("abstract class");
|
|
8929
8929
|
}
|
|
8930
8930
|
start(done) {
|
|
8931
|
-
this._responseStream = new Promise((
|
|
8932
|
-
const request = this.
|
|
8931
|
+
this._responseStream = new Promise((resolve2, reject) => {
|
|
8932
|
+
const request = this.startJob();
|
|
8933
8933
|
request.then((response) => {
|
|
8934
8934
|
if (response.status != 200) {
|
|
8935
8935
|
reject(`upload error ${response.status}: ${response.text()}`);
|
|
8936
8936
|
} else if (!response.body) {
|
|
8937
8937
|
reject(`response body is empty`);
|
|
8938
8938
|
} else {
|
|
8939
|
-
|
|
8939
|
+
resolve2(response.body);
|
|
8940
8940
|
}
|
|
8941
8941
|
}).catch((reason) => {
|
|
8942
8942
|
reject(reason);
|
|
@@ -8956,12 +8956,12 @@ var UploadJob = class extends AbstractJob {
|
|
|
8956
8956
|
get [Symbol.toStringTag]() {
|
|
8957
8957
|
return "uploadJob";
|
|
8958
8958
|
}
|
|
8959
|
-
constructor(stream, mimeType, baseUrl, pipelineId, authorizationHeader,
|
|
8960
|
-
super(baseUrl, pipelineId, authorizationHeader,
|
|
8959
|
+
constructor(stream, mimeType, baseUrl, pipelineId, authorizationHeader, client, requestLogger) {
|
|
8960
|
+
super(baseUrl, pipelineId, authorizationHeader, client, requestLogger);
|
|
8961
8961
|
this._uploadStream = stream;
|
|
8962
8962
|
this._mimeType = mimeType;
|
|
8963
8963
|
}
|
|
8964
|
-
async
|
|
8964
|
+
async startJob() {
|
|
8965
8965
|
const headers = {
|
|
8966
8966
|
"Authorization": this._authorizationHeader,
|
|
8967
8967
|
"Accept": "application/jsonl",
|
|
@@ -8969,7 +8969,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
8969
8969
|
};
|
|
8970
8970
|
const postUrl = `${this._baseUrl}/pipelines/${this._pipelineId}/source?mode=queue&processing=sync`;
|
|
8971
8971
|
this._requestLogger.debug("before POST %s with stream as body");
|
|
8972
|
-
const response = await fetch(postUrl, {
|
|
8972
|
+
const response = await this._client.fetch(postUrl, {
|
|
8973
8973
|
headers,
|
|
8974
8974
|
method: "POST",
|
|
8975
8975
|
body: this._uploadStream,
|
|
@@ -8983,14 +8983,14 @@ var UploadJob = class extends AbstractJob {
|
|
|
8983
8983
|
}
|
|
8984
8984
|
};
|
|
8985
8985
|
var LoadFromJob = class extends AbstractJob {
|
|
8986
|
-
constructor(location, baseUrl, pipelineId, authorizationHeader,
|
|
8987
|
-
super(baseUrl, pipelineId, authorizationHeader,
|
|
8986
|
+
constructor(location, baseUrl, pipelineId, authorizationHeader, client, requestLogger) {
|
|
8987
|
+
super(baseUrl, pipelineId, authorizationHeader, client, requestLogger);
|
|
8988
8988
|
this._location = location;
|
|
8989
8989
|
}
|
|
8990
8990
|
get [Symbol.toStringTag]() {
|
|
8991
8991
|
return "loadFromJob";
|
|
8992
8992
|
}
|
|
8993
|
-
async
|
|
8993
|
+
async startJob() {
|
|
8994
8994
|
const headers = {
|
|
8995
8995
|
"Authorization": this._authorizationHeader,
|
|
8996
8996
|
"Accept": "application/jsonl",
|
|
@@ -9002,7 +9002,7 @@ var LoadFromJob = class extends AbstractJob {
|
|
|
9002
9002
|
};
|
|
9003
9003
|
const postUrl = `${this._baseUrl}/pipelines/${this._pipelineId}/source?mode=queue&processing=sync`;
|
|
9004
9004
|
this._requestLogger.debug("before PATCH %s with url %s as source", postUrl, this._location);
|
|
9005
|
-
const response = await fetch(postUrl, {
|
|
9005
|
+
const response = await this._client.fetch(postUrl, {
|
|
9006
9006
|
headers,
|
|
9007
9007
|
method: "PATCH",
|
|
9008
9008
|
body: JSON.stringify(body),
|
|
@@ -9015,20 +9015,226 @@ var LoadFromJob = class extends AbstractJob {
|
|
|
9015
9015
|
}
|
|
9016
9016
|
};
|
|
9017
9017
|
|
|
9018
|
+
// src/shims/http_client.ts
|
|
9019
|
+
var createHttpClient;
|
|
9020
|
+
if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
9021
|
+
class HttpClient2 {
|
|
9022
|
+
constructor() {
|
|
9023
|
+
}
|
|
9024
|
+
async fetch(input, init) {
|
|
9025
|
+
return fetch(input, init);
|
|
9026
|
+
}
|
|
9027
|
+
async close() {
|
|
9028
|
+
}
|
|
9029
|
+
}
|
|
9030
|
+
createHttpClient = async () => {
|
|
9031
|
+
return new HttpClient2();
|
|
9032
|
+
};
|
|
9033
|
+
} else {
|
|
9034
|
+
class HttpClient2 {
|
|
9035
|
+
constructor(agent) {
|
|
9036
|
+
this.agent = agent;
|
|
9037
|
+
}
|
|
9038
|
+
async fetch(input, init) {
|
|
9039
|
+
init || (init = {});
|
|
9040
|
+
init.dispatcher = this.agent;
|
|
9041
|
+
return fetch(input, init);
|
|
9042
|
+
}
|
|
9043
|
+
async close() {
|
|
9044
|
+
return this.agent.close();
|
|
9045
|
+
}
|
|
9046
|
+
}
|
|
9047
|
+
createHttpClient = async () => {
|
|
9048
|
+
const undici = await import("undici");
|
|
9049
|
+
const agent = new undici.Agent({
|
|
9050
|
+
keepAliveTimeout: 1e4,
|
|
9051
|
+
connections: 5
|
|
9052
|
+
});
|
|
9053
|
+
return new HttpClient2(agent);
|
|
9054
|
+
};
|
|
9055
|
+
}
|
|
9056
|
+
|
|
9057
|
+
// src/semaphore.ts
|
|
9058
|
+
var Semaphore = class {
|
|
9059
|
+
/**
|
|
9060
|
+
* Creates a semaphore.
|
|
9061
|
+
* @param permits The number of permits, i.e. strands of execution being allowed
|
|
9062
|
+
* to run in parallel.
|
|
9063
|
+
* This number can be initialized with a negative integer.
|
|
9064
|
+
*/
|
|
9065
|
+
constructor(permits) {
|
|
9066
|
+
this.promiseResolverQueue = [];
|
|
9067
|
+
this.permits = permits;
|
|
9068
|
+
}
|
|
9069
|
+
/**
|
|
9070
|
+
* Returns the number of available permits.
|
|
9071
|
+
* @returns The number of available permits.
|
|
9072
|
+
*/
|
|
9073
|
+
getPermits() {
|
|
9074
|
+
return this.permits;
|
|
9075
|
+
}
|
|
9076
|
+
/**
|
|
9077
|
+
* Returns a promise used to wait for a permit to become available. This method should be awaited on.
|
|
9078
|
+
* @returns A promise that gets resolved when execution is allowed to proceed.
|
|
9079
|
+
*/
|
|
9080
|
+
async wait() {
|
|
9081
|
+
if (this.permits > 0) {
|
|
9082
|
+
this.permits -= 1;
|
|
9083
|
+
return Promise.resolve(true);
|
|
9084
|
+
}
|
|
9085
|
+
return new Promise((resolver) => this.promiseResolverQueue.push(resolver));
|
|
9086
|
+
}
|
|
9087
|
+
/**
|
|
9088
|
+
* Alias for {@linkcode Semaphore.wait}.
|
|
9089
|
+
* @returns A promise that gets resolved when execution is allowed to proceed.
|
|
9090
|
+
*/
|
|
9091
|
+
async acquire() {
|
|
9092
|
+
return this.wait();
|
|
9093
|
+
}
|
|
9094
|
+
/**
|
|
9095
|
+
* Same as {@linkcode Semaphore.wait} except the promise returned gets resolved with false if no
|
|
9096
|
+
* permit becomes available in time.
|
|
9097
|
+
* @param milliseconds The time spent waiting before the wait is aborted. This is a lower bound,
|
|
9098
|
+
* you shouldn't rely on it being precise.
|
|
9099
|
+
* @returns A promise that gets resolved to true when execution is allowed to proceed or
|
|
9100
|
+
* false if the time given elapses before a permit becomes available.
|
|
9101
|
+
*/
|
|
9102
|
+
async waitFor(milliseconds) {
|
|
9103
|
+
if (this.permits > 0) {
|
|
9104
|
+
this.permits -= 1;
|
|
9105
|
+
return Promise.resolve(true);
|
|
9106
|
+
}
|
|
9107
|
+
let resolver = (b) => void 0;
|
|
9108
|
+
const promise = new Promise((r) => {
|
|
9109
|
+
resolver = r;
|
|
9110
|
+
});
|
|
9111
|
+
this.promiseResolverQueue.push(resolver);
|
|
9112
|
+
setTimeout(() => {
|
|
9113
|
+
const index = this.promiseResolverQueue.indexOf(resolver);
|
|
9114
|
+
if (index !== -1) {
|
|
9115
|
+
this.promiseResolverQueue.splice(index, 1);
|
|
9116
|
+
} else {
|
|
9117
|
+
console.warn(`Semaphore.waitFor couldn't find its promise resolver in the queue`);
|
|
9118
|
+
}
|
|
9119
|
+
resolver(false);
|
|
9120
|
+
}, milliseconds);
|
|
9121
|
+
return promise;
|
|
9122
|
+
}
|
|
9123
|
+
/**
|
|
9124
|
+
* Synchronous function that tries to acquire a permit and returns true if successful, false otherwise.
|
|
9125
|
+
* @returns Whether a permit could be acquired.
|
|
9126
|
+
*/
|
|
9127
|
+
tryAcquire() {
|
|
9128
|
+
if (this.permits > 0) {
|
|
9129
|
+
this.permits -= 1;
|
|
9130
|
+
return true;
|
|
9131
|
+
}
|
|
9132
|
+
return false;
|
|
9133
|
+
}
|
|
9134
|
+
/**
|
|
9135
|
+
* Acquires all permits that are currently available and returns the number of acquired permits.
|
|
9136
|
+
* @returns Number of acquired permits.
|
|
9137
|
+
*/
|
|
9138
|
+
drainPermits() {
|
|
9139
|
+
if (this.permits > 0) {
|
|
9140
|
+
const permitCount = this.permits;
|
|
9141
|
+
this.permits = 0;
|
|
9142
|
+
return permitCount;
|
|
9143
|
+
}
|
|
9144
|
+
return 0;
|
|
9145
|
+
}
|
|
9146
|
+
/**
|
|
9147
|
+
* Increases the number of permits by one. If there are other functions waiting, one of them will
|
|
9148
|
+
* continue to execute in a future iteration of the event loop.
|
|
9149
|
+
*/
|
|
9150
|
+
signal() {
|
|
9151
|
+
this.permits += 1;
|
|
9152
|
+
if (this.permits > 1 && this.promiseResolverQueue.length > 0) {
|
|
9153
|
+
console.warn("Semaphore.permits should never be > 0 when there is someone waiting.");
|
|
9154
|
+
} else if (this.permits === 1 && this.promiseResolverQueue.length > 0) {
|
|
9155
|
+
this.permits -= 1;
|
|
9156
|
+
const nextResolver = this.promiseResolverQueue.shift();
|
|
9157
|
+
if (nextResolver) {
|
|
9158
|
+
nextResolver(true);
|
|
9159
|
+
}
|
|
9160
|
+
}
|
|
9161
|
+
}
|
|
9162
|
+
/**
|
|
9163
|
+
* Alias for {@linkcode Semaphore.signal}.
|
|
9164
|
+
*/
|
|
9165
|
+
release() {
|
|
9166
|
+
this.signal();
|
|
9167
|
+
}
|
|
9168
|
+
/**
|
|
9169
|
+
* Schedules func to be called once a permit becomes available.
|
|
9170
|
+
* Returns a promise that resolves to the return value of func.
|
|
9171
|
+
* @typeparam T The return type of func.
|
|
9172
|
+
* @param func The function to be executed.
|
|
9173
|
+
* @return A promise that gets resolved with the return value of the function.
|
|
9174
|
+
*/
|
|
9175
|
+
async execute(func) {
|
|
9176
|
+
await this.wait();
|
|
9177
|
+
try {
|
|
9178
|
+
return await func();
|
|
9179
|
+
} finally {
|
|
9180
|
+
this.signal();
|
|
9181
|
+
}
|
|
9182
|
+
}
|
|
9183
|
+
};
|
|
9184
|
+
|
|
9185
|
+
// src/shims/local_file.ts
|
|
9186
|
+
var resolve;
|
|
9187
|
+
if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
9188
|
+
const isFileLike = (value) => value != null && typeof value === "object" && typeof value.name === "string" && typeof value.lastModified === "number";
|
|
9189
|
+
resolve = async (params) => {
|
|
9190
|
+
if (params.file) {
|
|
9191
|
+
if (isFileLike(params.file)) {
|
|
9192
|
+
params = {
|
|
9193
|
+
mimeType: params.file.type,
|
|
9194
|
+
file: params.file
|
|
9195
|
+
};
|
|
9196
|
+
return params;
|
|
9197
|
+
}
|
|
9198
|
+
}
|
|
9199
|
+
throw new DOMException("resolving a path to a file is not supported in browser");
|
|
9200
|
+
};
|
|
9201
|
+
} else {
|
|
9202
|
+
resolve = async (params) => {
|
|
9203
|
+
if (params.file) {
|
|
9204
|
+
return params;
|
|
9205
|
+
}
|
|
9206
|
+
const mime = await Promise.resolve().then(() => __toESM(require_mime_types()));
|
|
9207
|
+
const fs = await import("fs");
|
|
9208
|
+
let mimeType;
|
|
9209
|
+
let stream;
|
|
9210
|
+
if (params.filePath) {
|
|
9211
|
+
if (params.mimeType) {
|
|
9212
|
+
mimeType = params.mimeType;
|
|
9213
|
+
} else {
|
|
9214
|
+
mimeType = mime.lookup(params.filePath) || void 0;
|
|
9215
|
+
}
|
|
9216
|
+
stream = fs.createReadStream(params.filePath);
|
|
9217
|
+
}
|
|
9218
|
+
params = {
|
|
9219
|
+
filePath: params.filePath,
|
|
9220
|
+
mimeType,
|
|
9221
|
+
file: stream
|
|
9222
|
+
};
|
|
9223
|
+
return params;
|
|
9224
|
+
};
|
|
9225
|
+
}
|
|
9226
|
+
|
|
9018
9227
|
// src/endpoint.ts
|
|
9019
|
-
var import_mime_types = __toESM(require_mime_types());
|
|
9020
|
-
import * as fs from "fs";
|
|
9021
|
-
import { Agent } from "undici";
|
|
9022
|
-
import { Semaphore } from "await-semaphore";
|
|
9023
9228
|
import { pino } from "pino";
|
|
9024
|
-
var
|
|
9229
|
+
var Endpoint = class {
|
|
9025
9230
|
constructor(options) {
|
|
9026
9231
|
this._options = options;
|
|
9027
9232
|
this._baseUrl = null;
|
|
9028
9233
|
this._pipelineId = null;
|
|
9234
|
+
this._popName = null;
|
|
9029
9235
|
this._token = null;
|
|
9030
9236
|
this._expire_token_time = null;
|
|
9031
|
-
this.
|
|
9237
|
+
this._client = null;
|
|
9032
9238
|
this._limit = null;
|
|
9033
9239
|
let rootLogger;
|
|
9034
9240
|
if (options.logger) {
|
|
@@ -9039,56 +9245,62 @@ var _Endpoint = class _Endpoint {
|
|
|
9039
9245
|
this._logger = rootLogger.child({ module: "eyepop" });
|
|
9040
9246
|
this._requestLogger = this._logger.child({ module: "requests" });
|
|
9041
9247
|
}
|
|
9248
|
+
popName() {
|
|
9249
|
+
return this._popName;
|
|
9250
|
+
}
|
|
9251
|
+
async session() {
|
|
9252
|
+
await this.currentAccessToken();
|
|
9253
|
+
if (this._token == null || this._expire_token_time == null) {
|
|
9254
|
+
return Promise.reject("endpoint not connected");
|
|
9255
|
+
}
|
|
9256
|
+
const token = {
|
|
9257
|
+
accessToken: this._token,
|
|
9258
|
+
validUntil: new Date(this._expire_token_time * 1e3)
|
|
9259
|
+
};
|
|
9260
|
+
return token;
|
|
9261
|
+
}
|
|
9042
9262
|
async upload(params) {
|
|
9043
|
-
if (!this._baseUrl || !this._pipelineId || !this.
|
|
9263
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
9044
9264
|
return Promise.reject("endpoint not connected, use open() before upload()");
|
|
9045
9265
|
}
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
if (params.filePath) {
|
|
9049
|
-
if (params.mimeType) {
|
|
9050
|
-
mimeType = params.mimeType;
|
|
9051
|
-
} else {
|
|
9052
|
-
mimeType = import_mime_types.default.lookup(params.filePath);
|
|
9053
|
-
}
|
|
9054
|
-
stream = fs.createReadStream(params.filePath);
|
|
9055
|
-
} else if (params.stream) {
|
|
9056
|
-
stream = params.stream;
|
|
9057
|
-
mimeType = params.mimeType;
|
|
9058
|
-
}
|
|
9059
|
-
if (!mimeType) {
|
|
9266
|
+
params = await resolve(params);
|
|
9267
|
+
if (!params.mimeType) {
|
|
9060
9268
|
return Promise.reject("upload for streams requires a mimeType");
|
|
9061
9269
|
}
|
|
9062
|
-
|
|
9270
|
+
await this._limit.acquire();
|
|
9063
9271
|
const job = new UploadJob(
|
|
9064
|
-
|
|
9065
|
-
mimeType,
|
|
9272
|
+
params.file,
|
|
9273
|
+
params.mimeType,
|
|
9066
9274
|
this._baseUrl,
|
|
9067
9275
|
this._pipelineId,
|
|
9068
9276
|
await this.authorizationHeader(),
|
|
9069
|
-
this.
|
|
9277
|
+
this._client,
|
|
9070
9278
|
this._requestLogger
|
|
9071
9279
|
);
|
|
9072
|
-
return job.start(
|
|
9280
|
+
return job.start(() => {
|
|
9281
|
+
this._limit?.release();
|
|
9282
|
+
});
|
|
9073
9283
|
}
|
|
9074
9284
|
async loadFrom(location) {
|
|
9075
|
-
if (!this._baseUrl || !this._pipelineId || !this.
|
|
9285
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
9076
9286
|
throw new Error("endpoint not connected, use open() before loadFrom()");
|
|
9077
9287
|
}
|
|
9078
|
-
|
|
9288
|
+
await this._limit.acquire();
|
|
9079
9289
|
const job = new LoadFromJob(
|
|
9080
9290
|
location,
|
|
9081
9291
|
this._baseUrl,
|
|
9082
9292
|
this._pipelineId,
|
|
9083
9293
|
await this.authorizationHeader(),
|
|
9084
|
-
this.
|
|
9294
|
+
this._client,
|
|
9085
9295
|
this._requestLogger
|
|
9086
9296
|
);
|
|
9087
|
-
return job.start(
|
|
9297
|
+
return job.start(() => {
|
|
9298
|
+
this._limit?.release();
|
|
9299
|
+
});
|
|
9088
9300
|
}
|
|
9089
9301
|
// noinspection TypeScriptValidateTypes
|
|
9090
9302
|
async connect() {
|
|
9091
|
-
if (this.
|
|
9303
|
+
if (this._client) {
|
|
9092
9304
|
console.info("endpoint already connected");
|
|
9093
9305
|
return this;
|
|
9094
9306
|
}
|
|
@@ -9098,33 +9310,31 @@ var _Endpoint = class _Endpoint {
|
|
|
9098
9310
|
if (!this._options.popId) {
|
|
9099
9311
|
return Promise.reject("option popId or environment variable EYEPOP_POP_ID is required");
|
|
9100
9312
|
}
|
|
9101
|
-
if (
|
|
9102
|
-
|
|
9313
|
+
if (this._options.session) {
|
|
9314
|
+
this._token = this._options.session.accessToken;
|
|
9315
|
+
this._expire_token_time = this._options.session.validUntil.getTime() / 1e3;
|
|
9316
|
+
} else {
|
|
9317
|
+
if (!this._options.secretKey) {
|
|
9318
|
+
return Promise.reject("option secretKey or environment variable EYEPOP_SECRET_KEY is required");
|
|
9319
|
+
}
|
|
9103
9320
|
}
|
|
9104
|
-
this.
|
|
9105
|
-
keepAliveTimeout: 1e4,
|
|
9106
|
-
pipelining: 100,
|
|
9107
|
-
maxConcurrentStreams: 100,
|
|
9108
|
-
maxCachedSessions: 100,
|
|
9109
|
-
connections: _Endpoint.MAX_CONNECTIONS
|
|
9110
|
-
});
|
|
9321
|
+
this._client = await createHttpClient();
|
|
9111
9322
|
this._limit = new Semaphore(this._options.jobQueueLength);
|
|
9112
9323
|
const config_url = `${this.eyepopUrl()}/pops/${this._options.popId}/config?auto_start=${this._options.autoStart}`;
|
|
9113
9324
|
const headers = {
|
|
9114
9325
|
"Authorization": await this.authorizationHeader()
|
|
9115
9326
|
};
|
|
9116
9327
|
this._requestLogger.debug("before GET %s", config_url);
|
|
9117
|
-
let response = await fetch(config_url, { headers });
|
|
9328
|
+
let response = await this._client.fetch(config_url, { headers });
|
|
9118
9329
|
if (response.status == 401) {
|
|
9119
9330
|
this._requestLogger.debug("after GET %s: 401, about to retry with fresh access token", config_url);
|
|
9120
9331
|
this._token = null;
|
|
9121
9332
|
const headers2 = {
|
|
9122
9333
|
"Authorization": await this.authorizationHeader()
|
|
9123
9334
|
};
|
|
9124
|
-
response = await fetch(config_url, {
|
|
9125
|
-
headers: headers2
|
|
9335
|
+
response = await this._client.fetch(config_url, {
|
|
9336
|
+
headers: headers2
|
|
9126
9337
|
// @ts-ignore
|
|
9127
|
-
dispatcher: this._dispatcher
|
|
9128
9338
|
});
|
|
9129
9339
|
}
|
|
9130
9340
|
if (response.status != 200) {
|
|
@@ -9135,6 +9345,7 @@ var _Endpoint = class _Endpoint {
|
|
|
9135
9345
|
const config = data;
|
|
9136
9346
|
this._baseUrl = config.base_url;
|
|
9137
9347
|
this._pipelineId = config.pipeline_id;
|
|
9348
|
+
this._popName = config.name;
|
|
9138
9349
|
this._requestLogger.debug("after GET %s: %s / %s", config_url, this._baseUrl, this._pipelineId);
|
|
9139
9350
|
if (!this._pipelineId || !this._baseUrl) {
|
|
9140
9351
|
return Promise.reject(`Pop not started`);
|
|
@@ -9148,7 +9359,7 @@ var _Endpoint = class _Endpoint {
|
|
|
9148
9359
|
"Content-Type": "application/json"
|
|
9149
9360
|
};
|
|
9150
9361
|
this._requestLogger.debug("before PATCH %s", stop_url);
|
|
9151
|
-
let response2 = await fetch(stop_url, { method: "PATCH", headers: headers2, body: JSON.stringify(body) });
|
|
9362
|
+
let response2 = await this._client.fetch(stop_url, { method: "PATCH", headers: headers2, body: JSON.stringify(body) });
|
|
9152
9363
|
if (response2.status >= 300) {
|
|
9153
9364
|
const message = await response2.text();
|
|
9154
9365
|
return Promise.reject(`Unexpected status ${response2.status}: ${message}`);
|
|
@@ -9159,34 +9370,37 @@ var _Endpoint = class _Endpoint {
|
|
|
9159
9370
|
}
|
|
9160
9371
|
async disconnect(wait = true) {
|
|
9161
9372
|
if (wait && this._limit) {
|
|
9162
|
-
for (let
|
|
9373
|
+
for (let j = 0; j < this._options.jobQueueLength; j++) {
|
|
9163
9374
|
await this._limit.acquire();
|
|
9164
9375
|
}
|
|
9165
9376
|
}
|
|
9166
|
-
if (this.
|
|
9167
|
-
await this.
|
|
9168
|
-
this.
|
|
9377
|
+
if (this._client) {
|
|
9378
|
+
await this._client.close();
|
|
9379
|
+
this._client = null;
|
|
9169
9380
|
}
|
|
9170
9381
|
this._baseUrl = null;
|
|
9171
9382
|
this._pipelineId = null;
|
|
9172
9383
|
this._limit = null;
|
|
9173
9384
|
}
|
|
9174
9385
|
async authorizationHeader() {
|
|
9175
|
-
return `Bearer ${await this.
|
|
9386
|
+
return `Bearer ${await this.currentAccessToken()}`;
|
|
9176
9387
|
}
|
|
9177
|
-
async
|
|
9388
|
+
async currentAccessToken() {
|
|
9178
9389
|
const now = Date.now() / 1e3;
|
|
9179
9390
|
if (!this._token || this._expire_token_time < now) {
|
|
9391
|
+
if (!this._client) {
|
|
9392
|
+
return Promise.reject("endpoint not connected");
|
|
9393
|
+
} else if (!this._options.secretKey) {
|
|
9394
|
+
return Promise.reject("temporary access token expired");
|
|
9395
|
+
}
|
|
9180
9396
|
const body = { "secret_key": this._options.secretKey };
|
|
9181
9397
|
const headers = { "Content-Type": "application/json" };
|
|
9182
9398
|
const post_url = `${this.eyepopUrl()}/authentication/token`;
|
|
9183
9399
|
this._requestLogger.debug("before POST %s", post_url);
|
|
9184
|
-
const response = await fetch(post_url, {
|
|
9400
|
+
const response = await this._client.fetch(post_url, {
|
|
9185
9401
|
method: "POST",
|
|
9186
9402
|
headers,
|
|
9187
|
-
body: JSON.stringify(body)
|
|
9188
|
-
// @ts-ignore
|
|
9189
|
-
dispatcher: this._dispatcher
|
|
9403
|
+
body: JSON.stringify(body)
|
|
9190
9404
|
});
|
|
9191
9405
|
if (response.status != 200) {
|
|
9192
9406
|
const message = await response.text();
|
|
@@ -9209,8 +9423,6 @@ var _Endpoint = class _Endpoint {
|
|
|
9209
9423
|
}
|
|
9210
9424
|
}
|
|
9211
9425
|
};
|
|
9212
|
-
_Endpoint.MAX_CONNECTIONS = 5;
|
|
9213
|
-
var Endpoint = _Endpoint;
|
|
9214
9426
|
|
|
9215
9427
|
// src/visualize.ts
|
|
9216
9428
|
var _EyePopPlot = class _EyePopPlot {
|
|
@@ -9327,6 +9539,7 @@ var EyePopPlot = _EyePopPlot;
|
|
|
9327
9539
|
var EyePopSdk = class {
|
|
9328
9540
|
static endpoint({
|
|
9329
9541
|
secretKey = readEnv("EYEPOP_SECRET_KEY"),
|
|
9542
|
+
session = void 0,
|
|
9330
9543
|
popId = readEnv("EYEPOP_POP_ID"),
|
|
9331
9544
|
eyepopUrl = readEnv("EYEPOP_URL"),
|
|
9332
9545
|
autoStart = true,
|
|
@@ -9337,6 +9550,7 @@ var EyePopSdk = class {
|
|
|
9337
9550
|
} = {}) {
|
|
9338
9551
|
const options = {
|
|
9339
9552
|
secretKey,
|
|
9553
|
+
session,
|
|
9340
9554
|
popId,
|
|
9341
9555
|
eyepopUrl: eyepopUrl ?? "https://api.eyepop.ai",
|
|
9342
9556
|
autoStart,
|