mindee 5.0.0-alpha1 → 5.0.0-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 5.0.0-rc1 - 2026-01-17
4
+ ### Changes
5
+ * :boom: drop support for node.js 18
6
+ * :boom: :recycle: separate polling options
7
+
8
+
9
+ ## 5.0.0-alpha2 - 2026-01-16
10
+ ### Changes
11
+ * :recycle: use node test methods
12
+ * :recycle: v1 ocr word should be a class
13
+ * :recycle: make v2 products top level
14
+ * :bug: fix for optional node-poppler
15
+
16
+
17
+ ## 5.0.0-alpha1 - 2026-01-13
18
+ ### :boom: :recycle: base for v5
19
+ * :arrow_up: update file-type
20
+ * :recycle: migrate to ES modules (node18)
21
+ * :coffin: remove support for obsolete/unused products:
22
+ * API builder (no longer maintained, use v2)
23
+ * :coffin: remove support for unused products available in v2:
24
+ * nutrition facts
25
+ * business card
26
+ * US healthcare cards
27
+ * bill of lading
28
+ * :coffin: remove support for unused products:
29
+ * delivery note
30
+ * payslip_fra_v2_async
31
+ * idcard_fr_v1
32
+ * ind_passport_v1_async
33
+ * us_mail_v3_async
34
+ * energy_bill_fra_v1_async
35
+ * french_healthcard_v1_async
36
+ * payslip_fra_v3_async
37
+ * :recycle: use undici for HTTP requests and mocking
38
+ * :sparkles: add ability for a user to specify their own undici `Dispatcher` instance
39
+ * :sparkles: add basic V2 CLI
40
+ * :recycle: :boom: rework of directory structure
41
+ * :recycle: :boom: rework input source errors
42
+ * :sparkles: handle abort signal stream inputs
43
+ * :sparkles: add support for all utility products
44
+ * :boom: :sparkles: move PDF and image libraries to optional dependencies
45
+
46
+
3
47
  ## v4.36.3 - 2026-01-20
4
48
  ### Fixes
5
49
  * :bug: fix streams not loading properly
package/package.json CHANGED
@@ -1,25 +1,25 @@
1
1
  {
2
2
  "name": "mindee",
3
- "version": "5.0.0-alpha1",
3
+ "version": "5.0.0-rc1",
4
4
  "description": "Mindee Client Library for Node.js",
5
5
  "main": "src/index.js",
6
- "bin": "bin/mindee.js",
6
+ "bin": {
7
+ "mindeeV1": "bin/mindeeV1.js",
8
+ "mindeeV2": "bin/mindeeV2.js"
9
+ },
7
10
  "license": "MIT",
8
11
  "type": "module",
9
12
  "scripts": {
10
13
  "build": "tsc --build && tsc-alias",
11
14
  "build-for-dist": "tsc --build && tsc-alias && cp LICENSE README.md CHANGELOG.md ./dist",
12
15
  "clean": "rm -rf ./dist ./docs/_build",
13
- "test": "mocha --grep \"#omitOptionalDeps\" --invert \"tests/**/*.spec.ts\"",
14
- "test-light": "mocha --grep \"#includeOptionalDeps\" --invert \"tests/**/*.spec.ts\"",
15
- "test-integration": "mocha --grep \"#omitOptionalDeps\" --invert \"tests/**/*.integration.ts\"",
16
- "test-integration-light": "mocha --grep \"#includeOptionalDeps\" --invert \"tests/**/*.integration.ts\"",
17
- "test-v1": "mocha --grep \"#omitOptionalDeps\" --invert \"tests/v1/**/*.spec.ts\"",
18
- "test-v1-light": "mocha --grep \"#includeOptionalDeps\" --invert \"tests/v1/**/*.spec.ts\"",
19
- "test-v2": "mocha --grep \"#omitOptionalDeps\" --invert \"tests/v2/**/*.spec.ts\"",
20
- "test-v2-light": "mocha --grep \"#includeOptionalDeps\" --invert \"tests/v2/**/*.spec.ts\"",
21
- "lint": "tsc --noEmit && eslint './src/**/*.ts' --report-unused-disable-directives && echo 'Your .ts files look good.'",
22
- "lint-fix": "eslint './src/**/*.ts' --fix",
16
+ "test": "mocha --grep '#OptionalDepsRemoved' --invert 'tests/**/*.spec.ts'",
17
+ "test-light": "mocha --grep '#OptionalDepsRequired' --invert 'tests/**/*.spec.ts'",
18
+ "test-integration": "mocha --grep '#OptionalDepsRemoved' --invert 'tests/**/*.integration.ts'",
19
+ "test-integration-light": "mocha --grep '#OptionalDepsRequired' --invert 'tests/**/*.integration.ts'",
20
+ "test-v2": "tsc --noEmit && node --import tsx --test 'tests/v2/**/*.spec.ts'",
21
+ "lint": "tsc --noEmit && eslint --report-unused-disable-directives './src/**/*.ts' './tests/**/*.ts'",
22
+ "lint-fix": "eslint --fix --report-unused-disable-directives './src/**/*.ts' './tests/**/*.ts'",
23
23
  "docs": "typedoc --out docs/_build ./src/index.ts",
24
24
  "docs-for-dist": "typedoc --out docs/_build ./src/index.ts && cp -r ./docs/code_samples ./docs/_build/"
25
25
  },
@@ -31,7 +31,7 @@
31
31
  "CHANGELOG.md"
32
32
  ],
