@eyepop.ai/eyepop 3.15.1 → 3.17.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 +86 -11
- package/dist/eyepop.index.d.mts +64 -18
- package/dist/eyepop.index.d.ts +64 -18
- package/dist/eyepop.index.js +678 -143
- package/dist/eyepop.index.js.map +1 -1
- package/dist/eyepop.index.mjs +674 -142
- package/dist/eyepop.index.mjs.map +1 -1
- package/dist/eyepop.min.js +1 -1
- package/package.json +1 -1
package/dist/eyepop.index.js
CHANGED
|
@@ -8680,6 +8680,7 @@ __export(index_exports, {
|
|
|
8680
8680
|
ForwardOperatorType: () => ForwardOperatorType,
|
|
8681
8681
|
InferenceType: () => InferenceType,
|
|
8682
8682
|
LoadFromAssetUuidJob: () => LoadFromAssetUuidJob,
|
|
8683
|
+
LoadFromGroupJob: () => LoadFromGroupJob,
|
|
8683
8684
|
LoadFromJob: () => LoadFromJob,
|
|
8684
8685
|
LoadMediaStreamJob: () => LoadMediaStreamJob,
|
|
8685
8686
|
ModelExportStatus: () => ModelExportStatus,
|
|
@@ -8693,12 +8694,12 @@ __export(index_exports, {
|
|
|
8693
8694
|
PopComponentType: () => PopComponentType,
|
|
8694
8695
|
PredictionVersion: () => PredictionVersion,
|
|
8695
8696
|
Semaphore: () => Semaphore,
|
|
8696
|
-
SessionStatus: () => SessionStatus,
|
|
8697
8697
|
Stream: () => Stream,
|
|
8698
8698
|
TaskMode: () => TaskMode,
|
|
8699
8699
|
TaskType: () => TaskType,
|
|
8700
8700
|
TranscodeMode: () => TranscodeMode,
|
|
8701
8701
|
TransientPopId: () => TransientPopId,
|
|
8702
|
+
UploadGroupJob: () => UploadGroupJob,
|
|
8702
8703
|
UploadJob: () => UploadJob,
|
|
8703
8704
|
UserReview: () => UserReview,
|
|
8704
8705
|
VideoMode: () => VideoMode,
|
|
@@ -8709,11 +8710,211 @@ __export(index_exports, {
|
|
|
8709
8710
|
WorkerEndpoint: () => WorkerEndpoint,
|
|
8710
8711
|
WorkflowPhase: () => WorkflowPhase,
|
|
8711
8712
|
default: () => index_default,
|
|
8713
|
+
encodeMultipartFormData: () => encodeMultipartFormData,
|
|
8712
8714
|
getBaseUrl: () => getBaseUrl,
|
|
8715
|
+
randomMultipartBoundary: () => randomMultipartBoundary,
|
|
8713
8716
|
readableStreamFromString: () => readableStreamFromString
|
|
8714
8717
|
});
|
|
8715
8718
|
module.exports = __toCommonJS(index_exports);
|
|
8716
8719
|
|
|
8720
|
+
// compute/compute_session.ts
|
|
8721
|
+
var SESSION_DEAD = /* @__PURE__ */ new Set(["error" /* ERROR */, "failed" /* FAILED */, "stopped" /* STOPPED */, "pipeline_error" /* PIPELINE_ERROR */, "unknown" /* UNKNOWN */]);
|
|
8722
|
+
var CHECK_FOR_IS_READY_INTERVAL = 250;
|
|
8723
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
8724
|
+
function pipelineIdFromSession(session) {
|
|
8725
|
+
if (session.pipeline_uuid) {
|
|
8726
|
+
return session.pipeline_uuid;
|
|
8727
|
+
}
|
|
8728
|
+
const pipeline = session.pipelines?.[0];
|
|
8729
|
+
return pipeline?.id || pipeline?.pipeline_id || null;
|
|
8730
|
+
}
|
|
8731
|
+
function sessionCreateBody(options) {
|
|
8732
|
+
const body = {};
|
|
8733
|
+
if (options.sessionName) {
|
|
8734
|
+
body.session_name = options.sessionName;
|
|
8735
|
+
}
|
|
8736
|
+
if (options.pipelineImage) {
|
|
8737
|
+
body.pipeline_image = options.pipelineImage;
|
|
8738
|
+
}
|
|
8739
|
+
if (options.pipelineVersion) {
|
|
8740
|
+
body.pipeline_version = options.pipelineVersion;
|
|
8741
|
+
}
|
|
8742
|
+
if (options.pop) {
|
|
8743
|
+
body.pop = options.pop;
|
|
8744
|
+
}
|
|
8745
|
+
return Object.keys(body).length > 0 ? JSON.stringify(body) : void 0;
|
|
8746
|
+
}
|
|
8747
|
+
function sessionHealthReady(body, contentType) {
|
|
8748
|
+
if (contentType.includes("application/json")) {
|
|
8749
|
+
const health = JSON.parse(body);
|
|
8750
|
+
if (health && typeof health == "object") {
|
|
8751
|
+
if (health.message && !health.session_status) {
|
|
8752
|
+
return true;
|
|
8753
|
+
}
|
|
8754
|
+
return health.session_status == "running" /* RUNNING */;
|
|
8755
|
+
}
|
|
8756
|
+
}
|
|
8757
|
+
return contentType.includes("text/plain") && body.includes("I'm fine");
|
|
8758
|
+
}
|
|
8759
|
+
function accessTokenValidUntil(session) {
|
|
8760
|
+
if (session.access_token_expires_at) {
|
|
8761
|
+
const expiresAt = Date.parse(session.access_token_expires_at);
|
|
8762
|
+
return Number.isNaN(expiresAt) ? null : expiresAt;
|
|
8763
|
+
}
|
|
8764
|
+
if (session.access_token_expires_in) {
|
|
8765
|
+
return Date.now() + session.access_token_expires_in * 1e3;
|
|
8766
|
+
}
|
|
8767
|
+
return null;
|
|
8768
|
+
}
|
|
8769
|
+
var ComputeSessionClient = class {
|
|
8770
|
+
constructor(options) {
|
|
8771
|
+
this.options = options;
|
|
8772
|
+
}
|
|
8773
|
+
async resolve() {
|
|
8774
|
+
const session = this.options.sessionUuid ? await this.getPermanentComputeSession(this.options.sessionUuid) : await this.getOnDemandComputeSession();
|
|
8775
|
+
const accessToken = this.sessionAccessToken(session);
|
|
8776
|
+
await this.waitUntilReady(session, accessToken);
|
|
8777
|
+
const pipelineId = pipelineIdFromSession(session);
|
|
8778
|
+
if (this.options.pop && !pipelineId) {
|
|
8779
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
8780
|
+
}
|
|
8781
|
+
return {
|
|
8782
|
+
session,
|
|
8783
|
+
pipelineId,
|
|
8784
|
+
accessToken,
|
|
8785
|
+
accessTokenValidUntil: accessTokenValidUntil(session)
|
|
8786
|
+
};
|
|
8787
|
+
}
|
|
8788
|
+
async getOnDemandComputeSession() {
|
|
8789
|
+
let session = null;
|
|
8790
|
+
const sessionsUrl = `${this.options.computeUrl}/v1/sessions`;
|
|
8791
|
+
const headers = {
|
|
8792
|
+
Authorization: await this.options.authorizationHeader()
|
|
8793
|
+
};
|
|
8794
|
+
let sessions;
|
|
8795
|
+
if (!this.options.pop) {
|
|
8796
|
+
this.options.requestLogger?.debug("fetching sessions from: %s", sessionsUrl);
|
|
8797
|
+
const response = await this.options.httpClient.fetch(sessionsUrl, {
|
|
8798
|
+
headers
|
|
8799
|
+
});
|
|
8800
|
+
if (response.status == 404) {
|
|
8801
|
+
sessions = [];
|
|
8802
|
+
} else if (response.status != 200) {
|
|
8803
|
+
const message = await response.text();
|
|
8804
|
+
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
8805
|
+
} else {
|
|
8806
|
+
const response_content = await response.json();
|
|
8807
|
+
sessions = response_content;
|
|
8808
|
+
}
|
|
8809
|
+
if (sessions.length > 0) {
|
|
8810
|
+
this.options.logger?.debug(`User has ${sessions.length} sessions, inspecting for usable session`);
|
|
8811
|
+
for (let s of sessions) {
|
|
8812
|
+
if (!SESSION_DEAD.has(s.session_status) && !s.persistent && (!this.options.sessionName || s.session_name === this.options.sessionName)) {
|
|
8813
|
+
session = s;
|
|
8814
|
+
this.options.logger?.debug(`Use active session ${s.session_uuid} with pipeline ${pipelineIdFromSession(s)}`);
|
|
8815
|
+
break;
|
|
8816
|
+
}
|
|
8817
|
+
}
|
|
8818
|
+
}
|
|
8819
|
+
}
|
|
8820
|
+
if (!session) {
|
|
8821
|
+
this.options.requestLogger?.debug("creating a new session at: %s", sessionsUrl);
|
|
8822
|
+
const createBody = sessionCreateBody(this.options);
|
|
8823
|
+
const createHeaders = {
|
|
8824
|
+
...headers,
|
|
8825
|
+
...createBody ? { "Content-Type": "application/json" } : {}
|
|
8826
|
+
};
|
|
8827
|
+
const request = {
|
|
8828
|
+
headers: createHeaders,
|
|
8829
|
+
method: "POST"
|
|
8830
|
+
};
|
|
8831
|
+
if (createBody) {
|
|
8832
|
+
request.body = createBody;
|
|
8833
|
+
}
|
|
8834
|
+
const query = "wait=true";
|
|
8835
|
+
const response = await this.options.httpClient.fetch(`${sessionsUrl}?${query}`, request);
|
|
8836
|
+
if (response.status != 200) {
|
|
8837
|
+
const message = await response.text();
|
|
8838
|
+
throw new Error(`Unexpected status ${response.status} creating a compute session: ${message}`);
|
|
8839
|
+
} else {
|
|
8840
|
+
sessions = await response.json();
|
|
8841
|
+
}
|
|
8842
|
+
if (sessions.length == 0) {
|
|
8843
|
+
throw new Error("Unexpected, no compute session after attempt to create one");
|
|
8844
|
+
}
|
|
8845
|
+
session = sessions[0] || null;
|
|
8846
|
+
}
|
|
8847
|
+
if (!session) {
|
|
8848
|
+
throw new Error("unexpected undefined session");
|
|
8849
|
+
}
|
|
8850
|
+
if (this.options.pop && !pipelineIdFromSession(session)) {
|
|
8851
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
8852
|
+
}
|
|
8853
|
+
return session;
|
|
8854
|
+
}
|
|
8855
|
+
async getPermanentComputeSession(sessionUuid) {
|
|
8856
|
+
let session = null;
|
|
8857
|
+
const sessionUrl = `${this.options.computeUrl}/v1/sessions/${sessionUuid}`;
|
|
8858
|
+
this.options.requestLogger?.debug("fetching session from: %s", sessionUrl);
|
|
8859
|
+
const headers = {
|
|
8860
|
+
Authorization: await this.options.authorizationHeader()
|
|
8861
|
+
};
|
|
8862
|
+
let response = await this.options.httpClient.fetch(sessionUrl, {
|
|
8863
|
+
headers
|
|
8864
|
+
});
|
|
8865
|
+
if (response.status == 404) {
|
|
8866
|
+
throw new Error(`Unexpected status ${response.status} compute sessions ${sessionUuid} not found`);
|
|
8867
|
+
} else if (response.status != 200) {
|
|
8868
|
+
const message = await response.text();
|
|
8869
|
+
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
8870
|
+
} else {
|
|
8871
|
+
const response_content = await response.json();
|
|
8872
|
+
session = response_content;
|
|
8873
|
+
}
|
|
8874
|
+
return session;
|
|
8875
|
+
}
|
|
8876
|
+
sessionAccessToken(session) {
|
|
8877
|
+
if (!session.access_token) {
|
|
8878
|
+
throw new Error(`Compute session ${session.session_uuid} did not provide an access token`);
|
|
8879
|
+
}
|
|
8880
|
+
return session.access_token;
|
|
8881
|
+
}
|
|
8882
|
+
async waitUntilReady(session, accessToken) {
|
|
8883
|
+
let isReady = false;
|
|
8884
|
+
const deadline = Date.now() + this.options.readyTimeoutMs;
|
|
8885
|
+
while (!isReady) {
|
|
8886
|
+
const health_url = `${session.session_endpoint}/health`;
|
|
8887
|
+
const response = await this.options.httpClient.fetch(health_url, {
|
|
8888
|
+
headers: {
|
|
8889
|
+
Authorization: `Bearer ${accessToken}`,
|
|
8890
|
+
Accept: "application/json"
|
|
8891
|
+
}
|
|
8892
|
+
});
|
|
8893
|
+
if (response.status == 200) {
|
|
8894
|
+
const contentType = response.headers.get("content-type") || "";
|
|
8895
|
+
const body = await response.text();
|
|
8896
|
+
try {
|
|
8897
|
+
isReady = sessionHealthReady(body, contentType);
|
|
8898
|
+
} catch (error) {
|
|
8899
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check returned invalid JSON, wait and poll for update`);
|
|
8900
|
+
}
|
|
8901
|
+
if (!isReady && Date.now() > deadline) {
|
|
8902
|
+
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${this.options.readyTimeoutMs / 1e3} seconds`);
|
|
8903
|
+
}
|
|
8904
|
+
if (!isReady) {
|
|
8905
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check not ready, wait and poll for update`);
|
|
8906
|
+
await sleep(CHECK_FOR_IS_READY_INTERVAL);
|
|
8907
|
+
}
|
|
8908
|
+
} else if (Date.now() > deadline) {
|
|
8909
|
+
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${this.options.readyTimeoutMs / 1e3} seconds`);
|
|
8910
|
+
} else {
|
|
8911
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check status ${response.status}, wait and poll for update`);
|
|
8912
|
+
await sleep(CHECK_FOR_IS_READY_INTERVAL);
|
|
8913
|
+
}
|
|
8914
|
+
}
|
|
8915
|
+
}
|
|
8916
|
+
};
|
|
8917
|
+
|
|
8717
8918
|
// types.ts
|
|
8718
8919
|
var EndpointState = /* @__PURE__ */ ((EndpointState2) => {
|
|
8719
8920
|
EndpointState2["Idle"] = "Idle";
|
|
@@ -8726,6 +8927,7 @@ var EndpointState = /* @__PURE__ */ ((EndpointState2) => {
|
|
|
8726
8927
|
})(EndpointState || {});
|
|
8727
8928
|
|
|
8728
8929
|
// streaming.ts
|
|
8930
|
+
var import_uuid = require("uuid");
|
|
8729
8931
|
var Stream = class _Stream {
|
|
8730
8932
|
constructor(iterator, controller) {
|
|
8731
8933
|
this.iterator = iterator;
|
|
@@ -8906,6 +9108,76 @@ function readableStreamFromString(s) {
|
|
|
8906
9108
|
}
|
|
8907
9109
|
});
|
|
8908
9110
|
}
|
|
9111
|
+
function randomMultipartBoundary() {
|
|
9112
|
+
return `----formdata-boundary-${(0, import_uuid.v4)()}`;
|
|
9113
|
+
}
|
|
9114
|
+
function toPartStream(content) {
|
|
9115
|
+
if (content instanceof ReadableStream) {
|
|
9116
|
+
return content;
|
|
9117
|
+
}
|
|
9118
|
+
if (content instanceof Blob) {
|
|
9119
|
+
return content.stream();
|
|
9120
|
+
}
|
|
9121
|
+
const bytes = ArrayBuffer.isView(content) ? new Uint8Array(content.buffer, content.byteOffset, content.byteLength) : new Uint8Array(content);
|
|
9122
|
+
return new ReadableStream({
|
|
9123
|
+
start(controller) {
|
|
9124
|
+
controller.enqueue(bytes);
|
|
9125
|
+
controller.close();
|
|
9126
|
+
}
|
|
9127
|
+
});
|
|
9128
|
+
}
|
|
9129
|
+
async function cancelMultipartContent(content, reason) {
|
|
9130
|
+
if (content instanceof ReadableStream) {
|
|
9131
|
+
await content.cancel(reason);
|
|
9132
|
+
}
|
|
9133
|
+
}
|
|
9134
|
+
function encodeMultipartFormData(parts, boundary) {
|
|
9135
|
+
const encoder = new TextEncoder();
|
|
9136
|
+
let partIndex = 0;
|
|
9137
|
+
let reader = null;
|
|
9138
|
+
return new ReadableStream({
|
|
9139
|
+
async pull(controller) {
|
|
9140
|
+
if (reader) {
|
|
9141
|
+
const { done, value } = await reader.read();
|
|
9142
|
+
if (!done) {
|
|
9143
|
+
controller.enqueue(value);
|
|
9144
|
+
return;
|
|
9145
|
+
}
|
|
9146
|
+
reader = null;
|
|
9147
|
+
controller.enqueue(encoder.encode("\r\n"));
|
|
9148
|
+
partIndex++;
|
|
9149
|
+
}
|
|
9150
|
+
if (partIndex >= parts.length) {
|
|
9151
|
+
controller.enqueue(encoder.encode(`--${boundary}--\r
|
|
9152
|
+
`));
|
|
9153
|
+
controller.close();
|
|
9154
|
+
return;
|
|
9155
|
+
}
|
|
9156
|
+
const part = parts[partIndex];
|
|
9157
|
+
let header = `--${boundary}\r
|
|
9158
|
+
Content-Disposition: form-data; name="${part.name}"\r
|
|
9159
|
+
`;
|
|
9160
|
+
if (part.contentType) {
|
|
9161
|
+
header += `Content-Type: ${part.contentType}\r
|
|
9162
|
+
`;
|
|
9163
|
+
}
|
|
9164
|
+
header += "\r\n";
|
|
9165
|
+
controller.enqueue(encoder.encode(header));
|
|
9166
|
+
if (typeof part.content === "string") {
|
|
9167
|
+
controller.enqueue(encoder.encode(part.content));
|
|
9168
|
+
controller.enqueue(encoder.encode("\r\n"));
|
|
9169
|
+
partIndex++;
|
|
9170
|
+
} else {
|
|
9171
|
+
reader = toPartStream(part.content).getReader();
|
|
9172
|
+
}
|
|
9173
|
+
},
|
|
9174
|
+
async cancel(reason) {
|
|
9175
|
+
await reader?.cancel(reason);
|
|
9176
|
+
const firstUnstartedPart = reader ? partIndex + 1 : partIndex;
|
|
9177
|
+
await Promise.all(parts.slice(firstUnstartedPart).map((part) => cancelMultipartContent(part.content, reason)));
|
|
9178
|
+
}
|
|
9179
|
+
});
|
|
9180
|
+
}
|
|
8909
9181
|
|
|
8910
9182
|
// worker/worker_types.ts
|
|
8911
9183
|
var PredictionVersion = /* @__PURE__ */ ((PredictionVersion3) => {
|
|
@@ -8963,7 +9235,7 @@ var ContourType = /* @__PURE__ */ ((ContourType2) => {
|
|
|
8963
9235
|
})(ContourType || {});
|
|
8964
9236
|
|
|
8965
9237
|
// worker/webrtc_whip.ts
|
|
8966
|
-
var
|
|
9238
|
+
var import_uuid2 = require("uuid");
|
|
8967
9239
|
|
|
8968
9240
|
// worker/webrtc_base.ts
|
|
8969
9241
|
var import_path = __toESM(require("path"));
|
|
@@ -9238,7 +9510,7 @@ var WebrtcBase = class _WebrtcBase {
|
|
|
9238
9510
|
// worker/webrtc_whip.ts
|
|
9239
9511
|
var WebrtcWhip = class extends WebrtcBase {
|
|
9240
9512
|
constructor(stream, getSession, client, is_pipeline_direct, requestLogger) {
|
|
9241
|
-
super(getSession, client, (0,
|
|
9513
|
+
super(getSession, client, (0, import_uuid2.v4)().toString(), "liveIngress/whip", is_pipeline_direct, requestLogger);
|
|
9242
9514
|
this._stream = stream;
|
|
9243
9515
|
}
|
|
9244
9516
|
async start() {
|
|
@@ -9633,6 +9905,111 @@ var LoadFromJob = class extends AbstractJob {
|
|
|
9633
9905
|
});
|
|
9634
9906
|
}
|
|
9635
9907
|
};
|
|
9908
|
+
var UploadGroupJob = class extends AbstractJob {
|
|
9909
|
+
get [Symbol.toStringTag]() {
|
|
9910
|
+
return "uploadGroupJob";
|
|
9911
|
+
}
|
|
9912
|
+
constructor(sources, params, getSession, client, requestLogger) {
|
|
9913
|
+
super(params, getSession, client, requestLogger);
|
|
9914
|
+
if (sources.length === 0) {
|
|
9915
|
+
throw new Error("upload group requires at least one source");
|
|
9916
|
+
}
|
|
9917
|
+
this._sources = sources;
|
|
9918
|
+
}
|
|
9919
|
+
async startJob() {
|
|
9920
|
+
const session = await this._getSession();
|
|
9921
|
+
if (!session.baseUrl) {
|
|
9922
|
+
return Promise.reject(new Error("session.baseUrl must not be null"));
|
|
9923
|
+
}
|
|
9924
|
+
const queryParams = new URLSearchParams({
|
|
9925
|
+
mode: "queue",
|
|
9926
|
+
processing: "sync"
|
|
9927
|
+
});
|
|
9928
|
+
if (this._version !== void 0) {
|
|
9929
|
+
queryParams.set("version", this._version.toString());
|
|
9930
|
+
}
|
|
9931
|
+
if (this._params.motionDetect) {
|
|
9932
|
+
for (const [key, value] of Object.entries(this._params.motionDetect)) {
|
|
9933
|
+
queryParams.set(key, value);
|
|
9934
|
+
}
|
|
9935
|
+
}
|
|
9936
|
+
const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?${queryParams.toString()}`;
|
|
9937
|
+
const parts = [];
|
|
9938
|
+
if (this._params.componentParams) {
|
|
9939
|
+
parts.push({ name: "params", contentType: "application/json", content: JSON.stringify(this._params.componentParams) });
|
|
9940
|
+
}
|
|
9941
|
+
if (this._params.roi) {
|
|
9942
|
+
parts.push({ name: "roi", contentType: "application/json", content: JSON.stringify(this._params.roi) });
|
|
9943
|
+
}
|
|
9944
|
+
if (this._params.fps) {
|
|
9945
|
+
parts.push({ name: "fps", contentType: "application/json", content: JSON.stringify(this._params.fps) });
|
|
9946
|
+
}
|
|
9947
|
+
for (const source of this._sources) {
|
|
9948
|
+
parts.push({ name: "file", contentType: source.mimeType, content: source.stream });
|
|
9949
|
+
}
|
|
9950
|
+
const boundary = randomMultipartBoundary();
|
|
9951
|
+
const headers = {
|
|
9952
|
+
...session.authenticationHeaders(),
|
|
9953
|
+
Accept: "application/jsonl",
|
|
9954
|
+
"Content-Type": `multipart/form-data; boundary=${boundary}`
|
|
9955
|
+
};
|
|
9956
|
+
return await this._client.fetch(postUrl, {
|
|
9957
|
+
headers,
|
|
9958
|
+
method: "POST",
|
|
9959
|
+
body: encodeMultipartFormData(parts, boundary),
|
|
9960
|
+
signal: this._controller.signal,
|
|
9961
|
+
// @ts-ignore
|
|
9962
|
+
duplex: "half",
|
|
9963
|
+
eyepop: { responseStreaming: true }
|
|
9964
|
+
});
|
|
9965
|
+
}
|
|
9966
|
+
};
|
|
9967
|
+
var LoadFromGroupJob = class extends AbstractJob {
|
|
9968
|
+
get [Symbol.toStringTag]() {
|
|
9969
|
+
return "loadFromGroupJob";
|
|
9970
|
+
}
|
|
9971
|
+
constructor(urls, params, getSession, client, requestLogger) {
|
|
9972
|
+
super(params, getSession, client, requestLogger);
|
|
9973
|
+
if (urls.length === 0) {
|
|
9974
|
+
throw new Error("load from group requires at least one url");
|
|
9975
|
+
}
|
|
9976
|
+
this._urls = urls;
|
|
9977
|
+
}
|
|
9978
|
+
async startJob() {
|
|
9979
|
+
const session = await this._getSession();
|
|
9980
|
+
if (!session.baseUrl) {
|
|
9981
|
+
return Promise.reject(new Error("session.baseUrl must not be null"));
|
|
9982
|
+
}
|
|
9983
|
+
const body = {
|
|
9984
|
+
sourceType: "GROUP",
|
|
9985
|
+
sources: this._urls.map((url) => ({ sourceType: "URL", url })),
|
|
9986
|
+
version: this._version
|
|
9987
|
+
};
|
|
9988
|
+
if (this._params.componentParams) {
|
|
9989
|
+
body["params"] = this._params.componentParams;
|
|
9990
|
+
}
|
|
9991
|
+
if (this._params.roi) {
|
|
9992
|
+
body["roi"] = this._params.roi;
|
|
9993
|
+
}
|
|
9994
|
+
if (this._params.motionDetect) {
|
|
9995
|
+
Object.assign(body, this._params.motionDetect);
|
|
9996
|
+
}
|
|
9997
|
+
const headers = {
|
|
9998
|
+
...session.authenticationHeaders(),
|
|
9999
|
+
Accept: "application/jsonl",
|
|
10000
|
+
"Content-Type": "application/json"
|
|
10001
|
+
};
|
|
10002
|
+
const patchUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
|
|
10003
|
+
return await this._client.fetch(patchUrl, {
|
|
10004
|
+
headers,
|
|
10005
|
+
method: "PATCH",
|
|
10006
|
+
body: JSON.stringify(body),
|
|
10007
|
+
signal: this._controller.signal,
|
|
10008
|
+
// @ts-ignore
|
|
10009
|
+
eyepop: { responseStreaming: true }
|
|
10010
|
+
});
|
|
10011
|
+
}
|
|
10012
|
+
};
|
|
9636
10013
|
var LoadFromAssetUuidJob = class extends AbstractJob {
|
|
9637
10014
|
constructor(assetUuid, params, getSession, client, requestLogger) {
|
|
9638
10015
|
super(params, getSession, client, requestLogger);
|
|
@@ -9799,8 +10176,9 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
|
9799
10176
|
};
|
|
9800
10177
|
} else {
|
|
9801
10178
|
class NodeHttpClient {
|
|
9802
|
-
constructor(agent, logger) {
|
|
10179
|
+
constructor(agent, fetchFn, logger) {
|
|
9803
10180
|
this._agent = agent;
|
|
10181
|
+
this._fetch = fetchFn;
|
|
9804
10182
|
this._logger = logger;
|
|
9805
10183
|
}
|
|
9806
10184
|
async fetch(input, init) {
|
|
@@ -9808,7 +10186,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
|
9808
10186
|
init.dispatcher = this._agent;
|
|
9809
10187
|
const logLine = logLineFromRequest(input, init);
|
|
9810
10188
|
this._logger.debug(`Node fetch() BEFORE ${logLine}`);
|
|
9811
|
-
const response = await
|
|
10189
|
+
const response = await this._fetch(input, init);
|
|
9812
10190
|
this._logger.debug(`AFTER ${logLine} -> ${response.status}`);
|
|
9813
10191
|
return response;
|
|
9814
10192
|
}
|
|
@@ -9828,7 +10206,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
|
|
|
9828
10206
|
pipelining: 0
|
|
9829
10207
|
});
|
|
9830
10208
|
logger.debug("Using node fetch with undici agent as http client");
|
|
9831
|
-
return new NodeHttpClient(agent, logger);
|
|
10209
|
+
return new NodeHttpClient(agent, undici.fetch, logger);
|
|
9832
10210
|
};
|
|
9833
10211
|
}
|
|
9834
10212
|
|
|
@@ -10233,20 +10611,6 @@ var TransientPopId = /* @__PURE__ */ ((TransientPopId2) => {
|
|
|
10233
10611
|
})(TransientPopId || {});
|
|
10234
10612
|
|
|
10235
10613
|
// worker/worker_endpoint.ts
|
|
10236
|
-
var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
|
|
10237
|
-
SessionStatus2["UNKNOWN"] = "unknown";
|
|
10238
|
-
SessionStatus2["PENDING"] = "pending";
|
|
10239
|
-
SessionStatus2["RUNNING"] = "running";
|
|
10240
|
-
SessionStatus2["STOPPED"] = "stopped";
|
|
10241
|
-
SessionStatus2["FAILED"] = "failed";
|
|
10242
|
-
SessionStatus2["ERROR"] = "error";
|
|
10243
|
-
SessionStatus2["PIPELINE_CREATING"] = "pipeline_creating";
|
|
10244
|
-
SessionStatus2["PIPELINE_OK"] = "pipeline_ok";
|
|
10245
|
-
SessionStatus2["PIPELINE_CHECKING"] = "pipeline_checking";
|
|
10246
|
-
SessionStatus2["PIPELINE_ERROR"] = "pipeline_error";
|
|
10247
|
-
return SessionStatus2;
|
|
10248
|
-
})(SessionStatus || {});
|
|
10249
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10250
10614
|
var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
10251
10615
|
constructor(options) {
|
|
10252
10616
|
super(options);
|
|
@@ -10254,7 +10618,10 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10254
10618
|
this._baseUrl = null;
|
|
10255
10619
|
this._pipelineId = null;
|
|
10256
10620
|
this._popName = null;
|
|
10621
|
+
this._sessionAccessToken = null;
|
|
10622
|
+
this._sessionAccessTokenValidUntil = null;
|
|
10257
10623
|
this._pipeline = null;
|
|
10624
|
+
this._pipelineCreatePromise = null;
|
|
10258
10625
|
}
|
|
10259
10626
|
options() {
|
|
10260
10627
|
return this._options;
|
|
@@ -10281,20 +10648,29 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10281
10648
|
this._baseUrl = null;
|
|
10282
10649
|
}
|
|
10283
10650
|
async session() {
|
|
10284
|
-
|
|
10285
|
-
if (this._baseUrl == null
|
|
10651
|
+
let session = null;
|
|
10652
|
+
if (this._baseUrl == null) {
|
|
10286
10653
|
await this.reconnect();
|
|
10287
|
-
if (this._baseUrl == null
|
|
10654
|
+
if (this._baseUrl == null) {
|
|
10288
10655
|
return Promise.reject("endpoint not connected");
|
|
10289
10656
|
}
|
|
10290
10657
|
}
|
|
10658
|
+
if (this._sessionAccessToken) {
|
|
10659
|
+
session = {
|
|
10660
|
+
eyepopUrl: this.options().eyepopUrl,
|
|
10661
|
+
accessToken: this._sessionAccessToken,
|
|
10662
|
+
validUntil: this._sessionAccessTokenValidUntil || Number.MAX_VALUE
|
|
10663
|
+
};
|
|
10664
|
+
} else {
|
|
10665
|
+
session = await super.session();
|
|
10666
|
+
}
|
|
10291
10667
|
return {
|
|
10292
10668
|
eyepopUrl: session.eyepopUrl,
|
|
10293
10669
|
accessToken: session.accessToken,
|
|
10294
10670
|
validUntil: session.validUntil,
|
|
10295
10671
|
popId: this.options().popId,
|
|
10296
10672
|
baseUrl: this._baseUrl,
|
|
10297
|
-
pipelineId: this._pipelineId,
|
|
10673
|
+
pipelineId: this._pipelineId || void 0,
|
|
10298
10674
|
authenticationHeaders: () => this._authenticationHeaders(session)
|
|
10299
10675
|
};
|
|
10300
10676
|
}
|
|
@@ -10304,11 +10680,14 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10304
10680
|
pop() {
|
|
10305
10681
|
if (this._pipeline) {
|
|
10306
10682
|
return this._pipeline.pop || null;
|
|
10307
|
-
} else {
|
|
10308
|
-
return null;
|
|
10309
10683
|
}
|
|
10684
|
+
return this.options().pop || null;
|
|
10310
10685
|
}
|
|
10311
10686
|
async changePop(pop) {
|
|
10687
|
+
if (this.options().popId == "transient" /* Transient */) {
|
|
10688
|
+
await this.changeTransientPop(pop);
|
|
10689
|
+
return;
|
|
10690
|
+
}
|
|
10312
10691
|
const client = this._client;
|
|
10313
10692
|
const baseUrl = this._baseUrl;
|
|
10314
10693
|
if (!baseUrl || !client) {
|
|
@@ -10331,6 +10710,7 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10331
10710
|
const message = await response.text();
|
|
10332
10711
|
throw new Error(`Unexpected status ${response.status}: ${message}`);
|
|
10333
10712
|
}
|
|
10713
|
+
this.options().pop = pop;
|
|
10334
10714
|
if (this._pipeline) {
|
|
10335
10715
|
this._pipeline.pop = pop;
|
|
10336
10716
|
} else {
|
|
@@ -10345,6 +10725,10 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10345
10725
|
_authenticationHeaders(session) {
|
|
10346
10726
|
return this._options.auth.isLocal !== void 0 ? {} : { Authorization: `Bearer ${session.accessToken}` };
|
|
10347
10727
|
}
|
|
10728
|
+
/**
|
|
10729
|
+
* @deprecated Pop ids are only retained for backwards compatibility.
|
|
10730
|
+
* Configure transient sessions with `WorkerOptions.pop`.
|
|
10731
|
+
*/
|
|
10348
10732
|
popId() {
|
|
10349
10733
|
return this.options().popId || null;
|
|
10350
10734
|
}
|
|
@@ -10389,7 +10773,116 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10389
10773
|
return Promise.reject("unknown source type");
|
|
10390
10774
|
}
|
|
10391
10775
|
}
|
|
10776
|
+
async uploadGroup(paths, params = {}) {
|
|
10777
|
+
if (paths.length === 0) {
|
|
10778
|
+
throw new Error("upload group requires at least one path");
|
|
10779
|
+
}
|
|
10780
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10781
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10782
|
+
}
|
|
10783
|
+
await this._limit.acquire();
|
|
10784
|
+
try {
|
|
10785
|
+
this.updateState();
|
|
10786
|
+
const sources = await Promise.all(
|
|
10787
|
+
paths.map(async (path2) => {
|
|
10788
|
+
let streamSource;
|
|
10789
|
+
if (this._options.platformSupport?.resolvePath) {
|
|
10790
|
+
streamSource = await this._options.platformSupport.resolvePath({ path: path2 }, this._logger);
|
|
10791
|
+
} else {
|
|
10792
|
+
streamSource = await resolvePath({ path: path2 }, this._logger);
|
|
10793
|
+
}
|
|
10794
|
+
return { stream: streamSource.stream, mimeType: streamSource.mimeType };
|
|
10795
|
+
})
|
|
10796
|
+
);
|
|
10797
|
+
const job = new UploadGroupJob(
|
|
10798
|
+
sources,
|
|
10799
|
+
params,
|
|
10800
|
+
async () => this.session(),
|
|
10801
|
+
this._client,
|
|
10802
|
+
this._requestLogger
|
|
10803
|
+
);
|
|
10804
|
+
return job.start(
|
|
10805
|
+
() => {
|
|
10806
|
+
this.jobDone(job);
|
|
10807
|
+
},
|
|
10808
|
+
(statusCode) => {
|
|
10809
|
+
this.jobStatus(job, statusCode);
|
|
10810
|
+
}
|
|
10811
|
+
);
|
|
10812
|
+
} catch (e) {
|
|
10813
|
+
this._limit.release();
|
|
10814
|
+
throw e;
|
|
10815
|
+
}
|
|
10816
|
+
}
|
|
10817
|
+
async uploadStreamGroup(streams, mimeTypes, params = {}) {
|
|
10818
|
+
if (streams.length === 0) {
|
|
10819
|
+
throw new Error("upload stream group requires at least one stream");
|
|
10820
|
+
}
|
|
10821
|
+
if (mimeTypes !== void 0 && mimeTypes.length !== streams.length) {
|
|
10822
|
+
throw new Error("mimeTypes must have the same length as streams");
|
|
10823
|
+
}
|
|
10824
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10825
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10826
|
+
}
|
|
10827
|
+
await this._limit.acquire();
|
|
10828
|
+
try {
|
|
10829
|
+
this.updateState();
|
|
10830
|
+
const sources = streams.map((stream, i) => ({
|
|
10831
|
+
stream,
|
|
10832
|
+
mimeType: mimeTypes?.[i] ?? null
|
|
10833
|
+
}));
|
|
10834
|
+
const job = new UploadGroupJob(
|
|
10835
|
+
sources,
|
|
10836
|
+
params,
|
|
10837
|
+
async () => this.session(),
|
|
10838
|
+
this._client,
|
|
10839
|
+
this._requestLogger
|
|
10840
|
+
);
|
|
10841
|
+
return job.start(
|
|
10842
|
+
() => {
|
|
10843
|
+
this.jobDone(job);
|
|
10844
|
+
},
|
|
10845
|
+
(statusCode) => {
|
|
10846
|
+
this.jobStatus(job, statusCode);
|
|
10847
|
+
}
|
|
10848
|
+
);
|
|
10849
|
+
} catch (e) {
|
|
10850
|
+
this._limit.release();
|
|
10851
|
+
throw e;
|
|
10852
|
+
}
|
|
10853
|
+
}
|
|
10854
|
+
async loadFromGroup(urls, params = {}) {
|
|
10855
|
+
if (urls.length === 0) {
|
|
10856
|
+
throw new Error("load from group requires at least one url");
|
|
10857
|
+
}
|
|
10858
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10859
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10860
|
+
}
|
|
10861
|
+
await this._limit.acquire();
|
|
10862
|
+
try {
|
|
10863
|
+
this.updateState();
|
|
10864
|
+
const job = new LoadFromGroupJob(
|
|
10865
|
+
urls,
|
|
10866
|
+
params,
|
|
10867
|
+
async () => this.session(),
|
|
10868
|
+
this._client,
|
|
10869
|
+
this._requestLogger
|
|
10870
|
+
);
|
|
10871
|
+
return job.start(
|
|
10872
|
+
() => {
|
|
10873
|
+
this.jobDone(job);
|
|
10874
|
+
},
|
|
10875
|
+
(statusCode) => {
|
|
10876
|
+
this.jobStatus(job, statusCode);
|
|
10877
|
+
}
|
|
10878
|
+
);
|
|
10879
|
+
} catch (e) {
|
|
10880
|
+
this._limit.release();
|
|
10881
|
+
throw e;
|
|
10882
|
+
}
|
|
10883
|
+
}
|
|
10392
10884
|
async uploadFile(source, params) {
|
|
10885
|
+
await this.ensureTransientPipelineStarted();
|
|
10393
10886
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10394
10887
|
return Promise.reject("endpoint not connected, use connect()");
|
|
10395
10888
|
}
|
|
@@ -10422,6 +10915,7 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10422
10915
|
}
|
|
10423
10916
|
}
|
|
10424
10917
|
async uploadStream(source, params) {
|
|
10918
|
+
await this.ensureTransientPipelineStarted();
|
|
10425
10919
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10426
10920
|
return Promise.reject("endpoint not connected, use connect()");
|
|
10427
10921
|
}
|
|
@@ -10454,6 +10948,7 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10454
10948
|
}
|
|
10455
10949
|
}
|
|
10456
10950
|
async uploadPath(source, params) {
|
|
10951
|
+
await this.ensureTransientPipelineStarted();
|
|
10457
10952
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10458
10953
|
throw new Error("endpoint not connected, use connect()");
|
|
10459
10954
|
}
|
|
@@ -10500,6 +10995,7 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10500
10995
|
params
|
|
10501
10996
|
);
|
|
10502
10997
|
}
|
|
10998
|
+
await this.ensureTransientPipelineStarted();
|
|
10503
10999
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10504
11000
|
throw new Error("endpoint not connected, use connect()");
|
|
10505
11001
|
}
|
|
@@ -10529,6 +11025,7 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10529
11025
|
}
|
|
10530
11026
|
}
|
|
10531
11027
|
async loadFromAssetUuid(source, params) {
|
|
11028
|
+
await this.ensureTransientPipelineStarted();
|
|
10532
11029
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10533
11030
|
throw new Error("endpoint not connected, use connect()");
|
|
10534
11031
|
}
|
|
@@ -10558,6 +11055,7 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10558
11055
|
}
|
|
10559
11056
|
}
|
|
10560
11057
|
async loadMediaStream(source, params) {
|
|
11058
|
+
await this.ensureTransientPipelineStarted();
|
|
10561
11059
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10562
11060
|
throw new Error("endpoint not connected, use connect()");
|
|
10563
11061
|
}
|
|
@@ -10600,7 +11098,9 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10600
11098
|
async reconnect() {
|
|
10601
11099
|
if (this.options().popId == "transient" /* Transient */) {
|
|
10602
11100
|
await this.getComputeSession();
|
|
10603
|
-
|
|
11101
|
+
if (this.options().pop) {
|
|
11102
|
+
this.setTransientPipelinePop();
|
|
11103
|
+
}
|
|
10604
11104
|
} else if (this.options().sessionUuid) {
|
|
10605
11105
|
await this.getComputeSession();
|
|
10606
11106
|
} else {
|
|
@@ -10697,120 +11197,41 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10697
11197
|
}
|
|
10698
11198
|
}
|
|
10699
11199
|
}
|
|
11200
|
+
sessionReadyTimeoutMs() {
|
|
11201
|
+
const seconds = this.options().sessionReadyTimeoutSeconds;
|
|
11202
|
+
return typeof seconds == "number" && Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : _WorkerEndpoint.WAIT_FOR_IS_READY;
|
|
11203
|
+
}
|
|
10700
11204
|
async getComputeSession() {
|
|
10701
11205
|
if (!this._client) {
|
|
10702
11206
|
throw new Error("endpoint not initialized");
|
|
10703
11207
|
}
|
|
10704
|
-
let
|
|
10705
|
-
|
|
10706
|
-
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
10710
|
-
|
|
10711
|
-
|
|
10712
|
-
|
|
10713
|
-
|
|
10714
|
-
|
|
10715
|
-
|
|
10716
|
-
|
|
10717
|
-
|
|
10718
|
-
});
|
|
10719
|
-
|
|
10720
|
-
isReady = true;
|
|
10721
|
-
} else if (Date.now() > deadline) {
|
|
10722
|
-
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${_WorkerEndpoint.WAIT_FOR_IS_READY / 1e3} seconds`);
|
|
10723
|
-
} else {
|
|
10724
|
-
this._logger.debug(`session ${session.session_uuid} health check status ${response.status}, wait and poll for update`);
|
|
10725
|
-
await sleep(_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL);
|
|
10726
|
-
}
|
|
10727
|
-
}
|
|
10728
|
-
this._baseUrl = session.session_endpoint;
|
|
10729
|
-
this._pipeline = null;
|
|
10730
|
-
if (session.pipeline_uuid) {
|
|
10731
|
-
this._pipelineId = session.pipeline_uuid;
|
|
10732
|
-
} else if (session.pipelines) {
|
|
10733
|
-
this._pipelineId = session.pipelines[0].pipeline_id;
|
|
10734
|
-
} else {
|
|
10735
|
-
this._pipelineId = null;
|
|
10736
|
-
}
|
|
10737
|
-
}
|
|
10738
|
-
async getOnDemandComputeSession(httpClient) {
|
|
10739
|
-
let session = null;
|
|
10740
|
-
const sessionsUrl = `${this.eyepopUrl()}/v1/sessions`;
|
|
10741
|
-
this._requestLogger.debug("fetching sessions from: %s", sessionsUrl);
|
|
10742
|
-
const headers = {
|
|
10743
|
-
Authorization: await this.authorizationHeader()
|
|
10744
|
-
};
|
|
10745
|
-
let response = await httpClient.fetch(sessionsUrl, {
|
|
10746
|
-
headers
|
|
10747
|
-
});
|
|
10748
|
-
let sessions;
|
|
10749
|
-
if (response.status == 404) {
|
|
10750
|
-
sessions = [];
|
|
10751
|
-
} else if (response.status != 200) {
|
|
11208
|
+
let resolved;
|
|
11209
|
+
try {
|
|
11210
|
+
resolved = await new ComputeSessionClient({
|
|
11211
|
+
computeUrl: this.eyepopUrl(),
|
|
11212
|
+
httpClient: this._client,
|
|
11213
|
+
authorizationHeader: () => this.computeAuthorizationHeader(),
|
|
11214
|
+
sessionUuid: this.options().sessionUuid,
|
|
11215
|
+
sessionName: this.options().sessionName,
|
|
11216
|
+
pipelineImage: this.options().pipelineImage,
|
|
11217
|
+
pipelineVersion: this.options().pipelineVersion,
|
|
11218
|
+
pop: this.options().pop,
|
|
11219
|
+
readyTimeoutMs: this.sessionReadyTimeoutMs(),
|
|
11220
|
+
logger: this._logger,
|
|
11221
|
+
requestLogger: this._requestLogger
|
|
11222
|
+
}).resolve();
|
|
11223
|
+
} catch (error) {
|
|
10752
11224
|
this.updateState("Error" /* Error */);
|
|
10753
|
-
|
|
10754
|
-
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
10755
|
-
} else {
|
|
10756
|
-
const response_content = await response.json();
|
|
10757
|
-
sessions = response_content;
|
|
10758
|
-
}
|
|
10759
|
-
if (sessions.length > 0) {
|
|
10760
|
-
this._logger.debug(`User has ${sessions.length} sessions, inspecting for usable session`);
|
|
10761
|
-
for (let s of sessions) {
|
|
10762
|
-
if (!_WorkerEndpoint.SESSION_DEAD.has(s.session_status) && !s.persistent) {
|
|
10763
|
-
session = s;
|
|
10764
|
-
this._logger.debug(`Use active session ${s.session_uuid} with pipeline ${s.pipeline_uuid}`);
|
|
10765
|
-
break;
|
|
10766
|
-
}
|
|
10767
|
-
}
|
|
11225
|
+
throw error;
|
|
10768
11226
|
}
|
|
10769
|
-
|
|
10770
|
-
|
|
10771
|
-
|
|
10772
|
-
|
|
10773
|
-
|
|
10774
|
-
|
|
10775
|
-
|
|
10776
|
-
this.updateState("Error" /* Error */);
|
|
10777
|
-
const message = await response.text();
|
|
10778
|
-
throw new Error(`Unexpected status ${response.status} creating a compute session: ${message}`);
|
|
10779
|
-
} else {
|
|
10780
|
-
sessions = await response.json();
|
|
10781
|
-
}
|
|
10782
|
-
if (sessions.length == 0) {
|
|
10783
|
-
throw new Error("Unexpected, no compute session after attempt to create one");
|
|
10784
|
-
}
|
|
10785
|
-
session = sessions[0] || null;
|
|
10786
|
-
}
|
|
10787
|
-
if (!session) {
|
|
10788
|
-
throw new Error("unexpected undefined session");
|
|
10789
|
-
}
|
|
10790
|
-
return [session, headers];
|
|
10791
|
-
}
|
|
10792
|
-
async getPermanentComputeSession(httpClient, sessionUuid) {
|
|
10793
|
-
let session = null;
|
|
10794
|
-
const sessionUrl = `${this.eyepopUrl()}/v1/sessions/${sessionUuid}`;
|
|
10795
|
-
this._requestLogger.debug("fetching session from: %s", sessionUrl);
|
|
10796
|
-
const headers = {
|
|
10797
|
-
Authorization: await this.authorizationHeader()
|
|
10798
|
-
};
|
|
10799
|
-
let response = await httpClient.fetch(sessionUrl, {
|
|
10800
|
-
headers
|
|
10801
|
-
});
|
|
10802
|
-
if (response.status == 404) {
|
|
10803
|
-
this.updateState("Error" /* Error */);
|
|
10804
|
-
throw new Error(`Unexpected status ${response.status} compute sessions ${sessionUuid} not found`);
|
|
10805
|
-
} else if (response.status != 200) {
|
|
10806
|
-
this.updateState("Error" /* Error */);
|
|
10807
|
-
const message = await response.text();
|
|
10808
|
-
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
10809
|
-
} else {
|
|
10810
|
-
const response_content = await response.json();
|
|
10811
|
-
session = response_content;
|
|
11227
|
+
this._sessionAccessToken = resolved.accessToken;
|
|
11228
|
+
this._sessionAccessTokenValidUntil = resolved.accessTokenValidUntil;
|
|
11229
|
+
this._baseUrl = resolved.session.session_endpoint;
|
|
11230
|
+
this._pipeline = null;
|
|
11231
|
+
this._pipelineId = resolved.pipelineId;
|
|
11232
|
+
if (this.options().pop) {
|
|
11233
|
+
this.setTransientPipelinePop();
|
|
10812
11234
|
}
|
|
10813
|
-
return [session, headers];
|
|
10814
11235
|
}
|
|
10815
11236
|
async startTransientPipeline() {
|
|
10816
11237
|
const client = this._client;
|
|
@@ -10819,12 +11240,12 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10819
11240
|
throw new Error("endpoint not initialized");
|
|
10820
11241
|
}
|
|
10821
11242
|
let pop;
|
|
10822
|
-
if (this.
|
|
11243
|
+
if (this.options().pop) {
|
|
11244
|
+
pop = this.options().pop;
|
|
11245
|
+
} else if (this._pipeline && this._pipeline.pop) {
|
|
10823
11246
|
pop = this._pipeline.pop;
|
|
10824
11247
|
} else {
|
|
10825
|
-
|
|
10826
|
-
components: []
|
|
10827
|
-
};
|
|
11248
|
+
throw new Error("Cannot start a transient pipeline without a pop");
|
|
10828
11249
|
}
|
|
10829
11250
|
const body = {
|
|
10830
11251
|
pop,
|
|
@@ -10836,8 +11257,9 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10836
11257
|
videoOutput: "no_output"
|
|
10837
11258
|
};
|
|
10838
11259
|
const post_url = `${baseUrl.replace(/\/+$/, "")}/pipelines`;
|
|
10839
|
-
|
|
11260
|
+
const response = await this.fetchWithRetry(async () => {
|
|
10840
11261
|
let headers = {
|
|
11262
|
+
Accept: "application/json",
|
|
10841
11263
|
"Content-Type": "application/json",
|
|
10842
11264
|
Authorization: await this.authorizationHeader()
|
|
10843
11265
|
};
|
|
@@ -10849,15 +11271,116 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10849
11271
|
});
|
|
10850
11272
|
if (response.status != 200) {
|
|
10851
11273
|
const message = await response.text();
|
|
10852
|
-
throw new Error(`Unexpected status ${response.status}: ${message}`);
|
|
11274
|
+
throw new Error(`Unexpected status ${response.status} starting transient pipeline: ${message.slice(0, 300)}`);
|
|
10853
11275
|
}
|
|
10854
11276
|
const result = await response.json();
|
|
10855
11277
|
return result["id"];
|
|
10856
11278
|
}
|
|
11279
|
+
async ensureTransientPipelineStarted() {
|
|
11280
|
+
if (this.options().popId != "transient" /* Transient */ || this._pipelineId) {
|
|
11281
|
+
return;
|
|
11282
|
+
}
|
|
11283
|
+
if (!this.options().pop) {
|
|
11284
|
+
return;
|
|
11285
|
+
}
|
|
11286
|
+
if (!this._baseUrl) {
|
|
11287
|
+
await this.reconnect();
|
|
11288
|
+
}
|
|
11289
|
+
if (this._pipelineId) {
|
|
11290
|
+
return;
|
|
11291
|
+
}
|
|
11292
|
+
if (this.options().pop) {
|
|
11293
|
+
await this.reconnect();
|
|
11294
|
+
if (!this._pipelineId) {
|
|
11295
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
11296
|
+
}
|
|
11297
|
+
return;
|
|
11298
|
+
}
|
|
11299
|
+
if (!this._pipelineCreatePromise) {
|
|
11300
|
+
this._pipelineCreatePromise = this.startTransientPipeline();
|
|
11301
|
+
}
|
|
11302
|
+
try {
|
|
11303
|
+
this._pipelineId = await this._pipelineCreatePromise;
|
|
11304
|
+
this.setTransientPipelinePop();
|
|
11305
|
+
} finally {
|
|
11306
|
+
this._pipelineCreatePromise = null;
|
|
11307
|
+
}
|
|
11308
|
+
}
|
|
11309
|
+
async changeTransientPop(pop) {
|
|
11310
|
+
if (!this._client) {
|
|
11311
|
+
throw new Error("endpoint not initialized");
|
|
11312
|
+
}
|
|
11313
|
+
const previousPop = this.options().pop;
|
|
11314
|
+
const previousBaseUrl = this._baseUrl;
|
|
11315
|
+
const previousSessionAccessToken = this._sessionAccessToken;
|
|
11316
|
+
const previousSessionAccessTokenValidUntil = this._sessionAccessTokenValidUntil;
|
|
11317
|
+
if (this._pipelineId) {
|
|
11318
|
+
await this.deleteTransientPipeline(this._pipelineId);
|
|
11319
|
+
this._pipelineId = null;
|
|
11320
|
+
}
|
|
11321
|
+
this._pipeline = null;
|
|
11322
|
+
try {
|
|
11323
|
+
this.options().pop = pop;
|
|
11324
|
+
await this.getComputeSession();
|
|
11325
|
+
} catch (error) {
|
|
11326
|
+
this.options().pop = previousPop;
|
|
11327
|
+
this._pipeline = null;
|
|
11328
|
+
this._pipelineId = null;
|
|
11329
|
+
this._baseUrl = previousPop ? null : previousBaseUrl;
|
|
11330
|
+
this._sessionAccessToken = previousSessionAccessToken;
|
|
11331
|
+
this._sessionAccessTokenValidUntil = previousSessionAccessTokenValidUntil;
|
|
11332
|
+
throw error;
|
|
11333
|
+
}
|
|
11334
|
+
if (!this._pipelineId) {
|
|
11335
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
11336
|
+
}
|
|
11337
|
+
this.setTransientPipelinePop();
|
|
11338
|
+
}
|
|
11339
|
+
async deleteTransientPipeline(pipelineId) {
|
|
11340
|
+
if (!this._client || !this._baseUrl) {
|
|
11341
|
+
return;
|
|
11342
|
+
}
|
|
11343
|
+
const deleteUrl = `${this._baseUrl}/pipelines/${pipelineId}`;
|
|
11344
|
+
const headers = {
|
|
11345
|
+
Authorization: await this.authorizationHeader()
|
|
11346
|
+
};
|
|
11347
|
+
let response = await this._client.fetch(deleteUrl, {
|
|
11348
|
+
method: "DELETE",
|
|
11349
|
+
headers
|
|
11350
|
+
});
|
|
11351
|
+
if (response.status >= 300) {
|
|
11352
|
+
const message = await response.text();
|
|
11353
|
+
this._logger.info(`stopping pipeline failed, status ${response.status}: ${message}`);
|
|
11354
|
+
}
|
|
11355
|
+
}
|
|
11356
|
+
async authorizationHeader() {
|
|
11357
|
+
if (this._sessionAccessToken) {
|
|
11358
|
+
return `Bearer ${this._sessionAccessToken}`;
|
|
11359
|
+
}
|
|
11360
|
+
return super.authorizationHeader();
|
|
11361
|
+
}
|
|
11362
|
+
async computeAuthorizationHeader() {
|
|
11363
|
+
if (this.options().auth.isLocal !== void 0) {
|
|
11364
|
+
return "Implicit";
|
|
11365
|
+
}
|
|
11366
|
+
if (this.options().auth.apiKey !== void 0) {
|
|
11367
|
+
return `Bearer ${this.options().auth.apiKey}`;
|
|
11368
|
+
}
|
|
11369
|
+
return super.authorizationHeader();
|
|
11370
|
+
}
|
|
11371
|
+
setTransientPipelinePop() {
|
|
11372
|
+
const pop = this.options().pop;
|
|
11373
|
+
if (pop && this._pipelineId) {
|
|
11374
|
+
this._pipeline = {
|
|
11375
|
+
id: this._pipelineId,
|
|
11376
|
+
state: "idle",
|
|
11377
|
+
startTime: (/* @__PURE__ */ new Date()).toString(),
|
|
11378
|
+
pop
|
|
11379
|
+
};
|
|
11380
|
+
}
|
|
11381
|
+
}
|
|
10857
11382
|
};
|
|
10858
|
-
_WorkerEndpoint.SESSION_DEAD = /* @__PURE__ */ new Set(["error" /* ERROR */, "failed" /* FAILED */, "stopped" /* STOPPED */, "pipeline_error" /* PIPELINE_ERROR */, "unknown" /* UNKNOWN */]);
|
|
10859
11383
|
_WorkerEndpoint.WAIT_FOR_IS_READY = 60 * 1e3;
|
|
10860
|
-
_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL = 250;
|
|
10861
11384
|
var WorkerEndpoint = _WorkerEndpoint;
|
|
10862
11385
|
|
|
10863
11386
|
// shims/websockets.ts
|
|
@@ -12231,6 +12754,15 @@ var EyePop;
|
|
|
12231
12754
|
if (opts.sessionUuid === void 0) {
|
|
12232
12755
|
opts.sessionUuid = readEnv("EYEPOP_SESSION_UUID");
|
|
12233
12756
|
}
|
|
12757
|
+
if (opts.sessionName === void 0) {
|
|
12758
|
+
opts.sessionName = readEnv("EYEPOP_SESSION_NAME");
|
|
12759
|
+
}
|
|
12760
|
+
if (opts.pipelineImage === void 0) {
|
|
12761
|
+
opts.pipelineImage = readEnv("EYEPOP_PIPELINE_IMAGE");
|
|
12762
|
+
}
|
|
12763
|
+
if (opts.pipelineVersion === void 0) {
|
|
12764
|
+
opts.pipelineVersion = readEnv("EYEPOP_PIPELINE_VERSION");
|
|
12765
|
+
}
|
|
12234
12766
|
if (opts.popId === void 0 && opts.sessionUuid === void 0) {
|
|
12235
12767
|
opts.popId = readEnv("EYEPOP_POP_ID") || "transient" /* Transient */;
|
|
12236
12768
|
}
|
|
@@ -12340,6 +12872,7 @@ var index_default = EyePop;
|
|
|
12340
12872
|
ForwardOperatorType,
|
|
12341
12873
|
InferenceType,
|
|
12342
12874
|
LoadFromAssetUuidJob,
|
|
12875
|
+
LoadFromGroupJob,
|
|
12343
12876
|
LoadFromJob,
|
|
12344
12877
|
LoadMediaStreamJob,
|
|
12345
12878
|
ModelExportStatus,
|
|
@@ -12353,12 +12886,12 @@ var index_default = EyePop;
|
|
|
12353
12886
|
PopComponentType,
|
|
12354
12887
|
PredictionVersion,
|
|
12355
12888
|
Semaphore,
|
|
12356
|
-
SessionStatus,
|
|
12357
12889
|
Stream,
|
|
12358
12890
|
TaskMode,
|
|
12359
12891
|
TaskType,
|
|
12360
12892
|
TranscodeMode,
|
|
12361
12893
|
TransientPopId,
|
|
12894
|
+
UploadGroupJob,
|
|
12362
12895
|
UploadJob,
|
|
12363
12896
|
UserReview,
|
|
12364
12897
|
VideoMode,
|
|
@@ -12368,7 +12901,9 @@ var index_default = EyePop;
|
|
|
12368
12901
|
WebrtcWhip,
|
|
12369
12902
|
WorkerEndpoint,
|
|
12370
12903
|
WorkflowPhase,
|
|
12904
|
+
encodeMultipartFormData,
|
|
12371
12905
|
getBaseUrl,
|
|
12906
|
+
randomMultipartBoundary,
|
|
12372
12907
|
readableStreamFromString
|
|
12373
12908
|
});
|
|
12374
12909
|
/*! Bundled license information:
|