@eyepop.ai/eyepop 1.2.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8648,7 +8648,7 @@ var Stream = class _Stream {
8648
8648
  this.iterator = iterator;
8649
8649
  this.controller = controller;
8650
8650
  }
8651
- static iterFromReadableStream(readableStream, controller) {
8651
+ static iterFromReadableStream(readableStream, controller, eventHandler) {
8652
8652
  let consumed = false;
8653
8653
  async function* iterLines() {
8654
8654
  const lineDecoder = new LineDecoder();
@@ -8671,7 +8671,16 @@ var Stream = class _Stream {
8671
8671
  try {
8672
8672
  for await (const line of iterLines()) {
8673
8673
  if (done) continue;
8674
- if (line) yield JSON.parse(line);
8674
+ if (line) {
8675
+ const message = JSON.parse(line);
8676
+ const event = message["event"];
8677
+ if (event !== void 0) {
8678
+ eventHandler(event).then(() => {
8679
+ });
8680
+ } else {
8681
+ yield message;
8682
+ }
8683
+ }
8675
8684
  }
8676
8685
  done = true;
8677
8686
  } catch (e) {
@@ -8894,11 +8903,20 @@ var AbstractJob = class {
8894
8903
  if (!this._responseStream) {
8895
8904
  throw Error("logical bug");
8896
8905
  }
8897
- return Stream.iterFromReadableStream(this._responseStream, this._controller);
8906
+ return Stream.iterFromReadableStream(
8907
+ this._responseStream,
8908
+ this._controller,
8909
+ async (event) => {
8910
+ return await this.onEvent(event);
8911
+ }
8912
+ );
8898
8913
  }
8899
8914
  async startJob() {
8900
8915
  return Promise.reject("abstract class");
8901
8916
  }
8917
+ async onEvent(event) {
8918
+ return Promise.resolve();
8919
+ }
8902
8920
  start(done, status) {
8903
8921
  this._responseStream = new Promise(async (resolve, reject) => {
8904
8922
  try {
@@ -8964,52 +8982,126 @@ var UploadJob = class extends AbstractJob {
8964
8982
  super(params, getSession, client, requestLogger);
8965
8983
  this._uploadStream = stream;
8966
8984
  this._mimeType = mimeType;
8985
+ this._needsFullDuplex = mimeType.startsWith("video/");
8986
+ }
8987
+ async onEvent(event) {
8988
+ if (event.type == "prepared") {
8989
+ if (!event.source_id) {
8990
+ return Promise.reject("did not get a prepared sourceId to simulate full duplex");
8991
+ }
8992
+ const session = await this._getSession();
8993
+ if (!session.baseUrl) {
8994
+ return Promise.reject("session.baseUrl must not ne null");
8995
+ }
8996
+ let request;
8997
+ const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=async&sourceId=${event.source_id}`;
8998
+ if (this._params) {
8999
+ this._requestLogger.debug("before POST %s with multipart body because of params", postUrl);
9000
+ const params = JSON.stringify(this._params);
9001
+ const paramBlob = new Blob([params], { type: "application/json" });
9002
+ const formData = new FormData();
9003
+ formData.append("params", paramBlob);
9004
+ formData.append("file", this._uploadStream);
9005
+ const headers = {
9006
+ "Authorization": `Bearer ${session.accessToken}`,
9007
+ "Accept": "application/jsonl"
9008
+ };
9009
+ request = this._client.fetch(postUrl, {
9010
+ headers,
9011
+ method: "POST",
9012
+ body: formData,
9013
+ signal: this._controller.signal,
9014
+ // @ts-ignore
9015
+ duplex: "half"
9016
+ });
9017
+ } else {
9018
+ this._requestLogger.debug("before POST %s with stream as body", postUrl);
9019
+ const headers = {
9020
+ "Authorization": `Bearer ${session.accessToken}`,
9021
+ "Accept": "application/jsonl",
9022
+ "Content-Type": this._mimeType
9023
+ };
9024
+ request = this._client.fetch(postUrl, {
9025
+ headers,
9026
+ method: "POST",
9027
+ body: this._uploadStream,
9028
+ signal: this._controller.signal,
9029
+ // @ts-ignore
9030
+ duplex: "half"
9031
+ });
9032
+ }
9033
+ request.then(async (value) => {
9034
+ if (value.status != 204) {
9035
+ this._requestLogger.debug("unexpected status %d (%s) for POST %s ", value.status, await value.text(), postUrl);
9036
+ }
9037
+ }).catch((reason) => {
9038
+ this._requestLogger.debug("error %v for POST %s ", reason, postUrl);
9039
+ }).finally(() => {
9040
+ this._requestLogger.debug("after POST %s ", postUrl);
9041
+ });
9042
+ }
9043
+ return Promise.resolve();
8967
9044
  }
8968
9045
  async startJob() {
8969
9046
  const session = await this._getSession();
8970
9047
  if (!session.baseUrl) {
8971
9048
  return Promise.reject("session.baseUrl must not ne null");
8972
9049
  }
8973
- const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
8974
9050
  let response;
8975
- if (this._params) {
8976
- this._requestLogger.debug("before POST %s with multipart body because of params");
8977
- const params = JSON.stringify(this._params);
8978
- const paramBlob = new Blob([params], { type: "application/json" });
8979
- const formData = new FormData();
8980
- formData.append("params", paramBlob);
8981
- formData.append("file", this._uploadStream);
9051
+ if (this._needsFullDuplex) {
9052
+ const prepareUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/prepareSource?timeout=10s`;
8982
9053
  const headers = {
8983
9054
  "Authorization": `Bearer ${session.accessToken}`,
8984
9055
  "Accept": "application/jsonl"
8985
9056
  };
8986
- response = await this._client.fetch(postUrl, {
9057
+ this._requestLogger.debug("before POST %s to prepare full duplex upload", prepareUrl);
9058
+ response = await this._client.fetch(prepareUrl, {
8987
9059
  headers,
8988
9060
  method: "POST",
8989
- body: formData,
8990
9061
  signal: this._controller.signal,
8991
9062
  // @ts-ignore
8992
- "duplex": "half",
8993
- dispatcher: this._dispatcher
9063
+ duplex: "half"
8994
9064
  });
8995
- this._requestLogger.debug("after POST %s with multipart body because of params");
9065
+ this._requestLogger.debug("after POST %s to prepare full duplex upload", prepareUrl);
8996
9066
  } else {
8997
- this._requestLogger.debug("before POST %s with stream as body");
8998
- const headers = {
8999
- "Authorization": `Bearer ${session.accessToken}`,
9000
- "Accept": "application/jsonl",
9001
- "Content-Type": this._mimeType
9002
- };
9003
- response = await this._client.fetch(postUrl, {
9004
- headers,
9005
- method: "POST",
9006
- body: this._uploadStream,
9007
- signal: this._controller.signal,
9008
- // @ts-ignore
9009
- "duplex": "half",
9010
- dispatcher: this._dispatcher
9011
- });
9012
- this._requestLogger.debug("after POST %s with stream as body");
9067
+ const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
9068
+ if (this._params) {
9069
+ this._requestLogger.debug("before POST %s with multipart body because of params", postUrl);
9070
+ const params = JSON.stringify(this._params);
9071
+ const paramBlob = new Blob([params], { type: "application/json" });
9072
+ const formData = new FormData();
9073
+ formData.append("params", paramBlob);
9074
+ formData.append("file", this._uploadStream);
9075
+ const headers = {
9076
+ "Authorization": `Bearer ${session.accessToken}`,
9077
+ "Accept": "application/jsonl"
9078
+ };
9079
+ response = await this._client.fetch(postUrl, {
9080
+ headers,
9081
+ method: "POST",
9082
+ body: formData,
9083
+ signal: this._controller.signal,
9084
+ // @ts-ignore
9085
+ duplex: "half"
9086
+ });
9087
+ this._requestLogger.debug("after POST %s with multipart body because of params", postUrl);
9088
+ } else {
9089
+ this._requestLogger.debug("before POST %s with stream as body", postUrl);
9090
+ const headers = {
9091
+ "Authorization": `Bearer ${session.accessToken}`,
9092
+ "Accept": "application/jsonl",
9093
+ "Content-Type": this._mimeType
9094
+ };
9095
+ response = await this._client.fetch(postUrl, {
9096
+ headers,
9097
+ method: "POST",
9098
+ body: this._uploadStream,
9099
+ signal: this._controller.signal,
9100
+ // @ts-ignore
9101
+ duplex: "half"
9102
+ });
9103
+ this._requestLogger.debug("after POST %s with stream as body", postUrl);
9104
+ }
9013
9105
  }
9014
9106
  return response;
9015
9107
  }
@@ -9043,9 +9135,7 @@ var LoadFromJob = class extends AbstractJob {
9043
9135
  headers,
9044
9136
  method: "PATCH",
9045
9137
  body: JSON.stringify(body),
9046
- signal: this._controller.signal,
9047
- // @ts-ignore
9048
- dispatcher: this._dispatcher
9138
+ signal: this._controller.signal
9049
9139
  });
9050
9140
  this._requestLogger.debug("after PATCH %s with url %s as source", patchUrl, this._location);
9051
9141
  return response;
@@ -9080,9 +9170,7 @@ var LoadLiveIngressJob = class extends AbstractJob {
9080
9170
  headers,
9081
9171
  method: "PATCH",
9082
9172
  body: JSON.stringify(body),
9083
- signal: this._controller.signal,
9084
- // @ts-ignore
9085
- dispatcher: this._dispatcher
9173
+ signal: this._controller.signal
9086
9174
  });
9087
9175
  this._requestLogger.debug("after PATCH %s with url %s as source", patchUrl, this._ingressId);
9088
9176
  return response;
@@ -9556,18 +9644,39 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9556
9644
  throw new DOMException("resolving a path to a file is not supported in browser");
9557
9645
  };
9558
9646
  } else {
9647
+ let iteratorToStream = function(iterator) {
9648
+ return new ReadableStream({
9649
+ async pull(controller) {
9650
+ const { value, done } = await iterator.next();
9651
+ if (done) {
9652
+ controller.close();
9653
+ } else {
9654
+ controller.enqueue(new Uint8Array(value));
9655
+ }
9656
+ }
9657
+ });
9658
+ };
9659
+ iteratorToStream2 = iteratorToStream;
9660
+ async function* nodeStreamToIterator(stream) {
9661
+ for await (const chunk of stream) {
9662
+ yield chunk;
9663
+ }
9664
+ }
9559
9665
  resolvePath = async (source) => {
9560
9666
  const mime = require_mime_types();
9561
9667
  const filehandle = __require("node:fs/promises");
9562
9668
  const fd = await filehandle.open(source.path, "r");
9563
9669
  const stream = fd.createReadStream();
9670
+ const iterator = nodeStreamToIterator(stream);
9671
+ const webStream = iteratorToStream(iterator);
9564
9672
  const mimeType = mime.lookup(source.path) || "application/octet-stream";
9565
9673
  return {
9566
- stream,
9674
+ stream: webStream,
9567
9675
  mimeType
9568
9676
  };
9569
9677
  };
9570
9678
  }
9679
+ var iteratorToStream2;
9571
9680
 
9572
9681
  // shims/http_client.ts
9573
9682
  var createHttpClient;
@@ -9602,7 +9711,9 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9602
9711
  const undici = __require("undici");
9603
9712
  const agent = new undici.Agent({
9604
9713
  keepAliveTimeout: 1e4,
9605
- connections: 5
9714
+ connections: 5,
9715
+ // two parallel streaming requests to the same host seem to deadlock with pipelining > 0
9716
+ pipelining: 0
9606
9717
  });
9607
9718
  return new HttpClient2(agent);
9608
9719
  };
@@ -10943,8 +11054,8 @@ var DataEndpoint = class extends Endpoint {
10943
11054
  this._requestLogger.debug("Response - " + response.status + " " + response.statusText);
10944
11055
  return response.json();
10945
11056
  }
10946
- async listDatasets(include_hero_asset = false) {
10947
- return this.request(`/datasets?account_uuid=${this._accountId}&include_hero_asset=${include_hero_asset}`, {
11057
+ async listDatasets(include_hero_asset = false, include_stats = true) {
11058
+ return this.request(`/datasets?account_uuid=${this._accountId}&include_stats=${include_stats}`, {
10948
11059
  method: "GET"
10949
11060
  });
10950
11061
  }
@@ -10954,8 +11065,8 @@ var DataEndpoint = class extends Endpoint {
10954
11065
  body: JSON.stringify(data)
10955
11066
  });
10956
11067
  }
10957
- async getDataset(dataset_uuid, include_hero_asset = false) {
10958
- return this.request(`/datasets/${dataset_uuid}?include_hero_asset=${include_hero_asset}`, {
11068
+ async getDataset(dataset_uuid, include_hero_asset = false, include_stats = true) {
11069
+ return this.request(`/datasets/${dataset_uuid}?include_stats=${include_stats}`, {
10959
11070
  method: "GET"
10960
11071
  });
10961
11072
  }
@@ -10965,6 +11076,12 @@ var DataEndpoint = class extends Endpoint {
10965
11076
  body: JSON.stringify(data)
10966
11077
  });
10967
11078
  }
11079
+ async updateDatasetHeroAsset(dataset_uuid, update) {
11080
+ return this.request(`/datasets/${dataset_uuid}/hero_asset`, {
11081
+ method: "PATCH",
11082
+ body: JSON.stringify(update)
11083
+ });
11084
+ }
10968
11085
  async deleteDataset(dataset_uuid) {
10969
11086
  return this.request(`/datasets/${dataset_uuid}`, {
10970
11087
  method: "DELETE"
@@ -11320,7 +11437,7 @@ var EyePop;
11320
11437
  }
11321
11438
  if (typeof opts.auth.oAuth2 != "undefined") {
11322
11439
  if (typeof opts.auth.oAuth2 === "boolean") {
11323
- if (opts.eyepopUrl.startsWith("https://staging-api.eyepop.ai")) {
11440
+ if (opts.eyepopUrl.startsWith("https://web-api.staging.eyepop.xyz")) {
11324
11441
  opts.auth = {
11325
11442
  oAuth2: {
11326
11443
  domain: "dev-eyepop.us.auth0.com",