{"version":3,"file":"index-CVKYlRwh.cjs","sources":["../src/lib/webworker/runner.ts","../src/lib/pdfium/index.ts","../src/lib/pdfium/runner.ts"],"sourcesContent":["import {\n  Logger,\n  NoopLogger,\n  PdfEngine,\n  PdfEngineError,\n  PdfEngineMethodArgs,\n  PdfEngineMethodName,\n  PdfEngineMethodReturnType,\n  PdfErrorCode,\n  Task,\n  TaskReturn,\n} from '@kopjra/embedpdf-models';\n\n/**\n * Request body that represent method calls of PdfEngine, it contains the\n * method name and arguments\n */\nexport type PdfEngineMethodRequestBody = {\n  [P in PdfEngineMethodName]: {\n    name: P;\n    args: PdfEngineMethodArgs<P>;\n  };\n}[PdfEngineMethodName];\n\n/**\n * Request body that represent method calls of PdfEngine, it contains the\n * method name and arguments\n */\nexport type SpecificExecuteRequest<M extends PdfEngineMethodName> = {\n  id: string;\n  type: 'ExecuteRequest';\n  data: {\n    name: M;\n    args: PdfEngineMethodArgs<M>;\n  };\n};\n\n/**\n * Response body that represent return value of PdfEngine\n */\nexport type PdfEngineMethodResponseBody = {\n  [P in PdfEngineMethodName]: TaskReturn<PdfEngineMethodReturnType<P>>;\n}[PdfEngineMethodName];\n\n/**\n * Request that abort the specified task\n */\nexport interface AbortRequest {\n  /**\n   * message id\n   */\n  id: string;\n  /**\n   * request type\n   */\n  type: 'AbortRequest';\n}\n/**\n * Request that execute pdf engine method\n */\nexport interface ExecuteRequest {\n  /**\n   * message id\n   */\n  id: string;\n  /**\n   * request type\n   */\n  type: 'ExecuteRequest';\n  /**\n   * request body\n   */\n  data: PdfEngineMethodRequestBody;\n}\n/**\n * Response that execute pdf engine method\n */\nexport interface ExecuteResponse {\n  /**\n   * message id\n   */\n  id: string;\n  /**\n   * response type\n   */\n  type: 'ExecuteResponse';\n  /**\n   * response body\n   */\n  data: PdfEngineMethodResponseBody;\n}\n\n/**\n * Response that indicate progress of the task\n */\nexport interface ExecuteProgress<T = unknown> {\n  /**\n   * message id\n   */\n  id: string;\n  /**\n   * response type\n   */\n  type: 'ExecuteProgress';\n  /**\n   * response body\n   */\n  data: T;\n}\n\n/**\n * Response that indicate engine is ready\n */\nexport interface ReadyResponse {\n  /**\n   * message id\n   */\n  id: string;\n  /**\n   * response type\n   */\n  type: 'ReadyResponse';\n}\n\n/**\n * Request type\n */\nexport type Request = ExecuteRequest | AbortRequest;\n/**\n * Response type\n */\nexport type Response = ExecuteResponse | ReadyResponse | ExecuteProgress;\n\nconst LOG_SOURCE = 'WebWorkerEngineRunner';\nconst LOG_CATEGORY = 'Engine';\n\n/**\n * Pdf engine runner, it will execute pdf engine based on the request it received and\n * send back the response with post message\n */\nexport class EngineRunner {\n  engine: PdfEngine | undefined;\n\n  /** All running tasks, keyed by the message-id coming from the UI */\n  private tasks = new Map<string, Task<any, any>>();\n\n  /**\n   * Last time we yielded to the event loop\n   */\n  private lastYield = 0;\n  /**\n   * Ids of tasks that have been cancelled\n   */\n  private cancelledIds = new Set<string>();\n\n  /**\n   * Create instance of EngineRunnder\n   * @param logger - logger instance\n   */\n  constructor(public logger: Logger = new NoopLogger()) {}\n\n  /**\n   * Listening on post message\n   */\n  listen() {\n    self.onmessage = (evt: MessageEvent<Request>) => {\n      return this.handle(evt);\n    };\n  }\n\n  /**\n   * Handle post message\n   */\n  handle(evt: MessageEvent<Request>) {\n    this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'webworker receive message event: ', evt.data);\n    try {\n      const request = evt.data as Request;\n      switch (request.type) {\n        case 'ExecuteRequest':\n          this.execute(request);\n          break;\n        case 'AbortRequest':\n          this.abort(request);\n          break;\n      }\n    } catch (e) {\n      this.logger.info(\n        LOG_SOURCE,\n        LOG_CATEGORY,\n        'webworker met error when processing message event:',\n        e,\n      );\n    }\n  }\n\n  /**\n   * Send the ready response when pdf engine is ready\n   * @returns\n   *\n   * @protected\n   */\n  ready() {\n    this.listen();\n\n    this.respond({\n      id: '0',\n      type: 'ReadyResponse',\n    });\n    this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'runner is ready');\n  }\n\n  private abort(request: AbortRequest) {\n    const t = this.tasks.get(request.id);\n\n    // Always record the abort id\n    this.cancelledIds.add(request.id);\n\n    if (!t) {\n      // nothing to cancel (already finished or wrong id) – just ignore\n      return;\n    }\n\n    t.abort({\n      code: PdfErrorCode.Cancelled,\n      message: 'aborted by client',\n    });\n\n    // we won’t hear from that task again\n    this.tasks.delete(request.id);\n  }\n\n  private async maybeYield() {\n    const now = performance.now();\n    // give the event loop a breath roughly every ~8ms (tune as you like)\n    if (now - this.lastYield > 8) {\n      await new Promise((r) => setTimeout(r, 0));\n      this.lastYield = performance.now();\n    }\n  }\n\n  /**\n   * Execute the request\n   * @param request - request that represent the pdf engine call\n   * @returns\n   *\n   * @protected\n   */\n  execute = async (request: ExecuteRequest) => {\n    this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'runner start exeucte request');\n    if (!this.engine) {\n      const error: PdfEngineError = {\n        type: 'reject',\n        reason: {\n          code: PdfErrorCode.NotReady,\n          message: 'engine has not started yet',\n        },\n      };\n      const response: ExecuteResponse = {\n        id: request.id,\n        type: 'ExecuteResponse',\n        data: {\n          type: 'error',\n          value: error,\n        },\n      };\n      this.respond(response);\n      return;\n    }\n\n    // let AbortRequest messages land and pre-cancel flags get set\n    await this.maybeYield();\n\n    if (this.cancelledIds.has(request.id)) {\n      this.respond({\n        id: request.id,\n        type: 'ExecuteResponse',\n        data: {\n          type: 'error',\n          value: {\n            type: 'reject',\n            reason: { code: PdfErrorCode.Cancelled, message: 'aborted by client (pre-cancelled)' },\n          },\n        },\n      });\n      return;\n    }\n\n    const engine = this.engine;\n    const { name, args } = request.data;\n    if (!engine[name]) {\n      const error: PdfEngineError = {\n        type: 'reject',\n        reason: {\n          code: PdfErrorCode.NotSupport,\n          message: `engine method ${name} is not supported yet`,\n        },\n      };\n      const response: ExecuteResponse = {\n        id: request.id,\n        type: 'ExecuteResponse',\n        data: {\n          type: 'error',\n          value: error,\n        },\n      };\n      this.respond(response);\n      return;\n    }\n\n    let task: PdfEngineMethodReturnType<typeof name>;\n    switch (name) {\n      case 'isSupport':\n        task = this.engine[name]!(...args);\n        break;\n      case 'initialize':\n        task = this.engine[name]!(...args);\n        break;\n      case 'destroy':\n        task = this.engine[name]!(...args);\n        break;\n      case 'openDocumentUrl':\n        task = this.engine[name]!(...args);\n        break;\n      case 'openDocumentBuffer':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getDocPermissions':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getDocUserPermissions':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getMetadata':\n        task = this.engine[name]!(...args);\n        break;\n      case 'setMetadata':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getBookmarks':\n        task = this.engine[name]!(...args);\n        break;\n      case 'setBookmarks':\n        task = this.engine[name]!(...args);\n        break;\n      case 'deleteBookmarks':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getSignatures':\n        task = this.engine[name]!(...args);\n        break;\n      case 'renderPage':\n        task = this.engine[name]!(...args);\n        break;\n      case 'renderPageRect':\n        task = this.engine[name]!(...args);\n        break;\n      case 'renderPageAnnotation':\n        task = this.engine[name]!(...args);\n        break;\n      case 'renderThumbnail':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getAllAnnotations':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getPageAnnotations':\n        task = this.engine[name]!(...args);\n        break;\n      case 'createPageAnnotation':\n        task = this.engine[name]!(...args);\n        break;\n      case 'updatePageAnnotation':\n        task = this.engine[name]!(...args);\n        break;\n      case 'removePageAnnotation':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getPageTextRects':\n        task = this.engine[name]!(...args);\n        break;\n      case 'searchAllPages':\n        task = this.engine[name]!(...args);\n        break;\n      case 'closeDocument':\n        task = this.engine[name]!(...args);\n        break;\n      case 'closeAllDocuments':\n        task = this.engine[name]!(...args);\n        break;\n      case 'saveAsCopy':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getAttachments':\n        task = this.engine[name]!(...args);\n        break;\n      case 'addAttachment':\n        task = this.engine[name]!(...args);\n        break;\n      case 'removeAttachment':\n        task = this.engine[name]!(...args);\n        break;\n      case 'readAttachmentContent':\n        task = this.engine[name]!(...args);\n        break;\n      case 'setFormFieldValue':\n        task = this.engine[name]!(...args);\n        break;\n      case 'flattenPage':\n        task = this.engine[name]!(...args);\n        break;\n      case 'extractPages':\n        task = this.engine[name]!(...args);\n        break;\n      case 'extractText':\n        task = this.engine[name]!(...args);\n        break;\n      case 'redactTextInRects':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getTextSlices':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getPageGlyphs':\n        task = this.engine[name]!(...args);\n        break;\n      case 'getPageGeometry':\n        task = this.engine[name]!(...args);\n        break;\n      case 'merge':\n        task = this.engine[name]!(...args);\n        break;\n      case 'mergePages':\n        task = this.engine[name]!(...args);\n        break;\n      case 'preparePrintDocument':\n        task = this.engine[name]!(...args);\n        break;\n    }\n\n    this.tasks.set(request.id, task);\n\n    task.onProgress((progress) => {\n      const response: ExecuteProgress = {\n        id: request.id,\n        type: 'ExecuteProgress',\n        data: progress,\n      };\n      this.respond(response);\n    });\n\n    task.wait(\n      (result) => {\n        const response: ExecuteResponse = {\n          id: request.id,\n          type: 'ExecuteResponse',\n          data: {\n            type: 'result',\n            value: result,\n          },\n        };\n        this.respond(response);\n        this.tasks.delete(request.id);\n        this.cancelledIds.delete(request.id);\n      },\n      (error) => {\n        const response: ExecuteResponse = {\n          id: request.id,\n          type: 'ExecuteResponse',\n          data: {\n            type: 'error',\n            value: error,\n          },\n        };\n        this.respond(response);\n        this.tasks.delete(request.id);\n        this.cancelledIds.delete(request.id);\n      },\n    );\n  };\n\n  /**\n   * Send back the response\n   * @param response - response that needs sent back\n   *\n   * @protected\n   */\n  respond(response: Response) {\n    this.logger.debug(LOG_SOURCE, LOG_CATEGORY, 'runner respond: ', response);\n    self.postMessage(response);\n  }\n}\n","export * from './engine';\nexport * from './helper';\nexport * from './runner';\n\nexport const DEFAULT_PDFIUM_WASM_URL: string =\n  'https://cdn.jsdelivr.net/npm/@kopjra/embedpdf-pdfium@__PDFIUM_VERSION__/dist/pdfium.wasm';\n","import { init } from '@kopjra/embedpdf-pdfium';\nimport { EngineRunner } from '../webworker/runner';\nimport { PdfiumEngine } from './engine';\nimport { Logger } from '@kopjra/embedpdf-models';\n\n/**\n * EngineRunner for pdfium-based wasm engine\n */\nexport class PdfiumEngineRunner extends EngineRunner {\n  /**\n   * Create an instance of PdfiumEngineRunner\n   * @param wasmBinary - wasm binary that contains the pdfium wasm file\n   */\n  constructor(\n    private wasmBinary: ArrayBuffer,\n    logger?: Logger,\n  ) {\n    super(logger);\n  }\n\n  /**\n   * Initialize runner\n   */\n  async prepare() {\n    const wasmBinary = this.wasmBinary;\n    const wasmModule = await init({ wasmBinary });\n    this.engine = new PdfiumEngine(wasmModule, { logger: this.logger });\n    this.ready();\n  }\n}\n"],"names":["LOG_SOURCE","LOG_CATEGORY","EngineRunner","constructor","logger","NoopLogger","this","tasks","Map","lastYield","cancelledIds","Set","execute","async","request","debug","engine","error","type","reason","code","PdfErrorCode","NotReady","message","response","id","data","value","respond","maybeYield","has","Cancelled","name","args","NotSupport","task","set","onProgress","progress","wait","result","delete","listen","self","onmessage","evt","handle","abort","e","info","ready","t","get","add","performance","now","Promise","r","setTimeout","postMessage","wasmBinary","super","prepare","wasmModule","init","PdfiumEngine"],"mappings":"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"}