@embedpdf/core 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact"),n=require("preact/hooks"),i=require("preact/jsx-runtime"),t=require("@embedpdf/core"),s=require("@embedpdf/models"),o=e.createContext({registry:null,coreState:null,isInitializing:!0,pluginsReady:!1,activeDocumentId:null,activeDocument:null,documents:{},documentStates:[]});function r({plugins:s,children:o}){const{utilities:r,wrappers:l}=n.useMemo(()=>{const e=[],n=[];for(const i of s){const s=i.package;if(t.hasAutoMountElements(s)){const i=s.autoMountElements()||[];for(const t of i)"utility"===t.type?e.push(t.component):"wrapper"===t.type&&n.push(t.component)}}return{utilities:e,wrappers:n}},[s]),u=l.reduce((e,n)=>i.jsx(n,{children:e}),o);return i.jsxs(e.Fragment,{children:[u,r.map((e,n)=>i.jsx(e,{},`utility-${n}`))]})}function l(){const e=n.useContext(o);if(void 0===e)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:i,isInitializing:t}=e;if(t)return e;if(null===i)throw new Error("PDF registry failed to initialize properly");return e}function u(e){const{registry:n}=l();if(null===n)return{plugin:null,isLoading:!0,ready:new Promise(()=>{})};const i=n.getPlugin(e);if(!i)throw new Error(`Plugin ${e} not found`);return{plugin:i,isLoading:!1,ready:i.ready()}}function a(){const{coreState:e}=n.useContext(o);return e}s.PdfPermissionFlag.Print,s.PdfPermissionFlag.ModifyContents,s.PdfPermissionFlag.CopyContents,s.PdfPermissionFlag.ModifyAnnotations,s.PdfPermissionFlag.FillForms,s.PdfPermissionFlag.ExtractForAccessibility,s.PdfPermissionFlag.AssembleDocument,s.PdfPermissionFlag.PrintHighQuality;const c=[s.PdfPermissionFlag.Print,s.PdfPermissionFlag.ModifyContents,s.PdfPermissionFlag.CopyContents,s.PdfPermissionFlag.ModifyAnnotations,s.PdfPermissionFlag.FillForms,s.PdfPermissionFlag.ExtractForAccessibility,s.PdfPermissionFlag.AssembleDocument,s.PdfPermissionFlag.PrintHighQuality],d={[s.PdfPermissionFlag.Print]:"print",[s.PdfPermissionFlag.ModifyContents]:"modifyContents",[s.PdfPermissionFlag.CopyContents]:"copyContents",[s.PdfPermissionFlag.ModifyAnnotations]:"modifyAnnotations",[s.PdfPermissionFlag.FillForms]:"fillForms",[s.PdfPermissionFlag.ExtractForAccessibility]:"extractForAccessibility",[s.PdfPermissionFlag.AssembleDocument]:"assembleDocument",[s.PdfPermissionFlag.PrintHighQuality]:"printHighQuality"};function m(e,n){if(!e)return;if(n in e)return e[n];const i=d[n];return i&&i in e?e[i]:void 0}function P(e,n,i){var t;const o=e.documents[n],r=null==o?void 0:o.permissions,l=e.globalPermissions,u=(null==(t=null==o?void 0:o.document)?void 0:t.permissions)??s.PdfPermissionFlag.AllowAll,a=m(null==r?void 0:r.overrides,i);if(void 0!==a)return a;const c=m(null==l?void 0:l.overrides,i);if(void 0!==c)return c;return!((null==r?void 0:r.enforceDocumentPermissions)??(null==l?void 0:l.enforceDocumentPermissions)??!0)||0!==(u&i)}exports.EmbedPDF=function({engine:e,config:s,logger:l,onInitialized:u,plugins:a,children:c,autoMountDomElements:d=!0}){const[m,P]=n.useState(null),[f,g]=n.useState(null),[y,p]=n.useState(!0),[F,v]=n.useState(!1),A=n.useRef(u);n.useEffect(()=>{A.current=u},[u]),n.useEffect(()=>{const n={...s,logger:(null==s?void 0:s.logger)??l},i=new t.PluginRegistry(e,n);i.registerPluginBatch(a);let o;return(async()=>{var e;if(await i.initialize(),i.isDestroyed())return;const n=i.getStore();g(n.getState().core);const t=n.subscribe((e,i,t)=>{n.isCoreAction(e)&&i.core!==t.core&&g(i.core)});if(await(null==(e=A.current)?void 0:e.call(A,i)),!i.isDestroyed())return i.pluginsReady().then(()=>{i.isDestroyed()||v(!0)}),P(i),p(!1),t;t()})().then(e=>{o=e}).catch(console.error),()=>{null==o||o(),i.destroy(),P(null),g(null),p(!0),v(!1)}},[e,a]);const h=n.useMemo(()=>{const e=(null==f?void 0:f.activeDocumentId)??null,n=(null==f?void 0:f.documents)??{},i=(null==f?void 0:f.documentOrder)??[],t=e&&n[e]?n[e]:null,s=i.map(e=>n[e]).filter(e=>null!=e);return{registry:m,coreState:f,isInitializing:y,pluginsReady:F,activeDocumentId:e,activeDocument:t,documents:n,documentStates:s}},[m,f,y,F]),C="function"==typeof c?c(h):c;return i.jsx(o.Provider,{value:h,children:F&&d?i.jsx(r,{plugins:a,children:C}):C})},exports.PDFContext=o,exports.useCapability=function(e){const{plugin:n,isLoading:i,ready:t}=u(e);if(!n)return{provides:null,isLoading:i,ready:t};if(!n.provides)throw new Error(`Plugin ${e} does not provide a capability`);return{provides:n.provides(),isLoading:i,ready:t}},exports.useCoreState=a,exports.useDocumentPermissions=function(e){const i=a();return n.useMemo(()=>{var n,t;if(!i)return{permissions:s.PdfPermissionFlag.AllowAll,pdfPermissions:s.PdfPermissionFlag.AllowAll,hasPermission:()=>!0,hasAllPermissions:()=>!0,canPrint:!0,canModifyContents:!0,canCopyContents:!0,canModifyAnnotations:!0,canFillForms:!0,canExtractForAccessibility:!0,canAssembleDocument:!0,canPrintHighQuality:!0};const o=function(e,n){return c.reduce((i,t)=>P(e,n,t)?i|t:i,0)}(i,e),r=n=>P(i,e,n);return{permissions:o,pdfPermissions:(null==(t=null==(n=i.documents[e])?void 0:n.document)?void 0:t.permissions)??s.PdfPermissionFlag.AllowAll,hasPermission:r,hasAllPermissions:(...n)=>n.every(n=>P(i,e,n)),canPrint:r(s.PdfPermissionFlag.Print),canModifyContents:r(s.PdfPermissionFlag.ModifyContents),canCopyContents:r(s.PdfPermissionFlag.CopyContents),canModifyAnnotations:r(s.PdfPermissionFlag.ModifyAnnotations),canFillForms:r(s.PdfPermissionFlag.FillForms),canExtractForAccessibility:r(s.PdfPermissionFlag.ExtractForAccessibility),canAssembleDocument:r(s.PdfPermissionFlag.AssembleDocument),canPrintHighQuality:r(s.PdfPermissionFlag.PrintHighQuality)}},[i,e])},exports.useDocumentState=function(e){const i=a();return n.useMemo(()=>i&&e?i.documents[e]??null:null,[i,e])},exports.usePlugin=u,exports.useRegistry=l,exports.useStoreState=function(){const{registry:e}=l(),[i,t]=n.useState(null);return n.useEffect(()=>{if(!e)return;t(e.getStore().getState());const n=e.getStore().subscribe((e,n)=>{t(n)});return()=>n()},[e]),i};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact"),n=require("preact/hooks"),i=require("preact/jsx-runtime"),t=require("@embedpdf/core"),s=require("@embedpdf/models"),o=e.createContext({registry:null,coreState:null,isInitializing:!0,pluginsReady:!1,activeDocumentId:null,activeDocument:null,documents:{},documentStates:[]});function r({plugins:s,children:o}){const{utilities:r,wrappers:l}=n.useMemo(()=>{const e=[],n=[];for(const i of s){const s=i.package;if(t.hasAutoMountElements(s)){const i=s.autoMountElements()||[];for(const t of i)"utility"===t.type?e.push(t.component):"wrapper"===t.type&&n.push(t.component)}}return{utilities:e,wrappers:n}},[s]),u=i.jsxs(e.Fragment,{children:[o,r.map((e,n)=>i.jsx(e,{},`utility-${n}`))]}),a=l.reduce((e,n)=>i.jsx(n,{children:e}),u);return i.jsx(e.Fragment,{children:a})}function l(){const e=n.useContext(o);if(void 0===e)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:i,isInitializing:t}=e;if(t)return e;if(null===i)throw new Error("PDF registry failed to initialize properly");return e}function u(e){const{registry:n}=l();if(null===n)return{plugin:null,isLoading:!0,ready:new Promise(()=>{})};const i=n.getPlugin(e);if(!i)throw new Error(`Plugin ${e} not found`);return{plugin:i,isLoading:!1,ready:i.ready()}}function a(){const{coreState:e}=n.useContext(o);return e}s.PdfPermissionFlag.Print,s.PdfPermissionFlag.ModifyContents,s.PdfPermissionFlag.CopyContents,s.PdfPermissionFlag.ModifyAnnotations,s.PdfPermissionFlag.FillForms,s.PdfPermissionFlag.ExtractForAccessibility,s.PdfPermissionFlag.AssembleDocument,s.PdfPermissionFlag.PrintHighQuality;const c=[s.PdfPermissionFlag.Print,s.PdfPermissionFlag.ModifyContents,s.PdfPermissionFlag.CopyContents,s.PdfPermissionFlag.ModifyAnnotations,s.PdfPermissionFlag.FillForms,s.PdfPermissionFlag.ExtractForAccessibility,s.PdfPermissionFlag.AssembleDocument,s.PdfPermissionFlag.PrintHighQuality],d={[s.PdfPermissionFlag.Print]:"print",[s.PdfPermissionFlag.ModifyContents]:"modifyContents",[s.PdfPermissionFlag.CopyContents]:"copyContents",[s.PdfPermissionFlag.ModifyAnnotations]:"modifyAnnotations",[s.PdfPermissionFlag.FillForms]:"fillForms",[s.PdfPermissionFlag.ExtractForAccessibility]:"extractForAccessibility",[s.PdfPermissionFlag.AssembleDocument]:"assembleDocument",[s.PdfPermissionFlag.PrintHighQuality]:"printHighQuality"};function m(e,n){if(!e)return;if(n in e)return e[n];const i=d[n];return i&&i in e?e[i]:void 0}function P(e,n,i){var t;const o=e.documents[n],r=null==o?void 0:o.permissions,l=e.globalPermissions,u=(null==(t=null==o?void 0:o.document)?void 0:t.permissions)??s.PdfPermissionFlag.AllowAll,a=m(null==r?void 0:r.overrides,i);if(void 0!==a)return a;const c=m(null==l?void 0:l.overrides,i);if(void 0!==c)return c;return!((null==r?void 0:r.enforceDocumentPermissions)??(null==l?void 0:l.enforceDocumentPermissions)??!0)||0!==(u&i)}exports.EmbedPDF=function({engine:e,config:s,logger:l,onInitialized:u,plugins:a,children:c,autoMountDomElements:d=!0}){const[m,P]=n.useState(null),[f,g]=n.useState(null),[y,p]=n.useState(!0),[F,v]=n.useState(!1),A=n.useRef(u);n.useEffect(()=>{A.current=u},[u]),n.useEffect(()=>{const n={...s,logger:(null==s?void 0:s.logger)??l},i=new t.PluginRegistry(e,n);i.registerPluginBatch(a);let o;return(async()=>{var e;if(await i.initialize(),i.isDestroyed())return;const n=i.getStore();g(n.getState().core);const t=n.subscribe((e,i,t)=>{n.isCoreAction(e)&&i.core!==t.core&&g(i.core)});if(await(null==(e=A.current)?void 0:e.call(A,i)),!i.isDestroyed())return i.pluginsReady().then(()=>{i.isDestroyed()||v(!0)}),P(i),p(!1),t;t()})().then(e=>{o=e}).catch(console.error),()=>{null==o||o(),i.destroy(),P(null),g(null),p(!0),v(!1)}},[e,a]);const h=n.useMemo(()=>{const e=(null==f?void 0:f.activeDocumentId)??null,n=(null==f?void 0:f.documents)??{},i=(null==f?void 0:f.documentOrder)??[],t=e&&n[e]?n[e]:null,s=i.map(e=>n[e]).filter(e=>null!=e);return{registry:m,coreState:f,isInitializing:y,pluginsReady:F,activeDocumentId:e,activeDocument:t,documents:n,documentStates:s}},[m,f,y,F]),x="function"==typeof c?c(h):c;return i.jsx(o.Provider,{value:h,children:F&&d?i.jsx(r,{plugins:a,children:x}):x})},exports.PDFContext=o,exports.useCapability=function(e){const{plugin:n,isLoading:i,ready:t}=u(e);if(!n)return{provides:null,isLoading:i,ready:t};if(!n.provides)throw new Error(`Plugin ${e} does not provide a capability`);return{provides:n.provides(),isLoading:i,ready:t}},exports.useCoreState=a,exports.useDocumentPermissions=function(e){const i=a();return n.useMemo(()=>{var n,t;if(!i)return{permissions:s.PdfPermissionFlag.AllowAll,pdfPermissions:s.PdfPermissionFlag.AllowAll,hasPermission:()=>!0,hasAllPermissions:()=>!0,canPrint:!0,canModifyContents:!0,canCopyContents:!0,canModifyAnnotations:!0,canFillForms:!0,canExtractForAccessibility:!0,canAssembleDocument:!0,canPrintHighQuality:!0};const o=function(e,n){return c.reduce((i,t)=>P(e,n,t)?i|t:i,0)}(i,e),r=n=>P(i,e,n);return{permissions:o,pdfPermissions:(null==(t=null==(n=i.documents[e])?void 0:n.document)?void 0:t.permissions)??s.PdfPermissionFlag.AllowAll,hasPermission:r,hasAllPermissions:(...n)=>n.every(n=>P(i,e,n)),canPrint:r(s.PdfPermissionFlag.Print),canModifyContents:r(s.PdfPermissionFlag.ModifyContents),canCopyContents:r(s.PdfPermissionFlag.CopyContents),canModifyAnnotations:r(s.PdfPermissionFlag.ModifyAnnotations),canFillForms:r(s.PdfPermissionFlag.FillForms),canExtractForAccessibility:r(s.PdfPermissionFlag.ExtractForAccessibility),canAssembleDocument:r(s.PdfPermissionFlag.AssembleDocument),canPrintHighQuality:r(s.PdfPermissionFlag.PrintHighQuality)}},[i,e])},exports.useDocumentState=function(e){const i=a();return n.useMemo(()=>i&&e?i.documents[e]??null:null,[i,e])},exports.usePlugin=u,exports.useRegistry=l,exports.useStoreState=function(){const{registry:e}=l(),[i,t]=n.useState(null);return n.useEffect(()=>{if(!e)return;t(e.getStore().getState());const n=e.getStore().subscribe((e,n)=>{t(n)});return()=>n()},[e]),i};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/components/auto-mount.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/hooks/use-core-state.ts","../../src/lib/types/permissions.ts","../../src/lib/store/selectors.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-document-permissions.ts","../../src/shared/hooks/use-document-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { CoreState, DocumentState, PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n coreState: CoreState | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: string | null;\n activeDocument: DocumentState | null;\n documents: Record<string, DocumentState>;\n documentStates: DocumentState[];\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n coreState: null,\n isInitializing: true,\n pluginsReady: false,\n activeDocumentId: null,\n activeDocument: null,\n documents: {},\n documentStates: [],\n});\n","import { Fragment, useMemo, ComponentType, ReactNode } from '@framework';\nimport { hasAutoMountElements } from '@embedpdf/core';\nimport type { PluginBatchRegistration, IPlugin } from '@embedpdf/core';\n\ninterface AutoMountProps {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode;\n}\n\nexport function AutoMount({ plugins, children }: AutoMountProps) {\n const { utilities, wrappers } = useMemo(() => {\n // React-specific types for internal use\n const utilities: ComponentType[] = [];\n const wrappers: ComponentType<{ children: ReactNode }>[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements() || [];\n\n for (const element of elements) {\n if (element.type === 'utility') {\n utilities.push(element.component);\n } else if (element.type === 'wrapper') {\n // In React context, we know wrappers need children\n wrappers.push(element.component);\n }\n }\n }\n }\n return { utilities, wrappers };\n }, [plugins]);\n\n // React-specific wrapping logic\n const wrappedContent = wrappers.reduce(\n (content, Wrapper) => <Wrapper>{content}</Wrapper>,\n children,\n );\n\n return (\n <Fragment>\n {wrappedContent}\n {utilities.map((Utility, i) => (\n <Utility key={`utility-${i}`} />\n ))}\n </Fragment>\n );\n}\n","import { useContext } from '@framework';\nimport { PDFContext, PDFContextState } from '../context';\n\n/**\n * Hook to access the PDF registry.\n * @returns The PDF registry or null during initialization\n */\nexport function useRegistry(): PDFContextState {\n const contextValue = useContext(PDFContext);\n\n // Error if used outside of context\n if (contextValue === undefined) {\n throw new Error('useCapability must be used within a PDFContext.Provider');\n }\n\n const { registry, isInitializing } = contextValue;\n\n // During initialization, return null instead of throwing an error\n if (isInitializing) {\n return contextValue;\n }\n\n // At this point, initialization is complete but registry is still null, which is unexpected\n if (registry === null) {\n throw new Error('PDF registry failed to initialize properly');\n }\n\n return contextValue;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\ntype PluginState<T extends BasePlugin> = {\n plugin: T | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin.\n * @param pluginId The ID of the plugin to access\n * @returns The plugin or null during initialization\n * @example\n * // Get zoom plugin\n * const zoom = usePlugin<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n if (registry === null) {\n return {\n plugin: null,\n isLoading: true,\n ready: new Promise(() => {}),\n };\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n return {\n plugin,\n isLoading: false,\n ready: plugin.ready(),\n };\n}\n","import { useContext } from '@framework';\nimport { CoreState } from '@embedpdf/core';\nimport { PDFContext } from '../context';\n\n/**\n * Hook that provides access to the current core state.\n *\n * Note: This reads from the context which is already subscribed to core state changes\n * in the EmbedPDF component, so there's no additional subscription overhead.\n */\nexport function useCoreState(): CoreState | null {\n const { coreState } = useContext(PDFContext);\n return coreState;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\n\n/**\n * Human-readable permission names for use in configuration.\n */\nexport type PermissionName =\n | 'print'\n | 'modifyContents'\n | 'copyContents'\n | 'modifyAnnotations'\n | 'fillForms'\n | 'extractForAccessibility'\n | 'assembleDocument'\n | 'printHighQuality';\n\n/**\n * Map from human-readable names to PdfPermissionFlag values.\n */\nexport const PERMISSION_NAME_TO_FLAG: Record<PermissionName, PdfPermissionFlag> = {\n print: PdfPermissionFlag.Print,\n modifyContents: PdfPermissionFlag.ModifyContents,\n copyContents: PdfPermissionFlag.CopyContents,\n modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,\n fillForms: PdfPermissionFlag.FillForms,\n extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,\n assembleDocument: PdfPermissionFlag.AssembleDocument,\n printHighQuality: PdfPermissionFlag.PrintHighQuality,\n};\n\n/**\n * Permission overrides can use either numeric flags or human-readable string names.\n */\nexport type PermissionOverrides = Partial<\n Record<PdfPermissionFlag, boolean> & Record<PermissionName, boolean>\n>;\n\n/**\n * Configuration for overriding document permissions.\n * Can be applied globally (at PluginRegistry level) or per-document (when opening).\n */\nexport interface PermissionConfig {\n /**\n * When true (default): use PDF's permissions as the base, then apply overrides.\n * When false: treat document as having all permissions allowed, then apply overrides.\n */\n enforceDocumentPermissions?: boolean;\n\n /**\n * Explicit per-flag overrides. Supports both numeric flags and string names.\n * - true = force allow (even if PDF denies)\n * - false = force deny (even if PDF allows)\n * - undefined = use base permissions\n *\n * @example\n * // Using string names (recommended)\n * overrides: { print: false, modifyAnnotations: true }\n *\n * @example\n * // Using numeric flags\n * overrides: { [PdfPermissionFlag.Print]: false }\n */\n overrides?: PermissionOverrides;\n}\n\n/**\n * All permission flags for iteration when computing effective permissions.\n */\nexport const ALL_PERMISSION_FLAGS: PdfPermissionFlag[] = [\n PdfPermissionFlag.Print,\n PdfPermissionFlag.ModifyContents,\n PdfPermissionFlag.CopyContents,\n PdfPermissionFlag.ModifyAnnotations,\n PdfPermissionFlag.FillForms,\n PdfPermissionFlag.ExtractForAccessibility,\n PdfPermissionFlag.AssembleDocument,\n PdfPermissionFlag.PrintHighQuality,\n];\n\n/**\n * All permission names for iteration.\n */\nexport const ALL_PERMISSION_NAMES: PermissionName[] = [\n 'print',\n 'modifyContents',\n 'copyContents',\n 'modifyAnnotations',\n 'fillForms',\n 'extractForAccessibility',\n 'assembleDocument',\n 'printHighQuality',\n];\n\n/**\n * Map from PdfPermissionFlag to human-readable name.\n */\nexport const PERMISSION_FLAG_TO_NAME: Record<PdfPermissionFlag, PermissionName> = {\n [PdfPermissionFlag.Print]: 'print',\n [PdfPermissionFlag.ModifyContents]: 'modifyContents',\n [PdfPermissionFlag.CopyContents]: 'copyContents',\n [PdfPermissionFlag.ModifyAnnotations]: 'modifyAnnotations',\n [PdfPermissionFlag.FillForms]: 'fillForms',\n [PdfPermissionFlag.ExtractForAccessibility]: 'extractForAccessibility',\n [PdfPermissionFlag.AssembleDocument]: 'assembleDocument',\n [PdfPermissionFlag.PrintHighQuality]: 'printHighQuality',\n};\n\n/**\n * Helper to get the override value for a permission flag, checking both numeric and string keys.\n */\nexport function getPermissionOverride(\n overrides: PermissionOverrides | undefined,\n flag: PdfPermissionFlag,\n): boolean | undefined {\n if (!overrides) return undefined;\n\n // Check numeric key first\n if (flag in overrides) {\n return (overrides as Record<PdfPermissionFlag, boolean>)[flag];\n }\n\n // Check string key\n const name = PERMISSION_FLAG_TO_NAME[flag];\n if (name && name in overrides) {\n return (overrides as Record<PermissionName, boolean>)[name];\n }\n\n return undefined;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\nimport { CoreState, DocumentState } from './initial-state';\nimport { ALL_PERMISSION_FLAGS, getPermissionOverride } from '../types/permissions';\n\n/**\n * Get the active document state\n */\nexport const getActiveDocumentState = (state: CoreState): DocumentState | null => {\n if (!state.activeDocumentId) return null;\n return state.documents[state.activeDocumentId] ?? null;\n};\n\n/**\n * Get document state by ID\n */\nexport const getDocumentState = (state: CoreState, documentId: string): DocumentState | null => {\n return state.documents[documentId] ?? null;\n};\n\n/**\n * Get all document IDs\n */\nexport const getDocumentIds = (state: CoreState): string[] => {\n return Object.keys(state.documents);\n};\n\n/**\n * Check if a document is loaded\n */\nexport const isDocumentLoaded = (state: CoreState, documentId: string): boolean => {\n return !!state.documents[documentId];\n};\n\n/**\n * Get the number of open documents\n */\nexport const getDocumentCount = (state: CoreState): number => {\n return Object.keys(state.documents).length;\n};\n\n// ─────────────────────────────────────────────────────────\n// Permission Selectors\n// ─────────────────────────────────────────────────────────\n\n/**\n * Check if a specific permission flag is effectively allowed for a document.\n * Applies layered resolution: per-document override → global override → enforceDocumentPermissions → PDF permission.\n *\n * @param state - The core state\n * @param documentId - The document ID to check permissions for\n * @param flag - The permission flag to check\n * @returns true if the permission is allowed, false otherwise\n */\nexport function getEffectivePermission(\n state: CoreState,\n documentId: string,\n flag: PdfPermissionFlag,\n): boolean {\n const docState = state.documents[documentId];\n const docConfig = docState?.permissions;\n const globalConfig = state.globalPermissions;\n const pdfPermissions = docState?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n // 1. Per-document override wins (supports both numeric and string keys)\n const docOverride = getPermissionOverride(docConfig?.overrides, flag);\n if (docOverride !== undefined) {\n return docOverride;\n }\n\n // 2. Global override (supports both numeric and string keys)\n const globalOverride = getPermissionOverride(globalConfig?.overrides, flag);\n if (globalOverride !== undefined) {\n return globalOverride;\n }\n\n // 3. Check enforce setting (per-doc takes precedence over global)\n const enforce =\n docConfig?.enforceDocumentPermissions ?? globalConfig?.enforceDocumentPermissions ?? true;\n\n if (!enforce) return true; // Not enforcing = allow all\n\n // 4. Use PDF permission\n return (pdfPermissions & flag) !== 0;\n}\n\n/**\n * Get all effective permissions as a bitmask for a document.\n * Combines all individual permission checks into a single bitmask.\n *\n * @param state - The core state\n * @param documentId - The document ID to get permissions for\n * @returns A bitmask of all effective permissions\n */\nexport function getEffectivePermissions(state: CoreState, documentId: string): number {\n return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {\n return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;\n }, 0);\n}\n","import { useState, useEffect, useRef, useMemo, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry, CoreState, DocumentState, PluginRegistryConfig } from '@embedpdf/core';\nimport type { PluginBatchRegistrations } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\nimport { AutoMount } from './auto-mount';\n\nexport type { PluginBatchRegistrations };\n\ninterface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * Registry configuration including logger, permissions, and defaults.\n */\n config?: PluginRegistryConfig;\n /**\n * @deprecated Use config.logger instead. Will be removed in next major version.\n */\n logger?: Logger;\n /**\n * The callback to call when the PDF viewer is initialized.\n */\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n /**\n * The plugins to use for the PDF viewer.\n */\n plugins: PluginBatchRegistrations;\n /**\n * The children to render for the PDF viewer.\n */\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n}\n\nexport function EmbedPDF({\n engine,\n config,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n}: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n const [isInitializing, setIsInitializing] = useState<boolean>(true);\n const [pluginsReady, setPluginsReady] = useState<boolean>(false);\n const initRef = useRef<EmbedPDFProps['onInitialized']>(onInitialized);\n\n useEffect(() => {\n initRef.current = onInitialized;\n }, [onInitialized]);\n\n useEffect(() => {\n // Merge deprecated logger prop into config (config.logger takes precedence)\n const finalConfig: PluginRegistryConfig = {\n ...config,\n logger: config?.logger ?? logger,\n };\n const pdfViewer = new PluginRegistry(engine, finalConfig);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n const store = pdfViewer.getStore();\n setCoreState(store.getState().core);\n\n const unsubscribe = store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && newState.core !== oldState.core) {\n setCoreState(newState.core);\n }\n });\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n if (pdfViewer.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n pdfViewer.pluginsReady().then(() => {\n if (!pdfViewer.isDestroyed()) {\n setPluginsReady(true);\n }\n });\n\n // Provide the registry to children via context\n setRegistry(pdfViewer);\n setIsInitializing(false);\n\n // Return cleanup function\n return unsubscribe;\n };\n\n let cleanup: (() => void) | undefined;\n initialize()\n .then((unsub) => {\n cleanup = unsub;\n })\n .catch(console.error);\n\n return () => {\n cleanup?.();\n pdfViewer.destroy();\n setRegistry(null);\n setCoreState(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n // Compute convenience accessors\n const contextValue: PDFContextState = useMemo(() => {\n const activeDocumentId = coreState?.activeDocumentId ?? null;\n const documents = coreState?.documents ?? {};\n const documentOrder = coreState?.documentOrder ?? [];\n\n // Compute active document\n const activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n\n // Compute open documents in order\n const documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n\n return {\n registry,\n coreState,\n isInitializing,\n pluginsReady,\n // Convenience accessors (always safe to use)\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n };\n }, [registry, coreState, isInitializing, pluginsReady]);\n\n const content = typeof children === 'function' ? children(contextValue) : children;\n\n return (\n <PDFContext.Provider value={contextValue}>\n {pluginsReady && autoMountDomElements ? (\n <AutoMount plugins={plugins}>{content}</AutoMount>\n ) : (\n content\n )}\n </PDFContext.Provider>\n );\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin';\n\ntype CapabilityState<T extends BasePlugin> = {\n provides: ReturnType<NonNullable<T['provides']>> | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin's capability.\n * @param pluginId The ID of the plugin to access\n * @returns The capability provided by the plugin or null during initialization\n * @example\n * // Get zoom capability\n * const zoom = useCapability<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function useCapability<T extends BasePlugin>(pluginId: T['id']): CapabilityState<T> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n if (!plugin) {\n return {\n provides: null,\n isLoading,\n ready,\n };\n }\n\n if (!plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n return {\n provides: plugin.provides() as ReturnType<NonNullable<T['provides']>>,\n isLoading,\n ready,\n };\n}\n","import { useMemo } from '@framework';\nimport { PdfPermissionFlag } from '@embedpdf/models';\nimport { useCoreState } from './use-core-state';\nimport { getEffectivePermission, getEffectivePermissions } from '../../lib/store/selectors';\n\nexport interface DocumentPermissions {\n /** Effective permission flags after applying overrides */\n permissions: number;\n /** Raw PDF permission flags (before overrides) */\n pdfPermissions: number;\n /** Check if a specific permission flag is effectively allowed */\n hasPermission: (flag: PdfPermissionFlag) => boolean;\n /** Check if all specified flags are effectively allowed */\n hasAllPermissions: (...flags: PdfPermissionFlag[]) => boolean;\n\n // Shorthand booleans for all permission flags (using effective permissions):\n /** Can print (possibly degraded quality) */\n canPrint: boolean;\n /** Can modify document contents */\n canModifyContents: boolean;\n /** Can copy/extract text and graphics */\n canCopyContents: boolean;\n /** Can add/modify annotations and fill forms */\n canModifyAnnotations: boolean;\n /** Can fill in existing form fields */\n canFillForms: boolean;\n /** Can extract for accessibility */\n canExtractForAccessibility: boolean;\n /** Can assemble document (insert, rotate, delete pages) */\n canAssembleDocument: boolean;\n /** Can print high quality */\n canPrintHighQuality: boolean;\n}\n\n/**\n * Hook that provides reactive access to a document's effective permission flags.\n * Applies layered resolution: per-document override → global override → PDF permission.\n *\n * @param documentId The ID of the document to check permissions for.\n * @returns An object with effective permissions, raw PDF permissions, helper functions, and shorthand booleans.\n */\nexport function useDocumentPermissions(documentId: string): DocumentPermissions {\n const coreState = useCoreState();\n\n return useMemo(() => {\n if (!coreState) {\n return {\n permissions: PdfPermissionFlag.AllowAll,\n pdfPermissions: PdfPermissionFlag.AllowAll,\n hasPermission: () => true,\n hasAllPermissions: () => true,\n canPrint: true,\n canModifyContents: true,\n canCopyContents: true,\n canModifyAnnotations: true,\n canFillForms: true,\n canExtractForAccessibility: true,\n canAssembleDocument: true,\n canPrintHighQuality: true,\n };\n }\n\n const effectivePermissions = getEffectivePermissions(coreState, documentId);\n const pdfPermissions =\n coreState.documents[documentId]?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n const hasPermission = (flag: PdfPermissionFlag) =>\n getEffectivePermission(coreState, documentId, flag);\n const hasAllPermissions = (...flags: PdfPermissionFlag[]) =>\n flags.every((flag) => getEffectivePermission(coreState, documentId, flag));\n\n return {\n permissions: effectivePermissions,\n pdfPermissions,\n hasPermission,\n hasAllPermissions,\n // All permission flags as booleans (using effective permissions)\n canPrint: hasPermission(PdfPermissionFlag.Print),\n canModifyContents: hasPermission(PdfPermissionFlag.ModifyContents),\n canCopyContents: hasPermission(PdfPermissionFlag.CopyContents),\n canModifyAnnotations: hasPermission(PdfPermissionFlag.ModifyAnnotations),\n canFillForms: hasPermission(PdfPermissionFlag.FillForms),\n canExtractForAccessibility: hasPermission(PdfPermissionFlag.ExtractForAccessibility),\n canAssembleDocument: hasPermission(PdfPermissionFlag.AssembleDocument),\n canPrintHighQuality: hasPermission(PdfPermissionFlag.PrintHighQuality),\n };\n }, [coreState, documentId]);\n}\n","import { useMemo } from '@framework';\nimport { DocumentState } from '@embedpdf/core';\nimport { useCoreState } from './use-core-state';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param documentId The ID of the document to retrieve.\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: string | null): DocumentState | null {\n const coreState = useCoreState();\n\n const documentState = useMemo(() => {\n if (!coreState || !documentId) return null;\n return coreState.documents[documentId] ?? null;\n }, [coreState, documentId]);\n\n return documentState;\n}\n","import { useState, useEffect } from '@framework';\nimport { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Hook that provides access to the current global store state\n * and re-renders the component when the state changes\n */\nexport function useStoreState<T = CoreState>(): StoreState<T> | null {\n const { registry } = useRegistry();\n const [state, setState] = useState<StoreState<T> | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n // Get initial state\n setState(registry.getStore().getState() as StoreState<T>);\n\n // Subscribe to store changes\n const unsubscribe = registry.getStore().subscribe((_action, newState) => {\n setState(newState as StoreState<T>);\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return state;\n}\n"],"names":["PDFContext","createContext","registry","coreState","isInitializing","pluginsReady","activeDocumentId","activeDocument","documents","documentStates","AutoMount","plugins","children","utilities","wrappers","useMemo","reg","pkg","package","hasAutoMountElements","elements","autoMountElements","element","type","push","component","wrappedContent","reduce","content","Wrapper","jsx","Fragment","map","Utility","i","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","useCoreState","PdfPermissionFlag","Print","ModifyContents","CopyContents","ModifyAnnotations","FillForms","ExtractForAccessibility","AssembleDocument","PrintHighQuality","ALL_PERMISSION_FLAGS","PERMISSION_FLAG_TO_NAME","getPermissionOverride","overrides","flag","name","getEffectivePermission","state","documentId","docState","docConfig","permissions","globalConfig","globalPermissions","pdfPermissions","_a","document","AllowAll","docOverride","globalOverride","enforceDocumentPermissions","engine","config","logger","onInitialized","autoMountDomElements","setRegistry","useState","setCoreState","setIsInitializing","setPluginsReady","initRef","useRef","useEffect","current","finalConfig","pdfViewer","PluginRegistry","registerPluginBatch","cleanup","async","initialize","isDestroyed","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","call","then","unsub","catch","console","error","destroy","documentOrder","docId","filter","doc","Provider","value","provides","hasPermission","hasAllPermissions","canPrint","canModifyContents","canCopyContents","canModifyAnnotations","canFillForms","canExtractForAccessibility","canAssembleDocument","canPrintHighQuality","effectivePermissions","acc","getEffectivePermissions","_b","flags","every","setState","_action"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/components/auto-mount.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/hooks/use-core-state.ts","../../src/lib/types/permissions.ts","../../src/lib/store/selectors.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-document-permissions.ts","../../src/shared/hooks/use-document-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { CoreState, DocumentState, PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n coreState: CoreState | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: string | null;\n activeDocument: DocumentState | null;\n documents: Record<string, DocumentState>;\n documentStates: DocumentState[];\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n coreState: null,\n isInitializing: true,\n pluginsReady: false,\n activeDocumentId: null,\n activeDocument: null,\n documents: {},\n documentStates: [],\n});\n","import { Fragment, useMemo, ComponentType, ReactNode } from '@framework';\nimport { hasAutoMountElements } from '@embedpdf/core';\nimport type { PluginBatchRegistration, IPlugin } from '@embedpdf/core';\n\ninterface AutoMountProps {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode;\n}\n\nexport function AutoMount({ plugins, children }: AutoMountProps) {\n const { utilities, wrappers } = useMemo(() => {\n // React-specific types for internal use\n const utilities: ComponentType[] = [];\n const wrappers: ComponentType<{ children: ReactNode }>[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements() || [];\n\n for (const element of elements) {\n if (element.type === 'utility') {\n utilities.push(element.component);\n } else if (element.type === 'wrapper') {\n // In React context, we know wrappers need children\n wrappers.push(element.component);\n }\n }\n }\n }\n return { utilities, wrappers };\n }, [plugins]);\n\n // Combine children and utilities as siblings inside the wrapper chain\n const contentWithUtilities = (\n <Fragment>\n {children}\n {utilities.map((Utility, i) => (\n <Utility key={`utility-${i}`} />\n ))}\n </Fragment>\n );\n\n // Wrap everything together - utilities now inside wrapper context\n const wrappedContent = wrappers.reduce(\n (content, Wrapper) => <Wrapper>{content}</Wrapper>,\n contentWithUtilities,\n );\n\n return <Fragment>{wrappedContent}</Fragment>;\n}\n","import { useContext } from '@framework';\nimport { PDFContext, PDFContextState } from '../context';\n\n/**\n * Hook to access the PDF registry.\n * @returns The PDF registry or null during initialization\n */\nexport function useRegistry(): PDFContextState {\n const contextValue = useContext(PDFContext);\n\n // Error if used outside of context\n if (contextValue === undefined) {\n throw new Error('useCapability must be used within a PDFContext.Provider');\n }\n\n const { registry, isInitializing } = contextValue;\n\n // During initialization, return null instead of throwing an error\n if (isInitializing) {\n return contextValue;\n }\n\n // At this point, initialization is complete but registry is still null, which is unexpected\n if (registry === null) {\n throw new Error('PDF registry failed to initialize properly');\n }\n\n return contextValue;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\ntype PluginState<T extends BasePlugin> = {\n plugin: T | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin.\n * @param pluginId The ID of the plugin to access\n * @returns The plugin or null during initialization\n * @example\n * // Get zoom plugin\n * const zoom = usePlugin<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n if (registry === null) {\n return {\n plugin: null,\n isLoading: true,\n ready: new Promise(() => {}),\n };\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n return {\n plugin,\n isLoading: false,\n ready: plugin.ready(),\n };\n}\n","import { useContext } from '@framework';\nimport { CoreState } from '@embedpdf/core';\nimport { PDFContext } from '../context';\n\n/**\n * Hook that provides access to the current core state.\n *\n * Note: This reads from the context which is already subscribed to core state changes\n * in the EmbedPDF component, so there's no additional subscription overhead.\n */\nexport function useCoreState(): CoreState | null {\n const { coreState } = useContext(PDFContext);\n return coreState;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\n\n/**\n * Human-readable permission names for use in configuration.\n */\nexport type PermissionName =\n | 'print'\n | 'modifyContents'\n | 'copyContents'\n | 'modifyAnnotations'\n | 'fillForms'\n | 'extractForAccessibility'\n | 'assembleDocument'\n | 'printHighQuality';\n\n/**\n * Map from human-readable names to PdfPermissionFlag values.\n */\nexport const PERMISSION_NAME_TO_FLAG: Record<PermissionName, PdfPermissionFlag> = {\n print: PdfPermissionFlag.Print,\n modifyContents: PdfPermissionFlag.ModifyContents,\n copyContents: PdfPermissionFlag.CopyContents,\n modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,\n fillForms: PdfPermissionFlag.FillForms,\n extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,\n assembleDocument: PdfPermissionFlag.AssembleDocument,\n printHighQuality: PdfPermissionFlag.PrintHighQuality,\n};\n\n/**\n * Permission overrides can use either numeric flags or human-readable string names.\n */\nexport type PermissionOverrides = Partial<\n Record<PdfPermissionFlag, boolean> & Record<PermissionName, boolean>\n>;\n\n/**\n * Configuration for overriding document permissions.\n * Can be applied globally (at PluginRegistry level) or per-document (when opening).\n */\nexport interface PermissionConfig {\n /**\n * When true (default): use PDF's permissions as the base, then apply overrides.\n * When false: treat document as having all permissions allowed, then apply overrides.\n */\n enforceDocumentPermissions?: boolean;\n\n /**\n * Explicit per-flag overrides. Supports both numeric flags and string names.\n * - true = force allow (even if PDF denies)\n * - false = force deny (even if PDF allows)\n * - undefined = use base permissions\n *\n * @example\n * // Using string names (recommended)\n * overrides: { print: false, modifyAnnotations: true }\n *\n * @example\n * // Using numeric flags\n * overrides: { [PdfPermissionFlag.Print]: false }\n */\n overrides?: PermissionOverrides;\n}\n\n/**\n * All permission flags for iteration when computing effective permissions.\n */\nexport const ALL_PERMISSION_FLAGS: PdfPermissionFlag[] = [\n PdfPermissionFlag.Print,\n PdfPermissionFlag.ModifyContents,\n PdfPermissionFlag.CopyContents,\n PdfPermissionFlag.ModifyAnnotations,\n PdfPermissionFlag.FillForms,\n PdfPermissionFlag.ExtractForAccessibility,\n PdfPermissionFlag.AssembleDocument,\n PdfPermissionFlag.PrintHighQuality,\n];\n\n/**\n * All permission names for iteration.\n */\nexport const ALL_PERMISSION_NAMES: PermissionName[] = [\n 'print',\n 'modifyContents',\n 'copyContents',\n 'modifyAnnotations',\n 'fillForms',\n 'extractForAccessibility',\n 'assembleDocument',\n 'printHighQuality',\n];\n\n/**\n * Map from PdfPermissionFlag to human-readable name.\n */\nexport const PERMISSION_FLAG_TO_NAME: Record<PdfPermissionFlag, PermissionName> = {\n [PdfPermissionFlag.Print]: 'print',\n [PdfPermissionFlag.ModifyContents]: 'modifyContents',\n [PdfPermissionFlag.CopyContents]: 'copyContents',\n [PdfPermissionFlag.ModifyAnnotations]: 'modifyAnnotations',\n [PdfPermissionFlag.FillForms]: 'fillForms',\n [PdfPermissionFlag.ExtractForAccessibility]: 'extractForAccessibility',\n [PdfPermissionFlag.AssembleDocument]: 'assembleDocument',\n [PdfPermissionFlag.PrintHighQuality]: 'printHighQuality',\n};\n\n/**\n * Helper to get the override value for a permission flag, checking both numeric and string keys.\n */\nexport function getPermissionOverride(\n overrides: PermissionOverrides | undefined,\n flag: PdfPermissionFlag,\n): boolean | undefined {\n if (!overrides) return undefined;\n\n // Check numeric key first\n if (flag in overrides) {\n return (overrides as Record<PdfPermissionFlag, boolean>)[flag];\n }\n\n // Check string key\n const name = PERMISSION_FLAG_TO_NAME[flag];\n if (name && name in overrides) {\n return (overrides as Record<PermissionName, boolean>)[name];\n }\n\n return undefined;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\nimport { CoreState, DocumentState } from './initial-state';\nimport { ALL_PERMISSION_FLAGS, getPermissionOverride } from '../types/permissions';\n\n/**\n * Get the active document state\n */\nexport const getActiveDocumentState = (state: CoreState): DocumentState | null => {\n if (!state.activeDocumentId) return null;\n return state.documents[state.activeDocumentId] ?? null;\n};\n\n/**\n * Get document state by ID\n */\nexport const getDocumentState = (state: CoreState, documentId: string): DocumentState | null => {\n return state.documents[documentId] ?? null;\n};\n\n/**\n * Get all document IDs\n */\nexport const getDocumentIds = (state: CoreState): string[] => {\n return Object.keys(state.documents);\n};\n\n/**\n * Check if a document is loaded\n */\nexport const isDocumentLoaded = (state: CoreState, documentId: string): boolean => {\n return !!state.documents[documentId];\n};\n\n/**\n * Get the number of open documents\n */\nexport const getDocumentCount = (state: CoreState): number => {\n return Object.keys(state.documents).length;\n};\n\n// ─────────────────────────────────────────────────────────\n// Permission Selectors\n// ─────────────────────────────────────────────────────────\n\n/**\n * Check if a specific permission flag is effectively allowed for a document.\n * Applies layered resolution: per-document override → global override → enforceDocumentPermissions → PDF permission.\n *\n * @param state - The core state\n * @param documentId - The document ID to check permissions for\n * @param flag - The permission flag to check\n * @returns true if the permission is allowed, false otherwise\n */\nexport function getEffectivePermission(\n state: CoreState,\n documentId: string,\n flag: PdfPermissionFlag,\n): boolean {\n const docState = state.documents[documentId];\n const docConfig = docState?.permissions;\n const globalConfig = state.globalPermissions;\n const pdfPermissions = docState?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n // 1. Per-document override wins (supports both numeric and string keys)\n const docOverride = getPermissionOverride(docConfig?.overrides, flag);\n if (docOverride !== undefined) {\n return docOverride;\n }\n\n // 2. Global override (supports both numeric and string keys)\n const globalOverride = getPermissionOverride(globalConfig?.overrides, flag);\n if (globalOverride !== undefined) {\n return globalOverride;\n }\n\n // 3. Check enforce setting (per-doc takes precedence over global)\n const enforce =\n docConfig?.enforceDocumentPermissions ?? globalConfig?.enforceDocumentPermissions ?? true;\n\n if (!enforce) return true; // Not enforcing = allow all\n\n // 4. Use PDF permission\n return (pdfPermissions & flag) !== 0;\n}\n\n/**\n * Get all effective permissions as a bitmask for a document.\n * Combines all individual permission checks into a single bitmask.\n *\n * @param state - The core state\n * @param documentId - The document ID to get permissions for\n * @returns A bitmask of all effective permissions\n */\nexport function getEffectivePermissions(state: CoreState, documentId: string): number {\n return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {\n return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;\n }, 0);\n}\n","import { useState, useEffect, useRef, useMemo, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry, CoreState, DocumentState, PluginRegistryConfig } from '@embedpdf/core';\nimport type { PluginBatchRegistrations } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\nimport { AutoMount } from './auto-mount';\n\nexport type { PluginBatchRegistrations };\n\ninterface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * Registry configuration including logger, permissions, and defaults.\n */\n config?: PluginRegistryConfig;\n /**\n * @deprecated Use config.logger instead. Will be removed in next major version.\n */\n logger?: Logger;\n /**\n * The callback to call when the PDF viewer is initialized.\n */\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n /**\n * The plugins to use for the PDF viewer.\n */\n plugins: PluginBatchRegistrations;\n /**\n * The children to render for the PDF viewer.\n */\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n}\n\nexport function EmbedPDF({\n engine,\n config,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n}: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n const [isInitializing, setIsInitializing] = useState<boolean>(true);\n const [pluginsReady, setPluginsReady] = useState<boolean>(false);\n const initRef = useRef<EmbedPDFProps['onInitialized']>(onInitialized);\n\n useEffect(() => {\n initRef.current = onInitialized;\n }, [onInitialized]);\n\n useEffect(() => {\n // Merge deprecated logger prop into config (config.logger takes precedence)\n const finalConfig: PluginRegistryConfig = {\n ...config,\n logger: config?.logger ?? logger,\n };\n const pdfViewer = new PluginRegistry(engine, finalConfig);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n const store = pdfViewer.getStore();\n setCoreState(store.getState().core);\n\n const unsubscribe = store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && newState.core !== oldState.core) {\n setCoreState(newState.core);\n }\n });\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n if (pdfViewer.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n pdfViewer.pluginsReady().then(() => {\n if (!pdfViewer.isDestroyed()) {\n setPluginsReady(true);\n }\n });\n\n // Provide the registry to children via context\n setRegistry(pdfViewer);\n setIsInitializing(false);\n\n // Return cleanup function\n return unsubscribe;\n };\n\n let cleanup: (() => void) | undefined;\n initialize()\n .then((unsub) => {\n cleanup = unsub;\n })\n .catch(console.error);\n\n return () => {\n cleanup?.();\n pdfViewer.destroy();\n setRegistry(null);\n setCoreState(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n // Compute convenience accessors\n const contextValue: PDFContextState = useMemo(() => {\n const activeDocumentId = coreState?.activeDocumentId ?? null;\n const documents = coreState?.documents ?? {};\n const documentOrder = coreState?.documentOrder ?? [];\n\n // Compute active document\n const activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n\n // Compute open documents in order\n const documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n\n return {\n registry,\n coreState,\n isInitializing,\n pluginsReady,\n // Convenience accessors (always safe to use)\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n };\n }, [registry, coreState, isInitializing, pluginsReady]);\n\n const content = typeof children === 'function' ? children(contextValue) : children;\n\n return (\n <PDFContext.Provider value={contextValue}>\n {pluginsReady && autoMountDomElements ? (\n <AutoMount plugins={plugins}>{content}</AutoMount>\n ) : (\n content\n )}\n </PDFContext.Provider>\n );\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin';\n\ntype CapabilityState<T extends BasePlugin> = {\n provides: ReturnType<NonNullable<T['provides']>> | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin's capability.\n * @param pluginId The ID of the plugin to access\n * @returns The capability provided by the plugin or null during initialization\n * @example\n * // Get zoom capability\n * const zoom = useCapability<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function useCapability<T extends BasePlugin>(pluginId: T['id']): CapabilityState<T> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n if (!plugin) {\n return {\n provides: null,\n isLoading,\n ready,\n };\n }\n\n if (!plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n return {\n provides: plugin.provides() as ReturnType<NonNullable<T['provides']>>,\n isLoading,\n ready,\n };\n}\n","import { useMemo } from '@framework';\nimport { PdfPermissionFlag } from '@embedpdf/models';\nimport { useCoreState } from './use-core-state';\nimport { getEffectivePermission, getEffectivePermissions } from '../../lib/store/selectors';\n\nexport interface DocumentPermissions {\n /** Effective permission flags after applying overrides */\n permissions: number;\n /** Raw PDF permission flags (before overrides) */\n pdfPermissions: number;\n /** Check if a specific permission flag is effectively allowed */\n hasPermission: (flag: PdfPermissionFlag) => boolean;\n /** Check if all specified flags are effectively allowed */\n hasAllPermissions: (...flags: PdfPermissionFlag[]) => boolean;\n\n // Shorthand booleans for all permission flags (using effective permissions):\n /** Can print (possibly degraded quality) */\n canPrint: boolean;\n /** Can modify document contents */\n canModifyContents: boolean;\n /** Can copy/extract text and graphics */\n canCopyContents: boolean;\n /** Can add/modify annotations and fill forms */\n canModifyAnnotations: boolean;\n /** Can fill in existing form fields */\n canFillForms: boolean;\n /** Can extract for accessibility */\n canExtractForAccessibility: boolean;\n /** Can assemble document (insert, rotate, delete pages) */\n canAssembleDocument: boolean;\n /** Can print high quality */\n canPrintHighQuality: boolean;\n}\n\n/**\n * Hook that provides reactive access to a document's effective permission flags.\n * Applies layered resolution: per-document override → global override → PDF permission.\n *\n * @param documentId The ID of the document to check permissions for.\n * @returns An object with effective permissions, raw PDF permissions, helper functions, and shorthand booleans.\n */\nexport function useDocumentPermissions(documentId: string): DocumentPermissions {\n const coreState = useCoreState();\n\n return useMemo(() => {\n if (!coreState) {\n return {\n permissions: PdfPermissionFlag.AllowAll,\n pdfPermissions: PdfPermissionFlag.AllowAll,\n hasPermission: () => true,\n hasAllPermissions: () => true,\n canPrint: true,\n canModifyContents: true,\n canCopyContents: true,\n canModifyAnnotations: true,\n canFillForms: true,\n canExtractForAccessibility: true,\n canAssembleDocument: true,\n canPrintHighQuality: true,\n };\n }\n\n const effectivePermissions = getEffectivePermissions(coreState, documentId);\n const pdfPermissions =\n coreState.documents[documentId]?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n const hasPermission = (flag: PdfPermissionFlag) =>\n getEffectivePermission(coreState, documentId, flag);\n const hasAllPermissions = (...flags: PdfPermissionFlag[]) =>\n flags.every((flag) => getEffectivePermission(coreState, documentId, flag));\n\n return {\n permissions: effectivePermissions,\n pdfPermissions,\n hasPermission,\n hasAllPermissions,\n // All permission flags as booleans (using effective permissions)\n canPrint: hasPermission(PdfPermissionFlag.Print),\n canModifyContents: hasPermission(PdfPermissionFlag.ModifyContents),\n canCopyContents: hasPermission(PdfPermissionFlag.CopyContents),\n canModifyAnnotations: hasPermission(PdfPermissionFlag.ModifyAnnotations),\n canFillForms: hasPermission(PdfPermissionFlag.FillForms),\n canExtractForAccessibility: hasPermission(PdfPermissionFlag.ExtractForAccessibility),\n canAssembleDocument: hasPermission(PdfPermissionFlag.AssembleDocument),\n canPrintHighQuality: hasPermission(PdfPermissionFlag.PrintHighQuality),\n };\n }, [coreState, documentId]);\n}\n","import { useMemo } from '@framework';\nimport { DocumentState } from '@embedpdf/core';\nimport { useCoreState } from './use-core-state';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param documentId The ID of the document to retrieve.\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: string | null): DocumentState | null {\n const coreState = useCoreState();\n\n const documentState = useMemo(() => {\n if (!coreState || !documentId) return null;\n return coreState.documents[documentId] ?? null;\n }, [coreState, documentId]);\n\n return documentState;\n}\n","import { useState, useEffect } from '@framework';\nimport { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Hook that provides access to the current global store state\n * and re-renders the component when the state changes\n */\nexport function useStoreState<T = CoreState>(): StoreState<T> | null {\n const { registry } = useRegistry();\n const [state, setState] = useState<StoreState<T> | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n // Get initial state\n setState(registry.getStore().getState() as StoreState<T>);\n\n // Subscribe to store changes\n const unsubscribe = registry.getStore().subscribe((_action, newState) => {\n setState(newState as StoreState<T>);\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return state;\n}\n"],"names":["PDFContext","createContext","registry","coreState","isInitializing","pluginsReady","activeDocumentId","activeDocument","documents","documentStates","AutoMount","plugins","children","utilities","wrappers","useMemo","reg","pkg","package","hasAutoMountElements","elements","autoMountElements","element","type","push","component","contentWithUtilities","Fragment","map","Utility","i","wrappedContent","reduce","content","Wrapper","jsx","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","useCoreState","PdfPermissionFlag","Print","ModifyContents","CopyContents","ModifyAnnotations","FillForms","ExtractForAccessibility","AssembleDocument","PrintHighQuality","ALL_PERMISSION_FLAGS","PERMISSION_FLAG_TO_NAME","getPermissionOverride","overrides","flag","name","getEffectivePermission","state","documentId","docState","docConfig","permissions","globalConfig","globalPermissions","pdfPermissions","_a","document","AllowAll","docOverride","globalOverride","enforceDocumentPermissions","engine","config","logger","onInitialized","autoMountDomElements","setRegistry","useState","setCoreState","setIsInitializing","setPluginsReady","initRef","useRef","useEffect","current","finalConfig","pdfViewer","PluginRegistry","registerPluginBatch","cleanup","async","initialize","isDestroyed","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","call","then","unsub","catch","console","error","destroy","documentOrder","docId","filter","doc","Provider","value","provides","hasPermission","hasAllPermissions","canPrint","canModifyContents","canCopyContents","canModifyAnnotations","canFillForms","canExtractForAccessibility","canAssembleDocument","canPrintHighQuality","effectivePermissions","acc","getEffectivePermissions","_b","flags","every","setState","_action"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createContext, Fragment } from "preact";
2
2
  import { useMemo, useState, useRef, useEffect, useContext } from "preact/hooks";
3
- import { jsx, jsxs } from "preact/jsx-runtime";
3
+ import { jsxs, jsx } from "preact/jsx-runtime";
4
4
  import { hasAutoMountElements, PluginRegistry } from "@embedpdf/core";
5
5
  import { PdfPermissionFlag } from "@embedpdf/models";
6
6
  const PDFContext = createContext({
@@ -32,14 +32,15 @@ function AutoMount({ plugins, children }) {
32
32
  }
33
33
  return { utilities: utilities2, wrappers: wrappers2 };
34
34
  }, [plugins]);
35
+ const contentWithUtilities = /* @__PURE__ */ jsxs(Fragment, { children: [
36
+ children,
37
+ utilities.map((Utility, i) => /* @__PURE__ */ jsx(Utility, {}, `utility-${i}`))
38
+ ] });
35
39
  const wrappedContent = wrappers.reduce(
36
40
  (content, Wrapper) => /* @__PURE__ */ jsx(Wrapper, { children: content }),
37
- children
41
+ contentWithUtilities
38
42
  );
39
- return /* @__PURE__ */ jsxs(Fragment, { children: [
40
- wrappedContent,
41
- utilities.map((Utility, i) => /* @__PURE__ */ jsx(Utility, {}, `utility-${i}`))
42
- ] });
43
+ return /* @__PURE__ */ jsx(Fragment, { children: wrappedContent });
43
44
  }
44
45
  function EmbedPDF({
45
46
  engine,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/context.ts","../../src/shared/components/auto-mount.tsx","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-store-state.ts","../../src/shared/hooks/use-core-state.ts","../../src/shared/hooks/use-document-state.ts","../../src/lib/types/permissions.ts","../../src/lib/store/selectors.ts","../../src/shared/hooks/use-document-permissions.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { CoreState, DocumentState, PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n coreState: CoreState | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: string | null;\n activeDocument: DocumentState | null;\n documents: Record<string, DocumentState>;\n documentStates: DocumentState[];\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n coreState: null,\n isInitializing: true,\n pluginsReady: false,\n activeDocumentId: null,\n activeDocument: null,\n documents: {},\n documentStates: [],\n});\n","import { Fragment, useMemo, ComponentType, ReactNode } from '@framework';\nimport { hasAutoMountElements } from '@embedpdf/core';\nimport type { PluginBatchRegistration, IPlugin } from '@embedpdf/core';\n\ninterface AutoMountProps {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode;\n}\n\nexport function AutoMount({ plugins, children }: AutoMountProps) {\n const { utilities, wrappers } = useMemo(() => {\n // React-specific types for internal use\n const utilities: ComponentType[] = [];\n const wrappers: ComponentType<{ children: ReactNode }>[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements() || [];\n\n for (const element of elements) {\n if (element.type === 'utility') {\n utilities.push(element.component);\n } else if (element.type === 'wrapper') {\n // In React context, we know wrappers need children\n wrappers.push(element.component);\n }\n }\n }\n }\n return { utilities, wrappers };\n }, [plugins]);\n\n // React-specific wrapping logic\n const wrappedContent = wrappers.reduce(\n (content, Wrapper) => <Wrapper>{content}</Wrapper>,\n children,\n );\n\n return (\n <Fragment>\n {wrappedContent}\n {utilities.map((Utility, i) => (\n <Utility key={`utility-${i}`} />\n ))}\n </Fragment>\n );\n}\n","import { useState, useEffect, useRef, useMemo, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry, CoreState, DocumentState, PluginRegistryConfig } from '@embedpdf/core';\nimport type { PluginBatchRegistrations } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\nimport { AutoMount } from './auto-mount';\n\nexport type { PluginBatchRegistrations };\n\ninterface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * Registry configuration including logger, permissions, and defaults.\n */\n config?: PluginRegistryConfig;\n /**\n * @deprecated Use config.logger instead. Will be removed in next major version.\n */\n logger?: Logger;\n /**\n * The callback to call when the PDF viewer is initialized.\n */\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n /**\n * The plugins to use for the PDF viewer.\n */\n plugins: PluginBatchRegistrations;\n /**\n * The children to render for the PDF viewer.\n */\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n}\n\nexport function EmbedPDF({\n engine,\n config,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n}: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n const [isInitializing, setIsInitializing] = useState<boolean>(true);\n const [pluginsReady, setPluginsReady] = useState<boolean>(false);\n const initRef = useRef<EmbedPDFProps['onInitialized']>(onInitialized);\n\n useEffect(() => {\n initRef.current = onInitialized;\n }, [onInitialized]);\n\n useEffect(() => {\n // Merge deprecated logger prop into config (config.logger takes precedence)\n const finalConfig: PluginRegistryConfig = {\n ...config,\n logger: config?.logger ?? logger,\n };\n const pdfViewer = new PluginRegistry(engine, finalConfig);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n const store = pdfViewer.getStore();\n setCoreState(store.getState().core);\n\n const unsubscribe = store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && newState.core !== oldState.core) {\n setCoreState(newState.core);\n }\n });\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n if (pdfViewer.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n pdfViewer.pluginsReady().then(() => {\n if (!pdfViewer.isDestroyed()) {\n setPluginsReady(true);\n }\n });\n\n // Provide the registry to children via context\n setRegistry(pdfViewer);\n setIsInitializing(false);\n\n // Return cleanup function\n return unsubscribe;\n };\n\n let cleanup: (() => void) | undefined;\n initialize()\n .then((unsub) => {\n cleanup = unsub;\n })\n .catch(console.error);\n\n return () => {\n cleanup?.();\n pdfViewer.destroy();\n setRegistry(null);\n setCoreState(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n // Compute convenience accessors\n const contextValue: PDFContextState = useMemo(() => {\n const activeDocumentId = coreState?.activeDocumentId ?? null;\n const documents = coreState?.documents ?? {};\n const documentOrder = coreState?.documentOrder ?? [];\n\n // Compute active document\n const activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n\n // Compute open documents in order\n const documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n\n return {\n registry,\n coreState,\n isInitializing,\n pluginsReady,\n // Convenience accessors (always safe to use)\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n };\n }, [registry, coreState, isInitializing, pluginsReady]);\n\n const content = typeof children === 'function' ? children(contextValue) : children;\n\n return (\n <PDFContext.Provider value={contextValue}>\n {pluginsReady && autoMountDomElements ? (\n <AutoMount plugins={plugins}>{content}</AutoMount>\n ) : (\n content\n )}\n </PDFContext.Provider>\n );\n}\n","import { useContext } from '@framework';\nimport { PDFContext, PDFContextState } from '../context';\n\n/**\n * Hook to access the PDF registry.\n * @returns The PDF registry or null during initialization\n */\nexport function useRegistry(): PDFContextState {\n const contextValue = useContext(PDFContext);\n\n // Error if used outside of context\n if (contextValue === undefined) {\n throw new Error('useCapability must be used within a PDFContext.Provider');\n }\n\n const { registry, isInitializing } = contextValue;\n\n // During initialization, return null instead of throwing an error\n if (isInitializing) {\n return contextValue;\n }\n\n // At this point, initialization is complete but registry is still null, which is unexpected\n if (registry === null) {\n throw new Error('PDF registry failed to initialize properly');\n }\n\n return contextValue;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\ntype PluginState<T extends BasePlugin> = {\n plugin: T | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin.\n * @param pluginId The ID of the plugin to access\n * @returns The plugin or null during initialization\n * @example\n * // Get zoom plugin\n * const zoom = usePlugin<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n if (registry === null) {\n return {\n plugin: null,\n isLoading: true,\n ready: new Promise(() => {}),\n };\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n return {\n plugin,\n isLoading: false,\n ready: plugin.ready(),\n };\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin';\n\ntype CapabilityState<T extends BasePlugin> = {\n provides: ReturnType<NonNullable<T['provides']>> | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin's capability.\n * @param pluginId The ID of the plugin to access\n * @returns The capability provided by the plugin or null during initialization\n * @example\n * // Get zoom capability\n * const zoom = useCapability<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function useCapability<T extends BasePlugin>(pluginId: T['id']): CapabilityState<T> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n if (!plugin) {\n return {\n provides: null,\n isLoading,\n ready,\n };\n }\n\n if (!plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n return {\n provides: plugin.provides() as ReturnType<NonNullable<T['provides']>>,\n isLoading,\n ready,\n };\n}\n","import { useState, useEffect } from '@framework';\nimport { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Hook that provides access to the current global store state\n * and re-renders the component when the state changes\n */\nexport function useStoreState<T = CoreState>(): StoreState<T> | null {\n const { registry } = useRegistry();\n const [state, setState] = useState<StoreState<T> | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n // Get initial state\n setState(registry.getStore().getState() as StoreState<T>);\n\n // Subscribe to store changes\n const unsubscribe = registry.getStore().subscribe((_action, newState) => {\n setState(newState as StoreState<T>);\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return state;\n}\n","import { useContext } from '@framework';\nimport { CoreState } from '@embedpdf/core';\nimport { PDFContext } from '../context';\n\n/**\n * Hook that provides access to the current core state.\n *\n * Note: This reads from the context which is already subscribed to core state changes\n * in the EmbedPDF component, so there's no additional subscription overhead.\n */\nexport function useCoreState(): CoreState | null {\n const { coreState } = useContext(PDFContext);\n return coreState;\n}\n","import { useMemo } from '@framework';\nimport { DocumentState } from '@embedpdf/core';\nimport { useCoreState } from './use-core-state';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param documentId The ID of the document to retrieve.\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: string | null): DocumentState | null {\n const coreState = useCoreState();\n\n const documentState = useMemo(() => {\n if (!coreState || !documentId) return null;\n return coreState.documents[documentId] ?? null;\n }, [coreState, documentId]);\n\n return documentState;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\n\n/**\n * Human-readable permission names for use in configuration.\n */\nexport type PermissionName =\n | 'print'\n | 'modifyContents'\n | 'copyContents'\n | 'modifyAnnotations'\n | 'fillForms'\n | 'extractForAccessibility'\n | 'assembleDocument'\n | 'printHighQuality';\n\n/**\n * Map from human-readable names to PdfPermissionFlag values.\n */\nexport const PERMISSION_NAME_TO_FLAG: Record<PermissionName, PdfPermissionFlag> = {\n print: PdfPermissionFlag.Print,\n modifyContents: PdfPermissionFlag.ModifyContents,\n copyContents: PdfPermissionFlag.CopyContents,\n modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,\n fillForms: PdfPermissionFlag.FillForms,\n extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,\n assembleDocument: PdfPermissionFlag.AssembleDocument,\n printHighQuality: PdfPermissionFlag.PrintHighQuality,\n};\n\n/**\n * Permission overrides can use either numeric flags or human-readable string names.\n */\nexport type PermissionOverrides = Partial<\n Record<PdfPermissionFlag, boolean> & Record<PermissionName, boolean>\n>;\n\n/**\n * Configuration for overriding document permissions.\n * Can be applied globally (at PluginRegistry level) or per-document (when opening).\n */\nexport interface PermissionConfig {\n /**\n * When true (default): use PDF's permissions as the base, then apply overrides.\n * When false: treat document as having all permissions allowed, then apply overrides.\n */\n enforceDocumentPermissions?: boolean;\n\n /**\n * Explicit per-flag overrides. Supports both numeric flags and string names.\n * - true = force allow (even if PDF denies)\n * - false = force deny (even if PDF allows)\n * - undefined = use base permissions\n *\n * @example\n * // Using string names (recommended)\n * overrides: { print: false, modifyAnnotations: true }\n *\n * @example\n * // Using numeric flags\n * overrides: { [PdfPermissionFlag.Print]: false }\n */\n overrides?: PermissionOverrides;\n}\n\n/**\n * All permission flags for iteration when computing effective permissions.\n */\nexport const ALL_PERMISSION_FLAGS: PdfPermissionFlag[] = [\n PdfPermissionFlag.Print,\n PdfPermissionFlag.ModifyContents,\n PdfPermissionFlag.CopyContents,\n PdfPermissionFlag.ModifyAnnotations,\n PdfPermissionFlag.FillForms,\n PdfPermissionFlag.ExtractForAccessibility,\n PdfPermissionFlag.AssembleDocument,\n PdfPermissionFlag.PrintHighQuality,\n];\n\n/**\n * All permission names for iteration.\n */\nexport const ALL_PERMISSION_NAMES: PermissionName[] = [\n 'print',\n 'modifyContents',\n 'copyContents',\n 'modifyAnnotations',\n 'fillForms',\n 'extractForAccessibility',\n 'assembleDocument',\n 'printHighQuality',\n];\n\n/**\n * Map from PdfPermissionFlag to human-readable name.\n */\nexport const PERMISSION_FLAG_TO_NAME: Record<PdfPermissionFlag, PermissionName> = {\n [PdfPermissionFlag.Print]: 'print',\n [PdfPermissionFlag.ModifyContents]: 'modifyContents',\n [PdfPermissionFlag.CopyContents]: 'copyContents',\n [PdfPermissionFlag.ModifyAnnotations]: 'modifyAnnotations',\n [PdfPermissionFlag.FillForms]: 'fillForms',\n [PdfPermissionFlag.ExtractForAccessibility]: 'extractForAccessibility',\n [PdfPermissionFlag.AssembleDocument]: 'assembleDocument',\n [PdfPermissionFlag.PrintHighQuality]: 'printHighQuality',\n};\n\n/**\n * Helper to get the override value for a permission flag, checking both numeric and string keys.\n */\nexport function getPermissionOverride(\n overrides: PermissionOverrides | undefined,\n flag: PdfPermissionFlag,\n): boolean | undefined {\n if (!overrides) return undefined;\n\n // Check numeric key first\n if (flag in overrides) {\n return (overrides as Record<PdfPermissionFlag, boolean>)[flag];\n }\n\n // Check string key\n const name = PERMISSION_FLAG_TO_NAME[flag];\n if (name && name in overrides) {\n return (overrides as Record<PermissionName, boolean>)[name];\n }\n\n return undefined;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\nimport { CoreState, DocumentState } from './initial-state';\nimport { ALL_PERMISSION_FLAGS, getPermissionOverride } from '../types/permissions';\n\n/**\n * Get the active document state\n */\nexport const getActiveDocumentState = (state: CoreState): DocumentState | null => {\n if (!state.activeDocumentId) return null;\n return state.documents[state.activeDocumentId] ?? null;\n};\n\n/**\n * Get document state by ID\n */\nexport const getDocumentState = (state: CoreState, documentId: string): DocumentState | null => {\n return state.documents[documentId] ?? null;\n};\n\n/**\n * Get all document IDs\n */\nexport const getDocumentIds = (state: CoreState): string[] => {\n return Object.keys(state.documents);\n};\n\n/**\n * Check if a document is loaded\n */\nexport const isDocumentLoaded = (state: CoreState, documentId: string): boolean => {\n return !!state.documents[documentId];\n};\n\n/**\n * Get the number of open documents\n */\nexport const getDocumentCount = (state: CoreState): number => {\n return Object.keys(state.documents).length;\n};\n\n// ─────────────────────────────────────────────────────────\n// Permission Selectors\n// ─────────────────────────────────────────────────────────\n\n/**\n * Check if a specific permission flag is effectively allowed for a document.\n * Applies layered resolution: per-document override → global override → enforceDocumentPermissions → PDF permission.\n *\n * @param state - The core state\n * @param documentId - The document ID to check permissions for\n * @param flag - The permission flag to check\n * @returns true if the permission is allowed, false otherwise\n */\nexport function getEffectivePermission(\n state: CoreState,\n documentId: string,\n flag: PdfPermissionFlag,\n): boolean {\n const docState = state.documents[documentId];\n const docConfig = docState?.permissions;\n const globalConfig = state.globalPermissions;\n const pdfPermissions = docState?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n // 1. Per-document override wins (supports both numeric and string keys)\n const docOverride = getPermissionOverride(docConfig?.overrides, flag);\n if (docOverride !== undefined) {\n return docOverride;\n }\n\n // 2. Global override (supports both numeric and string keys)\n const globalOverride = getPermissionOverride(globalConfig?.overrides, flag);\n if (globalOverride !== undefined) {\n return globalOverride;\n }\n\n // 3. Check enforce setting (per-doc takes precedence over global)\n const enforce =\n docConfig?.enforceDocumentPermissions ?? globalConfig?.enforceDocumentPermissions ?? true;\n\n if (!enforce) return true; // Not enforcing = allow all\n\n // 4. Use PDF permission\n return (pdfPermissions & flag) !== 0;\n}\n\n/**\n * Get all effective permissions as a bitmask for a document.\n * Combines all individual permission checks into a single bitmask.\n *\n * @param state - The core state\n * @param documentId - The document ID to get permissions for\n * @returns A bitmask of all effective permissions\n */\nexport function getEffectivePermissions(state: CoreState, documentId: string): number {\n return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {\n return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;\n }, 0);\n}\n","import { useMemo } from '@framework';\nimport { PdfPermissionFlag } from '@embedpdf/models';\nimport { useCoreState } from './use-core-state';\nimport { getEffectivePermission, getEffectivePermissions } from '../../lib/store/selectors';\n\nexport interface DocumentPermissions {\n /** Effective permission flags after applying overrides */\n permissions: number;\n /** Raw PDF permission flags (before overrides) */\n pdfPermissions: number;\n /** Check if a specific permission flag is effectively allowed */\n hasPermission: (flag: PdfPermissionFlag) => boolean;\n /** Check if all specified flags are effectively allowed */\n hasAllPermissions: (...flags: PdfPermissionFlag[]) => boolean;\n\n // Shorthand booleans for all permission flags (using effective permissions):\n /** Can print (possibly degraded quality) */\n canPrint: boolean;\n /** Can modify document contents */\n canModifyContents: boolean;\n /** Can copy/extract text and graphics */\n canCopyContents: boolean;\n /** Can add/modify annotations and fill forms */\n canModifyAnnotations: boolean;\n /** Can fill in existing form fields */\n canFillForms: boolean;\n /** Can extract for accessibility */\n canExtractForAccessibility: boolean;\n /** Can assemble document (insert, rotate, delete pages) */\n canAssembleDocument: boolean;\n /** Can print high quality */\n canPrintHighQuality: boolean;\n}\n\n/**\n * Hook that provides reactive access to a document's effective permission flags.\n * Applies layered resolution: per-document override → global override → PDF permission.\n *\n * @param documentId The ID of the document to check permissions for.\n * @returns An object with effective permissions, raw PDF permissions, helper functions, and shorthand booleans.\n */\nexport function useDocumentPermissions(documentId: string): DocumentPermissions {\n const coreState = useCoreState();\n\n return useMemo(() => {\n if (!coreState) {\n return {\n permissions: PdfPermissionFlag.AllowAll,\n pdfPermissions: PdfPermissionFlag.AllowAll,\n hasPermission: () => true,\n hasAllPermissions: () => true,\n canPrint: true,\n canModifyContents: true,\n canCopyContents: true,\n canModifyAnnotations: true,\n canFillForms: true,\n canExtractForAccessibility: true,\n canAssembleDocument: true,\n canPrintHighQuality: true,\n };\n }\n\n const effectivePermissions = getEffectivePermissions(coreState, documentId);\n const pdfPermissions =\n coreState.documents[documentId]?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n const hasPermission = (flag: PdfPermissionFlag) =>\n getEffectivePermission(coreState, documentId, flag);\n const hasAllPermissions = (...flags: PdfPermissionFlag[]) =>\n flags.every((flag) => getEffectivePermission(coreState, documentId, flag));\n\n return {\n permissions: effectivePermissions,\n pdfPermissions,\n hasPermission,\n hasAllPermissions,\n // All permission flags as booleans (using effective permissions)\n canPrint: hasPermission(PdfPermissionFlag.Print),\n canModifyContents: hasPermission(PdfPermissionFlag.ModifyContents),\n canCopyContents: hasPermission(PdfPermissionFlag.CopyContents),\n canModifyAnnotations: hasPermission(PdfPermissionFlag.ModifyAnnotations),\n canFillForms: hasPermission(PdfPermissionFlag.FillForms),\n canExtractForAccessibility: hasPermission(PdfPermissionFlag.ExtractForAccessibility),\n canAssembleDocument: hasPermission(PdfPermissionFlag.AssembleDocument),\n canPrintHighQuality: hasPermission(PdfPermissionFlag.PrintHighQuality),\n };\n }, [coreState, documentId]);\n}\n"],"names":["utilities","wrappers"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/context.ts","../../src/shared/components/auto-mount.tsx","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-store-state.ts","../../src/shared/hooks/use-core-state.ts","../../src/shared/hooks/use-document-state.ts","../../src/lib/types/permissions.ts","../../src/lib/store/selectors.ts","../../src/shared/hooks/use-document-permissions.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { CoreState, DocumentState, PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n coreState: CoreState | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: string | null;\n activeDocument: DocumentState | null;\n documents: Record<string, DocumentState>;\n documentStates: DocumentState[];\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n coreState: null,\n isInitializing: true,\n pluginsReady: false,\n activeDocumentId: null,\n activeDocument: null,\n documents: {},\n documentStates: [],\n});\n","import { Fragment, useMemo, ComponentType, ReactNode } from '@framework';\nimport { hasAutoMountElements } from '@embedpdf/core';\nimport type { PluginBatchRegistration, IPlugin } from '@embedpdf/core';\n\ninterface AutoMountProps {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode;\n}\n\nexport function AutoMount({ plugins, children }: AutoMountProps) {\n const { utilities, wrappers } = useMemo(() => {\n // React-specific types for internal use\n const utilities: ComponentType[] = [];\n const wrappers: ComponentType<{ children: ReactNode }>[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements() || [];\n\n for (const element of elements) {\n if (element.type === 'utility') {\n utilities.push(element.component);\n } else if (element.type === 'wrapper') {\n // In React context, we know wrappers need children\n wrappers.push(element.component);\n }\n }\n }\n }\n return { utilities, wrappers };\n }, [plugins]);\n\n // Combine children and utilities as siblings inside the wrapper chain\n const contentWithUtilities = (\n <Fragment>\n {children}\n {utilities.map((Utility, i) => (\n <Utility key={`utility-${i}`} />\n ))}\n </Fragment>\n );\n\n // Wrap everything together - utilities now inside wrapper context\n const wrappedContent = wrappers.reduce(\n (content, Wrapper) => <Wrapper>{content}</Wrapper>,\n contentWithUtilities,\n );\n\n return <Fragment>{wrappedContent}</Fragment>;\n}\n","import { useState, useEffect, useRef, useMemo, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry, CoreState, DocumentState, PluginRegistryConfig } from '@embedpdf/core';\nimport type { PluginBatchRegistrations } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\nimport { AutoMount } from './auto-mount';\n\nexport type { PluginBatchRegistrations };\n\ninterface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * Registry configuration including logger, permissions, and defaults.\n */\n config?: PluginRegistryConfig;\n /**\n * @deprecated Use config.logger instead. Will be removed in next major version.\n */\n logger?: Logger;\n /**\n * The callback to call when the PDF viewer is initialized.\n */\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n /**\n * The plugins to use for the PDF viewer.\n */\n plugins: PluginBatchRegistrations;\n /**\n * The children to render for the PDF viewer.\n */\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n}\n\nexport function EmbedPDF({\n engine,\n config,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n}: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n const [isInitializing, setIsInitializing] = useState<boolean>(true);\n const [pluginsReady, setPluginsReady] = useState<boolean>(false);\n const initRef = useRef<EmbedPDFProps['onInitialized']>(onInitialized);\n\n useEffect(() => {\n initRef.current = onInitialized;\n }, [onInitialized]);\n\n useEffect(() => {\n // Merge deprecated logger prop into config (config.logger takes precedence)\n const finalConfig: PluginRegistryConfig = {\n ...config,\n logger: config?.logger ?? logger,\n };\n const pdfViewer = new PluginRegistry(engine, finalConfig);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n const store = pdfViewer.getStore();\n setCoreState(store.getState().core);\n\n const unsubscribe = store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && newState.core !== oldState.core) {\n setCoreState(newState.core);\n }\n });\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n if (pdfViewer.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n pdfViewer.pluginsReady().then(() => {\n if (!pdfViewer.isDestroyed()) {\n setPluginsReady(true);\n }\n });\n\n // Provide the registry to children via context\n setRegistry(pdfViewer);\n setIsInitializing(false);\n\n // Return cleanup function\n return unsubscribe;\n };\n\n let cleanup: (() => void) | undefined;\n initialize()\n .then((unsub) => {\n cleanup = unsub;\n })\n .catch(console.error);\n\n return () => {\n cleanup?.();\n pdfViewer.destroy();\n setRegistry(null);\n setCoreState(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n // Compute convenience accessors\n const contextValue: PDFContextState = useMemo(() => {\n const activeDocumentId = coreState?.activeDocumentId ?? null;\n const documents = coreState?.documents ?? {};\n const documentOrder = coreState?.documentOrder ?? [];\n\n // Compute active document\n const activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n\n // Compute open documents in order\n const documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n\n return {\n registry,\n coreState,\n isInitializing,\n pluginsReady,\n // Convenience accessors (always safe to use)\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n };\n }, [registry, coreState, isInitializing, pluginsReady]);\n\n const content = typeof children === 'function' ? children(contextValue) : children;\n\n return (\n <PDFContext.Provider value={contextValue}>\n {pluginsReady && autoMountDomElements ? (\n <AutoMount plugins={plugins}>{content}</AutoMount>\n ) : (\n content\n )}\n </PDFContext.Provider>\n );\n}\n","import { useContext } from '@framework';\nimport { PDFContext, PDFContextState } from '../context';\n\n/**\n * Hook to access the PDF registry.\n * @returns The PDF registry or null during initialization\n */\nexport function useRegistry(): PDFContextState {\n const contextValue = useContext(PDFContext);\n\n // Error if used outside of context\n if (contextValue === undefined) {\n throw new Error('useCapability must be used within a PDFContext.Provider');\n }\n\n const { registry, isInitializing } = contextValue;\n\n // During initialization, return null instead of throwing an error\n if (isInitializing) {\n return contextValue;\n }\n\n // At this point, initialization is complete but registry is still null, which is unexpected\n if (registry === null) {\n throw new Error('PDF registry failed to initialize properly');\n }\n\n return contextValue;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\ntype PluginState<T extends BasePlugin> = {\n plugin: T | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin.\n * @param pluginId The ID of the plugin to access\n * @returns The plugin or null during initialization\n * @example\n * // Get zoom plugin\n * const zoom = usePlugin<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n if (registry === null) {\n return {\n plugin: null,\n isLoading: true,\n ready: new Promise(() => {}),\n };\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n return {\n plugin,\n isLoading: false,\n ready: plugin.ready(),\n };\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin';\n\ntype CapabilityState<T extends BasePlugin> = {\n provides: ReturnType<NonNullable<T['provides']>> | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin's capability.\n * @param pluginId The ID of the plugin to access\n * @returns The capability provided by the plugin or null during initialization\n * @example\n * // Get zoom capability\n * const zoom = useCapability<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function useCapability<T extends BasePlugin>(pluginId: T['id']): CapabilityState<T> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n if (!plugin) {\n return {\n provides: null,\n isLoading,\n ready,\n };\n }\n\n if (!plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n return {\n provides: plugin.provides() as ReturnType<NonNullable<T['provides']>>,\n isLoading,\n ready,\n };\n}\n","import { useState, useEffect } from '@framework';\nimport { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Hook that provides access to the current global store state\n * and re-renders the component when the state changes\n */\nexport function useStoreState<T = CoreState>(): StoreState<T> | null {\n const { registry } = useRegistry();\n const [state, setState] = useState<StoreState<T> | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n // Get initial state\n setState(registry.getStore().getState() as StoreState<T>);\n\n // Subscribe to store changes\n const unsubscribe = registry.getStore().subscribe((_action, newState) => {\n setState(newState as StoreState<T>);\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return state;\n}\n","import { useContext } from '@framework';\nimport { CoreState } from '@embedpdf/core';\nimport { PDFContext } from '../context';\n\n/**\n * Hook that provides access to the current core state.\n *\n * Note: This reads from the context which is already subscribed to core state changes\n * in the EmbedPDF component, so there's no additional subscription overhead.\n */\nexport function useCoreState(): CoreState | null {\n const { coreState } = useContext(PDFContext);\n return coreState;\n}\n","import { useMemo } from '@framework';\nimport { DocumentState } from '@embedpdf/core';\nimport { useCoreState } from './use-core-state';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param documentId The ID of the document to retrieve.\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: string | null): DocumentState | null {\n const coreState = useCoreState();\n\n const documentState = useMemo(() => {\n if (!coreState || !documentId) return null;\n return coreState.documents[documentId] ?? null;\n }, [coreState, documentId]);\n\n return documentState;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\n\n/**\n * Human-readable permission names for use in configuration.\n */\nexport type PermissionName =\n | 'print'\n | 'modifyContents'\n | 'copyContents'\n | 'modifyAnnotations'\n | 'fillForms'\n | 'extractForAccessibility'\n | 'assembleDocument'\n | 'printHighQuality';\n\n/**\n * Map from human-readable names to PdfPermissionFlag values.\n */\nexport const PERMISSION_NAME_TO_FLAG: Record<PermissionName, PdfPermissionFlag> = {\n print: PdfPermissionFlag.Print,\n modifyContents: PdfPermissionFlag.ModifyContents,\n copyContents: PdfPermissionFlag.CopyContents,\n modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,\n fillForms: PdfPermissionFlag.FillForms,\n extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,\n assembleDocument: PdfPermissionFlag.AssembleDocument,\n printHighQuality: PdfPermissionFlag.PrintHighQuality,\n};\n\n/**\n * Permission overrides can use either numeric flags or human-readable string names.\n */\nexport type PermissionOverrides = Partial<\n Record<PdfPermissionFlag, boolean> & Record<PermissionName, boolean>\n>;\n\n/**\n * Configuration for overriding document permissions.\n * Can be applied globally (at PluginRegistry level) or per-document (when opening).\n */\nexport interface PermissionConfig {\n /**\n * When true (default): use PDF's permissions as the base, then apply overrides.\n * When false: treat document as having all permissions allowed, then apply overrides.\n */\n enforceDocumentPermissions?: boolean;\n\n /**\n * Explicit per-flag overrides. Supports both numeric flags and string names.\n * - true = force allow (even if PDF denies)\n * - false = force deny (even if PDF allows)\n * - undefined = use base permissions\n *\n * @example\n * // Using string names (recommended)\n * overrides: { print: false, modifyAnnotations: true }\n *\n * @example\n * // Using numeric flags\n * overrides: { [PdfPermissionFlag.Print]: false }\n */\n overrides?: PermissionOverrides;\n}\n\n/**\n * All permission flags for iteration when computing effective permissions.\n */\nexport const ALL_PERMISSION_FLAGS: PdfPermissionFlag[] = [\n PdfPermissionFlag.Print,\n PdfPermissionFlag.ModifyContents,\n PdfPermissionFlag.CopyContents,\n PdfPermissionFlag.ModifyAnnotations,\n PdfPermissionFlag.FillForms,\n PdfPermissionFlag.ExtractForAccessibility,\n PdfPermissionFlag.AssembleDocument,\n PdfPermissionFlag.PrintHighQuality,\n];\n\n/**\n * All permission names for iteration.\n */\nexport const ALL_PERMISSION_NAMES: PermissionName[] = [\n 'print',\n 'modifyContents',\n 'copyContents',\n 'modifyAnnotations',\n 'fillForms',\n 'extractForAccessibility',\n 'assembleDocument',\n 'printHighQuality',\n];\n\n/**\n * Map from PdfPermissionFlag to human-readable name.\n */\nexport const PERMISSION_FLAG_TO_NAME: Record<PdfPermissionFlag, PermissionName> = {\n [PdfPermissionFlag.Print]: 'print',\n [PdfPermissionFlag.ModifyContents]: 'modifyContents',\n [PdfPermissionFlag.CopyContents]: 'copyContents',\n [PdfPermissionFlag.ModifyAnnotations]: 'modifyAnnotations',\n [PdfPermissionFlag.FillForms]: 'fillForms',\n [PdfPermissionFlag.ExtractForAccessibility]: 'extractForAccessibility',\n [PdfPermissionFlag.AssembleDocument]: 'assembleDocument',\n [PdfPermissionFlag.PrintHighQuality]: 'printHighQuality',\n};\n\n/**\n * Helper to get the override value for a permission flag, checking both numeric and string keys.\n */\nexport function getPermissionOverride(\n overrides: PermissionOverrides | undefined,\n flag: PdfPermissionFlag,\n): boolean | undefined {\n if (!overrides) return undefined;\n\n // Check numeric key first\n if (flag in overrides) {\n return (overrides as Record<PdfPermissionFlag, boolean>)[flag];\n }\n\n // Check string key\n const name = PERMISSION_FLAG_TO_NAME[flag];\n if (name && name in overrides) {\n return (overrides as Record<PermissionName, boolean>)[name];\n }\n\n return undefined;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\nimport { CoreState, DocumentState } from './initial-state';\nimport { ALL_PERMISSION_FLAGS, getPermissionOverride } from '../types/permissions';\n\n/**\n * Get the active document state\n */\nexport const getActiveDocumentState = (state: CoreState): DocumentState | null => {\n if (!state.activeDocumentId) return null;\n return state.documents[state.activeDocumentId] ?? null;\n};\n\n/**\n * Get document state by ID\n */\nexport const getDocumentState = (state: CoreState, documentId: string): DocumentState | null => {\n return state.documents[documentId] ?? null;\n};\n\n/**\n * Get all document IDs\n */\nexport const getDocumentIds = (state: CoreState): string[] => {\n return Object.keys(state.documents);\n};\n\n/**\n * Check if a document is loaded\n */\nexport const isDocumentLoaded = (state: CoreState, documentId: string): boolean => {\n return !!state.documents[documentId];\n};\n\n/**\n * Get the number of open documents\n */\nexport const getDocumentCount = (state: CoreState): number => {\n return Object.keys(state.documents).length;\n};\n\n// ─────────────────────────────────────────────────────────\n// Permission Selectors\n// ─────────────────────────────────────────────────────────\n\n/**\n * Check if a specific permission flag is effectively allowed for a document.\n * Applies layered resolution: per-document override → global override → enforceDocumentPermissions → PDF permission.\n *\n * @param state - The core state\n * @param documentId - The document ID to check permissions for\n * @param flag - The permission flag to check\n * @returns true if the permission is allowed, false otherwise\n */\nexport function getEffectivePermission(\n state: CoreState,\n documentId: string,\n flag: PdfPermissionFlag,\n): boolean {\n const docState = state.documents[documentId];\n const docConfig = docState?.permissions;\n const globalConfig = state.globalPermissions;\n const pdfPermissions = docState?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n // 1. Per-document override wins (supports both numeric and string keys)\n const docOverride = getPermissionOverride(docConfig?.overrides, flag);\n if (docOverride !== undefined) {\n return docOverride;\n }\n\n // 2. Global override (supports both numeric and string keys)\n const globalOverride = getPermissionOverride(globalConfig?.overrides, flag);\n if (globalOverride !== undefined) {\n return globalOverride;\n }\n\n // 3. Check enforce setting (per-doc takes precedence over global)\n const enforce =\n docConfig?.enforceDocumentPermissions ?? globalConfig?.enforceDocumentPermissions ?? true;\n\n if (!enforce) return true; // Not enforcing = allow all\n\n // 4. Use PDF permission\n return (pdfPermissions & flag) !== 0;\n}\n\n/**\n * Get all effective permissions as a bitmask for a document.\n * Combines all individual permission checks into a single bitmask.\n *\n * @param state - The core state\n * @param documentId - The document ID to get permissions for\n * @returns A bitmask of all effective permissions\n */\nexport function getEffectivePermissions(state: CoreState, documentId: string): number {\n return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {\n return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;\n }, 0);\n}\n","import { useMemo } from '@framework';\nimport { PdfPermissionFlag } from '@embedpdf/models';\nimport { useCoreState } from './use-core-state';\nimport { getEffectivePermission, getEffectivePermissions } from '../../lib/store/selectors';\n\nexport interface DocumentPermissions {\n /** Effective permission flags after applying overrides */\n permissions: number;\n /** Raw PDF permission flags (before overrides) */\n pdfPermissions: number;\n /** Check if a specific permission flag is effectively allowed */\n hasPermission: (flag: PdfPermissionFlag) => boolean;\n /** Check if all specified flags are effectively allowed */\n hasAllPermissions: (...flags: PdfPermissionFlag[]) => boolean;\n\n // Shorthand booleans for all permission flags (using effective permissions):\n /** Can print (possibly degraded quality) */\n canPrint: boolean;\n /** Can modify document contents */\n canModifyContents: boolean;\n /** Can copy/extract text and graphics */\n canCopyContents: boolean;\n /** Can add/modify annotations and fill forms */\n canModifyAnnotations: boolean;\n /** Can fill in existing form fields */\n canFillForms: boolean;\n /** Can extract for accessibility */\n canExtractForAccessibility: boolean;\n /** Can assemble document (insert, rotate, delete pages) */\n canAssembleDocument: boolean;\n /** Can print high quality */\n canPrintHighQuality: boolean;\n}\n\n/**\n * Hook that provides reactive access to a document's effective permission flags.\n * Applies layered resolution: per-document override → global override → PDF permission.\n *\n * @param documentId The ID of the document to check permissions for.\n * @returns An object with effective permissions, raw PDF permissions, helper functions, and shorthand booleans.\n */\nexport function useDocumentPermissions(documentId: string): DocumentPermissions {\n const coreState = useCoreState();\n\n return useMemo(() => {\n if (!coreState) {\n return {\n permissions: PdfPermissionFlag.AllowAll,\n pdfPermissions: PdfPermissionFlag.AllowAll,\n hasPermission: () => true,\n hasAllPermissions: () => true,\n canPrint: true,\n canModifyContents: true,\n canCopyContents: true,\n canModifyAnnotations: true,\n canFillForms: true,\n canExtractForAccessibility: true,\n canAssembleDocument: true,\n canPrintHighQuality: true,\n };\n }\n\n const effectivePermissions = getEffectivePermissions(coreState, documentId);\n const pdfPermissions =\n coreState.documents[documentId]?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n const hasPermission = (flag: PdfPermissionFlag) =>\n getEffectivePermission(coreState, documentId, flag);\n const hasAllPermissions = (...flags: PdfPermissionFlag[]) =>\n flags.every((flag) => getEffectivePermission(coreState, documentId, flag));\n\n return {\n permissions: effectivePermissions,\n pdfPermissions,\n hasPermission,\n hasAllPermissions,\n // All permission flags as booleans (using effective permissions)\n canPrint: hasPermission(PdfPermissionFlag.Print),\n canModifyContents: hasPermission(PdfPermissionFlag.ModifyContents),\n canCopyContents: hasPermission(PdfPermissionFlag.CopyContents),\n canModifyAnnotations: hasPermission(PdfPermissionFlag.ModifyAnnotations),\n canFillForms: hasPermission(PdfPermissionFlag.FillForms),\n canExtractForAccessibility: hasPermission(PdfPermissionFlag.ExtractForAccessibility),\n canAssembleDocument: hasPermission(PdfPermissionFlag.AssembleDocument),\n canPrintHighQuality: hasPermission(PdfPermissionFlag.PrintHighQuality),\n };\n }, [coreState, documentId]);\n}\n"],"names":["utilities","wrappers"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),n=require("react/jsx-runtime"),i=require("@embedpdf/core"),t=require("@embedpdf/models"),s=e.createContext({registry:null,coreState:null,isInitializing:!0,pluginsReady:!1,activeDocumentId:null,activeDocument:null,documents:{},documentStates:[]});function o({plugins:t,children:s}){const{utilities:o,wrappers:r}=e.useMemo(()=>{const e=[],n=[];for(const s of t){const t=s.package;if(i.hasAutoMountElements(t)){const i=t.autoMountElements()||[];for(const t of i)"utility"===t.type?e.push(t.component):"wrapper"===t.type&&n.push(t.component)}}return{utilities:e,wrappers:n}},[t]),l=r.reduce((e,i)=>n.jsx(i,{children:e}),s);return n.jsxs(e.Fragment,{children:[l,o.map((e,i)=>n.jsx(e,{},`utility-${i}`))]})}function r(){const n=e.useContext(s);if(void 0===n)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:i,isInitializing:t}=n;if(t)return n;if(null===i)throw new Error("PDF registry failed to initialize properly");return n}function l(e){const{registry:n}=r();if(null===n)return{plugin:null,isLoading:!0,ready:new Promise(()=>{})};const i=n.getPlugin(e);if(!i)throw new Error(`Plugin ${e} not found`);return{plugin:i,isLoading:!1,ready:i.ready()}}function u(){const{coreState:n}=e.useContext(s);return n}t.PdfPermissionFlag.Print,t.PdfPermissionFlag.ModifyContents,t.PdfPermissionFlag.CopyContents,t.PdfPermissionFlag.ModifyAnnotations,t.PdfPermissionFlag.FillForms,t.PdfPermissionFlag.ExtractForAccessibility,t.PdfPermissionFlag.AssembleDocument,t.PdfPermissionFlag.PrintHighQuality;const a=[t.PdfPermissionFlag.Print,t.PdfPermissionFlag.ModifyContents,t.PdfPermissionFlag.CopyContents,t.PdfPermissionFlag.ModifyAnnotations,t.PdfPermissionFlag.FillForms,t.PdfPermissionFlag.ExtractForAccessibility,t.PdfPermissionFlag.AssembleDocument,t.PdfPermissionFlag.PrintHighQuality],c={[t.PdfPermissionFlag.Print]:"print",[t.PdfPermissionFlag.ModifyContents]:"modifyContents",[t.PdfPermissionFlag.CopyContents]:"copyContents",[t.PdfPermissionFlag.ModifyAnnotations]:"modifyAnnotations",[t.PdfPermissionFlag.FillForms]:"fillForms",[t.PdfPermissionFlag.ExtractForAccessibility]:"extractForAccessibility",[t.PdfPermissionFlag.AssembleDocument]:"assembleDocument",[t.PdfPermissionFlag.PrintHighQuality]:"printHighQuality"};function d(e,n){if(!e)return;if(n in e)return e[n];const i=c[n];return i&&i in e?e[i]:void 0}function m(e,n,i){var s;const o=e.documents[n],r=null==o?void 0:o.permissions,l=e.globalPermissions,u=(null==(s=null==o?void 0:o.document)?void 0:s.permissions)??t.PdfPermissionFlag.AllowAll,a=d(null==r?void 0:r.overrides,i);if(void 0!==a)return a;const c=d(null==l?void 0:l.overrides,i);if(void 0!==c)return c;return!((null==r?void 0:r.enforceDocumentPermissions)??(null==l?void 0:l.enforceDocumentPermissions)??!0)||0!==(u&i)}exports.EmbedPDF=function({engine:t,config:r,logger:l,onInitialized:u,plugins:a,children:c,autoMountDomElements:d=!0}){const[m,P]=e.useState(null),[f,g]=e.useState(null),[y,p]=e.useState(!0),[F,v]=e.useState(!1),A=e.useRef(u);e.useEffect(()=>{A.current=u},[u]),e.useEffect(()=>{const e={...r,logger:(null==r?void 0:r.logger)??l},n=new i.PluginRegistry(t,e);n.registerPluginBatch(a);let s;return(async()=>{var e;if(await n.initialize(),n.isDestroyed())return;const i=n.getStore();g(i.getState().core);const t=i.subscribe((e,n,t)=>{i.isCoreAction(e)&&n.core!==t.core&&g(n.core)});if(await(null==(e=A.current)?void 0:e.call(A,n)),!n.isDestroyed())return n.pluginsReady().then(()=>{n.isDestroyed()||v(!0)}),P(n),p(!1),t;t()})().then(e=>{s=e}).catch(console.error),()=>{null==s||s(),n.destroy(),P(null),g(null),p(!0),v(!1)}},[t,a]);const h=e.useMemo(()=>{const e=(null==f?void 0:f.activeDocumentId)??null,n=(null==f?void 0:f.documents)??{},i=(null==f?void 0:f.documentOrder)??[],t=e&&n[e]?n[e]:null,s=i.map(e=>n[e]).filter(e=>null!=e);return{registry:m,coreState:f,isInitializing:y,pluginsReady:F,activeDocumentId:e,activeDocument:t,documents:n,documentStates:s}},[m,f,y,F]),C="function"==typeof c?c(h):c;return n.jsx(s.Provider,{value:h,children:F&&d?n.jsx(o,{plugins:a,children:C}):C})},exports.PDFContext=s,exports.useCapability=function(e){const{plugin:n,isLoading:i,ready:t}=l(e);if(!n)return{provides:null,isLoading:i,ready:t};if(!n.provides)throw new Error(`Plugin ${e} does not provide a capability`);return{provides:n.provides(),isLoading:i,ready:t}},exports.useCoreState=u,exports.useDocumentPermissions=function(n){const i=u();return e.useMemo(()=>{var e,s;if(!i)return{permissions:t.PdfPermissionFlag.AllowAll,pdfPermissions:t.PdfPermissionFlag.AllowAll,hasPermission:()=>!0,hasAllPermissions:()=>!0,canPrint:!0,canModifyContents:!0,canCopyContents:!0,canModifyAnnotations:!0,canFillForms:!0,canExtractForAccessibility:!0,canAssembleDocument:!0,canPrintHighQuality:!0};const o=function(e,n){return a.reduce((i,t)=>m(e,n,t)?i|t:i,0)}(i,n),r=e=>m(i,n,e);return{permissions:o,pdfPermissions:(null==(s=null==(e=i.documents[n])?void 0:e.document)?void 0:s.permissions)??t.PdfPermissionFlag.AllowAll,hasPermission:r,hasAllPermissions:(...e)=>e.every(e=>m(i,n,e)),canPrint:r(t.PdfPermissionFlag.Print),canModifyContents:r(t.PdfPermissionFlag.ModifyContents),canCopyContents:r(t.PdfPermissionFlag.CopyContents),canModifyAnnotations:r(t.PdfPermissionFlag.ModifyAnnotations),canFillForms:r(t.PdfPermissionFlag.FillForms),canExtractForAccessibility:r(t.PdfPermissionFlag.ExtractForAccessibility),canAssembleDocument:r(t.PdfPermissionFlag.AssembleDocument),canPrintHighQuality:r(t.PdfPermissionFlag.PrintHighQuality)}},[i,n])},exports.useDocumentState=function(n){const i=u();return e.useMemo(()=>i&&n?i.documents[n]??null:null,[i,n])},exports.usePlugin=l,exports.useRegistry=r,exports.useStoreState=function(){const{registry:n}=r(),[i,t]=e.useState(null);return e.useEffect(()=>{if(!n)return;t(n.getStore().getState());const e=n.getStore().subscribe((e,n)=>{t(n)});return()=>e()},[n]),i};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),n=require("react/jsx-runtime"),i=require("@embedpdf/core"),t=require("@embedpdf/models"),s=e.createContext({registry:null,coreState:null,isInitializing:!0,pluginsReady:!1,activeDocumentId:null,activeDocument:null,documents:{},documentStates:[]});function o({plugins:t,children:s}){const{utilities:o,wrappers:r}=e.useMemo(()=>{const e=[],n=[];for(const s of t){const t=s.package;if(i.hasAutoMountElements(t)){const i=t.autoMountElements()||[];for(const t of i)"utility"===t.type?e.push(t.component):"wrapper"===t.type&&n.push(t.component)}}return{utilities:e,wrappers:n}},[t]),l=n.jsxs(e.Fragment,{children:[s,o.map((e,i)=>n.jsx(e,{},`utility-${i}`))]}),u=r.reduce((e,i)=>n.jsx(i,{children:e}),l);return n.jsx(e.Fragment,{children:u})}function r(){const n=e.useContext(s);if(void 0===n)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:i,isInitializing:t}=n;if(t)return n;if(null===i)throw new Error("PDF registry failed to initialize properly");return n}function l(e){const{registry:n}=r();if(null===n)return{plugin:null,isLoading:!0,ready:new Promise(()=>{})};const i=n.getPlugin(e);if(!i)throw new Error(`Plugin ${e} not found`);return{plugin:i,isLoading:!1,ready:i.ready()}}function u(){const{coreState:n}=e.useContext(s);return n}t.PdfPermissionFlag.Print,t.PdfPermissionFlag.ModifyContents,t.PdfPermissionFlag.CopyContents,t.PdfPermissionFlag.ModifyAnnotations,t.PdfPermissionFlag.FillForms,t.PdfPermissionFlag.ExtractForAccessibility,t.PdfPermissionFlag.AssembleDocument,t.PdfPermissionFlag.PrintHighQuality;const a=[t.PdfPermissionFlag.Print,t.PdfPermissionFlag.ModifyContents,t.PdfPermissionFlag.CopyContents,t.PdfPermissionFlag.ModifyAnnotations,t.PdfPermissionFlag.FillForms,t.PdfPermissionFlag.ExtractForAccessibility,t.PdfPermissionFlag.AssembleDocument,t.PdfPermissionFlag.PrintHighQuality],c={[t.PdfPermissionFlag.Print]:"print",[t.PdfPermissionFlag.ModifyContents]:"modifyContents",[t.PdfPermissionFlag.CopyContents]:"copyContents",[t.PdfPermissionFlag.ModifyAnnotations]:"modifyAnnotations",[t.PdfPermissionFlag.FillForms]:"fillForms",[t.PdfPermissionFlag.ExtractForAccessibility]:"extractForAccessibility",[t.PdfPermissionFlag.AssembleDocument]:"assembleDocument",[t.PdfPermissionFlag.PrintHighQuality]:"printHighQuality"};function d(e,n){if(!e)return;if(n in e)return e[n];const i=c[n];return i&&i in e?e[i]:void 0}function m(e,n,i){var s;const o=e.documents[n],r=null==o?void 0:o.permissions,l=e.globalPermissions,u=(null==(s=null==o?void 0:o.document)?void 0:s.permissions)??t.PdfPermissionFlag.AllowAll,a=d(null==r?void 0:r.overrides,i);if(void 0!==a)return a;const c=d(null==l?void 0:l.overrides,i);if(void 0!==c)return c;return!((null==r?void 0:r.enforceDocumentPermissions)??(null==l?void 0:l.enforceDocumentPermissions)??!0)||0!==(u&i)}exports.EmbedPDF=function({engine:t,config:r,logger:l,onInitialized:u,plugins:a,children:c,autoMountDomElements:d=!0}){const[m,P]=e.useState(null),[f,g]=e.useState(null),[y,p]=e.useState(!0),[F,v]=e.useState(!1),A=e.useRef(u);e.useEffect(()=>{A.current=u},[u]),e.useEffect(()=>{const e={...r,logger:(null==r?void 0:r.logger)??l},n=new i.PluginRegistry(t,e);n.registerPluginBatch(a);let s;return(async()=>{var e;if(await n.initialize(),n.isDestroyed())return;const i=n.getStore();g(i.getState().core);const t=i.subscribe((e,n,t)=>{i.isCoreAction(e)&&n.core!==t.core&&g(n.core)});if(await(null==(e=A.current)?void 0:e.call(A,n)),!n.isDestroyed())return n.pluginsReady().then(()=>{n.isDestroyed()||v(!0)}),P(n),p(!1),t;t()})().then(e=>{s=e}).catch(console.error),()=>{null==s||s(),n.destroy(),P(null),g(null),p(!0),v(!1)}},[t,a]);const h=e.useMemo(()=>{const e=(null==f?void 0:f.activeDocumentId)??null,n=(null==f?void 0:f.documents)??{},i=(null==f?void 0:f.documentOrder)??[],t=e&&n[e]?n[e]:null,s=i.map(e=>n[e]).filter(e=>null!=e);return{registry:m,coreState:f,isInitializing:y,pluginsReady:F,activeDocumentId:e,activeDocument:t,documents:n,documentStates:s}},[m,f,y,F]),x="function"==typeof c?c(h):c;return n.jsx(s.Provider,{value:h,children:F&&d?n.jsx(o,{plugins:a,children:x}):x})},exports.PDFContext=s,exports.useCapability=function(e){const{plugin:n,isLoading:i,ready:t}=l(e);if(!n)return{provides:null,isLoading:i,ready:t};if(!n.provides)throw new Error(`Plugin ${e} does not provide a capability`);return{provides:n.provides(),isLoading:i,ready:t}},exports.useCoreState=u,exports.useDocumentPermissions=function(n){const i=u();return e.useMemo(()=>{var e,s;if(!i)return{permissions:t.PdfPermissionFlag.AllowAll,pdfPermissions:t.PdfPermissionFlag.AllowAll,hasPermission:()=>!0,hasAllPermissions:()=>!0,canPrint:!0,canModifyContents:!0,canCopyContents:!0,canModifyAnnotations:!0,canFillForms:!0,canExtractForAccessibility:!0,canAssembleDocument:!0,canPrintHighQuality:!0};const o=function(e,n){return a.reduce((i,t)=>m(e,n,t)?i|t:i,0)}(i,n),r=e=>m(i,n,e);return{permissions:o,pdfPermissions:(null==(s=null==(e=i.documents[n])?void 0:e.document)?void 0:s.permissions)??t.PdfPermissionFlag.AllowAll,hasPermission:r,hasAllPermissions:(...e)=>e.every(e=>m(i,n,e)),canPrint:r(t.PdfPermissionFlag.Print),canModifyContents:r(t.PdfPermissionFlag.ModifyContents),canCopyContents:r(t.PdfPermissionFlag.CopyContents),canModifyAnnotations:r(t.PdfPermissionFlag.ModifyAnnotations),canFillForms:r(t.PdfPermissionFlag.FillForms),canExtractForAccessibility:r(t.PdfPermissionFlag.ExtractForAccessibility),canAssembleDocument:r(t.PdfPermissionFlag.AssembleDocument),canPrintHighQuality:r(t.PdfPermissionFlag.PrintHighQuality)}},[i,n])},exports.useDocumentState=function(n){const i=u();return e.useMemo(()=>i&&n?i.documents[n]??null:null,[i,n])},exports.usePlugin=l,exports.useRegistry=r,exports.useStoreState=function(){const{registry:n}=r(),[i,t]=e.useState(null);return e.useEffect(()=>{if(!n)return;t(n.getStore().getState());const e=n.getStore().subscribe((e,n)=>{t(n)});return()=>e()},[n]),i};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/components/auto-mount.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/hooks/use-core-state.ts","../../src/lib/types/permissions.ts","../../src/lib/store/selectors.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-document-permissions.ts","../../src/shared/hooks/use-document-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { CoreState, DocumentState, PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n coreState: CoreState | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: string | null;\n activeDocument: DocumentState | null;\n documents: Record<string, DocumentState>;\n documentStates: DocumentState[];\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n coreState: null,\n isInitializing: true,\n pluginsReady: false,\n activeDocumentId: null,\n activeDocument: null,\n documents: {},\n documentStates: [],\n});\n","import { Fragment, useMemo, ComponentType, ReactNode } from '@framework';\nimport { hasAutoMountElements } from '@embedpdf/core';\nimport type { PluginBatchRegistration, IPlugin } from '@embedpdf/core';\n\ninterface AutoMountProps {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode;\n}\n\nexport function AutoMount({ plugins, children }: AutoMountProps) {\n const { utilities, wrappers } = useMemo(() => {\n // React-specific types for internal use\n const utilities: ComponentType[] = [];\n const wrappers: ComponentType<{ children: ReactNode }>[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements() || [];\n\n for (const element of elements) {\n if (element.type === 'utility') {\n utilities.push(element.component);\n } else if (element.type === 'wrapper') {\n // In React context, we know wrappers need children\n wrappers.push(element.component);\n }\n }\n }\n }\n return { utilities, wrappers };\n }, [plugins]);\n\n // React-specific wrapping logic\n const wrappedContent = wrappers.reduce(\n (content, Wrapper) => <Wrapper>{content}</Wrapper>,\n children,\n );\n\n return (\n <Fragment>\n {wrappedContent}\n {utilities.map((Utility, i) => (\n <Utility key={`utility-${i}`} />\n ))}\n </Fragment>\n );\n}\n","import { useContext } from '@framework';\nimport { PDFContext, PDFContextState } from '../context';\n\n/**\n * Hook to access the PDF registry.\n * @returns The PDF registry or null during initialization\n */\nexport function useRegistry(): PDFContextState {\n const contextValue = useContext(PDFContext);\n\n // Error if used outside of context\n if (contextValue === undefined) {\n throw new Error('useCapability must be used within a PDFContext.Provider');\n }\n\n const { registry, isInitializing } = contextValue;\n\n // During initialization, return null instead of throwing an error\n if (isInitializing) {\n return contextValue;\n }\n\n // At this point, initialization is complete but registry is still null, which is unexpected\n if (registry === null) {\n throw new Error('PDF registry failed to initialize properly');\n }\n\n return contextValue;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\ntype PluginState<T extends BasePlugin> = {\n plugin: T | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin.\n * @param pluginId The ID of the plugin to access\n * @returns The plugin or null during initialization\n * @example\n * // Get zoom plugin\n * const zoom = usePlugin<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n if (registry === null) {\n return {\n plugin: null,\n isLoading: true,\n ready: new Promise(() => {}),\n };\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n return {\n plugin,\n isLoading: false,\n ready: plugin.ready(),\n };\n}\n","import { useContext } from '@framework';\nimport { CoreState } from '@embedpdf/core';\nimport { PDFContext } from '../context';\n\n/**\n * Hook that provides access to the current core state.\n *\n * Note: This reads from the context which is already subscribed to core state changes\n * in the EmbedPDF component, so there's no additional subscription overhead.\n */\nexport function useCoreState(): CoreState | null {\n const { coreState } = useContext(PDFContext);\n return coreState;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\n\n/**\n * Human-readable permission names for use in configuration.\n */\nexport type PermissionName =\n | 'print'\n | 'modifyContents'\n | 'copyContents'\n | 'modifyAnnotations'\n | 'fillForms'\n | 'extractForAccessibility'\n | 'assembleDocument'\n | 'printHighQuality';\n\n/**\n * Map from human-readable names to PdfPermissionFlag values.\n */\nexport const PERMISSION_NAME_TO_FLAG: Record<PermissionName, PdfPermissionFlag> = {\n print: PdfPermissionFlag.Print,\n modifyContents: PdfPermissionFlag.ModifyContents,\n copyContents: PdfPermissionFlag.CopyContents,\n modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,\n fillForms: PdfPermissionFlag.FillForms,\n extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,\n assembleDocument: PdfPermissionFlag.AssembleDocument,\n printHighQuality: PdfPermissionFlag.PrintHighQuality,\n};\n\n/**\n * Permission overrides can use either numeric flags or human-readable string names.\n */\nexport type PermissionOverrides = Partial<\n Record<PdfPermissionFlag, boolean> & Record<PermissionName, boolean>\n>;\n\n/**\n * Configuration for overriding document permissions.\n * Can be applied globally (at PluginRegistry level) or per-document (when opening).\n */\nexport interface PermissionConfig {\n /**\n * When true (default): use PDF's permissions as the base, then apply overrides.\n * When false: treat document as having all permissions allowed, then apply overrides.\n */\n enforceDocumentPermissions?: boolean;\n\n /**\n * Explicit per-flag overrides. Supports both numeric flags and string names.\n * - true = force allow (even if PDF denies)\n * - false = force deny (even if PDF allows)\n * - undefined = use base permissions\n *\n * @example\n * // Using string names (recommended)\n * overrides: { print: false, modifyAnnotations: true }\n *\n * @example\n * // Using numeric flags\n * overrides: { [PdfPermissionFlag.Print]: false }\n */\n overrides?: PermissionOverrides;\n}\n\n/**\n * All permission flags for iteration when computing effective permissions.\n */\nexport const ALL_PERMISSION_FLAGS: PdfPermissionFlag[] = [\n PdfPermissionFlag.Print,\n PdfPermissionFlag.ModifyContents,\n PdfPermissionFlag.CopyContents,\n PdfPermissionFlag.ModifyAnnotations,\n PdfPermissionFlag.FillForms,\n PdfPermissionFlag.ExtractForAccessibility,\n PdfPermissionFlag.AssembleDocument,\n PdfPermissionFlag.PrintHighQuality,\n];\n\n/**\n * All permission names for iteration.\n */\nexport const ALL_PERMISSION_NAMES: PermissionName[] = [\n 'print',\n 'modifyContents',\n 'copyContents',\n 'modifyAnnotations',\n 'fillForms',\n 'extractForAccessibility',\n 'assembleDocument',\n 'printHighQuality',\n];\n\n/**\n * Map from PdfPermissionFlag to human-readable name.\n */\nexport const PERMISSION_FLAG_TO_NAME: Record<PdfPermissionFlag, PermissionName> = {\n [PdfPermissionFlag.Print]: 'print',\n [PdfPermissionFlag.ModifyContents]: 'modifyContents',\n [PdfPermissionFlag.CopyContents]: 'copyContents',\n [PdfPermissionFlag.ModifyAnnotations]: 'modifyAnnotations',\n [PdfPermissionFlag.FillForms]: 'fillForms',\n [PdfPermissionFlag.ExtractForAccessibility]: 'extractForAccessibility',\n [PdfPermissionFlag.AssembleDocument]: 'assembleDocument',\n [PdfPermissionFlag.PrintHighQuality]: 'printHighQuality',\n};\n\n/**\n * Helper to get the override value for a permission flag, checking both numeric and string keys.\n */\nexport function getPermissionOverride(\n overrides: PermissionOverrides | undefined,\n flag: PdfPermissionFlag,\n): boolean | undefined {\n if (!overrides) return undefined;\n\n // Check numeric key first\n if (flag in overrides) {\n return (overrides as Record<PdfPermissionFlag, boolean>)[flag];\n }\n\n // Check string key\n const name = PERMISSION_FLAG_TO_NAME[flag];\n if (name && name in overrides) {\n return (overrides as Record<PermissionName, boolean>)[name];\n }\n\n return undefined;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\nimport { CoreState, DocumentState } from './initial-state';\nimport { ALL_PERMISSION_FLAGS, getPermissionOverride } from '../types/permissions';\n\n/**\n * Get the active document state\n */\nexport const getActiveDocumentState = (state: CoreState): DocumentState | null => {\n if (!state.activeDocumentId) return null;\n return state.documents[state.activeDocumentId] ?? null;\n};\n\n/**\n * Get document state by ID\n */\nexport const getDocumentState = (state: CoreState, documentId: string): DocumentState | null => {\n return state.documents[documentId] ?? null;\n};\n\n/**\n * Get all document IDs\n */\nexport const getDocumentIds = (state: CoreState): string[] => {\n return Object.keys(state.documents);\n};\n\n/**\n * Check if a document is loaded\n */\nexport const isDocumentLoaded = (state: CoreState, documentId: string): boolean => {\n return !!state.documents[documentId];\n};\n\n/**\n * Get the number of open documents\n */\nexport const getDocumentCount = (state: CoreState): number => {\n return Object.keys(state.documents).length;\n};\n\n// ─────────────────────────────────────────────────────────\n// Permission Selectors\n// ─────────────────────────────────────────────────────────\n\n/**\n * Check if a specific permission flag is effectively allowed for a document.\n * Applies layered resolution: per-document override → global override → enforceDocumentPermissions → PDF permission.\n *\n * @param state - The core state\n * @param documentId - The document ID to check permissions for\n * @param flag - The permission flag to check\n * @returns true if the permission is allowed, false otherwise\n */\nexport function getEffectivePermission(\n state: CoreState,\n documentId: string,\n flag: PdfPermissionFlag,\n): boolean {\n const docState = state.documents[documentId];\n const docConfig = docState?.permissions;\n const globalConfig = state.globalPermissions;\n const pdfPermissions = docState?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n // 1. Per-document override wins (supports both numeric and string keys)\n const docOverride = getPermissionOverride(docConfig?.overrides, flag);\n if (docOverride !== undefined) {\n return docOverride;\n }\n\n // 2. Global override (supports both numeric and string keys)\n const globalOverride = getPermissionOverride(globalConfig?.overrides, flag);\n if (globalOverride !== undefined) {\n return globalOverride;\n }\n\n // 3. Check enforce setting (per-doc takes precedence over global)\n const enforce =\n docConfig?.enforceDocumentPermissions ?? globalConfig?.enforceDocumentPermissions ?? true;\n\n if (!enforce) return true; // Not enforcing = allow all\n\n // 4. Use PDF permission\n return (pdfPermissions & flag) !== 0;\n}\n\n/**\n * Get all effective permissions as a bitmask for a document.\n * Combines all individual permission checks into a single bitmask.\n *\n * @param state - The core state\n * @param documentId - The document ID to get permissions for\n * @returns A bitmask of all effective permissions\n */\nexport function getEffectivePermissions(state: CoreState, documentId: string): number {\n return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {\n return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;\n }, 0);\n}\n","import { useState, useEffect, useRef, useMemo, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry, CoreState, DocumentState, PluginRegistryConfig } from '@embedpdf/core';\nimport type { PluginBatchRegistrations } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\nimport { AutoMount } from './auto-mount';\n\nexport type { PluginBatchRegistrations };\n\ninterface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * Registry configuration including logger, permissions, and defaults.\n */\n config?: PluginRegistryConfig;\n /**\n * @deprecated Use config.logger instead. Will be removed in next major version.\n */\n logger?: Logger;\n /**\n * The callback to call when the PDF viewer is initialized.\n */\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n /**\n * The plugins to use for the PDF viewer.\n */\n plugins: PluginBatchRegistrations;\n /**\n * The children to render for the PDF viewer.\n */\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n}\n\nexport function EmbedPDF({\n engine,\n config,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n}: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n const [isInitializing, setIsInitializing] = useState<boolean>(true);\n const [pluginsReady, setPluginsReady] = useState<boolean>(false);\n const initRef = useRef<EmbedPDFProps['onInitialized']>(onInitialized);\n\n useEffect(() => {\n initRef.current = onInitialized;\n }, [onInitialized]);\n\n useEffect(() => {\n // Merge deprecated logger prop into config (config.logger takes precedence)\n const finalConfig: PluginRegistryConfig = {\n ...config,\n logger: config?.logger ?? logger,\n };\n const pdfViewer = new PluginRegistry(engine, finalConfig);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n const store = pdfViewer.getStore();\n setCoreState(store.getState().core);\n\n const unsubscribe = store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && newState.core !== oldState.core) {\n setCoreState(newState.core);\n }\n });\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n if (pdfViewer.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n pdfViewer.pluginsReady().then(() => {\n if (!pdfViewer.isDestroyed()) {\n setPluginsReady(true);\n }\n });\n\n // Provide the registry to children via context\n setRegistry(pdfViewer);\n setIsInitializing(false);\n\n // Return cleanup function\n return unsubscribe;\n };\n\n let cleanup: (() => void) | undefined;\n initialize()\n .then((unsub) => {\n cleanup = unsub;\n })\n .catch(console.error);\n\n return () => {\n cleanup?.();\n pdfViewer.destroy();\n setRegistry(null);\n setCoreState(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n // Compute convenience accessors\n const contextValue: PDFContextState = useMemo(() => {\n const activeDocumentId = coreState?.activeDocumentId ?? null;\n const documents = coreState?.documents ?? {};\n const documentOrder = coreState?.documentOrder ?? [];\n\n // Compute active document\n const activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n\n // Compute open documents in order\n const documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n\n return {\n registry,\n coreState,\n isInitializing,\n pluginsReady,\n // Convenience accessors (always safe to use)\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n };\n }, [registry, coreState, isInitializing, pluginsReady]);\n\n const content = typeof children === 'function' ? children(contextValue) : children;\n\n return (\n <PDFContext.Provider value={contextValue}>\n {pluginsReady && autoMountDomElements ? (\n <AutoMount plugins={plugins}>{content}</AutoMount>\n ) : (\n content\n )}\n </PDFContext.Provider>\n );\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin';\n\ntype CapabilityState<T extends BasePlugin> = {\n provides: ReturnType<NonNullable<T['provides']>> | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin's capability.\n * @param pluginId The ID of the plugin to access\n * @returns The capability provided by the plugin or null during initialization\n * @example\n * // Get zoom capability\n * const zoom = useCapability<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function useCapability<T extends BasePlugin>(pluginId: T['id']): CapabilityState<T> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n if (!plugin) {\n return {\n provides: null,\n isLoading,\n ready,\n };\n }\n\n if (!plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n return {\n provides: plugin.provides() as ReturnType<NonNullable<T['provides']>>,\n isLoading,\n ready,\n };\n}\n","import { useMemo } from '@framework';\nimport { PdfPermissionFlag } from '@embedpdf/models';\nimport { useCoreState } from './use-core-state';\nimport { getEffectivePermission, getEffectivePermissions } from '../../lib/store/selectors';\n\nexport interface DocumentPermissions {\n /** Effective permission flags after applying overrides */\n permissions: number;\n /** Raw PDF permission flags (before overrides) */\n pdfPermissions: number;\n /** Check if a specific permission flag is effectively allowed */\n hasPermission: (flag: PdfPermissionFlag) => boolean;\n /** Check if all specified flags are effectively allowed */\n hasAllPermissions: (...flags: PdfPermissionFlag[]) => boolean;\n\n // Shorthand booleans for all permission flags (using effective permissions):\n /** Can print (possibly degraded quality) */\n canPrint: boolean;\n /** Can modify document contents */\n canModifyContents: boolean;\n /** Can copy/extract text and graphics */\n canCopyContents: boolean;\n /** Can add/modify annotations and fill forms */\n canModifyAnnotations: boolean;\n /** Can fill in existing form fields */\n canFillForms: boolean;\n /** Can extract for accessibility */\n canExtractForAccessibility: boolean;\n /** Can assemble document (insert, rotate, delete pages) */\n canAssembleDocument: boolean;\n /** Can print high quality */\n canPrintHighQuality: boolean;\n}\n\n/**\n * Hook that provides reactive access to a document's effective permission flags.\n * Applies layered resolution: per-document override → global override → PDF permission.\n *\n * @param documentId The ID of the document to check permissions for.\n * @returns An object with effective permissions, raw PDF permissions, helper functions, and shorthand booleans.\n */\nexport function useDocumentPermissions(documentId: string): DocumentPermissions {\n const coreState = useCoreState();\n\n return useMemo(() => {\n if (!coreState) {\n return {\n permissions: PdfPermissionFlag.AllowAll,\n pdfPermissions: PdfPermissionFlag.AllowAll,\n hasPermission: () => true,\n hasAllPermissions: () => true,\n canPrint: true,\n canModifyContents: true,\n canCopyContents: true,\n canModifyAnnotations: true,\n canFillForms: true,\n canExtractForAccessibility: true,\n canAssembleDocument: true,\n canPrintHighQuality: true,\n };\n }\n\n const effectivePermissions = getEffectivePermissions(coreState, documentId);\n const pdfPermissions =\n coreState.documents[documentId]?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n const hasPermission = (flag: PdfPermissionFlag) =>\n getEffectivePermission(coreState, documentId, flag);\n const hasAllPermissions = (...flags: PdfPermissionFlag[]) =>\n flags.every((flag) => getEffectivePermission(coreState, documentId, flag));\n\n return {\n permissions: effectivePermissions,\n pdfPermissions,\n hasPermission,\n hasAllPermissions,\n // All permission flags as booleans (using effective permissions)\n canPrint: hasPermission(PdfPermissionFlag.Print),\n canModifyContents: hasPermission(PdfPermissionFlag.ModifyContents),\n canCopyContents: hasPermission(PdfPermissionFlag.CopyContents),\n canModifyAnnotations: hasPermission(PdfPermissionFlag.ModifyAnnotations),\n canFillForms: hasPermission(PdfPermissionFlag.FillForms),\n canExtractForAccessibility: hasPermission(PdfPermissionFlag.ExtractForAccessibility),\n canAssembleDocument: hasPermission(PdfPermissionFlag.AssembleDocument),\n canPrintHighQuality: hasPermission(PdfPermissionFlag.PrintHighQuality),\n };\n }, [coreState, documentId]);\n}\n","import { useMemo } from '@framework';\nimport { DocumentState } from '@embedpdf/core';\nimport { useCoreState } from './use-core-state';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param documentId The ID of the document to retrieve.\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: string | null): DocumentState | null {\n const coreState = useCoreState();\n\n const documentState = useMemo(() => {\n if (!coreState || !documentId) return null;\n return coreState.documents[documentId] ?? null;\n }, [coreState, documentId]);\n\n return documentState;\n}\n","import { useState, useEffect } from '@framework';\nimport { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Hook that provides access to the current global store state\n * and re-renders the component when the state changes\n */\nexport function useStoreState<T = CoreState>(): StoreState<T> | null {\n const { registry } = useRegistry();\n const [state, setState] = useState<StoreState<T> | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n // Get initial state\n setState(registry.getStore().getState() as StoreState<T>);\n\n // Subscribe to store changes\n const unsubscribe = registry.getStore().subscribe((_action, newState) => {\n setState(newState as StoreState<T>);\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return state;\n}\n"],"names":["PDFContext","createContext","registry","coreState","isInitializing","pluginsReady","activeDocumentId","activeDocument","documents","documentStates","AutoMount","plugins","children","utilities","wrappers","useMemo","reg","pkg","package","hasAutoMountElements","elements","autoMountElements","element","type","push","component","wrappedContent","reduce","content","Wrapper","jsx","Fragment","map","Utility","i","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","useCoreState","PdfPermissionFlag","Print","ModifyContents","CopyContents","ModifyAnnotations","FillForms","ExtractForAccessibility","AssembleDocument","PrintHighQuality","ALL_PERMISSION_FLAGS","PERMISSION_FLAG_TO_NAME","getPermissionOverride","overrides","flag","name","getEffectivePermission","state","documentId","docState","docConfig","permissions","globalConfig","globalPermissions","pdfPermissions","_a","document","AllowAll","docOverride","globalOverride","enforceDocumentPermissions","engine","config","logger","onInitialized","autoMountDomElements","setRegistry","useState","setCoreState","setIsInitializing","setPluginsReady","initRef","useRef","useEffect","current","finalConfig","pdfViewer","PluginRegistry","registerPluginBatch","cleanup","async","initialize","isDestroyed","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","call","then","unsub","catch","console","error","destroy","documentOrder","docId","filter","doc","Provider","value","provides","hasPermission","hasAllPermissions","canPrint","canModifyContents","canCopyContents","canModifyAnnotations","canFillForms","canExtractForAccessibility","canAssembleDocument","canPrintHighQuality","effectivePermissions","acc","getEffectivePermissions","_b","flags","every","setState","_action"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/components/auto-mount.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/hooks/use-core-state.ts","../../src/lib/types/permissions.ts","../../src/lib/store/selectors.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-document-permissions.ts","../../src/shared/hooks/use-document-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { CoreState, DocumentState, PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n coreState: CoreState | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: string | null;\n activeDocument: DocumentState | null;\n documents: Record<string, DocumentState>;\n documentStates: DocumentState[];\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n coreState: null,\n isInitializing: true,\n pluginsReady: false,\n activeDocumentId: null,\n activeDocument: null,\n documents: {},\n documentStates: [],\n});\n","import { Fragment, useMemo, ComponentType, ReactNode } from '@framework';\nimport { hasAutoMountElements } from '@embedpdf/core';\nimport type { PluginBatchRegistration, IPlugin } from '@embedpdf/core';\n\ninterface AutoMountProps {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode;\n}\n\nexport function AutoMount({ plugins, children }: AutoMountProps) {\n const { utilities, wrappers } = useMemo(() => {\n // React-specific types for internal use\n const utilities: ComponentType[] = [];\n const wrappers: ComponentType<{ children: ReactNode }>[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements() || [];\n\n for (const element of elements) {\n if (element.type === 'utility') {\n utilities.push(element.component);\n } else if (element.type === 'wrapper') {\n // In React context, we know wrappers need children\n wrappers.push(element.component);\n }\n }\n }\n }\n return { utilities, wrappers };\n }, [plugins]);\n\n // Combine children and utilities as siblings inside the wrapper chain\n const contentWithUtilities = (\n <Fragment>\n {children}\n {utilities.map((Utility, i) => (\n <Utility key={`utility-${i}`} />\n ))}\n </Fragment>\n );\n\n // Wrap everything together - utilities now inside wrapper context\n const wrappedContent = wrappers.reduce(\n (content, Wrapper) => <Wrapper>{content}</Wrapper>,\n contentWithUtilities,\n );\n\n return <Fragment>{wrappedContent}</Fragment>;\n}\n","import { useContext } from '@framework';\nimport { PDFContext, PDFContextState } from '../context';\n\n/**\n * Hook to access the PDF registry.\n * @returns The PDF registry or null during initialization\n */\nexport function useRegistry(): PDFContextState {\n const contextValue = useContext(PDFContext);\n\n // Error if used outside of context\n if (contextValue === undefined) {\n throw new Error('useCapability must be used within a PDFContext.Provider');\n }\n\n const { registry, isInitializing } = contextValue;\n\n // During initialization, return null instead of throwing an error\n if (isInitializing) {\n return contextValue;\n }\n\n // At this point, initialization is complete but registry is still null, which is unexpected\n if (registry === null) {\n throw new Error('PDF registry failed to initialize properly');\n }\n\n return contextValue;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\ntype PluginState<T extends BasePlugin> = {\n plugin: T | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin.\n * @param pluginId The ID of the plugin to access\n * @returns The plugin or null during initialization\n * @example\n * // Get zoom plugin\n * const zoom = usePlugin<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n if (registry === null) {\n return {\n plugin: null,\n isLoading: true,\n ready: new Promise(() => {}),\n };\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n return {\n plugin,\n isLoading: false,\n ready: plugin.ready(),\n };\n}\n","import { useContext } from '@framework';\nimport { CoreState } from '@embedpdf/core';\nimport { PDFContext } from '../context';\n\n/**\n * Hook that provides access to the current core state.\n *\n * Note: This reads from the context which is already subscribed to core state changes\n * in the EmbedPDF component, so there's no additional subscription overhead.\n */\nexport function useCoreState(): CoreState | null {\n const { coreState } = useContext(PDFContext);\n return coreState;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\n\n/**\n * Human-readable permission names for use in configuration.\n */\nexport type PermissionName =\n | 'print'\n | 'modifyContents'\n | 'copyContents'\n | 'modifyAnnotations'\n | 'fillForms'\n | 'extractForAccessibility'\n | 'assembleDocument'\n | 'printHighQuality';\n\n/**\n * Map from human-readable names to PdfPermissionFlag values.\n */\nexport const PERMISSION_NAME_TO_FLAG: Record<PermissionName, PdfPermissionFlag> = {\n print: PdfPermissionFlag.Print,\n modifyContents: PdfPermissionFlag.ModifyContents,\n copyContents: PdfPermissionFlag.CopyContents,\n modifyAnnotations: PdfPermissionFlag.ModifyAnnotations,\n fillForms: PdfPermissionFlag.FillForms,\n extractForAccessibility: PdfPermissionFlag.ExtractForAccessibility,\n assembleDocument: PdfPermissionFlag.AssembleDocument,\n printHighQuality: PdfPermissionFlag.PrintHighQuality,\n};\n\n/**\n * Permission overrides can use either numeric flags or human-readable string names.\n */\nexport type PermissionOverrides = Partial<\n Record<PdfPermissionFlag, boolean> & Record<PermissionName, boolean>\n>;\n\n/**\n * Configuration for overriding document permissions.\n * Can be applied globally (at PluginRegistry level) or per-document (when opening).\n */\nexport interface PermissionConfig {\n /**\n * When true (default): use PDF's permissions as the base, then apply overrides.\n * When false: treat document as having all permissions allowed, then apply overrides.\n */\n enforceDocumentPermissions?: boolean;\n\n /**\n * Explicit per-flag overrides. Supports both numeric flags and string names.\n * - true = force allow (even if PDF denies)\n * - false = force deny (even if PDF allows)\n * - undefined = use base permissions\n *\n * @example\n * // Using string names (recommended)\n * overrides: { print: false, modifyAnnotations: true }\n *\n * @example\n * // Using numeric flags\n * overrides: { [PdfPermissionFlag.Print]: false }\n */\n overrides?: PermissionOverrides;\n}\n\n/**\n * All permission flags for iteration when computing effective permissions.\n */\nexport const ALL_PERMISSION_FLAGS: PdfPermissionFlag[] = [\n PdfPermissionFlag.Print,\n PdfPermissionFlag.ModifyContents,\n PdfPermissionFlag.CopyContents,\n PdfPermissionFlag.ModifyAnnotations,\n PdfPermissionFlag.FillForms,\n PdfPermissionFlag.ExtractForAccessibility,\n PdfPermissionFlag.AssembleDocument,\n PdfPermissionFlag.PrintHighQuality,\n];\n\n/**\n * All permission names for iteration.\n */\nexport const ALL_PERMISSION_NAMES: PermissionName[] = [\n 'print',\n 'modifyContents',\n 'copyContents',\n 'modifyAnnotations',\n 'fillForms',\n 'extractForAccessibility',\n 'assembleDocument',\n 'printHighQuality',\n];\n\n/**\n * Map from PdfPermissionFlag to human-readable name.\n */\nexport const PERMISSION_FLAG_TO_NAME: Record<PdfPermissionFlag, PermissionName> = {\n [PdfPermissionFlag.Print]: 'print',\n [PdfPermissionFlag.ModifyContents]: 'modifyContents',\n [PdfPermissionFlag.CopyContents]: 'copyContents',\n [PdfPermissionFlag.ModifyAnnotations]: 'modifyAnnotations',\n [PdfPermissionFlag.FillForms]: 'fillForms',\n [PdfPermissionFlag.ExtractForAccessibility]: 'extractForAccessibility',\n [PdfPermissionFlag.AssembleDocument]: 'assembleDocument',\n [PdfPermissionFlag.PrintHighQuality]: 'printHighQuality',\n};\n\n/**\n * Helper to get the override value for a permission flag, checking both numeric and string keys.\n */\nexport function getPermissionOverride(\n overrides: PermissionOverrides | undefined,\n flag: PdfPermissionFlag,\n): boolean | undefined {\n if (!overrides) return undefined;\n\n // Check numeric key first\n if (flag in overrides) {\n return (overrides as Record<PdfPermissionFlag, boolean>)[flag];\n }\n\n // Check string key\n const name = PERMISSION_FLAG_TO_NAME[flag];\n if (name && name in overrides) {\n return (overrides as Record<PermissionName, boolean>)[name];\n }\n\n return undefined;\n}\n","import { PdfPermissionFlag } from '@embedpdf/models';\nimport { CoreState, DocumentState } from './initial-state';\nimport { ALL_PERMISSION_FLAGS, getPermissionOverride } from '../types/permissions';\n\n/**\n * Get the active document state\n */\nexport const getActiveDocumentState = (state: CoreState): DocumentState | null => {\n if (!state.activeDocumentId) return null;\n return state.documents[state.activeDocumentId] ?? null;\n};\n\n/**\n * Get document state by ID\n */\nexport const getDocumentState = (state: CoreState, documentId: string): DocumentState | null => {\n return state.documents[documentId] ?? null;\n};\n\n/**\n * Get all document IDs\n */\nexport const getDocumentIds = (state: CoreState): string[] => {\n return Object.keys(state.documents);\n};\n\n/**\n * Check if a document is loaded\n */\nexport const isDocumentLoaded = (state: CoreState, documentId: string): boolean => {\n return !!state.documents[documentId];\n};\n\n/**\n * Get the number of open documents\n */\nexport const getDocumentCount = (state: CoreState): number => {\n return Object.keys(state.documents).length;\n};\n\n// ─────────────────────────────────────────────────────────\n// Permission Selectors\n// ─────────────────────────────────────────────────────────\n\n/**\n * Check if a specific permission flag is effectively allowed for a document.\n * Applies layered resolution: per-document override → global override → enforceDocumentPermissions → PDF permission.\n *\n * @param state - The core state\n * @param documentId - The document ID to check permissions for\n * @param flag - The permission flag to check\n * @returns true if the permission is allowed, false otherwise\n */\nexport function getEffectivePermission(\n state: CoreState,\n documentId: string,\n flag: PdfPermissionFlag,\n): boolean {\n const docState = state.documents[documentId];\n const docConfig = docState?.permissions;\n const globalConfig = state.globalPermissions;\n const pdfPermissions = docState?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n // 1. Per-document override wins (supports both numeric and string keys)\n const docOverride = getPermissionOverride(docConfig?.overrides, flag);\n if (docOverride !== undefined) {\n return docOverride;\n }\n\n // 2. Global override (supports both numeric and string keys)\n const globalOverride = getPermissionOverride(globalConfig?.overrides, flag);\n if (globalOverride !== undefined) {\n return globalOverride;\n }\n\n // 3. Check enforce setting (per-doc takes precedence over global)\n const enforce =\n docConfig?.enforceDocumentPermissions ?? globalConfig?.enforceDocumentPermissions ?? true;\n\n if (!enforce) return true; // Not enforcing = allow all\n\n // 4. Use PDF permission\n return (pdfPermissions & flag) !== 0;\n}\n\n/**\n * Get all effective permissions as a bitmask for a document.\n * Combines all individual permission checks into a single bitmask.\n *\n * @param state - The core state\n * @param documentId - The document ID to get permissions for\n * @returns A bitmask of all effective permissions\n */\nexport function getEffectivePermissions(state: CoreState, documentId: string): number {\n return ALL_PERMISSION_FLAGS.reduce((acc, flag) => {\n return getEffectivePermission(state, documentId, flag) ? acc | flag : acc;\n }, 0);\n}\n","import { useState, useEffect, useRef, useMemo, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry, CoreState, DocumentState, PluginRegistryConfig } from '@embedpdf/core';\nimport type { PluginBatchRegistrations } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\nimport { AutoMount } from './auto-mount';\n\nexport type { PluginBatchRegistrations };\n\ninterface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * Registry configuration including logger, permissions, and defaults.\n */\n config?: PluginRegistryConfig;\n /**\n * @deprecated Use config.logger instead. Will be removed in next major version.\n */\n logger?: Logger;\n /**\n * The callback to call when the PDF viewer is initialized.\n */\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n /**\n * The plugins to use for the PDF viewer.\n */\n plugins: PluginBatchRegistrations;\n /**\n * The children to render for the PDF viewer.\n */\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n}\n\nexport function EmbedPDF({\n engine,\n config,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n}: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | null>(null);\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n const [isInitializing, setIsInitializing] = useState<boolean>(true);\n const [pluginsReady, setPluginsReady] = useState<boolean>(false);\n const initRef = useRef<EmbedPDFProps['onInitialized']>(onInitialized);\n\n useEffect(() => {\n initRef.current = onInitialized;\n }, [onInitialized]);\n\n useEffect(() => {\n // Merge deprecated logger prop into config (config.logger takes precedence)\n const finalConfig: PluginRegistryConfig = {\n ...config,\n logger: config?.logger ?? logger,\n };\n const pdfViewer = new PluginRegistry(engine, finalConfig);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n const store = pdfViewer.getStore();\n setCoreState(store.getState().core);\n\n const unsubscribe = store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && newState.core !== oldState.core) {\n setCoreState(newState.core);\n }\n });\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n if (pdfViewer.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n pdfViewer.pluginsReady().then(() => {\n if (!pdfViewer.isDestroyed()) {\n setPluginsReady(true);\n }\n });\n\n // Provide the registry to children via context\n setRegistry(pdfViewer);\n setIsInitializing(false);\n\n // Return cleanup function\n return unsubscribe;\n };\n\n let cleanup: (() => void) | undefined;\n initialize()\n .then((unsub) => {\n cleanup = unsub;\n })\n .catch(console.error);\n\n return () => {\n cleanup?.();\n pdfViewer.destroy();\n setRegistry(null);\n setCoreState(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n // Compute convenience accessors\n const contextValue: PDFContextState = useMemo(() => {\n const activeDocumentId = coreState?.activeDocumentId ?? null;\n const documents = coreState?.documents ?? {};\n const documentOrder = coreState?.documentOrder ?? [];\n\n // Compute active document\n const activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n\n // Compute open documents in order\n const documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n\n return {\n registry,\n coreState,\n isInitializing,\n pluginsReady,\n // Convenience accessors (always safe to use)\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n };\n }, [registry, coreState, isInitializing, pluginsReady]);\n\n const content = typeof children === 'function' ? children(contextValue) : children;\n\n return (\n <PDFContext.Provider value={contextValue}>\n {pluginsReady && autoMountDomElements ? (\n <AutoMount plugins={plugins}>{content}</AutoMount>\n ) : (\n content\n )}\n </PDFContext.Provider>\n );\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin';\n\ntype CapabilityState<T extends BasePlugin> = {\n provides: ReturnType<NonNullable<T['provides']>> | null;\n isLoading: boolean;\n ready: Promise<void>;\n};\n\n/**\n * Hook to access a plugin's capability.\n * @param pluginId The ID of the plugin to access\n * @returns The capability provided by the plugin or null during initialization\n * @example\n * // Get zoom capability\n * const zoom = useCapability<ZoomPlugin>(ZoomPlugin.id);\n */\nexport function useCapability<T extends BasePlugin>(pluginId: T['id']): CapabilityState<T> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n if (!plugin) {\n return {\n provides: null,\n isLoading,\n ready,\n };\n }\n\n if (!plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n return {\n provides: plugin.provides() as ReturnType<NonNullable<T['provides']>>,\n isLoading,\n ready,\n };\n}\n","import { useMemo } from '@framework';\nimport { PdfPermissionFlag } from '@embedpdf/models';\nimport { useCoreState } from './use-core-state';\nimport { getEffectivePermission, getEffectivePermissions } from '../../lib/store/selectors';\n\nexport interface DocumentPermissions {\n /** Effective permission flags after applying overrides */\n permissions: number;\n /** Raw PDF permission flags (before overrides) */\n pdfPermissions: number;\n /** Check if a specific permission flag is effectively allowed */\n hasPermission: (flag: PdfPermissionFlag) => boolean;\n /** Check if all specified flags are effectively allowed */\n hasAllPermissions: (...flags: PdfPermissionFlag[]) => boolean;\n\n // Shorthand booleans for all permission flags (using effective permissions):\n /** Can print (possibly degraded quality) */\n canPrint: boolean;\n /** Can modify document contents */\n canModifyContents: boolean;\n /** Can copy/extract text and graphics */\n canCopyContents: boolean;\n /** Can add/modify annotations and fill forms */\n canModifyAnnotations: boolean;\n /** Can fill in existing form fields */\n canFillForms: boolean;\n /** Can extract for accessibility */\n canExtractForAccessibility: boolean;\n /** Can assemble document (insert, rotate, delete pages) */\n canAssembleDocument: boolean;\n /** Can print high quality */\n canPrintHighQuality: boolean;\n}\n\n/**\n * Hook that provides reactive access to a document's effective permission flags.\n * Applies layered resolution: per-document override → global override → PDF permission.\n *\n * @param documentId The ID of the document to check permissions for.\n * @returns An object with effective permissions, raw PDF permissions, helper functions, and shorthand booleans.\n */\nexport function useDocumentPermissions(documentId: string): DocumentPermissions {\n const coreState = useCoreState();\n\n return useMemo(() => {\n if (!coreState) {\n return {\n permissions: PdfPermissionFlag.AllowAll,\n pdfPermissions: PdfPermissionFlag.AllowAll,\n hasPermission: () => true,\n hasAllPermissions: () => true,\n canPrint: true,\n canModifyContents: true,\n canCopyContents: true,\n canModifyAnnotations: true,\n canFillForms: true,\n canExtractForAccessibility: true,\n canAssembleDocument: true,\n canPrintHighQuality: true,\n };\n }\n\n const effectivePermissions = getEffectivePermissions(coreState, documentId);\n const pdfPermissions =\n coreState.documents[documentId]?.document?.permissions ?? PdfPermissionFlag.AllowAll;\n\n const hasPermission = (flag: PdfPermissionFlag) =>\n getEffectivePermission(coreState, documentId, flag);\n const hasAllPermissions = (...flags: PdfPermissionFlag[]) =>\n flags.every((flag) => getEffectivePermission(coreState, documentId, flag));\n\n return {\n permissions: effectivePermissions,\n pdfPermissions,\n hasPermission,\n hasAllPermissions,\n // All permission flags as booleans (using effective permissions)\n canPrint: hasPermission(PdfPermissionFlag.Print),\n canModifyContents: hasPermission(PdfPermissionFlag.ModifyContents),\n canCopyContents: hasPermission(PdfPermissionFlag.CopyContents),\n canModifyAnnotations: hasPermission(PdfPermissionFlag.ModifyAnnotations),\n canFillForms: hasPermission(PdfPermissionFlag.FillForms),\n canExtractForAccessibility: hasPermission(PdfPermissionFlag.ExtractForAccessibility),\n canAssembleDocument: hasPermission(PdfPermissionFlag.AssembleDocument),\n canPrintHighQuality: hasPermission(PdfPermissionFlag.PrintHighQuality),\n };\n }, [coreState, documentId]);\n}\n","import { useMemo } from '@framework';\nimport { DocumentState } from '@embedpdf/core';\nimport { useCoreState } from './use-core-state';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param documentId The ID of the document to retrieve.\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: string | null): DocumentState | null {\n const coreState = useCoreState();\n\n const documentState = useMemo(() => {\n if (!coreState || !documentId) return null;\n return coreState.documents[documentId] ?? null;\n }, [coreState, documentId]);\n\n return documentState;\n}\n","import { useState, useEffect } from '@framework';\nimport { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Hook that provides access to the current global store state\n * and re-renders the component when the state changes\n */\nexport function useStoreState<T = CoreState>(): StoreState<T> | null {\n const { registry } = useRegistry();\n const [state, setState] = useState<StoreState<T> | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n // Get initial state\n setState(registry.getStore().getState() as StoreState<T>);\n\n // Subscribe to store changes\n const unsubscribe = registry.getStore().subscribe((_action, newState) => {\n setState(newState as StoreState<T>);\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return state;\n}\n"],"names":["PDFContext","createContext","registry","coreState","isInitializing","pluginsReady","activeDocumentId","activeDocument","documents","documentStates","AutoMount","plugins","children","utilities","wrappers","useMemo","reg","pkg","package","hasAutoMountElements","elements","autoMountElements","element","type","push","component","contentWithUtilities","Fragment","map","Utility","i","wrappedContent","reduce","content","Wrapper","jsx","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","useCoreState","PdfPermissionFlag","Print","ModifyContents","CopyContents","ModifyAnnotations","FillForms","ExtractForAccessibility","AssembleDocument","PrintHighQuality","ALL_PERMISSION_FLAGS","PERMISSION_FLAG_TO_NAME","getPermissionOverride","overrides","flag","name","getEffectivePermission","state","documentId","docState","docConfig","permissions","globalConfig","globalPermissions","pdfPermissions","_a","document","AllowAll","docOverride","globalOverride","enforceDocumentPermissions","engine","config","logger","onInitialized","autoMountDomElements","setRegistry","useState","setCoreState","setIsInitializing","setPluginsReady","initRef","useRef","useEffect","current","finalConfig","pdfViewer","PluginRegistry","registerPluginBatch","cleanup","async","initialize","isDestroyed","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","call","then","unsub","catch","console","error","destroy","documentOrder","docId","filter","doc","Provider","value","provides","hasPermission","hasAllPermissions","canPrint","canModifyContents","canCopyContents","canModifyAnnotations","canFillForms","canExtractForAccessibility","canAssembleDocument","canPrintHighQuality","effectivePermissions","acc","getEffectivePermissions","_b","flags","every","setState","_action"],"mappings":"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"}