@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.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,290 @@ __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
|
+
function errorInfoMessage(errorInfo) {
|
|
8770
|
+
return [errorInfo.code, errorInfo.message, errorInfo.details].filter((part) => typeof part == "string" && part.length > 0).join(": ");
|
|
8771
|
+
}
|
|
8772
|
+
function pipelineErrorMessage(session) {
|
|
8773
|
+
if (session.pipeline_error) {
|
|
8774
|
+
const message = errorInfoMessage(session.pipeline_error);
|
|
8775
|
+
return message ? `Pipeline failed for compute session ${session.session_uuid}: ${message}` : `Pipeline failed for compute session ${session.session_uuid}`;
|
|
8776
|
+
}
|
|
8777
|
+
if (session.session_status == "pipeline_error" /* PIPELINE_ERROR */) {
|
|
8778
|
+
return `Pipeline failed for compute session ${session.session_uuid}`;
|
|
8779
|
+
}
|
|
8780
|
+
return null;
|
|
8781
|
+
}
|
|
8782
|
+
async function responseErrorMessage(response) {
|
|
8783
|
+
const contentType = response.headers.get("content-type") || "";
|
|
8784
|
+
if (contentType.includes("application/json")) {
|
|
8785
|
+
try {
|
|
8786
|
+
const parsed = normalizedJsonValue(await response.clone().json());
|
|
8787
|
+
const message2 = normalizedErrorMessage(parsed);
|
|
8788
|
+
if (message2) {
|
|
8789
|
+
return message2;
|
|
8790
|
+
}
|
|
8791
|
+
} catch (_) {
|
|
8792
|
+
}
|
|
8793
|
+
}
|
|
8794
|
+
const body = await response.text();
|
|
8795
|
+
const message = normalizedErrorMessage(body);
|
|
8796
|
+
return message || body;
|
|
8797
|
+
}
|
|
8798
|
+
function normalizedJsonValue(value) {
|
|
8799
|
+
if (typeof value == "string") {
|
|
8800
|
+
try {
|
|
8801
|
+
const parsed = JSON.parse(value);
|
|
8802
|
+
return normalizedJsonValue(parsed);
|
|
8803
|
+
} catch (_) {
|
|
8804
|
+
const unescaped = value.replace(/\\"/g, '"');
|
|
8805
|
+
if (unescaped != value) {
|
|
8806
|
+
try {
|
|
8807
|
+
const parsed = JSON.parse(unescaped);
|
|
8808
|
+
return normalizedJsonValue(parsed);
|
|
8809
|
+
} catch (_2) {
|
|
8810
|
+
}
|
|
8811
|
+
}
|
|
8812
|
+
return value;
|
|
8813
|
+
}
|
|
8814
|
+
}
|
|
8815
|
+
return value;
|
|
8816
|
+
}
|
|
8817
|
+
async function responseJson(response) {
|
|
8818
|
+
return normalizedJsonValue(await response.json());
|
|
8819
|
+
}
|
|
8820
|
+
function normalizedErrorMessage(value) {
|
|
8821
|
+
value = normalizedJsonValue(value);
|
|
8822
|
+
if (typeof value == "string") {
|
|
8823
|
+
return value;
|
|
8824
|
+
}
|
|
8825
|
+
if (!value || typeof value != "object") {
|
|
8826
|
+
return null;
|
|
8827
|
+
}
|
|
8828
|
+
const record = value;
|
|
8829
|
+
const normalizedError = normalizedJsonValue(record["error"]);
|
|
8830
|
+
const errorMessage = normalizedErrorMessage(normalizedError) || (typeof normalizedError == "string" ? normalizedError : null);
|
|
8831
|
+
const message = [record["code"], errorMessage, record["message"], record["details"]].filter((part) => typeof part == "string" && part.length > 0).join(": ");
|
|
8832
|
+
if (message) {
|
|
8833
|
+
return message;
|
|
8834
|
+
}
|
|
8835
|
+
if (record["pipeline_error"]) {
|
|
8836
|
+
return normalizedErrorMessage(record["pipeline_error"]);
|
|
8837
|
+
}
|
|
8838
|
+
if (normalizedError && typeof normalizedError == "object") {
|
|
8839
|
+
return normalizedErrorMessage(normalizedError);
|
|
8840
|
+
}
|
|
8841
|
+
try {
|
|
8842
|
+
return JSON.stringify(value);
|
|
8843
|
+
} catch (_) {
|
|
8844
|
+
return null;
|
|
8845
|
+
}
|
|
8846
|
+
}
|
|
8847
|
+
var ComputeSessionClient = class {
|
|
8848
|
+
constructor(options) {
|
|
8849
|
+
this.options = options;
|
|
8850
|
+
}
|
|
8851
|
+
async resolve() {
|
|
8852
|
+
const session = this.options.sessionUuid ? await this.getPermanentComputeSession(this.options.sessionUuid) : await this.getOnDemandComputeSession();
|
|
8853
|
+
const pipelineFailure = pipelineErrorMessage(session);
|
|
8854
|
+
if (pipelineFailure) {
|
|
8855
|
+
throw new Error(pipelineFailure);
|
|
8856
|
+
}
|
|
8857
|
+
const accessToken = this.sessionAccessToken(session);
|
|
8858
|
+
await this.waitUntilReady(session, accessToken);
|
|
8859
|
+
const pipelineId = pipelineIdFromSession(session);
|
|
8860
|
+
if (this.options.pop && !pipelineId) {
|
|
8861
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
8862
|
+
}
|
|
8863
|
+
return {
|
|
8864
|
+
session,
|
|
8865
|
+
pipelineId,
|
|
8866
|
+
accessToken,
|
|
8867
|
+
accessTokenValidUntil: accessTokenValidUntil(session)
|
|
8868
|
+
};
|
|
8869
|
+
}
|
|
8870
|
+
async getOnDemandComputeSession() {
|
|
8871
|
+
let session = null;
|
|
8872
|
+
const sessionsUrl = `${this.options.computeUrl}/v1/sessions`;
|
|
8873
|
+
const headers = {
|
|
8874
|
+
Authorization: await this.options.authorizationHeader()
|
|
8875
|
+
};
|
|
8876
|
+
let sessions;
|
|
8877
|
+
if (!this.options.pop) {
|
|
8878
|
+
this.options.requestLogger?.debug("fetching sessions from: %s", sessionsUrl);
|
|
8879
|
+
const response = await this.options.httpClient.fetch(sessionsUrl, {
|
|
8880
|
+
headers
|
|
8881
|
+
});
|
|
8882
|
+
if (response.status == 404) {
|
|
8883
|
+
sessions = [];
|
|
8884
|
+
} else if (response.status != 200) {
|
|
8885
|
+
const message = await responseErrorMessage(response);
|
|
8886
|
+
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
8887
|
+
} else {
|
|
8888
|
+
const response_content = await responseJson(response);
|
|
8889
|
+
sessions = response_content;
|
|
8890
|
+
}
|
|
8891
|
+
if (sessions.length > 0) {
|
|
8892
|
+
this.options.logger?.debug(`User has ${sessions.length} sessions, inspecting for usable session`);
|
|
8893
|
+
for (let s of sessions) {
|
|
8894
|
+
if (!SESSION_DEAD.has(s.session_status) && !s.persistent && (!this.options.sessionName || s.session_name === this.options.sessionName)) {
|
|
8895
|
+
session = s;
|
|
8896
|
+
this.options.logger?.debug(`Use active session ${s.session_uuid} with pipeline ${pipelineIdFromSession(s)}`);
|
|
8897
|
+
break;
|
|
8898
|
+
}
|
|
8899
|
+
}
|
|
8900
|
+
}
|
|
8901
|
+
}
|
|
8902
|
+
if (!session) {
|
|
8903
|
+
this.options.requestLogger?.debug("creating a new session at: %s", sessionsUrl);
|
|
8904
|
+
const createBody = sessionCreateBody(this.options);
|
|
8905
|
+
const createHeaders = {
|
|
8906
|
+
...headers,
|
|
8907
|
+
...createBody ? { "Content-Type": "application/json" } : {}
|
|
8908
|
+
};
|
|
8909
|
+
const request = {
|
|
8910
|
+
headers: createHeaders,
|
|
8911
|
+
method: "POST"
|
|
8912
|
+
};
|
|
8913
|
+
if (createBody) {
|
|
8914
|
+
request.body = createBody;
|
|
8915
|
+
}
|
|
8916
|
+
const query = "wait=true";
|
|
8917
|
+
const response = await this.options.httpClient.fetch(`${sessionsUrl}?${query}`, request);
|
|
8918
|
+
if (response.status != 200) {
|
|
8919
|
+
const message = await responseErrorMessage(response);
|
|
8920
|
+
throw new Error(`Unexpected status ${response.status} creating a compute session: ${message}`);
|
|
8921
|
+
} else {
|
|
8922
|
+
sessions = await responseJson(response);
|
|
8923
|
+
}
|
|
8924
|
+
if (sessions.length == 0) {
|
|
8925
|
+
throw new Error("Unexpected, no compute session after attempt to create one");
|
|
8926
|
+
}
|
|
8927
|
+
session = sessions[0] || null;
|
|
8928
|
+
}
|
|
8929
|
+
if (!session) {
|
|
8930
|
+
throw new Error("unexpected undefined session");
|
|
8931
|
+
}
|
|
8932
|
+
return session;
|
|
8933
|
+
}
|
|
8934
|
+
async getPermanentComputeSession(sessionUuid) {
|
|
8935
|
+
let session = null;
|
|
8936
|
+
const sessionUrl = `${this.options.computeUrl}/v1/sessions/${sessionUuid}`;
|
|
8937
|
+
this.options.requestLogger?.debug("fetching session from: %s", sessionUrl);
|
|
8938
|
+
const headers = {
|
|
8939
|
+
Authorization: await this.options.authorizationHeader()
|
|
8940
|
+
};
|
|
8941
|
+
let response = await this.options.httpClient.fetch(sessionUrl, {
|
|
8942
|
+
headers
|
|
8943
|
+
});
|
|
8944
|
+
if (response.status == 404) {
|
|
8945
|
+
throw new Error(`Unexpected status ${response.status} compute sessions ${sessionUuid} not found`);
|
|
8946
|
+
} else if (response.status != 200) {
|
|
8947
|
+
const message = await responseErrorMessage(response);
|
|
8948
|
+
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
8949
|
+
} else {
|
|
8950
|
+
const response_content = await responseJson(response);
|
|
8951
|
+
session = response_content;
|
|
8952
|
+
}
|
|
8953
|
+
return session;
|
|
8954
|
+
}
|
|
8955
|
+
sessionAccessToken(session) {
|
|
8956
|
+
if (!session.access_token) {
|
|
8957
|
+
throw new Error(`Compute session ${session.session_uuid} did not provide an access token`);
|
|
8958
|
+
}
|
|
8959
|
+
return session.access_token;
|
|
8960
|
+
}
|
|
8961
|
+
async waitUntilReady(session, accessToken) {
|
|
8962
|
+
let isReady = false;
|
|
8963
|
+
const deadline = Date.now() + this.options.readyTimeoutMs;
|
|
8964
|
+
while (!isReady) {
|
|
8965
|
+
const health_url = `${session.session_endpoint}/health`;
|
|
8966
|
+
const response = await this.options.httpClient.fetch(health_url, {
|
|
8967
|
+
headers: {
|
|
8968
|
+
Authorization: `Bearer ${accessToken}`,
|
|
8969
|
+
Accept: "application/json"
|
|
8970
|
+
}
|
|
8971
|
+
});
|
|
8972
|
+
if (response.status == 200) {
|
|
8973
|
+
const contentType = response.headers.get("content-type") || "";
|
|
8974
|
+
const body = await response.text();
|
|
8975
|
+
try {
|
|
8976
|
+
isReady = sessionHealthReady(body, contentType);
|
|
8977
|
+
} catch (error) {
|
|
8978
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check returned invalid JSON, wait and poll for update`);
|
|
8979
|
+
}
|
|
8980
|
+
if (!isReady && Date.now() > deadline) {
|
|
8981
|
+
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${this.options.readyTimeoutMs / 1e3} seconds`);
|
|
8982
|
+
}
|
|
8983
|
+
if (!isReady) {
|
|
8984
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check not ready, wait and poll for update`);
|
|
8985
|
+
await sleep(CHECK_FOR_IS_READY_INTERVAL);
|
|
8986
|
+
}
|
|
8987
|
+
} else if (Date.now() > deadline) {
|
|
8988
|
+
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${this.options.readyTimeoutMs / 1e3} seconds`);
|
|
8989
|
+
} else {
|
|
8990
|
+
this.options.logger?.debug(`session ${session.session_uuid} health check status ${response.status}, wait and poll for update`);
|
|
8991
|
+
await sleep(CHECK_FOR_IS_READY_INTERVAL);
|
|
8992
|
+
}
|
|
8993
|
+
}
|
|
8994
|
+
}
|
|
8995
|
+
};
|
|
8996
|
+
|
|
8717
8997
|
// types.ts
|
|
8718
8998
|
var EndpointState = /* @__PURE__ */ ((EndpointState2) => {
|
|
8719
8999
|
EndpointState2["Idle"] = "Idle";
|
|
@@ -8726,6 +9006,7 @@ var EndpointState = /* @__PURE__ */ ((EndpointState2) => {
|
|
|
8726
9006
|
})(EndpointState || {});
|
|
8727
9007
|
|
|
8728
9008
|
// streaming.ts
|
|
9009
|
+
var import_uuid = require("uuid");
|
|
8729
9010
|
var Stream = class _Stream {
|
|
8730
9011
|
constructor(iterator, controller) {
|
|
8731
9012
|
this.iterator = iterator;
|
|
@@ -8906,6 +9187,76 @@ function readableStreamFromString(s) {
|
|
|
8906
9187
|
}
|
|
8907
9188
|
});
|
|
8908
9189
|
}
|
|
9190
|
+
function randomMultipartBoundary() {
|
|
9191
|
+
return `----formdata-boundary-${(0, import_uuid.v4)()}`;
|
|
9192
|
+
}
|
|
9193
|
+
function toPartStream(content) {
|
|
9194
|
+
if (content instanceof ReadableStream) {
|
|
9195
|
+
return content;
|
|
9196
|
+
}
|
|
9197
|
+
if (content instanceof Blob) {
|
|
9198
|
+
return content.stream();
|
|
9199
|
+
}
|
|
9200
|
+
const bytes = ArrayBuffer.isView(content) ? new Uint8Array(content.buffer, content.byteOffset, content.byteLength) : new Uint8Array(content);
|
|
9201
|
+
return new ReadableStream({
|
|
9202
|
+
start(controller) {
|
|
9203
|
+
controller.enqueue(bytes);
|
|
9204
|
+
controller.close();
|
|
9205
|
+
}
|
|
9206
|
+
});
|
|
9207
|
+
}
|
|
9208
|
+
async function cancelMultipartContent(content, reason) {
|
|
9209
|
+
if (content instanceof ReadableStream) {
|
|
9210
|
+
await content.cancel(reason);
|
|
9211
|
+
}
|
|
9212
|
+
}
|
|
9213
|
+
function encodeMultipartFormData(parts, boundary) {
|
|
9214
|
+
const encoder = new TextEncoder();
|
|
9215
|
+
let partIndex = 0;
|
|
9216
|
+
let reader = null;
|
|
9217
|
+
return new ReadableStream({
|
|
9218
|
+
async pull(controller) {
|
|
9219
|
+
if (reader) {
|
|
9220
|
+
const { done, value } = await reader.read();
|
|
9221
|
+
if (!done) {
|
|
9222
|
+
controller.enqueue(value);
|
|
9223
|
+
return;
|
|
9224
|
+
}
|
|
9225
|
+
reader = null;
|
|
9226
|
+
controller.enqueue(encoder.encode("\r\n"));
|
|
9227
|
+
partIndex++;
|
|
9228
|
+
}
|
|
9229
|
+
if (partIndex >= parts.length) {
|
|
9230
|
+
controller.enqueue(encoder.encode(`--${boundary}--\r
|
|
9231
|
+
`));
|
|
9232
|
+
controller.close();
|
|
9233
|
+
return;
|
|
9234
|
+
}
|
|
9235
|
+
const part = parts[partIndex];
|
|
9236
|
+
let header = `--${boundary}\r
|
|
9237
|
+
Content-Disposition: form-data; name="${part.name}"\r
|
|
9238
|
+
`;
|
|
9239
|
+
if (part.contentType) {
|
|
9240
|
+
header += `Content-Type: ${part.contentType}\r
|
|
9241
|
+
`;
|
|
9242
|
+
}
|
|
9243
|
+
header += "\r\n";
|
|
9244
|
+
controller.enqueue(encoder.encode(header));
|
|
9245
|
+
if (typeof part.content === "string") {
|
|
9246
|
+
controller.enqueue(encoder.encode(part.content));
|
|
9247
|
+
controller.enqueue(encoder.encode("\r\n"));
|
|
9248
|
+
partIndex++;
|
|
9249
|
+
} else {
|
|
9250
|
+
reader = toPartStream(part.content).getReader();
|
|
9251
|
+
}
|
|
9252
|
+
},
|
|
9253
|
+
async cancel(reason) {
|
|
9254
|
+
await reader?.cancel(reason);
|
|
9255
|
+
const firstUnstartedPart = reader ? partIndex + 1 : partIndex;
|
|
9256
|
+
await Promise.all(parts.slice(firstUnstartedPart).map((part) => cancelMultipartContent(part.content, reason)));
|
|
9257
|
+
}
|
|
9258
|
+
});
|
|
9259
|
+
}
|
|
8909
9260
|
|
|
8910
9261
|
// worker/worker_types.ts
|
|
8911
9262
|
var PredictionVersion = /* @__PURE__ */ ((PredictionVersion3) => {
|
|
@@ -8963,7 +9314,7 @@ var ContourType = /* @__PURE__ */ ((ContourType2) => {
|
|
|
8963
9314
|
})(ContourType || {});
|
|
8964
9315
|
|
|
8965
9316
|
// worker/webrtc_whip.ts
|
|
8966
|
-
var
|
|
9317
|
+
var import_uuid2 = require("uuid");
|
|
8967
9318
|
|
|
8968
9319
|
// worker/webrtc_base.ts
|
|
8969
9320
|
var import_path = __toESM(require("path"));
|
|
@@ -9238,7 +9589,7 @@ var WebrtcBase = class _WebrtcBase {
|
|
|
9238
9589
|
// worker/webrtc_whip.ts
|
|
9239
9590
|
var WebrtcWhip = class extends WebrtcBase {
|
|
9240
9591
|
constructor(stream, getSession, client, is_pipeline_direct, requestLogger) {
|
|
9241
|
-
super(getSession, client, (0,
|
|
9592
|
+
super(getSession, client, (0, import_uuid2.v4)().toString(), "liveIngress/whip", is_pipeline_direct, requestLogger);
|
|
9242
9593
|
this._stream = stream;
|
|
9243
9594
|
}
|
|
9244
9595
|
async start() {
|
|
@@ -9412,14 +9763,18 @@ var UploadJob = class extends AbstractJob {
|
|
|
9412
9763
|
get [Symbol.toStringTag]() {
|
|
9413
9764
|
return "uploadJob";
|
|
9414
9765
|
}
|
|
9415
|
-
constructor(stream, mimeType, size, videoMode, params, getSession, client, requestLogger) {
|
|
9766
|
+
constructor(stream, mimeType, size, videoMode, params, getSession, client, requestLogger, uploadBodyFactory) {
|
|
9416
9767
|
super(params, getSession, client, requestLogger);
|
|
9417
9768
|
this._uploadStream = stream;
|
|
9769
|
+
this._uploadBodyFactory = uploadBodyFactory;
|
|
9418
9770
|
this._mimeType = mimeType;
|
|
9419
9771
|
this._size = size;
|
|
9420
9772
|
this._videoMode = videoMode;
|
|
9421
9773
|
this._needsFullDuplex = !client.isFullDuplex() && mimeType.startsWith("video/") && videoMode == "stream" /* STREAM */;
|
|
9422
9774
|
}
|
|
9775
|
+
async uploadBody() {
|
|
9776
|
+
return this._uploadBodyFactory ? await this._uploadBodyFactory() : this._uploadStream;
|
|
9777
|
+
}
|
|
9423
9778
|
async onEvent(event) {
|
|
9424
9779
|
if (event.type == "prepared") {
|
|
9425
9780
|
if (!event.source_id) {
|
|
@@ -9461,7 +9816,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9461
9816
|
const blob = new Blob([JSON.stringify(this._params.fps)], { type: "application/json" });
|
|
9462
9817
|
formData.append("fps", blob);
|
|
9463
9818
|
}
|
|
9464
|
-
const fileBlob = await new Response(this.
|
|
9819
|
+
const fileBlob = await new Response(await this.uploadBody()).blob();
|
|
9465
9820
|
formData.append("file", fileBlob);
|
|
9466
9821
|
const headers = {
|
|
9467
9822
|
...session.authenticationHeaders(),
|
|
@@ -9488,7 +9843,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9488
9843
|
request = this._client.fetch(postUrl, {
|
|
9489
9844
|
headers,
|
|
9490
9845
|
method: "POST",
|
|
9491
|
-
body: this.
|
|
9846
|
+
body: await this.uploadBody(),
|
|
9492
9847
|
signal: this._controller.signal,
|
|
9493
9848
|
// @ts-ignore
|
|
9494
9849
|
duplex: "half",
|
|
@@ -9556,7 +9911,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9556
9911
|
const blob = new Blob([JSON.stringify(this._params.fps)], { type: "application/json" });
|
|
9557
9912
|
formData.append("fps", blob);
|
|
9558
9913
|
}
|
|
9559
|
-
const fileBlob = await new Response(this.
|
|
9914
|
+
const fileBlob = await new Response(await this.uploadBody()).blob();
|
|
9560
9915
|
formData.append("file", fileBlob);
|
|
9561
9916
|
const headers = {
|
|
9562
9917
|
...session.authenticationHeaders(),
|
|
@@ -9583,7 +9938,7 @@ var UploadJob = class extends AbstractJob {
|
|
|
9583
9938
|
response = await this._client.fetch(postUrl, {
|
|
9584
9939
|
headers,
|
|
9585
9940
|
method: "POST",
|
|
9586
|
-
body: this.
|
|
9941
|
+
body: await this.uploadBody(),
|
|
9587
9942
|
signal: this._controller.signal,
|
|
9588
9943
|
// @ts-ignore
|
|
9589
9944
|
duplex: "half"
|
|
@@ -9633,6 +9988,111 @@ var LoadFromJob = class extends AbstractJob {
|
|
|
9633
9988
|
});
|
|
9634
9989
|
}
|
|
9635
9990
|
};
|
|
9991
|
+
var UploadGroupJob = class extends AbstractJob {
|
|
9992
|
+
get [Symbol.toStringTag]() {
|
|
9993
|
+
return "uploadGroupJob";
|
|
9994
|
+
}
|
|
9995
|
+
constructor(sources, params, getSession, client, requestLogger) {
|
|
9996
|
+
super(params, getSession, client, requestLogger);
|
|
9997
|
+
if (sources.length === 0) {
|
|
9998
|
+
throw new Error("upload group requires at least one source");
|
|
9999
|
+
}
|
|
10000
|
+
this._sources = sources;
|
|
10001
|
+
}
|
|
10002
|
+
async startJob() {
|
|
10003
|
+
const session = await this._getSession();
|
|
10004
|
+
if (!session.baseUrl) {
|
|
10005
|
+
return Promise.reject(new Error("session.baseUrl must not be null"));
|
|
10006
|
+
}
|
|
10007
|
+
const queryParams = new URLSearchParams({
|
|
10008
|
+
mode: "queue",
|
|
10009
|
+
processing: "sync"
|
|
10010
|
+
});
|
|
10011
|
+
if (this._version !== void 0) {
|
|
10012
|
+
queryParams.set("version", this._version.toString());
|
|
10013
|
+
}
|
|
10014
|
+
if (this._params.motionDetect) {
|
|
10015
|
+
for (const [key, value] of Object.entries(this._params.motionDetect)) {
|
|
10016
|
+
queryParams.set(key, value);
|
|
10017
|
+
}
|
|
10018
|
+
}
|
|
10019
|
+
const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?${queryParams.toString()}`;
|
|
10020
|
+
const parts = [];
|
|
10021
|
+
if (this._params.componentParams) {
|
|
10022
|
+
parts.push({ name: "params", contentType: "application/json", content: JSON.stringify(this._params.componentParams) });
|
|
10023
|
+
}
|
|
10024
|
+
if (this._params.roi) {
|
|
10025
|
+
parts.push({ name: "roi", contentType: "application/json", content: JSON.stringify(this._params.roi) });
|
|
10026
|
+
}
|
|
10027
|
+
if (this._params.fps) {
|
|
10028
|
+
parts.push({ name: "fps", contentType: "application/json", content: JSON.stringify(this._params.fps) });
|
|
10029
|
+
}
|
|
10030
|
+
for (const source of this._sources) {
|
|
10031
|
+
parts.push({ name: "file", contentType: source.mimeType, content: source.stream });
|
|
10032
|
+
}
|
|
10033
|
+
const boundary = randomMultipartBoundary();
|
|
10034
|
+
const headers = {
|
|
10035
|
+
...session.authenticationHeaders(),
|
|
10036
|
+
Accept: "application/jsonl",
|
|
10037
|
+
"Content-Type": `multipart/form-data; boundary=${boundary}`
|
|
10038
|
+
};
|
|
10039
|
+
return await this._client.fetch(postUrl, {
|
|
10040
|
+
headers,
|
|
10041
|
+
method: "POST",
|
|
10042
|
+
body: encodeMultipartFormData(parts, boundary),
|
|
10043
|
+
signal: this._controller.signal,
|
|
10044
|
+
// @ts-ignore
|
|
10045
|
+
duplex: "half",
|
|
10046
|
+
eyepop: { responseStreaming: true }
|
|
10047
|
+
});
|
|
10048
|
+
}
|
|
10049
|
+
};
|
|
10050
|
+
var LoadFromGroupJob = class extends AbstractJob {
|
|
10051
|
+
get [Symbol.toStringTag]() {
|
|
10052
|
+
return "loadFromGroupJob";
|
|
10053
|
+
}
|
|
10054
|
+
constructor(urls, params, getSession, client, requestLogger) {
|
|
10055
|
+
super(params, getSession, client, requestLogger);
|
|
10056
|
+
if (urls.length === 0) {
|
|
10057
|
+
throw new Error("load from group requires at least one url");
|
|
10058
|
+
}
|
|
10059
|
+
this._urls = urls;
|
|
10060
|
+
}
|
|
10061
|
+
async startJob() {
|
|
10062
|
+
const session = await this._getSession();
|
|
10063
|
+
if (!session.baseUrl) {
|
|
10064
|
+
return Promise.reject(new Error("session.baseUrl must not be null"));
|
|
10065
|
+
}
|
|
10066
|
+
const body = {
|
|
10067
|
+
sourceType: "GROUP",
|
|
10068
|
+
sources: this._urls.map((url) => ({ sourceType: "URL", url })),
|
|
10069
|
+
version: this._version
|
|
10070
|
+
};
|
|
10071
|
+
if (this._params.componentParams) {
|
|
10072
|
+
body["params"] = this._params.componentParams;
|
|
10073
|
+
}
|
|
10074
|
+
if (this._params.roi) {
|
|
10075
|
+
body["roi"] = this._params.roi;
|
|
10076
|
+
}
|
|
10077
|
+
if (this._params.motionDetect) {
|
|
10078
|
+
Object.assign(body, this._params.motionDetect);
|
|
10079
|
+
}
|
|
10080
|
+
const headers = {
|
|
10081
|
+
...session.authenticationHeaders(),
|
|
10082
|
+
Accept: "application/jsonl",
|
|
10083
|
+
"Content-Type": "application/json"
|
|
10084
|
+
};
|
|
10085
|
+
const patchUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
|
|
10086
|
+
return await this._client.fetch(patchUrl, {
|
|
10087
|
+
headers,
|
|
10088
|
+
method: "PATCH",
|
|
10089
|
+
body: JSON.stringify(body),
|
|
10090
|
+
signal: this._controller.signal,
|
|
10091
|
+
// @ts-ignore
|
|
10092
|
+
eyepop: { responseStreaming: true }
|
|
10093
|
+
});
|
|
10094
|
+
}
|
|
10095
|
+
};
|
|
9636
10096
|
var LoadFromAssetUuidJob = class extends AbstractJob {
|
|
9637
10097
|
constructor(assetUuid, params, getSession, client, requestLogger) {
|
|
9638
10098
|
super(params, getSession, client, requestLogger);
|
|
@@ -10234,21 +10694,6 @@ var TransientPopId = /* @__PURE__ */ ((TransientPopId2) => {
|
|
|
10234
10694
|
})(TransientPopId || {});
|
|
10235
10695
|
|
|
10236
10696
|
// worker/worker_endpoint.ts
|
|
10237
|
-
var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
|
|
10238
|
-
SessionStatus2["UNKNOWN"] = "unknown";
|
|
10239
|
-
SessionStatus2["PENDING"] = "pending";
|
|
10240
|
-
SessionStatus2["RUNNING"] = "running";
|
|
10241
|
-
SessionStatus2["STOPPED"] = "stopped";
|
|
10242
|
-
SessionStatus2["FAILED"] = "failed";
|
|
10243
|
-
SessionStatus2["ERROR"] = "error";
|
|
10244
|
-
SessionStatus2["PIPELINE_CREATING"] = "pipeline_creating";
|
|
10245
|
-
SessionStatus2["PIPELINE_OK"] = "pipeline_ok";
|
|
10246
|
-
SessionStatus2["PIPELINE_CHECKING"] = "pipeline_checking";
|
|
10247
|
-
SessionStatus2["PIPELINE_ERROR"] = "pipeline_error";
|
|
10248
|
-
SessionStatus2["UPGRADING"] = "upgrading";
|
|
10249
|
-
return SessionStatus2;
|
|
10250
|
-
})(SessionStatus || {});
|
|
10251
|
-
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10252
10697
|
var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
10253
10698
|
constructor(options) {
|
|
10254
10699
|
super(options);
|
|
@@ -10411,6 +10856,114 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10411
10856
|
return Promise.reject("unknown source type");
|
|
10412
10857
|
}
|
|
10413
10858
|
}
|
|
10859
|
+
async uploadGroup(paths, params = {}) {
|
|
10860
|
+
if (paths.length === 0) {
|
|
10861
|
+
throw new Error("upload group requires at least one path");
|
|
10862
|
+
}
|
|
10863
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10864
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10865
|
+
}
|
|
10866
|
+
await this._limit.acquire();
|
|
10867
|
+
try {
|
|
10868
|
+
this.updateState();
|
|
10869
|
+
const sources = await Promise.all(
|
|
10870
|
+
paths.map(async (path2) => {
|
|
10871
|
+
let streamSource;
|
|
10872
|
+
if (this._options.platformSupport?.resolvePath) {
|
|
10873
|
+
streamSource = await this._options.platformSupport.resolvePath({ path: path2 }, this._logger);
|
|
10874
|
+
} else {
|
|
10875
|
+
streamSource = await resolvePath({ path: path2 }, this._logger);
|
|
10876
|
+
}
|
|
10877
|
+
return { stream: streamSource.stream, mimeType: streamSource.mimeType };
|
|
10878
|
+
})
|
|
10879
|
+
);
|
|
10880
|
+
const job = new UploadGroupJob(
|
|
10881
|
+
sources,
|
|
10882
|
+
params,
|
|
10883
|
+
async () => this.session(),
|
|
10884
|
+
this._client,
|
|
10885
|
+
this._requestLogger
|
|
10886
|
+
);
|
|
10887
|
+
return job.start(
|
|
10888
|
+
() => {
|
|
10889
|
+
this.jobDone(job);
|
|
10890
|
+
},
|
|
10891
|
+
(statusCode) => {
|
|
10892
|
+
this.jobStatus(job, statusCode);
|
|
10893
|
+
}
|
|
10894
|
+
);
|
|
10895
|
+
} catch (e) {
|
|
10896
|
+
this._limit.release();
|
|
10897
|
+
throw e;
|
|
10898
|
+
}
|
|
10899
|
+
}
|
|
10900
|
+
async uploadStreamGroup(streams, mimeTypes, params = {}) {
|
|
10901
|
+
if (streams.length === 0) {
|
|
10902
|
+
throw new Error("upload stream group requires at least one stream");
|
|
10903
|
+
}
|
|
10904
|
+
if (mimeTypes !== void 0 && mimeTypes.length !== streams.length) {
|
|
10905
|
+
throw new Error("mimeTypes must have the same length as streams");
|
|
10906
|
+
}
|
|
10907
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10908
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10909
|
+
}
|
|
10910
|
+
await this._limit.acquire();
|
|
10911
|
+
try {
|
|
10912
|
+
this.updateState();
|
|
10913
|
+
const sources = streams.map((stream, i) => ({
|
|
10914
|
+
stream,
|
|
10915
|
+
mimeType: mimeTypes?.[i] ?? null
|
|
10916
|
+
}));
|
|
10917
|
+
const job = new UploadGroupJob(
|
|
10918
|
+
sources,
|
|
10919
|
+
params,
|
|
10920
|
+
async () => this.session(),
|
|
10921
|
+
this._client,
|
|
10922
|
+
this._requestLogger
|
|
10923
|
+
);
|
|
10924
|
+
return job.start(
|
|
10925
|
+
() => {
|
|
10926
|
+
this.jobDone(job);
|
|
10927
|
+
},
|
|
10928
|
+
(statusCode) => {
|
|
10929
|
+
this.jobStatus(job, statusCode);
|
|
10930
|
+
}
|
|
10931
|
+
);
|
|
10932
|
+
} catch (e) {
|
|
10933
|
+
this._limit.release();
|
|
10934
|
+
throw e;
|
|
10935
|
+
}
|
|
10936
|
+
}
|
|
10937
|
+
async loadFromGroup(urls, params = {}) {
|
|
10938
|
+
if (urls.length === 0) {
|
|
10939
|
+
throw new Error("load from group requires at least one url");
|
|
10940
|
+
}
|
|
10941
|
+
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
10942
|
+
throw new Error("endpoint not connected, use connect()");
|
|
10943
|
+
}
|
|
10944
|
+
await this._limit.acquire();
|
|
10945
|
+
try {
|
|
10946
|
+
this.updateState();
|
|
10947
|
+
const job = new LoadFromGroupJob(
|
|
10948
|
+
urls,
|
|
10949
|
+
params,
|
|
10950
|
+
async () => this.session(),
|
|
10951
|
+
this._client,
|
|
10952
|
+
this._requestLogger
|
|
10953
|
+
);
|
|
10954
|
+
return job.start(
|
|
10955
|
+
() => {
|
|
10956
|
+
this.jobDone(job);
|
|
10957
|
+
},
|
|
10958
|
+
(statusCode) => {
|
|
10959
|
+
this.jobStatus(job, statusCode);
|
|
10960
|
+
}
|
|
10961
|
+
);
|
|
10962
|
+
} catch (e) {
|
|
10963
|
+
this._limit.release();
|
|
10964
|
+
throw e;
|
|
10965
|
+
}
|
|
10966
|
+
}
|
|
10414
10967
|
async uploadFile(source, params) {
|
|
10415
10968
|
await this.ensureTransientPipelineStarted();
|
|
10416
10969
|
if (!this._baseUrl || !this._pipelineId || !this._client || !this._limit) {
|
|
@@ -10485,12 +11038,21 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10485
11038
|
await this._limit.acquire();
|
|
10486
11039
|
try {
|
|
10487
11040
|
this.updateState();
|
|
10488
|
-
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
}
|
|
11041
|
+
const resolveStreamSource = async () => {
|
|
11042
|
+
if (this._options.platformSupport?.resolvePath) {
|
|
11043
|
+
return await this._options.platformSupport.resolvePath(source, this._logger);
|
|
11044
|
+
}
|
|
11045
|
+
return await resolvePath(source, this._logger);
|
|
11046
|
+
};
|
|
11047
|
+
const streamSource = await resolveStreamSource();
|
|
11048
|
+
let firstStreamPending = true;
|
|
11049
|
+
const uploadBodyFactory = async () => {
|
|
11050
|
+
if (firstStreamPending) {
|
|
11051
|
+
firstStreamPending = false;
|
|
11052
|
+
return streamSource.stream;
|
|
11053
|
+
}
|
|
11054
|
+
return (await resolveStreamSource()).stream;
|
|
11055
|
+
};
|
|
10494
11056
|
const job = new UploadJob(
|
|
10495
11057
|
streamSource.stream,
|
|
10496
11058
|
streamSource.mimeType,
|
|
@@ -10501,7 +11063,8 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10501
11063
|
return this.session();
|
|
10502
11064
|
},
|
|
10503
11065
|
this._client,
|
|
10504
|
-
this._requestLogger
|
|
11066
|
+
this._requestLogger,
|
|
11067
|
+
uploadBodyFactory
|
|
10505
11068
|
);
|
|
10506
11069
|
return job.start(
|
|
10507
11070
|
() => {
|
|
@@ -10731,161 +11294,38 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10731
11294
|
const seconds = this.options().sessionReadyTimeoutSeconds;
|
|
10732
11295
|
return typeof seconds == "number" && Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : _WorkerEndpoint.WAIT_FOR_IS_READY;
|
|
10733
11296
|
}
|
|
10734
|
-
sessionHealthReady(body, contentType) {
|
|
10735
|
-
if (contentType.includes("application/json")) {
|
|
10736
|
-
const health = JSON.parse(body);
|
|
10737
|
-
if (health && typeof health == "object") {
|
|
10738
|
-
if (health.message && !health.session_status) {
|
|
10739
|
-
return true;
|
|
10740
|
-
}
|
|
10741
|
-
return health.session_status == "running" /* RUNNING */;
|
|
10742
|
-
}
|
|
10743
|
-
}
|
|
10744
|
-
return contentType.includes("text/plain") && body.includes("I'm fine");
|
|
10745
|
-
}
|
|
10746
11297
|
async getComputeSession() {
|
|
10747
11298
|
if (!this._client) {
|
|
10748
11299
|
throw new Error("endpoint not initialized");
|
|
10749
11300
|
}
|
|
10750
|
-
let
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10758
|
-
|
|
10759
|
-
|
|
10760
|
-
|
|
10761
|
-
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
...headers,
|
|
10769
|
-
Accept: "application/json"
|
|
10770
|
-
}
|
|
10771
|
-
});
|
|
10772
|
-
if (response.status == 200) {
|
|
10773
|
-
const contentType = response.headers.get("content-type") || "";
|
|
10774
|
-
const body = await response.text();
|
|
10775
|
-
try {
|
|
10776
|
-
isReady = this.sessionHealthReady(body, contentType);
|
|
10777
|
-
} catch (error) {
|
|
10778
|
-
this._logger.debug(`session ${session.session_uuid} health check returned invalid JSON, wait and poll for update`);
|
|
10779
|
-
}
|
|
10780
|
-
if (!isReady && Date.now() > deadline) {
|
|
10781
|
-
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${readyTimeoutMs / 1e3} seconds`);
|
|
10782
|
-
}
|
|
10783
|
-
if (!isReady) {
|
|
10784
|
-
this._logger.debug(`session ${session.session_uuid} health check not ready, wait and poll for update`);
|
|
10785
|
-
await sleep(_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL);
|
|
10786
|
-
}
|
|
10787
|
-
} else if (Date.now() > deadline) {
|
|
10788
|
-
throw new Error(`Created session ${session.session_uuid} did not become healthy after ${readyTimeoutMs / 1e3} seconds`);
|
|
10789
|
-
} else {
|
|
10790
|
-
this._logger.debug(`session ${session.session_uuid} health check status ${response.status}, wait and poll for update`);
|
|
10791
|
-
await sleep(_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL);
|
|
10792
|
-
}
|
|
11301
|
+
let resolved;
|
|
11302
|
+
try {
|
|
11303
|
+
resolved = await new ComputeSessionClient({
|
|
11304
|
+
computeUrl: this.eyepopUrl(),
|
|
11305
|
+
httpClient: this._client,
|
|
11306
|
+
authorizationHeader: () => this.computeAuthorizationHeader(),
|
|
11307
|
+
sessionUuid: this.options().sessionUuid,
|
|
11308
|
+
sessionName: this.options().sessionName,
|
|
11309
|
+
pipelineImage: this.options().pipelineImage,
|
|
11310
|
+
pipelineVersion: this.options().pipelineVersion,
|
|
11311
|
+
pop: this.options().pop,
|
|
11312
|
+
readyTimeoutMs: this.sessionReadyTimeoutMs(),
|
|
11313
|
+
logger: this._logger,
|
|
11314
|
+
requestLogger: this._requestLogger
|
|
11315
|
+
}).resolve();
|
|
11316
|
+
} catch (error) {
|
|
11317
|
+
this.updateState("Error" /* Error */);
|
|
11318
|
+
throw error;
|
|
10793
11319
|
}
|
|
10794
|
-
this.
|
|
11320
|
+
this._sessionAccessToken = resolved.accessToken;
|
|
11321
|
+
this._sessionAccessTokenValidUntil = resolved.accessTokenValidUntil;
|
|
11322
|
+
this._baseUrl = resolved.session.session_endpoint;
|
|
10795
11323
|
this._pipeline = null;
|
|
10796
|
-
this._pipelineId =
|
|
11324
|
+
this._pipelineId = resolved.pipelineId;
|
|
10797
11325
|
if (this.options().pop) {
|
|
10798
11326
|
this.setTransientPipelinePop();
|
|
10799
11327
|
}
|
|
10800
11328
|
}
|
|
10801
|
-
async getOnDemandComputeSession(httpClient) {
|
|
10802
|
-
let session = null;
|
|
10803
|
-
const sessionsUrl = `${this.eyepopUrl()}/v1/sessions`;
|
|
10804
|
-
const headers = {
|
|
10805
|
-
Authorization: await this.computeAuthorizationHeader()
|
|
10806
|
-
};
|
|
10807
|
-
let sessions;
|
|
10808
|
-
if (!this.options().pop) {
|
|
10809
|
-
this._requestLogger.debug("fetching sessions from: %s", sessionsUrl);
|
|
10810
|
-
const response = await httpClient.fetch(sessionsUrl, {
|
|
10811
|
-
headers
|
|
10812
|
-
});
|
|
10813
|
-
if (response.status == 404) {
|
|
10814
|
-
sessions = [];
|
|
10815
|
-
} else if (response.status != 200) {
|
|
10816
|
-
this.updateState("Error" /* Error */);
|
|
10817
|
-
const message = await response.text();
|
|
10818
|
-
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
10819
|
-
} else {
|
|
10820
|
-
const response_content = await response.json();
|
|
10821
|
-
sessions = response_content;
|
|
10822
|
-
}
|
|
10823
|
-
if (sessions.length > 0) {
|
|
10824
|
-
this._logger.debug(`User has ${sessions.length} sessions, inspecting for usable session`);
|
|
10825
|
-
for (let s of sessions) {
|
|
10826
|
-
if (!_WorkerEndpoint.SESSION_DEAD.has(s.session_status) && !s.persistent) {
|
|
10827
|
-
session = s;
|
|
10828
|
-
this._logger.debug(`Use active session ${s.session_uuid} with pipeline ${this.pipelineIdFromSession(s)}`);
|
|
10829
|
-
break;
|
|
10830
|
-
}
|
|
10831
|
-
}
|
|
10832
|
-
}
|
|
10833
|
-
}
|
|
10834
|
-
if (!session) {
|
|
10835
|
-
this._requestLogger.debug("creating a new session at: %s", sessionsUrl);
|
|
10836
|
-
const createBody = this.sessionCreateBody();
|
|
10837
|
-
const createHeaders = {
|
|
10838
|
-
...headers,
|
|
10839
|
-
...createBody ? { "Content-Type": "application/json" } : {}
|
|
10840
|
-
};
|
|
10841
|
-
const request = {
|
|
10842
|
-
headers: createHeaders,
|
|
10843
|
-
method: "POST"
|
|
10844
|
-
};
|
|
10845
|
-
if (createBody) {
|
|
10846
|
-
request.body = createBody;
|
|
10847
|
-
}
|
|
10848
|
-
const response = await httpClient.fetch(`${sessionsUrl}?wait=true`, request);
|
|
10849
|
-
if (response.status != 200) {
|
|
10850
|
-
this.updateState("Error" /* Error */);
|
|
10851
|
-
const message = await response.text();
|
|
10852
|
-
throw new Error(`Unexpected status ${response.status} creating a compute session: ${message}`);
|
|
10853
|
-
} else {
|
|
10854
|
-
sessions = await response.json();
|
|
10855
|
-
}
|
|
10856
|
-
if (sessions.length == 0) {
|
|
10857
|
-
throw new Error("Unexpected, no compute session after attempt to create one");
|
|
10858
|
-
}
|
|
10859
|
-
session = sessions[0] || null;
|
|
10860
|
-
}
|
|
10861
|
-
if (!session) {
|
|
10862
|
-
throw new Error("unexpected undefined session");
|
|
10863
|
-
}
|
|
10864
|
-
return session;
|
|
10865
|
-
}
|
|
10866
|
-
async getPermanentComputeSession(httpClient, sessionUuid) {
|
|
10867
|
-
let session = null;
|
|
10868
|
-
const sessionUrl = `${this.eyepopUrl()}/v1/sessions/${sessionUuid}`;
|
|
10869
|
-
this._requestLogger.debug("fetching session from: %s", sessionUrl);
|
|
10870
|
-
const headers = {
|
|
10871
|
-
Authorization: await this.computeAuthorizationHeader()
|
|
10872
|
-
};
|
|
10873
|
-
let response = await httpClient.fetch(sessionUrl, {
|
|
10874
|
-
headers
|
|
10875
|
-
});
|
|
10876
|
-
if (response.status == 404) {
|
|
10877
|
-
this.updateState("Error" /* Error */);
|
|
10878
|
-
throw new Error(`Unexpected status ${response.status} compute sessions ${sessionUuid} not found`);
|
|
10879
|
-
} else if (response.status != 200) {
|
|
10880
|
-
this.updateState("Error" /* Error */);
|
|
10881
|
-
const message = await response.text();
|
|
10882
|
-
throw new Error(`Unexpected status ${response.status} fetching compute sessions: ${message}`);
|
|
10883
|
-
} else {
|
|
10884
|
-
const response_content = await response.json();
|
|
10885
|
-
session = response_content;
|
|
10886
|
-
}
|
|
10887
|
-
return session;
|
|
10888
|
-
}
|
|
10889
11329
|
async startTransientPipeline() {
|
|
10890
11330
|
const client = this._client;
|
|
10891
11331
|
const baseUrl = this._baseUrl;
|
|
@@ -10942,6 +11382,13 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10942
11382
|
if (this._pipelineId) {
|
|
10943
11383
|
return;
|
|
10944
11384
|
}
|
|
11385
|
+
if (this.options().pop) {
|
|
11386
|
+
await this.reconnect();
|
|
11387
|
+
if (!this._pipelineId) {
|
|
11388
|
+
throw new Error("Compute session did not provide a pipeline for the requested pop");
|
|
11389
|
+
}
|
|
11390
|
+
return;
|
|
11391
|
+
}
|
|
10945
11392
|
if (!this._pipelineCreatePromise) {
|
|
10946
11393
|
this._pipelineCreatePromise = this.startTransientPipeline();
|
|
10947
11394
|
}
|
|
@@ -10957,7 +11404,9 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10957
11404
|
throw new Error("endpoint not initialized");
|
|
10958
11405
|
}
|
|
10959
11406
|
const previousPop = this.options().pop;
|
|
10960
|
-
const
|
|
11407
|
+
const previousBaseUrl = this._baseUrl;
|
|
11408
|
+
const previousSessionAccessToken = this._sessionAccessToken;
|
|
11409
|
+
const previousSessionAccessTokenValidUntil = this._sessionAccessTokenValidUntil;
|
|
10961
11410
|
if (this._pipelineId) {
|
|
10962
11411
|
await this.deleteTransientPipeline(this._pipelineId);
|
|
10963
11412
|
this._pipelineId = null;
|
|
@@ -10965,10 +11414,14 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10965
11414
|
this._pipeline = null;
|
|
10966
11415
|
try {
|
|
10967
11416
|
this.options().pop = pop;
|
|
10968
|
-
await this.
|
|
11417
|
+
await this.getComputeSession();
|
|
10969
11418
|
} catch (error) {
|
|
10970
11419
|
this.options().pop = previousPop;
|
|
10971
|
-
this._pipeline =
|
|
11420
|
+
this._pipeline = null;
|
|
11421
|
+
this._pipelineId = null;
|
|
11422
|
+
this._baseUrl = previousPop ? null : previousBaseUrl;
|
|
11423
|
+
this._sessionAccessToken = previousSessionAccessToken;
|
|
11424
|
+
this._sessionAccessTokenValidUntil = previousSessionAccessTokenValidUntil;
|
|
10972
11425
|
throw error;
|
|
10973
11426
|
}
|
|
10974
11427
|
if (!this._pipelineId) {
|
|
@@ -10993,13 +11446,6 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
10993
11446
|
this._logger.info(`stopping pipeline failed, status ${response.status}: ${message}`);
|
|
10994
11447
|
}
|
|
10995
11448
|
}
|
|
10996
|
-
pipelineIdFromSession(session) {
|
|
10997
|
-
if (session.pipeline_uuid) {
|
|
10998
|
-
return session.pipeline_uuid;
|
|
10999
|
-
}
|
|
11000
|
-
const pipeline = session.pipelines?.[0];
|
|
11001
|
-
return pipeline?.id || pipeline?.pipeline_id || null;
|
|
11002
|
-
}
|
|
11003
11449
|
async authorizationHeader() {
|
|
11004
11450
|
if (this._sessionAccessToken) {
|
|
11005
11451
|
return `Bearer ${this._sessionAccessToken}`;
|
|
@@ -11015,20 +11461,6 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
11015
11461
|
}
|
|
11016
11462
|
return super.authorizationHeader();
|
|
11017
11463
|
}
|
|
11018
|
-
setComputeSessionAccessToken(session) {
|
|
11019
|
-
if (!session.access_token) {
|
|
11020
|
-
throw new Error(`Compute session ${session.session_uuid} did not provide an access token`);
|
|
11021
|
-
}
|
|
11022
|
-
this._sessionAccessToken = session.access_token;
|
|
11023
|
-
if (session.access_token_expires_at) {
|
|
11024
|
-
const expiresAt = Date.parse(session.access_token_expires_at);
|
|
11025
|
-
this._sessionAccessTokenValidUntil = Number.isNaN(expiresAt) ? null : expiresAt;
|
|
11026
|
-
} else if (session.access_token_expires_in) {
|
|
11027
|
-
this._sessionAccessTokenValidUntil = Date.now() + session.access_token_expires_in * 1e3;
|
|
11028
|
-
} else {
|
|
11029
|
-
this._sessionAccessTokenValidUntil = null;
|
|
11030
|
-
}
|
|
11031
|
-
}
|
|
11032
11464
|
setTransientPipelinePop() {
|
|
11033
11465
|
const pop = this.options().pop;
|
|
11034
11466
|
if (pop && this._pipelineId) {
|
|
@@ -11040,26 +11472,8 @@ var _WorkerEndpoint = class _WorkerEndpoint extends Endpoint {
|
|
|
11040
11472
|
};
|
|
11041
11473
|
}
|
|
11042
11474
|
}
|
|
11043
|
-
sessionCreateBody() {
|
|
11044
|
-
const body = {};
|
|
11045
|
-
if (this.options().sessionName) {
|
|
11046
|
-
body.session_name = this.options().sessionName;
|
|
11047
|
-
}
|
|
11048
|
-
if (this.options().pipelineImage) {
|
|
11049
|
-
body.pipeline_image = this.options().pipelineImage;
|
|
11050
|
-
}
|
|
11051
|
-
if (this.options().pipelineVersion) {
|
|
11052
|
-
body.pipeline_version = this.options().pipelineVersion;
|
|
11053
|
-
}
|
|
11054
|
-
if (this.options().pop) {
|
|
11055
|
-
body.pop = this.options().pop;
|
|
11056
|
-
}
|
|
11057
|
-
return Object.keys(body).length > 0 ? JSON.stringify(body) : void 0;
|
|
11058
|
-
}
|
|
11059
11475
|
};
|
|
11060
|
-
_WorkerEndpoint.SESSION_DEAD = /* @__PURE__ */ new Set(["error" /* ERROR */, "failed" /* FAILED */, "stopped" /* STOPPED */, "pipeline_error" /* PIPELINE_ERROR */, "unknown" /* UNKNOWN */]);
|
|
11061
11476
|
_WorkerEndpoint.WAIT_FOR_IS_READY = 60 * 1e3;
|
|
11062
|
-
_WorkerEndpoint.CHECK_FOR_IS_READY_INTERVAL = 250;
|
|
11063
11477
|
var WorkerEndpoint = _WorkerEndpoint;
|
|
11064
11478
|
|
|
11065
11479
|
// shims/websockets.ts
|
|
@@ -12551,6 +12965,7 @@ var index_default = EyePop;
|
|
|
12551
12965
|
ForwardOperatorType,
|
|
12552
12966
|
InferenceType,
|
|
12553
12967
|
LoadFromAssetUuidJob,
|
|
12968
|
+
LoadFromGroupJob,
|
|
12554
12969
|
LoadFromJob,
|
|
12555
12970
|
LoadMediaStreamJob,
|
|
12556
12971
|
ModelExportStatus,
|
|
@@ -12564,12 +12979,12 @@ var index_default = EyePop;
|
|
|
12564
12979
|
PopComponentType,
|
|
12565
12980
|
PredictionVersion,
|
|
12566
12981
|
Semaphore,
|
|
12567
|
-
SessionStatus,
|
|
12568
12982
|
Stream,
|
|
12569
12983
|
TaskMode,
|
|
12570
12984
|
TaskType,
|
|
12571
12985
|
TranscodeMode,
|
|
12572
12986
|
TransientPopId,
|
|
12987
|
+
UploadGroupJob,
|
|
12573
12988
|
UploadJob,
|
|
12574
12989
|
UserReview,
|
|
12575
12990
|
VideoMode,
|
|
@@ -12579,7 +12994,9 @@ var index_default = EyePop;
|
|
|
12579
12994
|
WebrtcWhip,
|
|
12580
12995
|
WorkerEndpoint,
|
|
12581
12996
|
WorkflowPhase,
|
|
12997
|
+
encodeMultipartFormData,
|
|
12582
12998
|
getBaseUrl,
|
|
12999
|
+
randomMultipartBoundary,
|
|
12583
13000
|
readableStreamFromString
|
|
12584
13001
|
});
|
|
12585
13002
|
/*! Bundled license information:
|