@eyepop.ai/eyepop 3.16.0 → 3.17.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/README.md +77 -4
- package/dist/eyepop.index.d.mts +36 -23
- package/dist/eyepop.index.d.ts +36 -23
- package/dist/eyepop.index.js +635 -218
- package/dist/eyepop.index.js.map +1 -1
- package/dist/eyepop.index.mjs +631 -217
- package/dist/eyepop.index.mjs.map +1 -1
- package/dist/eyepop.min.js +1 -1
- package/package.json +1 -1
package/dist/eyepop.index.mjs
CHANGED
|
@@ -8632,6 +8632,283 @@ var require_mime_types = __commonJS({
|
|
|
8632
8632
|
}
|
|
8633
8633
|
});
|
|
8634
8634
|
|
|
8635
|
+
// compute/compute_session.ts
|
|
8636
|
+
var SESSION_DEAD = /* @__PURE__ */ new Set(["error" /* ERROR */, "failed" /* FAILED */, "stopped" /* STOPPED */, "pipeline_error" /* PIPELINE_ERROR */, "unknown" /* UNKNOWN */]);
|
|
8637
|
+
var CHECK_FOR_IS_READY_INTERVAL = 250;
|
|
8638
|
+
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
8639
|
+
function pipelineIdFromSession(session) {
|
|
8640
|
+
if (session.pipeline_uuid) {
|
|
8641
|
+
return session.pipeline_uuid;
|
|
8642
|
+
}
|
|
8643
|
+
const pipeline = session.pipelines?.[0];
|
|
8644
|
+
return pipeline?.id || pipeline?.pipeline_id || null;
|
|
8645
|
+
}
|
|
8646
|
+
function sessionCreateBody(options) {
|
|
8647
|
+
const body = {};
|
|
8648
|
+
if (options.sessionName) {
|
|
8649
|
+
body.session_name = options.sessionName;
|
|
8650
|
+
}
|
|
8651
|
+
if (options.pipelineImage) {
|
|
8652
|
+
body.pipeline_image = options.pipelineImage;
|
|
8653
|
+
}
|
|
8654
|
+
if (options.pipelineVersion) {
|
|
8655
|
+
body.pipeline_version = options.pipelineVersion;
|
|
8656
|
+
}
|
|
8657
|
+
if (options.pop) {
|
|
8658
|
+
body.pop = options.pop;
|
|
8659
|
+
}
|
|
8660
|
+
return Object.keys(body).length > 0 ? JSON.stringify(body) : void 0;
|
|
8661
|
+
}
|
|
8662
|
+
function sessionHealthReady(body, contentType) {
|
|
8663
|
+
if (contentType.includes("application/json")) {
|
|
8664
|
+
const health = JSON.parse(body);
|
|
8665
|
+
if (health && typeof health == "object") {
|
|
8666
|
+
if (health.message && !health.session_status) {
|
|
8667
|
+
return true;
|
|
8668
|
+
}
|
|
8669
|
+
return health.session_status == "running" /* RUNNING */;
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8672
|
+
return contentType.includes("text/plain") && body.includes("I'm fine");
|
|
8673
|
+
}
|
|
8674
|
+
function accessTokenValidUntil(session) {
|
|
8675
|
+
if (session.access_token_expires_at) {
|
|
8676
|
+
const expiresAt = Date.parse(session.access_token_expires_at);
|
|
8677
|
+
return Number.isNaN(expiresAt) ? null : expiresAt;
|
|
8678
|
+
}
|
|
8679
|
+
if (session.access_token_expires_in) {
|
|
8680
|
+
return Date.now() + session.access_token_expires_in * 1e3;
|
|
8681
|
+
}
|
|
8682
|
+
return null;
|
|
8683
|
+
}
|
|
8684
|
+
function errorInfoMessage(errorInfo) {
|
|
8685
|
+
return [errorInfo.code, errorInfo.message, errorInfo.details].filter((part) => typeof part == "string" && part.length > 0).join(": ");
|
|
8686
|
+
}
|
|
8687
|
+
function pipelineErrorMessage(session) {
|
|
8688
|
+
if (session.pipeline_error) {
|
|
8689
|
+
const message = errorInfoMessage(session.pipeline_error);
|
|
8690
|
+
return message ? `Pipeline failed for compute session ${session.session_uuid}: ${message}` : `Pipeline failed for compute session ${session.session_uuid}`;
|
|
8691
|
+
}
|
|
8692
|
+
if (session.session_status == "pipeline_error" /* PIPELINE_ERROR */) {
|
|
8693
|
+
return `Pipeline failed for compute session ${session.session_uuid}`;
|
|
8694
|
+
}
|
|
8695
|
+
return null;
|
|
8696
|
+
}
|
|
8697
|
+
async function responseErrorMessage(response) {
|
|
8698
|
+
const contentType = response.headers.get("content-type") || "";
|
|
8699
|
+
if (contentType.includes("application/json")) {
|
|
8700
|
+
try {
|
|
8701
|
+
const parsed = normalizedJsonValue(await response.clone().json());
|
|
8702
|
+
const message2 = normalizedErrorMessage(parsed);
|
|
8703
|
+
if (message2) {
|
|
8704
|
+
return message2;
|
|
8705
|
+
}
|
|
8706
|
+
} catch (_) {
|
|
8707
|
+
}
|
|
8708
|
+
}
|
|
8709
|
+
const body = await response.text();
|
|
8710
|
+
const message = normalizedErrorMessage(body);
|
|
8711
|
+
return message || body;
|
|
8712
|
+
}
|
|
8713
|
+
function normalizedJsonValue(value) {
|
|
8714
|
+
if (typeof value == "string") {
|
|
8715
|
+
try {
|
|
8716
|
+
const parsed = JSON.parse(value);
|
|
8717
|
+
return normalizedJsonValue(parsed);
|
|
8718
|
+
} catch (_) {
|
|
8719
|
+
const unescaped = value.replace(/\\"/g, '"');
|
|
8720
|
+
if (unescaped != value) {
|
|
8721
|
+
try {
|
|
8722
|
+
const parsed = JSON.parse(unescaped);
|
|
8723
|
+
return normalizedJsonValue(parsed);
|
|
8724
|
+
} catch (_2) {
|
|
8725
|
+
}
|
|
8726
|
+
}
|
|
8727
|
+
return value;
|
|
8728
|
+
}
|
|
8729
|
+
}
|
|
8730
|
+
return value;
|
|
8731
|
+
}
|
|
8732
|
+
async function responseJson(response) {
|
|
8733
|
+
return normalizedJsonValue(await response.json());
|
|
8734
|
+
}
|
|
8735
|
+
function normalizedErrorMessage(value) {
|
|
8736
|
+
value = normalizedJsonValue(value);
|
|
8737
|
+
if (typeof value == "string") {
|
|
8738
|
+
return value;
|
|
8739
|
+
}
|
|
8740
|
+
if (!value || typeof value != "object") {
|
|
8741
|
+
return null;
|
|
8742
|
+
}
|
|
8743
|
+
const record = value;
|
|
8744
|
+
const normalizedError = normalizedJsonValue(record["error"]);
|
|
8745
|
+
const errorMessage = normalizedErrorMessage(normalizedError) || (typeof normalizedError == "string" ? normalizedError : null);
|
|
8746
|
+
const message = [record["code"], errorMessage, record["message"], record["details"]].filter((part) => typeof part == "string" && part.length > 0).join(": ");
|
|
8747
|
+
if (message) {
|
|
8748
|
+
return message;
|
|
8749
|
+
}
|
|
8750
|
+
if (record["pipeline_error"]) {
|
|
8751
|
+
return normalizedErrorMessage(record["pipeline_error"]);
|
|
8752
|
+
}
|
|
8753
|
+
if (normalizedError && typeof normalizedError == "object") {
|
|
8754
|
+
return normalizedErrorMessage(normalizedError);
|
|
8755
|
+
}
|
|
8756
|
+
try {
|
|
8757
|
+
return JSON.stringify(value);
|
|
8758
|
+
} catch (_) {
|
|
8759
|
+
return null;
|
|
8760
|
+
}
|
|
8761
|
+
}
|
|
8762
|
+
var ComputeSessionClient = class {
|
|
8763
|
+
constructor(options) {
|
|
8764
|
+
this.options = options;
|
|
8765
|
+
}
|
|
8766
|
+
async resolve() {
|
|
8767
|
+
const session = this.options.sessionUuid ? await this.getPermanentComputeSession(this.options.sessionUuid) : await this.getOnDemandComputeSession();
|
|
8768
|
+
const pipelineFailure = pipelineErrorMessage(session);
|
|
8769
|
+
if (pipelineFailure) {
|
|
8770
|
+
throw new Error(pipelineFailure);
|
|
8771
|
+
}
|
|
8772
|
+
const accessToken = this.sessionAccessToken(session);
|
|
8773
|
+
await this.waitUntilReady(session, accessToken);
|
|
8774
|
+
const pipelineId = pipelineIdFromSession(session);
|
|
8775
|
+
if (this.options.pop && !pipelineId) {
|
|
8776
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
8777
|
+
}
|
|
8778
|
+
return {
|
|
8779
|
+
session,
|
|
8780
|
+
pipelineId,
|
|
8781
|
+
accessToken,
|
|
8782
|
+
accessTokenValidUntil: accessTokenValidUntil(session)
|
|
8783
|
+
};
|
|
8784
|
+
}
|
|
8785
|
+
async getOnDemandComputeSession() {
|
|
8786
|
+
let session = null;
|
|
8787
|
+
const sessionsUrl = `${this.options.computeUrl}/v1/sessions`;
|
|
8788
|
+
const headers = {
|
|
8789
|
+
Authorization: await this.options.authorizationHeader()
|
|
8790
|
+
};
|
|
8791
|
+
let sessions;
|
|
8792
|
+
if (!this.options.pop) {
|
|
8793
|
+
this.options.requestLogger?.debug("fetching sessions from: %s", sessionsUrl);
|
|
8794
|
+
const response = await this.options.httpClient.fetch(sessionsUrl, {
|
|
8795
|
+
headers
|
|
8796
|
+
});
|
|
8797
|
+
if (response.status == 404) {
|
|
8798
|
+
sessions = [];
|
|
8799
|
+
} else if (response.status != 200) {
|
|
8800
|
+
const message = await responseErrorMessage(response);
|
|
8801
|
+
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
8802
|
+
} else {
|
|
8803
|
+
const response_content = await responseJson(response);
|
|
8804
|
+
sessions = response_content;
|
|
8805
|
+
}
|
|
8806
|
+
if (sessions.length > 0) {
|
|
8807
|
+
this.options.logger?.debug(`User has ${sessions.length} sessions, inspecting for usable session`);
|
|
8808
|
+
for (let s of sessions) {
|
|
8809
|
+
if (!SESSION_DEAD.has(s.session_status) && !s.persistent && (!this.options.sessionName || s.session_name === this.options.sessionName)) {
|
|
8810
|
+
session = s;
|
|
8811
|
+
this.options.logger?.debug(`Use active session ${s.session_uuid} with pipeline ${pipelineIdFromSession(s)}`);
|
|
8812
|
+
break;
|
|
8813
|
+
}
|
|
8814
|
+
}
|
|
8815
|
+
}
|
|
8816
|
+
}
|
|
8817
|
+
if (!session) {
|
|
8818
|
+
this.options.requestLogger?.debug("creating a new session at: %s", sessionsUrl);
|
|
8819
|
+
const createBody = sessionCreateBody(this.options);
|
|
8820
|
+
const createHeaders = {
|
|
8821
|
+
...headers,
|
|
8822
|
+
...createBody ? { "Content-Type": "application/json" } : {}
|
|
8823
|
+
};
|
|
8824
|
+
const request = {
|
|
8825
|
+
headers: createHeaders,
|
|
8826
|
+
method: "POST"
|
|
8827
|
+
};
|
|
8828
|
+
if (createBody) {
|
|
8829
|
+
request.body = createBody;
|
|
8830
|
+
}
|
|
8831
|
+
const query = "wait=true";
|
|
8832
|
+
const response = await this.options.httpClient.fetch(`${sessionsUrl}?${query}`, request);
|
|
8833
|
+
if (response.status != 200) {
|
|
8834
|
+
const message = await responseErrorMessage(response);
|
|
8835
|
+
throw new Error(`Unexpected status ${response.status} creating a compute session: ${message}`);
|
|
8836
|
+
} else {
|
|
8837
|
+
sessions = await responseJson(response);
|
|
8838
|
+
}
|
|
8839
|
+
if (sessions.length == 0) {
|
|
8840
|
+
throw new Error("Unexpected, no compute session after attempt to create one");
|
|
8841
|
+
}
|
|
8842
|
+
session = sessions[0] || null;
|
|
8843
|
+
}
|
|
8844
|
+
if (!session) {
|
|
8845
|
+
throw new Error("unexpected undefined session");
|
|
8846
|
+
}
|
|
8847
|
+
return session;
|
|
8848
|
+
}
|
|
8849
|
+
async getPermanentComputeSession(sessionUuid) {
|
|
8850
|
+
let session = null;
|
|
8851
|
+
const sessionUrl = `${this.options.computeUrl}/v1/sessions/${sessionUuid}`;
|
|
8852
|
+
this.options.requestLogger?.debug("fetching session from: %s", sessionUrl);
|
|
8853
|
+
const headers = {
|
|
8854
|
+
Authorization: await this.options.authorizationHeader()
|
|
8855
|
+
};
|
|
8856
|
+
let response = await this.options.httpClient.fetch(sessionUrl, {
|
|
8857
|
+
headers
|
|
8858
|
+
});
|
|
8859
|
+
if (response.status == 404) {
|
|
8860
|
+
throw new Error(`Unexpected status ${response.status} compute sessions ${sessionUuid} not found`);
|
|
8861
|
+
} else if (response.status != 200) {
|
|
8862
|
+
const message = await responseErrorMessage(response);
|
|
8863
|
+
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
8864
|
+
} else {
|
|
8865
|
+
const response_content = await responseJson(response);
|
|
8866
|
+
session = response_content;
|
|
8867
|
+
}
|
|
8868
|
+
return session;
|
|
8869
|
+
}
|
|
8870
|
+
sessionAccessToken(session) {
|
|
8871
|
+
if (!session.access_token) {
|
|
8872
|
+
throw new Error(`Compute session ${session.session_uuid} did not provide an access token`);
|
|
8873
|
+
}
|
|
8874
|
+
return session.access_token;
|
|
8875
|
+
}
|
|
8876
|
+
async waitUntilReady(session, accessToken) {
|
|
8877
|
+
let isReady = false;
|
|
8878
|
+
const deadline = Date.now() + this.options.readyTimeoutMs;
|
|
8879
|
+
while (!isReady) {
|
|
8880
|
+
const health_url = `${session.session_endpoint}/health`;
|
|
8881
|
+
const response = await this.options.httpClient.fetch(health_url, {
|
|
8882
|
+
headers: {
|
|
8883
|
+
Authorization: `Bearer ${accessToken}`,
|
|
8884
|
+
Accept: "application/json"
|
|
8885
|
+
}
|
|
8886
|
+
});
|
|
8887
|
+
if (response.status == 200) {
|
|
8888
|
+
const contentType = response.headers.get("content-type") || "";
|
|
8889
|
+
const body = await response.text();
|
|
8890
|
+
try {
|
|
8891
|
+
isReady = sessionHealthReady(body, contentType);
|
|
8892
|
+
} catch (error) {
|
|
8893
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check returned invalid JSON, wait and poll for update`);
|
|
8894
|
+
}
|
|
8895
|
+
if (!isReady && Date.now() > deadline) {
|
|
8896
|
+
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${this.options.readyTimeoutMs / 1e3} seconds`);
|
|
8897
|
+
}
|
|
8898
|
+
if (!isReady) {
|
|
8899
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check not ready, wait and poll for update`);
|
|
8900
|
+
await sleep(CHECK_FOR_IS_READY_INTERVAL);
|
|
8901
|
+
}
|
|
8902
|
+
} else if (Date.now() > deadline) {
|
|
8903
|
+
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${this.options.readyTimeoutMs / 1e3} seconds`);
|
|
8904
|
+
} else {
|
|
8905
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check status ${response.status}, wait and poll for update`);
|
|
8906
|
+
await sleep(CHECK_FOR_IS_READY_INTERVAL);
|
|
8907
|
+
}
|
|
8908
|
+
}
|
|
8909
|
+
}
|
|
8910
|
+
};
|
|
8911
|
+
|
|
8635
8912
|
// types.ts
|
|
8636
8913
|
var EndpointState = /* @__PURE__ */ ((EndpointState2) => {
|
|
8637
8914
|
EndpointState2["Idle"] = "Idle";
|
|
@@ -8644,6 +8921,7 @@ var EndpointState = /* @__PURE__ */ ((EndpointState2) => {
|
|
|
8644
8921
|
})(EndpointState || {});
|
|
8645
8922
|
|
|
8646
8923
|
// streaming.ts
|
|
8924
|
+
import { v4 as uuidv4 } from "uuid";
|
|
8647
8925
|
var Stream = class _Stream {
|
|
8648
8926
|
constructor(iterator, controller) {
|
|
8649
8927
|
this.iterator = iterator;
|
|
@@ -8824,6 +9102,76 @@ function readableStreamFromString(s) {
|
|
|
8824
9102
|
}
|
|
8825
9103
|
});
|
|
8826
9104
|
}
|
|
9105
|
+
function randomMultipartBoundary() {
|
|
9106
|
+
return `----formdata-boundary-${uuidv4()}`;
|
|
9107
|
+
}
|
|
9108
|
+
function toPartStream(content) {
|
|
9109
|
+
if (content instanceof ReadableStream) {
|
|
9110
|
+
return content;
|
|
9111
|
+
}
|
|
9112
|
+
if (content instanceof Blob) {
|
|
9113
|
+
return content.stream();
|
|
9114
|
+
}
|
|
9115
|
+
const bytes = ArrayBuffer.isView(content) ? new Uint8Array(content.buffer, content.byteOffset, content.byteLength) : new Uint8Array(content);
|
|
9116
|
+
return new ReadableStream({
|
|
9117
|
+
start(controller) {
|
|
9118
|
+
controller.enqueue(bytes);
|
|
9119
|
+
controller.close();
|
|
9120
|
+
}
|
|
9121
|
+
});
|
|
9122
|
+
}
|
|
9123
|
+
async function cancelMultipartContent(content, reason) {
|
|
9124
|
+
if (content instanceof ReadableStream) {
|
|
9125
|
+
await content.cancel(reason);
|
|
9126
|
+
}
|
|
9127
|
+
}
|
|
9128
|
+
function encodeMultipartFormData(parts, boundary) {
|
|
9129
|
+
const encoder = new TextEncoder();
|
|
9130
|
+
let partIndex = 0;
|
|
9131
|
+
let reader = null;
|
|
9132
|
+
return new ReadableStream({
|
|
9133
|
+
async pull(controller) {
|
|
9134
|
+
if (reader) {
|
|
9135
|
+
const { done, value } = await reader.read();
|
|
9136
|
+
if (!done) {
|
|
9137
|
+
controller.enqueue(value);
|
|
9138
|
+
return;
|
|
9139
|
+
}
|
|
9140
|
+
reader = null;
|
|
9141
|
+
controller.enqueue(encoder.encode("\r\n"));
|
|
9142
|
+
partIndex++;
|
|
9143
|
+
}
|
|
9144
|
+
if (partIndex >= parts.length) {
|
|
9145
|
+
controller.enqueue(encoder.encode(`--${boundary}--\r
|
|
9146
|
+
`));
|
|
9147
|
+
controller.close();
|
|
9148
|
+
return;
|
|
9149
|
+
}
|
|
9150
|
+
const part = parts[partIndex];
|
|
9151
|
+
let header = `--${boundary}\r
|
|
9152
|
+
Content-Disposition: form-data; name="${part.name}"\r
|
|
9153
|
+
`;
|
|
9154
|
+
if (part.contentType) {
|
|
9155
|
+
header += `Content-Type: ${part.contentType}\r
|
|
9156
|
+
`;
|
|
9157
|
+
}
|
|
9158
|
+
header += "\r\n";
|
|
9159
|
+
controller.enqueue(encoder.encode(header));
|
|
9160
|
+
if (typeof part.content === "string") {
|
|
9161
|
+
controller.enqueue(encoder.encode(part.content));
|
|
9162
|
+
controller.enqueue(encoder.encode("\r\n"));
|
|
9163
|
+
partIndex++;
|
|
9164
|
+
} else {
|
|
9165
|
+
reader = toPartStream(part.content).getReader();
|
|
9166
|
+
}
|
|
9167
|
+
},
|
|
9168
|
+
async cancel(reason) {
|
|
9169
|
+
await reader?.cancel(reason);
|
|
9170
|
+
const firstUnstartedPart = reader ? partIndex + 1 : partIndex;
|
|
9171
|
+
await Promise.all(parts.slice(firstUnstartedPart).map((part) => cancelMultipartContent(part.content, reason)));
|
|
9172
|
+
}
|
|
9173
|
+
});
|
|
9174
|
+
}
|
|
8827
9175
|
|
|
8828
9176
|
// worker/worker_types.ts
|
|
8829
9177
|
var PredictionVersion = /* @__PURE__ */ ((PredictionVersion3) => {
|
|
@@ -8881,7 +9229,7 @@ var ContourType = /* @__PURE__ */ ((ContourType2) => {
|
|
|
8881
9229
|
})(ContourType || {});
|
|
8882
9230
|
|
|
8883
9231
|
// worker/webrtc_whip.ts
|
|
8884
|
-
import { v4 as
|
|
9232
|
+
import { v4 as uuidv42 } from "uuid";
|
|
8885
9233
|
|
|
8886
9234
|
// worker/webrtc_base.ts
|
|
8887
9235
|
import path from "path";
|
|
@@ -9156,7 +9504,7 @@ var WebrtcBase = class _WebrtcBase {
|
|
|
9156
9504
|
// worker/webrtc_whip.ts
|
|
9157
9505
|
var WebrtcWhip = class extends WebrtcBase {
|
|
9158
9506
|
constructor(stream, getSession, client, is_pipeline_direct, requestLogger) {
|
|
9159
|
-
super(getSession, client,
|
|
9507
|
+
super(getSession, client, uuidv42().toString(), "liveIngress/whip", is_pipeline_direct, requestLogger);
|
|
9160
9508
|
this._stream = stream;
|
|
9161
9509
|
}
|
|
9162
9510
|
async start() {
|
|
@@ -9330,14 +9678,18 @@ var UploadJob = class extends AbstractJob {
|
|
|
9330
9678
|
get [Symbol.toStringTag]() {
|
|
9331
9679
|
return "uploadJob";
|
|
9332
9680
|
}
|
|
9333
|
-
constructor(stream, mimeType, size, videoMode, params, getSession, client, requestLogger) {
|
|
9681
|
+
constructor(stream, mimeType, size, videoMode, params, getSession, client, requestLogger, uploadBodyFactory) {
|
|
9334
9682
|
super(params, getSession, client, requestLogger);
|
|
9335
9683
|
this._uploadStream = stream;
|
|
9684
|
+
this._uploadBodyFactory = uploadBodyFactory;
|
|
9336
9685
|
this._mimeType = mimeType;
|
|
9337
9686
|
this._size = size;
|
|
9338
9687
|
this._videoMode = videoMode;
|
|
9339
9688
|
this._needsFullDuplex = !client.isFullDuplex() && mimeType.startsWith("video/") && videoMode == "stream" /* STREAM */;
|
|
9340
9689
|
}
|
|
9690
|
+
async uploadBody() {
|
|
9691
|
+
return this._uploadBodyFactory ? await this._uploadBodyFactory() : this._uploadStream;
|
|
9692
|
+
}
|
|
9341
9693
|
async onEvent(event) {
|
|
9342
9694
|
if (event.type == "prepared") {
|
|
9343
9695
|
if (!event.source_id) {
|
|
@@ -9379,7 +9731,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9379
9731
|
const blob = new Blob([JSON.stringify(this._params.fps)], { type: "application/json" });
|
|
9380
9732
|
formData.append("fps", blob);
|
|
9381
9733
|
}
|
|
9382
|
-
const fileBlob = await new Response(this.
|
|
9734
|
+
const fileBlob = await new Response(await this.uploadBody()).blob();
|
|
9383
9735
|
formData.append("file", fileBlob);
|
|
9384
9736
|
const headers = {
|
|
9385
9737
|
...session.authenticationHeaders(),
|
|
@@ -9406,7 +9758,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9406
9758
|
request = this._client.fetch(postUrl, {
|
|
9407
9759
|
headers,
|
|
9408
9760
|
method: "POST",
|
|
9409
|
-
body: this.
|
|
9761
|
+
body: await this.uploadBody(),
|
|
9410
9762
|
signal: this._controller.signal,
|
|
9411
9763
|
// @ts-ignore
|
|
9412
9764
|
duplex: "half",
|
|
@@ -9474,7 +9826,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9474
9826
|
const blob = new Blob([JSON.stringify(this._params.fps)], { type: "application/json" });
|
|
9475
9827
|
formData.append("fps", blob);
|
|
9476
9828
|
}
|
|
9477
|
-
const fileBlob = await new Response(this.
|
|
9829
|
+
const fileBlob = await new Response(await this.uploadBody()).blob();
|
|
9478
9830
|
formData.append("file", fileBlob);
|
|
9479
9831
|
const headers = {
|
|
9480
9832
|
...session.authenticationHeaders(),
|
|
@@ -9501,7 +9853,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9501
9853
|
response = await this._client.fetch(postUrl, {
|
|
9502
9854
|
headers,
|
|
9503
9855
|
method: "POST",
|
|
9504
|
-
body: this.
|
|
9856
|
+
body: await this.uploadBody(),
|
|
9505
9857
|
signal: this._controller.signal,
|
|
9506
9858
|
// @ts-ignore
|
|
9507
9859
|
duplex: "half"
|
|
@@ -9551,6 +9903,111 @@ var LoadFromJob = class extends AbstractJob {
|
|
|
9551
9903
|
});
|
|
9552
9904
|
}
|
|
9553
9905
|
};
|
|
9906
|
+
var UploadGroupJob = class extends AbstractJob {
|
|
9907
|
+
get [Symbol.toStringTag]() {
|
|
9908
|
+
return "uploadGroupJob";
|
|
9909
|
+
}
|
|
9910
|
+
constructor(sources, params, getSession, client, requestLogger) {
|
|
9911
|
+
super(params, getSession, client, requestLogger);
|
|
9912
|
+
if (sources.length === 0) {
|
|
9913
|
+
throw new Error("upload group requires at least one source");
|
|
9914
|
+
}
|
|
9915
|
+
this._sources = sources;
|
|
9916
|
+
}
|
|
9917
|
+
async startJob() {
|
|
9918
|
+
const session = await this._getSession();
|
|
9919
|
+
if (!session.baseUrl) {
|
|
9920
|
+
return Promise.reject(new Error("session.baseUrl must not be null"));
|
|
9921
|
+
}
|
|
9922
|
+
const queryParams = new URLSearchParams({
|
|
9923
|
+
mode: "queue",
|
|
9924
|
+
processing: "sync"
|
|
9925
|
+
});
|
|
9926
|
+
if (this._version !== void 0) {
|
|
9927
|
+
queryParams.set("version", this._version.toString());
|
|
9928
|
+
}
|
|
9929
|
+
if (this._params.motionDetect) {
|
|
9930
|
+
for (const [key, value] of Object.entries(this._params.motionDetect)) {
|
|
9931
|
+
queryParams.set(key, value);
|
|
9932
|
+
}
|
|
9933
|
+
}
|
|
9934
|
+
const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?${queryParams.toString()}`;
|
|
9935
|
+
const parts = [];
|
|
9936
|
+
if (this._params.componentParams) {
|
|
9937
|
+
parts.push({ name: "params", contentType: "application/json", content: JSON.stringify(this._params.componentParams) });
|
|
9938
|
+
}
|
|
9939
|
+
if (this._params.roi) {
|
|
9940
|
+
parts.push({ name: "roi", contentType: "application/json", content: JSON.stringify(this._params.roi) });
|
|
9941
|
+
}
|
|
9942
|
+
if (this._params.fps) {
|
|
9943
|
+
parts.push({ name: "fps", contentType: "application/json", content: JSON.stringify(this._params.fps) });
|
|
9944
|
+
}
|
|
9945
|
+
for (const source of this._sources) {
|
|
9946
|
+
parts.push({ name: "file", contentType: source.mimeType, content: source.stream });
|
|
9947
|
+
}
|
|
9948
|
+
const boundary = randomMultipartBoundary();
|
|
9949
|
+
const headers = {
|
|
9950
|
+
...session.authenticationHeaders(),
|
|
9951
|
+
Accept: "application/jsonl",
|
|
9952
|
+
"Content-Type": `multipart/form-data; boundary=${boundary}`
|
|
9953
|
+
};
|
|
9954
|
+
return await this._client.fetch(postUrl, {
|
|
9955
|
+
headers,
|
|
9956
|
+
method: "POST",
|
|
9957
|
+
body: encodeMultipartFormData(parts, boundary),
|
|
9958
|
+
signal: this._controller.signal,
|
|
9959
|
+
// @ts-ignore
|
|
9960
|
+
duplex: "half",
|
|
9961
|
+
eyepop: { responseStreaming: true }
|
|
9962
|
+
});
|
|
9963
|
+
}
|
|
9964
|
+
};
|
|
9965
|
+
var LoadFromGroupJob = class extends AbstractJob {
|
|
9966
|
+
get [Symbol.toStringTag]() {
|
|
9967
|
+
return "loadFromGroupJob";
|
|
9968
|
+
}
|
|
9969
|
+
constructor(urls, params, getSession, client, requestLogger) {
|
|
9970
|
+
super(params, getSession, client, requestLogger);
|
|
9971
|
+
if (urls.length === 0) {
|
|
9972
|
+
throw new Error("load from group requires at least one url");
|
|
9973
|
+
}
|
|
9974
|
+
this._urls = urls;
|
|
9975
|
+
}
|
|
9976
|
+
async startJob() {
|
|
9977
|
+
const session = await this._getSession();
|
|
9978
|
+
if (!session.baseUrl) {
|
|
9979
|
+
return Promise.reject(new Error("session.baseUrl must not be null"));
|
|
9980
|
+
}
|
|
9981
|
+
const body = {
|
|
9982
|
+
sourceType: "GROUP",
|
|
9983
|
+
sources: this._urls.map((url) => ({ sourceType: "URL", url })),
|
|
9984
|
+
version: this._version
|
|
9985
|
+
};
|
|
9986
|
+
if (this._params.componentParams) {
|
|
9987
|
+
body["params"] = this._params.componentParams;
|
|
9988
|
+
}
|
|
9989
|
+
if (this._params.roi) {
|
|
9990
|
+
body["roi"] = this._params.roi;
|
|
9991
|
+
}
|
|
9992
|
+
if (this._params.motionDetect) {
|
|
9993
|
+
Object.assign(body, this._params.motionDetect);
|
|
9994
|
+
}
|
|
9995
|
+
const headers = {
|
|
9996
|
+
...session.authenticationHeaders(),
|
|
9997
|
+
Accept: "application/jsonl",
|
|
9998
|
+
"Content-Type": "application/json"
|
|
9999
|
+
};
|
|
10000
|
+
const patchUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
|
|
10001
|
+
return await this._client.fetch(patchUrl, {
|
|
10002
|
+
headers,
|
|
10003
|
+
method: "PATCH",
|
|
10004
|
+
body: JSON.stringify(body),
|
|
10005
|
+
signal: this._controller.signal,
|
|
10006
|
+
// @ts-ignore
|
|
10007
|
+
eyepop: { responseStreaming: true }
|
|
10008
|
+
});
|
|
10009
|
+
}
|
|
10010
|
+
};
|
|
9554
10011
|
var LoadFromAssetUuidJob = class extends AbstractJob {
|
|
9555
10012
|
constructor(assetUuid, params, getSession, client, requestLogger) {
|
|
9556
10013
|
super(params, getSession, client, requestLogger);
|
|
@@ -10152,21 +10609,6 @@ var TransientPopId = /* @__PURE__ */ ((TransientPopId2) => {
|
|
|
10152
10609
|
})(TransientPopId || {});
|
|
10153
10610
|
|
|
10154
10611
|
// worker/worker_endpoint.ts
|
|
10155
|
-
var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
|
|
10156
|
-
SessionStatus2["UNKNOWN"] = "unknown";
|
|
10157
|
-
SessionStatus2["PENDING"] = "pending";
|
|
10158
|
-
SessionStatus2["RUNNING"] = "running";
|
|
10159
|
-
SessionStatus2["STOPPED"] = "stopped";
|
|
10160
|
-
SessionStatus2["FAILED"] = "failed";
|
|
10161
|
-
SessionStatus2["ERROR"] = "error";
|
|
10162
|
-
SessionStatus2["PIPELINE_CREATING"] = "pipeline_creating";
|
|
10163
|
-
SessionStatus2["PIPELINE_OK"] = "pipeline_ok";
|
|
10164
|
-
SessionStatus2["PIPELINE_CHECKING"] = "pipeline_checking";
|
|
10165
|
-
SessionStatus2["PIPELINE_ERROR"] = "pipeline_error";
|
|
10166
|
-
SessionStatus2["UPGRADING"] = "upgrading";
|
|
10167
|
-
return SessionStatus2;
|
|
10168
|
-
})(SessionStatus || {});
|
|
10169
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10170
10612
|
var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
10171
10613
|
constructor(options) {
|
|
10172
10614
|
super(options);
|
|
@@ -10329,6 +10771,114 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10329
10771
|
return Promise.reject("unknown source type");
|
|
10330
10772
|
}
|
|
10331
10773
|
}
|
|
10774
|
+
async uploadGroup(paths, params = {}) {
|
|
10775
|
+
if (paths.length === 0) {
|
|
10776
|
+
throw new Error("upload group requires at least one path");
|
|
10777
|
+
}
|
|
10778
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10779
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10780
|
+
}
|
|
10781
|
+
await this._limit.acquire();
|
|
10782
|
+
try {
|
|
10783
|
+
this.updateState();
|
|
10784
|
+
const sources = await Promise.all(
|
|
10785
|
+
paths.map(async (path2) => {
|
|
10786
|
+
let streamSource;
|
|
10787
|
+
if (this._options.platformSupport?.resolvePath) {
|
|
10788
|
+
streamSource = await this._options.platformSupport.resolvePath({ path: path2 }, this._logger);
|
|
10789
|
+
} else {
|
|
10790
|
+
streamSource = await resolvePath({ path: path2 }, this._logger);
|
|
10791
|
+
}
|
|
10792
|
+
return { stream: streamSource.stream, mimeType: streamSource.mimeType };
|
|
10793
|
+
})
|
|
10794
|
+
);
|
|
10795
|
+
const job = new UploadGroupJob(
|
|
10796
|
+
sources,
|
|
10797
|
+
params,
|
|
10798
|
+
async () => this.session(),
|
|
10799
|
+
this._client,
|
|
10800
|
+
this._requestLogger
|
|
10801
|
+
);
|
|
10802
|
+
return job.start(
|
|
10803
|
+
() => {
|
|
10804
|
+
this.jobDone(job);
|
|
10805
|
+
},
|
|
10806
|
+
(statusCode) => {
|
|
10807
|
+
this.jobStatus(job, statusCode);
|
|
10808
|
+
}
|
|
10809
|
+
);
|
|
10810
|
+
} catch (e) {
|
|
10811
|
+
this._limit.release();
|
|
10812
|
+
throw e;
|
|
10813
|
+
}
|
|
10814
|
+
}
|
|
10815
|
+
async uploadStreamGroup(streams, mimeTypes, params = {}) {
|
|
10816
|
+
if (streams.length === 0) {
|
|
10817
|
+
throw new Error("upload stream group requires at least one stream");
|
|
10818
|
+
}
|
|
10819
|
+
if (mimeTypes !== void 0 && mimeTypes.length !== streams.length) {
|
|
10820
|
+
throw new Error("mimeTypes must have the same length as streams");
|
|
10821
|
+
}
|
|
10822
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10823
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10824
|
+
}
|
|
10825
|
+
await this._limit.acquire();
|
|
10826
|
+
try {
|
|
10827
|
+
this.updateState();
|
|
10828
|
+
const sources = streams.map((stream, i) => ({
|
|
10829
|
+
stream,
|
|
10830
|
+
mimeType: mimeTypes?.[i] ?? null
|
|
10831
|
+
}));
|
|
10832
|
+
const job = new UploadGroupJob(
|
|
10833
|
+
sources,
|
|
10834
|
+
params,
|
|
10835
|
+
async () => this.session(),
|
|
10836
|
+
this._client,
|
|
10837
|
+
this._requestLogger
|
|
10838
|
+
);
|
|
10839
|
+
return job.start(
|
|
10840
|
+
() => {
|
|
10841
|
+
this.jobDone(job);
|
|
10842
|
+
},
|
|
10843
|
+
(statusCode) => {
|
|
10844
|
+
this.jobStatus(job, statusCode);
|
|
10845
|
+
}
|
|
10846
|
+
);
|
|
10847
|
+
} catch (e) {
|
|
10848
|
+
this._limit.release();
|
|
10849
|
+
throw e;
|
|
10850
|
+
}
|
|
10851
|
+
}
|
|
10852
|
+
async loadFromGroup(urls, params = {}) {
|
|
10853
|
+
if (urls.length === 0) {
|
|
10854
|
+
throw new Error("load from group requires at least one url");
|
|
10855
|
+
}
|
|
10856
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10857
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10858
|
+
}
|
|
10859
|
+
await this._limit.acquire();
|
|
10860
|
+
try {
|
|
10861
|
+
this.updateState();
|
|
10862
|
+
const job = new LoadFromGroupJob(
|
|
10863
|
+
urls,
|
|
10864
|
+
params,
|
|
10865
|
+
async () => this.session(),
|
|
10866
|
+
this._client,
|
|
10867
|
+
this._requestLogger
|
|
10868
|
+
);
|
|
10869
|
+
return job.start(
|
|
10870
|
+
() => {
|
|
10871
|
+
this.jobDone(job);
|
|
10872
|
+
},
|
|
10873
|
+
(statusCode) => {
|
|
10874
|
+
this.jobStatus(job, statusCode);
|
|
10875
|
+
}
|
|
10876
|
+
);
|
|
10877
|
+
} catch (e) {
|
|
10878
|
+
this._limit.release();
|
|
10879
|
+
throw e;
|
|
10880
|
+
}
|
|
10881
|
+
}
|
|
10332
10882
|
async uploadFile(source, params) {
|
|
10333
10883
|
await this.ensureTransientPipelineStarted();
|
|
10334
10884
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
@@ -10403,12 +10953,21 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10403
10953
|
await this._limit.acquire();
|
|
10404
10954
|
try {
|
|
10405
10955
|
this.updateState();
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
|
|
10410
|
-
|
|
10411
|
-
}
|
|
10956
|
+
const resolveStreamSource = async () => {
|
|
10957
|
+
if (this._options.platformSupport?.resolvePath) {
|
|
10958
|
+
return await this._options.platformSupport.resolvePath(source, this._logger);
|
|
10959
|
+
}
|
|
10960
|
+
return await resolvePath(source, this._logger);
|
|
10961
|
+
};
|
|
10962
|
+
const streamSource = await resolveStreamSource();
|
|
10963
|
+
let firstStreamPending = true;
|
|
10964
|
+
const uploadBodyFactory = async () => {
|
|
10965
|
+
if (firstStreamPending) {
|
|
10966
|
+
firstStreamPending = false;
|
|
10967
|
+
return streamSource.stream;
|
|
10968
|
+
}
|
|
10969
|
+
return (await resolveStreamSource()).stream;
|
|
10970
|
+
};
|
|
10412
10971
|
const job = new UploadJob(
|
|
10413
10972
|
streamSource.stream,
|
|
10414
10973
|
streamSource.mimeType,
|
|
@@ -10419,7 +10978,8 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10419
10978
|
return this.session();
|
|
10420
10979
|
},
|
|
10421
10980
|
this._client,
|
|
10422
|
-
this._requestLogger
|
|
10981
|
+
this._requestLogger,
|
|
10982
|
+
uploadBodyFactory
|
|
10423
10983
|
);
|
|
10424
10984
|
return job.start(
|
|
10425
10985
|
() => {
|
|
@@ -10649,161 +11209,38 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10649
11209
|
const seconds = this.options().sessionReadyTimeoutSeconds;
|
|
10650
11210
|
return typeof seconds == "number" && Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : _WorkerEndpoint.WAIT_FOR_IS_READY;
|
|
10651
11211
|
}
|
|
10652
|
-
sessionHealthReady(body, contentType) {
|
|
10653
|
-
if (contentType.includes("application/json")) {
|
|
10654
|
-
const health = JSON.parse(body);
|
|
10655
|
-
if (health && typeof health == "object") {
|
|
10656
|
-
if (health.message && !health.session_status) {
|
|
10657
|
-
return true;
|
|
10658
|
-
}
|
|
10659
|
-
return health.session_status == "running" /* RUNNING */;
|
|
10660
|
-
}
|
|
10661
|
-
}
|
|
10662
|
-
return contentType.includes("text/plain") && body.includes("I'm fine");
|
|
10663
|
-
}
|
|
10664
11212
|
async getComputeSession() {
|
|
10665
11213
|
if (!this._client) {
|
|
10666
11214
|
throw new Error("endpoint not initialized");
|
|
10667
11215
|
}
|
|
10668
|
-
let
|
|
10669
|
-
|
|
10670
|
-
|
|
10671
|
-
|
|
10672
|
-
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10676
|
-
|
|
10677
|
-
|
|
10678
|
-
|
|
10679
|
-
|
|
10680
|
-
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10684
|
-
|
|
10685
|
-
|
|
10686
|
-
...headers,
|
|
10687
|
-
Accept: "application/json"
|
|
10688
|
-
}
|
|
10689
|
-
});
|
|
10690
|
-
if (response.status == 200) {
|
|
10691
|
-
const contentType = response.headers.get("content-type") || "";
|
|
10692
|
-
const body = await response.text();
|
|
10693
|
-
try {
|
|
10694
|
-
isReady = this.sessionHealthReady(body, contentType);
|
|
10695
|
-
} catch (error) {
|
|
10696
|
-
this._logger.debug(`session ${session.session_uuid} health check returned invalid JSON, wait and poll for update`);
|
|
10697
|
-
}
|
|
10698
|
-
if (!isReady && Date.now() > deadline) {
|
|
10699
|
-
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${readyTimeoutMs / 1e3} seconds`);
|
|
10700
|
-
}
|
|
10701
|
-
if (!isReady) {
|
|
10702
|
-
this._logger.debug(`session ${session.session_uuid} health check not ready, wait and poll for update`);
|
|
10703
|
-
await sleep(_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL);
|
|
10704
|
-
}
|
|
10705
|
-
} else if (Date.now() > deadline) {
|
|
10706
|
-
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${readyTimeoutMs / 1e3} seconds`);
|
|
10707
|
-
} else {
|
|
10708
|
-
this._logger.debug(`session ${session.session_uuid} health check status ${response.status}, wait and poll for update`);
|
|
10709
|
-
await sleep(_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL);
|
|
10710
|
-
}
|
|
11216
|
+
let resolved;
|
|
11217
|
+
try {
|
|
11218
|
+
resolved = await new ComputeSessionClient({
|
|
11219
|
+
computeUrl: this.eyepopUrl(),
|
|
11220
|
+
httpClient: this._client,
|
|
11221
|
+
authorizationHeader: () => this.computeAuthorizationHeader(),
|
|
11222
|
+
sessionUuid: this.options().sessionUuid,
|
|
11223
|
+
sessionName: this.options().sessionName,
|
|
11224
|
+
pipelineImage: this.options().pipelineImage,
|
|
11225
|
+
pipelineVersion: this.options().pipelineVersion,
|
|
11226
|
+
pop: this.options().pop,
|
|
11227
|
+
readyTimeoutMs: this.sessionReadyTimeoutMs(),
|
|
11228
|
+
logger: this._logger,
|
|
11229
|
+
requestLogger: this._requestLogger
|
|
11230
|
+
}).resolve();
|
|
11231
|
+
} catch (error) {
|
|
11232
|
+
this.updateState("Error" /* Error */);
|
|
11233
|
+
throw error;
|
|
10711
11234
|
}
|
|
10712
|
-
this.
|
|
11235
|
+
this._sessionAccessToken = resolved.accessToken;
|
|
11236
|
+
this._sessionAccessTokenValidUntil = resolved.accessTokenValidUntil;
|
|
11237
|
+
this._baseUrl = resolved.session.session_endpoint;
|
|
10713
11238
|
this._pipeline = null;
|
|
10714
|
-
this._pipelineId =
|
|
11239
|
+
this._pipelineId = resolved.pipelineId;
|
|
10715
11240
|
if (this.options().pop) {
|
|
10716
11241
|
this.setTransientPipelinePop();
|
|
10717
11242
|
}
|
|
10718
11243
|
}
|
|
10719
|
-
async getOnDemandComputeSession(httpClient) {
|
|
10720
|
-
let session = null;
|
|
10721
|
-
const sessionsUrl = `${this.eyepopUrl()}/v1/sessions`;
|
|
10722
|
-
const headers = {
|
|
10723
|
-
Authorization: await this.computeAuthorizationHeader()
|
|
10724
|
-
};
|
|
10725
|
-
let sessions;
|
|
10726
|
-
if (!this.options().pop) {
|
|
10727
|
-
this._requestLogger.debug("fetching sessions from: %s", sessionsUrl);
|
|
10728
|
-
const response = await httpClient.fetch(sessionsUrl, {
|
|
10729
|
-
headers
|
|
10730
|
-
});
|
|
10731
|
-
if (response.status == 404) {
|
|
10732
|
-
sessions = [];
|
|
10733
|
-
} else if (response.status != 200) {
|
|
10734
|
-
this.updateState("Error" /* Error */);
|
|
10735
|
-
const message = await response.text();
|
|
10736
|
-
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
10737
|
-
} else {
|
|
10738
|
-
const response_content = await response.json();
|
|
10739
|
-
sessions = response_content;
|
|
10740
|
-
}
|
|
10741
|
-
if (sessions.length > 0) {
|
|
10742
|
-
this._logger.debug(`User has ${sessions.length} sessions, inspecting for usable session`);
|
|
10743
|
-
for (let s of sessions) {
|
|
10744
|
-
if (!_WorkerEndpoint.SESSION_DEAD.has(s.session_status) && !s.persistent) {
|
|
10745
|
-
session = s;
|
|
10746
|
-
this._logger.debug(`Use active session ${s.session_uuid} with pipeline ${this.pipelineIdFromSession(s)}`);
|
|
10747
|
-
break;
|
|
10748
|
-
}
|
|
10749
|
-
}
|
|
10750
|
-
}
|
|
10751
|
-
}
|
|
10752
|
-
if (!session) {
|
|
10753
|
-
this._requestLogger.debug("creating a new session at: %s", sessionsUrl);
|
|
10754
|
-
const createBody = this.sessionCreateBody();
|
|
10755
|
-
const createHeaders = {
|
|
10756
|
-
...headers,
|
|
10757
|
-
...createBody ? { "Content-Type": "application/json" } : {}
|
|
10758
|
-
};
|
|
10759
|
-
const request = {
|
|
10760
|
-
headers: createHeaders,
|
|
10761
|
-
method: "POST"
|
|
10762
|
-
};
|
|
10763
|
-
if (createBody) {
|
|
10764
|
-
request.body = createBody;
|
|
10765
|
-
}
|
|
10766
|
-
const response = await httpClient.fetch(`${sessionsUrl}?wait=true`, request);
|
|
10767
|
-
if (response.status != 200) {
|
|
10768
|
-
this.updateState("Error" /* Error */);
|
|
10769
|
-
const message = await response.text();
|
|
10770
|
-
throw new Error(`Unexpected status ${response.status} creating a compute session: ${message}`);
|
|
10771
|
-
} else {
|
|
10772
|
-
sessions = await response.json();
|
|
10773
|
-
}
|
|
10774
|
-
if (sessions.length == 0) {
|
|
10775
|
-
throw new Error("Unexpected, no compute session after attempt to create one");
|
|
10776
|
-
}
|
|
10777
|
-
session = sessions[0] || null;
|
|
10778
|
-
}
|
|
10779
|
-
if (!session) {
|
|
10780
|
-
throw new Error("unexpected undefined session");
|
|
10781
|
-
}
|
|
10782
|
-
return session;
|
|
10783
|
-
}
|
|
10784
|
-
async getPermanentComputeSession(httpClient, sessionUuid) {
|
|
10785
|
-
let session = null;
|
|
10786
|
-
const sessionUrl = `${this.eyepopUrl()}/v1/sessions/${sessionUuid}`;
|
|
10787
|
-
this._requestLogger.debug("fetching session from: %s", sessionUrl);
|
|
10788
|
-
const headers = {
|
|
10789
|
-
Authorization: await this.computeAuthorizationHeader()
|
|
10790
|
-
};
|
|
10791
|
-
let response = await httpClient.fetch(sessionUrl, {
|
|
10792
|
-
headers
|
|
10793
|
-
});
|
|
10794
|
-
if (response.status == 404) {
|
|
10795
|
-
this.updateState("Error" /* Error */);
|
|
10796
|
-
throw new Error(`Unexpected status ${response.status} compute sessions ${sessionUuid} not found`);
|
|
10797
|
-
} else if (response.status != 200) {
|
|
10798
|
-
this.updateState("Error" /* Error */);
|
|
10799
|
-
const message = await response.text();
|
|
10800
|
-
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
10801
|
-
} else {
|
|
10802
|
-
const response_content = await response.json();
|
|
10803
|
-
session = response_content;
|
|
10804
|
-
}
|
|
10805
|
-
return session;
|
|
10806
|
-
}
|
|
10807
11244
|
async startTransientPipeline() {
|
|
10808
11245
|
const client = this._client;
|
|
10809
11246
|
const baseUrl = this._baseUrl;
|
|
@@ -10860,6 +11297,13 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10860
11297
|
if (this._pipelineId) {
|
|
10861
11298
|
return;
|
|
10862
11299
|
}
|
|
11300
|
+
if (this.options().pop) {
|
|
11301
|
+
await this.reconnect();
|
|
11302
|
+
if (!this._pipelineId) {
|
|
11303
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
11304
|
+
}
|
|
11305
|
+
return;
|
|
11306
|
+
}
|
|
10863
11307
|
if (!this._pipelineCreatePromise) {
|
|
10864
11308
|
this._pipelineCreatePromise = this.startTransientPipeline();
|
|
10865
11309
|
}
|
|
@@ -10875,7 +11319,9 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10875
11319
|
throw new Error("endpoint not initialized");
|
|
10876
11320
|
}
|
|
10877
11321
|
const previousPop = this.options().pop;
|
|
10878
|
-
const
|
|
11322
|
+
const previousBaseUrl = this._baseUrl;
|
|
11323
|
+
const previousSessionAccessToken = this._sessionAccessToken;
|
|
11324
|
+
const previousSessionAccessTokenValidUntil = this._sessionAccessTokenValidUntil;
|
|
10879
11325
|
if (this._pipelineId) {
|
|
10880
11326
|
await this.deleteTransientPipeline(this._pipelineId);
|
|
10881
11327
|
this._pipelineId = null;
|
|
@@ -10883,10 +11329,14 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10883
11329
|
this._pipeline = null;
|
|
10884
11330
|
try {
|
|
10885
11331
|
this.options().pop = pop;
|
|
10886
|
-
await this.
|
|
11332
|
+
await this.getComputeSession();
|
|
10887
11333
|
} catch (error) {
|
|
10888
11334
|
this.options().pop = previousPop;
|
|
10889
|
-
this._pipeline =
|
|
11335
|
+
this._pipeline = null;
|
|
11336
|
+
this._pipelineId = null;
|
|
11337
|
+
this._baseUrl = previousPop ? null : previousBaseUrl;
|
|
11338
|
+
this._sessionAccessToken = previousSessionAccessToken;
|
|
11339
|
+
this._sessionAccessTokenValidUntil = previousSessionAccessTokenValidUntil;
|
|
10890
11340
|
throw error;
|
|
10891
11341
|
}
|
|
10892
11342
|
if (!this._pipelineId) {
|
|
@@ -10911,13 +11361,6 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10911
11361
|
this._logger.info(`stopping pipeline failed, status ${response.status}: ${message}`);
|
|
10912
11362
|
}
|
|
10913
11363
|
}
|
|
10914
|
-
pipelineIdFromSession(session) {
|
|
10915
|
-
if (session.pipeline_uuid) {
|
|
10916
|
-
return session.pipeline_uuid;
|
|
10917
|
-
}
|
|
10918
|
-
const pipeline = session.pipelines?.[0];
|
|
10919
|
-
return pipeline?.id || pipeline?.pipeline_id || null;
|
|
10920
|
-
}
|
|
10921
11364
|
async authorizationHeader() {
|
|
10922
11365
|
if (this._sessionAccessToken) {
|
|
10923
11366
|
return `Bearer ${this._sessionAccessToken}`;
|
|
@@ -10933,20 +11376,6 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10933
11376
|
}
|
|
10934
11377
|
return super.authorizationHeader();
|
|
10935
11378
|
}
|
|
10936
|
-
setComputeSessionAccessToken(session) {
|
|
10937
|
-
if (!session.access_token) {
|
|
10938
|
-
throw new Error(`Compute session ${session.session_uuid} did not provide an access token`);
|
|
10939
|
-
}
|
|
10940
|
-
this._sessionAccessToken = session.access_token;
|
|
10941
|
-
if (session.access_token_expires_at) {
|
|
10942
|
-
const expiresAt = Date.parse(session.access_token_expires_at);
|
|
10943
|
-
this._sessionAccessTokenValidUntil = Number.isNaN(expiresAt) ? null : expiresAt;
|
|
10944
|
-
} else if (session.access_token_expires_in) {
|
|
10945
|
-
this._sessionAccessTokenValidUntil = Date.now() + session.access_token_expires_in * 1e3;
|
|
10946
|
-
} else {
|
|
10947
|
-
this._sessionAccessTokenValidUntil = null;
|
|
10948
|
-
}
|
|
10949
|
-
}
|
|
10950
11379
|
setTransientPipelinePop() {
|
|
10951
11380
|
const pop = this.options().pop;
|
|
10952
11381
|
if (pop && this._pipelineId) {
|
|
@@ -10958,26 +11387,8 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10958
11387
|
};
|
|
10959
11388
|
}
|
|
10960
11389
|
}
|
|
10961
|
-
sessionCreateBody() {
|
|
10962
|
-
const body = {};
|
|
10963
|
-
if (this.options().sessionName) {
|
|
10964
|
-
body.session_name = this.options().sessionName;
|
|
10965
|
-
}
|
|
10966
|
-
if (this.options().pipelineImage) {
|
|
10967
|
-
body.pipeline_image = this.options().pipelineImage;
|
|
10968
|
-
}
|
|
10969
|
-
if (this.options().pipelineVersion) {
|
|
10970
|
-
body.pipeline_version = this.options().pipelineVersion;
|
|
10971
|
-
}
|
|
10972
|
-
if (this.options().pop) {
|
|
10973
|
-
body.pop = this.options().pop;
|
|
10974
|
-
}
|
|
10975
|
-
return Object.keys(body).length > 0 ? JSON.stringify(body) : void 0;
|
|
10976
|
-
}
|
|
10977
11390
|
};
|
|
10978
|
-
_WorkerEndpoint.SESSION_DEAD = /* @__PURE__ */ new Set(["error" /* ERROR */, "failed" /* FAILED */, "stopped" /* STOPPED */, "pipeline_error" /* PIPELINE_ERROR */, "unknown" /* UNKNOWN */]);
|
|
10979
11391
|
_WorkerEndpoint.WAIT_FOR_IS_READY = 60 * 1e3;
|
|
10980
|
-
_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL = 250;
|
|
10981
11392
|
var WorkerEndpoint = _WorkerEndpoint;
|
|
10982
11393
|
|
|
10983
11394
|
// shims/websockets.ts
|
|
@@ -12468,6 +12879,7 @@ export {
|
|
|
12468
12879
|
ForwardOperatorType,
|
|
12469
12880
|
InferenceType,
|
|
12470
12881
|
LoadFromAssetUuidJob,
|
|
12882
|
+
LoadFromGroupJob,
|
|
12471
12883
|
LoadFromJob,
|
|
12472
12884
|
LoadMediaStreamJob,
|
|
12473
12885
|
ModelExportStatus,
|
|
@@ -12481,12 +12893,12 @@ export {
|
|
|
12481
12893
|
PopComponentType,
|
|
12482
12894
|
PredictionVersion,
|
|
12483
12895
|
Semaphore,
|
|
12484
|
-
SessionStatus,
|
|
12485
12896
|
Stream,
|
|
12486
12897
|
TaskMode,
|
|
12487
12898
|
TaskType,
|
|
12488
12899
|
TranscodeMode,
|
|
12489
12900
|
TransientPopId,
|
|
12901
|
+
UploadGroupJob,
|
|
12490
12902
|
UploadJob,
|
|
12491
12903
|
UserReview,
|
|
12492
12904
|
VideoMode,
|
|
@@ -12497,7 +12909,9 @@ export {
|
|
|
12497
12909
|
WorkerEndpoint,
|
|
12498
12910
|
WorkflowPhase,
|
|
12499
12911
|
index_default as default,
|
|
12912
|
+
encodeMultipartFormData,
|
|
12500
12913
|
getBaseUrl,
|
|
12914
|
+
randomMultipartBoundary,
|
|
12501
12915
|
readableStreamFromString
|
|
12502
12916
|
};
|
|
12503
12917
|
/*! Bundled license information:
|