@eyepop.ai/eyepop 1.3.0 → 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.
@@ -687,11 +687,16 @@ declare class DataEndpoint extends Endpoint<DataEndpoint> {
687
687
  private dispatchChangeEvent;
688
688
  }
689
689
 
690
+ interface StreamEvent {
691
+ type: string;
692
+ source_id?: string;
693
+ message?: string;
694
+ }
690
695
  declare class Stream<Prediction> implements AsyncIterable<Prediction> {
691
696
  private iterator;
692
697
  controller: AbortController;
693
698
  constructor(iterator: () => AsyncIterator<Prediction>, controller: AbortController);
694
- static iterFromReadableStream<Prediction>(readableStream: Promise<ReadableStream<Uint8Array>>, controller: AbortController): AsyncIterator<Prediction, any, undefined>;
699
+ static iterFromReadableStream<Prediction>(readableStream: Promise<ReadableStream<Uint8Array>>, controller: AbortController, eventHandler: (event: StreamEvent) => Promise<void>): AsyncIterator<Prediction, any, undefined>;
695
700
  /**
696
701
  * Generates a Stream from a newline-separated ReadableStream
697
702
  * where each item is a JSON value.
@@ -721,6 +726,7 @@ declare class AbstractJob implements ResultStream {
721
726
  [Symbol.asyncIterator](): AsyncIterator<Prediction>;
722
727
  protected constructor(params: SourceParams | undefined, getSession: () => Promise<WorkerSession>, client: HttpClient, requestLogger: Logger);
723
728
  protected startJob(): Promise<Response>;
729
+ protected onEvent(event: StreamEvent): Promise<void>;
724
730
  static n: number;
725
731
  start(done: () => void, status: (statusCode: number) => void): AbstractJob;
726
732
  cancel(): void;
@@ -728,8 +734,10 @@ declare class AbstractJob implements ResultStream {
728
734
  declare class UploadJob extends AbstractJob {
729
735
  private readonly _uploadStream;
730
736
  private readonly _mimeType;
737
+ private readonly _needsFullDuplex;
731
738
  get [Symbol.toStringTag](): string;
732
739
  constructor(stream: any, mimeType: string, params: SourceParams | undefined, getSession: () => Promise<WorkerSession>, client: HttpClient, requestLogger: Logger);
740
+ protected onEvent(event: StreamEvent): Promise<void>;
733
741
  protected startJob(): Promise<Response>;
734
742
  }
735
743
  declare class LoadFromJob extends AbstractJob {
@@ -807,4 +815,4 @@ declare namespace EyePop {
807
815
  function dataEndpoint(opts?: DataOptions): DataEndpoint;
808
816
  }
809
817
 
810
- export { AbstractJob, type Annotation, AnnotationType, type Asset, type AssetImport, AssetStatus, type Auth0Options, type Authentication, type AutoAnnotateParams, type BaseComponent, type Box, type ChangeEvent, ChangeType, type ComponentFinderComponent, type Contour, type ContourFinderComponent, ContourType, DataEndpoint, type DataOptions, type DataSession, type Dataset, type DatasetCreate, type DatasetHeroAssetUpdate, type DatasetUpdate, type DatasetVersion, type DatasetVersionAssetStats, Endpoint, EndpointState, EyePop, type FileSource, type ForwardComponent, ForwardOperatorType, type InferenceComponent, InferenceType, type IngressEvent, type LiveMedia, type LiveSource, LoadFromJob, LoadLiveIngressJob, type Mask, type Model, type ModelCreate, ModelFormat, type ModelInstanceDef, type ModelMetrics, ModelPrecisionType, type ModelSample, ModelStatus, type ModelTrainingProgress, ModelTrainingStage, ModelType, type ModelUpdate, type OAuth2Auth, type OnChangeEvent, type Options, type PathSource, type Point2d, type Point3d, type Pop, type PopComponent, PopComponentType, type PopCrop, type PopForward, type PopForwardOperator, type PredictedClass, type PredictedKeyPoint, type PredictedKeyPoints, type PredictedLabel, type PredictedMesh, type PredictedObject, type Prediction, type ResultStream, type Roi, type SecretKeyAuth, Semaphore, type Session, type SessionAuth, type Source, type SourceParams, type SourcesEntry, Stream, type StreamSource, type StreamTime, type TracingComponent, TranscodeMode, TransientPopId, UploadJob, type UrlSource, UserReview, WebrtcBase, WebrtcWhep, WebrtcWhip, WorkerEndpoint, type WorkerOptions, type WorkerSession, EyePop as default };
818
+ export { AbstractJob, type Annotation, AnnotationType, type Asset, type AssetImport, AssetStatus, type Auth0Options, type Authentication, type AutoAnnotateParams, type BaseComponent, type Box, type ChangeEvent, ChangeType, type ComponentFinderComponent, type Contour, type ContourFinderComponent, ContourType, DataEndpoint, type DataOptions, type DataSession, type Dataset, type DatasetCreate, type DatasetHeroAssetUpdate, type DatasetUpdate, type DatasetVersion, type DatasetVersionAssetStats, Endpoint, EndpointState, EyePop, type FileSource, type ForwardComponent, ForwardOperatorType, type InferenceComponent, InferenceType, type IngressEvent, type LiveMedia, type LiveSource, LoadFromJob, LoadLiveIngressJob, type Mask, type Model, type ModelCreate, ModelFormat, type ModelInstanceDef, type ModelMetrics, ModelPrecisionType, type ModelSample, ModelStatus, type ModelTrainingProgress, ModelTrainingStage, ModelType, type ModelUpdate, type OAuth2Auth, type OnChangeEvent, type Options, type PathSource, type Point2d, type Point3d, type Pop, type PopComponent, PopComponentType, type PopCrop, type PopForward, type PopForwardOperator, type PredictedClass, type PredictedKeyPoint, type PredictedKeyPoints, type PredictedLabel, type PredictedMesh, type PredictedObject, type Prediction, type ResultStream, type Roi, type SecretKeyAuth, Semaphore, type Session, type SessionAuth, type Source, type SourceParams, type SourcesEntry, Stream, type StreamEvent, type StreamSource, type StreamTime, type TracingComponent, TranscodeMode, TransientPopId, UploadJob, type UrlSource, UserReview, WebrtcBase, WebrtcWhep, WebrtcWhip, WorkerEndpoint, type WorkerOptions, type WorkerSession, EyePop as default };
@@ -687,11 +687,16 @@ declare class DataEndpoint extends Endpoint<DataEndpoint> {
687
687
  private dispatchChangeEvent;
688
688
  }
689
689
 
690
+ interface StreamEvent {
691
+ type: string;
692
+ source_id?: string;
693
+ message?: string;
694
+ }
690
695
  declare class Stream<Prediction> implements AsyncIterable<Prediction> {
691
696
  private iterator;
692
697
  controller: AbortController;
693
698
  constructor(iterator: () => AsyncIterator<Prediction>, controller: AbortController);
694
- static iterFromReadableStream<Prediction>(readableStream: Promise<ReadableStream<Uint8Array>>, controller: AbortController): AsyncIterator<Prediction, any, undefined>;
699
+ static iterFromReadableStream<Prediction>(readableStream: Promise<ReadableStream<Uint8Array>>, controller: AbortController, eventHandler: (event: StreamEvent) => Promise<void>): AsyncIterator<Prediction, any, undefined>;
695
700
  /**
696
701
  * Generates a Stream from a newline-separated ReadableStream
697
702
  * where each item is a JSON value.
@@ -721,6 +726,7 @@ declare class AbstractJob implements ResultStream {
721
726
  [Symbol.asyncIterator](): AsyncIterator<Prediction>;
722
727
  protected constructor(params: SourceParams | undefined, getSession: () => Promise<WorkerSession>, client: HttpClient, requestLogger: Logger);
723
728
  protected startJob(): Promise<Response>;
729
+ protected onEvent(event: StreamEvent): Promise<void>;
724
730
  static n: number;
725
731
  start(done: () => void, status: (statusCode: number) => void): AbstractJob;
726
732
  cancel(): void;
@@ -728,8 +734,10 @@ declare class AbstractJob implements ResultStream {
728
734
  declare class UploadJob extends AbstractJob {
729
735
  private readonly _uploadStream;
730
736
  private readonly _mimeType;
737
+ private readonly _needsFullDuplex;
731
738
  get [Symbol.toStringTag](): string;
732
739
  constructor(stream: any, mimeType: string, params: SourceParams | undefined, getSession: () => Promise<WorkerSession>, client: HttpClient, requestLogger: Logger);
740
+ protected onEvent(event: StreamEvent): Promise<void>;
733
741
  protected startJob(): Promise<Response>;
734
742
  }
735
743
  declare class LoadFromJob extends AbstractJob {
@@ -807,4 +815,4 @@ declare namespace EyePop {
807
815
  function dataEndpoint(opts?: DataOptions): DataEndpoint;
808
816
  }
809
817
 
810
- export { AbstractJob, type Annotation, AnnotationType, type Asset, type AssetImport, AssetStatus, type Auth0Options, type Authentication, type AutoAnnotateParams, type BaseComponent, type Box, type ChangeEvent, ChangeType, type ComponentFinderComponent, type Contour, type ContourFinderComponent, ContourType, DataEndpoint, type DataOptions, type DataSession, type Dataset, type DatasetCreate, type DatasetHeroAssetUpdate, type DatasetUpdate, type DatasetVersion, type DatasetVersionAssetStats, Endpoint, EndpointState, EyePop, type FileSource, type ForwardComponent, ForwardOperatorType, type InferenceComponent, InferenceType, type IngressEvent, type LiveMedia, type LiveSource, LoadFromJob, LoadLiveIngressJob, type Mask, type Model, type ModelCreate, ModelFormat, type ModelInstanceDef, type ModelMetrics, ModelPrecisionType, type ModelSample, ModelStatus, type ModelTrainingProgress, ModelTrainingStage, ModelType, type ModelUpdate, type OAuth2Auth, type OnChangeEvent, type Options, type PathSource, type Point2d, type Point3d, type Pop, type PopComponent, PopComponentType, type PopCrop, type PopForward, type PopForwardOperator, type PredictedClass, type PredictedKeyPoint, type PredictedKeyPoints, type PredictedLabel, type PredictedMesh, type PredictedObject, type Prediction, type ResultStream, type Roi, type SecretKeyAuth, Semaphore, type Session, type SessionAuth, type Source, type SourceParams, type SourcesEntry, Stream, type StreamSource, type StreamTime, type TracingComponent, TranscodeMode, TransientPopId, UploadJob, type UrlSource, UserReview, WebrtcBase, WebrtcWhep, WebrtcWhip, WorkerEndpoint, type WorkerOptions, type WorkerSession, EyePop as default };
818
+ export { AbstractJob, type Annotation, AnnotationType, type Asset, type AssetImport, AssetStatus, type Auth0Options, type Authentication, type AutoAnnotateParams, type BaseComponent, type Box, type ChangeEvent, ChangeType, type ComponentFinderComponent, type Contour, type ContourFinderComponent, ContourType, DataEndpoint, type DataOptions, type DataSession, type Dataset, type DatasetCreate, type DatasetHeroAssetUpdate, type DatasetUpdate, type DatasetVersion, type DatasetVersionAssetStats, Endpoint, EndpointState, EyePop, type FileSource, type ForwardComponent, ForwardOperatorType, type InferenceComponent, InferenceType, type IngressEvent, type LiveMedia, type LiveSource, LoadFromJob, LoadLiveIngressJob, type Mask, type Model, type ModelCreate, ModelFormat, type ModelInstanceDef, type ModelMetrics, ModelPrecisionType, type ModelSample, ModelStatus, type ModelTrainingProgress, ModelTrainingStage, ModelType, type ModelUpdate, type OAuth2Auth, type OnChangeEvent, type Options, type PathSource, type Point2d, type Point3d, type Pop, type PopComponent, PopComponentType, type PopCrop, type PopForward, type PopForwardOperator, type PredictedClass, type PredictedKeyPoint, type PredictedKeyPoints, type PredictedLabel, type PredictedMesh, type PredictedObject, type Prediction, type ResultStream, type Roi, type SecretKeyAuth, Semaphore, type Session, type SessionAuth, type Source, type SourceParams, type SourcesEntry, Stream, type StreamEvent, type StreamSource, type StreamTime, type TracingComponent, TranscodeMode, TransientPopId, UploadJob, type UrlSource, UserReview, WebrtcBase, WebrtcWhep, WebrtcWhip, WorkerEndpoint, type WorkerOptions, type WorkerSession, EyePop as default };
@@ -8705,7 +8705,7 @@ var Stream = class _Stream {
8705
8705
  this.iterator = iterator;
8706
8706
  this.controller = controller;
8707
8707
  }
8708
- static iterFromReadableStream(readableStream, controller) {
8708
+ static iterFromReadableStream(readableStream, controller, eventHandler) {
8709
8709
  let consumed = false;
8710
8710
  async function* iterLines() {
8711
8711
  const lineDecoder = new LineDecoder();
@@ -8728,7 +8728,16 @@ var Stream = class _Stream {
8728
8728
  try {
8729
8729
  for await (const line of iterLines()) {
8730
8730
  if (done) continue;
8731
- if (line) yield JSON.parse(line);
8731
+ if (line) {
8732
+ const message = JSON.parse(line);
8733
+ const event = message["event"];
8734
+ if (event !== void 0) {
8735
+ eventHandler(event).then(() => {
8736
+ });
8737
+ } else {
8738
+ yield message;
8739
+ }
8740
+ }
8732
8741
  }
8733
8742
  done = true;
8734
8743
  } catch (e) {
@@ -8951,11 +8960,20 @@ var AbstractJob = class {
8951
8960
  if (!this._responseStream) {
8952
8961
  throw Error("logical bug");
8953
8962
  }
8954
- return Stream.iterFromReadableStream(this._responseStream, this._controller);
8963
+ return Stream.iterFromReadableStream(
8964
+ this._responseStream,
8965
+ this._controller,
8966
+ async (event) => {
8967
+ return await this.onEvent(event);
8968
+ }
8969
+ );
8955
8970
  }
8956
8971
  async startJob() {
8957
8972
  return Promise.reject("abstract class");
8958
8973
  }
8974
+ async onEvent(event) {
8975
+ return Promise.resolve();
8976
+ }
8959
8977
  start(done, status) {
8960
8978
  this._responseStream = new Promise(async (resolve, reject) => {
8961
8979
  try {
@@ -9021,50 +9039,126 @@ var UploadJob = class extends AbstractJob {
9021
9039
  super(params, getSession, client, requestLogger);
9022
9040
  this._uploadStream = stream;
9023
9041
  this._mimeType = mimeType;
9042
+ this._needsFullDuplex = mimeType.startsWith("video/");
9043
+ }
9044
+ async onEvent(event) {
9045
+ if (event.type == "prepared") {
9046
+ if (!event.source_id) {
9047
+ return Promise.reject("did not get a prepared sourceId to simulate full duplex");
9048
+ }
9049
+ const session = await this._getSession();
9050
+ if (!session.baseUrl) {
9051
+ return Promise.reject("session.baseUrl must not ne null");
9052
+ }
9053
+ let request;
9054
+ const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=async&sourceId=${event.source_id}`;
9055
+ if (this._params) {
9056
+ this._requestLogger.debug("before POST %s with multipart body because of params", postUrl);
9057
+ const params = JSON.stringify(this._params);
9058
+ const paramBlob = new Blob([params], { type: "application/json" });
9059
+ const formData = new FormData();
9060
+ formData.append("params", paramBlob);
9061
+ formData.append("file", this._uploadStream);
9062
+ const headers = {
9063
+ "Authorization": `Bearer ${session.accessToken}`,
9064
+ "Accept": "application/jsonl"
9065
+ };
9066
+ request = this._client.fetch(postUrl, {
9067
+ headers,
9068
+ method: "POST",
9069
+ body: formData,
9070
+ signal: this._controller.signal,
9071
+ // @ts-ignore
9072
+ duplex: "half"
9073
+ });
9074
+ } else {
9075
+ this._requestLogger.debug("before POST %s with stream as body", postUrl);
9076
+ const headers = {
9077
+ "Authorization": `Bearer ${session.accessToken}`,
9078
+ "Accept": "application/jsonl",
9079
+ "Content-Type": this._mimeType
9080
+ };
9081
+ request = this._client.fetch(postUrl, {
9082
+ headers,
9083
+ method: "POST",
9084
+ body: this._uploadStream,
9085
+ signal: this._controller.signal,
9086
+ // @ts-ignore
9087
+ duplex: "half"
9088
+ });
9089
+ }
9090
+ request.then(async (value) => {
9091
+ if (value.status != 204) {
9092
+ this._requestLogger.debug("unexpected status %d (%s) for POST %s ", value.status, await value.text(), postUrl);
9093
+ }
9094
+ }).catch((reason) => {
9095
+ this._requestLogger.debug("error %v for POST %s ", reason, postUrl);
9096
+ }).finally(() => {
9097
+ this._requestLogger.debug("after POST %s ", postUrl);
9098
+ });
9099
+ }
9100
+ return Promise.resolve();
9024
9101
  }
9025
9102
  async startJob() {
9026
9103
  const session = await this._getSession();
9027
9104
  if (!session.baseUrl) {
9028
9105
  return Promise.reject("session.baseUrl must not ne null");
9029
9106
  }
9030
- const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
9031
9107
  let response;
9032
- if (this._params) {
9033
- this._requestLogger.debug("before POST %s with multipart body because of params");
9034
- const params = JSON.stringify(this._params);
9035
- const paramBlob = new Blob([params], { type: "application/json" });
9036
- const formData = new FormData();
9037
- formData.append("params", paramBlob);
9038
- formData.append("file", this._uploadStream);
9108
+ if (this._needsFullDuplex) {
9109
+ const prepareUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/prepareSource?timeout=10s`;
9039
9110
  const headers = {
9040
9111
  "Authorization": `Bearer ${session.accessToken}`,
9041
9112
  "Accept": "application/jsonl"
9042
9113
  };
9043
- response = await this._client.fetch(postUrl, {
9114
+ this._requestLogger.debug("before POST %s to prepare full duplex upload", prepareUrl);
9115
+ response = await this._client.fetch(prepareUrl, {
9044
9116
  headers,
9045
9117
  method: "POST",
9046
- body: formData,
9047
9118
  signal: this._controller.signal,
9048
9119
  // @ts-ignore
9049
9120
  duplex: "half"
9050
9121
  });
9051
- this._requestLogger.debug("after POST %s with multipart body because of params");
9122
+ this._requestLogger.debug("after POST %s to prepare full duplex upload", prepareUrl);
9052
9123
  } else {
9053
- this._requestLogger.debug("before POST %s with stream as body");
9054
- const headers = {
9055
- "Authorization": `Bearer ${session.accessToken}`,
9056
- "Accept": "application/jsonl",
9057
- "Content-Type": this._mimeType
9058
- };
9059
- response = await this._client.fetch(postUrl, {
9060
- headers,
9061
- method: "POST",
9062
- body: this._uploadStream,
9063
- signal: this._controller.signal,
9064
- // @ts-ignore
9065
- duplex: "half"
9066
- });
9067
- this._requestLogger.debug("after POST %s with stream as body");
9124
+ const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync`;
9125
+ if (this._params) {
9126
+ this._requestLogger.debug("before POST %s with multipart body because of params", postUrl);
9127
+ const params = JSON.stringify(this._params);
9128
+ const paramBlob = new Blob([params], { type: "application/json" });
9129
+ const formData = new FormData();
9130
+ formData.append("params", paramBlob);
9131
+ formData.append("file", this._uploadStream);
9132
+ const headers = {
9133
+ "Authorization": `Bearer ${session.accessToken}`,
9134
+ "Accept": "application/jsonl"
9135
+ };
9136
+ response = await this._client.fetch(postUrl, {
9137
+ headers,
9138
+ method: "POST",
9139
+ body: formData,
9140
+ signal: this._controller.signal,
9141
+ // @ts-ignore
9142
+ duplex: "half"
9143
+ });
9144
+ this._requestLogger.debug("after POST %s with multipart body because of params", postUrl);
9145
+ } else {
9146
+ this._requestLogger.debug("before POST %s with stream as body", postUrl);
9147
+ const headers = {
9148
+ "Authorization": `Bearer ${session.accessToken}`,
9149
+ "Accept": "application/jsonl",
9150
+ "Content-Type": this._mimeType
9151
+ };
9152
+ response = await this._client.fetch(postUrl, {
9153
+ headers,
9154
+ method: "POST",
9155
+ body: this._uploadStream,
9156
+ signal: this._controller.signal,
9157
+ // @ts-ignore
9158
+ duplex: "half"
9159
+ });
9160
+ this._requestLogger.debug("after POST %s with stream as body", postUrl);
9161
+ }
9068
9162
  }
9069
9163
  return response;
9070
9164
  }
@@ -9607,18 +9701,39 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9607
9701
  throw new DOMException("resolving a path to a file is not supported in browser");
9608
9702
  };
9609
9703
  } else {
9704
+ let iteratorToStream = function(iterator) {
9705
+ return new ReadableStream({
9706
+ async pull(controller) {
9707
+ const { value, done } = await iterator.next();
9708
+ if (done) {
9709
+ controller.close();
9710
+ } else {
9711
+ controller.enqueue(new Uint8Array(value));
9712
+ }
9713
+ }
9714
+ });
9715
+ };
9716
+ iteratorToStream2 = iteratorToStream;
9717
+ async function* nodeStreamToIterator(stream) {
9718
+ for await (const chunk of stream) {
9719
+ yield chunk;
9720
+ }
9721
+ }
9610
9722
  resolvePath = async (source) => {
9611
9723
  const mime = require_mime_types();
9612
9724
  const filehandle = require("fs/promises");
9613
9725
  const fd = await filehandle.open(source.path, "r");
9614
9726
  const stream = fd.createReadStream();
9727
+ const iterator = nodeStreamToIterator(stream);
9728
+ const webStream = iteratorToStream(iterator);
9615
9729
  const mimeType = mime.lookup(source.path) || "application/octet-stream";
9616
9730
  return {
9617
- stream,
9731
+ stream: webStream,
9618
9732
  mimeType
9619
9733
  };
9620
9734
  };
9621
9735
  }
9736
+ var iteratorToStream2;
9622
9737
 
9623
9738
  // shims/http_client.ts
9624
9739
  var createHttpClient;
@@ -9653,7 +9768,9 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9653
9768
  const undici = require("undici");
9654
9769
  const agent = new undici.Agent({
9655
9770
  keepAliveTimeout: 1e4,
9656
- connections: 5
9771
+ connections: 5,
9772
+ // two parallel streaming requests to the same host seem to deadlock with pipelining > 0
9773
+ pipelining: 0
9657
9774
  });
9658
9775
  return new HttpClient2(agent);
9659
9776
  };
@@ -11377,7 +11494,7 @@ var EyePop;
11377
11494
  }
11378
11495
  if (typeof opts.auth.oAuth2 != "undefined") {
11379
11496
  if (typeof opts.auth.oAuth2 === "boolean") {
11380
- if (opts.eyepopUrl.startsWith("https://staging-api.eyepop.ai")) {
11497
+ if (opts.eyepopUrl.startsWith("https://web-api.staging.eyepop.xyz")) {
11381
11498
  opts.auth = {
11382
11499
  oAuth2: {
11383
11500
  domain: "dev-eyepop.us.auth0.com",