33
33
  "engines": {
34
- "node": ">= 18.17"
34
+ "node": ">= 20.1"
35
35
  },
36
36
  "repository": {
37
37
  "type": "git",
@@ -47,33 +47,31 @@
47
47
  },
48
48
  "homepage": "https://mindee.com/",
49
49
  "devDependencies": {
50
- "@types/chai": "^5.2.3",
51
50
  "@types/mocha": "^10.0.10",
52
51
  "@types/node": "^18.19.130",
53
52
  "@types/tmp": "^0.2.6",
54
- "@typescript-eslint/eslint-plugin": "^8.52.0",
55
- "@typescript-eslint/parser": "^8.52.0",
56
- "chai": "^6.2.2",
53
+ "@typescript-eslint/eslint-plugin": "^8.55.0",
54
+ "@typescript-eslint/parser": "^8.55.0",
57
55
  "eslint": "^9.39.2",
58
- "eslint-plugin-jsdoc": "^50.6.17",
59
- "mocha": "^11.7.5",
56
+ "eslint-plugin-jsdoc": "^52.0.4",
57
+ "mocha": "^11.3.0",
60
58
  "tsc-alias": "^1.8.16",
61
59
  "tsx": "^4.21.0",
62
- "typedoc": "~0.28.15",
60
+ "typedoc": "~0.28.16",
63
61
  "typescript": "^5.9.3"
64
62
  },
65
63
  "dependencies": {
66
64
  "commander": "~9.4.1",
67
65
  "file-type": "^19.6.0",
68
- "node-poppler": "^7.2.4",
69
66
  "tmp": "^0.2.3",
70
67
  "tslib": "^2.8.1",
71
68
  "undici": "^6.23.0"
72
69
  },
73
70
  "optionalDependencies": {
74
- "sharp": "~0.34.5",
75
71
  "@cantoo/pdf-lib": "^2.3.2",
76
- "pdf.js-extract": "^0.2.1"
72
+ "node-poppler": "^7.2.4",
73
+ "pdf.js-extract": "^0.2.1",
74
+ "sharp": "~0.34.5"
77
75
  },
