@embedpdf/plugin-document-manager 2.0.0-next.3 → 2.0.1
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/types.d.ts +1 -0
- package/dist/svelte/index.cjs.map +1 -1
- package/dist/svelte/index.js.map +1 -1
- package/dist/vue/components/document-content.vue.d.ts +4 -4
- package/dist/vue/components/document-context.vue.d.ts +3 -3
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/models"),o=class extends e.BasePlugin{constructor(t,o,n){super(t,o),this.id=t,this.documentOpened$=e.createBehaviorEmitter(),this.documentClosed$=e.createBehaviorEmitter(),this.activeDocumentChanged$=e.createBehaviorEmitter(),this.documentError$=e.createBehaviorEmitter(),this.documentOrderChanged$=e.createBehaviorEmitter(),this.openFileRequest$=e.createEmitter(),this.loadOptions=new Map,this.maxDocuments=null==n?void 0:n.maxDocuments}buildCapability(){return{openFileDialog:e=>this.openFileDialog(e),openDocumentUrl:e=>this.openDocumentUrl(e),openDocumentBuffer:e=>this.openDocumentBuffer(e),retryDocument:(e,t)=>this.retryDocument(e,t),closeDocument:e=>this.closeDocument(e),closeAllDocuments:()=>this.closeAllDocuments(),setActiveDocument:t=>{if(!this.isDocumentOpen(t))throw new Error(`Cannot set active document: ${t} is not open`);this.dispatchCoreAction(e.setActiveDocument(t))},getActiveDocumentId:()=>this.coreState.core.activeDocumentId,getActiveDocument:()=>{var e;const t=this.coreState.core.activeDocumentId;return t?(null==(e=this.coreState.core.documents[t])?void 0:e.document)??null:null},getDocumentOrder:()=>this.coreState.core.documentOrder,moveDocument:(t,o)=>{this.dispatchCoreAction(e.moveDocument(t,o))},swapDocuments:(t,o)=>{const n=this.coreState.core.documentOrder,r=n.indexOf(t),s=n.indexOf(o);if(-1===r||-1===s)throw new Error("One or both documents not found in order");const c=[...n];[c[r],c[s]]=[c[s],c[r]],this.dispatchCoreAction(e.reorderDocuments(c))},getDocument:e=>{var t;return(null==(t=this.coreState.core.documents[e])?void 0:t.document)??null},getDocumentState:e=>this.coreState.core.documents[e]??null,getOpenDocuments:()=>this.coreState.core.documentOrder.map(e=>this.coreState.core.documents[e]).filter(e=>null!==e),isDocumentOpen:e=>this.isDocumentOpen(e),getDocumentCount:()=>Object.keys(this.coreState.core.documents).length,getDocumentIndex:e=>this.coreState.core.documentOrder.indexOf(e),onDocumentOpened:this.documentOpened$.on,onDocumentClosed:this.documentClosed$.on,onDocumentError:this.documentError$.on,onActiveDocumentChanged:this.activeDocumentChanged$.on,onDocumentOrderChanged:this.documentOrderChanged$.on}}isDocumentOpen(e){return!!this.coreState.core.documents[e]}onDocumentLoaded(e){const t=this.coreState.core.documents[e];t&&"loaded"===t.status&&(this.loadOptions.delete(e),this.documentOpened$.emit(t),this.logger.info("DocumentManagerPlugin","DocumentOpened",`Document ${e} opened successfully`,{name:t.name}))}onDocumentClosed(e){this.loadOptions.delete(e),this.documentClosed$.emit(e),this.logger.info("DocumentManagerPlugin","DocumentClosed",`Document ${e} closed`)}onActiveDocumentChanged(e,t){this.activeDocumentChanged$.emit({previousDocumentId:e,currentDocumentId:t}),this.logger.info("DocumentManagerPlugin","ActiveDocumentChanged",`Active document changed from ${e} to ${t}`)}onCoreStoreUpdated(e,t){e.core.documentOrder!==t.core.documentOrder&&this.documentOrderChanged$.emit({order:t.core.documentOrder})}onOpenFileRequest(e){return this.openFileRequest$.on(e)}openDocumentUrl(o){const n=new t.Task,r=o.documentId||this.generateDocumentId(),s=this.checkDocumentLimit();if(s)return n.reject(s),n;const c=this.extractNameFromUrl(o.url);this.loadOptions.set(r,o),this.dispatchCoreAction(e.startLoadingDocument(r,c,o.scale,o.rotation,!!o.password,o.autoActivate)),this.logger.info("DocumentManagerPlugin","OpenDocumentUrl",`Starting to load document from URL: ${o.url}`,{documentId:r,passwordProvided:!!o.password});const i={id:r,url:o.url},
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),t=require("@embedpdf/models"),o=class extends e.BasePlugin{constructor(t,o,n){super(t,o),this.id=t,this.documentOpened$=e.createBehaviorEmitter(),this.documentClosed$=e.createBehaviorEmitter(),this.activeDocumentChanged$=e.createBehaviorEmitter(),this.documentError$=e.createBehaviorEmitter(),this.documentOrderChanged$=e.createBehaviorEmitter(),this.openFileRequest$=e.createEmitter(),this.loadOptions=new Map,this.maxDocuments=null==n?void 0:n.maxDocuments}buildCapability(){return{openFileDialog:e=>this.openFileDialog(e),openDocumentUrl:e=>this.openDocumentUrl(e),openDocumentBuffer:e=>this.openDocumentBuffer(e),retryDocument:(e,t)=>this.retryDocument(e,t),closeDocument:e=>this.closeDocument(e),closeAllDocuments:()=>this.closeAllDocuments(),setActiveDocument:t=>{if(!this.isDocumentOpen(t))throw new Error(`Cannot set active document: ${t} is not open`);this.dispatchCoreAction(e.setActiveDocument(t))},getActiveDocumentId:()=>this.coreState.core.activeDocumentId,getActiveDocument:()=>{var e;const t=this.coreState.core.activeDocumentId;return t?(null==(e=this.coreState.core.documents[t])?void 0:e.document)??null:null},getDocumentOrder:()=>this.coreState.core.documentOrder,moveDocument:(t,o)=>{this.dispatchCoreAction(e.moveDocument(t,o))},swapDocuments:(t,o)=>{const n=this.coreState.core.documentOrder,r=n.indexOf(t),s=n.indexOf(o);if(-1===r||-1===s)throw new Error("One or both documents not found in order");const c=[...n];[c[r],c[s]]=[c[s],c[r]],this.dispatchCoreAction(e.reorderDocuments(c))},getDocument:e=>{var t;return(null==(t=this.coreState.core.documents[e])?void 0:t.document)??null},getDocumentState:e=>this.coreState.core.documents[e]??null,getOpenDocuments:()=>this.coreState.core.documentOrder.map(e=>this.coreState.core.documents[e]).filter(e=>null!==e),isDocumentOpen:e=>this.isDocumentOpen(e),getDocumentCount:()=>Object.keys(this.coreState.core.documents).length,getDocumentIndex:e=>this.coreState.core.documentOrder.indexOf(e),onDocumentOpened:this.documentOpened$.on,onDocumentClosed:this.documentClosed$.on,onDocumentError:this.documentError$.on,onActiveDocumentChanged:this.activeDocumentChanged$.on,onDocumentOrderChanged:this.documentOrderChanged$.on}}isDocumentOpen(e){return!!this.coreState.core.documents[e]}onDocumentLoaded(e){const t=this.coreState.core.documents[e];t&&"loaded"===t.status&&(this.loadOptions.delete(e),this.documentOpened$.emit(t),this.logger.info("DocumentManagerPlugin","DocumentOpened",`Document ${e} opened successfully`,{name:t.name}))}onDocumentClosed(e){this.loadOptions.delete(e),this.documentClosed$.emit(e),this.logger.info("DocumentManagerPlugin","DocumentClosed",`Document ${e} closed`)}onActiveDocumentChanged(e,t){this.activeDocumentChanged$.emit({previousDocumentId:e,currentDocumentId:t}),this.logger.info("DocumentManagerPlugin","ActiveDocumentChanged",`Active document changed from ${e} to ${t}`)}onCoreStoreUpdated(e,t){e.core.documentOrder!==t.core.documentOrder&&this.documentOrderChanged$.emit({order:t.core.documentOrder})}onOpenFileRequest(e){return this.openFileRequest$.on(e)}openDocumentUrl(o){const n=new t.Task,r=o.documentId||this.generateDocumentId(),s=this.checkDocumentLimit();if(s)return n.reject(s),n;const c=o.name??this.extractNameFromUrl(o.url);this.loadOptions.set(r,o),this.dispatchCoreAction(e.startLoadingDocument(r,c,o.scale,o.rotation,!!o.password,o.autoActivate)),this.logger.info("DocumentManagerPlugin","OpenDocumentUrl",`Starting to load document from URL: ${o.url}`,{documentId:r,passwordProvided:!!o.password});const i={id:r,url:o.url},a=this.engine.openDocumentUrl(i,{password:o.password,mode:o.mode,requestOptions:o.requestOptions});return n.resolve({documentId:r,task:a}),this.handleLoadTask(r,a,"OpenDocumentUrl"),n}openDocumentBuffer(o){const n=new t.Task,r=this.checkDocumentLimit();if(r)return n.reject(r),n;const s=o.documentId||this.generateDocumentId();this.loadOptions.set(s,o),this.dispatchCoreAction(e.startLoadingDocument(s,o.name,o.scale,o.rotation,!!o.password,o.autoActivate)),this.logger.info("DocumentManagerPlugin","OpenDocumentBuffer",`Starting to load document from buffer: ${o.name}`,{documentId:s,passwordProvided:!!o.password});const c={id:s,content:o.buffer},i=this.engine.openDocumentBuffer(c,{password:o.password});return n.resolve({documentId:s,task:i}),this.handleLoadTask(s,i,"OpenDocumentBuffer"),n}retryDocument(o,n){const r=new t.Task,s=this.validateRetry(o);if(!s.valid)return r.reject(s.error),r;const c={...this.loadOptions.get(o),...(null==n?void 0:n.password)&&{password:n.password}};this.loadOptions.set(o,c),this.dispatchCoreAction(e.retryLoadingDocument(o,!!(null==n?void 0:n.password))),this.logger.info("DocumentManagerPlugin","RetryDocument",`Retrying to load document ${o}`,{passwordProvided:!!(null==n?void 0:n.password)});const i="url"in c?this.retryUrlDocument(o,c):this.retryBufferDocument(o,c);return r.resolve({documentId:o,task:i}),this.handleLoadTask(o,i,"RetryDocument"),r}openFileDialog(e){const o=new t.Task;return this.openFileRequest$.emit({task:o,options:e}),o}closeDocument(o){const n=new t.Task,r=this.coreState.core.documents[o];return r?("loaded"===r.status&&r.document?this.engine.closeDocument(r.document).wait(()=>{this.dispatchCoreAction(e.closeDocument(o)),n.resolve()},e=>{this.logger.error("DocumentManagerPlugin","CloseDocument",`Failed to close document ${o}`,e),n.fail(e)}):(this.logger.info("DocumentManagerPlugin","CloseDocument",`Closing document ${o} in ${r.status} state (skipping engine close)`),this.dispatchCoreAction(e.closeDocument(o)),n.resolve()),n):(this.logger.warn("DocumentManagerPlugin","CloseDocument",`Cannot close document ${o}: not found in state`),n.resolve(),n)}closeAllDocuments(){const e=Object.keys(this.coreState.core.documents),o=e.map(e=>this.closeDocument(e));return this.logger.info("DocumentManagerPlugin","CloseAllDocuments",`Closing ${e.length} documents`),t.Task.all(o)}checkDocumentLimit(){return this.maxDocuments&&Object.keys(this.coreState.core.documents).length>=this.maxDocuments?{code:t.PdfErrorCode.Unknown,message:`Maximum number of documents (${this.maxDocuments}) reached`}:null}validateRetry(e){const o=this.coreState.core.documents[e];return o?"loaded"===o.status?{valid:!1,error:{code:t.PdfErrorCode.Unknown,message:`Document ${e} is already loaded successfully`}}:"error"!==o.status?{valid:!1,error:{code:t.PdfErrorCode.Unknown,message:`Document ${e} is not in error state (current state: ${o.status})`}}:this.loadOptions.has(e)?{valid:!0}:{valid:!1,error:{code:t.PdfErrorCode.Unknown,message:`No retry information available for document ${e}`}}:{valid:!1,error:{code:t.PdfErrorCode.NotFound,message:`Document ${e} not found`}}}retryUrlDocument(e,t){const o={id:e,url:t.url};return this.engine.openDocumentUrl(o,{password:t.password,mode:t.mode,requestOptions:t.requestOptions})}retryBufferDocument(e,t){const o={id:e,content:t.buffer};return this.engine.openDocumentBuffer(o,{password:t.password})}handleLoadTask(t,o,n){o.wait(o=>{this.dispatchCoreAction(e.setDocumentLoaded(t,o))},e=>{this.handleLoadError(t,e,n)})}handleLoadError(t,o,n){var r,s,c;const i=(null==(r=o.reason)?void 0:r.message)||"Failed to load document";this.logger.error("DocumentManagerPlugin",n,"Failed to load document",o),this.dispatchCoreAction(e.setDocumentError(t,i,null==(s=o.reason)?void 0:s.code,o.reason)),this.documentError$.emit({documentId:t,message:i,code:null==(c=o.reason)?void 0:c.code,reason:o.reason})}generateDocumentId(){return`doc-${Date.now()}-${Math.random().toString(36).substr(2,9)}`}extractNameFromUrl(e){try{const t=new URL(e),o=t.pathname.split("/").pop();if(!o)return;let n=decodeURIComponent(o);return n.toLowerCase().endsWith(".pdf")||(n+=".pdf"),n}catch{return}}async initialize(e){var t;if(this.logger.info("DocumentManagerPlugin","Initialize","Document Manager Plugin initialized",{maxDocuments:this.maxDocuments,initialDocumentsCount:(null==(t=e.initialDocuments)?void 0:t.length)??0}),e.initialDocuments&&e.initialDocuments.length>0)for(const n of e.initialDocuments)try{"buffer"in n?this.openDocumentBuffer(n):"url"in n&&this.openDocumentUrl(n)}catch(o){this.logger.error("DocumentManagerPlugin","Initialize","Failed to initiate initial document load",o)}}async destroy(){await this.closeAllDocuments().toPromise(),this.loadOptions.clear(),this.documentOpened$.clear(),this.documentClosed$.clear(),this.activeDocumentChanged$.clear(),this.documentOrderChanged$.clear(),this.documentError$.clear(),super.destroy()}};o.id="document-manager";let n=o;const r="document-manager",s={id:r,name:"Document Manager Plugin",version:"1.0.0",provides:["document-manager"],requires:[],optional:[],defaultConfig:{maxDocuments:10}},c={manifest:s,create:(e,t)=>new n(r,e,t),reducer:e=>e,initialState:{}};exports.DOCUMENT_MANAGER_PLUGIN_ID=r,exports.DocumentManagerPlugin=n,exports.DocumentManagerPluginPackage=c,exports.manifest=s;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/lib/document-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts"],"sourcesContent":["import {\n BasePlugin,\n PluginRegistry,\n createBehaviorEmitter,\n startLoadingDocument,\n setDocumentLoaded,\n setDocumentError,\n retryLoadingDocument,\n closeDocument as closeDocumentAction,\n setActiveDocument as setActiveDocumentAction,\n moveDocument as moveDocumentAction,\n reorderDocuments as reorderDocumentsAction,\n DocumentState,\n Unsubscribe,\n Listener,\n createEmitter,\n} from '@embedpdf/core';\nimport {\n PdfDocumentObject,\n Task,\n PdfFile,\n PdfFileUrl,\n PdfErrorReason,\n PdfErrorCode,\n} from '@embedpdf/models';\n\nimport {\n DocumentManagerPluginConfig,\n DocumentManagerCapability,\n DocumentChangeEvent,\n DocumentOrderChangeEvent,\n LoadDocumentUrlOptions,\n LoadDocumentBufferOptions,\n RetryOptions,\n DocumentErrorEvent,\n OpenDocumentResponse,\n OpenFileDialogOptions,\n} from './types';\n\nexport class DocumentManagerPlugin extends BasePlugin<\n DocumentManagerPluginConfig,\n DocumentManagerCapability\n> {\n static readonly id = 'document-manager' as const;\n\n private readonly documentOpened$ = createBehaviorEmitter<DocumentState>();\n private readonly documentClosed$ = createBehaviorEmitter<string>();\n private readonly activeDocumentChanged$ = createBehaviorEmitter<DocumentChangeEvent>();\n private readonly documentError$ = createBehaviorEmitter<DocumentErrorEvent>();\n\n private readonly documentOrderChanged$ = createBehaviorEmitter<DocumentOrderChangeEvent>();\n\n private readonly openFileRequest$ = createEmitter<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>();\n\n private maxDocuments?: number;\n\n private loadOptions = new Map<string, LoadDocumentUrlOptions | LoadDocumentBufferOptions>();\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n config?: DocumentManagerPluginConfig,\n ) {\n super(id, registry);\n this.maxDocuments = config?.maxDocuments;\n }\n\n protected buildCapability(): DocumentManagerCapability {\n return {\n // Document lifecycle - orchestration only\n openFileDialog: (options) => this.openFileDialog(options),\n openDocumentUrl: (options) => this.openDocumentUrl(options),\n openDocumentBuffer: (options) => this.openDocumentBuffer(options),\n retryDocument: (documentId, options) => this.retryDocument(documentId, options),\n closeDocument: (documentId) => this.closeDocument(documentId),\n closeAllDocuments: () => this.closeAllDocuments(),\n\n setActiveDocument: (documentId) => {\n if (!this.isDocumentOpen(documentId)) {\n throw new Error(`Cannot set active document: ${documentId} is not open`);\n }\n this.dispatchCoreAction(setActiveDocumentAction(documentId));\n },\n\n getActiveDocumentId: () => this.coreState.core.activeDocumentId,\n getActiveDocument: () => {\n const activeId = this.coreState.core.activeDocumentId;\n if (!activeId) return null;\n return this.coreState.core.documents[activeId]?.document ?? null;\n },\n\n getDocumentOrder: () => this.coreState.core.documentOrder,\n\n moveDocument: (documentId, toIndex) => {\n this.dispatchCoreAction(moveDocumentAction(documentId, toIndex));\n },\n\n swapDocuments: (id1, id2) => {\n const order = this.coreState.core.documentOrder;\n const index1 = order.indexOf(id1);\n const index2 = order.indexOf(id2);\n\n if (index1 === -1 || index2 === -1) {\n throw new Error('One or both documents not found in order');\n }\n\n const newOrder = [...order];\n [newOrder[index1], newOrder[index2]] = [newOrder[index2], newOrder[index1]];\n\n this.dispatchCoreAction(reorderDocumentsAction(newOrder));\n },\n\n getDocument: (documentId) => {\n return this.coreState.core.documents[documentId]?.document ?? null;\n },\n\n getDocumentState: (documentId) => {\n return this.coreState.core.documents[documentId] ?? null;\n },\n\n getOpenDocuments: () => {\n return this.coreState.core.documentOrder\n .map((documentId) => this.coreState.core.documents[documentId])\n .filter((state): state is DocumentState => state !== null);\n },\n\n isDocumentOpen: (documentId) => this.isDocumentOpen(documentId),\n\n getDocumentCount: () => {\n return Object.keys(this.coreState.core.documents).length;\n },\n\n getDocumentIndex: (documentId) => {\n return this.coreState.core.documentOrder.indexOf(documentId);\n },\n\n // Events\n onDocumentOpened: this.documentOpened$.on,\n onDocumentClosed: this.documentClosed$.on,\n onDocumentError: this.documentError$.on,\n onActiveDocumentChanged: this.activeDocumentChanged$.on,\n onDocumentOrderChanged: this.documentOrderChanged$.on,\n };\n }\n\n /**\n * Check if a document is currently open\n */\n private isDocumentOpen(documentId: string): boolean {\n return !!this.coreState.core.documents[documentId];\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Lifecycle Hooks (from BasePlugin)\n // ─────────────────────────────────────────────────────────\n\n protected override onDocumentLoaded(documentId: string): void {\n const docState = this.coreState.core.documents[documentId];\n if (!docState || docState.status !== 'loaded') return;\n\n // Clean up load options to free memory\n this.loadOptions.delete(documentId);\n\n // Emit opened event\n this.documentOpened$.emit(docState);\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'DocumentOpened',\n `Document ${documentId} opened successfully`,\n { name: docState.name },\n );\n }\n\n protected override onDocumentClosed(documentId: string): void {\n // Clean up load options\n this.loadOptions.delete(documentId);\n\n // Emit closed event\n this.documentClosed$.emit(documentId);\n\n this.logger.info('DocumentManagerPlugin', 'DocumentClosed', `Document ${documentId} closed`);\n }\n\n protected override onActiveDocumentChanged(\n previousId: string | null,\n currentId: string | null,\n ): void {\n this.activeDocumentChanged$.emit({\n previousDocumentId: previousId,\n currentDocumentId: currentId,\n });\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'ActiveDocumentChanged',\n `Active document changed from ${previousId} to ${currentId}`,\n );\n }\n\n protected override onCoreStoreUpdated(oldState: any, newState: any): void {\n // Emit order change event if order changed\n if (oldState.core.documentOrder !== newState.core.documentOrder) {\n this.documentOrderChanged$.emit({\n order: newState.core.documentOrder,\n });\n }\n }\n\n public onOpenFileRequest(\n handler: Listener<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>,\n ): Unsubscribe {\n return this.openFileRequest$.on(handler);\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Loading (orchestration only - no state management)\n // ─────────────────────────────────────────────────────────\n\n private openDocumentUrl(\n options: LoadDocumentUrlOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Check limit\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentName = this.extractNameFromUrl(options.url);\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n documentName,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentUrl',\n `Starting to load document from URL: ${options.url}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n const engineTask = this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentUrl');\n\n return task;\n }\n\n private openDocumentBuffer(\n options: LoadDocumentBufferOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n options.name,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentBuffer',\n `Starting to load document from buffer: ${options.name}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n const engineTask = this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentBuffer');\n\n return task;\n }\n\n private retryDocument(\n documentId: string,\n retryOptions?: RetryOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n // Validate retry\n const validation = this.validateRetry(documentId);\n if (!validation.valid) {\n task.reject(validation.error!);\n return task;\n }\n\n const originalOptions = this.loadOptions.get(documentId)!;\n\n // Merge retry options (e.g., new password)\n const mergedOptions = {\n ...originalOptions,\n ...(retryOptions?.password && { password: retryOptions.password }),\n };\n\n // Update stored options\n this.loadOptions.set(documentId, mergedOptions);\n\n // Set back to loading state\n this.dispatchCoreAction(retryLoadingDocument(documentId, !!retryOptions?.password));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'RetryDocument',\n `Retrying to load document ${documentId}`,\n { passwordProvided: !!retryOptions?.password },\n );\n\n // Execute retry based on type\n const engineTask =\n 'url' in mergedOptions\n ? this.retryUrlDocument(documentId, mergedOptions)\n : this.retryBufferDocument(documentId, mergedOptions);\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'RetryDocument');\n\n return task;\n }\n\n private openFileDialog(\n options?: OpenFileDialogOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n this.openFileRequest$.emit({ task, options });\n return task;\n }\n\n private closeDocument(documentId: string): Task<void, PdfErrorReason> {\n const task = new Task<void, PdfErrorReason>();\n\n const docState = this.coreState.core.documents[documentId];\n if (!docState) {\n this.logger.warn(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Cannot close document ${documentId}: not found in state`,\n );\n task.resolve();\n return task;\n }\n\n // ✅ SIMPLIFIED: Just dispatch - reducer calculates next active!\n if (docState.status === 'loaded' && docState.document) {\n this.engine.closeDocument(docState.document).wait(\n () => {\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n },\n (error) => {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Failed to close document ${documentId}`,\n error,\n );\n task.fail(error);\n },\n );\n } else {\n // Document is not loaded (error, loading, etc.), just clean up state\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Closing document ${documentId} in ${docState.status} state (skipping engine close)`,\n );\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n }\n\n return task;\n }\n\n private closeAllDocuments(): Task<void[], PdfErrorReason> {\n const documentIds = Object.keys(this.coreState.core.documents);\n const tasks = documentIds.map((documentId) => this.closeDocument(documentId));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseAllDocuments',\n `Closing ${documentIds.length} documents`,\n );\n\n return Task.all(tasks);\n }\n\n // ─────────────────────────────────────────────────────────\n // Helper Methods\n // ─────────────────────────────────────────────────────────\n\n private checkDocumentLimit(): PdfErrorReason | null {\n if (\n this.maxDocuments &&\n Object.keys(this.coreState.core.documents).length >= this.maxDocuments\n ) {\n return {\n code: PdfErrorCode.Unknown,\n message: `Maximum number of documents (${this.maxDocuments}) reached`,\n };\n }\n return null;\n }\n\n private validateRetry(documentId: string): {\n valid: boolean;\n error?: PdfErrorReason;\n } {\n const docState = this.coreState.core.documents[documentId];\n\n if (!docState) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.NotFound,\n message: `Document ${documentId} not found`,\n },\n };\n }\n\n if (docState.status === 'loaded') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is already loaded successfully`,\n },\n };\n }\n\n if (docState.status !== 'error') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is not in error state (current state: ${docState.status})`,\n },\n };\n }\n\n if (!this.loadOptions.has(documentId)) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `No retry information available for document ${documentId}`,\n },\n };\n }\n\n return { valid: true };\n }\n\n private retryUrlDocument(\n documentId: string,\n options: LoadDocumentUrlOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n\n return this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n }\n\n private retryBufferDocument(\n documentId: string,\n options: LoadDocumentBufferOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n\n return this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n }\n\n private handleLoadTask(\n documentId: string,\n engineTask: Task<PdfDocumentObject, PdfErrorReason>,\n context: string,\n ): void {\n engineTask.wait(\n (pdfDocument) => {\n this.dispatchCoreAction(setDocumentLoaded(documentId, pdfDocument));\n },\n (error) => {\n this.handleLoadError(documentId, error, context);\n },\n );\n }\n\n private handleLoadError(documentId: string, error: any, context: string): void {\n const errorMessage = error.reason?.message || 'Failed to load document';\n\n this.logger.error('DocumentManagerPlugin', context, 'Failed to load document', error);\n\n this.dispatchCoreAction(\n setDocumentError(documentId, errorMessage, error.reason?.code, error.reason),\n );\n\n this.documentError$.emit({\n documentId,\n message: errorMessage,\n code: error.reason?.code,\n reason: error.reason,\n });\n }\n\n private generateDocumentId(): string {\n return `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private extractNameFromUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname;\n const filename = pathname.split('/').pop() || 'document.pdf';\n return decodeURIComponent(filename);\n } catch {\n return 'document.pdf';\n }\n }\n\n // ─────────────────────────────────────────────────────────\n // Plugin Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(config: DocumentManagerPluginConfig): Promise<void> {\n this.logger.info('DocumentManagerPlugin', 'Initialize', 'Document Manager Plugin initialized', {\n maxDocuments: this.maxDocuments,\n initialDocumentsCount: config.initialDocuments?.length ?? 0,\n });\n\n // Handle initial documents from config\n if (config.initialDocuments && config.initialDocuments.length > 0) {\n // Process strictly in order\n for (const docConfig of config.initialDocuments) {\n try {\n // Type guard to distinguish between URL and Buffer options\n if ('buffer' in docConfig) {\n this.openDocumentBuffer(docConfig);\n } else if ('url' in docConfig) {\n this.openDocumentUrl(docConfig);\n }\n } catch (error) {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'Initialize',\n 'Failed to initiate initial document load',\n error,\n );\n }\n }\n }\n }\n\n async destroy(): Promise<void> {\n // Close all documents\n await this.closeAllDocuments().toPromise();\n\n // Clear load options\n this.loadOptions.clear();\n\n // Clear emitters\n this.documentOpened$.clear();\n this.documentClosed$.clear();\n this.activeDocumentChanged$.clear();\n this.documentOrderChanged$.clear();\n this.documentError$.clear();\n\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DOCUMENT_MANAGER_PLUGIN_ID = 'document-manager';\n\nexport const manifest: PluginManifest<DocumentManagerPluginConfig> = {\n id: DOCUMENT_MANAGER_PLUGIN_ID,\n name: 'Document Manager Plugin',\n version: '1.0.0',\n provides: ['document-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n maxDocuments: 10,\n },\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPlugin } from './document-manager-plugin';\nimport { manifest, DOCUMENT_MANAGER_PLUGIN_ID } from './manifest';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DocumentManagerPluginPackage: PluginPackage<\n DocumentManagerPlugin,\n DocumentManagerPluginConfig\n> = {\n manifest,\n create: (registry, config) =>\n new DocumentManagerPlugin(DOCUMENT_MANAGER_PLUGIN_ID, registry, config),\n reducer: (state) => state,\n initialState: {},\n};\n\nexport * from './document-manager-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["_DocumentManagerPlugin","BasePlugin","constructor","id","registry","config","super","this","documentOpened$","createBehaviorEmitter","documentClosed$","activeDocumentChanged$","documentError$","documentOrderChanged$","openFileRequest$","createEmitter","loadOptions","Map","maxDocuments","buildCapability","openFileDialog","options","openDocumentUrl","openDocumentBuffer","retryDocument","documentId","closeDocument","closeAllDocuments","setActiveDocument","isDocumentOpen","Error","dispatchCoreAction","setActiveDocumentAction","getActiveDocumentId","coreState","core","activeDocumentId","getActiveDocument","activeId","_a","documents","document","getDocumentOrder","documentOrder","moveDocument","toIndex","moveDocumentAction","swapDocuments","id1","id2","order","index1","indexOf","index2","newOrder","reorderDocumentsAction","getDocument","getDocumentState","getOpenDocuments","map","filter","state","getDocumentCount","Object","keys","length","getDocumentIndex","onDocumentOpened","on","onDocumentClosed","onDocumentError","onActiveDocumentChanged","onDocumentOrderChanged","onDocumentLoaded","docState","status","delete","emit","logger","info","name","previousId","currentId","previousDocumentId","currentDocumentId","onCoreStoreUpdated","oldState","newState","onOpenFileRequest","handler","task","Task","generateDocumentId","limitError","checkDocumentLimit","reject","documentName","extractNameFromUrl","url","set","startLoadingDocument","scale","rotation","password","autoActivate","passwordProvided","file","engineTask","engine","mode","requestOptions","resolve","handleLoadTask","content","buffer","retryOptions","validation","validateRetry","valid","error","mergedOptions","get","retryLoadingDocument","retryUrlDocument","retryBufferDocument","wait","closeDocumentAction","fail","warn","documentIds","tasks","all","code","PdfErrorCode","Unknown","message","has","NotFound","context","pdfDocument","setDocumentLoaded","handleLoadError","errorMessage","reason","setDocumentError","_b","_c","Date","now","Math","random","toString","substr","urlObj","URL","filename","pathname","split","pop","decodeURIComponent","initialize","initialDocumentsCount","initialDocuments","docConfig","destroy","toPromise","clear","DocumentManagerPlugin","DOCUMENT_MANAGER_PLUGIN_ID","manifest","version","provides","requires","optional","defaultConfig","DocumentManagerPluginPackage","create","reducer","initialState"],"mappings":"gJAuCaA,EAAN,cAAoCC,EAAAA,WAsBzC,WAAAC,CACkBC,EAChBC,EACAC,GAEAC,MAAMH,EAAIC,GAJMG,KAAAJ,GAAAA,EAjBlBI,KAAiBC,gBAAkBC,0BACnCF,KAAiBG,gBAAkBD,0BACnCF,KAAiBI,uBAAyBF,0BAC1CF,KAAiBK,eAAiBH,0BAElCF,KAAiBM,sBAAwBJ,0BAEzCF,KAAiBO,iBAAmBC,kBAOpCR,KAAQS,gBAAkBC,IAQxBV,KAAKW,aAAe,MAAAb,OAAA,EAAAA,EAAQa,YAC9B,CAEU,eAAAC,GACR,MAAO,CAELC,eAAiBC,GAAYd,KAAKa,eAAeC,GACjDC,gBAAkBD,GAAYd,KAAKe,gBAAgBD,GACnDE,mBAAqBF,GAAYd,KAAKgB,mBAAmBF,GACzDG,cAAe,CAACC,EAAYJ,IAAYd,KAAKiB,cAAcC,EAAYJ,GACvEK,cAAgBD,GAAelB,KAAKmB,cAAcD,GAClDE,kBAAmB,IAAMpB,KAAKoB,oBAE9BC,kBAAoBH,IAClB,IAAKlB,KAAKsB,eAAeJ,GACvB,MAAM,IAAIK,MAAM,+BAA+BL,iBAEjDlB,KAAKwB,mBAAmBC,oBAAwBP,KAGlDQ,oBAAqB,IAAM1B,KAAK2B,UAAUC,KAAKC,iBAC/CC,kBAAmB,WACjB,MAAMC,EAAW/B,KAAK2B,UAAUC,KAAKC,iBACrC,OAAKE,GACE,OAAAC,OAAKL,UAAUC,KAAKK,UAAUF,aAAWG,WAAY,KADtC,MAIxBC,iBAAkB,IAAMnC,KAAK2B,UAAUC,KAAKQ,cAE5CC,aAAc,CAACnB,EAAYoB,KACzBtC,KAAKwB,mBAAmBe,EAAAA,aAAmBrB,EAAYoB,KAGzDE,cAAe,CAACC,EAAKC,KACnB,MAAMC,EAAQ3C,KAAK2B,UAAUC,KAAKQ,cAC5BQ,EAASD,EAAME,QAAQJ,GACvBK,EAASH,EAAME,QAAQH,GAE7B,IAAe,IAAXE,IAA4B,IAAXE,EACnB,MAAM,IAAIvB,MAAM,4CAGlB,MAAMwB,EAAW,IAAIJ,IACpBI,EAASH,GAASG,EAASD,IAAW,CAACC,EAASD,GAASC,EAASH,IAEnE5C,KAAKwB,mBAAmBwB,mBAAuBD,KAGjDE,YAAc/B,UACZ,OAAO,OAAAc,OAAKL,UAAUC,KAAKK,UAAUf,aAAagB,WAAY,MAGhEgB,iBAAmBhC,GACVlB,KAAK2B,UAAUC,KAAKK,UAAUf,IAAe,KAGtDiC,iBAAkB,IACTnD,KAAK2B,UAAUC,KAAKQ,cACxBgB,IAAKlC,GAAelB,KAAK2B,UAAUC,KAAKK,UAAUf,IAClDmC,OAAQC,GAA4C,OAAVA,GAG/ChC,eAAiBJ,GAAelB,KAAKsB,eAAeJ,GAEpDqC,iBAAkB,IACTC,OAAOC,KAAKzD,KAAK2B,UAAUC,KAAKK,WAAWyB,OAGpDC,iBAAmBzC,GACVlB,KAAK2B,UAAUC,KAAKQ,cAAcS,QAAQ3B,GAInD0C,iBAAkB5D,KAAKC,gBAAgB4D,GACvCC,iBAAkB9D,KAAKG,gBAAgB0D,GACvCE,gBAAiB/D,KAAKK,eAAewD,GACrCG,wBAAyBhE,KAAKI,uBAAuByD,GACrDI,uBAAwBjE,KAAKM,sBAAsBuD,GAEvD,CAKQ,cAAAvC,CAAeJ,GACrB,QAASlB,KAAK2B,UAAUC,KAAKK,UAAUf,EACzC,CAMmB,gBAAAgD,CAAiBhD,GAClC,MAAMiD,EAAWnE,KAAK2B,UAAUC,KAAKK,UAAUf,GAC1CiD,GAAgC,WAApBA,EAASC,SAG1BpE,KAAKS,YAAY4D,OAAOnD,GAGxBlB,KAAKC,gBAAgBqE,KAAKH,GAE1BnE,KAAKuE,OAAOC,KACV,wBACA,iBACA,YAAYtD,wBACZ,CAAEuD,KAAMN,EAASM,OAErB,CAEmB,gBAAAX,CAAiB5C,GAElClB,KAAKS,YAAY4D,OAAOnD,GAGxBlB,KAAKG,gBAAgBmE,KAAKpD,GAE1BlB,KAAKuE,OAAOC,KAAK,wBAAyB,iBAAkB,YAAYtD,WAC1E,CAEmB,uBAAA8C,CACjBU,EACAC,GAEA3E,KAAKI,uBAAuBkE,KAAK,CAC/BM,mBAAoBF,EACpBG,kBAAmBF,IAGrB3E,KAAKuE,OAAOC,KACV,wBACA,wBACA,gCAAgCE,QAAiBC,IAErD,CAEmB,kBAAAG,CAAmBC,EAAeC,GAE/CD,EAASnD,KAAKQ,gBAAkB4C,EAASpD,KAAKQ,eAChDpC,KAAKM,sBAAsBgE,KAAK,CAC9B3B,MAAOqC,EAASpD,KAAKQ,eAG3B,CAEO,iBAAA6C,CACLC,GAKA,OAAOlF,KAAKO,iBAAiBsD,GAAGqB,EAClC,CAMQ,eAAAnE,CACND,GAEA,MAAMqE,EAAO,IAAIC,OAEXlE,EAAaJ,EAAQI,YAAclB,KAAKqF,qBAGxCC,EAAatF,KAAKuF,qBACxB,GAAID,EAEF,OADAH,EAAKK,OAAOF,GACLH,EAGT,MAAMM,EAAezF,KAAK0F,mBAAmB5E,EAAQ6E,KAGrD3F,KAAKS,YAAYmF,IAAI1E,EAAYJ,GAEjCd,KAAKwB,mBACHqE,EAAAA,qBACE3E,EACAuE,EACA3E,EAAQgF,MACRhF,EAAQiF,WACNjF,EAAQkF,SACVlF,EAAQmF,eAIZjG,KAAKuE,OAAOC,KACV,wBACA,kBACA,uCAAuC1D,EAAQ6E,MAC/C,CAAEzE,aAAYgF,mBAAoBpF,EAAQkF,WAI5C,MAAMG,EAAmB,CACvBvG,GAAIsB,EACJyE,IAAK7E,EAAQ6E,KAETS,EAAapG,KAAKqG,OAAOtF,gBAAgBoF,EAAM,CACnDH,SAAUlF,EAAQkF,SAClBM,KAAMxF,EAAQwF,KACdC,eAAgBzF,EAAQyF,iBAW1B,OARApB,EAAKqB,QAAQ,CACXtF,aACAiE,KAAMiB,IAIRpG,KAAKyG,eAAevF,EAAYkF,EAAY,mBAErCjB,CACT,CAEQ,kBAAAnE,CACNF,GAEA,MAAMqE,EAAO,IAAIC,OAEXE,EAAatF,KAAKuF,qBACxB,GAAID,EAEF,OADAH,EAAKK,OAAOF,GACLH,EAGT,MAAMjE,EAAaJ,EAAQI,YAAclB,KAAKqF,qBAG9CrF,KAAKS,YAAYmF,IAAI1E,EAAYJ,GAEjCd,KAAKwB,mBACHqE,EAAAA,qBACE3E,EACAJ,EAAQ2D,KACR3D,EAAQgF,MACRhF,EAAQiF,WACNjF,EAAQkF,SACVlF,EAAQmF,eAIZjG,KAAKuE,OAAOC,KACV,wBACA,qBACA,0CAA0C1D,EAAQ2D,OAClD,CAAEvD,aAAYgF,mBAAoBpF,EAAQkF,WAI5C,MAAMG,EAAgB,CACpBvG,GAAIsB,EACJwF,QAAS5F,EAAQ6F,QAEbP,EAAapG,KAAKqG,OAAOrF,mBAAmBmF,EAAM,CACtDH,SAAUlF,EAAQkF,WAWpB,OARAb,EAAKqB,QAAQ,CACXtF,aACAiE,KAAMiB,IAIRpG,KAAKyG,eAAevF,EAAYkF,EAAY,sBAErCjB,CACT,CAEQ,aAAAlE,CACNC,EACA0F,GAEA,MAAMzB,EAAO,IAAIC,OAGXyB,EAAa7G,KAAK8G,cAAc5F,GACtC,IAAK2F,EAAWE,MAEd,OADA5B,EAAKK,OAAOqB,EAAWG,OAChB7B,EAGT,MAGM8B,EAAgB,IAHEjH,KAAKS,YAAYyG,IAAIhG,OAKvC,MAAA0F,OAAA,EAAAA,EAAcZ,WAAY,CAAEA,SAAUY,EAAaZ,WAIzDhG,KAAKS,YAAYmF,IAAI1E,EAAY+F,GAGjCjH,KAAKwB,mBAAmB2F,uBAAqBjG,KAAc,MAAA0F,OAAA,EAAAA,EAAcZ,YAEzEhG,KAAKuE,OAAOC,KACV,wBACA,gBACA,6BAA6BtD,IAC7B,CAAEgF,0BAAoBU,WAAcZ,YAItC,MAAMI,EACJ,QAASa,EACLjH,KAAKoH,iBAAiBlG,EAAY+F,GAClCjH,KAAKqH,oBAAoBnG,EAAY+F,GAU3C,OARA9B,EAAKqB,QAAQ,CACXtF,aACAiE,KAAMiB,IAIRpG,KAAKyG,eAAevF,EAAYkF,EAAY,iBAErCjB,CACT,CAEQ,cAAAtE,CACNC,GAEA,MAAMqE,EAAO,IAAIC,OAEjB,OADApF,KAAKO,iBAAiB+D,KAAK,CAAEa,OAAMrE,YAC5BqE,CACT,CAEQ,aAAAhE,CAAcD,GACpB,MAAMiE,EAAO,IAAIC,OAEXjB,EAAWnE,KAAK2B,UAAUC,KAAKK,UAAUf,GAC/C,OAAKiD,GAWmB,WAApBA,EAASC,QAAuBD,EAASjC,SAC3ClC,KAAKqG,OAAOlF,cAAcgD,EAASjC,UAAUoF,KAC3C,KACEtH,KAAKwB,mBAAmB+F,gBAAoBrG,IAC5CiE,EAAKqB,WAENQ,IACChH,KAAKuE,OAAOyC,MACV,wBACA,gBACA,4BAA4B9F,IAC5B8F,GAEF7B,EAAKqC,KAAKR,MAKdhH,KAAKuE,OAAOC,KACV,wBACA,gBACA,oBAAoBtD,QAAiBiD,EAASC,wCAEhDpE,KAAKwB,mBAAmB+F,gBAAoBrG,IAC5CiE,EAAKqB,WAGArB,IArCLnF,KAAKuE,OAAOkD,KACV,wBACA,gBACA,yBAAyBvG,yBAE3BiE,EAAKqB,UACErB,EAgCX,CAEQ,iBAAA/D,GACN,MAAMsG,EAAclE,OAAOC,KAAKzD,KAAK2B,UAAUC,KAAKK,WAC9C0F,EAAQD,EAAYtE,IAAKlC,GAAelB,KAAKmB,cAAcD,IAQjE,OANAlB,KAAKuE,OAAOC,KACV,wBACA,oBACA,WAAWkD,EAAYhE,oBAGlB0B,EAAAA,KAAKwC,IAAID,EAClB,CAMQ,kBAAApC,GACN,OACEvF,KAAKW,cACL6C,OAAOC,KAAKzD,KAAK2B,UAAUC,KAAKK,WAAWyB,QAAU1D,KAAKW,aAEnD,CACLkH,KAAMC,EAAAA,aAAaC,QACnBC,QAAS,gCAAgChI,KAAKW,yBAG3C,IACT,CAEQ,aAAAmG,CAAc5F,GAIpB,MAAMiD,EAAWnE,KAAK2B,UAAUC,KAAKK,UAAUf,GAE/C,OAAKiD,EAUmB,WAApBA,EAASC,OACJ,CACL2C,OAAO,EACPC,MAAO,CACLa,KAAMC,EAAAA,aAAaC,QACnBC,QAAS,YAAY9G,qCAKH,UAApBiD,EAASC,OACJ,CACL2C,OAAO,EACPC,MAAO,CACLa,KAAMC,EAAAA,aAAaC,QACnBC,QAAS,YAAY9G,2CAAoDiD,EAASC,YAKnFpE,KAAKS,YAAYwH,IAAI/G,GAUnB,CAAE6F,OAAO,GATP,CACLA,OAAO,EACPC,MAAO,CACLa,KAAMC,EAAAA,aAAaC,QACnBC,QAAS,+CAA+C9G,MAlCrD,CACL6F,OAAO,EACPC,MAAO,CACLa,KAAMC,EAAAA,aAAaI,SACnBF,QAAS,YAAY9G,eAoC7B,CAEQ,gBAAAkG,CACNlG,EACAJ,GAEA,MAAMqF,EAAmB,CACvBvG,GAAIsB,EACJyE,IAAK7E,EAAQ6E,KAGf,OAAO3F,KAAKqG,OAAOtF,gBAAgBoF,EAAM,CACvCH,SAAUlF,EAAQkF,SAClBM,KAAMxF,EAAQwF,KACdC,eAAgBzF,EAAQyF,gBAE5B,CAEQ,mBAAAc,CACNnG,EACAJ,GAEA,MAAMqF,EAAgB,CACpBvG,GAAIsB,EACJwF,QAAS5F,EAAQ6F,QAGnB,OAAO3G,KAAKqG,OAAOrF,mBAAmBmF,EAAM,CAC1CH,SAAUlF,EAAQkF,UAEtB,CAEQ,cAAAS,CACNvF,EACAkF,EACA+B,GAEA/B,EAAWkB,KACRc,IACCpI,KAAKwB,mBAAmB6G,EAAAA,kBAAkBnH,EAAYkH,KAEvDpB,IACChH,KAAKsI,gBAAgBpH,EAAY8F,EAAOmB,IAG9C,CAEQ,eAAAG,CAAgBpH,EAAoB8F,EAAYmB,aACtD,MAAMI,GAAe,OAAAvG,EAAAgF,EAAMwB,aAAN,EAAAxG,EAAcgG,UAAW,0BAE9ChI,KAAKuE,OAAOyC,MAAM,wBAAyBmB,EAAS,0BAA2BnB,GAE/EhH,KAAKwB,mBACHiH,EAAAA,iBAAiBvH,EAAYqH,EAAc,OAAAG,IAAMF,aAAN,EAAAE,EAAcb,KAAMb,EAAMwB,SAGvExI,KAAKK,eAAeiE,KAAK,CACvBpD,aACA8G,QAASO,EACTV,KAAM,OAAAc,EAAA3B,EAAMwB,aAAN,EAAAG,EAAcd,KACpBW,OAAQxB,EAAMwB,QAElB,CAEQ,kBAAAnD,GACN,MAAO,OAAOuD,KAAKC,SAASC,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,IACnE,CAEQ,kBAAAvD,CAAmBC,GACzB,IACE,MAAMuD,EAAS,IAAIC,IAAIxD,GAEjByD,EADWF,EAAOG,SACEC,MAAM,KAAKC,OAAS,eAC9C,OAAOC,mBAAmBJ,EAC5B,CAAA,MACE,MAAO,cACT,CACF,CAMA,gBAAMK,CAAW3J,SAOf,GANAE,KAAKuE,OAAOC,KAAK,wBAAyB,aAAc,sCAAuC,CAC7F7D,aAAcX,KAAKW,aACnB+I,uBAAuB,OAAA1H,EAAAlC,EAAO6J,uBAAP,EAAA3H,EAAyB0B,SAAU,IAIxD5D,EAAO6J,kBAAoB7J,EAAO6J,iBAAiBjG,OAAS,EAE9D,IAAA,MAAWkG,KAAa9J,EAAO6J,iBAC7B,IAEM,WAAYC,EACd5J,KAAKgB,mBAAmB4I,GACf,QAASA,GAClB5J,KAAKe,gBAAgB6I,EAEzB,OAAS5C,GACPhH,KAAKuE,OAAOyC,MACV,wBACA,aACA,2CACAA,EAEJ,CAGN,CAEA,aAAM6C,SAEE7J,KAAKoB,oBAAoB0I,YAG/B9J,KAAKS,YAAYsJ,QAGjB/J,KAAKC,gBAAgB8J,QACrB/J,KAAKG,gBAAgB4J,QACrB/J,KAAKI,uBAAuB2J,QAC5B/J,KAAKM,sBAAsByJ,QAC3B/J,KAAKK,eAAe0J,QAEpBhK,MAAM8J,SACR,GA3lBApK,EAAgBG,GAAK,mBAJhB,IAAMoK,EAANvK,ECpCA,MAAMwK,EAA6B,mBAE7BC,EAAwD,CACnEtK,GAAIqK,EACJxF,KAAM,0BACN0F,QAAS,QACTC,SAAU,CAAC,oBACXC,SAAU,GACVC,SAAU,GACVC,cAAe,CACb5J,aAAc,KCRL6J,EAGT,CACFN,WACAO,OAAQ,CAAC5K,EAAUC,IACjB,IAAIkK,EAAsBC,EAA4BpK,EAAUC,GAClE4K,QAAUpH,GAAUA,EACpBqH,aAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/lib/document-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts"],"sourcesContent":["import {\n BasePlugin,\n PluginRegistry,\n createBehaviorEmitter,\n startLoadingDocument,\n setDocumentLoaded,\n setDocumentError,\n retryLoadingDocument,\n closeDocument as closeDocumentAction,\n setActiveDocument as setActiveDocumentAction,\n moveDocument as moveDocumentAction,\n reorderDocuments as reorderDocumentsAction,\n DocumentState,\n Unsubscribe,\n Listener,\n createEmitter,\n} from '@embedpdf/core';\nimport {\n PdfDocumentObject,\n Task,\n PdfFile,\n PdfFileUrl,\n PdfErrorReason,\n PdfErrorCode,\n} from '@embedpdf/models';\n\nimport {\n DocumentManagerPluginConfig,\n DocumentManagerCapability,\n DocumentChangeEvent,\n DocumentOrderChangeEvent,\n LoadDocumentUrlOptions,\n LoadDocumentBufferOptions,\n RetryOptions,\n DocumentErrorEvent,\n OpenDocumentResponse,\n OpenFileDialogOptions,\n} from './types';\n\nexport class DocumentManagerPlugin extends BasePlugin<\n DocumentManagerPluginConfig,\n DocumentManagerCapability\n> {\n static readonly id = 'document-manager' as const;\n\n private readonly documentOpened$ = createBehaviorEmitter<DocumentState>();\n private readonly documentClosed$ = createBehaviorEmitter<string>();\n private readonly activeDocumentChanged$ = createBehaviorEmitter<DocumentChangeEvent>();\n private readonly documentError$ = createBehaviorEmitter<DocumentErrorEvent>();\n\n private readonly documentOrderChanged$ = createBehaviorEmitter<DocumentOrderChangeEvent>();\n\n private readonly openFileRequest$ = createEmitter<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>();\n\n private maxDocuments?: number;\n\n private loadOptions = new Map<string, LoadDocumentUrlOptions | LoadDocumentBufferOptions>();\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n config?: DocumentManagerPluginConfig,\n ) {\n super(id, registry);\n this.maxDocuments = config?.maxDocuments;\n }\n\n protected buildCapability(): DocumentManagerCapability {\n return {\n // Document lifecycle - orchestration only\n openFileDialog: (options) => this.openFileDialog(options),\n openDocumentUrl: (options) => this.openDocumentUrl(options),\n openDocumentBuffer: (options) => this.openDocumentBuffer(options),\n retryDocument: (documentId, options) => this.retryDocument(documentId, options),\n closeDocument: (documentId) => this.closeDocument(documentId),\n closeAllDocuments: () => this.closeAllDocuments(),\n\n setActiveDocument: (documentId) => {\n if (!this.isDocumentOpen(documentId)) {\n throw new Error(`Cannot set active document: ${documentId} is not open`);\n }\n this.dispatchCoreAction(setActiveDocumentAction(documentId));\n },\n\n getActiveDocumentId: () => this.coreState.core.activeDocumentId,\n getActiveDocument: () => {\n const activeId = this.coreState.core.activeDocumentId;\n if (!activeId) return null;\n return this.coreState.core.documents[activeId]?.document ?? null;\n },\n\n getDocumentOrder: () => this.coreState.core.documentOrder,\n\n moveDocument: (documentId, toIndex) => {\n this.dispatchCoreAction(moveDocumentAction(documentId, toIndex));\n },\n\n swapDocuments: (id1, id2) => {\n const order = this.coreState.core.documentOrder;\n const index1 = order.indexOf(id1);\n const index2 = order.indexOf(id2);\n\n if (index1 === -1 || index2 === -1) {\n throw new Error('One or both documents not found in order');\n }\n\n const newOrder = [...order];\n [newOrder[index1], newOrder[index2]] = [newOrder[index2], newOrder[index1]];\n\n this.dispatchCoreAction(reorderDocumentsAction(newOrder));\n },\n\n getDocument: (documentId) => {\n return this.coreState.core.documents[documentId]?.document ?? null;\n },\n\n getDocumentState: (documentId) => {\n return this.coreState.core.documents[documentId] ?? null;\n },\n\n getOpenDocuments: () => {\n return this.coreState.core.documentOrder\n .map((documentId) => this.coreState.core.documents[documentId])\n .filter((state): state is DocumentState => state !== null);\n },\n\n isDocumentOpen: (documentId) => this.isDocumentOpen(documentId),\n\n getDocumentCount: () => {\n return Object.keys(this.coreState.core.documents).length;\n },\n\n getDocumentIndex: (documentId) => {\n return this.coreState.core.documentOrder.indexOf(documentId);\n },\n\n // Events\n onDocumentOpened: this.documentOpened$.on,\n onDocumentClosed: this.documentClosed$.on,\n onDocumentError: this.documentError$.on,\n onActiveDocumentChanged: this.activeDocumentChanged$.on,\n onDocumentOrderChanged: this.documentOrderChanged$.on,\n };\n }\n\n /**\n * Check if a document is currently open\n */\n private isDocumentOpen(documentId: string): boolean {\n return !!this.coreState.core.documents[documentId];\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Lifecycle Hooks (from BasePlugin)\n // ─────────────────────────────────────────────────────────\n\n protected override onDocumentLoaded(documentId: string): void {\n const docState = this.coreState.core.documents[documentId];\n if (!docState || docState.status !== 'loaded') return;\n\n // Clean up load options to free memory\n this.loadOptions.delete(documentId);\n\n // Emit opened event\n this.documentOpened$.emit(docState);\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'DocumentOpened',\n `Document ${documentId} opened successfully`,\n { name: docState.name },\n );\n }\n\n protected override onDocumentClosed(documentId: string): void {\n // Clean up load options\n this.loadOptions.delete(documentId);\n\n // Emit closed event\n this.documentClosed$.emit(documentId);\n\n this.logger.info('DocumentManagerPlugin', 'DocumentClosed', `Document ${documentId} closed`);\n }\n\n protected override onActiveDocumentChanged(\n previousId: string | null,\n currentId: string | null,\n ): void {\n this.activeDocumentChanged$.emit({\n previousDocumentId: previousId,\n currentDocumentId: currentId,\n });\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'ActiveDocumentChanged',\n `Active document changed from ${previousId} to ${currentId}`,\n );\n }\n\n protected override onCoreStoreUpdated(oldState: any, newState: any): void {\n // Emit order change event if order changed\n if (oldState.core.documentOrder !== newState.core.documentOrder) {\n this.documentOrderChanged$.emit({\n order: newState.core.documentOrder,\n });\n }\n }\n\n public onOpenFileRequest(\n handler: Listener<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>,\n ): Unsubscribe {\n return this.openFileRequest$.on(handler);\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Loading (orchestration only - no state management)\n // ─────────────────────────────────────────────────────────\n\n private openDocumentUrl(\n options: LoadDocumentUrlOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Check limit\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentName = options.name ?? this.extractNameFromUrl(options.url);\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n documentName,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentUrl',\n `Starting to load document from URL: ${options.url}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n const engineTask = this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentUrl');\n\n return task;\n }\n\n private openDocumentBuffer(\n options: LoadDocumentBufferOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n options.name,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentBuffer',\n `Starting to load document from buffer: ${options.name}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n const engineTask = this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentBuffer');\n\n return task;\n }\n\n private retryDocument(\n documentId: string,\n retryOptions?: RetryOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n // Validate retry\n const validation = this.validateRetry(documentId);\n if (!validation.valid) {\n task.reject(validation.error!);\n return task;\n }\n\n const originalOptions = this.loadOptions.get(documentId)!;\n\n // Merge retry options (e.g., new password)\n const mergedOptions = {\n ...originalOptions,\n ...(retryOptions?.password && { password: retryOptions.password }),\n };\n\n // Update stored options\n this.loadOptions.set(documentId, mergedOptions);\n\n // Set back to loading state\n this.dispatchCoreAction(retryLoadingDocument(documentId, !!retryOptions?.password));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'RetryDocument',\n `Retrying to load document ${documentId}`,\n { passwordProvided: !!retryOptions?.password },\n );\n\n // Execute retry based on type\n const engineTask =\n 'url' in mergedOptions\n ? this.retryUrlDocument(documentId, mergedOptions)\n : this.retryBufferDocument(documentId, mergedOptions);\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'RetryDocument');\n\n return task;\n }\n\n private openFileDialog(\n options?: OpenFileDialogOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n this.openFileRequest$.emit({ task, options });\n return task;\n }\n\n private closeDocument(documentId: string): Task<void, PdfErrorReason> {\n const task = new Task<void, PdfErrorReason>();\n\n const docState = this.coreState.core.documents[documentId];\n if (!docState) {\n this.logger.warn(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Cannot close document ${documentId}: not found in state`,\n );\n task.resolve();\n return task;\n }\n\n // ✅ SIMPLIFIED: Just dispatch - reducer calculates next active!\n if (docState.status === 'loaded' && docState.document) {\n this.engine.closeDocument(docState.document).wait(\n () => {\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n },\n (error) => {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Failed to close document ${documentId}`,\n error,\n );\n task.fail(error);\n },\n );\n } else {\n // Document is not loaded (error, loading, etc.), just clean up state\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Closing document ${documentId} in ${docState.status} state (skipping engine close)`,\n );\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n }\n\n return task;\n }\n\n private closeAllDocuments(): Task<void[], PdfErrorReason> {\n const documentIds = Object.keys(this.coreState.core.documents);\n const tasks = documentIds.map((documentId) => this.closeDocument(documentId));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseAllDocuments',\n `Closing ${documentIds.length} documents`,\n );\n\n return Task.all(tasks);\n }\n\n // ─────────────────────────────────────────────────────────\n // Helper Methods\n // ─────────────────────────────────────────────────────────\n\n private checkDocumentLimit(): PdfErrorReason | null {\n if (\n this.maxDocuments &&\n Object.keys(this.coreState.core.documents).length >= this.maxDocuments\n ) {\n return {\n code: PdfErrorCode.Unknown,\n message: `Maximum number of documents (${this.maxDocuments}) reached`,\n };\n }\n return null;\n }\n\n private validateRetry(documentId: string): {\n valid: boolean;\n error?: PdfErrorReason;\n } {\n const docState = this.coreState.core.documents[documentId];\n\n if (!docState) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.NotFound,\n message: `Document ${documentId} not found`,\n },\n };\n }\n\n if (docState.status === 'loaded') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is already loaded successfully`,\n },\n };\n }\n\n if (docState.status !== 'error') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is not in error state (current state: ${docState.status})`,\n },\n };\n }\n\n if (!this.loadOptions.has(documentId)) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `No retry information available for document ${documentId}`,\n },\n };\n }\n\n return { valid: true };\n }\n\n private retryUrlDocument(\n documentId: string,\n options: LoadDocumentUrlOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n\n return this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n }\n\n private retryBufferDocument(\n documentId: string,\n options: LoadDocumentBufferOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n\n return this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n }\n\n private handleLoadTask(\n documentId: string,\n engineTask: Task<PdfDocumentObject, PdfErrorReason>,\n context: string,\n ): void {\n engineTask.wait(\n (pdfDocument) => {\n this.dispatchCoreAction(setDocumentLoaded(documentId, pdfDocument));\n },\n (error) => {\n this.handleLoadError(documentId, error, context);\n },\n );\n }\n\n private handleLoadError(documentId: string, error: any, context: string): void {\n const errorMessage = error.reason?.message || 'Failed to load document';\n\n this.logger.error('DocumentManagerPlugin', context, 'Failed to load document', error);\n\n this.dispatchCoreAction(\n setDocumentError(documentId, errorMessage, error.reason?.code, error.reason),\n );\n\n this.documentError$.emit({\n documentId,\n message: errorMessage,\n code: error.reason?.code,\n reason: error.reason,\n });\n }\n\n private generateDocumentId(): string {\n return `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private extractNameFromUrl(url: string): string | undefined {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname;\n const lastSegment = pathname.split('/').pop();\n if (!lastSegment) {\n return undefined;\n }\n let filename = decodeURIComponent(lastSegment);\n if (!filename.toLowerCase().endsWith('.pdf')) {\n filename += '.pdf';\n }\n return filename;\n } catch {\n return undefined;\n }\n }\n\n // ─────────────────────────────────────────────────────────\n // Plugin Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(config: DocumentManagerPluginConfig): Promise<void> {\n this.logger.info('DocumentManagerPlugin', 'Initialize', 'Document Manager Plugin initialized', {\n maxDocuments: this.maxDocuments,\n initialDocumentsCount: config.initialDocuments?.length ?? 0,\n });\n\n // Handle initial documents from config\n if (config.initialDocuments && config.initialDocuments.length > 0) {\n // Process strictly in order\n for (const docConfig of config.initialDocuments) {\n try {\n // Type guard to distinguish between URL and Buffer options\n if ('buffer' in docConfig) {\n this.openDocumentBuffer(docConfig);\n } else if ('url' in docConfig) {\n this.openDocumentUrl(docConfig);\n }\n } catch (error) {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'Initialize',\n 'Failed to initiate initial document load',\n error,\n );\n }\n }\n }\n }\n\n async destroy(): Promise<void> {\n // Close all documents\n await this.closeAllDocuments().toPromise();\n\n // Clear load options\n this.loadOptions.clear();\n\n // Clear emitters\n this.documentOpened$.clear();\n this.documentClosed$.clear();\n this.activeDocumentChanged$.clear();\n this.documentOrderChanged$.clear();\n this.documentError$.clear();\n\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DOCUMENT_MANAGER_PLUGIN_ID = 'document-manager';\n\nexport const manifest: PluginManifest<DocumentManagerPluginConfig> = {\n id: DOCUMENT_MANAGER_PLUGIN_ID,\n name: 'Document Manager Plugin',\n version: '1.0.0',\n provides: ['document-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n maxDocuments: 10,\n },\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPlugin } from './document-manager-plugin';\nimport { manifest, DOCUMENT_MANAGER_PLUGIN_ID } from './manifest';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DocumentManagerPluginPackage: PluginPackage<\n DocumentManagerPlugin,\n DocumentManagerPluginConfig\n> = {\n manifest,\n create: (registry, config) =>\n new DocumentManagerPlugin(DOCUMENT_MANAGER_PLUGIN_ID, registry, config),\n reducer: (state) => state,\n initialState: {},\n};\n\nexport * from './document-manager-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["_DocumentManagerPlugin","BasePlugin","constructor","id","registry","config","super","this","documentOpened$","createBehaviorEmitter","documentClosed$","activeDocumentChanged$","documentError$","documentOrderChanged$","openFileRequest$","createEmitter","loadOptions","Map","maxDocuments","buildCapability","openFileDialog","options","openDocumentUrl","openDocumentBuffer","retryDocument","documentId","closeDocument","closeAllDocuments","setActiveDocument","isDocumentOpen","Error","dispatchCoreAction","setActiveDocumentAction","getActiveDocumentId","coreState","core","activeDocumentId","getActiveDocument","activeId","_a","documents","document","getDocumentOrder","documentOrder","moveDocument","toIndex","moveDocumentAction","swapDocuments","id1","id2","order","index1","indexOf","index2","newOrder","reorderDocumentsAction","getDocument","getDocumentState","getOpenDocuments","map","filter","state","getDocumentCount","Object","keys","length","getDocumentIndex","onDocumentOpened","on","onDocumentClosed","onDocumentError","onActiveDocumentChanged","onDocumentOrderChanged","onDocumentLoaded","docState","status","delete","emit","logger","info","name","previousId","currentId","previousDocumentId","currentDocumentId","onCoreStoreUpdated","oldState","newState","onOpenFileRequest","handler","task","Task","generateDocumentId","limitError","checkDocumentLimit","reject","documentName","extractNameFromUrl","url","set","startLoadingDocument","scale","rotation","password","autoActivate","passwordProvided","file","engineTask","engine","mode","requestOptions","resolve","handleLoadTask","content","buffer","retryOptions","validation","validateRetry","valid","error","mergedOptions","get","retryLoadingDocument","retryUrlDocument","retryBufferDocument","wait","closeDocumentAction","fail","warn","documentIds","tasks","all","code","PdfErrorCode","Unknown","message","has","NotFound","context","pdfDocument","setDocumentLoaded","handleLoadError","errorMessage","reason","setDocumentError","_b","_c","Date","now","Math","random","toString","substr","urlObj","URL","lastSegment","pathname","split","pop","filename","decodeURIComponent","toLowerCase","endsWith","initialize","initialDocumentsCount","initialDocuments","docConfig","destroy","toPromise","clear","DocumentManagerPlugin","DOCUMENT_MANAGER_PLUGIN_ID","manifest","version","provides","requires","optional","defaultConfig","DocumentManagerPluginPackage","create","reducer","initialState"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -133,7 +133,7 @@ const _DocumentManagerPlugin = class _DocumentManagerPlugin extends BasePlugin {
|
|
|
133
133
|
task.reject(limitError);
|
|
134
134
|
return task;
|
|
135
135
|
}
|
|
136
|
-
const documentName = this.extractNameFromUrl(options.url);
|
|
136
|
+
const documentName = options.name ?? this.extractNameFromUrl(options.url);
|
|
137
137
|
this.loadOptions.set(documentId, options);
|
|
138
138
|
this.dispatchCoreAction(
|
|
139
139
|
startLoadingDocument(
|
|
@@ -391,10 +391,17 @@ const _DocumentManagerPlugin = class _DocumentManagerPlugin extends BasePlugin {
|
|
|
391
391
|
try {
|
|
392
392
|
const urlObj = new URL(url);
|
|
393
393
|
const pathname = urlObj.pathname;
|
|
394
|
-
const
|
|
395
|
-
|
|
394
|
+
const lastSegment = pathname.split("/").pop();
|
|
395
|
+
if (!lastSegment) {
|
|
396
|
+
return void 0;
|
|
397
|
+
}
|
|
398
|
+
let filename = decodeURIComponent(lastSegment);
|
|
399
|
+
if (!filename.toLowerCase().endsWith(".pdf")) {
|
|
400
|
+
filename += ".pdf";
|
|
401
|
+
}
|
|
402
|
+
return filename;
|
|
396
403
|
} catch {
|
|
397
|
-
return
|
|
404
|
+
return void 0;
|
|
398
405
|
}
|
|
399
406
|
}
|
|
400
407
|
// ─────────────────────────────────────────────────────────
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/lib/document-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts"],"sourcesContent":["import {\n BasePlugin,\n PluginRegistry,\n createBehaviorEmitter,\n startLoadingDocument,\n setDocumentLoaded,\n setDocumentError,\n retryLoadingDocument,\n closeDocument as closeDocumentAction,\n setActiveDocument as setActiveDocumentAction,\n moveDocument as moveDocumentAction,\n reorderDocuments as reorderDocumentsAction,\n DocumentState,\n Unsubscribe,\n Listener,\n createEmitter,\n} from '@embedpdf/core';\nimport {\n PdfDocumentObject,\n Task,\n PdfFile,\n PdfFileUrl,\n PdfErrorReason,\n PdfErrorCode,\n} from '@embedpdf/models';\n\nimport {\n DocumentManagerPluginConfig,\n DocumentManagerCapability,\n DocumentChangeEvent,\n DocumentOrderChangeEvent,\n LoadDocumentUrlOptions,\n LoadDocumentBufferOptions,\n RetryOptions,\n DocumentErrorEvent,\n OpenDocumentResponse,\n OpenFileDialogOptions,\n} from './types';\n\nexport class DocumentManagerPlugin extends BasePlugin<\n DocumentManagerPluginConfig,\n DocumentManagerCapability\n> {\n static readonly id = 'document-manager' as const;\n\n private readonly documentOpened$ = createBehaviorEmitter<DocumentState>();\n private readonly documentClosed$ = createBehaviorEmitter<string>();\n private readonly activeDocumentChanged$ = createBehaviorEmitter<DocumentChangeEvent>();\n private readonly documentError$ = createBehaviorEmitter<DocumentErrorEvent>();\n\n private readonly documentOrderChanged$ = createBehaviorEmitter<DocumentOrderChangeEvent>();\n\n private readonly openFileRequest$ = createEmitter<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>();\n\n private maxDocuments?: number;\n\n private loadOptions = new Map<string, LoadDocumentUrlOptions | LoadDocumentBufferOptions>();\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n config?: DocumentManagerPluginConfig,\n ) {\n super(id, registry);\n this.maxDocuments = config?.maxDocuments;\n }\n\n protected buildCapability(): DocumentManagerCapability {\n return {\n // Document lifecycle - orchestration only\n openFileDialog: (options) => this.openFileDialog(options),\n openDocumentUrl: (options) => this.openDocumentUrl(options),\n openDocumentBuffer: (options) => this.openDocumentBuffer(options),\n retryDocument: (documentId, options) => this.retryDocument(documentId, options),\n closeDocument: (documentId) => this.closeDocument(documentId),\n closeAllDocuments: () => this.closeAllDocuments(),\n\n setActiveDocument: (documentId) => {\n if (!this.isDocumentOpen(documentId)) {\n throw new Error(`Cannot set active document: ${documentId} is not open`);\n }\n this.dispatchCoreAction(setActiveDocumentAction(documentId));\n },\n\n getActiveDocumentId: () => this.coreState.core.activeDocumentId,\n getActiveDocument: () => {\n const activeId = this.coreState.core.activeDocumentId;\n if (!activeId) return null;\n return this.coreState.core.documents[activeId]?.document ?? null;\n },\n\n getDocumentOrder: () => this.coreState.core.documentOrder,\n\n moveDocument: (documentId, toIndex) => {\n this.dispatchCoreAction(moveDocumentAction(documentId, toIndex));\n },\n\n swapDocuments: (id1, id2) => {\n const order = this.coreState.core.documentOrder;\n const index1 = order.indexOf(id1);\n const index2 = order.indexOf(id2);\n\n if (index1 === -1 || index2 === -1) {\n throw new Error('One or both documents not found in order');\n }\n\n const newOrder = [...order];\n [newOrder[index1], newOrder[index2]] = [newOrder[index2], newOrder[index1]];\n\n this.dispatchCoreAction(reorderDocumentsAction(newOrder));\n },\n\n getDocument: (documentId) => {\n return this.coreState.core.documents[documentId]?.document ?? null;\n },\n\n getDocumentState: (documentId) => {\n return this.coreState.core.documents[documentId] ?? null;\n },\n\n getOpenDocuments: () => {\n return this.coreState.core.documentOrder\n .map((documentId) => this.coreState.core.documents[documentId])\n .filter((state): state is DocumentState => state !== null);\n },\n\n isDocumentOpen: (documentId) => this.isDocumentOpen(documentId),\n\n getDocumentCount: () => {\n return Object.keys(this.coreState.core.documents).length;\n },\n\n getDocumentIndex: (documentId) => {\n return this.coreState.core.documentOrder.indexOf(documentId);\n },\n\n // Events\n onDocumentOpened: this.documentOpened$.on,\n onDocumentClosed: this.documentClosed$.on,\n onDocumentError: this.documentError$.on,\n onActiveDocumentChanged: this.activeDocumentChanged$.on,\n onDocumentOrderChanged: this.documentOrderChanged$.on,\n };\n }\n\n /**\n * Check if a document is currently open\n */\n private isDocumentOpen(documentId: string): boolean {\n return !!this.coreState.core.documents[documentId];\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Lifecycle Hooks (from BasePlugin)\n // ─────────────────────────────────────────────────────────\n\n protected override onDocumentLoaded(documentId: string): void {\n const docState = this.coreState.core.documents[documentId];\n if (!docState || docState.status !== 'loaded') return;\n\n // Clean up load options to free memory\n this.loadOptions.delete(documentId);\n\n // Emit opened event\n this.documentOpened$.emit(docState);\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'DocumentOpened',\n `Document ${documentId} opened successfully`,\n { name: docState.name },\n );\n }\n\n protected override onDocumentClosed(documentId: string): void {\n // Clean up load options\n this.loadOptions.delete(documentId);\n\n // Emit closed event\n this.documentClosed$.emit(documentId);\n\n this.logger.info('DocumentManagerPlugin', 'DocumentClosed', `Document ${documentId} closed`);\n }\n\n protected override onActiveDocumentChanged(\n previousId: string | null,\n currentId: string | null,\n ): void {\n this.activeDocumentChanged$.emit({\n previousDocumentId: previousId,\n currentDocumentId: currentId,\n });\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'ActiveDocumentChanged',\n `Active document changed from ${previousId} to ${currentId}`,\n );\n }\n\n protected override onCoreStoreUpdated(oldState: any, newState: any): void {\n // Emit order change event if order changed\n if (oldState.core.documentOrder !== newState.core.documentOrder) {\n this.documentOrderChanged$.emit({\n order: newState.core.documentOrder,\n });\n }\n }\n\n public onOpenFileRequest(\n handler: Listener<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>,\n ): Unsubscribe {\n return this.openFileRequest$.on(handler);\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Loading (orchestration only - no state management)\n // ─────────────────────────────────────────────────────────\n\n private openDocumentUrl(\n options: LoadDocumentUrlOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Check limit\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentName = this.extractNameFromUrl(options.url);\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n documentName,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentUrl',\n `Starting to load document from URL: ${options.url}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n const engineTask = this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentUrl');\n\n return task;\n }\n\n private openDocumentBuffer(\n options: LoadDocumentBufferOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n options.name,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentBuffer',\n `Starting to load document from buffer: ${options.name}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n const engineTask = this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentBuffer');\n\n return task;\n }\n\n private retryDocument(\n documentId: string,\n retryOptions?: RetryOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n // Validate retry\n const validation = this.validateRetry(documentId);\n if (!validation.valid) {\n task.reject(validation.error!);\n return task;\n }\n\n const originalOptions = this.loadOptions.get(documentId)!;\n\n // Merge retry options (e.g., new password)\n const mergedOptions = {\n ...originalOptions,\n ...(retryOptions?.password && { password: retryOptions.password }),\n };\n\n // Update stored options\n this.loadOptions.set(documentId, mergedOptions);\n\n // Set back to loading state\n this.dispatchCoreAction(retryLoadingDocument(documentId, !!retryOptions?.password));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'RetryDocument',\n `Retrying to load document ${documentId}`,\n { passwordProvided: !!retryOptions?.password },\n );\n\n // Execute retry based on type\n const engineTask =\n 'url' in mergedOptions\n ? this.retryUrlDocument(documentId, mergedOptions)\n : this.retryBufferDocument(documentId, mergedOptions);\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'RetryDocument');\n\n return task;\n }\n\n private openFileDialog(\n options?: OpenFileDialogOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n this.openFileRequest$.emit({ task, options });\n return task;\n }\n\n private closeDocument(documentId: string): Task<void, PdfErrorReason> {\n const task = new Task<void, PdfErrorReason>();\n\n const docState = this.coreState.core.documents[documentId];\n if (!docState) {\n this.logger.warn(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Cannot close document ${documentId}: not found in state`,\n );\n task.resolve();\n return task;\n }\n\n // ✅ SIMPLIFIED: Just dispatch - reducer calculates next active!\n if (docState.status === 'loaded' && docState.document) {\n this.engine.closeDocument(docState.document).wait(\n () => {\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n },\n (error) => {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Failed to close document ${documentId}`,\n error,\n );\n task.fail(error);\n },\n );\n } else {\n // Document is not loaded (error, loading, etc.), just clean up state\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Closing document ${documentId} in ${docState.status} state (skipping engine close)`,\n );\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n }\n\n return task;\n }\n\n private closeAllDocuments(): Task<void[], PdfErrorReason> {\n const documentIds = Object.keys(this.coreState.core.documents);\n const tasks = documentIds.map((documentId) => this.closeDocument(documentId));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseAllDocuments',\n `Closing ${documentIds.length} documents`,\n );\n\n return Task.all(tasks);\n }\n\n // ─────────────────────────────────────────────────────────\n // Helper Methods\n // ─────────────────────────────────────────────────────────\n\n private checkDocumentLimit(): PdfErrorReason | null {\n if (\n this.maxDocuments &&\n Object.keys(this.coreState.core.documents).length >= this.maxDocuments\n ) {\n return {\n code: PdfErrorCode.Unknown,\n message: `Maximum number of documents (${this.maxDocuments}) reached`,\n };\n }\n return null;\n }\n\n private validateRetry(documentId: string): {\n valid: boolean;\n error?: PdfErrorReason;\n } {\n const docState = this.coreState.core.documents[documentId];\n\n if (!docState) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.NotFound,\n message: `Document ${documentId} not found`,\n },\n };\n }\n\n if (docState.status === 'loaded') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is already loaded successfully`,\n },\n };\n }\n\n if (docState.status !== 'error') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is not in error state (current state: ${docState.status})`,\n },\n };\n }\n\n if (!this.loadOptions.has(documentId)) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `No retry information available for document ${documentId}`,\n },\n };\n }\n\n return { valid: true };\n }\n\n private retryUrlDocument(\n documentId: string,\n options: LoadDocumentUrlOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n\n return this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n }\n\n private retryBufferDocument(\n documentId: string,\n options: LoadDocumentBufferOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n\n return this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n }\n\n private handleLoadTask(\n documentId: string,\n engineTask: Task<PdfDocumentObject, PdfErrorReason>,\n context: string,\n ): void {\n engineTask.wait(\n (pdfDocument) => {\n this.dispatchCoreAction(setDocumentLoaded(documentId, pdfDocument));\n },\n (error) => {\n this.handleLoadError(documentId, error, context);\n },\n );\n }\n\n private handleLoadError(documentId: string, error: any, context: string): void {\n const errorMessage = error.reason?.message || 'Failed to load document';\n\n this.logger.error('DocumentManagerPlugin', context, 'Failed to load document', error);\n\n this.dispatchCoreAction(\n setDocumentError(documentId, errorMessage, error.reason?.code, error.reason),\n );\n\n this.documentError$.emit({\n documentId,\n message: errorMessage,\n code: error.reason?.code,\n reason: error.reason,\n });\n }\n\n private generateDocumentId(): string {\n return `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private extractNameFromUrl(url: string): string {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname;\n const filename = pathname.split('/').pop() || 'document.pdf';\n return decodeURIComponent(filename);\n } catch {\n return 'document.pdf';\n }\n }\n\n // ─────────────────────────────────────────────────────────\n // Plugin Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(config: DocumentManagerPluginConfig): Promise<void> {\n this.logger.info('DocumentManagerPlugin', 'Initialize', 'Document Manager Plugin initialized', {\n maxDocuments: this.maxDocuments,\n initialDocumentsCount: config.initialDocuments?.length ?? 0,\n });\n\n // Handle initial documents from config\n if (config.initialDocuments && config.initialDocuments.length > 0) {\n // Process strictly in order\n for (const docConfig of config.initialDocuments) {\n try {\n // Type guard to distinguish between URL and Buffer options\n if ('buffer' in docConfig) {\n this.openDocumentBuffer(docConfig);\n } else if ('url' in docConfig) {\n this.openDocumentUrl(docConfig);\n }\n } catch (error) {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'Initialize',\n 'Failed to initiate initial document load',\n error,\n );\n }\n }\n }\n }\n\n async destroy(): Promise<void> {\n // Close all documents\n await this.closeAllDocuments().toPromise();\n\n // Clear load options\n this.loadOptions.clear();\n\n // Clear emitters\n this.documentOpened$.clear();\n this.documentClosed$.clear();\n this.activeDocumentChanged$.clear();\n this.documentOrderChanged$.clear();\n this.documentError$.clear();\n\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DOCUMENT_MANAGER_PLUGIN_ID = 'document-manager';\n\nexport const manifest: PluginManifest<DocumentManagerPluginConfig> = {\n id: DOCUMENT_MANAGER_PLUGIN_ID,\n name: 'Document Manager Plugin',\n version: '1.0.0',\n provides: ['document-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n maxDocuments: 10,\n },\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPlugin } from './document-manager-plugin';\nimport { manifest, DOCUMENT_MANAGER_PLUGIN_ID } from './manifest';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DocumentManagerPluginPackage: PluginPackage<\n DocumentManagerPlugin,\n DocumentManagerPluginConfig\n> = {\n manifest,\n create: (registry, config) =>\n new DocumentManagerPlugin(DOCUMENT_MANAGER_PLUGIN_ID, registry, config),\n reducer: (state) => state,\n initialState: {},\n};\n\nexport * from './document-manager-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["setActiveDocumentAction","moveDocumentAction","reorderDocumentsAction","closeDocumentAction"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/document-manager-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts"],"sourcesContent":["import {\n BasePlugin,\n PluginRegistry,\n createBehaviorEmitter,\n startLoadingDocument,\n setDocumentLoaded,\n setDocumentError,\n retryLoadingDocument,\n closeDocument as closeDocumentAction,\n setActiveDocument as setActiveDocumentAction,\n moveDocument as moveDocumentAction,\n reorderDocuments as reorderDocumentsAction,\n DocumentState,\n Unsubscribe,\n Listener,\n createEmitter,\n} from '@embedpdf/core';\nimport {\n PdfDocumentObject,\n Task,\n PdfFile,\n PdfFileUrl,\n PdfErrorReason,\n PdfErrorCode,\n} from '@embedpdf/models';\n\nimport {\n DocumentManagerPluginConfig,\n DocumentManagerCapability,\n DocumentChangeEvent,\n DocumentOrderChangeEvent,\n LoadDocumentUrlOptions,\n LoadDocumentBufferOptions,\n RetryOptions,\n DocumentErrorEvent,\n OpenDocumentResponse,\n OpenFileDialogOptions,\n} from './types';\n\nexport class DocumentManagerPlugin extends BasePlugin<\n DocumentManagerPluginConfig,\n DocumentManagerCapability\n> {\n static readonly id = 'document-manager' as const;\n\n private readonly documentOpened$ = createBehaviorEmitter<DocumentState>();\n private readonly documentClosed$ = createBehaviorEmitter<string>();\n private readonly activeDocumentChanged$ = createBehaviorEmitter<DocumentChangeEvent>();\n private readonly documentError$ = createBehaviorEmitter<DocumentErrorEvent>();\n\n private readonly documentOrderChanged$ = createBehaviorEmitter<DocumentOrderChangeEvent>();\n\n private readonly openFileRequest$ = createEmitter<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>();\n\n private maxDocuments?: number;\n\n private loadOptions = new Map<string, LoadDocumentUrlOptions | LoadDocumentBufferOptions>();\n\n constructor(\n public readonly id: string,\n registry: PluginRegistry,\n config?: DocumentManagerPluginConfig,\n ) {\n super(id, registry);\n this.maxDocuments = config?.maxDocuments;\n }\n\n protected buildCapability(): DocumentManagerCapability {\n return {\n // Document lifecycle - orchestration only\n openFileDialog: (options) => this.openFileDialog(options),\n openDocumentUrl: (options) => this.openDocumentUrl(options),\n openDocumentBuffer: (options) => this.openDocumentBuffer(options),\n retryDocument: (documentId, options) => this.retryDocument(documentId, options),\n closeDocument: (documentId) => this.closeDocument(documentId),\n closeAllDocuments: () => this.closeAllDocuments(),\n\n setActiveDocument: (documentId) => {\n if (!this.isDocumentOpen(documentId)) {\n throw new Error(`Cannot set active document: ${documentId} is not open`);\n }\n this.dispatchCoreAction(setActiveDocumentAction(documentId));\n },\n\n getActiveDocumentId: () => this.coreState.core.activeDocumentId,\n getActiveDocument: () => {\n const activeId = this.coreState.core.activeDocumentId;\n if (!activeId) return null;\n return this.coreState.core.documents[activeId]?.document ?? null;\n },\n\n getDocumentOrder: () => this.coreState.core.documentOrder,\n\n moveDocument: (documentId, toIndex) => {\n this.dispatchCoreAction(moveDocumentAction(documentId, toIndex));\n },\n\n swapDocuments: (id1, id2) => {\n const order = this.coreState.core.documentOrder;\n const index1 = order.indexOf(id1);\n const index2 = order.indexOf(id2);\n\n if (index1 === -1 || index2 === -1) {\n throw new Error('One or both documents not found in order');\n }\n\n const newOrder = [...order];\n [newOrder[index1], newOrder[index2]] = [newOrder[index2], newOrder[index1]];\n\n this.dispatchCoreAction(reorderDocumentsAction(newOrder));\n },\n\n getDocument: (documentId) => {\n return this.coreState.core.documents[documentId]?.document ?? null;\n },\n\n getDocumentState: (documentId) => {\n return this.coreState.core.documents[documentId] ?? null;\n },\n\n getOpenDocuments: () => {\n return this.coreState.core.documentOrder\n .map((documentId) => this.coreState.core.documents[documentId])\n .filter((state): state is DocumentState => state !== null);\n },\n\n isDocumentOpen: (documentId) => this.isDocumentOpen(documentId),\n\n getDocumentCount: () => {\n return Object.keys(this.coreState.core.documents).length;\n },\n\n getDocumentIndex: (documentId) => {\n return this.coreState.core.documentOrder.indexOf(documentId);\n },\n\n // Events\n onDocumentOpened: this.documentOpened$.on,\n onDocumentClosed: this.documentClosed$.on,\n onDocumentError: this.documentError$.on,\n onActiveDocumentChanged: this.activeDocumentChanged$.on,\n onDocumentOrderChanged: this.documentOrderChanged$.on,\n };\n }\n\n /**\n * Check if a document is currently open\n */\n private isDocumentOpen(documentId: string): boolean {\n return !!this.coreState.core.documents[documentId];\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Lifecycle Hooks (from BasePlugin)\n // ─────────────────────────────────────────────────────────\n\n protected override onDocumentLoaded(documentId: string): void {\n const docState = this.coreState.core.documents[documentId];\n if (!docState || docState.status !== 'loaded') return;\n\n // Clean up load options to free memory\n this.loadOptions.delete(documentId);\n\n // Emit opened event\n this.documentOpened$.emit(docState);\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'DocumentOpened',\n `Document ${documentId} opened successfully`,\n { name: docState.name },\n );\n }\n\n protected override onDocumentClosed(documentId: string): void {\n // Clean up load options\n this.loadOptions.delete(documentId);\n\n // Emit closed event\n this.documentClosed$.emit(documentId);\n\n this.logger.info('DocumentManagerPlugin', 'DocumentClosed', `Document ${documentId} closed`);\n }\n\n protected override onActiveDocumentChanged(\n previousId: string | null,\n currentId: string | null,\n ): void {\n this.activeDocumentChanged$.emit({\n previousDocumentId: previousId,\n currentDocumentId: currentId,\n });\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'ActiveDocumentChanged',\n `Active document changed from ${previousId} to ${currentId}`,\n );\n }\n\n protected override onCoreStoreUpdated(oldState: any, newState: any): void {\n // Emit order change event if order changed\n if (oldState.core.documentOrder !== newState.core.documentOrder) {\n this.documentOrderChanged$.emit({\n order: newState.core.documentOrder,\n });\n }\n }\n\n public onOpenFileRequest(\n handler: Listener<{\n task: Task<OpenDocumentResponse, PdfErrorReason>;\n options?: OpenFileDialogOptions;\n }>,\n ): Unsubscribe {\n return this.openFileRequest$.on(handler);\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Loading (orchestration only - no state management)\n // ─────────────────────────────────────────────────────────\n\n private openDocumentUrl(\n options: LoadDocumentUrlOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Check limit\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentName = options.name ?? this.extractNameFromUrl(options.url);\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n documentName,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentUrl',\n `Starting to load document from URL: ${options.url}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n const engineTask = this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentUrl');\n\n return task;\n }\n\n private openDocumentBuffer(\n options: LoadDocumentBufferOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n const limitError = this.checkDocumentLimit();\n if (limitError) {\n task.reject(limitError);\n return task;\n }\n\n const documentId = options.documentId || this.generateDocumentId();\n\n // Store options for potential retry\n this.loadOptions.set(documentId, options);\n\n this.dispatchCoreAction(\n startLoadingDocument(\n documentId,\n options.name,\n options.scale,\n options.rotation,\n !!options.password,\n options.autoActivate,\n ),\n );\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'OpenDocumentBuffer',\n `Starting to load document from buffer: ${options.name}`,\n { documentId, passwordProvided: !!options.password },\n );\n\n // Create file object and call engine\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n const engineTask = this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'OpenDocumentBuffer');\n\n return task;\n }\n\n private retryDocument(\n documentId: string,\n retryOptions?: RetryOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n\n // Validate retry\n const validation = this.validateRetry(documentId);\n if (!validation.valid) {\n task.reject(validation.error!);\n return task;\n }\n\n const originalOptions = this.loadOptions.get(documentId)!;\n\n // Merge retry options (e.g., new password)\n const mergedOptions = {\n ...originalOptions,\n ...(retryOptions?.password && { password: retryOptions.password }),\n };\n\n // Update stored options\n this.loadOptions.set(documentId, mergedOptions);\n\n // Set back to loading state\n this.dispatchCoreAction(retryLoadingDocument(documentId, !!retryOptions?.password));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'RetryDocument',\n `Retrying to load document ${documentId}`,\n { passwordProvided: !!retryOptions?.password },\n );\n\n // Execute retry based on type\n const engineTask =\n 'url' in mergedOptions\n ? this.retryUrlDocument(documentId, mergedOptions)\n : this.retryBufferDocument(documentId, mergedOptions);\n\n task.resolve({\n documentId,\n task: engineTask,\n });\n\n // Handle result\n this.handleLoadTask(documentId, engineTask, 'RetryDocument');\n\n return task;\n }\n\n private openFileDialog(\n options?: OpenFileDialogOptions,\n ): Task<OpenDocumentResponse, PdfErrorReason> {\n const task = new Task<OpenDocumentResponse, PdfErrorReason>();\n this.openFileRequest$.emit({ task, options });\n return task;\n }\n\n private closeDocument(documentId: string): Task<void, PdfErrorReason> {\n const task = new Task<void, PdfErrorReason>();\n\n const docState = this.coreState.core.documents[documentId];\n if (!docState) {\n this.logger.warn(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Cannot close document ${documentId}: not found in state`,\n );\n task.resolve();\n return task;\n }\n\n // ✅ SIMPLIFIED: Just dispatch - reducer calculates next active!\n if (docState.status === 'loaded' && docState.document) {\n this.engine.closeDocument(docState.document).wait(\n () => {\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n },\n (error) => {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Failed to close document ${documentId}`,\n error,\n );\n task.fail(error);\n },\n );\n } else {\n // Document is not loaded (error, loading, etc.), just clean up state\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseDocument',\n `Closing document ${documentId} in ${docState.status} state (skipping engine close)`,\n );\n this.dispatchCoreAction(closeDocumentAction(documentId));\n task.resolve();\n }\n\n return task;\n }\n\n private closeAllDocuments(): Task<void[], PdfErrorReason> {\n const documentIds = Object.keys(this.coreState.core.documents);\n const tasks = documentIds.map((documentId) => this.closeDocument(documentId));\n\n this.logger.info(\n 'DocumentManagerPlugin',\n 'CloseAllDocuments',\n `Closing ${documentIds.length} documents`,\n );\n\n return Task.all(tasks);\n }\n\n // ─────────────────────────────────────────────────────────\n // Helper Methods\n // ─────────────────────────────────────────────────────────\n\n private checkDocumentLimit(): PdfErrorReason | null {\n if (\n this.maxDocuments &&\n Object.keys(this.coreState.core.documents).length >= this.maxDocuments\n ) {\n return {\n code: PdfErrorCode.Unknown,\n message: `Maximum number of documents (${this.maxDocuments}) reached`,\n };\n }\n return null;\n }\n\n private validateRetry(documentId: string): {\n valid: boolean;\n error?: PdfErrorReason;\n } {\n const docState = this.coreState.core.documents[documentId];\n\n if (!docState) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.NotFound,\n message: `Document ${documentId} not found`,\n },\n };\n }\n\n if (docState.status === 'loaded') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is already loaded successfully`,\n },\n };\n }\n\n if (docState.status !== 'error') {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `Document ${documentId} is not in error state (current state: ${docState.status})`,\n },\n };\n }\n\n if (!this.loadOptions.has(documentId)) {\n return {\n valid: false,\n error: {\n code: PdfErrorCode.Unknown,\n message: `No retry information available for document ${documentId}`,\n },\n };\n }\n\n return { valid: true };\n }\n\n private retryUrlDocument(\n documentId: string,\n options: LoadDocumentUrlOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFileUrl = {\n id: documentId,\n url: options.url,\n };\n\n return this.engine.openDocumentUrl(file, {\n password: options.password,\n mode: options.mode,\n requestOptions: options.requestOptions,\n });\n }\n\n private retryBufferDocument(\n documentId: string,\n options: LoadDocumentBufferOptions,\n ): Task<PdfDocumentObject, PdfErrorReason> {\n const file: PdfFile = {\n id: documentId,\n content: options.buffer,\n };\n\n return this.engine.openDocumentBuffer(file, {\n password: options.password,\n });\n }\n\n private handleLoadTask(\n documentId: string,\n engineTask: Task<PdfDocumentObject, PdfErrorReason>,\n context: string,\n ): void {\n engineTask.wait(\n (pdfDocument) => {\n this.dispatchCoreAction(setDocumentLoaded(documentId, pdfDocument));\n },\n (error) => {\n this.handleLoadError(documentId, error, context);\n },\n );\n }\n\n private handleLoadError(documentId: string, error: any, context: string): void {\n const errorMessage = error.reason?.message || 'Failed to load document';\n\n this.logger.error('DocumentManagerPlugin', context, 'Failed to load document', error);\n\n this.dispatchCoreAction(\n setDocumentError(documentId, errorMessage, error.reason?.code, error.reason),\n );\n\n this.documentError$.emit({\n documentId,\n message: errorMessage,\n code: error.reason?.code,\n reason: error.reason,\n });\n }\n\n private generateDocumentId(): string {\n return `doc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private extractNameFromUrl(url: string): string | undefined {\n try {\n const urlObj = new URL(url);\n const pathname = urlObj.pathname;\n const lastSegment = pathname.split('/').pop();\n if (!lastSegment) {\n return undefined;\n }\n let filename = decodeURIComponent(lastSegment);\n if (!filename.toLowerCase().endsWith('.pdf')) {\n filename += '.pdf';\n }\n return filename;\n } catch {\n return undefined;\n }\n }\n\n // ─────────────────────────────────────────────────────────\n // Plugin Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(config: DocumentManagerPluginConfig): Promise<void> {\n this.logger.info('DocumentManagerPlugin', 'Initialize', 'Document Manager Plugin initialized', {\n maxDocuments: this.maxDocuments,\n initialDocumentsCount: config.initialDocuments?.length ?? 0,\n });\n\n // Handle initial documents from config\n if (config.initialDocuments && config.initialDocuments.length > 0) {\n // Process strictly in order\n for (const docConfig of config.initialDocuments) {\n try {\n // Type guard to distinguish between URL and Buffer options\n if ('buffer' in docConfig) {\n this.openDocumentBuffer(docConfig);\n } else if ('url' in docConfig) {\n this.openDocumentUrl(docConfig);\n }\n } catch (error) {\n this.logger.error(\n 'DocumentManagerPlugin',\n 'Initialize',\n 'Failed to initiate initial document load',\n error,\n );\n }\n }\n }\n }\n\n async destroy(): Promise<void> {\n // Close all documents\n await this.closeAllDocuments().toPromise();\n\n // Clear load options\n this.loadOptions.clear();\n\n // Clear emitters\n this.documentOpened$.clear();\n this.documentClosed$.clear();\n this.activeDocumentChanged$.clear();\n this.documentOrderChanged$.clear();\n this.documentError$.clear();\n\n super.destroy();\n }\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DOCUMENT_MANAGER_PLUGIN_ID = 'document-manager';\n\nexport const manifest: PluginManifest<DocumentManagerPluginConfig> = {\n id: DOCUMENT_MANAGER_PLUGIN_ID,\n name: 'Document Manager Plugin',\n version: '1.0.0',\n provides: ['document-manager'],\n requires: [],\n optional: [],\n defaultConfig: {\n maxDocuments: 10,\n },\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPlugin } from './document-manager-plugin';\nimport { manifest, DOCUMENT_MANAGER_PLUGIN_ID } from './manifest';\nimport { DocumentManagerPluginConfig } from './types';\n\nexport const DocumentManagerPluginPackage: PluginPackage<\n DocumentManagerPlugin,\n DocumentManagerPluginConfig\n> = {\n manifest,\n create: (registry, config) =>\n new DocumentManagerPlugin(DOCUMENT_MANAGER_PLUGIN_ID, registry, config),\n reducer: (state) => state,\n initialState: {},\n};\n\nexport * from './document-manager-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["setActiveDocumentAction","moveDocumentAction","reorderDocumentsAction","closeDocumentAction"],"mappings":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-document-manager.svelte.ts","../../src/svelte/components/FilePicker.svelte","../../src/svelte/index.ts","../../src/svelte/components/DocumentContent.svelte","../../src/svelte/components/DocumentContext.svelte"],"sourcesContent":["import { useCapability, usePlugin, useCoreState } from '@embedpdf/core/svelte';\nimport { DocumentManagerPlugin } from '@embedpdf/plugin-document-manager';\nimport type { DocumentState } from '@embedpdf/core';\n\nexport const useDocumentManagerPlugin = () =>\n usePlugin<DocumentManagerPlugin>(DocumentManagerPlugin.id);\nexport const useDocumentManagerCapability = () =>\n useCapability<DocumentManagerPlugin>(DocumentManagerPlugin.id);\n\n/**\n * Hook for active document state\n */\nexport function useActiveDocument() {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Use $derived.by for computed values that depend on the reactive coreState\n const activeDocumentId = $derived.by(() => {\n return coreStateRef.current?.activeDocumentId ?? null;\n });\n\n const activeDocument = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return null;\n\n const docId = core.activeDocumentId;\n return docId ? (core.documents[docId] ?? null) : null;\n });\n\n return {\n get activeDocumentId() {\n return activeDocumentId;\n },\n get activeDocument() {\n return activeDocument;\n },\n };\n}\n\n/**\n * Hook for all open documents (in order)\n * @param getDocumentIds Optional getter function for specific document IDs to filter/order by\n */\nexport function useOpenDocuments(getDocumentIds?: () => string[] | undefined) {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Derive documentIds reactively if getter is provided\n const documentIds = $derived(getDocumentIds ? getDocumentIds() : undefined);\n\n // Use $derived.by for computed array of documents\n const documents = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return [];\n\n // If specific documentIds are provided, use THEIR order\n if (documentIds) {\n return documentIds\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n }\n\n // Otherwise use the global document order\n return core.documentOrder\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n });\n\n return {\n get current() {\n return documents;\n },\n };\n}\n","<script lang=\"ts\">\n import { useDocumentManagerCapability, useDocumentManagerPlugin } from '../hooks';\n import type { Task } from '@embedpdf/models';\n import type { PdfErrorReason } from '@embedpdf/models';\n import type {\n OpenDocumentResponse,\n OpenFileDialogOptions,\n } from '@embedpdf/plugin-document-manager';\n\n const documentManagerPlugin = useDocumentManagerPlugin();\n const documentManagerCapability = useDocumentManagerCapability();\n\n let inputRef = $state<HTMLInputElement | null>(null);\n let taskRef = $state<Task<OpenDocumentResponse, PdfErrorReason> | null>(null);\n let optionsRef = $state<OpenFileDialogOptions | undefined>(undefined);\n\n $effect(() => {\n if (!documentManagerPlugin.plugin?.onOpenFileRequest) return;\n\n const unsubscribe = documentManagerPlugin.plugin.onOpenFileRequest(({ task, options }) => {\n taskRef = task;\n optionsRef = options;\n inputRef?.click();\n });\n\n return unsubscribe;\n });\n\n const onChange = async (event: Event) => {\n const target = event.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file || !documentManagerCapability.provides) return;\n\n const buffer = await file.arrayBuffer();\n const openTask = documentManagerCapability.provides.openDocumentBuffer({\n name: file.name,\n buffer,\n documentId: optionsRef?.documentId,\n scale: optionsRef?.scale,\n rotation: optionsRef?.rotation,\n autoActivate: optionsRef?.autoActivate,\n });\n\n openTask.wait(\n (result) => {\n taskRef?.resolve(result);\n },\n (error) => {\n taskRef?.fail(error);\n },\n );\n };\n</script>\n\n<input\n bind:this={inputRef}\n type=\"file\"\n accept=\"application/pdf\"\n style:display=\"none\"\n onchange={onChange}\n/>\n","import { createPluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPluginPackage as BaseDocumentManagerPackage } from '@embedpdf/plugin-document-manager';\n\nimport { FilePicker, DocumentContext, DocumentContent } from './components';\n\nexport * from './hooks';\nexport * from './components';\n\nexport * from '@embedpdf/plugin-document-manager';\n\nexport const DocumentManagerPluginPackage = createPluginPackage(BaseDocumentManagerPackage)\n .addUtility(FilePicker)\n .build();\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface DocumentContentRenderProps {\n documentState: DocumentState;\n isLoading: boolean;\n isError: boolean;\n isLoaded: boolean;\n }\n\n interface DocumentContentProps {\n documentId: string | null;\n children: Snippet<[DocumentContentRenderProps]>;\n }\n\n let { documentId, children }: DocumentContentProps = $props();\n\n const docState = useDocumentState(() => documentId);\n\n const isLoading = $derived(docState.current?.status === 'loading');\n const isError = $derived(docState.current?.status === 'error');\n const isLoaded = $derived(docState.current?.status === 'loaded');\n</script>\n\n<!--\n Headless component for rendering document content with loading/error states\n \n @example\n <DocumentContent {documentId}>\n {#snippet children({ documentState, isLoading, isError, isLoaded })}\n {#if isLoading}\n <LoadingSpinner />\n {:else if isError}\n <ErrorMessage />\n {:else if isLoaded}\n <PDFViewer {documentState} />\n {/if}\n {/snippet}\n </DocumentContent>\n-->\n{#if docState.current}\n {@render children({\n documentState: docState.current,\n isLoading,\n isError,\n isLoaded,\n })}\n{/if}\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useOpenDocuments, useActiveDocument, useDocumentManagerCapability } from '../hooks';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface TabActions {\n select: (documentId: string) => void;\n close: (documentId: string) => void;\n move: (documentId: string, toIndex: number) => void;\n }\n\n export interface DocumentContextRenderProps {\n documentStates: DocumentState[];\n activeDocumentId: string | null;\n actions: TabActions;\n }\n\n interface DocumentContextProps {\n children: Snippet<[DocumentContextRenderProps]>;\n }\n\n let { children }: DocumentContextProps = $props();\n\n const openDocuments = useOpenDocuments();\n const activeDoc = useActiveDocument();\n const capability = useDocumentManagerCapability();\n\n const actions: TabActions = {\n select: (documentId: string) => {\n capability.provides?.setActiveDocument(documentId);\n },\n close: (documentId: string) => {\n capability.provides?.closeDocument(documentId);\n },\n move: (documentId: string, toIndex: number) => {\n capability.provides?.moveDocument(documentId, toIndex);\n },\n };\n</script>\n\n<!--\n Headless component for managing document tabs\n Provides all state and actions, completely UI-agnostic\n \n @example\n <DocumentContext>\n {#snippet children({ documentStates, activeDocumentId, actions })}\n <div class=\"tabs\">\n {#each documentStates as doc (doc.id)}\n <button\n onclick={() => actions.select(doc.id)}\n class:active={doc.id === activeDocumentId}\n >\n {doc.name}\n <button onclick={(e) => { e.stopPropagation(); actions.close(doc.id); }}>×</button>\n </button>\n {/each}\n </div>\n {/snippet}\n </DocumentContext>\n-->\n{@render children({\n documentStates: openDocuments.current,\n activeDocumentId: activeDoc.activeDocumentId,\n actions,\n})}\n"],"names":["useDocumentManagerPlugin","usePlugin","DocumentManagerPlugin","id","useDocumentManagerCapability","useCapability","useActiveDocument","coreStateRef","useCoreState","activeDocumentId","_a","current","activeDocument","core","docId","documents","useOpenDocuments","getDocumentIds","documentIds","$","derived","get","map","filter","doc","documentOrder","documentManagerPlugin","documentManagerCapability","inputRef","taskRef","optionsRef","user_effect","plugin","onOpenFileRequest","task","options","set","click","async","event","file","target","files","provides","buffer","arrayBuffer","openDocumentBuffer","name","documentId","scale","rotation","autoActivate","wait","result","resolve","error","fail","bind_this","input","$$value","DocumentManagerPluginPackage","createPluginPackage","BaseDocumentManagerPackage","addUtility","FilePicker","build","docState","useDocumentState","$$props","isLoading","status","isError","isLoaded","documentState","$$render","consequent","openDocuments","activeDoc","capability","actions","select","setActiveDocument","close","closeDocument","move","toIndex","moveDocument","documentStates"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-document-manager.svelte.ts","../../src/svelte/components/FilePicker.svelte","../../src/svelte/index.ts","../../src/svelte/components/DocumentContent.svelte","../../src/svelte/components/DocumentContext.svelte"],"sourcesContent":["import { useCapability, usePlugin, useCoreState } from '@embedpdf/core/svelte';\nimport { DocumentManagerPlugin } from '@embedpdf/plugin-document-manager';\nimport type { DocumentState } from '@embedpdf/core';\n\nexport const useDocumentManagerPlugin = () =>\n usePlugin<DocumentManagerPlugin>(DocumentManagerPlugin.id);\nexport const useDocumentManagerCapability = () =>\n useCapability<DocumentManagerPlugin>(DocumentManagerPlugin.id);\n\n/**\n * Hook for active document state\n */\nexport function useActiveDocument() {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Use $derived.by for computed values that depend on the reactive coreState\n const activeDocumentId = $derived.by(() => {\n return coreStateRef.current?.activeDocumentId ?? null;\n });\n\n const activeDocument = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return null;\n\n const docId = core.activeDocumentId;\n return docId ? (core.documents[docId] ?? null) : null;\n });\n\n return {\n get activeDocumentId() {\n return activeDocumentId;\n },\n get activeDocument() {\n return activeDocument;\n },\n };\n}\n\n/**\n * Hook for all open documents (in order)\n * @param getDocumentIds Optional getter function for specific document IDs to filter/order by\n */\nexport function useOpenDocuments(getDocumentIds?: () => string[] | undefined) {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Derive documentIds reactively if getter is provided\n const documentIds = $derived(getDocumentIds ? getDocumentIds() : undefined);\n\n // Use $derived.by for computed array of documents\n const documents = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return [];\n\n // If specific documentIds are provided, use THEIR order\n if (documentIds) {\n return documentIds\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n }\n\n // Otherwise use the global document order\n return core.documentOrder\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n });\n\n return {\n get current() {\n return documents;\n },\n };\n}\n","<script lang=\"ts\">\n import { useDocumentManagerCapability, useDocumentManagerPlugin } from '../hooks';\n import type { Task } from '@embedpdf/models';\n import type { PdfErrorReason } from '@embedpdf/models';\n import type {\n OpenDocumentResponse,\n OpenFileDialogOptions,\n } from '@embedpdf/plugin-document-manager';\n\n const documentManagerPlugin = useDocumentManagerPlugin();\n const documentManagerCapability = useDocumentManagerCapability();\n\n let inputRef = $state<HTMLInputElement | null>(null);\n let taskRef = $state<Task<OpenDocumentResponse, PdfErrorReason> | null>(null);\n let optionsRef = $state<OpenFileDialogOptions | undefined>(undefined);\n\n $effect(() => {\n if (!documentManagerPlugin.plugin?.onOpenFileRequest) return;\n\n const unsubscribe = documentManagerPlugin.plugin.onOpenFileRequest(({ task, options }) => {\n taskRef = task;\n optionsRef = options;\n inputRef?.click();\n });\n\n return unsubscribe;\n });\n\n const onChange = async (event: Event) => {\n const target = event.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file || !documentManagerCapability.provides) return;\n\n const buffer = await file.arrayBuffer();\n const openTask = documentManagerCapability.provides.openDocumentBuffer({\n name: file.name,\n buffer,\n documentId: optionsRef?.documentId,\n scale: optionsRef?.scale,\n rotation: optionsRef?.rotation,\n autoActivate: optionsRef?.autoActivate,\n });\n\n openTask.wait(\n (result) => {\n taskRef?.resolve(result);\n },\n (error) => {\n taskRef?.fail(error);\n },\n );\n };\n</script>\n\n<input\n bind:this={inputRef}\n type=\"file\"\n accept=\"application/pdf\"\n style:display=\"none\"\n onchange={onChange}\n/>\n","import { createPluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPluginPackage as BaseDocumentManagerPackage } from '@embedpdf/plugin-document-manager';\n\nimport { FilePicker, DocumentContext, DocumentContent } from './components';\n\nexport * from './hooks';\nexport * from './components';\n\nexport * from '@embedpdf/plugin-document-manager';\n\nexport const DocumentManagerPluginPackage = createPluginPackage(BaseDocumentManagerPackage)\n .addUtility(FilePicker)\n .build();\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface DocumentContentRenderProps {\n documentState: DocumentState;\n isLoading: boolean;\n isError: boolean;\n isLoaded: boolean;\n }\n\n interface DocumentContentProps {\n documentId: string | null;\n children: Snippet<[DocumentContentRenderProps]>;\n }\n\n let { documentId, children }: DocumentContentProps = $props();\n\n const docState = useDocumentState(() => documentId);\n\n const isLoading = $derived(docState.current?.status === 'loading');\n const isError = $derived(docState.current?.status === 'error');\n const isLoaded = $derived(docState.current?.status === 'loaded');\n</script>\n\n<!--\n Headless component for rendering document content with loading/error states\n \n @example\n <DocumentContent {documentId}>\n {#snippet children({ documentState, isLoading, isError, isLoaded })}\n {#if isLoading}\n <LoadingSpinner />\n {:else if isError}\n <ErrorMessage />\n {:else if isLoaded}\n <PDFViewer {documentState} />\n {/if}\n {/snippet}\n </DocumentContent>\n-->\n{#if docState.current}\n {@render children({\n documentState: docState.current,\n isLoading,\n isError,\n isLoaded,\n })}\n{/if}\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useOpenDocuments, useActiveDocument, useDocumentManagerCapability } from '../hooks';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface TabActions {\n select: (documentId: string) => void;\n close: (documentId: string) => void;\n move: (documentId: string, toIndex: number) => void;\n }\n\n export interface DocumentContextRenderProps {\n documentStates: DocumentState[];\n activeDocumentId: string | null;\n actions: TabActions;\n }\n\n interface DocumentContextProps {\n children: Snippet<[DocumentContextRenderProps]>;\n }\n\n let { children }: DocumentContextProps = $props();\n\n const openDocuments = useOpenDocuments();\n const activeDoc = useActiveDocument();\n const capability = useDocumentManagerCapability();\n\n const actions: TabActions = {\n select: (documentId: string) => {\n capability.provides?.setActiveDocument(documentId);\n },\n close: (documentId: string) => {\n capability.provides?.closeDocument(documentId);\n },\n move: (documentId: string, toIndex: number) => {\n capability.provides?.moveDocument(documentId, toIndex);\n },\n };\n</script>\n\n<!--\n Headless component for managing document tabs\n Provides all state and actions, completely UI-agnostic\n \n @example\n <DocumentContext>\n {#snippet children({ documentStates, activeDocumentId, actions })}\n <div class=\"tabs\">\n {#each documentStates as doc (doc.id)}\n <button\n onclick={() => actions.select(doc.id)}\n class:active={doc.id === activeDocumentId}\n >\n {doc.name}\n <button onclick={(e) => { e.stopPropagation(); actions.close(doc.id); }}>×</button>\n </button>\n {/each}\n </div>\n {/snippet}\n </DocumentContext>\n-->\n{@render children({\n documentStates: openDocuments.current,\n activeDocumentId: activeDoc.activeDocumentId,\n actions,\n})}\n"],"names":["useDocumentManagerPlugin","usePlugin","DocumentManagerPlugin","id","useDocumentManagerCapability","useCapability","useActiveDocument","coreStateRef","useCoreState","activeDocumentId","_a","current","activeDocument","core","docId","documents","useOpenDocuments","getDocumentIds","documentIds","$","derived","get","map","filter","doc","documentOrder","documentManagerPlugin","documentManagerCapability","inputRef","state","taskRef","optionsRef","user_effect","plugin","onOpenFileRequest","task","options","set","click","input","root","__change","async","event","file","target","files","provides","buffer","arrayBuffer","openDocumentBuffer","name","documentId","scale","rotation","autoActivate","wait","result","resolve","error","fail","display","$$value","DocumentManagerPluginPackage","createPluginPackage","BaseDocumentManagerPackage","addUtility","FilePicker","build","docState","useDocumentState","$$props","isLoading","status","isError","isLoaded","documentState","$$render","consequent","openDocuments","activeDoc","capability","actions","select","setActiveDocument","close","closeDocument","move","toIndex","moveDocument","documentStates"],"mappings":"kjBAIaA,EAAA,IACXC,YAAiCC,EAAAA,sBAAsBC,IAC5CC,EAAA,IACXC,gBAAqCH,EAAAA,sBAAsBC,IAK7C,SAAAG,IAER,MAAAC,EAAeC,EAAAA,eAGfC,uBACG,OAAA,OAAAC,EAAAH,EAAaI,cAAb,EAAAD,EAAsBD,mBAAoB,OAG7CG,uBACEC,EAAON,EAAaI,QACrB,IAAAE,SAAa,WAEZC,EAAQD,EAAKJ,wBACZK,EAASD,EAAKE,UAAUD,IAAU,KAAQ,cAI7C,oBAAAL,gBACKA,EACT,EACI,kBAAAG,gBACKA,EACT,EAEJ,UAMgBI,EAAiBC,GAEzB,MAAAV,EAAeC,EAAAA,eAGfU,EAAAC,EAAAC,QAAA,IAAuBH,EAAiBA,YAGxCF,uBACEF,EAAON,EAAaI,eACrBE,EAGDM,EAAAE,IAAAH,SACKA,GACJI,IAAKR,GAAUD,EAAKE,UAAUD,IAC9BS,OAAQC,GAA8BA,SAIpCX,EAAKY,cACTH,IAAKR,GAAUD,EAAKE,UAAUD,IAC9BS,OAAQC,GAA8BA,SAZpC,YAgBD,WAAAb,gBACKI,EACT,EAEJ,iGChEQ,MAAAW,EAAwB1B,IACxB2B,EAA4BvB,QAE9BwB,EAAWT,EAAAU,MAAgC,MAC3CC,EAAUX,EAAAU,MAA0D,MACpEE,EAAaZ,EAAAU,WAA0C,GAE3DV,EAAAa,YAAO,gBACA,OAAAtB,EAAAgB,EAAsBO,aAAtB,EAAAvB,EAA8BwB,mBAAiB,cAEhCR,EAAsBO,OAAOC,kBAAiB,EAAIC,OAAMC,oBAC1EjB,EAAAkB,IAAAP,EAAUK,GAAI,GACdhB,EAAAkB,IAAAN,EAAaK,GAAO,GACpBjB,OAAAA,EAAAA,EAAAE,IAAAO,KAAAT,EAAUmB,gBAgCfC,EAAIC,IAAJD,EAKCE,SA/BcC,MAAUC,wBAEhBC,EAAO,OAAAlC,EADEiC,EAAME,OACDC,YAAP,EAAApC,EAAe,OACvBkC,IAASjB,EAA0BoB,SAAQ,aAE1CC,QAAeJ,EAAKK,cACTtB,EAA0BoB,SAASG,mBAAkB,CACpEC,KAAMP,EAAKO,KACXH,SACAI,WAAUjC,OAAAA,EAAAA,EAAAE,IAAEU,SAAFZ,EAAAA,EAAciC,WACxBC,MAAKlC,OAAAA,EAAAA,EAAAE,IAAEU,SAAFZ,EAAAA,EAAckC,MACnBC,SAAQnC,OAAAA,EAAAA,EAAAE,IAAEU,SAAFZ,EAAAA,EAAcmC,SACtBC,aAAYpC,OAAAA,EAAAA,EAAAE,IAAEU,SAAFZ,EAAAA,EAAcoC,eAGnBC,KACNC,yBACC3B,OAAS4B,QAAQD,IAElBE,yBACC7B,OAAS8B,KAAKD,kBAMrBpB,EAAI,GAAA,CAAA,EAAA,CAAAsB,QAAA,qBAAJtB,EAAIuB,GAAA3C,EAAAkB,IACQT,EAAQkC,GAAA,IAAA3C,EAAAE,IAARO,eADZW,UAFD,wBC1CO,MAAMwB,EAA+BC,EAAAA,oBAAoBC,EAAAA,8BAC7DC,WAAWC,GACXC,2DCOK,MAAAC,EAAWC,EAAAA,iBAAgB,IAAAC,EAAAnB,YAE3BoB,uBAAqB,MAA6B,aAA7B,OAAA9D,EAAA2D,EAAS1D,kBAAS8D,UACvCC,uBAAmB,MAA6B,WAA7B,OAAAhE,EAAA2D,EAAS1D,kBAAS8D,UACrCE,uBAAoB,MAA6B,YAA7B,OAAAjE,EAAA2D,EAAS1D,kBAAS8D,2HAqB1CG,cAAeP,EAAS1D,QACxB6D,gBAAAA,GACAE,cAAAA,GACAC,eAAAA,gCALCN,EAAS1D,SAAOkE,EAAAC,0BAlBrB,qDCDQ,MAAAC,EAAgB/D,IAChBgE,EAAY1E,IACZ2E,EAAa7E,IAEb8E,EAAmB,CACvBC,OAAS/B,UACP,OAAA1C,EAAAuE,EAAWlC,aAAUqC,kBAAkBhC,IAEzCiC,MAAQjC,UACN,OAAA1C,EAAAuE,EAAWlC,aAAUuC,cAAclC,IAErCmC,KAAI,CAAGnC,EAAoBoC,WACzB,OAAA9E,EAAAuE,EAAWlC,WAAXrC,EAAqB+E,aAAarC,EAAYoC,2EA2BlDE,eAAgBX,EAAcpE,QAC9BF,iBAAkBuE,EAAUvE,iBAC5ByE,kCA1BF"}
|
package/dist/svelte/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/svelte/hooks/use-document-manager.svelte.ts","../../src/svelte/components/FilePicker.svelte","../../src/svelte/components/DocumentContext.svelte","../../src/svelte/components/DocumentContent.svelte","../../src/svelte/index.ts"],"sourcesContent":["import { useCapability, usePlugin, useCoreState } from '@embedpdf/core/svelte';\nimport { DocumentManagerPlugin } from '@embedpdf/plugin-document-manager';\nimport type { DocumentState } from '@embedpdf/core';\n\nexport const useDocumentManagerPlugin = () =>\n usePlugin<DocumentManagerPlugin>(DocumentManagerPlugin.id);\nexport const useDocumentManagerCapability = () =>\n useCapability<DocumentManagerPlugin>(DocumentManagerPlugin.id);\n\n/**\n * Hook for active document state\n */\nexport function useActiveDocument() {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Use $derived.by for computed values that depend on the reactive coreState\n const activeDocumentId = $derived.by(() => {\n return coreStateRef.current?.activeDocumentId ?? null;\n });\n\n const activeDocument = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return null;\n\n const docId = core.activeDocumentId;\n return docId ? (core.documents[docId] ?? null) : null;\n });\n\n return {\n get activeDocumentId() {\n return activeDocumentId;\n },\n get activeDocument() {\n return activeDocument;\n },\n };\n}\n\n/**\n * Hook for all open documents (in order)\n * @param getDocumentIds Optional getter function for specific document IDs to filter/order by\n */\nexport function useOpenDocuments(getDocumentIds?: () => string[] | undefined) {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Derive documentIds reactively if getter is provided\n const documentIds = $derived(getDocumentIds ? getDocumentIds() : undefined);\n\n // Use $derived.by for computed array of documents\n const documents = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return [];\n\n // If specific documentIds are provided, use THEIR order\n if (documentIds) {\n return documentIds\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n }\n\n // Otherwise use the global document order\n return core.documentOrder\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n });\n\n return {\n get current() {\n return documents;\n },\n };\n}\n","<script lang=\"ts\">\n import { useDocumentManagerCapability, useDocumentManagerPlugin } from '../hooks';\n import type { Task } from '@embedpdf/models';\n import type { PdfErrorReason } from '@embedpdf/models';\n import type {\n OpenDocumentResponse,\n OpenFileDialogOptions,\n } from '@embedpdf/plugin-document-manager';\n\n const documentManagerPlugin = useDocumentManagerPlugin();\n const documentManagerCapability = useDocumentManagerCapability();\n\n let inputRef = $state<HTMLInputElement | null>(null);\n let taskRef = $state<Task<OpenDocumentResponse, PdfErrorReason> | null>(null);\n let optionsRef = $state<OpenFileDialogOptions | undefined>(undefined);\n\n $effect(() => {\n if (!documentManagerPlugin.plugin?.onOpenFileRequest) return;\n\n const unsubscribe = documentManagerPlugin.plugin.onOpenFileRequest(({ task, options }) => {\n taskRef = task;\n optionsRef = options;\n inputRef?.click();\n });\n\n return unsubscribe;\n });\n\n const onChange = async (event: Event) => {\n const target = event.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file || !documentManagerCapability.provides) return;\n\n const buffer = await file.arrayBuffer();\n const openTask = documentManagerCapability.provides.openDocumentBuffer({\n name: file.name,\n buffer,\n documentId: optionsRef?.documentId,\n scale: optionsRef?.scale,\n rotation: optionsRef?.rotation,\n autoActivate: optionsRef?.autoActivate,\n });\n\n openTask.wait(\n (result) => {\n taskRef?.resolve(result);\n },\n (error) => {\n taskRef?.fail(error);\n },\n );\n };\n</script>\n\n<input\n bind:this={inputRef}\n type=\"file\"\n accept=\"application/pdf\"\n style:display=\"none\"\n onchange={onChange}\n/>\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useOpenDocuments, useActiveDocument, useDocumentManagerCapability } from '../hooks';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface TabActions {\n select: (documentId: string) => void;\n close: (documentId: string) => void;\n move: (documentId: string, toIndex: number) => void;\n }\n\n export interface DocumentContextRenderProps {\n documentStates: DocumentState[];\n activeDocumentId: string | null;\n actions: TabActions;\n }\n\n interface DocumentContextProps {\n children: Snippet<[DocumentContextRenderProps]>;\n }\n\n let { children }: DocumentContextProps = $props();\n\n const openDocuments = useOpenDocuments();\n const activeDoc = useActiveDocument();\n const capability = useDocumentManagerCapability();\n\n const actions: TabActions = {\n select: (documentId: string) => {\n capability.provides?.setActiveDocument(documentId);\n },\n close: (documentId: string) => {\n capability.provides?.closeDocument(documentId);\n },\n move: (documentId: string, toIndex: number) => {\n capability.provides?.moveDocument(documentId, toIndex);\n },\n };\n</script>\n\n<!--\n Headless component for managing document tabs\n Provides all state and actions, completely UI-agnostic\n \n @example\n <DocumentContext>\n {#snippet children({ documentStates, activeDocumentId, actions })}\n <div class=\"tabs\">\n {#each documentStates as doc (doc.id)}\n <button\n onclick={() => actions.select(doc.id)}\n class:active={doc.id === activeDocumentId}\n >\n {doc.name}\n <button onclick={(e) => { e.stopPropagation(); actions.close(doc.id); }}>×</button>\n </button>\n {/each}\n </div>\n {/snippet}\n </DocumentContext>\n-->\n{@render children({\n documentStates: openDocuments.current,\n activeDocumentId: activeDoc.activeDocumentId,\n actions,\n})}\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface DocumentContentRenderProps {\n documentState: DocumentState;\n isLoading: boolean;\n isError: boolean;\n isLoaded: boolean;\n }\n\n interface DocumentContentProps {\n documentId: string | null;\n children: Snippet<[DocumentContentRenderProps]>;\n }\n\n let { documentId, children }: DocumentContentProps = $props();\n\n const docState = useDocumentState(() => documentId);\n\n const isLoading = $derived(docState.current?.status === 'loading');\n const isError = $derived(docState.current?.status === 'error');\n const isLoaded = $derived(docState.current?.status === 'loaded');\n</script>\n\n<!--\n Headless component for rendering document content with loading/error states\n \n @example\n <DocumentContent {documentId}>\n {#snippet children({ documentState, isLoading, isError, isLoaded })}\n {#if isLoading}\n <LoadingSpinner />\n {:else if isError}\n <ErrorMessage />\n {:else if isLoaded}\n <PDFViewer {documentState} />\n {/if}\n {/snippet}\n </DocumentContent>\n-->\n{#if docState.current}\n {@render children({\n documentState: docState.current,\n isLoading,\n isError,\n isLoaded,\n })}\n{/if}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPluginPackage as BaseDocumentManagerPackage } from '@embedpdf/plugin-document-manager';\n\nimport { FilePicker, DocumentContext, DocumentContent } from './components';\n\nexport * from './hooks';\nexport * from './components';\n\nexport * from '@embedpdf/plugin-document-manager';\n\nexport const DocumentManagerPluginPackage = createPluginPackage(BaseDocumentManagerPackage)\n .addUtility(FilePicker)\n .build();\n"],"names":["_a","BaseDocumentManagerPackage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/svelte/hooks/use-document-manager.svelte.ts","../../src/svelte/components/FilePicker.svelte","../../src/svelte/components/DocumentContext.svelte","../../src/svelte/components/DocumentContent.svelte","../../src/svelte/index.ts"],"sourcesContent":["import { useCapability, usePlugin, useCoreState } from '@embedpdf/core/svelte';\nimport { DocumentManagerPlugin } from '@embedpdf/plugin-document-manager';\nimport type { DocumentState } from '@embedpdf/core';\n\nexport const useDocumentManagerPlugin = () =>\n usePlugin<DocumentManagerPlugin>(DocumentManagerPlugin.id);\nexport const useDocumentManagerCapability = () =>\n useCapability<DocumentManagerPlugin>(DocumentManagerPlugin.id);\n\n/**\n * Hook for active document state\n */\nexport function useActiveDocument() {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Use $derived.by for computed values that depend on the reactive coreState\n const activeDocumentId = $derived.by(() => {\n return coreStateRef.current?.activeDocumentId ?? null;\n });\n\n const activeDocument = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return null;\n\n const docId = core.activeDocumentId;\n return docId ? (core.documents[docId] ?? null) : null;\n });\n\n return {\n get activeDocumentId() {\n return activeDocumentId;\n },\n get activeDocument() {\n return activeDocument;\n },\n };\n}\n\n/**\n * Hook for all open documents (in order)\n * @param getDocumentIds Optional getter function for specific document IDs to filter/order by\n */\nexport function useOpenDocuments(getDocumentIds?: () => string[] | undefined) {\n // Keep reference to avoid destructuring - maintains reactivity\n const coreStateRef = useCoreState();\n\n // Derive documentIds reactively if getter is provided\n const documentIds = $derived(getDocumentIds ? getDocumentIds() : undefined);\n\n // Use $derived.by for computed array of documents\n const documents = $derived.by(() => {\n const core = coreStateRef.current;\n if (!core) return [];\n\n // If specific documentIds are provided, use THEIR order\n if (documentIds) {\n return documentIds\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n }\n\n // Otherwise use the global document order\n return core.documentOrder\n .map((docId) => core.documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n });\n\n return {\n get current() {\n return documents;\n },\n };\n}\n","<script lang=\"ts\">\n import { useDocumentManagerCapability, useDocumentManagerPlugin } from '../hooks';\n import type { Task } from '@embedpdf/models';\n import type { PdfErrorReason } from '@embedpdf/models';\n import type {\n OpenDocumentResponse,\n OpenFileDialogOptions,\n } from '@embedpdf/plugin-document-manager';\n\n const documentManagerPlugin = useDocumentManagerPlugin();\n const documentManagerCapability = useDocumentManagerCapability();\n\n let inputRef = $state<HTMLInputElement | null>(null);\n let taskRef = $state<Task<OpenDocumentResponse, PdfErrorReason> | null>(null);\n let optionsRef = $state<OpenFileDialogOptions | undefined>(undefined);\n\n $effect(() => {\n if (!documentManagerPlugin.plugin?.onOpenFileRequest) return;\n\n const unsubscribe = documentManagerPlugin.plugin.onOpenFileRequest(({ task, options }) => {\n taskRef = task;\n optionsRef = options;\n inputRef?.click();\n });\n\n return unsubscribe;\n });\n\n const onChange = async (event: Event) => {\n const target = event.target as HTMLInputElement;\n const file = target.files?.[0];\n if (!file || !documentManagerCapability.provides) return;\n\n const buffer = await file.arrayBuffer();\n const openTask = documentManagerCapability.provides.openDocumentBuffer({\n name: file.name,\n buffer,\n documentId: optionsRef?.documentId,\n scale: optionsRef?.scale,\n rotation: optionsRef?.rotation,\n autoActivate: optionsRef?.autoActivate,\n });\n\n openTask.wait(\n (result) => {\n taskRef?.resolve(result);\n },\n (error) => {\n taskRef?.fail(error);\n },\n );\n };\n</script>\n\n<input\n bind:this={inputRef}\n type=\"file\"\n accept=\"application/pdf\"\n style:display=\"none\"\n onchange={onChange}\n/>\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useOpenDocuments, useActiveDocument, useDocumentManagerCapability } from '../hooks';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface TabActions {\n select: (documentId: string) => void;\n close: (documentId: string) => void;\n move: (documentId: string, toIndex: number) => void;\n }\n\n export interface DocumentContextRenderProps {\n documentStates: DocumentState[];\n activeDocumentId: string | null;\n actions: TabActions;\n }\n\n interface DocumentContextProps {\n children: Snippet<[DocumentContextRenderProps]>;\n }\n\n let { children }: DocumentContextProps = $props();\n\n const openDocuments = useOpenDocuments();\n const activeDoc = useActiveDocument();\n const capability = useDocumentManagerCapability();\n\n const actions: TabActions = {\n select: (documentId: string) => {\n capability.provides?.setActiveDocument(documentId);\n },\n close: (documentId: string) => {\n capability.provides?.closeDocument(documentId);\n },\n move: (documentId: string, toIndex: number) => {\n capability.provides?.moveDocument(documentId, toIndex);\n },\n };\n</script>\n\n<!--\n Headless component for managing document tabs\n Provides all state and actions, completely UI-agnostic\n \n @example\n <DocumentContext>\n {#snippet children({ documentStates, activeDocumentId, actions })}\n <div class=\"tabs\">\n {#each documentStates as doc (doc.id)}\n <button\n onclick={() => actions.select(doc.id)}\n class:active={doc.id === activeDocumentId}\n >\n {doc.name}\n <button onclick={(e) => { e.stopPropagation(); actions.close(doc.id); }}>×</button>\n </button>\n {/each}\n </div>\n {/snippet}\n </DocumentContext>\n-->\n{@render children({\n documentStates: openDocuments.current,\n activeDocumentId: activeDoc.activeDocumentId,\n actions,\n})}\n","<script lang=\"ts\">\n import type { Snippet } from 'svelte';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import type { DocumentState } from '@embedpdf/core';\n\n export interface DocumentContentRenderProps {\n documentState: DocumentState;\n isLoading: boolean;\n isError: boolean;\n isLoaded: boolean;\n }\n\n interface DocumentContentProps {\n documentId: string | null;\n children: Snippet<[DocumentContentRenderProps]>;\n }\n\n let { documentId, children }: DocumentContentProps = $props();\n\n const docState = useDocumentState(() => documentId);\n\n const isLoading = $derived(docState.current?.status === 'loading');\n const isError = $derived(docState.current?.status === 'error');\n const isLoaded = $derived(docState.current?.status === 'loaded');\n</script>\n\n<!--\n Headless component for rendering document content with loading/error states\n \n @example\n <DocumentContent {documentId}>\n {#snippet children({ documentState, isLoading, isError, isLoaded })}\n {#if isLoading}\n <LoadingSpinner />\n {:else if isError}\n <ErrorMessage />\n {:else if isLoaded}\n <PDFViewer {documentState} />\n {/if}\n {/snippet}\n </DocumentContent>\n-->\n{#if docState.current}\n {@render children({\n documentState: docState.current,\n isLoading,\n isError,\n isLoaded,\n })}\n{/if}\n","import { createPluginPackage } from '@embedpdf/core';\nimport { DocumentManagerPluginPackage as BaseDocumentManagerPackage } from '@embedpdf/plugin-document-manager';\n\nimport { FilePicker, DocumentContext, DocumentContent } from './components';\n\nexport * from './hooks';\nexport * from './components';\n\nexport * from '@embedpdf/plugin-document-manager';\n\nexport const DocumentManagerPluginPackage = createPluginPackage(BaseDocumentManagerPackage)\n .addUtility(FilePicker)\n .build();\n"],"names":["_a","BaseDocumentManagerPackage"],"mappings":"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"}
|
|
@@ -10,10 +10,10 @@ interface DocumentContentProps {
|
|
|
10
10
|
documentId: MaybeRefOrGetter<string | null>;
|
|
11
11
|
}
|
|
12
12
|
declare var __VLS_1: {
|
|
13
|
-
documentState:
|
|
14
|
-
isLoading:
|
|
15
|
-
isError:
|
|
16
|
-
isLoaded:
|
|
13
|
+
documentState: DocumentState;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
isError: boolean;
|
|
16
|
+
isLoaded: boolean;
|
|
17
17
|
};
|
|
18
18
|
type __VLS_Slots = {} & {
|
|
19
19
|
default?: (props: typeof __VLS_1) => any;
|
|
@@ -10,9 +10,9 @@ export interface DocumentContextRenderProps {
|
|
|
10
10
|
actions: TabActions;
|
|
11
11
|
}
|
|
12
12
|
declare var __VLS_1: {
|
|
13
|
-
documentStates:
|
|
14
|
-
activeDocumentId:
|
|
15
|
-
actions:
|
|
13
|
+
documentStates: DocumentState[];
|
|
14
|
+
activeDocumentId: string | null;
|
|
15
|
+
actions: TabActions;
|
|
16
16
|
};
|
|
17
17
|
type __VLS_Slots = {} & {
|
|
18
18
|
default?: (props: typeof __VLS_1) => any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@embedpdf/plugin-document-manager",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@embedpdf/models": "2.0.
|
|
37
|
+
"@embedpdf/models": "2.0.1"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/react": "^18.2.0",
|
|
41
41
|
"typescript": "^5.0.0",
|
|
42
42
|
"@embedpdf/build": "1.1.0",
|
|
43
|
-
"@embedpdf/core": "2.0.
|
|
43
|
+
"@embedpdf/core": "2.0.1"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": ">=16.8.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"preact": "^10.26.4",
|
|
49
49
|
"vue": ">=3.2.0",
|
|
50
50
|
"svelte": ">=5 <6",
|
|
51
|
-
"@embedpdf/core": "2.0.
|
|
51
|
+
"@embedpdf/core": "2.0.1"
|
|
52
52
|
},
|
|
53
53
|
"files": [
|
|
54
54
|
"dist",
|