@eyepop.ai/eyepop 0.17.0 → 0.18.1
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/eyepop.index.d.mts +9 -1
- package/dist/eyepop.index.d.ts +9 -1
- package/dist/eyepop.index.js +173 -25
- package/dist/eyepop.index.js.map +1 -1
- package/dist/eyepop.index.mjs +173 -25
- package/dist/eyepop.index.mjs.map +1 -1
- package/dist/eyepop.min.js +1 -1
- package/package.json +1 -1
package/dist/eyepop.index.d.mts
CHANGED
|
@@ -152,12 +152,15 @@ interface OAuth2Auth {
|
|
|
152
152
|
oAuth2: true | Auth0Options;
|
|
153
153
|
}
|
|
154
154
|
type Authentication = undefined | SecretKeyAuth | SessionAuth | OAuth2Auth;
|
|
155
|
+
declare enum TransientPopId {
|
|
156
|
+
Transient = "transient"
|
|
157
|
+
}
|
|
155
158
|
interface Options {
|
|
156
159
|
auth?: Authentication | undefined;
|
|
157
160
|
/**
|
|
158
161
|
* Defaults to process.env['EYEPOP_POP_ID'].
|
|
159
162
|
*/
|
|
160
|
-
popId?: string | undefined;
|
|
163
|
+
popId?: string | TransientPopId | undefined;
|
|
161
164
|
/**
|
|
162
165
|
* Override the default base URL for the API, e.g., "https://api.eyepop.ai/"
|
|
163
166
|
*
|
|
@@ -177,6 +180,7 @@ declare class Endpoint {
|
|
|
177
180
|
private _baseUrl;
|
|
178
181
|
private _pipelineId;
|
|
179
182
|
private _popName;
|
|
183
|
+
private _pipeline;
|
|
180
184
|
private _client;
|
|
181
185
|
private _limit;
|
|
182
186
|
private _state;
|
|
@@ -190,6 +194,8 @@ declare class Endpoint {
|
|
|
190
194
|
state(): EndpointState;
|
|
191
195
|
pendingJobs(): number;
|
|
192
196
|
popName(): string | null;
|
|
197
|
+
popComp(): string | null;
|
|
198
|
+
changePopComp(popComp: string): Promise<void>;
|
|
193
199
|
popId(): string | null;
|
|
194
200
|
onStateChanged(handler: (fromState: EndpointState, toState: EndpointState) => void): Endpoint;
|
|
195
201
|
onIngressEvent(handler: (event: IngressEvent) => void): Endpoint;
|
|
@@ -208,9 +214,11 @@ declare class Endpoint {
|
|
|
208
214
|
private jobDone;
|
|
209
215
|
private updateState;
|
|
210
216
|
private jobStatus;
|
|
217
|
+
private fetchWithRetry;
|
|
211
218
|
private reconnect;
|
|
212
219
|
private authorizationHeader;
|
|
213
220
|
private currentAccessToken;
|
|
221
|
+
private startPopLessPipeline;
|
|
214
222
|
}
|
|
215
223
|
|
|
216
224
|
declare namespace EyePop {
|
package/dist/eyepop.index.d.ts
CHANGED
|
@@ -152,12 +152,15 @@ interface OAuth2Auth {
|
|
|
152
152
|
oAuth2: true | Auth0Options;
|
|
153
153
|
}
|
|
154
154
|
type Authentication = undefined | SecretKeyAuth | SessionAuth | OAuth2Auth;
|
|
155
|
+
declare enum TransientPopId {
|
|
156
|
+
Transient = "transient"
|
|
157
|
+
}
|
|
155
158
|
interface Options {
|
|
156
159
|
auth?: Authentication | undefined;
|
|
157
160
|
/**
|
|
158
161
|
* Defaults to process.env['EYEPOP_POP_ID'].
|
|
159
162
|
*/
|
|
160
|
-
popId?: string | undefined;
|
|
163
|
+
popId?: string | TransientPopId | undefined;
|
|
161
164
|
/**
|
|
162
165
|
* Override the default base URL for the API, e.g., "https://api.eyepop.ai/"
|
|
163
166
|
*
|
|
@@ -177,6 +180,7 @@ declare class Endpoint {
|
|
|
177
180
|
private _baseUrl;
|
|
178
181
|
private _pipelineId;
|
|
179
182
|
private _popName;
|
|
183
|
+
private _pipeline;
|
|
180
184
|
private _client;
|
|
181
185
|
private _limit;
|
|
182
186
|
private _state;
|
|
@@ -190,6 +194,8 @@ declare class Endpoint {
|
|
|
190
194
|
state(): EndpointState;
|
|
191
195
|
pendingJobs(): number;
|
|
192
196
|
popName(): string | null;
|
|
197
|
+
popComp(): string | null;
|
|
198
|
+
changePopComp(popComp: string): Promise<void>;
|
|
193
199
|
popId(): string | null;
|
|
194
200
|
onStateChanged(handler: (fromState: EndpointState, toState: EndpointState) => void): Endpoint;
|
|
195
201
|
onIngressEvent(handler: (event: IngressEvent) => void): Endpoint;
|
|
@@ -208,9 +214,11 @@ declare class Endpoint {
|
|
|
208
214
|
private jobDone;
|
|
209
215
|
private updateState;
|
|
210
216
|
private jobStatus;
|
|
217
|
+
private fetchWithRetry;
|
|
211
218
|
private reconnect;
|
|
212
219
|
private authorizationHeader;
|
|
213
220
|
private currentAccessToken;
|
|
221
|
+
private startPopLessPipeline;
|
|
214
222
|
}
|
|
215
223
|
|
|
216
224
|
declare namespace EyePop {
|
package/dist/eyepop.index.js
CHANGED
|
@@ -9821,6 +9821,7 @@ var Endpoint = class {
|
|
|
9821
9821
|
this._expire_token_time = null;
|
|
9822
9822
|
this._client = null;
|
|
9823
9823
|
this._state = "Idle" /* Idle */;
|
|
9824
|
+
this._pipeline = null;
|
|
9824
9825
|
this._stateChangeHandler = null;
|
|
9825
9826
|
this._ingressEventHandler = null;
|
|
9826
9827
|
this._ingressEventWs = null;
|
|
@@ -9850,6 +9851,44 @@ var Endpoint = class {
|
|
|
9850
9851
|
popName() {
|
|
9851
9852
|
return this._popName;
|
|
9852
9853
|
}
|
|
9854
|
+
popComp() {
|
|
9855
|
+
if (this._pipeline) {
|
|
9856
|
+
return this._pipeline.inferPipeline;
|
|
9857
|
+
} else {
|
|
9858
|
+
return null;
|
|
9859
|
+
}
|
|
9860
|
+
}
|
|
9861
|
+
async changePopComp(popComp) {
|
|
9862
|
+
const client = this._client;
|
|
9863
|
+
const baseUrl = this._baseUrl;
|
|
9864
|
+
if (!baseUrl || !client) {
|
|
9865
|
+
return Promise.reject("endpoint not connected, use connect() before changePopComp()");
|
|
9866
|
+
}
|
|
9867
|
+
const patch_url = `${this._baseUrl}/pipelines/${this._pipelineId}/inferencePipeline`;
|
|
9868
|
+
const body = {
|
|
9869
|
+
"pipeline": popComp
|
|
9870
|
+
};
|
|
9871
|
+
this._requestLogger.debug("before PATCH %s", patch_url);
|
|
9872
|
+
let response = await this.fetchWithRetry(async () => {
|
|
9873
|
+
let headers = {
|
|
9874
|
+
"Authorization": await this.authorizationHeader(),
|
|
9875
|
+
"Content-Type": "application/json"
|
|
9876
|
+
};
|
|
9877
|
+
return client.fetch(patch_url, {
|
|
9878
|
+
method: "PATCH",
|
|
9879
|
+
body: JSON.stringify(body),
|
|
9880
|
+
headers
|
|
9881
|
+
});
|
|
9882
|
+
});
|
|
9883
|
+
if (response.status != 204) {
|
|
9884
|
+
const message = await response.text();
|
|
9885
|
+
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
9886
|
+
}
|
|
9887
|
+
this._requestLogger.debug("after PATCH %s", patch_url);
|
|
9888
|
+
if (this._pipeline) {
|
|
9889
|
+
this._pipeline.inferPipeline = popComp;
|
|
9890
|
+
}
|
|
9891
|
+
}
|
|
9853
9892
|
popId() {
|
|
9854
9893
|
return this._options.popId || null;
|
|
9855
9894
|
}
|
|
@@ -9888,19 +9927,22 @@ var Endpoint = class {
|
|
|
9888
9927
|
return Promise.reject("option secretKey or environment variable EYEPOP_SECRET_KEY is required");
|
|
9889
9928
|
}
|
|
9890
9929
|
this._client = await createHttpClient();
|
|
9930
|
+
const client = this._client;
|
|
9891
9931
|
let result = await this.reconnect();
|
|
9892
9932
|
if (this._baseUrl && this._options.stopJobs) {
|
|
9893
9933
|
const stop_url = `${this._baseUrl}/pipelines/${this._pipelineId}/source?mode=preempt&processing=sync`;
|
|
9894
9934
|
const body = { "sourceType": "NONE" };
|
|
9895
|
-
const headers = {
|
|
9896
|
-
"Authorization": await this.authorizationHeader(),
|
|
9897
|
-
"Content-Type": "application/json"
|
|
9898
|
-
};
|
|
9899
9935
|
this._requestLogger.debug("before PATCH %s", stop_url);
|
|
9900
|
-
let response = await this.
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9936
|
+
let response = await this.fetchWithRetry(async () => {
|
|
9937
|
+
const headers = {
|
|
9938
|
+
"Authorization": await this.authorizationHeader(),
|
|
9939
|
+
"Content-Type": "application/json"
|
|
9940
|
+
};
|
|
9941
|
+
return client.fetch(stop_url, {
|
|
9942
|
+
method: "PATCH",
|
|
9943
|
+
headers,
|
|
9944
|
+
body: JSON.stringify(body)
|
|
9945
|
+
});
|
|
9904
9946
|
});
|
|
9905
9947
|
if (response.status >= 300) {
|
|
9906
9948
|
const message = await response.text();
|
|
@@ -9981,25 +10023,19 @@ var Endpoint = class {
|
|
|
9981
10023
|
}
|
|
9982
10024
|
}
|
|
9983
10025
|
async startIngressWs() {
|
|
9984
|
-
|
|
10026
|
+
const client = this._client;
|
|
10027
|
+
if (this._ingressEventWs || !this._baseUrl || !client) {
|
|
9985
10028
|
return;
|
|
9986
10029
|
}
|
|
9987
10030
|
try {
|
|
9988
10031
|
const getTokenUrl = `${this._baseUrl}/liveIngress/events/token`;
|
|
9989
|
-
const headers = {
|
|
9990
|
-
"Authorization": await this.authorizationHeader()
|
|
9991
|
-
};
|
|
9992
10032
|
this._requestLogger.debug("before GET %s", getTokenUrl);
|
|
9993
|
-
let response = await this.
|
|
9994
|
-
|
|
9995
|
-
this._requestLogger.debug("after GET %s: 401, about to retry with fresh access token", getTokenUrl);
|
|
9996
|
-
this._token = null;
|
|
9997
|
-
const headers2 = {
|
|
10033
|
+
let response = await this.fetchWithRetry(async () => {
|
|
10034
|
+
const headers = {
|
|
9998
10035
|
"Authorization": await this.authorizationHeader()
|
|
9999
10036
|
};
|
|
10000
|
-
|
|
10001
|
-
|
|
10002
|
-
}
|
|
10037
|
+
return client.fetch(getTokenUrl, { headers });
|
|
10038
|
+
});
|
|
10003
10039
|
if (response.status != 200) {
|
|
10004
10040
|
const message = await response.text();
|
|
10005
10041
|
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
@@ -10145,11 +10181,49 @@ var Endpoint = class {
|
|
|
10145
10181
|
this._expire_token_time = null;
|
|
10146
10182
|
}
|
|
10147
10183
|
}
|
|
10184
|
+
async fetchWithRetry(fetcher, retries = 1) {
|
|
10185
|
+
while (true) {
|
|
10186
|
+
try {
|
|
10187
|
+
const response = await fetcher();
|
|
10188
|
+
if (response.status == 401) {
|
|
10189
|
+
this._token = null;
|
|
10190
|
+
this._expire_token_time = null;
|
|
10191
|
+
if (retries--) {
|
|
10192
|
+
this._requestLogger.info("received 401 response, attempt to reauthorize and retry");
|
|
10193
|
+
} else {
|
|
10194
|
+
return Promise.reject(`response ${response.status}: ${response.statusText}`);
|
|
10195
|
+
}
|
|
10196
|
+
} else if (response.status == 404) {
|
|
10197
|
+
this._pipelineId = null;
|
|
10198
|
+
this._baseUrl = null;
|
|
10199
|
+
if (retries--) {
|
|
10200
|
+
this._requestLogger.info("received 404 response, attempt to restart pop and retry");
|
|
10201
|
+
} else {
|
|
10202
|
+
return Promise.reject(`response ${response.status}: ${response.statusText}`);
|
|
10203
|
+
}
|
|
10204
|
+
} else {
|
|
10205
|
+
return response;
|
|
10206
|
+
}
|
|
10207
|
+
} catch (error) {
|
|
10208
|
+
this._pipelineId = null;
|
|
10209
|
+
this._baseUrl = null;
|
|
10210
|
+
if (retries--) {
|
|
10211
|
+
this._requestLogger.info("unknown, attempt to restart pop (as if we received 404)", error);
|
|
10212
|
+
return Promise.reject(error);
|
|
10213
|
+
}
|
|
10214
|
+
}
|
|
10215
|
+
}
|
|
10216
|
+
}
|
|
10148
10217
|
async reconnect() {
|
|
10149
10218
|
if (!this._client) {
|
|
10150
10219
|
return Promise.reject("endpoint not initialized");
|
|
10151
10220
|
}
|
|
10152
|
-
|
|
10221
|
+
let config_url;
|
|
10222
|
+
if (this._options.popId == "transient" /* Transient */) {
|
|
10223
|
+
config_url = `${this.eyepopUrl()}/workers/config`;
|
|
10224
|
+
} else {
|
|
10225
|
+
config_url = `${this.eyepopUrl()}/pops/${this._options.popId}/config?auto_start=false`;
|
|
10226
|
+
}
|
|
10153
10227
|
const headers = {
|
|
10154
10228
|
"Authorization": await this.authorizationHeader()
|
|
10155
10229
|
};
|
|
@@ -10165,7 +10239,6 @@ var Endpoint = class {
|
|
|
10165
10239
|
this.updateState("FetchConfig" /* FetchConfig */);
|
|
10166
10240
|
response = await this._client.fetch(config_url, {
|
|
10167
10241
|
headers: headers2
|
|
10168
|
-
// @ts-ignore
|
|
10169
10242
|
});
|
|
10170
10243
|
}
|
|
10171
10244
|
if (response.status != 200) {
|
|
@@ -10183,7 +10256,6 @@ var Endpoint = class {
|
|
|
10183
10256
|
this.updateState("StartingPop" /* StartingPop */);
|
|
10184
10257
|
response = await this._client.fetch(auto_start_config_url, {
|
|
10185
10258
|
headers: headers2
|
|
10186
|
-
// @ts-ignore
|
|
10187
10259
|
});
|
|
10188
10260
|
if (response.status != 200) {
|
|
10189
10261
|
this.updateState("Error" /* Error */);
|
|
@@ -10194,13 +10266,35 @@ var Endpoint = class {
|
|
|
10194
10266
|
}
|
|
10195
10267
|
const baseUrl = new URL(config.base_url, this.eyepopUrl());
|
|
10196
10268
|
this._baseUrl = baseUrl.toString();
|
|
10197
|
-
this.
|
|
10198
|
-
|
|
10269
|
+
if (this._options.popId == "transient" /* Transient */) {
|
|
10270
|
+
this._pipelineId = await this.startPopLessPipeline();
|
|
10271
|
+
this._popName = this._options.popId;
|
|
10272
|
+
} else {
|
|
10273
|
+
this._pipelineId = config.pipeline_id;
|
|
10274
|
+
this._popName = config.name;
|
|
10275
|
+
}
|
|
10199
10276
|
this._requestLogger.debug("after GET %s: %s / %s", config_url, this._baseUrl, this._pipelineId);
|
|
10200
10277
|
if (!this._pipelineId || !this._baseUrl) {
|
|
10201
10278
|
return Promise.reject(`Pop not started`);
|
|
10202
10279
|
}
|
|
10203
10280
|
this._baseUrl = this._baseUrl.replace(/\/+$/, "");
|
|
10281
|
+
if (this._baseUrl) {
|
|
10282
|
+
const get_url = `${this._baseUrl}/pipelines/${this._pipelineId}`;
|
|
10283
|
+
const headers2 = {
|
|
10284
|
+
"Authorization": await this.authorizationHeader()
|
|
10285
|
+
};
|
|
10286
|
+
this._requestLogger.debug("before GET %s", get_url);
|
|
10287
|
+
let response2 = await this._client.fetch(get_url, {
|
|
10288
|
+
method: "GET",
|
|
10289
|
+
headers: headers2
|
|
10290
|
+
});
|
|
10291
|
+
if (response2.status > 200) {
|
|
10292
|
+
const message = await response2.text();
|
|
10293
|
+
return Promise.reject(`Unexpected status ${response2.status}: ${message}`);
|
|
10294
|
+
}
|
|
10295
|
+
this._requestLogger.debug("after GET %s", get_url);
|
|
10296
|
+
this._pipeline = await response2.json();
|
|
10297
|
+
}
|
|
10204
10298
|
this.updateState();
|
|
10205
10299
|
return Promise.resolve(this);
|
|
10206
10300
|
}
|
|
@@ -10255,6 +10349,60 @@ var Endpoint = class {
|
|
|
10255
10349
|
this._logger.debug("using access token, valid for at least %d seconds", this._expire_token_time - now);
|
|
10256
10350
|
return this._token;
|
|
10257
10351
|
}
|
|
10352
|
+
async startPopLessPipeline() {
|
|
10353
|
+
if (this._client == null || this._baseUrl == null) {
|
|
10354
|
+
return Promise.reject("endpoint not initialized");
|
|
10355
|
+
}
|
|
10356
|
+
this.updateState("StartingPop" /* StartingPop */);
|
|
10357
|
+
let pipeline;
|
|
10358
|
+
if (this._pipeline) {
|
|
10359
|
+
pipeline = this._pipeline.inferPipeline;
|
|
10360
|
+
} else {
|
|
10361
|
+
pipeline = "identity";
|
|
10362
|
+
}
|
|
10363
|
+
const body = {
|
|
10364
|
+
"inferPipelineDef": {
|
|
10365
|
+
"pipeline": pipeline
|
|
10366
|
+
},
|
|
10367
|
+
"source": {
|
|
10368
|
+
"sourceType": "NONE"
|
|
10369
|
+
},
|
|
10370
|
+
"idleTimeoutSeconds": 30,
|
|
10371
|
+
"logging": ["out_meta"],
|
|
10372
|
+
"videoOutput": "no_output"
|
|
10373
|
+
};
|
|
10374
|
+
const post_url = `${this._baseUrl.replace(/\/+$/, "")}/pipelines`;
|
|
10375
|
+
let headers = {
|
|
10376
|
+
"Content-Type": "application/json",
|
|
10377
|
+
"Authorization": await this.authorizationHeader()
|
|
10378
|
+
};
|
|
10379
|
+
this._requestLogger.debug("before POST %s", post_url);
|
|
10380
|
+
let response = await this._client.fetch(post_url, {
|
|
10381
|
+
method: "POST",
|
|
10382
|
+
headers,
|
|
10383
|
+
body: JSON.stringify(body)
|
|
10384
|
+
});
|
|
10385
|
+
if (response.status == 401) {
|
|
10386
|
+
this._requestLogger.debug("after GET %s: 401, about to retry with fresh access token", post_url);
|
|
10387
|
+
this._token = null;
|
|
10388
|
+
headers = {
|
|
10389
|
+
"Content-Type": "application/json",
|
|
10390
|
+
"Authorization": await this.authorizationHeader()
|
|
10391
|
+
};
|
|
10392
|
+
response = await this._client.fetch(post_url, {
|
|
10393
|
+
method: "POST",
|
|
10394
|
+
headers,
|
|
10395
|
+
body: JSON.stringify(body)
|
|
10396
|
+
});
|
|
10397
|
+
}
|
|
10398
|
+
if (response.status != 200) {
|
|
10399
|
+
const message = await response.text();
|
|
10400
|
+
return Promise.reject(`Unexpected status ${response.status}: ${message}`);
|
|
10401
|
+
}
|
|
10402
|
+
this._requestLogger.debug("after POST %s", post_url);
|
|
10403
|
+
const pipelineId = (await response.json())["id"];
|
|
10404
|
+
return pipelineId;
|
|
10405
|
+
}
|
|
10258
10406
|
};
|
|
10259
10407
|
|
|
10260
10408
|
// index.ts
|