@dvvebond/core 0.2.12
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/LICENSE.md +21 -0
- package/README.md +214 -0
- package/dist/chunk-15K8U1wQ.mjs +18 -0
- package/dist/index.d.mts +22131 -0
- package/dist/index.mjs +61480 -0
- package/dist/index.mjs.map +1 -0
- package/dist/parsing-worker-host-COnJliNW.mjs +3 -0
- package/dist/parsing-worker-host-CcJO1eh7.mjs +550 -0
- package/dist/parsing-worker-host-CcJO1eh7.mjs.map +1 -0
- package/package.json +127 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsing-worker-host-CcJO1eh7.mjs","names":["transferables: ArrayBuffer[]","resolve!: (value: T) => void","reject!: (reason: unknown) => void","pending","pending: PendingRequest<T>","error: ParsingWorkerError"],"sources":["../src/worker/messages.ts","../src/worker/parsing-types.ts","../src/worker/parsing-utils.ts","../src/worker/parsing-worker-host.ts"],"sourcesContent":["/**\n * Web Worker message protocol definitions.\n *\n * Defines the message types and data structures used for communication\n * between the main thread and PDF worker threads.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Message IDs and Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Unique message identifier for request/response correlation.\n */\nexport type MessageId = string;\n\n/**\n * Task identifier for tracking ongoing operations.\n */\nexport type TaskId = string;\n\n/**\n * Generate a unique message ID.\n */\nexport function generateMessageId(): MessageId {\n return `msg-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Generate a unique task ID.\n */\nexport function generateTaskId(): TaskId {\n return `task-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Request Message Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Request types that can be sent to the worker.\n */\nexport type WorkerRequestType =\n | \"init\"\n | \"load\"\n | \"save\"\n | \"parse\"\n | \"extractText\"\n | \"findText\"\n | \"cancel\"\n | \"terminate\";\n\n/**\n * Base request message structure.\n */\nexport interface BaseRequest<T extends WorkerRequestType, D = unknown> {\n readonly type: \"request\";\n readonly id: MessageId;\n readonly requestType: T;\n readonly data: D;\n}\n\n/**\n * Initialize the worker with configuration.\n */\nexport interface InitRequest extends BaseRequest<\"init\", InitRequestData> {\n readonly requestType: \"init\";\n}\n\nexport interface InitRequestData {\n /** Worker configuration options */\n readonly verbose?: boolean;\n /** Optional worker name for debugging */\n readonly name?: string;\n}\n\n/**\n * Load a PDF document.\n */\nexport interface LoadRequest extends BaseRequest<\"load\", LoadRequestData> {\n readonly requestType: \"load\";\n}\n\nexport interface LoadRequestData {\n /** PDF bytes to load (transferred, not copied) */\n readonly bytes: Uint8Array;\n /** Optional password for encrypted PDFs */\n readonly password?: string;\n /** Document identifier for tracking */\n readonly documentId: string;\n}\n\n/**\n * Save a PDF document.\n */\nexport interface SaveRequest extends BaseRequest<\"save\", SaveRequestData> {\n readonly requestType: \"save\";\n}\n\nexport interface SaveRequestData {\n /** Document identifier */\n readonly documentId: string;\n /** Whether to use incremental save */\n readonly incremental?: boolean;\n /** Encryption options */\n readonly encrypt?: {\n readonly userPassword?: string;\n readonly ownerPassword?: string;\n readonly permissions?: number;\n };\n}\n\n/**\n * Parse PDF structure (xref, objects, etc.).\n */\nexport interface ParseRequest extends BaseRequest<\"parse\", ParseRequestData> {\n readonly requestType: \"parse\";\n}\n\nexport interface ParseRequestData {\n /** PDF bytes to parse */\n readonly bytes: Uint8Array;\n /** Parse options */\n readonly options?: {\n /** Whether to perform brute-force recovery if normal parsing fails */\n readonly bruteForceRecovery?: boolean;\n };\n}\n\n/**\n * Extract text from pages.\n */\nexport interface ExtractTextRequest extends BaseRequest<\"extractText\", ExtractTextRequestData> {\n readonly requestType: \"extractText\";\n}\n\nexport interface ExtractTextRequestData {\n /** Document identifier */\n readonly documentId: string;\n /** Page indices to extract (0-based), undefined means all pages */\n readonly pageIndices?: readonly number[];\n}\n\n/**\n * Find text in document.\n */\nexport interface FindTextRequest extends BaseRequest<\"findText\", FindTextRequestData> {\n readonly requestType: \"findText\";\n}\n\nexport interface FindTextRequestData {\n /** Document identifier */\n readonly documentId: string;\n /** Text or regex pattern to find */\n readonly pattern: string;\n /** Whether pattern is a regex */\n readonly isRegex?: boolean;\n /** Case-sensitive search */\n readonly caseSensitive?: boolean;\n /** Page indices to search (0-based), undefined means all pages */\n readonly pageIndices?: readonly number[];\n}\n\n/**\n * Cancel an ongoing operation.\n */\nexport interface CancelRequest extends BaseRequest<\"cancel\", CancelRequestData> {\n readonly requestType: \"cancel\";\n}\n\nexport interface CancelRequestData {\n /** Task ID to cancel */\n readonly taskId: TaskId;\n}\n\n/**\n * Terminate the worker.\n */\nexport interface TerminateRequest extends BaseRequest<\"terminate\", undefined> {\n readonly requestType: \"terminate\";\n readonly data: undefined;\n}\n\n/**\n * Union of all request types.\n */\nexport type WorkerRequest =\n | InitRequest\n | LoadRequest\n | SaveRequest\n | ParseRequest\n | ExtractTextRequest\n | FindTextRequest\n | CancelRequest\n | TerminateRequest;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Response Message Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Response status indicating success or failure.\n */\nexport type ResponseStatus = \"success\" | \"error\" | \"cancelled\";\n\n/**\n * Base response message structure.\n */\nexport interface BaseResponse<T extends WorkerRequestType, D = unknown> {\n readonly type: \"response\";\n readonly id: MessageId;\n readonly requestType: T;\n readonly status: ResponseStatus;\n readonly data?: D;\n readonly error?: WorkerError;\n}\n\n/**\n * Error information from the worker.\n */\nexport interface WorkerError {\n readonly code: string;\n readonly message: string;\n readonly stack?: string;\n readonly details?: Record<string, unknown>;\n}\n\n/**\n * Init response.\n */\nexport interface InitResponse extends BaseResponse<\"init\", InitResponseData> {\n readonly requestType: \"init\";\n}\n\nexport interface InitResponseData {\n /** Worker is ready */\n readonly ready: boolean;\n /** Worker version/capabilities */\n readonly version: string;\n}\n\n/**\n * Load response.\n */\nexport interface LoadResponse extends BaseResponse<\"load\", LoadResponseData> {\n readonly requestType: \"load\";\n}\n\nexport interface LoadResponseData {\n /** Document identifier */\n readonly documentId: string;\n /** Number of pages */\n readonly pageCount: number;\n /** Document metadata */\n readonly metadata?: {\n readonly title?: string;\n readonly author?: string;\n readonly subject?: string;\n readonly keywords?: string;\n readonly creator?: string;\n readonly producer?: string;\n readonly creationDate?: string;\n readonly modificationDate?: string;\n };\n /** Whether document is encrypted */\n readonly isEncrypted: boolean;\n /** Whether document has forms */\n readonly hasForms: boolean;\n /** Whether document has signatures */\n readonly hasSignatures: boolean;\n}\n\n/**\n * Save response.\n */\nexport interface SaveResponse extends BaseResponse<\"save\", SaveResponseData> {\n readonly requestType: \"save\";\n}\n\nexport interface SaveResponseData {\n /** Saved PDF bytes (transferred, not copied) */\n readonly bytes: Uint8Array;\n /** Size in bytes */\n readonly size: number;\n}\n\n/**\n * Parse response.\n */\nexport interface ParseResponse extends BaseResponse<\"parse\", ParseResponseData> {\n readonly requestType: \"parse\";\n}\n\nexport interface ParseResponseData {\n /** PDF version string */\n readonly version: string;\n /** Number of objects */\n readonly objectCount: number;\n /** Whether brute-force recovery was used */\n readonly usedBruteForce: boolean;\n}\n\n/**\n * Extract text response.\n */\nexport interface ExtractTextResponse extends BaseResponse<\"extractText\", ExtractTextResponseData> {\n readonly requestType: \"extractText\";\n}\n\nexport interface ExtractTextResponseData {\n /** Extracted text per page */\n readonly pages: readonly PageText[];\n}\n\nexport interface PageText {\n /** Page index (0-based) */\n readonly pageIndex: number;\n /** Extracted text content */\n readonly text: string;\n}\n\n/**\n * Find text response.\n */\nexport interface FindTextResponse extends BaseResponse<\"findText\", FindTextResponseData> {\n readonly requestType: \"findText\";\n}\n\nexport interface FindTextResponseData {\n /** Search results */\n readonly matches: readonly TextMatch[];\n /** Total match count */\n readonly totalCount: number;\n}\n\nexport interface TextMatch {\n /** Page index (0-based) */\n readonly pageIndex: number;\n /** Matched text */\n readonly text: string;\n /** Character offset in page text */\n readonly offset: number;\n /** Bounding box [x, y, width, height] in PDF coordinates */\n readonly bounds?: readonly [number, number, number, number];\n}\n\n/**\n * Cancel response.\n */\nexport interface CancelResponse extends BaseResponse<\"cancel\", CancelResponseData> {\n readonly requestType: \"cancel\";\n}\n\nexport interface CancelResponseData {\n /** Task ID that was cancelled */\n readonly taskId: TaskId;\n /** Whether the task was successfully cancelled */\n readonly wasCancelled: boolean;\n}\n\n/**\n * Terminate response.\n */\nexport interface TerminateResponse extends BaseResponse<\"terminate\", undefined> {\n readonly requestType: \"terminate\";\n}\n\n/**\n * Union of all response types.\n */\nexport type WorkerResponse =\n | InitResponse\n | LoadResponse\n | SaveResponse\n | ParseResponse\n | ExtractTextResponse\n | FindTextResponse\n | CancelResponse\n | TerminateResponse;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Progress Message Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Progress update from the worker.\n */\nexport interface ProgressMessage {\n readonly type: \"progress\";\n readonly taskId: TaskId;\n readonly requestType: WorkerRequestType;\n /** Progress percentage (0-100) */\n readonly percent: number;\n /** Current operation description */\n readonly operation?: string;\n /** Items processed / total items */\n readonly processed?: number;\n readonly total?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Union Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Any message from the main thread to the worker.\n */\nexport type MainToWorkerMessage = WorkerRequest;\n\n/**\n * Any message from the worker to the main thread.\n */\nexport type WorkerToMainMessage = WorkerResponse | ProgressMessage;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Type Guards\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Check if a message is a request.\n */\nexport function isRequest(message: unknown): message is WorkerRequest {\n return (\n typeof message === \"object\" &&\n message !== null &&\n \"type\" in message &&\n (message as { type: unknown }).type === \"request\"\n );\n}\n\n/**\n * Check if a message is a response.\n */\nexport function isResponse(message: unknown): message is WorkerResponse {\n return (\n typeof message === \"object\" &&\n message !== null &&\n \"type\" in message &&\n (message as { type: unknown }).type === \"response\"\n );\n}\n\n/**\n * Check if a message is a progress update.\n */\nexport function isProgress(message: unknown): message is ProgressMessage {\n return (\n typeof message === \"object\" &&\n message !== null &&\n \"type\" in message &&\n (message as { type: unknown }).type === \"progress\"\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Message Factories\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a request message.\n */\nexport function createRequest<T extends WorkerRequestType>(\n requestType: T,\n data: Extract<WorkerRequest, { requestType: T }>[\"data\"],\n): Extract<WorkerRequest, { requestType: T }> {\n return {\n type: \"request\",\n id: generateMessageId(),\n requestType,\n data,\n } as Extract<WorkerRequest, { requestType: T }>;\n}\n\n/**\n * Create a success response.\n */\nexport function createSuccessResponse<T extends WorkerRequestType>(\n id: MessageId,\n requestType: T,\n data: Extract<WorkerResponse, { requestType: T }>[\"data\"],\n): Extract<WorkerResponse, { requestType: T }> {\n return {\n type: \"response\",\n id,\n requestType,\n status: \"success\",\n data,\n } as Extract<WorkerResponse, { requestType: T }>;\n}\n\n/**\n * Create an error response.\n */\nexport function createErrorResponse<T extends WorkerRequestType>(\n id: MessageId,\n requestType: T,\n error: WorkerError,\n): Extract<WorkerResponse, { requestType: T }> {\n return {\n type: \"response\",\n id,\n requestType,\n status: \"error\",\n error,\n } as Extract<WorkerResponse, { requestType: T }>;\n}\n\n/**\n * Create a cancelled response.\n */\nexport function createCancelledResponse<T extends WorkerRequestType>(\n id: MessageId,\n requestType: T,\n): Extract<WorkerResponse, { requestType: T }> {\n return {\n type: \"response\",\n id,\n requestType,\n status: \"cancelled\",\n } as Extract<WorkerResponse, { requestType: T }>;\n}\n\n/**\n * Create a progress message.\n */\nexport function createProgress(\n taskId: TaskId,\n requestType: WorkerRequestType,\n percent: number,\n options?: {\n operation?: string;\n processed?: number;\n total?: number;\n },\n): ProgressMessage {\n return {\n type: \"progress\",\n taskId,\n requestType,\n percent,\n ...options,\n };\n}\n\n/**\n * Create a WorkerError from an Error.\n */\nexport function createWorkerError(error: Error, code?: string): WorkerError {\n return {\n code: code ?? error.name,\n message: error.message,\n stack: error.stack,\n };\n}\n","/**\n * TypeScript interfaces for parsing worker message protocols.\n *\n * These types define the contract between the main thread and the parsing worker,\n * supporting progress reporting with 500ms throttling and cancellation.\n */\n\nimport type { MessageId, TaskId, WorkerRequestType } from \"./messages\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Parsing Operation Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Types of parsing operations supported by the worker.\n */\nexport type ParsingOperationType =\n | \"parseDocument\"\n | \"parseXRef\"\n | \"parseObjects\"\n | \"extractText\"\n | \"validateStructure\";\n\n/**\n * Phase of parsing for progress reporting.\n */\nexport type ParsingPhase =\n | \"initializing\"\n | \"header\"\n | \"xref\"\n | \"trailer\"\n | \"objects\"\n | \"encryption\"\n | \"catalog\"\n | \"pages\"\n | \"text\"\n | \"complete\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Progress Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Progress event data for parsing operations.\n */\nexport interface ParsingProgress {\n /** Current parsing phase */\n readonly phase: ParsingPhase;\n\n /** Progress percentage (0-100) */\n readonly percent: number;\n\n /** Human-readable description of current operation */\n readonly operation: string;\n\n /** Number of items processed (e.g., objects parsed) */\n readonly processed?: number;\n\n /** Total number of items to process */\n readonly total?: number;\n\n /** Estimated time remaining in milliseconds */\n readonly estimatedRemaining?: number;\n\n /** Bytes processed so far */\n readonly bytesProcessed?: number;\n\n /** Total bytes to process */\n readonly totalBytes?: number;\n}\n\n/**\n * Progress callback function signature.\n */\nexport type ParsingProgressCallback = (progress: ParsingProgress) => void;\n\n/**\n * Progress message from worker to main thread.\n */\nexport interface ParsingProgressMessage {\n readonly type: \"parsingProgress\";\n readonly taskId: TaskId;\n readonly progress: ParsingProgress;\n readonly timestamp: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Request Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Options for document parsing in the worker.\n */\nexport interface WorkerParseOptions {\n /** Enable lenient parsing for malformed PDFs (default: true) */\n readonly lenient?: boolean;\n\n /** Password for encrypted documents */\n readonly password?: string;\n\n /** Enable brute-force recovery if normal parsing fails */\n readonly bruteForceRecovery?: boolean;\n\n /** Progress reporting interval in milliseconds (default: 500) */\n readonly progressInterval?: number;\n}\n\n/**\n * Request to parse a PDF document.\n */\nexport interface ParseDocumentRequest {\n readonly type: \"request\";\n readonly id: MessageId;\n readonly requestType: \"parseDocument\";\n readonly data: ParseDocumentRequestData;\n}\n\nexport interface ParseDocumentRequestData {\n /** PDF bytes to parse (transferred, not copied) */\n readonly bytes: Uint8Array;\n\n /** Unique task identifier for progress/cancellation */\n readonly taskId: TaskId;\n\n /** Parse options */\n readonly options?: WorkerParseOptions;\n}\n\n/**\n * Request to extract text from a parsed document.\n */\nexport interface ExtractTextRequest {\n readonly type: \"request\";\n readonly id: MessageId;\n readonly requestType: \"extractText\";\n readonly data: ExtractTextRequestData;\n}\n\nexport interface ExtractTextRequestData {\n /** Document ID (from previous parse) */\n readonly documentId: string;\n\n /** Task identifier */\n readonly taskId: TaskId;\n\n /** Page indices to extract (0-based), undefined means all pages */\n readonly pageIndices?: readonly number[];\n\n /** Include position information for each text item */\n readonly includePositions?: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Response Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Parsed document metadata.\n */\nexport interface ParsedDocumentInfo {\n /** PDF version from header (e.g., \"1.7\", \"2.0\") */\n readonly version: string;\n\n /** Number of pages in the document */\n readonly pageCount: number;\n\n /** Whether document is encrypted */\n readonly isEncrypted: boolean;\n\n /** Whether authentication succeeded (for encrypted docs) */\n readonly isAuthenticated: boolean;\n\n /** Whether document was recovered via brute-force parsing */\n readonly recoveredViaBruteForce: boolean;\n\n /** Document metadata from Info dictionary */\n readonly metadata: DocumentMetadata;\n\n /** Parsing warnings */\n readonly warnings: readonly string[];\n\n /** Total number of objects in the document */\n readonly objectCount: number;\n\n /** Whether document has forms */\n readonly hasForms: boolean;\n\n /** Whether document has signatures */\n readonly hasSignatures: boolean;\n\n /** Whether document has layers (Optional Content Groups) */\n readonly hasLayers: boolean;\n}\n\n/**\n * Document metadata from Info dictionary.\n */\nexport interface DocumentMetadata {\n readonly title?: string;\n readonly author?: string;\n readonly subject?: string;\n readonly keywords?: string;\n readonly creator?: string;\n readonly producer?: string;\n readonly creationDate?: string;\n readonly modificationDate?: string;\n}\n\n/**\n * Response from parseDocument request.\n */\nexport interface ParseDocumentResponse {\n readonly type: \"response\";\n readonly id: MessageId;\n readonly requestType: \"parseDocument\";\n readonly status: \"success\" | \"error\" | \"cancelled\";\n readonly data?: ParseDocumentResponseData;\n readonly error?: ParsingWorkerError;\n}\n\nexport interface ParseDocumentResponseData {\n /** Unique document identifier for subsequent operations */\n readonly documentId: string;\n\n /** Parsed document information */\n readonly info: ParsedDocumentInfo;\n\n /** Total parsing time in milliseconds */\n readonly parsingTime: number;\n}\n\n/**\n * Extracted text from a page.\n */\nexport interface ExtractedPageText {\n /** Page index (0-based) */\n readonly pageIndex: number;\n\n /** Extracted text content */\n readonly text: string;\n\n /** Text items with positions (if requested) */\n readonly items?: readonly TextItem[];\n}\n\n/**\n * Individual text item with position.\n */\nexport interface TextItem {\n /** Text content */\n readonly text: string;\n\n /** X position in PDF coordinates */\n readonly x: number;\n\n /** Y position in PDF coordinates */\n readonly y: number;\n\n /** Width of the text item */\n readonly width: number;\n\n /** Height of the text item */\n readonly height: number;\n\n /** Font size */\n readonly fontSize: number;\n\n /** Font name (if available) */\n readonly fontName?: string;\n}\n\n/**\n * Response from extractText request.\n */\nexport interface ExtractTextResponse {\n readonly type: \"response\";\n readonly id: MessageId;\n readonly requestType: \"extractText\";\n readonly status: \"success\" | \"error\" | \"cancelled\";\n readonly data?: ExtractTextResponseData;\n readonly error?: ParsingWorkerError;\n}\n\nexport interface ExtractTextResponseData {\n /** Extracted text per page */\n readonly pages: readonly ExtractedPageText[];\n\n /** Total extraction time in milliseconds */\n readonly extractionTime: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Error Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Error codes for parsing operations.\n */\nexport type ParsingErrorCode =\n | \"PARSE_ERROR\"\n | \"INVALID_PDF\"\n | \"ENCRYPTED\"\n | \"AUTH_FAILED\"\n | \"CANCELLED\"\n | \"TIMEOUT\"\n | \"OUT_OF_MEMORY\"\n | \"UNSUPPORTED_FEATURE\"\n | \"INTERNAL_ERROR\";\n\n/**\n * Error information from the parsing worker.\n */\nexport interface ParsingWorkerError {\n readonly code: ParsingErrorCode;\n readonly message: string;\n readonly stack?: string;\n readonly details?: Record<string, unknown>;\n /** Whether the error is recoverable */\n readonly recoverable: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Cancellation Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Request to cancel a parsing operation.\n */\nexport interface CancelParsingRequest {\n readonly type: \"request\";\n readonly id: MessageId;\n readonly requestType: \"cancelParsing\";\n readonly data: CancelParsingRequestData;\n}\n\nexport interface CancelParsingRequestData {\n /** Task ID to cancel */\n readonly taskId: TaskId;\n}\n\n/**\n * Response to cancel request.\n */\nexport interface CancelParsingResponse {\n readonly type: \"response\";\n readonly id: MessageId;\n readonly requestType: \"cancelParsing\";\n readonly status: \"success\";\n readonly data: CancelParsingResponseData;\n}\n\nexport interface CancelParsingResponseData {\n /** Task ID that was cancelled */\n readonly taskId: TaskId;\n /** Whether the task was successfully cancelled */\n readonly wasCancelled: boolean;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Union Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * All parsing worker request types.\n */\nexport type ParsingWorkerRequest = ParseDocumentRequest | ExtractTextRequest | CancelParsingRequest;\n\n/**\n * All parsing worker response types.\n */\nexport type ParsingWorkerResponse =\n | ParseDocumentResponse\n | ExtractTextResponse\n | CancelParsingResponse;\n\n/**\n * Messages from main thread to parsing worker.\n */\nexport type ParsingMainToWorkerMessage = ParsingWorkerRequest;\n\n/**\n * Messages from parsing worker to main thread.\n */\nexport type ParsingWorkerToMainMessage = ParsingWorkerResponse | ParsingProgressMessage;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Type Guards\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Check if a message is a parsing progress message.\n */\nexport function isParsingProgress(message: unknown): message is ParsingProgressMessage {\n return (\n typeof message === \"object\" &&\n message !== null &&\n \"type\" in message &&\n (message as { type: unknown }).type === \"parsingProgress\"\n );\n}\n\n/**\n * Check if a message is a parsing worker response.\n */\nexport function isParsingResponse(message: unknown): message is ParsingWorkerResponse {\n return (\n typeof message === \"object\" &&\n message !== null &&\n \"type\" in message &&\n (message as { type: unknown }).type === \"response\" &&\n \"requestType\" in message &&\n [\"parseDocument\", \"extractText\", \"cancelParsing\"].includes(\n (message as { requestType: unknown }).requestType as string,\n )\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Factory Functions\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a parsing progress message.\n */\nexport function createParsingProgress(\n taskId: TaskId,\n progress: ParsingProgress,\n): ParsingProgressMessage {\n return {\n type: \"parsingProgress\",\n taskId,\n progress,\n timestamp: Date.now(),\n };\n}\n\n/**\n * Create a parsing worker error.\n */\nexport function createParsingError(\n error: Error,\n code?: ParsingErrorCode,\n recoverable = false,\n): ParsingWorkerError {\n return {\n code: code ?? \"INTERNAL_ERROR\",\n message: error.message,\n stack: error.stack,\n recoverable,\n };\n}\n","/**\n * Utility functions for parsing worker initialization and environment detection.\n *\n * Provides cross-platform support for Node.js, Bun, and browsers.\n */\n\n// Declare browser globals for type checking\ndeclare const window: typeof globalThis | undefined;\ndeclare const document: unknown | undefined;\ndeclare const self: (typeof globalThis & { importScripts?: unknown }) | undefined;\ndeclare const Worker: new (url: string | URL, options?: WorkerOptions) => Worker;\ndeclare const MessagePort: new () => MessagePort;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Environment Detection\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Runtime environment types.\n */\nexport type RuntimeEnvironment = \"browser\" | \"node\" | \"bun\" | \"deno\" | \"unknown\";\n\n/**\n * Detect the current runtime environment.\n */\nexport function detectEnvironment(): RuntimeEnvironment {\n // Check for Bun first (it also has process.versions.node)\n if (typeof globalThis !== \"undefined\" && \"Bun\" in globalThis) {\n return \"bun\";\n }\n\n // Check for Deno\n if (typeof globalThis !== \"undefined\" && \"Deno\" in globalThis) {\n return \"deno\";\n }\n\n // Check for Node.js\n if (\n typeof globalThis !== \"undefined\" &&\n typeof (globalThis as { process?: { versions?: { node?: string } } }).process?.versions\n ?.node === \"string\"\n ) {\n return \"node\";\n }\n\n // Check for browser\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n return \"browser\";\n }\n\n // Web Worker context (no document but has self)\n if (typeof self !== \"undefined\" && typeof self.importScripts === \"function\") {\n return \"browser\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Check if Web Workers are supported in the current environment.\n */\nexport function isWorkerSupported(): boolean {\n const env = detectEnvironment();\n\n switch (env) {\n case \"browser\":\n return typeof Worker !== \"undefined\";\n\n case \"node\":\n // Node.js has worker_threads, but Web Worker API needs polyfill\n return false;\n\n case \"bun\":\n // Bun supports Web Workers natively\n return typeof Worker !== \"undefined\";\n\n case \"deno\":\n // Deno supports Web Workers\n return typeof Worker !== \"undefined\";\n\n default:\n return false;\n }\n}\n\n/**\n * Check if we're currently running inside a Web Worker.\n */\nexport function isWorkerContext(): boolean {\n // In a worker, 'self' exists but 'window' doesn't\n return (\n typeof self !== \"undefined\" &&\n typeof self.importScripts === \"function\" &&\n typeof window === \"undefined\"\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Worker Creation Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Options for creating a parsing worker.\n */\nexport interface ParsingWorkerCreationOptions {\n /** URL or path to the worker script */\n workerUrl?: string | URL;\n\n /** Worker name for debugging */\n name?: string;\n\n /** Whether to use module workers (ES modules) */\n module?: boolean;\n}\n\n/**\n * Create a Worker instance with proper error handling.\n *\n * @throws Error if workers are not supported or creation fails\n */\nexport function createWorkerInstance(options: ParsingWorkerCreationOptions): Worker {\n if (!isWorkerSupported()) {\n throw new Error(\n `Web Workers are not supported in ${detectEnvironment()} environment. ` +\n \"Use the synchronous parsing API instead.\",\n );\n }\n\n const { workerUrl, name, module = true } = options;\n\n if (!workerUrl) {\n throw new Error(\n \"Worker URL is required. Provide workerUrl pointing to the bundled parsing worker script.\",\n );\n }\n\n try {\n return new Worker(workerUrl, {\n type: module ? \"module\" : \"classic\",\n name: name ?? `parsing-worker-${Date.now()}`,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to create parsing worker: ${message}`, { cause: error });\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Transferable Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Extract transferable objects from data for efficient worker communication.\n *\n * Identifies ArrayBuffer instances that can be transferred (zero-copy)\n * instead of copied between threads.\n */\nexport function extractTransferables(data: unknown): ArrayBuffer[] {\n const transferables: ArrayBuffer[] = [];\n const seen = new WeakSet<object>();\n\n function collect(value: unknown): void {\n if (value === null || typeof value !== \"object\") {\n return;\n }\n\n // Prevent cycles\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n\n // Direct ArrayBuffer\n if (value instanceof ArrayBuffer) {\n transferables.push(value);\n return;\n }\n\n // TypedArray (Uint8Array, etc.)\n if (ArrayBuffer.isView(value) && value.buffer instanceof ArrayBuffer) {\n // Only transfer if the view covers the whole buffer\n if (value.byteOffset === 0 && value.byteLength === value.buffer.byteLength) {\n transferables.push(value.buffer);\n }\n return;\n }\n\n // MessagePort - skip for now as it requires DOM types\n // Users can pass these explicitly in transfer arrays\n\n // Recurse into arrays\n if (Array.isArray(value)) {\n for (const item of value) {\n collect(item);\n }\n return;\n }\n\n // Recurse into plain objects\n for (const key of Object.keys(value)) {\n collect((value as Record<string, unknown>)[key]);\n }\n }\n\n collect(data);\n return transferables;\n}\n\n/**\n * Clone data for cases where we can't or shouldn't transfer.\n *\n * Creates a structured clone of the data, which works across worker boundaries.\n */\nexport function cloneForTransfer<T>(data: T): T {\n // Use structuredClone if available (modern browsers/Node 17+)\n if (typeof structuredClone === \"function\") {\n return structuredClone(data);\n }\n\n // Fallback: JSON round-trip (loses some types like Uint8Array)\n // This should rarely be hit in practice\n return JSON.parse(JSON.stringify(data));\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Message Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Generate a unique ID for messages.\n */\nexport function generateParsingMessageId(): string {\n return `parse-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\n/**\n * Generate a unique task ID for parsing operations.\n */\nexport function generateParsingTaskId(): string {\n return `parsing-task-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Timeout Utilities\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Default timeouts for parsing operations (in milliseconds).\n */\nexport const DEFAULT_PARSING_TIMEOUTS = {\n /** Initialization timeout */\n init: 10_000,\n\n /** Small document parsing (<1MB) */\n small: 30_000,\n\n /** Medium document parsing (1-10MB) */\n medium: 60_000,\n\n /** Large document parsing (>10MB) */\n large: 300_000,\n\n /** Text extraction per page */\n textPerPage: 5_000,\n} as const;\n\n/**\n * Calculate appropriate timeout based on document size.\n */\nexport function calculateParsingTimeout(sizeBytes: number): number {\n const sizeMB = sizeBytes / (1024 * 1024);\n\n if (sizeMB < 1) {\n return DEFAULT_PARSING_TIMEOUTS.small;\n }\n\n if (sizeMB < 10) {\n return DEFAULT_PARSING_TIMEOUTS.medium;\n }\n\n return DEFAULT_PARSING_TIMEOUTS.large;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Deferred Promise\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * A promise that can be resolved or rejected externally.\n */\nexport interface Deferred<T> {\n readonly promise: Promise<T>;\n resolve(value: T): void;\n reject(reason: unknown): void;\n readonly isPending: boolean;\n}\n\n/**\n * Create a deferred promise for async coordination.\n */\nexport function createDeferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void;\n let reject!: (reason: unknown) => void;\n let isPending = true;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = (value: T) => {\n isPending = false;\n res(value);\n };\n reject = (reason: unknown) => {\n isPending = false;\n rej(reason);\n };\n });\n\n return {\n promise,\n resolve,\n reject,\n get isPending() {\n return isPending;\n },\n };\n}\n","/**\n * Main thread interface for parsing worker communication.\n *\n * ParsingWorkerHost manages the lifecycle of a parsing worker and provides\n * a Promise-based API for document parsing operations. It handles:\n * - Worker creation and initialization\n * - Message passing with request/response correlation\n * - Progress event handling with 500ms throttling\n * - Cancellation support\n * - Graceful shutdown and cleanup\n */\n\nimport { type MessageId, type TaskId, generateMessageId, generateTaskId } from \"./messages\";\nimport {\n type CancelParsingResponse,\n type ExtractTextResponse,\n type ExtractTextResponseData,\n type ParseDocumentResponse,\n type ParseDocumentResponseData,\n type ParsedDocumentInfo,\n type ParsingProgress,\n type ParsingProgressCallback,\n type ParsingProgressMessage,\n type ParsingWorkerError,\n type ParsingWorkerResponse,\n type WorkerParseOptions,\n isParsingProgress,\n isParsingResponse,\n} from \"./parsing-types\";\nimport {\n calculateParsingTimeout,\n createDeferred,\n createWorkerInstance,\n type Deferred,\n extractTransferables,\n generateParsingTaskId,\n isWorkerSupported,\n} from \"./parsing-utils\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * State of the parsing worker host.\n */\nexport type ParsingWorkerState =\n | \"idle\"\n | \"initializing\"\n | \"ready\"\n | \"busy\"\n | \"terminated\"\n | \"error\";\n\n/**\n * Options for creating a ParsingWorkerHost.\n */\nexport interface ParsingWorkerHostOptions {\n /**\n * URL or path to the parsing worker script.\n */\n workerUrl: string | URL;\n\n /**\n * Worker name for debugging purposes.\n */\n name?: string;\n\n /**\n * Enable verbose logging in the worker.\n * @default false\n */\n verbose?: boolean;\n\n /**\n * Timeout for worker initialization in milliseconds.\n * @default 10000\n */\n initTimeout?: number;\n\n /**\n * Default timeout for parsing operations in milliseconds.\n * @default 60000\n */\n defaultTimeout?: number;\n\n /**\n * Called when the worker reports parsing progress.\n */\n onProgress?: ParsingProgressCallback;\n\n /**\n * Called when the worker encounters an error.\n */\n onError?: (error: ParsingWorkerError) => void;\n\n /**\n * Called when the worker state changes.\n */\n onStateChange?: (state: ParsingWorkerState, previousState: ParsingWorkerState) => void;\n}\n\n/**\n * Pending request waiting for response.\n */\ninterface PendingRequest<T> {\n readonly messageId: MessageId;\n readonly taskId: TaskId;\n readonly deferred: Deferred<T>;\n readonly timeoutId?: ReturnType<typeof setTimeout>;\n readonly onProgress?: ParsingProgressCallback;\n}\n\n/**\n * Result of a parse operation.\n */\nexport interface ParseResult {\n /** Unique document identifier for subsequent operations */\n readonly documentId: string;\n\n /** Parsed document information */\n readonly info: ParsedDocumentInfo;\n\n /** Total parsing time in milliseconds */\n readonly parsingTime: number;\n}\n\n/**\n * Result of text extraction.\n */\nexport interface ExtractTextResult {\n /** Extracted text per page */\n readonly pages: readonly { pageIndex: number; text: string }[];\n\n /** Total extraction time in milliseconds */\n readonly extractionTime: number;\n}\n\n/**\n * Options for parsing a document.\n */\nexport interface ParseOptions extends WorkerParseOptions {\n /** Timeout in milliseconds (auto-calculated from file size if not provided) */\n timeout?: number;\n\n /** Progress callback for this operation */\n onProgress?: ParsingProgressCallback;\n}\n\n/**\n * Options for extracting text.\n */\nexport interface ExtractOptions {\n /** Page indices to extract (0-based), undefined means all pages */\n pages?: number[];\n\n /** Include position information for each text item */\n includePositions?: boolean;\n\n /** Timeout in milliseconds */\n timeout?: number;\n\n /** Progress callback for this operation */\n onProgress?: ParsingProgressCallback;\n}\n\n/**\n * Active operation that can be cancelled.\n */\nexport interface CancellableParseOperation<T> {\n /** Promise that resolves when the operation completes */\n readonly promise: Promise<T>;\n\n /** Cancel the operation */\n cancel(): Promise<boolean>;\n\n /** Task ID for the operation */\n readonly taskId: TaskId;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ParsingWorkerHost Class\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * ParsingWorkerHost manages a Web Worker for PDF parsing operations.\n *\n * @example\n * ```typescript\n * const host = new ParsingWorkerHost({\n * workerUrl: '/parsing-worker.js',\n * onProgress: (progress) => console.log(`${progress.percent}%`),\n * });\n *\n * await host.initialize();\n *\n * const result = await host.parse(pdfBytes);\n * console.log(`Parsed ${result.info.pageCount} pages`);\n *\n * const text = await host.extractText(result.documentId);\n * console.log(text.pages[0].text);\n *\n * await host.terminate();\n * ```\n */\nexport class ParsingWorkerHost {\n private _worker: Worker | null = null;\n private _state: ParsingWorkerState = \"idle\";\n private _options: Required<\n Omit<ParsingWorkerHostOptions, \"onProgress\" | \"onError\" | \"onStateChange\">\n > & {\n onProgress?: ParsingProgressCallback;\n onError?: (error: ParsingWorkerError) => void;\n onStateChange?: (state: ParsingWorkerState, previousState: ParsingWorkerState) => void;\n };\n private _pendingRequests: Map<MessageId, PendingRequest<unknown>> = new Map();\n private _taskProgressHandlers: Map<TaskId, ParsingProgressCallback> = new Map();\n private _initPromise: Promise<void> | null = null;\n\n constructor(options: ParsingWorkerHostOptions) {\n this._options = {\n workerUrl: options.workerUrl,\n name: options.name ?? `parsing-worker-host-${Date.now()}`,\n verbose: options.verbose ?? false,\n initTimeout: options.initTimeout ?? 10_000,\n defaultTimeout: options.defaultTimeout ?? 60_000,\n onProgress: options.onProgress,\n onError: options.onError,\n onStateChange: options.onStateChange,\n };\n }\n\n // ───────────────────────────────────────────────────────────────────────────\n // Public Properties\n // ───────────────────────────────────────────────────────────────────────────\n\n /**\n * Current worker state.\n */\n get state(): ParsingWorkerState {\n return this._state;\n }\n\n /**\n * Whether the worker is ready to accept requests.\n */\n get isReady(): boolean {\n return this._state === \"ready\" || this._state === \"busy\";\n }\n\n /**\n * Whether the worker has been terminated.\n */\n get isTerminated(): boolean {\n return this._state === \"terminated\";\n }\n\n /**\n * Number of pending requests.\n */\n get pendingCount(): number {\n return this._pendingRequests.size;\n }\n\n /**\n * Worker name.\n */\n get name(): string {\n return this._options.name;\n }\n\n // ───────────────────────────────────────────────────────────────────────────\n // Lifecycle Methods\n // ───────────────────────────────────────────────────────────────────────────\n\n /**\n * Initialize the worker.\n *\n * Creates the Web Worker instance and waits for it to be ready.\n * This method is idempotent — calling it multiple times returns the same promise.\n *\n * @throws Error if workers are not supported, creation fails, or initialization times out\n */\n async initialize(): Promise<void> {\n if (this._initPromise) {\n return this._initPromise;\n }\n\n if (this._state === \"terminated\") {\n throw new Error(\"Cannot initialize a terminated worker\");\n }\n\n this._initPromise = this._doInitialize();\n return this._initPromise;\n }\n\n private async _doInitialize(): Promise<void> {\n this._setState(\"initializing\");\n\n try {\n // Create the worker\n this._worker = createWorkerInstance({\n workerUrl: this._options.workerUrl,\n name: this._options.name,\n module: true,\n });\n\n // Set up message handling\n this._worker.onmessage = this._handleMessage.bind(this);\n this._worker.onerror = this._handleError.bind(this);\n\n // Send init request\n const initPromise = this._sendRequest<void>(\n \"init\",\n {\n verbose: this._options.verbose,\n name: this._options.name,\n },\n this._options.initTimeout,\n );\n\n await initPromise;\n this._setState(\"ready\");\n } catch (error) {\n this._setState(\"error\");\n this._cleanup();\n throw error;\n }\n }\n\n /**\n * Terminate the worker.\n *\n * @param graceful - If true, wait for pending operations to complete\n * @param timeout - Timeout for graceful shutdown in milliseconds\n */\n async terminate(graceful = true, timeout = 5000): Promise<void> {\n if (this._state === \"terminated\") {\n return;\n }\n\n if (graceful && this._worker && this.isReady) {\n try {\n await Promise.race([\n this._sendRequest(\"terminate\", undefined, timeout),\n new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(\"Terminate timeout\")), timeout),\n ),\n ]);\n } catch {\n // Ignore errors during graceful shutdown\n }\n }\n\n this._forceTerminate();\n }\n\n private _forceTerminate(): void {\n // Reject all pending requests\n for (const pending of this._pendingRequests.values()) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.deferred.reject(new Error(\"Worker terminated\"));\n }\n this._pendingRequests.clear();\n this._taskProgressHandlers.clear();\n\n // Terminate the worker\n if (this._worker) {\n this._worker.terminate();\n this._worker = null;\n }\n\n this._setState(\"terminated\");\n this._initPromise = null;\n }\n\n private _cleanup(): void {\n for (const pending of this._pendingRequests.values()) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n }\n this._pendingRequests.clear();\n this._taskProgressHandlers.clear();\n }\n\n // ───────────────────────────────────────────────────────────────────────────\n // Parsing Operations\n // ───────────────────────────────────────────────────────────────────────────\n\n /**\n * Parse a PDF document.\n *\n * @param bytes - PDF file bytes\n * @param options - Parse options\n * @returns Parsed document information\n */\n async parse(bytes: Uint8Array, options?: ParseOptions): Promise<ParseResult> {\n await this._ensureInitialized();\n\n const taskId = generateParsingTaskId();\n const timeout = options?.timeout ?? calculateParsingTimeout(bytes.length);\n\n // Register progress handler for this task\n if (options?.onProgress) {\n this._taskProgressHandlers.set(taskId, options.onProgress);\n }\n\n try {\n const response = await this._sendRequest<ParseDocumentResponse>(\n \"parseDocument\",\n {\n bytes,\n taskId,\n options: {\n lenient: options?.lenient,\n password: options?.password,\n bruteForceRecovery: options?.bruteForceRecovery,\n progressInterval: options?.progressInterval,\n },\n },\n timeout,\n taskId,\n [bytes.buffer as ArrayBuffer],\n );\n\n if (response.status === \"cancelled\") {\n throw new Error(\"Operation cancelled\");\n }\n\n if (response.status === \"error\" || !response.data) {\n throw new Error(response.error?.message ?? \"Failed to parse document\");\n }\n\n return response.data;\n } finally {\n this._taskProgressHandlers.delete(taskId);\n }\n }\n\n /**\n * Parse a PDF document with cancellation support.\n */\n parseCancellable(\n bytes: Uint8Array,\n options?: ParseOptions,\n ): CancellableParseOperation<ParseResult> {\n const taskId = generateParsingTaskId();\n\n const promise = this.parse(bytes, { ...options, taskId } as ParseOptions & { taskId: TaskId });\n\n return {\n promise,\n taskId,\n cancel: () => this.cancel(taskId),\n };\n }\n\n /**\n * Extract text from a parsed document.\n *\n * @param documentId - Document ID from parse result\n * @param options - Extraction options\n * @returns Extracted text per page\n */\n async extractText(documentId: string, options?: ExtractOptions): Promise<ExtractTextResult> {\n await this._ensureInitialized();\n\n const taskId = generateParsingTaskId();\n const timeout = options?.timeout ?? this._options.defaultTimeout;\n\n // Register progress handler\n if (options?.onProgress) {\n this._taskProgressHandlers.set(taskId, options.onProgress);\n }\n\n try {\n const response = await this._sendRequest<ExtractTextResponse>(\n \"extractText\",\n {\n documentId,\n taskId,\n pageIndices: options?.pages,\n includePositions: options?.includePositions,\n },\n timeout,\n taskId,\n );\n\n if (response.status === \"cancelled\") {\n throw new Error(\"Operation cancelled\");\n }\n\n if (response.status === \"error\" || !response.data) {\n throw new Error(response.error?.message ?? \"Failed to extract text\");\n }\n\n return response.data;\n } finally {\n this._taskProgressHandlers.delete(taskId);\n }\n }\n\n /**\n * Cancel an active parsing operation.\n *\n * @param taskId - Task ID to cancel\n * @returns Whether the task was successfully cancelled\n */\n async cancel(taskId: TaskId): Promise<boolean> {\n if (!this.isReady) {\n return false;\n }\n\n try {\n const response = await this._sendRequest<CancelParsingResponse>(\n \"cancelParsing\",\n { taskId },\n 5000,\n );\n\n return response.status === \"success\" && response.data?.wasCancelled;\n } catch {\n return false;\n }\n }\n\n // ───────────────────────────────────────────────────────────────────────────\n // Private Methods\n // ───────────────────────────────────────────────────────────────────────────\n\n private async _ensureInitialized(): Promise<void> {\n if (this._state === \"terminated\") {\n throw new Error(\"Worker has been terminated\");\n }\n\n if (!this.isReady) {\n await this.initialize();\n }\n }\n\n private _sendRequest<T>(\n requestType: string,\n data: unknown,\n timeout: number,\n taskId?: TaskId,\n transferables?: ArrayBuffer[],\n ): Promise<T> {\n if (this._state === \"terminated\") {\n return Promise.reject(new Error(\"Worker has been terminated\"));\n }\n\n if (!this._worker) {\n return Promise.reject(new Error(\"Worker not initialized\"));\n }\n\n const messageId = generateMessageId();\n const actualTaskId = taskId ?? generateTaskId();\n const deferred = createDeferred<T>();\n\n // Set up timeout\n const timeoutId = setTimeout(() => {\n const pending = this._pendingRequests.get(messageId);\n if (pending) {\n this._pendingRequests.delete(messageId);\n this._updateBusyState();\n pending.deferred.reject(new Error(`Request timeout after ${timeout}ms: ${requestType}`));\n }\n }, timeout);\n\n // Track pending request\n const pending: PendingRequest<T> = {\n messageId,\n taskId: actualTaskId,\n deferred,\n timeoutId,\n };\n\n this._pendingRequests.set(messageId, pending as PendingRequest<unknown>);\n\n // Update state to busy\n if (this._state === \"ready\") {\n this._setState(\"busy\");\n }\n\n // Send message\n const request = {\n type: \"request\",\n id: messageId,\n requestType,\n data,\n };\n\n try {\n if (transferables && transferables.length > 0) {\n this._worker.postMessage(request, transferables);\n } else {\n this._worker.postMessage(request);\n }\n } catch (error) {\n clearTimeout(timeoutId);\n this._pendingRequests.delete(messageId);\n this._updateBusyState();\n return Promise.reject(error);\n }\n\n return deferred.promise;\n }\n\n private _handleMessage(event: MessageEvent): void {\n const message = event.data;\n\n if (isParsingProgress(message)) {\n this._handleProgress(message);\n } else if (isParsingResponse(message)) {\n this._handleResponse(message);\n } else if (typeof message === \"object\" && message !== null && \"type\" in message) {\n // Handle standard responses (init, terminate)\n if ((message as { type: string }).type === \"response\") {\n this._handleResponse(message as ParsingWorkerResponse);\n }\n }\n }\n\n private _handleResponse(response: ParsingWorkerResponse): void {\n const pending = this._pendingRequests.get(response.id);\n if (!pending) {\n return;\n }\n\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n\n this._pendingRequests.delete(response.id);\n this._updateBusyState();\n\n if (response.status === \"error\" && response.error) {\n pending.deferred.reject(new Error(response.error.message));\n } else {\n pending.deferred.resolve(response);\n }\n }\n\n private _handleProgress(progress: ParsingProgressMessage): void {\n // Call task-specific handler\n const taskHandler = this._taskProgressHandlers.get(progress.taskId);\n if (taskHandler) {\n taskHandler(progress.progress);\n }\n\n // Call global handler\n if (this._options.onProgress) {\n this._options.onProgress(progress.progress);\n }\n }\n\n private _handleError(event: ErrorEvent): void {\n const error: ParsingWorkerError = {\n code: \"INTERNAL_ERROR\",\n message: event.message ?? \"Unknown worker error\",\n recoverable: false,\n };\n\n if (this._options.onError) {\n this._options.onError(error);\n }\n\n // Reject all pending requests if not initializing\n if (this._state !== \"initializing\") {\n for (const pending of this._pendingRequests.values()) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.deferred.reject(new Error(error.message));\n }\n this._pendingRequests.clear();\n this._setState(\"error\");\n }\n }\n\n private _updateBusyState(): void {\n if (this._state === \"busy\" && this._pendingRequests.size === 0) {\n this._setState(\"ready\");\n }\n }\n\n private _setState(newState: ParsingWorkerState): void {\n const previousState = this._state;\n if (previousState === newState) {\n return;\n }\n\n this._state = newState;\n\n if (this._options.onStateChange) {\n this._options.onStateChange(newState, previousState);\n }\n }\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Factory Function\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Create a new ParsingWorkerHost instance.\n */\nexport function createParsingWorkerHost(options: ParsingWorkerHostOptions): ParsingWorkerHost {\n return new ParsingWorkerHost(options);\n}\n\n/**\n * Check if parsing workers are supported in the current environment.\n */\nexport { isWorkerSupported };\n"],"mappings":";;;;AAwBA,SAAgB,oBAA+B;AAC7C,QAAO,OAAO,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;;;;;AAMpE,SAAgB,iBAAyB;AACvC,QAAO,QAAQ,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;;;;;AAiZrE,SAAgB,WAAW,SAA6C;AACtE,QACE,OAAO,YAAY,YACnB,YAAY,QACZ,UAAU,WACT,QAA8B,SAAS;;;;;AAO5C,SAAgB,WAAW,SAA8C;AACvE,QACE,OAAO,YAAY,YACnB,YAAY,QACZ,UAAU,WACT,QAA8B,SAAS;;;;;AAW5C,SAAgB,cACd,aACA,MAC4C;AAC5C,QAAO;EACL,MAAM;EACN,IAAI,mBAAmB;EACvB;EACA;EACD;;;;;AA6EH,SAAgB,kBAAkB,OAAc,MAA4B;AAC1E,QAAO;EACL,MAAM,QAAQ,MAAM;EACpB,SAAS,MAAM;EACf,OAAO,MAAM;EACd;;;;;;;;AChKH,SAAgB,kBAAkB,SAAqD;AACrF,QACE,OAAO,YAAY,YACnB,YAAY,QACZ,UAAU,WACT,QAA8B,SAAS;;;;;AAO5C,SAAgB,kBAAkB,SAAoD;AACpF,QACE,OAAO,YAAY,YACnB,YAAY,QACZ,UAAU,WACT,QAA8B,SAAS,cACxC,iBAAiB,WACjB;EAAC;EAAiB;EAAe;EAAgB,CAAC,SAC/C,QAAqC,YACvC;;;;;AAWL,SAAgB,sBACd,QACA,UACwB;AACxB,QAAO;EACL,MAAM;EACN;EACA;EACA,WAAW,KAAK,KAAK;EACtB;;;;;;;;ACxZH,SAAgB,oBAAwC;AAEtD,KAAI,OAAO,eAAe,eAAe,SAAS,WAChD,QAAO;AAIT,KAAI,OAAO,eAAe,eAAe,UAAU,WACjD,QAAO;AAIT,KACE,OAAO,eAAe,eACtB,OAAQ,WAA8D,SAAS,UAC3E,SAAS,SAEb,QAAO;AAIT,KAAI,OAAO,WAAW,eAAe,OAAO,aAAa,YACvD,QAAO;AAIT,KAAI,OAAO,SAAS,eAAe,OAAO,KAAK,kBAAkB,WAC/D,QAAO;AAGT,QAAO;;;;;AAMT,SAAgB,oBAA6B;AAG3C,SAFY,mBAAmB,EAE/B;EACE,KAAK,UACH,QAAO,OAAO,WAAW;EAE3B,KAAK,OAEH,QAAO;EAET,KAAK,MAEH,QAAO,OAAO,WAAW;EAE3B,KAAK,OAEH,QAAO,OAAO,WAAW;EAE3B,QACE,QAAO;;;;;;AAOb,SAAgB,kBAA2B;AAEzC,QACE,OAAO,SAAS,eAChB,OAAO,KAAK,kBAAkB,cAC9B,OAAO,WAAW;;;;;;;AA2BtB,SAAgB,qBAAqB,SAA+C;AAClF,KAAI,CAAC,mBAAmB,CACtB,OAAM,IAAI,MACR,oCAAoC,mBAAmB,CAAC,wDAEzD;CAGH,MAAM,EAAE,WAAW,MAAM,SAAS,SAAS;AAE3C,KAAI,CAAC,UACH,OAAM,IAAI,MACR,2FACD;AAGH,KAAI;AACF,SAAO,IAAI,OAAO,WAAW;GAC3B,MAAM,SAAS,WAAW;GAC1B,MAAM,QAAQ,kBAAkB,KAAK,KAAK;GAC3C,CAAC;UACK,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAM,IAAI,MAAM,oCAAoC,WAAW,EAAE,OAAO,OAAO,CAAC;;;;;;;;;AAcpF,SAAgB,qBAAqB,MAA8B;CACjE,MAAMA,gBAA+B,EAAE;CACvC,MAAM,uBAAO,IAAI,SAAiB;CAElC,SAAS,QAAQ,OAAsB;AACrC,MAAI,UAAU,QAAQ,OAAO,UAAU,SACrC;AAIF,MAAI,KAAK,IAAI,MAAM,CACjB;AAEF,OAAK,IAAI,MAAM;AAGf,MAAI,iBAAiB,aAAa;AAChC,iBAAc,KAAK,MAAM;AACzB;;AAIF,MAAI,YAAY,OAAO,MAAM,IAAI,MAAM,kBAAkB,aAAa;AAEpE,OAAI,MAAM,eAAe,KAAK,MAAM,eAAe,MAAM,OAAO,WAC9D,eAAc,KAAK,MAAM,OAAO;AAElC;;AAOF,MAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,QAAK,MAAM,QAAQ,MACjB,SAAQ,KAAK;AAEf;;AAIF,OAAK,MAAM,OAAO,OAAO,KAAK,MAAM,CAClC,SAAS,MAAkC,KAAK;;AAIpD,SAAQ,KAAK;AACb,QAAO;;;;;AA0BT,SAAgB,2BAAmC;AACjD,QAAO,SAAS,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;;;;;AAMtE,SAAgB,wBAAgC;AAC9C,QAAO,gBAAgB,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;;;;;AAU7E,MAAa,2BAA2B;CAEtC,MAAM;CAGN,OAAO;CAGP,QAAQ;CAGR,OAAO;CAGP,aAAa;CACd;;;;AAKD,SAAgB,wBAAwB,WAA2B;CACjE,MAAM,SAAS,aAAa,OAAO;AAEnC,KAAI,SAAS,EACX,QAAO,yBAAyB;AAGlC,KAAI,SAAS,GACX,QAAO,yBAAyB;AAGlC,QAAO,yBAAyB;;;;;AAoBlC,SAAgB,iBAAiC;CAC/C,IAAIC;CACJ,IAAIC;CACJ,IAAI,YAAY;AAahB,QAAO;EACL,SAZc,IAAI,SAAY,KAAK,QAAQ;AAC3C,cAAW,UAAa;AACtB,gBAAY;AACZ,QAAI,MAAM;;AAEZ,aAAU,WAAoB;AAC5B,gBAAY;AACZ,QAAI,OAAO;;IAEb;EAIA;EACA;EACA,IAAI,YAAY;AACd,UAAO;;EAEV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtHH,IAAa,oBAAb,MAA+B;CAC7B,AAAQ,UAAyB;CACjC,AAAQ,SAA6B;CACrC,AAAQ;CAOR,AAAQ,mCAA4D,IAAI,KAAK;CAC7E,AAAQ,wCAA8D,IAAI,KAAK;CAC/E,AAAQ,eAAqC;CAE7C,YAAY,SAAmC;AAC7C,OAAK,WAAW;GACd,WAAW,QAAQ;GACnB,MAAM,QAAQ,QAAQ,uBAAuB,KAAK,KAAK;GACvD,SAAS,QAAQ,WAAW;GAC5B,aAAa,QAAQ,eAAe;GACpC,gBAAgB,QAAQ,kBAAkB;GAC1C,YAAY,QAAQ;GACpB,SAAS,QAAQ;GACjB,eAAe,QAAQ;GACxB;;;;;CAUH,IAAI,QAA4B;AAC9B,SAAO,KAAK;;;;;CAMd,IAAI,UAAmB;AACrB,SAAO,KAAK,WAAW,WAAW,KAAK,WAAW;;;;;CAMpD,IAAI,eAAwB;AAC1B,SAAO,KAAK,WAAW;;;;;CAMzB,IAAI,eAAuB;AACzB,SAAO,KAAK,iBAAiB;;;;;CAM/B,IAAI,OAAe;AACjB,SAAO,KAAK,SAAS;;;;;;;;;;CAevB,MAAM,aAA4B;AAChC,MAAI,KAAK,aACP,QAAO,KAAK;AAGd,MAAI,KAAK,WAAW,aAClB,OAAM,IAAI,MAAM,wCAAwC;AAG1D,OAAK,eAAe,KAAK,eAAe;AACxC,SAAO,KAAK;;CAGd,MAAc,gBAA+B;AAC3C,OAAK,UAAU,eAAe;AAE9B,MAAI;AAEF,QAAK,UAAU,qBAAqB;IAClC,WAAW,KAAK,SAAS;IACzB,MAAM,KAAK,SAAS;IACpB,QAAQ;IACT,CAAC;AAGF,QAAK,QAAQ,YAAY,KAAK,eAAe,KAAK,KAAK;AACvD,QAAK,QAAQ,UAAU,KAAK,aAAa,KAAK,KAAK;AAYnD,SAToB,KAAK,aACvB,QACA;IACE,SAAS,KAAK,SAAS;IACvB,MAAM,KAAK,SAAS;IACrB,EACD,KAAK,SAAS,YACf;AAGD,QAAK,UAAU,QAAQ;WAChB,OAAO;AACd,QAAK,UAAU,QAAQ;AACvB,QAAK,UAAU;AACf,SAAM;;;;;;;;;CAUV,MAAM,UAAU,WAAW,MAAM,UAAU,KAAqB;AAC9D,MAAI,KAAK,WAAW,aAClB;AAGF,MAAI,YAAY,KAAK,WAAW,KAAK,QACnC,KAAI;AACF,SAAM,QAAQ,KAAK,CACjB,KAAK,aAAa,aAAa,QAAW,QAAQ,EAClD,IAAI,SAAgB,GAAG,WACrB,iBAAiB,uBAAO,IAAI,MAAM,oBAAoB,CAAC,EAAE,QAAQ,CAClE,CACF,CAAC;UACI;AAKV,OAAK,iBAAiB;;CAGxB,AAAQ,kBAAwB;AAE9B,OAAK,MAAM,WAAW,KAAK,iBAAiB,QAAQ,EAAE;AACpD,OAAI,QAAQ,UACV,cAAa,QAAQ,UAAU;AAEjC,WAAQ,SAAS,uBAAO,IAAI,MAAM,oBAAoB,CAAC;;AAEzD,OAAK,iBAAiB,OAAO;AAC7B,OAAK,sBAAsB,OAAO;AAGlC,MAAI,KAAK,SAAS;AAChB,QAAK,QAAQ,WAAW;AACxB,QAAK,UAAU;;AAGjB,OAAK,UAAU,aAAa;AAC5B,OAAK,eAAe;;CAGtB,AAAQ,WAAiB;AACvB,OAAK,MAAM,WAAW,KAAK,iBAAiB,QAAQ,CAClD,KAAI,QAAQ,UACV,cAAa,QAAQ,UAAU;AAGnC,OAAK,iBAAiB,OAAO;AAC7B,OAAK,sBAAsB,OAAO;;;;;;;;;CAcpC,MAAM,MAAM,OAAmB,SAA8C;AAC3E,QAAM,KAAK,oBAAoB;EAE/B,MAAM,SAAS,uBAAuB;EACtC,MAAM,UAAU,SAAS,WAAW,wBAAwB,MAAM,OAAO;AAGzE,MAAI,SAAS,WACX,MAAK,sBAAsB,IAAI,QAAQ,QAAQ,WAAW;AAG5D,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,aAC1B,iBACA;IACE;IACA;IACA,SAAS;KACP,SAAS,SAAS;KAClB,UAAU,SAAS;KACnB,oBAAoB,SAAS;KAC7B,kBAAkB,SAAS;KAC5B;IACF,EACD,SACA,QACA,CAAC,MAAM,OAAsB,CAC9B;AAED,OAAI,SAAS,WAAW,YACtB,OAAM,IAAI,MAAM,sBAAsB;AAGxC,OAAI,SAAS,WAAW,WAAW,CAAC,SAAS,KAC3C,OAAM,IAAI,MAAM,SAAS,OAAO,WAAW,2BAA2B;AAGxE,UAAO,SAAS;YACR;AACR,QAAK,sBAAsB,OAAO,OAAO;;;;;;CAO7C,iBACE,OACA,SACwC;EACxC,MAAM,SAAS,uBAAuB;AAItC,SAAO;GACL,SAHc,KAAK,MAAM,OAAO;IAAE,GAAG;IAAS;IAAQ,CAAsC;GAI5F;GACA,cAAc,KAAK,OAAO,OAAO;GAClC;;;;;;;;;CAUH,MAAM,YAAY,YAAoB,SAAsD;AAC1F,QAAM,KAAK,oBAAoB;EAE/B,MAAM,SAAS,uBAAuB;EACtC,MAAM,UAAU,SAAS,WAAW,KAAK,SAAS;AAGlD,MAAI,SAAS,WACX,MAAK,sBAAsB,IAAI,QAAQ,QAAQ,WAAW;AAG5D,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,aAC1B,eACA;IACE;IACA;IACA,aAAa,SAAS;IACtB,kBAAkB,SAAS;IAC5B,EACD,SACA,OACD;AAED,OAAI,SAAS,WAAW,YACtB,OAAM,IAAI,MAAM,sBAAsB;AAGxC,OAAI,SAAS,WAAW,WAAW,CAAC,SAAS,KAC3C,OAAM,IAAI,MAAM,SAAS,OAAO,WAAW,yBAAyB;AAGtE,UAAO,SAAS;YACR;AACR,QAAK,sBAAsB,OAAO,OAAO;;;;;;;;;CAU7C,MAAM,OAAO,QAAkC;AAC7C,MAAI,CAAC,KAAK,QACR,QAAO;AAGT,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,aAC1B,iBACA,EAAE,QAAQ,EACV,IACD;AAED,UAAO,SAAS,WAAW,aAAa,SAAS,MAAM;UACjD;AACN,UAAO;;;CAQX,MAAc,qBAAoC;AAChD,MAAI,KAAK,WAAW,aAClB,OAAM,IAAI,MAAM,6BAA6B;AAG/C,MAAI,CAAC,KAAK,QACR,OAAM,KAAK,YAAY;;CAI3B,AAAQ,aACN,aACA,MACA,SACA,QACA,eACY;AACZ,MAAI,KAAK,WAAW,aAClB,QAAO,QAAQ,uBAAO,IAAI,MAAM,6BAA6B,CAAC;AAGhE,MAAI,CAAC,KAAK,QACR,QAAO,QAAQ,uBAAO,IAAI,MAAM,yBAAyB,CAAC;EAG5D,MAAM,YAAY,mBAAmB;EACrC,MAAM,eAAe,UAAU,gBAAgB;EAC/C,MAAM,WAAW,gBAAmB;EAGpC,MAAM,YAAY,iBAAiB;GACjC,MAAMC,YAAU,KAAK,iBAAiB,IAAI,UAAU;AACpD,OAAIA,WAAS;AACX,SAAK,iBAAiB,OAAO,UAAU;AACvC,SAAK,kBAAkB;AACvB,cAAQ,SAAS,uBAAO,IAAI,MAAM,yBAAyB,QAAQ,MAAM,cAAc,CAAC;;KAEzF,QAAQ;EAGX,MAAMC,UAA6B;GACjC;GACA,QAAQ;GACR;GACA;GACD;AAED,OAAK,iBAAiB,IAAI,WAAW,QAAmC;AAGxE,MAAI,KAAK,WAAW,QAClB,MAAK,UAAU,OAAO;EAIxB,MAAM,UAAU;GACd,MAAM;GACN,IAAI;GACJ;GACA;GACD;AAED,MAAI;AACF,OAAI,iBAAiB,cAAc,SAAS,EAC1C,MAAK,QAAQ,YAAY,SAAS,cAAc;OAEhD,MAAK,QAAQ,YAAY,QAAQ;WAE5B,OAAO;AACd,gBAAa,UAAU;AACvB,QAAK,iBAAiB,OAAO,UAAU;AACvC,QAAK,kBAAkB;AACvB,UAAO,QAAQ,OAAO,MAAM;;AAG9B,SAAO,SAAS;;CAGlB,AAAQ,eAAe,OAA2B;EAChD,MAAM,UAAU,MAAM;AAEtB,MAAI,kBAAkB,QAAQ,CAC5B,MAAK,gBAAgB,QAAQ;WACpB,kBAAkB,QAAQ,CACnC,MAAK,gBAAgB,QAAQ;WACpB,OAAO,YAAY,YAAY,YAAY,QAAQ,UAAU,SAEtE;OAAK,QAA6B,SAAS,WACzC,MAAK,gBAAgB,QAAiC;;;CAK5D,AAAQ,gBAAgB,UAAuC;EAC7D,MAAM,UAAU,KAAK,iBAAiB,IAAI,SAAS,GAAG;AACtD,MAAI,CAAC,QACH;AAGF,MAAI,QAAQ,UACV,cAAa,QAAQ,UAAU;AAGjC,OAAK,iBAAiB,OAAO,SAAS,GAAG;AACzC,OAAK,kBAAkB;AAEvB,MAAI,SAAS,WAAW,WAAW,SAAS,MAC1C,SAAQ,SAAS,OAAO,IAAI,MAAM,SAAS,MAAM,QAAQ,CAAC;MAE1D,SAAQ,SAAS,QAAQ,SAAS;;CAItC,AAAQ,gBAAgB,UAAwC;EAE9D,MAAM,cAAc,KAAK,sBAAsB,IAAI,SAAS,OAAO;AACnE,MAAI,YACF,aAAY,SAAS,SAAS;AAIhC,MAAI,KAAK,SAAS,WAChB,MAAK,SAAS,WAAW,SAAS,SAAS;;CAI/C,AAAQ,aAAa,OAAyB;EAC5C,MAAMC,QAA4B;GAChC,MAAM;GACN,SAAS,MAAM,WAAW;GAC1B,aAAa;GACd;AAED,MAAI,KAAK,SAAS,QAChB,MAAK,SAAS,QAAQ,MAAM;AAI9B,MAAI,KAAK,WAAW,gBAAgB;AAClC,QAAK,MAAM,WAAW,KAAK,iBAAiB,QAAQ,EAAE;AACpD,QAAI,QAAQ,UACV,cAAa,QAAQ,UAAU;AAEjC,YAAQ,SAAS,OAAO,IAAI,MAAM,MAAM,QAAQ,CAAC;;AAEnD,QAAK,iBAAiB,OAAO;AAC7B,QAAK,UAAU,QAAQ;;;CAI3B,AAAQ,mBAAyB;AAC/B,MAAI,KAAK,WAAW,UAAU,KAAK,iBAAiB,SAAS,EAC3D,MAAK,UAAU,QAAQ;;CAI3B,AAAQ,UAAU,UAAoC;EACpD,MAAM,gBAAgB,KAAK;AAC3B,MAAI,kBAAkB,SACpB;AAGF,OAAK,SAAS;AAEd,MAAI,KAAK,SAAS,cAChB,MAAK,SAAS,cAAc,UAAU,cAAc;;;;;;AAY1D,SAAgB,wBAAwB,SAAsD;AAC5F,QAAO,IAAI,kBAAkB,QAAQ"}
|
package/package.json
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dvvebond/core",
|
|
3
|
+
"version": "0.2.12",
|
|
4
|
+
"description": "A modern PDF library for TypeScript - parsing and generation",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"digital-signature",
|
|
7
|
+
"document",
|
|
8
|
+
"esign",
|
|
9
|
+
"generator",
|
|
10
|
+
"parser",
|
|
11
|
+
"pdf",
|
|
12
|
+
"pkcs7",
|
|
13
|
+
"signing",
|
|
14
|
+
"typescript"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://libpdf.dev",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/LibPDF-js/core/issues"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Lucas Smith",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/LibPDF-js/core.git"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"LICENSE.md",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"main": "./dist/index.mjs",
|
|
34
|
+
"module": "./dist/index.mjs",
|
|
35
|
+
"types": "./dist/index.d.mts",
|
|
36
|
+
"imports": {
|
|
37
|
+
"#src/*": "./src/*"
|
|
38
|
+
},
|
|
39
|
+
"exports": {
|
|
40
|
+
".": {
|
|
41
|
+
"types": "./dist/index.d.mts",
|
|
42
|
+
"import": "./dist/index.mjs",
|
|
43
|
+
"default": "./dist/index.mjs"
|
|
44
|
+
},
|
|
45
|
+
"./package.json": "./package.json"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"bench": "vitest bench",
|
|
52
|
+
"bench:report": "bun run scripts/bench-report.ts",
|
|
53
|
+
"build": "tsdown",
|
|
54
|
+
"demo": "bun --hot demo/index.html",
|
|
55
|
+
"demo:serve": "bunx serve demo",
|
|
56
|
+
"demo2": "bun --hot demo2/index.html",
|
|
57
|
+
"demo2:serve": "bunx serve demo2",
|
|
58
|
+
"docs:build": "bun run --cwd apps/docs build",
|
|
59
|
+
"docs:dev": "bun run --cwd apps/docs dev",
|
|
60
|
+
"examples": "bun run examples/run-all.ts",
|
|
61
|
+
"examples:quiet": "bun run examples/run-all.ts --quiet",
|
|
62
|
+
"format": "oxfmt",
|
|
63
|
+
"lint": "oxlint --type-aware && oxfmt --check",
|
|
64
|
+
"lint:fix": "oxlint --type-aware --fix && oxfmt",
|
|
65
|
+
"prepare": "echo skip-prepare",
|
|
66
|
+
"prepublishOnly": "bun run build",
|
|
67
|
+
"release": "./scripts/release.sh",
|
|
68
|
+
"test": "bun --env-file=.env.local vitest",
|
|
69
|
+
"test:coverage": "bun --env-file=.env.local vitest run --coverage",
|
|
70
|
+
"test:run": "bun --env-file=.env.local vitest run",
|
|
71
|
+
"typecheck": "tsc --noEmit"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"@noble/ciphers": "^2.1.1",
|
|
75
|
+
"@noble/hashes": "^2.0.1",
|
|
76
|
+
"@scure/base": "^2.0.0",
|
|
77
|
+
"asn1js": "^3.0.7",
|
|
78
|
+
"lru-cache": "^11.2.6",
|
|
79
|
+
"pako": "^2.1.0",
|
|
80
|
+
"pdfjs-dist": "^4.8.69",
|
|
81
|
+
"pkijs": "^3.3.3"
|
|
82
|
+
},
|
|
83
|
+
"devDependencies": {
|
|
84
|
+
"@cantoo/pdf-lib": "^2.6.1",
|
|
85
|
+
"@google-cloud/kms": "^5.0.0",
|
|
86
|
+
"@google-cloud/secret-manager": "^6.0.0",
|
|
87
|
+
"@types/bun": "^1.3.5",
|
|
88
|
+
"@types/pako": "^2.0.4",
|
|
89
|
+
"@types/react": "^18.2.0",
|
|
90
|
+
"@types/react-dom": "^18.2.0",
|
|
91
|
+
"@vitest/coverage-v8": "4.0.16",
|
|
92
|
+
"husky": "^9.1.7",
|
|
93
|
+
"lint-staged": "^16.2.7",
|
|
94
|
+
"oxfmt": "^0.24.0",
|
|
95
|
+
"oxlint": "^1.56.0",
|
|
96
|
+
"oxlint-tsgolint": "^0.17.0",
|
|
97
|
+
"pdf-lib": "^1.17.1",
|
|
98
|
+
"react": "^18.3.1",
|
|
99
|
+
"react-dom": "^18.3.1",
|
|
100
|
+
"tsdown": "^0.18.4",
|
|
101
|
+
"typescript": "^5",
|
|
102
|
+
"vitest": "^4.0.16"
|
|
103
|
+
},
|
|
104
|
+
"peerDependencies": {
|
|
105
|
+
"@google-cloud/kms": "^5.0.0",
|
|
106
|
+
"@google-cloud/secret-manager": "^6.0.0",
|
|
107
|
+
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
108
|
+
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
109
|
+
},
|
|
110
|
+
"peerDependenciesMeta": {
|
|
111
|
+
"@google-cloud/kms": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
114
|
+
"@google-cloud/secret-manager": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
117
|
+
"react": {
|
|
118
|
+
"optional": true
|
|
119
|
+
},
|
|
120
|
+
"react-dom": {
|
|
121
|
+
"optional": true
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"engines": {
|
|
125
|
+
"node": ">=20"
|
|
126
|
+
}
|
|
127
|
+
}
|