@eyepop.ai/eyepop 1.13.1 → 1.14.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.
@@ -8668,6 +8668,7 @@ __export(index_exports, {
8668
8668
  EndpointState: () => EndpointState,
8669
8669
  ExportedBy: () => ExportedBy,
8670
8670
  EyePop: () => EyePop,
8671
+ EyepopLineDecoder: () => EyepopLineDecoder,
8671
8672
  ForwardOperatorType: () => ForwardOperatorType,
8672
8673
  InferenceType: () => InferenceType,
8673
8674
  LoadFromJob: () => LoadFromJob,
@@ -8881,6 +8882,65 @@ function readableStreamAsyncIterable(stream) {
8881
8882
  };
8882
8883
  }
8883
8884
 
8885
+ // worker/worker_types.ts
8886
+ var VideoMode = /* @__PURE__ */ ((VideoMode2) => {
8887
+ VideoMode2["STREAM"] = "stream";
8888
+ VideoMode2["BUFFER"] = "buffer";
8889
+ return VideoMode2;
8890
+ })(VideoMode || {});
8891
+ var ModelFormat = /* @__PURE__ */ ((ModelFormat2) => {
8892
+ ModelFormat2["TensorFlowLite"] = "TensorFlowLite";
8893
+ ModelFormat2["TensorFlowGraphDef"] = "TensorFlowGraphDef";
8894
+ ModelFormat2["ONNX"] = "ONNX";
8895
+ ModelFormat2["TorchScript"] = "TorchScript";
8896
+ ModelFormat2["TorchScriptCpu"] = "TorchScriptCpu";
8897
+ ModelFormat2["TorchScriptCuda"] = "TorchScriptCuda";
8898
+ return ModelFormat2;
8899
+ })(ModelFormat || {});
8900
+ var ModelPrecisionType = /* @__PURE__ */ ((ModelPrecisionType2) => {
8901
+ ModelPrecisionType2["float32"] = "float32";
8902
+ ModelPrecisionType2["float16"] = "float16";
8903
+ ModelPrecisionType2["int32"] = "int32";
8904
+ ModelPrecisionType2["int8"] = "int8";
8905
+ ModelPrecisionType2["uint8"] = "uint8";
8906
+ return ModelPrecisionType2;
8907
+ })(ModelPrecisionType || {});
8908
+ var PopComponentType = /* @__PURE__ */ ((PopComponentType2) => {
8909
+ PopComponentType2["FORWARD"] = "forward";
8910
+ PopComponentType2["INFERENCE"] = "inference";
8911
+ PopComponentType2["TRACING"] = "tracing";
8912
+ PopComponentType2["CONTOUR_FINDER"] = "contour_finder";
8913
+ PopComponentType2["COMPONENT_FINDER"] = "component_finder";
8914
+ return PopComponentType2;
8915
+ })(PopComponentType || {});
8916
+ var ForwardOperatorType = /* @__PURE__ */ ((ForwardOperatorType2) => {
8917
+ ForwardOperatorType2["FULL"] = "full";
8918
+ ForwardOperatorType2["CROP"] = "crop";
8919
+ ForwardOperatorType2["CROP_WITH_FULL_FALLBACK"] = "crop_with_full_fallback";
8920
+ return ForwardOperatorType2;
8921
+ })(ForwardOperatorType || {});
8922
+ var InferenceType = /* @__PURE__ */ ((InferenceType2) => {
8923
+ InferenceType2["IMAGE_CLASSIFICATION"] = "image_classification";
8924
+ InferenceType2["OBJECT_DETECTION"] = "object_detection";
8925
+ InferenceType2["KEY_POINTS"] = "key_points";
8926
+ InferenceType2["OCR"] = "ocr";
8927
+ InferenceType2["MESH"] = "mesh";
8928
+ InferenceType2["FEATURE_VECTOR"] = "feature_vector";
8929
+ InferenceType2["SEMANTIC_SEGMENTATION"] = "semantic_segmentation";
8930
+ InferenceType2["SEGMENTATION"] = "segmentation";
8931
+ return InferenceType2;
8932
+ })(InferenceType || {});
8933
+ var ContourType = /* @__PURE__ */ ((ContourType2) => {
8934
+ ContourType2["ALL_PIXELS"] = "all_pixels";
8935
+ ContourType2["POLYGON"] = "polygon";
8936
+ ContourType2["CONVEX_HULL"] = "convex_hull";
8937
+ ContourType2["HOUGH_CIRCLES"] = "hough_circles";
8938
+ ContourType2["CIRCLE"] = "circle";
8939
+ ContourType2["TRIANGLE"] = "triangle";
8940
+ ContourType2["RECTANGLE"] = "rectangle";
8941
+ return ContourType2;
8942
+ })(ContourType || {});
8943
+
8884
8944
  // worker/jobs.ts
8885
8945
  var AbstractJob = class {
8886
8946
  constructor(params, getSession, client, requestLogger) {
@@ -8932,7 +8992,7 @@ var AbstractJob = class {
8932
8992
  reject(`upload error ${response.status}: ${await response.text()}`);
8933
8993
  break;
8934
8994
  } else if (!response.body) {
8935
- reject(`response body is empty`);
8995
+ reject("response body is empty");
8936
8996
  break;
8937
8997
  } else {
8938
8998
  resolve(response.body);
@@ -8966,12 +9026,13 @@ var UploadJob = class extends AbstractJob {
8966
9026
  get [Symbol.toStringTag]() {
8967
9027
  return "uploadJob";
8968
9028
  }
8969
- constructor(stream, mimeType, videoMode, params, getSession, client, requestLogger) {
9029
+ constructor(stream, mimeType, size, videoMode, params, getSession, client, requestLogger) {
8970
9030
  super(params, getSession, client, requestLogger);
8971
9031
  this._uploadStream = stream;
8972
9032
  this._mimeType = mimeType;
9033
+ this._size = size;
8973
9034
  this._videoMode = videoMode;
8974
- this._needsFullDuplex = !client.isFullDuplex() && mimeType.startsWith("video/");
9035
+ this._needsFullDuplex = !client.isFullDuplex() && mimeType.startsWith("video/") && videoMode == "stream" /* STREAM */;
8975
9036
  }
8976
9037
  async onEvent(event) {
8977
9038
  if (event.type == "prepared") {
@@ -8986,7 +9047,7 @@ var UploadJob = class extends AbstractJob {
8986
9047
  const videoModeQuery = this._videoMode ? `&videoMode=${this._videoMode}` : "";
8987
9048
  const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=async&sourceId=${event.source_id}${videoModeQuery}`;
8988
9049
  if (this._params) {
8989
- this._requestLogger.debug("before POST %s with multipart body because of params", postUrl);
9050
+ this._requestLogger.debug(`before POST ${postUrl} with multipart body because of params`);
8990
9051
  const params = JSON.stringify(this._params);
8991
9052
  const paramBlob = new Blob([params], { type: "application/json" });
8992
9053
  const formData = new FormData();
@@ -9006,12 +9067,15 @@ var UploadJob = class extends AbstractJob {
9006
9067
  duplex: "half"
9007
9068
  });
9008
9069
  } else {
9009
- this._requestLogger.debug("before POST %s with stream as body", postUrl);
9070
+ this._requestLogger.debug(`before POST ${postUrl} with stream as body`);
9010
9071
  const headers = {
9011
9072
  ...session.authenticationHeaders(),
9012
9073
  Accept: "application/jsonl",
9013
9074
  "Content-Type": this._mimeType
9014
9075
  };
9076
+ if (this._size) {
9077
+ headers["Content-Length"] = `${this._size}`;
9078
+ }
9015
9079
  request = this._client.fetch(postUrl, {
9016
9080
  headers,
9017
9081
  method: "POST",
@@ -9023,12 +9087,12 @@ var UploadJob = class extends AbstractJob {
9023
9087
  }
9024
9088
  request.then(async (value) => {
9025
9089
  if (value.status != 204) {
9026
- this._requestLogger.debug("unexpected status %d (%s) for POST %s ", value.status, await value.text(), postUrl);
9090
+ this._requestLogger.debug(`unexpected status ${value.status} (${await value.text()}) for POST ${postUrl}`);
9027
9091
  }
9028
9092
  }).catch((reason) => {
9029
- this._requestLogger.debug("error %v for POST %s ", reason, postUrl);
9093
+ this._requestLogger.debug(`error ${reason} for POST ${postUrl}`);
9030
9094
  }).finally(() => {
9031
- this._requestLogger.debug("after POST %s ", postUrl);
9095
+ this._requestLogger.debug(`after POST ${postUrl}`);
9032
9096
  });
9033
9097
  }
9034
9098
  return Promise.resolve();
@@ -9036,7 +9100,7 @@ var UploadJob = class extends AbstractJob {
9036
9100
  async startJob() {
9037
9101
  const session = await this._getSession();
9038
9102
  if (!session.baseUrl) {
9039
- return Promise.reject("session.baseUrl must not ne null");
9103
+ return Promise.reject("session.baseUrl must not be null");
9040
9104
  }
9041
9105
  let response;
9042
9106
  if (this._needsFullDuplex) {
@@ -9045,7 +9109,7 @@ var UploadJob = class extends AbstractJob {
9045
9109
  ...session.authenticationHeaders(),
9046
9110
  Accept: "application/jsonl"
9047
9111
  };
9048
- this._requestLogger.debug("before POST {} to prepare full duplex upload", prepareUrl);
9112
+ this._requestLogger.debug(`before POST ${prepareUrl} to prepare full duplex upload`);
9049
9113
  response = await this._client.fetch(prepareUrl, {
9050
9114
  headers,
9051
9115
  method: "POST",
@@ -9053,12 +9117,12 @@ var UploadJob = class extends AbstractJob {
9053
9117
  // @ts-ignore
9054
9118
  duplex: "half"
9055
9119
  });
9056
- this._requestLogger.debug("after POST {} to prepare full duplex upload {} {}", prepareUrl, response.status, response.statusText);
9120
+ this._requestLogger.debug(`after POST ${prepareUrl} to prepare full duplex upload ${response.status} ${response.statusText}`);
9057
9121
  } else {
9058
9122
  const videoModeQuery = this._videoMode ? `&videoMode=${this._videoMode}` : "";
9059
9123
  const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync${videoModeQuery}`;
9060
9124
  if (this._params) {
9061
- this._requestLogger.debug("before POST {} with multipart body because of params", postUrl);
9125
+ this._requestLogger.debug(`before POST ${postUrl} with multipart body because of params`);
9062
9126
  const params = JSON.stringify(this._params);
9063
9127
  const paramBlob = new Blob([params], { type: "application/json" });
9064
9128
  const formData = new FormData();
@@ -9077,14 +9141,17 @@ var UploadJob = class extends AbstractJob {
9077
9141
  // @ts-ignore
9078
9142
  duplex: "half"
9079
9143
  });
9080
- this._requestLogger.debug("after POST %s with multipart body because of params", postUrl);
9144
+ this._requestLogger.debug(`after POST ${postUrl} with multipart body because of params)`);
9081
9145
  } else {
9082
- this._requestLogger.debug("before POST %s with stream as body", postUrl);
9146
+ this._requestLogger.debug(`before POST ${postUrl} with stream as body`);
9083
9147
  const headers = {
9084
9148
  ...session.authenticationHeaders(),
9085
9149
  Accept: "application/jsonl",
9086
9150
  "Content-Type": this._mimeType
9087
9151
  };
9152
+ if (this._size) {
9153
+ headers["Content-Length"] = `${this._size}`;
9154
+ }
9088
9155
  response = await this._client.fetch(postUrl, {
9089
9156
  headers,
9090
9157
  method: "POST",
@@ -9093,7 +9160,7 @@ var UploadJob = class extends AbstractJob {
9093
9160
  // @ts-ignore
9094
9161
  duplex: "half"
9095
9162
  });
9096
- this._requestLogger.debug("after POST %s with stream as body", postUrl);
9163
+ this._requestLogger.debug(`after POST ${postUrl} with stream as body`);
9097
9164
  }
9098
9165
  }
9099
9166
  return response;
@@ -9595,17 +9662,85 @@ var WebrtcWhep = class extends WebrtcBase {
9595
9662
  // shims/local_file.ts
9596
9663
  var resolvePath;
9597
9664
  if ("document" in globalThis && "implementation" in globalThis.document) {
9598
- resolvePath = async (source) => {
9665
+ resolvePath = async (source, logger) => {
9599
9666
  throw new DOMException("resolving a path to a file is not supported in browser");
9600
9667
  };
9601
9668
  } else if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
9602
- resolvePath = async (source) => {
9603
- const response = await fetch(`file://${source.path}`);
9604
- const blob = await response.blob();
9605
- return {
9606
- stream: blob,
9607
- mimeType: source.mimeType || "image/*"
9608
- };
9669
+ let RNFSName = "react-native-fs";
9670
+ let RNFS;
9671
+ let RNFSLoadError;
9672
+ try {
9673
+ RNFS = require(RNFSName);
9674
+ } catch (e) {
9675
+ RNFSLoadError = e;
9676
+ }
9677
+ let EFSName = "expo-file-system";
9678
+ let EFS;
9679
+ let EFSLoadError;
9680
+ try {
9681
+ EFS = require(EFSName);
9682
+ } catch (e) {
9683
+ EFSLoadError = e;
9684
+ }
9685
+ resolvePath = async (source, logger) => {
9686
+ if (RNFS?.read !== void 0) {
9687
+ logger.debug("Using react-native-fs to read local file");
9688
+ const bufferSize = 1024 * 1024;
9689
+ let pos = 0;
9690
+ let eof = false;
9691
+ const stream = new ReadableStream({
9692
+ async pull(controller) {
9693
+ if (eof) {
9694
+ return;
9695
+ }
9696
+ const chunkAsB64 = await RNFS.read(source.path, bufferSize, pos, "base64");
9697
+ if (chunkAsB64.length > 0) {
9698
+ const chunk = Buffer.from(chunkAsB64, "base64");
9699
+ controller.enqueue(chunk);
9700
+ pos += chunk.length;
9701
+ } else {
9702
+ eof = true;
9703
+ controller.close();
9704
+ }
9705
+ }
9706
+ });
9707
+ return {
9708
+ stream,
9709
+ size: (await RNFS.stat(source.path)).size,
9710
+ mimeType: source.mimeType || "image/*"
9711
+ };
9712
+ } else if (EFS?.readAsStringAsync !== void 0) {
9713
+ logger.debug("Using expo-file-system to read local file");
9714
+ const bufferSize = 1024 * 1024;
9715
+ let pos = 0;
9716
+ let eof = false;
9717
+ const stream = new ReadableStream({
9718
+ async pull(controller) {
9719
+ if (eof) {
9720
+ return;
9721
+ }
9722
+ const chunkAsB64 = await EFS.readAsStringAsync(`file://${source.path}`, {
9723
+ length: bufferSize,
9724
+ position: pos,
9725
+ encoding: "base64"
9726
+ });
9727
+ if (chunkAsB64) {
9728
+ const chunk = Buffer.from(chunkAsB64, "base64");
9729
+ controller.enqueue(chunk);
9730
+ pos += chunk.length;
9731
+ } else {
9732
+ eof = true;
9733
+ controller.close();
9734
+ }
9735
+ }
9736
+ });
9737
+ return {
9738
+ stream,
9739
+ size: (await EFS.getInfoAsync(`file://${source.path}`)).size,
9740
+ mimeType: source.mimeType || "image/*"
9741
+ };
9742
+ }
9743
+ return Promise.reject(`Could not load '${RNFSName}' (reason" ${RNFSLoadError}) or '${EFSName}' (reason" ${EFSLoadError}), include either of those packages in your application to enable uploads via PathSource - or provide the stream itself via StreamSource.`);
9609
9744
  };
9610
9745
  } else {
9611
9746
  let iteratorToStream = function(iterator) {
@@ -9626,7 +9761,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9626
9761
  yield chunk;
9627
9762
  }
9628
9763
  }
9629
- resolvePath = async (source) => {
9764
+ resolvePath = async (source, logger) => {
9630
9765
  const mime = require_mime_types();
9631
9766
  const filehandle = require("fs/promises");
9632
9767
  const fd = await filehandle.open(source.path, "r");
@@ -9642,6 +9777,403 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9642
9777
  }
9643
9778
  var iteratorToStream2;
9644
9779
 
9780
+ // shims/rn_http_header_parser.ts
9781
+ var startLine = /^[A-Z_]+(\/\d\.\d)? /;
9782
+ var requestLine = /^([A-Z_]+) (.+) [A-Z]+\/(\d)\.(\d)$/;
9783
+ var statusLine = /^[A-Z]+\/(\d)\.(\d) (\d{3}) (.*)$/;
9784
+ function parseHttpHeader(lines, onlyHeaders) {
9785
+ var line = lines[0];
9786
+ var match;
9787
+ if (onlyHeaders && startLine.test(line)) {
9788
+ return parseHeaders(lines);
9789
+ } else if ((match = line.match(requestLine)) !== null) {
9790
+ return {
9791
+ method: match[1],
9792
+ url: match[2],
9793
+ version: { major: parseInt(match[3], 10), minor: parseInt(match[4], 10) },
9794
+ headers: parseHeaders(lines)
9795
+ };
9796
+ } else if ((match = line.match(statusLine)) !== null) {
9797
+ return {
9798
+ version: { major: parseInt(match[1], 10), minor: parseInt(match[2], 10) },
9799
+ statusCode: parseInt(match[3], 10),
9800
+ statusMessage: match[4],
9801
+ headers: parseHeaders(lines)
9802
+ };
9803
+ } else {
9804
+ return parseHeaders(lines);
9805
+ }
9806
+ }
9807
+ function parseHeaders(lines) {
9808
+ var headers = {};
9809
+ var i = 0;
9810
+ var line = lines[i];
9811
+ var index, name, value;
9812
+ if (startLine.test(line)) {
9813
+ line = line[++i];
9814
+ }
9815
+ while (line) {
9816
+ if (line[0] === " " || line[0] === " ") {
9817
+ value += " " + line.trim();
9818
+ i++;
9819
+ if (i < lines.length) {
9820
+ line = lines[i];
9821
+ } else {
9822
+ line = "";
9823
+ }
9824
+ continue;
9825
+ }
9826
+ if (name && value) {
9827
+ addHeaderLine(name, value, headers);
9828
+ }
9829
+ index = line.indexOf(":");
9830
+ name = line.substr(0, index);
9831
+ value = line.substr(index + 1).trim();
9832
+ i++;
9833
+ if (i < lines.length) {
9834
+ line = lines[i];
9835
+ } else {
9836
+ line = "";
9837
+ }
9838
+ }
9839
+ if (name && value) {
9840
+ addHeaderLine(name, value, headers);
9841
+ }
9842
+ return headers;
9843
+ }
9844
+ function addHeaderLine(field, value, dest) {
9845
+ field = field.toLowerCase();
9846
+ switch (field) {
9847
+ // Array headers:
9848
+ case "set-cookie":
9849
+ if (dest[field] !== void 0) {
9850
+ dest[field].push(value);
9851
+ } else {
9852
+ dest[field] = [value];
9853
+ }
9854
+ break;
9855
+ // list is taken from:
9856
+ // https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
9857
+ case "content-type":
9858
+ case "content-length":
9859
+ case "user-agent":
9860
+ case "referer":
9861
+ case "host":
9862
+ case "authorization":
9863
+ case "proxy-authorization":
9864
+ case "if-modified-since":
9865
+ case "if-unmodified-since":
9866
+ case "from":
9867
+ case "location":
9868
+ case "max-forwards":
9869
+ case "retry-after":
9870
+ case "etag":
9871
+ case "last-modified":
9872
+ case "server":
9873
+ case "age":
9874
+ case "expires":
9875
+ if (dest[field] === void 0) dest[field] = value;
9876
+ break;
9877
+ default:
9878
+ if (typeof dest[field] === "string") {
9879
+ dest[field] += ", " + value;
9880
+ } else {
9881
+ dest[field] = value;
9882
+ }
9883
+ }
9884
+ }
9885
+
9886
+ // shims/rn_http_response_parser.ts
9887
+ var ResponseParser = class {
9888
+ constructor(logger, resolve, reject) {
9889
+ this.responseChunkRemainder = 0;
9890
+ this.logger = logger;
9891
+ this.resolve = resolve;
9892
+ this.reject = reject;
9893
+ this.error = null;
9894
+ this.responseReadBuffer = void 0;
9895
+ this.responseState = 0 /* RECEIVING_HEADER */;
9896
+ this.pullController = void 0;
9897
+ this.pullResolve = void 0;
9898
+ this.pullReject = void 0;
9899
+ }
9900
+ processResponseReadBuffer(data) {
9901
+ if (this.error) {
9902
+ this.logger.info(`RN http streamed response, received ${data.length} bytes in error mode`);
9903
+ return false;
9904
+ }
9905
+ if (this.responseReadBuffer) {
9906
+ this.responseReadBuffer = Buffer.concat([this.responseReadBuffer, data]);
9907
+ } else {
9908
+ this.responseReadBuffer = Buffer.from(data.subarray());
9909
+ }
9910
+ if (this.responseState === 3 /* RECEIVING_COMPLETED */) {
9911
+ if (this.pullController) {
9912
+ this.pullController.close();
9913
+ if (this.pullResolve) {
9914
+ this.pullResolve();
9915
+ }
9916
+ }
9917
+ return false;
9918
+ } else if (this.responseState === 0 /* RECEIVING_HEADER */) {
9919
+ const headerEnd = this.responseReadBuffer.indexOf("\r\n\r\n");
9920
+ if (headerEnd >= 0) {
9921
+ let headerChunk = this.responseReadBuffer.subarray(0, headerEnd + 4);
9922
+ this.responseReadBuffer = Buffer.from(this.responseReadBuffer.subarray(headerEnd + 4));
9923
+ const maxHeaderLines = 128;
9924
+ let responseHeaderLines = [];
9925
+ const lineDecoder = new EyepopLineDecoder();
9926
+ for (const line of lineDecoder.decode(headerChunk)) {
9927
+ if (line.length > 0) {
9928
+ responseHeaderLines.push(line);
9929
+ if (responseHeaderLines.length > maxHeaderLines) {
9930
+ this.error = `Response header exceeds ${maxHeaderLines} lines`;
9931
+ this.reject(this.error);
9932
+ return false;
9933
+ }
9934
+ }
9935
+ }
9936
+ let responseHeader = parseHttpHeader(responseHeaderLines, false);
9937
+ if (responseHeader.statusCode === void 0) {
9938
+ this.logger.warn(`Could not find status header in HTTP response ${JSON.stringify(responseHeader)}`);
9939
+ this.reject("missing status header in HTTP response");
9940
+ return false;
9941
+ }
9942
+ const headers = new Headers(responseHeader.headers);
9943
+ if (headers.has("transfer-encoding")) {
9944
+ if (headers.get("transfer-encoding")?.toLowerCase() === "chunked") {
9945
+ this.responseState = 2 /* RECEIVING_BODY_CHUNKED */;
9946
+ this.responseChunkRemainder = 0;
9947
+ } else {
9948
+ this.error = `Response with unsupported transfer-encoding '${headers.get("transfer-encoding")}'`;
9949
+ this.reject(this.error);
9950
+ return false;
9951
+ }
9952
+ } else if (headers.has("content-length")) {
9953
+ this.responseState = 1 /* RECEIVING_BODY */;
9954
+ this.responseChunkRemainder = parseInt(headers.get("content-length") || "-1");
9955
+ } else {
9956
+ this.responseState = 2 /* RECEIVING_BODY_CHUNKED */;
9957
+ this.responseChunkRemainder = 0;
9958
+ }
9959
+ const responseBody = new ReadableStream({
9960
+ pull: (controller) => {
9961
+ if (this.error || this.responseState == 3 /* RECEIVING_COMPLETED */) {
9962
+ return;
9963
+ }
9964
+ if (this.pull(controller)) {
9965
+ return;
9966
+ }
9967
+ return new Promise((resolve, reject) => {
9968
+ if (this.pullController) {
9969
+ if (this.pullReject) {
9970
+ this.pullReject("pull, we got a pending controller already");
9971
+ }
9972
+ }
9973
+ this.pullController = controller;
9974
+ this.pullResolve = resolve;
9975
+ this.pullReject = reject;
9976
+ });
9977
+ },
9978
+ cancel: (reason) => {
9979
+ if (!this.error) {
9980
+ this.error = `cancelled: ${reason}`;
9981
+ this.reject(this.error);
9982
+ }
9983
+ }
9984
+ });
9985
+ this.resolve(new Response(responseBody, {
9986
+ status: responseHeader.statusCode,
9987
+ statusText: responseHeader.statusText,
9988
+ headers
9989
+ }));
9990
+ }
9991
+ } else if (this.pullController) {
9992
+ if (this.pull(this.pullController)) {
9993
+ this.pullController = void 0;
9994
+ if (this.pullResolve) {
9995
+ this.pullResolve();
9996
+ }
9997
+ this.pullResolve = void 0;
9998
+ this.pullReject = void 0;
9999
+ }
10000
+ }
10001
+ return true;
10002
+ }
10003
+ pull(controller) {
10004
+ if (this.responseState == 3 /* RECEIVING_COMPLETED */) {
10005
+ controller.close();
10006
+ return false;
10007
+ }
10008
+ if (this.responseReadBuffer === void 0) {
10009
+ return false;
10010
+ }
10011
+ if (this.responseState == 1 /* RECEIVING_BODY */) {
10012
+ controller.enqueue(this.responseReadBuffer);
10013
+ this.responseChunkRemainder -= this.responseReadBuffer.length;
10014
+ this.responseReadBuffer = void 0;
10015
+ if (this.responseChunkRemainder <= 0) {
10016
+ this.responseState = 3 /* RECEIVING_COMPLETED */;
10017
+ controller.close();
10018
+ }
10019
+ return true;
10020
+ } else if (this.responseState == 2 /* RECEIVING_BODY_CHUNKED */) {
10021
+ while (this.responseReadBuffer.length > 1) {
10022
+ if (this.responseChunkRemainder == 0) {
10023
+ let chunkHeaderEnd = 0;
10024
+ while (this.responseReadBuffer.length >= 2 && chunkHeaderEnd == 0) {
10025
+ chunkHeaderEnd = this.responseReadBuffer.indexOf("\r\n");
10026
+ if (chunkHeaderEnd == 0) {
10027
+ this.responseReadBuffer = Buffer.from(this.responseReadBuffer.subarray(2));
10028
+ }
10029
+ }
10030
+ if (chunkHeaderEnd > 0) {
10031
+ this.responseChunkRemainder = parseInt(Buffer.from(this.responseReadBuffer, 0, chunkHeaderEnd).toString("utf8"), 16);
10032
+ this.responseReadBuffer = Buffer.from(this.responseReadBuffer.subarray(chunkHeaderEnd + 2));
10033
+ if (this.responseChunkRemainder <= 0) {
10034
+ this.responseState = 3 /* RECEIVING_COMPLETED */;
10035
+ controller.close();
10036
+ return true;
10037
+ }
10038
+ } else if (this.responseReadBuffer.length > 64) {
10039
+ this.error = "Cannot find chunked encoding header within 64 bytes, given up";
10040
+ controller.error(this.error);
10041
+ }
10042
+ }
10043
+ if (this.responseChunkRemainder > 0 && this.responseReadBuffer.length > 0) {
10044
+ const chunk = Buffer.from(this.responseReadBuffer.subarray(0, this.responseChunkRemainder));
10045
+ this.responseReadBuffer = Buffer.from(this.responseReadBuffer.subarray(this.responseChunkRemainder));
10046
+ controller.enqueue(chunk);
10047
+ this.responseChunkRemainder -= chunk.length;
10048
+ return true;
10049
+ } else {
10050
+ break;
10051
+ }
10052
+ }
10053
+ } else {
10054
+ this.error = `Received more data in wrong state ${this.responseState}`;
10055
+ controller.error(this.error);
10056
+ }
10057
+ return false;
10058
+ }
10059
+ };
10060
+
10061
+ // shims/rn_streaming_fetch.ts
10062
+ async function reactNativeStreamingFetch(url, method, headers, body, contentLength, sockets, logger) {
10063
+ const isHttps = url.protocol == "https:";
10064
+ const port = url.port ? parseInt(url.port) : isHttps ? 443 : 80;
10065
+ return new Promise((resolve, reject) => {
10066
+ const connectOptions = {
10067
+ port,
10068
+ host: url.hostname,
10069
+ reuseAddress: true
10070
+ };
10071
+ const clientSocket = new sockets.Socket();
10072
+ const client = isHttps ? new sockets.TLSSocket(clientSocket) : clientSocket;
10073
+ let error;
10074
+ const responseParser = new ResponseParser(logger, resolve, (reason) => {
10075
+ error = reason;
10076
+ reject(error);
10077
+ client.destroy();
10078
+ });
10079
+ client.on("data", function(data) {
10080
+ responseParser.processResponseReadBuffer(data);
10081
+ });
10082
+ client.on("error", function(err) {
10083
+ logger.info(`error: ${err}`);
10084
+ if (!error) {
10085
+ error = err;
10086
+ reject(error);
10087
+ }
10088
+ client.destroy();
10089
+ });
10090
+ client.on("close", function() {
10091
+ if (!error) {
10092
+ error = "socket closed";
10093
+ reject(error);
10094
+ }
10095
+ });
10096
+ client.connect(connectOptions, async () => {
10097
+ const headerLines = [
10098
+ `${method} ${url.pathname}${url.search} HTTP/1.1\r
10099
+ `,
10100
+ `Host: ${url.host}\r
10101
+ `
10102
+ ];
10103
+ headers.forEach((value, key) => {
10104
+ headerLines.push(`${key}: ${value}\r
10105
+ `);
10106
+ });
10107
+ headerLines.push("\r\n");
10108
+ const textEncoder = new TextEncoder();
10109
+ const headerChunk = headerLines.join("");
10110
+ const bodyReader = body ? body.getReader() : void 0;
10111
+ let headerEnqueued = false;
10112
+ let eof = false;
10113
+ const readableHeaderChunkedBody = new ReadableStream({
10114
+ async pull(controller) {
10115
+ if (!headerEnqueued) {
10116
+ controller.enqueue(headerChunk);
10117
+ headerEnqueued = true;
10118
+ return;
10119
+ }
10120
+ if (eof) {
10121
+ controller.close();
10122
+ return;
10123
+ }
10124
+ if (!bodyReader) {
10125
+ controller.close();
10126
+ return;
10127
+ }
10128
+ const chunk = await bodyReader.read();
10129
+ if (chunk.value) {
10130
+ let outputChunk;
10131
+ if (contentLength) {
10132
+ outputChunk = chunk.value;
10133
+ } else {
10134
+ outputChunk = Buffer.concat([
10135
+ textEncoder.encode(`${chunk.value.length.toString(16)}\r
10136
+ `),
10137
+ chunk.value,
10138
+ textEncoder.encode(`\r
10139
+ `)
10140
+ ]);
10141
+ }
10142
+ controller.enqueue(outputChunk);
10143
+ } else if (chunk.done) {
10144
+ if (!contentLength) {
10145
+ controller.enqueue(Buffer.from(`0\r
10146
+ \r
10147
+ `, "utf8"));
10148
+ }
10149
+ eof = true;
10150
+ }
10151
+ }
10152
+ });
10153
+ const readableHeaderChunkedBodyReader = readableHeaderChunkedBody.getReader();
10154
+ const pipeChunk = async () => {
10155
+ while (true) {
10156
+ try {
10157
+ const chunk = await readableHeaderChunkedBodyReader.read();
10158
+ if (chunk.value) {
10159
+ if (!client.write(chunk.value)) {
10160
+ break;
10161
+ }
10162
+ } else if (chunk.done) {
10163
+ break;
10164
+ }
10165
+ } catch (e) {
10166
+ logger.error(e);
10167
+ break;
10168
+ }
10169
+ }
10170
+ };
10171
+ client.on("drain", pipeChunk);
10172
+ await pipeChunk();
10173
+ });
10174
+ });
10175
+ }
10176
+
9645
10177
  // shims/http_client.ts
9646
10178
  var createHttpClient;
9647
10179
  if ("document" in globalThis && "implementation" in globalThis.document) {
@@ -9657,15 +10189,97 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9657
10189
  return false;
9658
10190
  }
9659
10191
  }
9660
- createHttpClient = async () => {
10192
+ createHttpClient = async (logger) => {
10193
+ logger.debug("Using browser fetch as http client");
9661
10194
  return new BrowserHttpClient();
9662
10195
  };
9663
10196
  } else if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
10197
+ let RNName = "react-native";
10198
+ let RN;
10199
+ let TcpSocketsName = "react-native-tcp-socket";
10200
+ let TcpSockets;
10201
+ let TcpSocketsError;
10202
+ try {
10203
+ RN = require(RNName);
10204
+ TcpSockets = require(TcpSocketsName);
10205
+ if (TcpSockets?.TLSSocket) {
10206
+ if (!RN?.NativeModules?.TcpSockets) {
10207
+ TcpSockets = void 0;
10208
+ throw Error(`'${TcpSocketsName}' but not symbol NativeModules?.TcpSockets, native sockets not available when running 'npx expo start', use 'npx expo run:android' or 'npx expo run:ios' instead`);
10209
+ }
10210
+ }
10211
+ } catch (e) {
10212
+ TcpSocketsError = e;
10213
+ }
9664
10214
  class ReactNativeHttpClient {
9665
- constructor() {
10215
+ constructor(logger) {
10216
+ this.logger = logger;
9666
10217
  }
9667
10218
  async fetch(input, init) {
9668
10219
  init || (init = {});
10220
+ let streamBody;
10221
+ if (input instanceof Request) {
10222
+ if (input.body instanceof ReadableStream) {
10223
+ streamBody = input.body;
10224
+ }
10225
+ } else if (init?.body instanceof ReadableStream) {
10226
+ streamBody = init.body;
10227
+ }
10228
+ if (streamBody) {
10229
+ if (TcpSockets?.TLSSocket !== void 0) {
10230
+ let url;
10231
+ let method;
10232
+ let headers;
10233
+ if (input instanceof Request) {
10234
+ url = new URL(input.url);
10235
+ method = input.method;
10236
+ headers = input.headers;
10237
+ } else {
10238
+ if (input instanceof URL) {
10239
+ url = input;
10240
+ } else {
10241
+ url = new URL(input);
10242
+ }
10243
+ method = init?.method || "POST";
10244
+ headers = new Headers(init?.headers);
10245
+ }
10246
+ let contentLength = void 0;
10247
+ if (headers.has("content-length")) {
10248
+ contentLength = parseInt(headers.get("content-length") || "");
10249
+ } else {
10250
+ headers.append("Transfer-Encoding", "chunked");
10251
+ }
10252
+ return await reactNativeStreamingFetch(
10253
+ url,
10254
+ method,
10255
+ headers,
10256
+ streamBody,
10257
+ contentLength,
10258
+ TcpSockets,
10259
+ this.logger
10260
+ );
10261
+ } else {
10262
+ this.logger.warn(`[${TcpSockets}] Could not load '${TcpSocketsName}' (reason" ${TcpSocketsError}), include this package in your application to enable streamed uploads; without this package local files have to be loaded into memory uploading and this will cause Out-Of-Memory errors for large files.`);
10263
+ try {
10264
+ const chunks = [];
10265
+ const reader = streamBody.getReader();
10266
+ while (true) {
10267
+ const { done, value } = await reader.read();
10268
+ if (done) {
10269
+ break;
10270
+ }
10271
+ chunks.push(value);
10272
+ }
10273
+ if (input instanceof Request) {
10274
+ input = new Request(input, { body: Buffer.concat(chunks) });
10275
+ } else {
10276
+ init.body = Buffer.concat(chunks);
10277
+ }
10278
+ } catch (e) {
10279
+ return Promise.reject(e);
10280
+ }
10281
+ }
10282
+ }
9669
10283
  init.reactNative = { textStreaming: true };
9670
10284
  return await fetch(input, init);
9671
10285
  }
@@ -9675,8 +10289,9 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9675
10289
  return true;
9676
10290
  }
9677
10291
  }
9678
- createHttpClient = async () => {
9679
- return new ReactNativeHttpClient();
10292
+ createHttpClient = async (logger) => {
10293
+ logger.debug("using React Native fetch and will attempt direct sockets communication for uploads to workaround the missing request body streaming support in React Native.");
10294
+ return new ReactNativeHttpClient(logger);
9680
10295
  };
9681
10296
  } else {
9682
10297
  class NodeHttpClient {
@@ -9695,7 +10310,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9695
10310
  return false;
9696
10311
  }
9697
10312
  }
9698
- createHttpClient = async () => {
10313
+ createHttpClient = async (logger) => {
9699
10314
  const undici = require("undici");
9700
10315
  const agent = new undici.Agent({
9701
10316
  keepAliveTimeout: 1e4,
@@ -9703,6 +10318,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9703
10318
  // two parallel streaming requests to the same host seem to deadlock with pipelining > 0
9704
10319
  pipelining: 0
9705
10320
  });
10321
+ logger.debug("Using node fetch with undici agent as http client");
9706
10322
  return new NodeHttpClient(agent);
9707
10323
  };
9708
10324
  }
@@ -9872,7 +10488,10 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9872
10488
  popId: workerOptions.popId,
9873
10489
  baseUrl: void 0,
9874
10490
  pipelineId: void 0,
9875
- sandboxId: void 0
10491
+ sandboxId: void 0,
10492
+ authenticationHeaders: () => {
10493
+ return { Authorization: `Bearer ${accessToken}` };
10494
+ }
9876
10495
  };
9877
10496
  session = workerSession;
9878
10497
  } else {
@@ -9971,7 +10590,7 @@ var Endpoint = class {
9971
10590
  } else {
9972
10591
  return Promise.reject("option secretKey or environment variable EYEPOP_SECRET_KEY is required");
9973
10592
  }
9974
- this._client = await createHttpClient();
10593
+ this._client = await createHttpClient(this._logger);
9975
10594
  return await this.reconnect();
9976
10595
  }
9977
10596
  async disconnect(wait = true) {
@@ -10406,6 +11025,7 @@ var WorkerEndpoint = class extends Endpoint {
10406
11025
  const job = new UploadJob(
10407
11026
  source.file.stream(),
10408
11027
  source.file.type,
11028
+ source.file.size,
10409
11029
  source.videoMode,
10410
11030
  params,
10411
11031
  async () => {
@@ -10437,6 +11057,7 @@ var WorkerEndpoint = class extends Endpoint {
10437
11057
  const job = new UploadJob(
10438
11058
  source.stream,
10439
11059
  source.mimeType,
11060
+ source.size,
10440
11061
  source.videoMode,
10441
11062
  params,
10442
11063
  async () => {
@@ -10465,10 +11086,11 @@ var WorkerEndpoint = class extends Endpoint {
10465
11086
  await this._limit.acquire();
10466
11087
  try {
10467
11088
  this.updateState();
10468
- const streamSource = await resolvePath(source);
11089
+ const streamSource = await resolvePath(source, this._logger);
10469
11090
  const job = new UploadJob(
10470
11091
  streamSource.stream,
10471
11092
  streamSource.mimeType,
11093
+ streamSource.size,
10472
11094
  source.videoMode,
10473
11095
  params,
10474
11096
  async () => {
@@ -10671,7 +11293,8 @@ var WorkerEndpoint = class extends Endpoint {
10671
11293
  if (this.options().stopJobs) {
10672
11294
  const body = { sourceType: "NONE" };
10673
11295
  const headers3 = {
10674
- Authorization: await this.authorizationHeader()
11296
+ Authorization: await this.authorizationHeader(),
11297
+ "Content-Type": "application/json"
10675
11298
  };
10676
11299
  const stop_url = `${this._baseUrl}/pipelines/${this._pipeline.id}/source?mode=preempt&processing=sync`;
10677
11300
  let response3 = await this._client.fetch(stop_url, {
@@ -11583,65 +12206,6 @@ var DataEndpoint = class extends Endpoint {
11583
12206
  }
11584
12207
  };
11585
12208
 
11586
- // worker/worker_types.ts
11587
- var VideoMode = /* @__PURE__ */ ((VideoMode2) => {
11588
- VideoMode2["STREAM"] = "stream";
11589
- VideoMode2["BUFFER"] = "buffer";
11590
- return VideoMode2;
11591
- })(VideoMode || {});
11592
- var ModelFormat = /* @__PURE__ */ ((ModelFormat2) => {
11593
- ModelFormat2["TensorFlowLite"] = "TensorFlowLite";
11594
- ModelFormat2["TensorFlowGraphDef"] = "TensorFlowGraphDef";
11595
- ModelFormat2["ONNX"] = "ONNX";
11596
- ModelFormat2["TorchScript"] = "TorchScript";
11597
- ModelFormat2["TorchScriptCpu"] = "TorchScriptCpu";
11598
- ModelFormat2["TorchScriptCuda"] = "TorchScriptCuda";
11599
- return ModelFormat2;
11600
- })(ModelFormat || {});
11601
- var ModelPrecisionType = /* @__PURE__ */ ((ModelPrecisionType2) => {
11602
- ModelPrecisionType2["float32"] = "float32";
11603
- ModelPrecisionType2["float16"] = "float16";
11604
- ModelPrecisionType2["int32"] = "int32";
11605
- ModelPrecisionType2["int8"] = "int8";
11606
- ModelPrecisionType2["uint8"] = "uint8";
11607
- return ModelPrecisionType2;
11608
- })(ModelPrecisionType || {});
11609
- var PopComponentType = /* @__PURE__ */ ((PopComponentType2) => {
11610
- PopComponentType2["FORWARD"] = "forward";
11611
- PopComponentType2["INFERENCE"] = "inference";
11612
- PopComponentType2["TRACING"] = "tracing";
11613
- PopComponentType2["CONTOUR_FINDER"] = "contour_finder";
11614
- PopComponentType2["COMPONENT_FINDER"] = "component_finder";
11615
- return PopComponentType2;
11616
- })(PopComponentType || {});
11617
- var ForwardOperatorType = /* @__PURE__ */ ((ForwardOperatorType2) => {
11618
- ForwardOperatorType2["FULL"] = "full";
11619
- ForwardOperatorType2["CROP"] = "crop";
11620
- ForwardOperatorType2["CROP_WITH_FULL_FALLBACK"] = "crop_with_full_fallback";
11621
- return ForwardOperatorType2;
11622
- })(ForwardOperatorType || {});
11623
- var InferenceType = /* @__PURE__ */ ((InferenceType2) => {
11624
- InferenceType2["IMAGE_CLASSIFICATION"] = "image_classification";
11625
- InferenceType2["OBJECT_DETECTION"] = "object_detection";
11626
- InferenceType2["KEY_POINTS"] = "key_points";
11627
- InferenceType2["OCR"] = "ocr";
11628
- InferenceType2["MESH"] = "mesh";
11629
- InferenceType2["FEATURE_VECTOR"] = "feature_vector";
11630
- InferenceType2["SEMANTIC_SEGMENTATION"] = "semantic_segmentation";
11631
- InferenceType2["SEGMENTATION"] = "segmentation";
11632
- return InferenceType2;
11633
- })(InferenceType || {});
11634
- var ContourType = /* @__PURE__ */ ((ContourType2) => {
11635
- ContourType2["ALL_PIXELS"] = "all_pixels";
11636
- ContourType2["POLYGON"] = "polygon";
11637
- ContourType2["CONVEX_HULL"] = "convex_hull";
11638
- ContourType2["HOUGH_CIRCLES"] = "hough_circles";
11639
- ContourType2["CIRCLE"] = "circle";
11640
- ContourType2["TRIANGLE"] = "triangle";
11641
- ContourType2["RECTANGLE"] = "rectangle";
11642
- return ContourType2;
11643
- })(ContourType || {});
11644
-
11645
12209
  // index.ts
11646
12210
  var readEnv = (env) => {
11647
12211
  if (typeof process !== "undefined") {
@@ -11771,6 +12335,7 @@ var index_default = EyePop;
11771
12335
  EndpointState,
11772
12336
  ExportedBy,
11773
12337
  EyePop,
12338
+ EyepopLineDecoder,
11774
12339
  ForwardOperatorType,
11775
12340
  InferenceType,
11776
12341
  LoadFromJob,