78
76
  "keywords": [
79
77
  "typescript",
@@ -0,0 +1,9 @@
1
+ /** A simple bounding box defined by 4 coordinates: xMin, yMin, xMax, yMax */
2
+ export declare class BBox {
3
+ xMin: number;
4
+ yMin: number;
5
+ xMax: number;
6
+ yMax: number;
7
+ constructor(xMin: number, yMin: number, xMax: number, yMax: number);
8
+ mergeBbox(bbox: BBox): BBox;
9
+ }
@@ -0,0 +1,13 @@
1
+ import { mergeBbox } from "../geometry/boundingBoxUtils.js";
2
+ /** A simple bounding box defined by 4 coordinates: xMin, yMin, xMax, yMax */
3
+ export class BBox {
4
+ constructor(xMin, yMin, xMax, yMax) {
5
+ this.xMin = xMin;
6
+ this.yMin = yMin;
7
+ this.xMax = xMax;
8
+ this.yMax = yMax;
9
+ }
10
+ mergeBbox(bbox) {
11
+ return mergeBbox(this, bbox);
12
+ }
13
+ }
@@ -1,13 +1,5 @@
1
1
  import { Point } from "./point.js";
2
2
  import { Polygon } from "./polygon.js";
3
- /** A simple bounding box defined by 4 coordinates: xMin, yMin, xMax, yMax */
4
- export declare class BBox {
5
- xMin: number;
6
- yMin: number;
7
- xMax: number;
8
- yMax: number;
9
- constructor(xMin: number, yMin: number, xMax: number, yMax: number);
10
- }
11
3
  /** A bounding box defined by 4 points. */
12
4
  export declare class BoundingBox extends Polygon {
13
5
  constructor(topLeft: Point, topRight: Point, bottomRight: Point, bottomLeft: Point);
@@ -1,13 +1,4 @@
1
1
  import { Polygon } from "./polygon.js";
2
- /** A simple bounding box defined by 4 coordinates: xMin, yMin, xMax, yMax */
3
- export class BBox {
4
- constructor(xMin, yMin, xMax, yMax) {
5
- this.xMin = xMin;
6
- this.yMin = yMin;
7
- this.xMax = xMax;
8
- this.yMax = yMax;
9
- }
10
- }
11
2
  /** A bounding box defined by 4 points. */
12
3
  export class BoundingBox extends Polygon {
13
4
  constructor(topLeft, topRight, bottomRight, bottomLeft) {
@@ -1,4 +1,5 @@
1
- import { BoundingBox, BBox } from "./boundingBox.js";
1
+ import { BoundingBox } from "./boundingBox.js";
2
+ import { BBox } from "./bbox.js";
2
3
  import { Polygon } from "./polygon.js";
3
4
  /**
4
5
  * Given a Polygon, calculate a polygon that encompasses all points.
@@ -1,4 +1,5 @@
1
- import { BoundingBox, BBox } from "./boundingBox.js";
1
+ import { BoundingBox } from "./boundingBox.js";
2
+ import { BBox } from "./bbox.js";
2
3
  /**
3
4
  * Given a Polygon, calculate a polygon that encompasses all points.
4
5
  */
@@ -1,6 +1,7 @@
1
1
  export { Polygon } from "./polygon.js";
2
2
  export { compareOnX, compareOnY, getCentroid, isPointInPolygonX, isPointInPolygonY, relativeX, relativeY, getMinMaxX, getMinMaxY, } from "./polygonUtils.js";
3
- export { BoundingBox, BBox } from "./boundingBox.js";
3
+ export { BoundingBox } from "./boundingBox.js";
4
+ export { BBox } from "./bbox.js";
4
5
  export { getBbox, getBBoxForPolygons, getBoundingBox, getBoundingBoxFromBBox, mergeBbox, } from "./boundingBoxUtils.js";
5
6
  export type { MinMax } from "./minMax.js";
6
7
  export type { Point } from "./point.js";
@@ -1,4 +1,5 @@
1
1
  export { Polygon } from "./polygon.js";
2
2
  export { compareOnX, compareOnY, getCentroid, isPointInPolygonX, isPointInPolygonY, relativeX, relativeY, getMinMaxX, getMinMaxY, } from "./polygonUtils.js";
3
- export { BoundingBox, BBox } from "./boundingBox.js";
3
+ export { BoundingBox } from "./boundingBox.js";
4
+ export { BBox } from "./bbox.js";
4
5
  export { getBbox, getBBoxForPolygons, getBoundingBox, getBoundingBoxFromBBox, mergeBbox, } from "./boundingBoxUtils.js";
@@ -1,10 +1,10 @@
1
1
  import { Buffer } from "node:buffer";
2
2
  import { MindeeError } from "../errors/index.js";
3
3
  import { writeFileSync } from "node:fs";
4
+ import { writeFile } from "fs/promises";
4
5
  import path from "node:path";
5
- import { logger } from "../logger.js";
6
6
  import { BufferInput, MIMETYPES } from "../input/index.js";
7
- import { writeFile } from "fs/promises";
7
+ import { logger } from "../logger.js";
8
8
  import { loadOptionalDependency } from "../dependency/index.js";
9
9
  /**
10
10
  * Generic class for image extraction
package/src/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  export { InputSource, Base64Input, BufferInput, BytesInput, PathInput, StreamInput, UrlInput, PageOptionsOperation, } from "./input/index.js";
2
2
  export type { PageOptions } from "./input/index.js";
3
3
  export * as image from "./image/index.js";
4
+ export * as pdf from "./pdf/index.js";
5
+ export * as geometry from "./geometry/index.js";
4
6
  export * as v1 from "./v1/index.js";
5
7
  export * as v2 from "./v2/index.js";
6
- export { Client, InferenceFile, InferenceModel, JobResponse, ErrorResponse, } from "./v2/index.js";
8
+ export * as product from "./v2/product/index.js";
9
+ export { Client, JobResponse, ErrorResponse, } from "./v2/index.js";
7
10
  export type { PollingOptions } from "./v2/index.js";
package/src/index.js CHANGED
@@ -1,7 +1,12 @@
1
+ // Core
1
2
  export { InputSource, Base64Input, BufferInput, BytesInput, PathInput, StreamInput, UrlInput, PageOptionsOperation, } from "./input/index.js";
2
3
  export * as image from "./image/index.js";
4
+ export * as pdf from "./pdf/index.js";
5
+ export * as geometry from "./geometry/index.js";
3
6
  // V1
4
7
  export * as v1 from "./v1/index.js";
5
8
  // V2
6
9
  export * as v2 from "./v2/index.js";
7
- export { Client, InferenceFile, InferenceModel, JobResponse, ErrorResponse, } from "./v2/index.js";
10
+ // Consider v2 the default
11
+ export * as product from "./v2/product/index.js";
12
+ export { Client, JobResponse, ErrorResponse, } from "./v2/index.js";
@@ -1,9 +1,9 @@
1
1
  import { logger } from "../logger.js";
2
2
  import tmp from "tmp";
3
- import { extractTextFromPdf, hasSourceText } from "./pdfUtils.js";
4
3
  import * as fs from "node:fs";
5
4
  import { compressImage } from "../image/index.js";
6
5
  import { loadOptionalDependency } from "../dependency/index.js";
6
+ import { extractTextFromPdf, hasSourceText } from "./pdfUtils.js";
7
7
  let pdfLib = null;
8
8
  async function getPdfLib() {
9
9
  if (!pdfLib) {
@@ -33,8 +33,8 @@ export async function compressPdf(pdfData, imageQuality = 85, forceSourceTextCom
33
33
  }
34
34
  }
35
35
  else {
36
- logger.warn("Found text inside of the provided PDF file. Compression operation aborted since disableSourceText "
37
- + "is set to 'true'.");
36
+ logger.warn("Found text inside of the provided PDF file. " +
37
+ "Compression operation aborted since disableSourceText is set to 'true'.");
38
38
  return pdfData;
39
39
  }
40
40
  }
@@ -4,7 +4,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _OcrPage_instances, _OcrPage_areWordsOnSameLine, _OcrPage_toLines;
7
- import { compareOnX, compareOnY, getCentroid, isPointInPolygonY, } from "../../../geometry/index.js";
7
+ import { compareOnX, compareOnY, isPointInPolygonY, } from "../../../geometry/index.js";
8
+ import { Word } from "../../../v1/parsing/standard/index.js";
8
9
  export class OcrPage {
9
10
  constructor(rawPrediction) {
10
11
  _OcrPage_instances.add(this);
@@ -15,7 +16,7 @@ export class OcrPage {
15
16
  const allWords = [];
16
17
  if (rawPrediction["all_words"]) {
17
18
  rawPrediction["all_words"].forEach((word) => {
18
- allWords.push(word);
19
+ allWords.push(new Word(word));
19
20
  });
20
21
  }
21
22
  this.allWords = allWords.sort((word1, word2) => compareOnY(word1.polygon, word2.polygon));
@@ -40,8 +41,8 @@ export class OcrPage {
40
41
  }
41
42
  }
42
43
  _OcrPage_instances = new WeakSet(), _OcrPage_areWordsOnSameLine = function _OcrPage_areWordsOnSameLine(currentWord, nextWord) {
43
- const currentInNext = isPointInPolygonY(getCentroid(currentWord.polygon), nextWord.polygon);
44
- const nextInCurrent = isPointInPolygonY(getCentroid(nextWord.polygon), currentWord.polygon);
44
+ const currentInNext = isPointInPolygonY(currentWord.polygon.getCentroid(), nextWord.polygon);
45
+ const nextInCurrent = isPointInPolygonY(nextWord.polygon.getCentroid(), currentWord.polygon);
45
46
  return nextInCurrent || currentInNext;
46
47
  }, _OcrPage_toLines = function _OcrPage_toLines() {
47
48
  const lines = [];
@@ -12,4 +12,4 @@ export { Taxes, TaxField } from "./tax.js";
12
12
  export { StringField } from "./text.js";
13
13
  export { PaymentDetailsField } from "./paymentDetails.js";
14
14
  export { PositionField } from "./position.js";
15
- export type { Word } from "./word.js";
15
+ export { Word } from "./word.js";
@@ -11,3 +11,4 @@ export { Taxes, TaxField } from "./tax.js";
11
11
  export { StringField } from "./text.js";
12
12
  export { PaymentDetailsField } from "./paymentDetails.js";
13
13
  export { PositionField } from "./position.js";
14
+ export { Word } from "./word.js";
@@ -1,10 +1,12 @@
1
- import * as geometry from "../../../geometry/index.js";
2
- export type Word = {
1
+ import { Polygon } from "../../../geometry/index.js";
2
+ import { StringDict } from "../../../parsing/index.js";
3
+ export declare class Word {
3
4
  /**
4
5
  * Contains the relative vertices coordinates (points) of a polygon containing
5
6
  * the field in the document.
6
7
  */
7
- polygon: geometry.Polygon;
8
+ polygon: Polygon;
8
9
  text: string;
9
10
  confidence: number;
10
- };
11
+ constructor(rawPrediction: StringDict);
12
+ }
@@ -1 +1,9 @@
1
- export {};
1
+ import { Polygon } from "../../../geometry/index.js";
2
+ export class Word {
3
+ constructor(rawPrediction) {
4
+ this.polygon = new Polygon(...rawPrediction["polygon"]);
5
+ this.text = rawPrediction["text"];
6
+ this.confidence = rawPrediction["confidence"];
7
+ }
8
+ }
9
+ ;
@@ -1,5 +1,3 @@
1
- import { ValidatedPollingOptions } from "../../v2/client/pollingOptions.js";
2
- import { PollingOptions } from "../../v2/index.js";
3
1
  /**
4
2
  * Constructor parameters for BaseParameters and its subclasses.
5
3
  */
@@ -7,7 +5,6 @@ export interface BaseParametersConstructor {
7
5
  modelId: string;
8
6
  alias?: string;
9
7
  webhookIds?: string[];
10
- pollingOptions?: PollingOptions;
11
8
  closeFile?: boolean;
12
9
  }
13
10
  /**
@@ -43,21 +40,12 @@ export declare abstract class BaseParameters {
43
40
  * If empty, no webhooks will be used.
44
41
  */
45
42
  webhookIds?: string[];
46
- /**
47
- * Client-side polling configuration (see {@link PollingOptions}).
48
- */
49
- pollingOptions?: PollingOptions;
50
43
  /**
51
44
  * By default, the file is closed once the upload is finished.
52
45
  * Set to `false` to keep it open.
53
46
  */
54
47
  closeFile?: boolean;
55
48
  protected constructor(params: BaseParametersConstructor);
56
- /**
57
- * Checks the values for asynchronous parsing. Returns their corrected value if they are undefined.
58
- * @returns A valid `AsyncOptions`.
59
- */
60
- getValidatedPollingOptions(): ValidatedPollingOptions;
61
49
  /**
62
50
  * Returns the form data to send to the API.
63
51
  * @returns A `FormData` object.
@@ -26,42 +26,6 @@ export class BaseParameters {
26
26
  this.alias = params.alias;
27
27
  this.webhookIds = params.webhookIds;
28
28
  this.closeFile = params.closeFile;
29
- this.pollingOptions = params.pollingOptions;
30
- }
31
- /**
32
- * Checks the values for asynchronous parsing. Returns their corrected value if they are undefined.
33
- * @returns A valid `AsyncOptions`.
34
- */
35
- getValidatedPollingOptions() {
36
- const minDelaySec = 1;
37
- const minInitialDelay = 1;
38
- const minRetries = 2;
39
- let newAsyncParams;
40
- if (this.pollingOptions === undefined) {
41
- newAsyncParams = {
42
- delaySec: 1.5,
43
- initialDelaySec: 2,
44
- maxRetries: 80
45
- };
46
- }
47
- else {
48
- newAsyncParams = { ...this.pollingOptions };
49
- if (!newAsyncParams.delaySec ||
50
- !newAsyncParams.initialDelaySec ||
51
- !newAsyncParams.maxRetries) {
52
- throw Error("Invalid polling options.");
53
- }
54
- if (newAsyncParams.delaySec < minDelaySec) {
55
- throw Error(`Cannot set auto-parsing delay to less than ${minDelaySec} second(s).`);
56
- }
57
- if (newAsyncParams.initialDelaySec < minInitialDelay) {
58
- throw Error(`Cannot set initial parsing delay to less than ${minInitialDelay} second(s).`);
59
- }
60
- if (newAsyncParams.maxRetries < minRetries) {
61
- throw Error(`Cannot set retry to less than ${minRetries}.`);
62
- }
63
- }
64
- return newAsyncParams;
65
29
  }
66
30
  /**
67
31
  * Returns the form data to send to the API.
@@ -1,2 +1,3 @@
1
- export type { PollingOptions, ValidatedPollingOptions } from "./pollingOptions.js";
1
+ export { PollingOptions } from "./pollingOptions.js";
2
+ export type { PollingOptionsConstructor } from "./pollingOptions.js";
2
3
  export { BaseParameters } from "./baseParameters.js";
@@ -1 +1,2 @@
1
+ export { PollingOptions } from "./pollingOptions.js";
1
2
  export { BaseParameters } from "./baseParameters.js";
@@ -1,3 +1,14 @@
1
+ export interface TimerOptions {
2
+ ref?: boolean;
3
+ signal?: AbortSignal;
4
+ }
5
+ export interface PollingOptionsConstructor {
6
+ initialDelaySec?: number;
7
+ delaySec?: number;
8
+ maxRetries?: number;
9
+ initialTimerOptions?: TimerOptions;
10
+ recurringTimerOptions?: TimerOptions;
11
+ }
1
12
  /**
2
13
  * Parameters for the internal polling loop in `enqueueAndGetInference()`.
3
14
  *
@@ -24,13 +35,13 @@
24
35
  *
25
36
  * const inference = await client.enqueueAndGetInference(inputDoc, params);
26
37
  */
27
- export interface PollingOptions {
38
+ export declare class PollingOptions {
28
39
  /** Number of seconds to wait *before the first poll*. */
29
- initialDelaySec?: number;
40
+ initialDelaySec: number;
30
41
  /** Interval in seconds between two consecutive polls. */
31
- delaySec?: number;
42
+ delaySec: number;
32
43
  /** Maximum number of polling attempts (including the first one). */
33
- maxRetries?: number;
44
+ maxRetries: number;
34
45
  /** Options passed to the initial `setTimeout()`. */
35
46
  initialTimerOptions?: {
36
47
  ref?: boolean;
@@ -41,9 +52,7 @@ export interface PollingOptions {
41
52
  ref?: boolean;
42
53
  signal?: AbortSignal;
43
54
  };
44
- }
45
- export interface ValidatedPollingOptions extends PollingOptions {
46
- initialDelaySec: number;
47
- delaySec: number;
48
- maxRetries: number;
55
+ constructor(params?: PollingOptionsConstructor);
56
+ validateOptions(): void;
57
+ toString(): string;
49
58
  }
@@ -1 +1,78 @@
1
- export {};
1
+ import { MindeeConfigurationError } from "../../errors/index.js";
2
+ import { logger } from "../../logger.js";
3
+ const minInitialDelay = 1;
4
+ const minDelaySec = 1;
5
+ const minRetries = 2;
6
+ /**
7
+ * Parameters for the internal polling loop in `enqueueAndGetInference()`.
8
+ *
9
+ * Default behavior:
10
+ * - `initialDelaySec` = 2s
11
+ * - `delaySec` = 1.5s
12
+ * - `maxRetries` = 80
13
+ *
14
+ * Validation rules:
15
+ * - `initialDelaySec` >= 1
16
+ * - `delaySec` >= 1
17
+ * - `maxRetries` >= 2
18
+ *
19
+ * The `initialTimerOptions` and `recurringTimerOptions` objects let you pass an
20
+ * `AbortSignal` or make the timer `unref`-ed to the `setTimeout()`.
21
+ *
22
+ * @category ClientV2
23
+ * @example
24
+ * const params = {
25
+ * initialDelaySec: 4,
26
+ * delaySec: 2,
27
+ * maxRetries: 50
28
+ * };
29
+ *
30
+ * const inference = await client.enqueueAndGetInference(inputDoc, params);
31
+ */
32
+ export class PollingOptions {
33
+ constructor(params) {
34
+ if (!params) {
35
+ params = {};
36
+ }
37
+ if (!params.initialDelaySec) {
38
+ this.initialDelaySec = 2;
39
+ }
40
+ else {
41
+ this.initialDelaySec = params.initialDelaySec;
42
+ }
43
+ if (!params.delaySec) {
44
+ this.delaySec = 1.5;
45
+ }
46
+ else {
47
+ this.delaySec = params.delaySec;
48
+ }
49
+ if (!params.maxRetries) {
50
+ this.maxRetries = 80;
51
+ }
52
+ else {
53
+ this.maxRetries = params.maxRetries;
54
+ }
55
+ if (params.initialTimerOptions) {
56
+ this.initialTimerOptions = params.initialTimerOptions;
57
+ }
58
+ if (params.recurringTimerOptions) {
59
+ this.recurringTimerOptions = params.recurringTimerOptions;
60
+ }
61
+ this.validateOptions();
62
+ logger.debug(`Polling options initialized: ${this.toString()}`);
63
+ }
64
+ validateOptions() {
65
+ if (this.delaySec < minDelaySec) {
66
+ throw new MindeeConfigurationError(`Cannot set auto-parsing delay to less than ${minDelaySec} second(s).`);
67
+ }
68
+ if (this.initialDelaySec < minInitialDelay) {
69
+ throw new MindeeConfigurationError(`Cannot set initial parsing delay to less than ${minInitialDelay} second(s).`);
70
+ }
71
+ if (this.maxRetries < minRetries) {
72
+ throw new MindeeConfigurationError(`Cannot set retry to less than ${minRetries}.`);
73
+ }
74
+ }
75
+ toString() {
76
+ return `{ initialDelaySec: ${this.initialDelaySec}, delaySec: ${this.delaySec}, maxRetries: ${this.maxRetries} }`;
77
+ }
78
+ }
@@ -2,7 +2,7 @@ import { Dispatcher } from "undici";
2
2
  import { InputSource } from "../input/index.js";
3
3
  import { JobResponse } from "./parsing/index.js";
4
4
  import { MindeeApiV2 } from "./http/mindeeApiV2.js";
5
- import { ValidatedPollingOptions } from "./client/index.js";
5
+ import { PollingOptions, PollingOptionsConstructor } from "./client/index.js";
6
6
  import { BaseProduct } from "../v2/product/baseProduct.js";
7
7
  /**
8
8
  * Options for the V2 Mindee Client.
@@ -65,15 +65,16 @@ export declare class Client {
65
65
  * @param inputSource file or URL to parse.
66
66
  * @param params parameters relating to prediction options.
67
67
  *
68
+ * @param pollingOptions options for the polling loop, see {@link PollingOptions}.
68
69
  * @typeParam T an extension of an `Inference`. Can be omitted as it will be inferred from the `productClass`.
69
70
  * @category Synchronous
70
71
  * @returns a `Promise` containing parsing results.
71
72
  */
72
- enqueueAndGetResult<P extends typeof BaseProduct>(product: P, inputSource: InputSource, params: InstanceType<P["parametersClass"]> | ConstructorParameters<P["parametersClass"]>[0]): Promise<InstanceType<P["responseClass"]>>;
73
+ enqueueAndGetResult<P extends typeof BaseProduct>(product: P, inputSource: InputSource, params: InstanceType<P["parametersClass"]> | ConstructorParameters<P["parametersClass"]>[0], pollingOptions?: PollingOptionsConstructor): Promise<InstanceType<P["responseClass"]>>;
73
74
  /**
74
75
  * Send a document to an endpoint and poll the server until the result is sent or
75
76
  * until the maximum number of tries is reached.
76
77
  * @protected
77
78
  */
78
- protected pollForResult<P extends typeof BaseProduct>(product: typeof BaseProduct, pollingOptions: ValidatedPollingOptions, queueId: string): Promise<InstanceType<P["responseClass"]>>;
79
+ protected pollForResult<P extends typeof BaseProduct>(product: typeof BaseProduct, pollingOptions: PollingOptions, queueId: string): Promise<InstanceType<P["responseClass"]>>;
79
80
  }
package/src/v2/client.js CHANGED
@@ -4,6 +4,7 @@ import { errorHandler } from "../errors/handler.js";
4
4
  import { LOG_LEVELS, logger } from "../logger.js";
5
5
  import { MindeeApiV2 } from "./http/mindeeApiV2.js";
6
6
  import { MindeeHttpErrorV2 } from "./http/errors.js";
7
+ import { PollingOptions } from "./client/index.js";
7
8
  /**
8
9
  * Mindee Client V2 class that centralizes most basic operations.
9
10
  *
@@ -76,15 +77,16 @@ export class Client {
76
77
  * @param inputSource file or URL to parse.
77
78
  * @param params parameters relating to prediction options.
78
79
  *
80
+ * @param pollingOptions options for the polling loop, see {@link PollingOptions}.
79
81
  * @typeParam T an extension of an `Inference`. Can be omitted as it will be inferred from the `productClass`.
80
82
  * @category Synchronous
81
83
  * @returns a `Promise` containing parsing results.
82
84
  */
83
- async enqueueAndGetResult(product, inputSource, params) {
85
+ async enqueueAndGetResult(product, inputSource, params, pollingOptions) {
84
86
  const paramsInstance = new product.parametersClass(params);
85
- const pollingOptions = paramsInstance.getValidatedPollingOptions();
87
+ const pollingOptionsInstance = new PollingOptions(pollingOptions);
86
88
  const jobResponse = await this.enqueue(product, inputSource, paramsInstance);
87
- return await this.pollForResult(product, pollingOptions, jobResponse.job.id);
89
+ return await this.pollForResult(product, pollingOptionsInstance, jobResponse.job.id);
88
90
  }
89
91
  /**
90
92
  * Send a document to an endpoint and poll the server until the result is sent or
@@ -114,8 +116,7 @@ export class Client {
114
116
  await setTimeout(pollingOptions.delaySec * 1000, undefined, pollingOptions.recurringTimerOptions);
115
117
  retryCounter++;
116
118
  }
117
- throw new MindeeError("Asynchronous parsing request timed out after " +
118
- pollingOptions.delaySec * retryCounter +
119
- " seconds");
119
+ throw new MindeeError(`Polling failed to retrieve a result after ${retryCounter} attempts. ` +
120
+ "You can increase poll attempts by passing the pollingOptions argument to enqueueAndGetResult()");
120
121
  }
121
122
  }
package/src/v2/index.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * as http from "./http/index.js";
2
2
  export * as parsing from "./parsing/index.js";
3
3
  export * as product from "./product/index.js";
4
- export { LocalResponse } from "./parsing/localResponse.js";
5
4
  export { Client } from "./client.js";
6
- export { InferenceFile, InferenceModel, JobResponse, ErrorResponse, } from "./parsing/index.js";
7
- export type { PollingOptions } from "./client/index.js";
5
+ export { JobResponse, ErrorResponse, LocalResponse, } from "./parsing/index.js";
6
+ export type { PollingOptions, BaseParameters } from "./client/index.js";
package/src/v2/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  export * as http from "./http/index.js";
2
2
  export * as parsing from "./parsing/index.js";
3
3
  export * as product from "./product/index.js";
4
- export { LocalResponse } from "./parsing/localResponse.js";
5
4
  export { Client } from "./client.js";
6
- export { InferenceFile, InferenceModel, JobResponse, ErrorResponse, } from "./parsing/index.js";
5
+ export { JobResponse, ErrorResponse, LocalResponse, } from "./parsing/index.js";
@@ -1,5 +1,5 @@
1
1
  import { InferenceModel } from "./inferenceModel.js";
2
- import { InferenceFile } from "../../../v2/index.js";
2
+ import { InferenceFile } from "./inferenceFile.js";
3
3
  import { StringDict } from "../../../parsing/index.js";
4
4
  export declare abstract class BaseInference {
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import { InferenceModel } from "./inferenceModel.js";
2
- import { InferenceFile } from "../../../v2/index.js";
2
+ import { InferenceFile } from "./inferenceFile.js";
3
3
  export class BaseInference {
4
4
  constructor(serverResponse) {
5
5
  this.id = serverResponse["id"];