@eyepop.ai/eyepop 1.13.2 → 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,
@@ -8991,7 +8992,7 @@ var AbstractJob = class {
8991
8992
  reject(`upload error ${response.status}: ${await response.text()}`);
8992
8993
  break;
8993
8994
  } else if (!response.body) {
8994
- reject(`response body is empty`);
8995
+ reject("response body is empty");
8995
8996
  break;
8996
8997
  } else {
8997
8998
  resolve(response.body);
@@ -9025,10 +9026,11 @@ var UploadJob = class extends AbstractJob {
9025
9026
  get [Symbol.toStringTag]() {
9026
9027
  return "uploadJob";
9027
9028
  }
9028
- constructor(stream, mimeType, videoMode, params, getSession, client, requestLogger) {
9029
+ constructor(stream, mimeType, size, videoMode, params, getSession, client, requestLogger) {
9029
9030
  super(params, getSession, client, requestLogger);
9030
9031
  this._uploadStream = stream;
9031
9032
  this._mimeType = mimeType;
9033
+ this._size = size;
9032
9034
  this._videoMode = videoMode;
9033
9035
  this._needsFullDuplex = !client.isFullDuplex() && mimeType.startsWith("video/") && videoMode == "stream" /* STREAM */;
9034
9036
  }
@@ -9045,7 +9047,7 @@ var UploadJob = class extends AbstractJob {
9045
9047
  const videoModeQuery = this._videoMode ? `&videoMode=${this._videoMode}` : "";
9046
9048
  const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=async&sourceId=${event.source_id}${videoModeQuery}`;
9047
9049
  if (this._params) {
9048
- 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`);
9049
9051
  const params = JSON.stringify(this._params);
9050
9052
  const paramBlob = new Blob([params], { type: "application/json" });
9051
9053
  const formData = new FormData();
@@ -9065,12 +9067,15 @@ var UploadJob = class extends AbstractJob {
9065
9067
  duplex: "half"
9066
9068
  });
9067
9069
  } else {
9068
- this._requestLogger.debug("before POST %s with stream as body", postUrl);
9070
+ this._requestLogger.debug(`before POST ${postUrl} with stream as body`);
9069
9071
  const headers = {
9070
9072
  ...session.authenticationHeaders(),
9071
9073
  Accept: "application/jsonl",
9072
9074
  "Content-Type": this._mimeType
9073
9075
  };
9076
+ if (this._size) {
9077
+ headers["Content-Length"] = `${this._size}`;
9078
+ }
9074
9079
  request = this._client.fetch(postUrl, {
9075
9080
  headers,
9076
9081
  method: "POST",
@@ -9082,12 +9087,12 @@ var UploadJob = class extends AbstractJob {
9082
9087
  }
9083
9088
  request.then(async (value) => {
9084
9089
  if (value.status != 204) {
9085
- 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}`);
9086
9091
  }
9087
9092
  }).catch((reason) => {
9088
- this._requestLogger.debug("error %v for POST %s ", reason, postUrl);
9093
+ this._requestLogger.debug(`error ${reason} for POST ${postUrl}`);
9089
9094
  }).finally(() => {
9090
- this._requestLogger.debug("after POST %s ", postUrl);
9095
+ this._requestLogger.debug(`after POST ${postUrl}`);
9091
9096
  });
9092
9097
  }
9093
9098
  return Promise.resolve();
@@ -9095,7 +9100,7 @@ var UploadJob = class extends AbstractJob {
9095
9100
  async startJob() {
9096
9101
  const session = await this._getSession();
9097
9102
  if (!session.baseUrl) {
9098
- return Promise.reject("session.baseUrl must not ne null");
9103
+ return Promise.reject("session.baseUrl must not be null");
9099
9104
  }
9100
9105
  let response;
9101
9106
  if (this._needsFullDuplex) {
@@ -9104,7 +9109,7 @@ var UploadJob = class extends AbstractJob {
9104
9109
  ...session.authenticationHeaders(),
9105
9110
  Accept: "application/jsonl"
9106
9111
  };
9107
- this._requestLogger.debug("before POST {} to prepare full duplex upload", prepareUrl);
9112
+ this._requestLogger.debug(`before POST ${prepareUrl} to prepare full duplex upload`);
9108
9113
  response = await this._client.fetch(prepareUrl, {
9109
9114
  headers,
9110
9115
  method: "POST",
@@ -9112,12 +9117,12 @@ var UploadJob = class extends AbstractJob {
9112
9117
  // @ts-ignore
9113
9118
  duplex: "half"
9114
9119
  });
9115
- 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}`);
9116
9121
  } else {
9117
9122
  const videoModeQuery = this._videoMode ? `&videoMode=${this._videoMode}` : "";
9118
9123
  const postUrl = `${session.baseUrl.replace(/\/+$/, "")}/pipelines/${session.pipelineId}/source?mode=queue&processing=sync${videoModeQuery}`;
9119
9124
  if (this._params) {
9120
- 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`);
9121
9126
  const params = JSON.stringify(this._params);
9122
9127
  const paramBlob = new Blob([params], { type: "application/json" });
9123
9128
  const formData = new FormData();
@@ -9136,14 +9141,17 @@ var UploadJob = class extends AbstractJob {
9136
9141
  // @ts-ignore
9137
9142
  duplex: "half"
9138
9143
  });
9139
- 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)`);
9140
9145
  } else {
9141
- this._requestLogger.debug("before POST %s with stream as body", postUrl);
9146
+ this._requestLogger.debug(`before POST ${postUrl} with stream as body`);
9142
9147
  const headers = {
9143
9148
  ...session.authenticationHeaders(),
9144
9149
  Accept: "application/jsonl",
9145
9150
  "Content-Type": this._mimeType
9146
9151
  };
9152
+ if (this._size) {
9153
+ headers["Content-Length"] = `${this._size}`;
9154
+ }
9147
9155
  response = await this._client.fetch(postUrl, {
9148
9156
  headers,
9149
9157
  method: "POST",
@@ -9152,7 +9160,7 @@ var UploadJob = class extends AbstractJob {
9152
9160
  // @ts-ignore
9153
9161
  duplex: "half"
9154
9162
  });
9155
- this._requestLogger.debug("after POST %s with stream as body", postUrl);
9163
+ this._requestLogger.debug(`after POST ${postUrl} with stream as body`);
9156
9164
  }
9157
9165
  }
9158
9166
  return response;
@@ -9654,17 +9662,85 @@ var WebrtcWhep = class extends WebrtcBase {
9654
9662
  // shims/local_file.ts
9655
9663
  var resolvePath;
9656
9664
  if ("document" in globalThis && "implementation" in globalThis.document) {
9657
- resolvePath = async (source) => {
9665
+ resolvePath = async (source, logger) => {
9658
9666
  throw new DOMException("resolving a path to a file is not supported in browser");
9659
9667
  };
9660
9668
  } else if (typeof navigator !== "undefined" && navigator.product === "ReactNative") {
9661
- resolvePath = async (source) => {
9662
- const response = await fetch(`file://${source.path}`);
9663
- const blob = await response.blob();
9664
- return {
9665
- stream: blob,
9666
- mimeType: source.mimeType || "image/*"
9667
- };
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.`);
9668
9744
  };
9669
9745
  } else {
9670
9746
  let iteratorToStream = function(iterator) {
@@ -9685,7 +9761,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9685
9761
  yield chunk;
9686
9762
  }
9687
9763
  }
9688
- resolvePath = async (source) => {
9764
+ resolvePath = async (source, logger) => {
9689
9765
  const mime = require_mime_types();
9690
9766
  const filehandle = require("fs/promises");
9691
9767
  const fd = await filehandle.open(source.path, "r");
@@ -9701,6 +9777,403 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9701
9777
  }
9702
9778
  var iteratorToStream2;
9703
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
+
9704
10177
  // shims/http_client.ts
9705
10178
  var createHttpClient;
9706
10179
  if ("document" in globalThis && "implementation" in globalThis.document) {
@@ -9716,15 +10189,97 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9716
10189
  return false;
9717
10190
  }
9718
10191
  }
9719
- createHttpClient = async () => {
10192
+ createHttpClient = async (logger) => {
10193
+ logger.debug("Using browser fetch as http client");
9720
10194
  return new BrowserHttpClient();
9721
10195
  };
9722
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
+ }
9723
10214
  class ReactNativeHttpClient {
9724
- constructor() {
10215
+ constructor(logger) {
10216
+ this.logger = logger;
9725
10217
  }
9726
10218
  async fetch(input, init) {
9727
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
+ }
9728
10283
  init.reactNative = { textStreaming: true };
9729
10284
  return await fetch(input, init);
9730
10285
  }
@@ -9734,8 +10289,9 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9734
10289
  return true;
9735
10290
  }
9736
10291
  }
9737
- createHttpClient = async () => {
9738
- 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);
9739
10295
  };
9740
10296
  } else {
9741
10297
  class NodeHttpClient {
@@ -9754,7 +10310,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9754
10310
  return false;
9755
10311
  }
9756
10312
  }
9757
- createHttpClient = async () => {
10313
+ createHttpClient = async (logger) => {
9758
10314
  const undici = require("undici");
9759
10315
  const agent = new undici.Agent({
9760
10316
  keepAliveTimeout: 1e4,
@@ -9762,6 +10318,7 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9762
10318
  // two parallel streaming requests to the same host seem to deadlock with pipelining > 0
9763
10319
  pipelining: 0
9764
10320
  });
10321
+ logger.debug("Using node fetch with undici agent as http client");
9765
10322
  return new NodeHttpClient(agent);
9766
10323
  };
9767
10324
  }
@@ -9931,7 +10488,10 @@ if ("document" in globalThis && "implementation" in globalThis.document) {
9931
10488
  popId: workerOptions.popId,
9932
10489
  baseUrl: void 0,
9933
10490
  pipelineId: void 0,
9934
- sandboxId: void 0
10491
+ sandboxId: void 0,
10492
+ authenticationHeaders: () => {
10493
+ return { Authorization: `Bearer ${accessToken}` };
10494
+ }
9935
10495
  };
9936
10496
  session = workerSession;
9937
10497
  } else {
@@ -10030,7 +10590,7 @@ var Endpoint = class {
10030
10590
  } else {
10031
10591
  return Promise.reject("option secretKey or environment variable EYEPOP_SECRET_KEY is required");
10032
10592
  }
10033
- this._client = await createHttpClient();
10593
+ this._client = await createHttpClient(this._logger);
10034
10594
  return await this.reconnect();
10035
10595
  }
10036
10596
  async disconnect(wait = true) {
@@ -10465,6 +11025,7 @@ var WorkerEndpoint = class extends Endpoint {
10465
11025
  const job = new UploadJob(
10466
11026
  source.file.stream(),
10467
11027
  source.file.type,
11028
+ source.file.size,
10468
11029
  source.videoMode,
10469
11030
  params,
10470
11031
  async () => {
@@ -10496,6 +11057,7 @@ var WorkerEndpoint = class extends Endpoint {
10496
11057
  const job = new UploadJob(
10497
11058
  source.stream,
10498
11059
  source.mimeType,
11060
+ source.size,
10499
11061
  source.videoMode,
10500
11062
  params,
10501
11063
  async () => {
@@ -10524,10 +11086,11 @@ var WorkerEndpoint = class extends Endpoint {
10524
11086
  await this._limit.acquire();
10525
11087
  try {
10526
11088
  this.updateState();
10527
- const streamSource = await resolvePath(source);
11089
+ const streamSource = await resolvePath(source, this._logger);
10528
11090
  const job = new UploadJob(
10529
11091
  streamSource.stream,
10530
11092
  streamSource.mimeType,
11093
+ streamSource.size,
10531
11094
  source.videoMode,
10532
11095
  params,
10533
11096
  async () => {
@@ -10730,7 +11293,8 @@ var WorkerEndpoint = class extends Endpoint {
10730
11293
  if (this.options().stopJobs) {
10731
11294
  const body = { sourceType: "NONE" };
10732
11295
  const headers3 = {
10733
- Authorization: await this.authorizationHeader()
11296
+ Authorization: await this.authorizationHeader(),
11297
+ "Content-Type": "application/json"
10734
11298
  };
10735
11299
  const stop_url = `${this._baseUrl}/pipelines/${this._pipeline.id}/source?mode=preempt&processing=sync`;
10736
11300
  let response3 = await this._client.fetch(stop_url, {
@@ -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,