@embedpdf/core 1.5.0 → 2.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +680 -113
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/base/base-plugin.d.ts +52 -0
  6. package/dist/lib/index.d.ts +1 -0
  7. package/dist/lib/registry/plugin-registry.d.ts +6 -2
  8. package/dist/lib/store/actions.d.ts +122 -31
  9. package/dist/lib/store/initial-state.d.ts +22 -6
  10. package/dist/lib/store/reducer-helpers.d.ts +11 -0
  11. package/dist/lib/store/selectors.d.ts +21 -3
  12. package/dist/lib/types/plugin.d.ts +2 -2
  13. package/dist/lib/utils/event-control.d.ts +37 -2
  14. package/dist/lib/utils/eventing.d.ts +1 -1
  15. package/dist/lib/utils/scoped-eventing.d.ts +71 -0
  16. package/dist/preact/index.cjs +1 -1
  17. package/dist/preact/index.cjs.map +1 -1
  18. package/dist/preact/index.js +53 -18
  19. package/dist/preact/index.js.map +1 -1
  20. package/dist/react/index.cjs +1 -1
  21. package/dist/react/index.cjs.map +1 -1
  22. package/dist/react/index.js +53 -18
  23. package/dist/react/index.js.map +1 -1
  24. package/dist/shared/context.d.ts +6 -1
  25. package/dist/shared/hooks/index.d.ts +1 -0
  26. package/dist/shared/hooks/use-core-state.d.ts +4 -2
  27. package/dist/shared/hooks/use-document-state.d.ts +8 -0
  28. package/dist/shared-preact/context.d.ts +6 -1
  29. package/dist/shared-preact/hooks/index.d.ts +1 -0
  30. package/dist/shared-preact/hooks/use-core-state.d.ts +4 -2
  31. package/dist/shared-preact/hooks/use-document-state.d.ts +8 -0
  32. package/dist/shared-react/context.d.ts +6 -1
  33. package/dist/shared-react/hooks/index.d.ts +1 -0
  34. package/dist/shared-react/hooks/use-core-state.d.ts +4 -2
  35. package/dist/shared-react/hooks/use-document-state.d.ts +8 -0
  36. package/dist/svelte/hooks/index.d.ts +1 -0
  37. package/dist/svelte/hooks/use-core-state.svelte.d.ts +5 -4
  38. package/dist/svelte/hooks/use-document-state.svelte.d.ts +9 -0
  39. package/dist/svelte/hooks/use-registry.svelte.d.ts +6 -1
  40. package/dist/svelte/index.cjs +1 -1
  41. package/dist/svelte/index.cjs.map +1 -1
  42. package/dist/svelte/index.js +55 -17
  43. package/dist/svelte/index.js.map +1 -1
  44. package/dist/vue/components/auto-mount.vue.d.ts +3 -2
  45. package/dist/vue/components/embed-pdf.vue.d.ts +13 -2
  46. package/dist/vue/components/nested-wrapper.vue.d.ts +3 -2
  47. package/dist/vue/composables/index.d.ts +1 -0
  48. package/dist/vue/composables/use-core-state.d.ts +8 -1
  49. package/dist/vue/composables/use-document-state.d.ts +8 -0
  50. package/dist/vue/context.d.ts +6 -1
  51. package/dist/vue/index.cjs +1 -1
  52. package/dist/vue/index.cjs.map +1 -1
  53. package/dist/vue/index.js +88 -27
  54. package/dist/vue/index.js.map +1 -1
  55. package/package.json +3 -3
@@ -1,6 +1,8 @@
1
1
  import { CoreState } from '../../lib/index.ts';
2
2
  /**
3
- * Hook that provides access to the current core state
4
- * and re-renders the component only when the core state changes
3
+ * Hook that provides access to the current core state.
4
+ *
5
+ * Note: This reads from the context which is already subscribed to core state changes
6
+ * in the EmbedPDF component, so there's no additional subscription overhead.
5
7
  */
6
8
  export declare function useCoreState(): CoreState | null;
@@ -0,0 +1,8 @@
1
+ import { DocumentState } from '../../lib/index.ts';
2
+ /**
3
+ * Hook that provides reactive access to a specific document's state from the core store.
4
+ *
5
+ * @param documentId The ID of the document to retrieve.
6
+ * @returns The reactive DocumentState object or null if not found.
7
+ */
8
+ export declare function useDocumentState(documentId: string | null): DocumentState | null;
@@ -1,4 +1,5 @@
1
1
  export * from './use-capability.svelte';
2
2
  export * from './use-core-state.svelte';
3
+ export * from './use-document-state.svelte';
3
4
  export * from './use-plugin.svelte';
4
5
  export * from './use-registry.svelte';
@@ -1,8 +1,9 @@
1
- import { CoreState } from '../../lib/index.ts';
2
1
  /**
3
- * Hook that provides access to the current core state
4
- * and re-renders the component only when the core state changes
2
+ * Hook that provides access to the current core state.
3
+ *
4
+ * Note: This reads from the context which is already subscribed to core state changes
5
+ * in the EmbedPDF component, so there's no additional subscription overhead.
5
6
  */
6
7
  export declare function useCoreState(): {
7
- coreState: CoreState | null;
8
+ readonly current: import('../../lib/index.ts').CoreState | null;
8
9
  };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Hook that provides reactive access to a specific document's state from the core store.
3
+ *
4
+ * @param getDocumentId Function that returns the document ID
5
+ * @returns The reactive DocumentState object or null if not found.
6
+ */
7
+ export declare function useDocumentState(getDocumentId: () => string | null): {
8
+ readonly current: import('../../lib/index.ts').DocumentState | null;
9
+ };
@@ -1,8 +1,13 @@
1
- import { PluginRegistry } from '../../lib/index.ts';
1
+ import { PluginRegistry, CoreState, DocumentState } from '../../lib/index.ts';
2
2
  export interface PDFContextState {
3
3
  registry: PluginRegistry | null;
4
+ coreState: CoreState | null;
4
5
  isInitializing: boolean;
5
6
  pluginsReady: boolean;
7
+ activeDocumentId: string | null;
8
+ activeDocument: DocumentState | null;
9
+ documents: Record<string, DocumentState>;
10
+ documentStates: DocumentState[];
6
11
  }
7
12
  export declare const pdfContext: PDFContextState;
8
13
  /**
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal/client"),t=require("@embedpdf/core");function n(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}require("svelte/internal/disclose-version");const r=n(e),i=r.proxy({registry:null,isInitializing:!0,pluginsReady:!1}),o=()=>i;function s(e){const{registry:t}=i,n=r.proxy({plugin:null,isLoading:!0,ready:new Promise((()=>{}))});if(null===t)return n;const o=t.getPlugin(e);if(!o)throw new Error(`Plugin ${e} not found`);return n.plugin=o,n.isLoading=!1,n.ready=o.ready(),n}function l(e,t){r.push(t,!0);var n=r.comment(),i=r.first_child(n),o=e=>{const n=r.derived((()=>t.wrappers[0]));var i=r.comment(),o=r.first_child(i);r.component(o,(()=>r.get(n)),((e,n)=>{n(e,{children:(e,n)=>{{let n=r.derived((()=>t.wrappers.slice(1)));l(e,{get wrappers(){return r.get(n)},children:(e,n)=>{var i=r.comment(),o=r.first_child(i);r.snippet(o,(()=>t.children??r.noop)),r.append(e,i)},$$slots:{default:!0}})}},$$slots:{default:!0}})})),r.append(e,i)},s=e=>{const n=r.derived((()=>t.wrappers[0]));var i=r.comment(),o=r.first_child(i);r.component(o,(()=>r.get(n)),((e,n)=>{n(e,{children:(e,n)=>{var i=r.comment(),o=r.first_child(i);r.snippet(o,(()=>t.children??r.noop)),r.append(e,i)},$$slots:{default:!0}})})),r.append(e,i)};r.if(i,(e=>{t.wrappers.length>1?e(o):e(s,!1)})),r.append(e,n),r.pop()}var p=r.from_html("<!> <!>",1);function a(e,n){r.push(n,!0);let i=r.state(r.proxy([])),o=r.state(r.proxy([]));r.user_effect((()=>{var e;const s=[],l=[];for(const r of n.plugins){const n=r.package;if(t.hasAutoMountElements(n)){const t=(null==(e=n.autoMountElements)?void 0:e.call(n))??[];for(const e of t)"utility"===e.type?s.push(e.component):"wrapper"===e.type&&l.push(e.component)}}r.set(i,s,!0),r.set(o,l,!0)}));var s=p(),a=r.first_child(s),c=e=>{l(e,{get wrappers(){return r.get(o)},get children(){return n.children}})},d=e=>{var t=r.comment(),i=r.first_child(t);r.snippet(i,(()=>n.children??r.noop)),r.append(e,t)};r.if(a,(e=>{r.get(o).length>0?e(c):e(d,!1)}));var u=r.sibling(a,2);r.each(u,19,(()=>r.get(i)),((e,t)=>`utility-${t}`),((e,t)=>{var n=r.comment(),i=r.first_child(n);r.component(i,(()=>r.get(t)),((e,t)=>{t(e,{})})),r.append(e,n)})),r.append(e,s),r.pop()}exports.EmbedPDF=function(e,n){r.push(n,!0);let o=r.prop(n,"autoMountDomElements",3,!0),s=n.onInitialized;r.user_effect((()=>{n.onInitialized&&(s=n.onInitialized)})),r.user_effect((()=>{if(n.engine||n.engine&&n.plugins){const e=new t.PluginRegistry(n.engine,{logger:n.logger});e.registerPluginBatch(n.plugins);return(async()=>{await e.initialize(),e.isDestroyed()||(await(null==s?void 0:s(e)),e.isDestroyed()||(e.pluginsReady().then((()=>{e.isDestroyed()||(i.pluginsReady=!0)})),i.registry=e,i.isInitializing=!1))})().catch(console.error),()=>{e.destroy(),i.registry=null,i.isInitializing=!1,i.pluginsReady=!1}}}));var l=r.comment(),p=r.first_child(l),c=e=>{a(e,{get plugins(){return n.plugins},children:(e,t)=>{var o=r.comment(),s=r.first_child(o);r.snippet(s,(()=>n.children),(()=>i)),r.append(e,o)},$$slots:{default:!0}})},d=e=>{var t=r.comment(),o=r.first_child(t);r.snippet(o,(()=>n.children),(()=>i)),r.append(e,t)};r.if(p,(e=>{i.pluginsReady&&o()?e(c):e(d,!1)})),r.append(e,l),r.pop()},exports.pdfContext=i,exports.useCapability=function(e){const t=s(e),n=r.proxy({provides:null,isLoading:!0,ready:new Promise((()=>{}))});return r.user_effect((()=>{if(!t.plugin)return n.provides=null,n.isLoading=t.isLoading,void(n.ready=t.ready);if(!t.plugin.provides)throw new Error(`Plugin ${e} does not provide a capability`);n.provides=t.plugin.provides(),n.isLoading=t.isLoading,n.ready=t.ready})),n},exports.useCoreState=function(){const{registry:e}=o(),n=r.proxy({coreState:null});return r.user_effect((()=>{if(!e)return;const r=e.getStore();return n.coreState=r.getState().core,r.subscribe(((e,i,o)=>{r.isCoreAction(e)&&!t.arePropsEqual(i.core,o.core)&&(n.coreState=i.core)}))})),n},exports.usePlugin=s,exports.useRegistry=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("svelte/internal/client");require("svelte/internal/disclose-version");const t=require("@embedpdf/core");function n(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const r=n(e),i=r.proxy({registry:null,coreState:null,isInitializing:!0,pluginsReady:!1,activeDocumentId:null,activeDocument:null,documents:{},documentStates:[]}),o=()=>i;function s(e){const{registry:t}=i,n=r.proxy({plugin:null,isLoading:!0,ready:new Promise(()=>{})});if(null===t)return n;const o=t.getPlugin(e);if(!o)throw new Error(`Plugin ${e} not found`);return n.plugin=o,n.isLoading=!1,n.ready=o.ready(),n}function l(){const e=o();return{get current(){return e.coreState}}}function c(e,t){r.push(t,!0);var n=r.comment(),i=r.first_child(n),o=e=>{const n=r.derived(()=>t.wrappers[0]);var i=r.comment(),o=r.first_child(i);r.component(o,()=>r.get(n),(e,n)=>{n(e,{children:(e,n)=>{{let n=r.derived(()=>t.wrappers.slice(1));c(e,{get wrappers(){return r.get(n)},children:(e,n)=>{var i=r.comment(),o=r.first_child(i);r.snippet(o,()=>t.children??r.noop),r.append(e,i)},$$slots:{default:!0}})}},$$slots:{default:!0}})}),r.append(e,i)},s=e=>{const n=r.derived(()=>t.wrappers[0]);var i=r.comment(),o=r.first_child(i);r.component(o,()=>r.get(n),(e,n)=>{n(e,{children:(e,n)=>{var i=r.comment(),o=r.first_child(i);r.snippet(o,()=>t.children??r.noop),r.append(e,i)},$$slots:{default:!0}})}),r.append(e,i)};r.if(i,e=>{t.wrappers.length>1?e(o):e(s,!1)}),r.append(e,n),r.pop()}var u=r.from_html("<!> <!>",1);function a(e,n){r.push(n,!0);let i=r.state(r.proxy([])),o=r.state(r.proxy([]));r.user_effect(()=>{var e;const s=[],l=[];for(const r of n.plugins){const n=r.package;if(t.hasAutoMountElements(n)){const t=(null==(e=n.autoMountElements)?void 0:e.call(n))??[];for(const e of t)"utility"===e.type?s.push(e.component):"wrapper"===e.type&&l.push(e.component)}}r.set(i,s,!0),r.set(o,l,!0)});var s=u(),l=r.first_child(s),a=e=>{c(e,{get wrappers(){return r.get(o)},get children(){return n.children}})},p=e=>{var t=r.comment(),i=r.first_child(t);r.snippet(i,()=>n.children??r.noop),r.append(e,t)};r.if(l,e=>{r.get(o).length>0?e(a):e(p,!1)});var d=r.sibling(l,2);r.each(d,19,()=>r.get(i),(e,t)=>`utility-${t}`,(e,t)=>{var n=r.comment(),i=r.first_child(n);r.component(i,()=>r.get(t),(e,t)=>{t(e,{})}),r.append(e,n)}),r.append(e,s),r.pop()}exports.EmbedPDF=function(e,n){r.push(n,!0);let o=r.prop(n,"autoMountDomElements",3,!0),s=n.onInitialized;r.user_effect(()=>{n.onInitialized&&(s=n.onInitialized)}),r.user_effect(()=>{if(n.engine||n.engine&&n.plugins){const e=new t.PluginRegistry(n.engine,{logger:n.logger});e.registerPluginBatch(n.plugins);let r;return(async()=>{if(await e.initialize(),e.isDestroyed())return;const t=e.getStore();i.coreState=t.getState().core;const n=t.subscribe((e,n,r)=>{if(t.isCoreAction(e)&&n.core!==r.core){i.coreState=n.core;const e=n.core.activeDocumentId??null,t=n.core.documents??{},r=n.core.documentOrder??[];i.activeDocumentId=e,i.activeDocument=e&&t[e]?t[e]:null,i.documents=t,i.documentStates=r.map(e=>t[e]).filter(e=>null!=e)}});if(await(null==s?void 0:s(e)),!e.isDestroyed())return e.pluginsReady().then(()=>{e.isDestroyed()||(i.pluginsReady=!0)}),i.registry=e,i.isInitializing=!1,n;n()})().then(e=>{r=e}).catch(console.error),()=>{null==r||r(),e.destroy(),i.registry=null,i.coreState=null,i.isInitializing=!0,i.pluginsReady=!1,i.activeDocumentId=null,i.activeDocument=null,i.documents={},i.documentStates=[]}}});var l=r.comment(),c=r.first_child(l),u=e=>{a(e,{get plugins(){return n.plugins},children:(e,t)=>{var o=r.comment(),s=r.first_child(o);r.snippet(s,()=>n.children,()=>i),r.append(e,o)},$$slots:{default:!0}})},p=e=>{var t=r.comment(),o=r.first_child(t);r.snippet(o,()=>n.children,()=>i),r.append(e,t)};r.if(c,e=>{i.pluginsReady&&o()?e(u):e(p,!1)}),r.append(e,l),r.pop()},exports.pdfContext=i,exports.useCapability=function(e){const t=s(e),n=r.proxy({provides:null,isLoading:!0,ready:new Promise(()=>{})});return r.user_effect(()=>{if(!t.plugin)return n.provides=null,n.isLoading=t.isLoading,void(n.ready=t.ready);if(!t.plugin.provides)throw new Error(`Plugin ${e} does not provide a capability`);n.provides=t.plugin.provides(),n.isLoading=t.isLoading,n.ready=t.ready}),n},exports.useCoreState=l,exports.useDocumentState=function(e){const t=l(),n=r.derived(e),i=r.derived(()=>t.current&&r.get(n)?t.current.documents[r.get(n)]??null:null);return{get current(){return r.get(i)}}},exports.usePlugin=s,exports.useRegistry=o;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-registry.svelte.ts","../../src/svelte/hooks/use-plugin.svelte.ts","../../src/svelte/components/NestedWrapper.svelte","../../src/svelte/components/AutoMount.svelte","../../src/svelte/components/EmbedPDF.svelte","../../src/svelte/hooks/use-capability.svelte.ts","../../src/svelte/hooks/use-core-state.svelte.ts"],"sourcesContent":["import type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const pdfContext = $state<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n\n/**\n * Hook to access the PDF registry context.\n * @returns The PDF registry or null during initialization\n */\n\nexport const useRegistry = () => pdfContext;","import type { BasePlugin } from '@embedpdf/core';\nimport { pdfContext } from './use-registry.svelte.js';\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']) {\n const { registry } = pdfContext;\n\n const state = $state({\n plugin: null as T | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n if (registry === null) {\n return state;\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n state.plugin = plugin;\n state.isLoading = false;\n state.ready = plugin.ready();\n\n return state;\n}\n","<script lang=\"ts\">\n import { type Component, type Snippet } from 'svelte';\n import NestedWrapper from './NestedWrapper.svelte';\n\n interface Props {\n wrappers: Component[];\n children?: Snippet;\n }\n\n let { wrappers, children }: Props = $props();\n</script>\n\n{#if wrappers.length > 1}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n <NestedWrapper wrappers={wrappers.slice(1)}>\n {@render children?.()}\n </NestedWrapper>\n </Wrapper>\n{:else}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n {@render children?.()}\n </Wrapper>\n{/if}\n","<script lang=\"ts\">\n import { hasAutoMountElements, type PluginBatchRegistration, type IPlugin } from '@embedpdf/core';\n import NestedWrapper from './NestedWrapper.svelte';\n import type { Snippet } from 'svelte';\n\n type Props = {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: Snippet;\n };\n\n let { plugins, children }: Props = $props();\n let utilities: any[] = $state([]);\n let wrappers: any[] = $state([]);\n\n // recompute when plugins change\n $effect(() => {\n const nextUtilities: any[] = [];\n const nextWrappers: any[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements?.() ?? [];\n for (const element of elements) {\n if (element.type === 'utility') {\n nextUtilities.push(element.component);\n } else if (element.type === 'wrapper') {\n nextWrappers.push(element.component);\n }\n }\n }\n }\n\n utilities = nextUtilities;\n wrappers = nextWrappers;\n });\n</script>\n\n{#if wrappers.length > 0}\n <!-- wrap slot content inside all wrappers -->\n <NestedWrapper {wrappers} {children} />\n{:else}\n {@render children?.()}\n{/if}\n\n<!-- mount all utilities -->\n{#each utilities as Utility, i (`utility-${i}`)}\n <Utility />\n{/each}\n","<script lang=\"ts\">\n import type { Logger, PdfEngine } from '@embedpdf/models';\n import { type IPlugin, type PluginBatchRegistrations, PluginRegistry } from '@embedpdf/core';\n import { type Snippet } from 'svelte';\n import AutoMount from './AutoMount.svelte';\n import { pdfContext, type PDFContextState } from '../hooks';\n\n export type { PluginBatchRegistrations };\n\n interface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * The logger to use for the PDF viewer.\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: Snippet<[PDFContextState]>;\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n }\n\n let {\n engine,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n }: EmbedPDFProps = $props();\n\n let latestInit = onInitialized;\n\n $effect(() => {\n if (onInitialized) {\n latestInit = onInitialized;\n }\n });\n\n $effect(() => {\n if (engine || (engine && plugins)) {\n const reg = new PluginRegistry(engine, { logger });\n reg.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await reg.initialize();\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await latestInit?.(reg);\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n return;\n }\n\n reg.pluginsReady().then(() => {\n if (!reg.isDestroyed()) {\n pdfContext.pluginsReady = true;\n }\n });\n\n // Provide the registry to children via context\n pdfContext.registry = reg;\n pdfContext.isInitializing = false;\n };\n initialize().catch(console.error);\n\n return () => {\n reg.destroy();\n pdfContext.registry = null;\n pdfContext.isInitializing = false;\n pdfContext.pluginsReady = false;\n };\n }\n });\n</script>\n\n{#if pdfContext.pluginsReady && autoMountDomElements}\n <AutoMount {plugins}>{@render children(pdfContext)}</AutoMount>\n{:else}\n {@render children(pdfContext)}\n{/if}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin.svelte.js';\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']) {\n const p = usePlugin<T>(pluginId);\n\n const state = $state({\n provides: null as ReturnType<NonNullable<T['provides']>> | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n // Use $effect to reactively update when plugin loads\n $effect(() => {\n if (!p.plugin) {\n state.provides = null;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n return;\n }\n\n if (!p.plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n state.provides = p.plugin.provides() as ReturnType<NonNullable<T['provides']>>;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n });\n\n return state;\n}\n","import { type CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry.svelte';\n\n/**\n * Hook that provides access to the current core state\n * and re-renders the component only when the core state changes\n */\nexport function useCoreState() {\n const { registry } = useRegistry();\n\n const state = $state({\n coreState: null as CoreState | null,\n });\n\n $effect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n state.coreState = store.getState().core;\n\n // Create a single subscription that handles all core actions\n return store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && !arePropsEqual(newState.core, oldState.core)) {\n state.coreState = newState.core;\n }\n });\n });\n\n return state;\n}\n"],"names":["pdfContext","registry","isInitializing","pluginsReady","useRegistry","usePlugin","pluginId","state","$","proxy","plugin","isLoading","ready","Promise","getPlugin","Error","Wrapper","$0","derived","$$props","wrappers","slice","length","consequent","$$render","alternate","utilities","user_effect","nextUtilities","nextWrappers","reg","plugins","pkg","package","hasAutoMountElements","elements","_a","autoMountElements","call","element","type","push","component","$__namespace","set","each","node_2","get","Utility","i","autoMountDomElements","latestInit","onInitialized","engine","PluginRegistry","logger","registerPluginBatch","async","initialize","isDestroyed","then","catch","console","error","destroy","p","provides","coreState","store","getStore","getState","core","subscribe","action","newState","oldState","isCoreAction","arePropsEqual"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-registry.svelte.ts","../../src/svelte/hooks/use-plugin.svelte.ts","../../src/svelte/hooks/use-core-state.svelte.ts","../../src/svelte/components/NestedWrapper.svelte","../../src/svelte/components/AutoMount.svelte","../../src/svelte/components/EmbedPDF.svelte","../../src/svelte/hooks/use-capability.svelte.ts","../../src/svelte/hooks/use-document-state.svelte.ts"],"sourcesContent":["import type { PluginRegistry, CoreState, DocumentState } 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 = $state<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\n/**\n * Hook to access the PDF registry context.\n * @returns The PDF registry or null during initialization\n */\n\nexport const useRegistry = () => pdfContext;\n","import type { BasePlugin } from '@embedpdf/core';\nimport { pdfContext } from './use-registry.svelte.js';\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']) {\n const { registry } = pdfContext;\n\n const state = $state({\n plugin: null as T | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n if (registry === null) {\n return state;\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n state.plugin = plugin;\n state.isLoading = false;\n state.ready = plugin.ready();\n\n return state;\n}\n","import { useRegistry } from './use-registry.svelte';\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() {\n const context = useRegistry();\n\n return {\n get current() {\n return context.coreState;\n },\n };\n}\n","<script lang=\"ts\">\n import { type Component, type Snippet } from 'svelte';\n import NestedWrapper from './NestedWrapper.svelte';\n\n interface Props {\n wrappers: Component[];\n children?: Snippet;\n }\n\n let { wrappers, children }: Props = $props();\n</script>\n\n{#if wrappers.length > 1}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n <NestedWrapper wrappers={wrappers.slice(1)}>\n {@render children?.()}\n </NestedWrapper>\n </Wrapper>\n{:else}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n {@render children?.()}\n </Wrapper>\n{/if}\n","<script lang=\"ts\">\n import { hasAutoMountElements, type PluginBatchRegistration, type IPlugin } from '@embedpdf/core';\n import NestedWrapper from './NestedWrapper.svelte';\n import type { Snippet } from 'svelte';\n\n type Props = {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: Snippet;\n };\n\n let { plugins, children }: Props = $props();\n let utilities: any[] = $state([]);\n let wrappers: any[] = $state([]);\n\n // recompute when plugins change\n $effect(() => {\n const nextUtilities: any[] = [];\n const nextWrappers: any[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements?.() ?? [];\n for (const element of elements) {\n if (element.type === 'utility') {\n nextUtilities.push(element.component);\n } else if (element.type === 'wrapper') {\n nextWrappers.push(element.component);\n }\n }\n }\n }\n\n utilities = nextUtilities;\n wrappers = nextWrappers;\n });\n</script>\n\n{#if wrappers.length > 0}\n <!-- wrap slot content inside all wrappers -->\n <NestedWrapper {wrappers} {children} />\n{:else}\n {@render children?.()}\n{/if}\n\n<!-- mount all utilities -->\n{#each utilities as Utility, i (`utility-${i}`)}\n <Utility />\n{/each}\n","<script lang=\"ts\">\n import type { Logger, PdfEngine } from '@embedpdf/models';\n import { type IPlugin, type PluginBatchRegistrations, PluginRegistry } from '@embedpdf/core';\n import { type Snippet } from 'svelte';\n import AutoMount from './AutoMount.svelte';\n import { pdfContext, type PDFContextState } from '../hooks';\n\n export type { PluginBatchRegistrations };\n\n interface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * The logger to use for the PDF viewer.\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: Snippet<[PDFContextState]>;\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n }\n\n let {\n engine,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n }: EmbedPDFProps = $props();\n\n let latestInit = onInitialized;\n\n $effect(() => {\n if (onInitialized) {\n latestInit = onInitialized;\n }\n });\n\n $effect(() => {\n if (engine || (engine && plugins)) {\n const reg = new PluginRegistry(engine, { logger });\n reg.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await reg.initialize();\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n return;\n }\n\n const store = reg.getStore();\n pdfContext.coreState = 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 pdfContext.coreState = newState.core;\n\n // Update convenience accessors\n const activeDocumentId = newState.core.activeDocumentId ?? null;\n const documents = newState.core.documents ?? {};\n const documentOrder = newState.core.documentOrder ?? [];\n\n pdfContext.activeDocumentId = activeDocumentId;\n pdfContext.activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n pdfContext.documents = documents;\n pdfContext.documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter(\n (doc): doc is import('@embedpdf/core').DocumentState =>\n doc !== null && doc !== undefined,\n );\n }\n });\n\n /* always call the *latest* callback */\n await latestInit?.(reg);\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n reg.pluginsReady().then(() => {\n if (!reg.isDestroyed()) {\n pdfContext.pluginsReady = true;\n }\n });\n\n // Provide the registry to children via context\n pdfContext.registry = reg;\n pdfContext.isInitializing = false;\n\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 reg.destroy();\n pdfContext.registry = null;\n pdfContext.coreState = null;\n pdfContext.isInitializing = true;\n pdfContext.pluginsReady = false;\n pdfContext.activeDocumentId = null;\n pdfContext.activeDocument = null;\n pdfContext.documents = {};\n pdfContext.documentStates = [];\n };\n }\n });\n</script>\n\n{#if pdfContext.pluginsReady && autoMountDomElements}\n <AutoMount {plugins}>{@render children(pdfContext)}</AutoMount>\n{:else}\n {@render children(pdfContext)}\n{/if}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin.svelte.js';\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']) {\n const p = usePlugin<T>(pluginId);\n\n const state = $state({\n provides: null as ReturnType<NonNullable<T['provides']>> | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n // Use $effect to reactively update when plugin loads\n $effect(() => {\n if (!p.plugin) {\n state.provides = null;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n return;\n }\n\n if (!p.plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n state.provides = p.plugin.provides() as ReturnType<NonNullable<T['provides']>>;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n });\n\n return state;\n}\n","import { useCoreState } from './use-core-state.svelte';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param getDocumentId Function that returns the document ID\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(getDocumentId: () => string | null) {\n const coreStateRef = useCoreState();\n\n // Reactive documentId\n const documentId = $derived(getDocumentId());\n\n const documentState = $derived(\n coreStateRef.current && documentId\n ? (coreStateRef.current.documents[documentId] ?? null)\n : null,\n );\n\n return {\n get current() {\n return documentState;\n },\n };\n}\n"],"names":["pdfContext","registry","coreState","isInitializing","pluginsReady","activeDocumentId","activeDocument","documents","documentStates","useRegistry","usePlugin","pluginId","state","plugin","isLoading","ready","Promise","getPlugin","Error","useCoreState","context","current","Wrapper","$0","$","derived","$$props","wrappers","slice","length","consequent","$$render","alternate","utilities","proxy","user_effect","nextUtilities","nextWrappers","reg","plugins","pkg","package","hasAutoMountElements","elements","_a","autoMountElements","call","element","type","push","component","set","each","node_2","get","Utility","i","autoMountDomElements","latestInit","onInitialized","engine","PluginRegistry","logger","registerPluginBatch","cleanup","async","initialize","isDestroyed","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","documentOrder","map","docId","filter","doc","then","unsub","catch","console","error","destroy","p","provides","getDocumentId","coreStateRef","documentId","documentState"],"mappings":"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"}
@@ -1,7 +1,16 @@
1
1
  import * as $ from "svelte/internal/client";
2
- import { arePropsEqual, hasAutoMountElements, PluginRegistry } from "@embedpdf/core";
3
2
  import "svelte/internal/disclose-version";
4
- const pdfContext = $.proxy({ registry: null, isInitializing: true, pluginsReady: false });
3
+ import { hasAutoMountElements, PluginRegistry } from "@embedpdf/core";
4
+ const pdfContext = $.proxy({
5
+ registry: null,
6
+ coreState: null,
7
+ isInitializing: true,
8
+ pluginsReady: false,
9
+ activeDocumentId: null,
10
+ activeDocument: null,
11
+ documents: {},
12
+ documentStates: []
13
+ });
5
14
  const useRegistry = () => pdfContext;
6
15
  function usePlugin(pluginId) {
7
16
  const { registry } = pdfContext;
@@ -44,19 +53,22 @@ function useCapability(pluginId) {
44
53
  return state;
45
54
  }
46
55
  function useCoreState() {
47
- const { registry } = useRegistry();
48
- const state = $.proxy({ coreState: null });
49
- $.user_effect(() => {
50
- if (!registry) return;
51
- const store = registry.getStore();
52
- state.coreState = store.getState().core;
53
- return store.subscribe((action, newState, oldState) => {
54
- if (store.isCoreAction(action) && !arePropsEqual(newState.core, oldState.core)) {
55
- state.coreState = newState.core;
56
- }
57
- });
58
- });
59
- return state;
56
+ const context = useRegistry();
57
+ return {
58
+ get current() {
59
+ return context.coreState;
60
+ }
61
+ };
62
+ }
63
+ function useDocumentState(getDocumentId) {
64
+ const coreStateRef = useCoreState();
65
+ const documentId = $.derived(getDocumentId);
66
+ const documentState = $.derived(() => coreStateRef.current && $.get(documentId) ? coreStateRef.current.documents[$.get(documentId)] ?? null : null);
67
+ return {
68
+ get current() {
69
+ return $.get(documentState);
70
+ }
71
+ };
60
72
  }
61
73
  function NestedWrapper_1($$anchor, $$props) {
62
74
  $.push($$props, true);
@@ -195,8 +207,23 @@ function EmbedPDF($$anchor, $$props) {
195
207
  if (reg.isDestroyed()) {
196
208
  return;
197
209
  }
210
+ const store = reg.getStore();
211
+ pdfContext.coreState = store.getState().core;
212
+ const unsubscribe = store.subscribe((action, newState, oldState) => {
213
+ if (store.isCoreAction(action) && newState.core !== oldState.core) {
214
+ pdfContext.coreState = newState.core;
215
+ const activeDocumentId = newState.core.activeDocumentId ?? null;
216
+ const documents = newState.core.documents ?? {};
217
+ const documentOrder = newState.core.documentOrder ?? [];
218
+ pdfContext.activeDocumentId = activeDocumentId;
219
+ pdfContext.activeDocument = activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;
220
+ pdfContext.documents = documents;
221
+ pdfContext.documentStates = documentOrder.map((docId) => documents[docId]).filter((doc) => doc !== null && doc !== void 0);
222
+ }
223
+ });
198
224
  await (latestInit == null ? void 0 : latestInit(reg));
199
225
  if (reg.isDestroyed()) {
226
+ unsubscribe();
200
227
  return;
201
228
  }
202
229
  reg.pluginsReady().then(() => {
@@ -206,13 +233,23 @@ function EmbedPDF($$anchor, $$props) {
206
233
  });
207
234
  pdfContext.registry = reg;
208
235
  pdfContext.isInitializing = false;
236
+ return unsubscribe;
209
237
  };
210
- initialize().catch(console.error);
238
+ let cleanup;
239
+ initialize().then((unsub) => {
240
+ cleanup = unsub;
241
+ }).catch(console.error);
211
242
  return () => {
243
+ cleanup == null ? void 0 : cleanup();
212
244
  reg.destroy();
213
245
  pdfContext.registry = null;
214
- pdfContext.isInitializing = false;
246
+ pdfContext.coreState = null;
247
+ pdfContext.isInitializing = true;
215
248
  pdfContext.pluginsReady = false;
249
+ pdfContext.activeDocumentId = null;
250
+ pdfContext.activeDocument = null;
251
+ pdfContext.documents = {};
252
+ pdfContext.documentStates = [];
216
253
  };
217
254
  }
218
255
  });
@@ -252,6 +289,7 @@ export {
252
289
  pdfContext,
253
290
  useCapability,
254
291
  useCoreState,
292
+ useDocumentState,
255
293
  usePlugin,
256
294
  useRegistry
257
295
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/svelte/hooks/use-registry.svelte.ts","../../src/svelte/hooks/use-plugin.svelte.ts","../../src/svelte/hooks/use-capability.svelte.ts","../../src/svelte/hooks/use-core-state.svelte.ts","../../src/svelte/components/NestedWrapper.svelte","../../src/svelte/components/AutoMount.svelte","../../src/svelte/components/EmbedPDF.svelte"],"sourcesContent":["import type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const pdfContext = $state<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n\n/**\n * Hook to access the PDF registry context.\n * @returns The PDF registry or null during initialization\n */\n\nexport const useRegistry = () => pdfContext;","import type { BasePlugin } from '@embedpdf/core';\nimport { pdfContext } from './use-registry.svelte.js';\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']) {\n const { registry } = pdfContext;\n\n const state = $state({\n plugin: null as T | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n if (registry === null) {\n return state;\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n state.plugin = plugin;\n state.isLoading = false;\n state.ready = plugin.ready();\n\n return state;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin.svelte.js';\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']) {\n const p = usePlugin<T>(pluginId);\n\n const state = $state({\n provides: null as ReturnType<NonNullable<T['provides']>> | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n // Use $effect to reactively update when plugin loads\n $effect(() => {\n if (!p.plugin) {\n state.provides = null;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n return;\n }\n\n if (!p.plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n state.provides = p.plugin.provides() as ReturnType<NonNullable<T['provides']>>;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n });\n\n return state;\n}\n","import { type CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry.svelte';\n\n/**\n * Hook that provides access to the current core state\n * and re-renders the component only when the core state changes\n */\nexport function useCoreState() {\n const { registry } = useRegistry();\n\n const state = $state({\n coreState: null as CoreState | null,\n });\n\n $effect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n state.coreState = store.getState().core;\n\n // Create a single subscription that handles all core actions\n return store.subscribe((action, newState, oldState) => {\n // Only update if it's a core action and the core state changed\n if (store.isCoreAction(action) && !arePropsEqual(newState.core, oldState.core)) {\n state.coreState = newState.core;\n }\n });\n });\n\n return state;\n}\n","<script lang=\"ts\">\n import { type Component, type Snippet } from 'svelte';\n import NestedWrapper from './NestedWrapper.svelte';\n\n interface Props {\n wrappers: Component[];\n children?: Snippet;\n }\n\n let { wrappers, children }: Props = $props();\n</script>\n\n{#if wrappers.length > 1}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n <NestedWrapper wrappers={wrappers.slice(1)}>\n {@render children?.()}\n </NestedWrapper>\n </Wrapper>\n{:else}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n {@render children?.()}\n </Wrapper>\n{/if}\n","<script lang=\"ts\">\n import { hasAutoMountElements, type PluginBatchRegistration, type IPlugin } from '@embedpdf/core';\n import NestedWrapper from './NestedWrapper.svelte';\n import type { Snippet } from 'svelte';\n\n type Props = {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: Snippet;\n };\n\n let { plugins, children }: Props = $props();\n let utilities: any[] = $state([]);\n let wrappers: any[] = $state([]);\n\n // recompute when plugins change\n $effect(() => {\n const nextUtilities: any[] = [];\n const nextWrappers: any[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements?.() ?? [];\n for (const element of elements) {\n if (element.type === 'utility') {\n nextUtilities.push(element.component);\n } else if (element.type === 'wrapper') {\n nextWrappers.push(element.component);\n }\n }\n }\n }\n\n utilities = nextUtilities;\n wrappers = nextWrappers;\n });\n</script>\n\n{#if wrappers.length > 0}\n <!-- wrap slot content inside all wrappers -->\n <NestedWrapper {wrappers} {children} />\n{:else}\n {@render children?.()}\n{/if}\n\n<!-- mount all utilities -->\n{#each utilities as Utility, i (`utility-${i}`)}\n <Utility />\n{/each}\n","<script lang=\"ts\">\n import type { Logger, PdfEngine } from '@embedpdf/models';\n import { type IPlugin, type PluginBatchRegistrations, PluginRegistry } from '@embedpdf/core';\n import { type Snippet } from 'svelte';\n import AutoMount from './AutoMount.svelte';\n import { pdfContext, type PDFContextState } from '../hooks';\n\n export type { PluginBatchRegistrations };\n\n interface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * The logger to use for the PDF viewer.\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: Snippet<[PDFContextState]>;\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n }\n\n let {\n engine,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n }: EmbedPDFProps = $props();\n\n let latestInit = onInitialized;\n\n $effect(() => {\n if (onInitialized) {\n latestInit = onInitialized;\n }\n });\n\n $effect(() => {\n if (engine || (engine && plugins)) {\n const reg = new PluginRegistry(engine, { logger });\n reg.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await reg.initialize();\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await latestInit?.(reg);\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n return;\n }\n\n reg.pluginsReady().then(() => {\n if (!reg.isDestroyed()) {\n pdfContext.pluginsReady = true;\n }\n });\n\n // Provide the registry to children via context\n pdfContext.registry = reg;\n pdfContext.isInitializing = false;\n };\n initialize().catch(console.error);\n\n return () => {\n reg.destroy();\n pdfContext.registry = null;\n pdfContext.isInitializing = false;\n pdfContext.pluginsReady = false;\n };\n }\n });\n</script>\n\n{#if pdfContext.pluginsReady && autoMountDomElements}\n <AutoMount {plugins}>{@render children(pdfContext)}</AutoMount>\n{:else}\n {@render children(pdfContext)}\n{/if}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/svelte/hooks/use-registry.svelte.ts","../../src/svelte/hooks/use-plugin.svelte.ts","../../src/svelte/hooks/use-capability.svelte.ts","../../src/svelte/hooks/use-core-state.svelte.ts","../../src/svelte/hooks/use-document-state.svelte.ts","../../src/svelte/components/NestedWrapper.svelte","../../src/svelte/components/AutoMount.svelte","../../src/svelte/components/EmbedPDF.svelte"],"sourcesContent":["import type { PluginRegistry, CoreState, DocumentState } 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 = $state<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\n/**\n * Hook to access the PDF registry context.\n * @returns The PDF registry or null during initialization\n */\n\nexport const useRegistry = () => pdfContext;\n","import type { BasePlugin } from '@embedpdf/core';\nimport { pdfContext } from './use-registry.svelte.js';\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']) {\n const { registry } = pdfContext;\n\n const state = $state({\n plugin: null as T | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n if (registry === null) {\n return state;\n }\n\n const plugin = registry.getPlugin<T>(pluginId);\n\n if (!plugin) {\n throw new Error(`Plugin ${pluginId} not found`);\n }\n\n state.plugin = plugin;\n state.isLoading = false;\n state.ready = plugin.ready();\n\n return state;\n}\n","import type { BasePlugin } from '@embedpdf/core';\nimport { usePlugin } from './use-plugin.svelte.js';\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']) {\n const p = usePlugin<T>(pluginId);\n\n const state = $state({\n provides: null as ReturnType<NonNullable<T['provides']>> | null,\n isLoading: true,\n ready: new Promise<void>(() => {}),\n });\n\n // Use $effect to reactively update when plugin loads\n $effect(() => {\n if (!p.plugin) {\n state.provides = null;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n return;\n }\n\n if (!p.plugin.provides) {\n throw new Error(`Plugin ${pluginId} does not provide a capability`);\n }\n\n state.provides = p.plugin.provides() as ReturnType<NonNullable<T['provides']>>;\n state.isLoading = p.isLoading;\n state.ready = p.ready;\n });\n\n return state;\n}\n","import { useRegistry } from './use-registry.svelte';\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() {\n const context = useRegistry();\n\n return {\n get current() {\n return context.coreState;\n },\n };\n}\n","import { useCoreState } from './use-core-state.svelte';\n\n/**\n * Hook that provides reactive access to a specific document's state from the core store.\n *\n * @param getDocumentId Function that returns the document ID\n * @returns The reactive DocumentState object or null if not found.\n */\nexport function useDocumentState(getDocumentId: () => string | null) {\n const coreStateRef = useCoreState();\n\n // Reactive documentId\n const documentId = $derived(getDocumentId());\n\n const documentState = $derived(\n coreStateRef.current && documentId\n ? (coreStateRef.current.documents[documentId] ?? null)\n : null,\n );\n\n return {\n get current() {\n return documentState;\n },\n };\n}\n","<script lang=\"ts\">\n import { type Component, type Snippet } from 'svelte';\n import NestedWrapper from './NestedWrapper.svelte';\n\n interface Props {\n wrappers: Component[];\n children?: Snippet;\n }\n\n let { wrappers, children }: Props = $props();\n</script>\n\n{#if wrappers.length > 1}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n <NestedWrapper wrappers={wrappers.slice(1)}>\n {@render children?.()}\n </NestedWrapper>\n </Wrapper>\n{:else}\n {@const Wrapper = wrappers[0]}\n <Wrapper>\n {@render children?.()}\n </Wrapper>\n{/if}\n","<script lang=\"ts\">\n import { hasAutoMountElements, type PluginBatchRegistration, type IPlugin } from '@embedpdf/core';\n import NestedWrapper from './NestedWrapper.svelte';\n import type { Snippet } from 'svelte';\n\n type Props = {\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: Snippet;\n };\n\n let { plugins, children }: Props = $props();\n let utilities: any[] = $state([]);\n let wrappers: any[] = $state([]);\n\n // recompute when plugins change\n $effect(() => {\n const nextUtilities: any[] = [];\n const nextWrappers: any[] = [];\n\n for (const reg of plugins) {\n const pkg = reg.package;\n if (hasAutoMountElements(pkg)) {\n const elements = pkg.autoMountElements?.() ?? [];\n for (const element of elements) {\n if (element.type === 'utility') {\n nextUtilities.push(element.component);\n } else if (element.type === 'wrapper') {\n nextWrappers.push(element.component);\n }\n }\n }\n }\n\n utilities = nextUtilities;\n wrappers = nextWrappers;\n });\n</script>\n\n{#if wrappers.length > 0}\n <!-- wrap slot content inside all wrappers -->\n <NestedWrapper {wrappers} {children} />\n{:else}\n {@render children?.()}\n{/if}\n\n<!-- mount all utilities -->\n{#each utilities as Utility, i (`utility-${i}`)}\n <Utility />\n{/each}\n","<script lang=\"ts\">\n import type { Logger, PdfEngine } from '@embedpdf/models';\n import { type IPlugin, type PluginBatchRegistrations, PluginRegistry } from '@embedpdf/core';\n import { type Snippet } from 'svelte';\n import AutoMount from './AutoMount.svelte';\n import { pdfContext, type PDFContextState } from '../hooks';\n\n export type { PluginBatchRegistrations };\n\n interface EmbedPDFProps {\n /**\n * The PDF engine to use for the PDF viewer.\n */\n engine: PdfEngine;\n /**\n * The logger to use for the PDF viewer.\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: Snippet<[PDFContextState]>;\n /**\n * Whether to auto-mount specific non-visual DOM elements from plugins.\n * @default true\n */\n autoMountDomElements?: boolean;\n }\n\n let {\n engine,\n logger,\n onInitialized,\n plugins,\n children,\n autoMountDomElements = true,\n }: EmbedPDFProps = $props();\n\n let latestInit = onInitialized;\n\n $effect(() => {\n if (onInitialized) {\n latestInit = onInitialized;\n }\n });\n\n $effect(() => {\n if (engine || (engine && plugins)) {\n const reg = new PluginRegistry(engine, { logger });\n reg.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await reg.initialize();\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n return;\n }\n\n const store = reg.getStore();\n pdfContext.coreState = 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 pdfContext.coreState = newState.core;\n\n // Update convenience accessors\n const activeDocumentId = newState.core.activeDocumentId ?? null;\n const documents = newState.core.documents ?? {};\n const documentOrder = newState.core.documentOrder ?? [];\n\n pdfContext.activeDocumentId = activeDocumentId;\n pdfContext.activeDocument =\n activeDocumentId && documents[activeDocumentId] ? documents[activeDocumentId] : null;\n pdfContext.documents = documents;\n pdfContext.documentStates = documentOrder\n .map((docId) => documents[docId])\n .filter(\n (doc): doc is import('@embedpdf/core').DocumentState =>\n doc !== null && doc !== undefined,\n );\n }\n });\n\n /* always call the *latest* callback */\n await latestInit?.(reg);\n\n // if the registry is destroyed, don't do anything\n if (reg.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n reg.pluginsReady().then(() => {\n if (!reg.isDestroyed()) {\n pdfContext.pluginsReady = true;\n }\n });\n\n // Provide the registry to children via context\n pdfContext.registry = reg;\n pdfContext.isInitializing = false;\n\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 reg.destroy();\n pdfContext.registry = null;\n pdfContext.coreState = null;\n pdfContext.isInitializing = true;\n pdfContext.pluginsReady = false;\n pdfContext.activeDocumentId = null;\n pdfContext.activeDocument = null;\n pdfContext.documents = {};\n pdfContext.documentStates = [];\n };\n }\n });\n</script>\n\n{#if pdfContext.pluginsReady && autoMountDomElements}\n <AutoMount {plugins}>{@render children(pdfContext)}</AutoMount>\n{:else}\n {@render children(pdfContext)}\n{/if}\n"],"names":[],"mappings":"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"}
@@ -8,8 +8,9 @@ type __VLS_Slots = {} & {
8
8
  } & {
9
9
  default?: (props: typeof __VLS_7) => any;
10
10
  };
11
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
12
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
11
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
12
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
13
+ declare const _default: typeof __VLS_export;
13
14
  export default _default;
14
15
  type __VLS_WithSlots<T, S> = T & {
15
16
  new (): {
@@ -10,22 +10,33 @@ type __VLS_Props = {
10
10
  };
11
11
  declare var __VLS_6: {
12
12
  registry: any;
13
+ coreState: any;
13
14
  isInitializing: any;
14
15
  pluginsReady: any;
16
+ activeDocumentId: any;
17
+ activeDocument: any;
18
+ documents: any;
19
+ documentStates: any;
15
20
  }, __VLS_8: {
16
21
  registry: any;
22
+ coreState: any;
17
23
  isInitializing: any;
18
24
  pluginsReady: any;
25
+ activeDocumentId: any;
26
+ activeDocument: any;
27
+ documents: any;
28
+ documentStates: any;
19
29
  };
20
30
  type __VLS_Slots = {} & {
21
31
  default?: (props: typeof __VLS_6) => any;
22
32
  } & {
23
33
  default?: (props: typeof __VLS_8) => any;
24
34
  };
25
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
35
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
26
36
  autoMountDomElements: boolean;
27
37
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
28
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
38
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
39
+ declare const _default: typeof __VLS_export;
29
40
  export default _default;
30
41
  type __VLS_WithSlots<T, S> = T & {
31
42
  new (): {
@@ -7,8 +7,9 @@ type __VLS_Slots = {} & {
7
7
  } & {
8
8
  default?: (props: typeof __VLS_14) => any;
9
9
  };
10
- declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
11
- declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
10
+ declare const __VLS_base: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
11
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
+ declare const _default: typeof __VLS_export;
12
13
  export default _default;
13
14
  type __VLS_WithSlots<T, S> = T & {
14
15
  new (): {
@@ -1,4 +1,5 @@
1
1
  export * from './use-core-state';
2
+ export * from './use-document-state';
2
3
  export * from './use-registry';
3
4
  export * from './use-plugin';
4
5
  export * from './use-capability';
@@ -1,2 +1,9 @@
1
+ import { Ref } from 'vue';
1
2
  import { CoreState } from '../../lib/index.ts';
2
- export declare function useCoreState(): import('vue').Ref<CoreState | undefined, CoreState | undefined>;
3
+ /**
4
+ * Hook that provides access to the current core state.
5
+ *
6
+ * Note: This reads from the context which is already subscribed to core state changes
7
+ * in the EmbedPDF component, so there's no additional subscription overhead.
8
+ */
9
+ export declare function useCoreState(): Ref<CoreState | null>;
@@ -0,0 +1,8 @@
1
+ import { MaybeRefOrGetter } from 'vue';
2
+ /**
3
+ * Hook that provides reactive access to a specific document's state from the core store.
4
+ *
5
+ * @param documentId The ID of the document to retrieve (can be ref, computed, getter, or plain value).
6
+ * @returns A computed ref containing the DocumentState object or null if not found.
7
+ */
8
+ export declare function useDocumentState(documentId: MaybeRefOrGetter<string | null>): import('vue').ComputedRef<import('../../lib/index.ts').DocumentState | null>;
@@ -1,8 +1,13 @@
1
1
  import { InjectionKey, Ref, ShallowRef } from 'vue';
2
- import { PluginRegistry } from '../lib/index.ts';
2
+ import { PluginRegistry, CoreState, DocumentState } from '../lib/index.ts';
3
3
  export interface PDFContextState {
4
4
  registry: ShallowRef<PluginRegistry | null>;
5
+ coreState: Ref<CoreState | null>;
5
6
  isInitializing: Ref<boolean>;
6
7
  pluginsReady: Ref<boolean>;
8
+ activeDocumentId: Ref<string | null>;
9
+ activeDocument: Ref<DocumentState | null>;
10
+ documents: Ref<Record<string, DocumentState>>;
11
+ documentStates: Ref<DocumentState[]>;
7
12
  }
8
13
  export declare const pdfKey: InjectionKey<PDFContextState>;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("@embedpdf/core"),n=Symbol("pdfKey");function r(){const t=e.inject(n);if(!t)throw new Error("useRegistry must be used inside <EmbedPDF>");return t}function o(t){const{registry:n}=r(),o=e.shallowRef(null),l=e.ref(!0),u=e.ref(new Promise((()=>{}))),s=()=>{var e;if(!n.value)return;const r=n.value.getPlugin(t);if(!r)throw new Error(`Plugin ${t} not found`);o.value=r,l.value=!1,u.value=(null==(e=r.ready)?void 0:e.call(r))??Promise.resolve()};return e.onMounted(s),e.watch(n,s),{plugin:o,isLoading:l,ready:u}}const l=e.defineComponent({__name:"nested-wrapper",props:{wrappers:{}},setup:t=>(t,n)=>{const r=e.resolveComponent("NestedWrapper",!0);return e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.wrappers[0]),null,{default:e.withCtx((()=>[t.wrappers.length>1?(e.openBlock(),e.createBlock(r,{key:0,wrappers:t.wrappers.slice(1)},{default:e.withCtx((()=>[e.renderSlot(t.$slots,"default")])),_:3},8,["wrappers"])):e.renderSlot(t.$slots,"default",{key:1})])),_:3})}}),u=e.defineComponent({__name:"auto-mount",props:{plugins:{}},setup(n){const r=n,o=e.computed((()=>{const e=[],n=[];for(const o of r.plugins){const r=o.package;if(t.hasAutoMountElements(r)){const t=r.autoMountElements()||[];for(const r of t)"utility"===r.type?e.push(r.component):"wrapper"===r.type&&n.push(r.component)}}return{utilities:e,wrappers:n}}));return(t,n)=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[o.value.wrappers.length>0?(e.openBlock(),e.createBlock(l,{key:0,wrappers:o.value.wrappers},{default:e.withCtx((()=>[e.renderSlot(t.$slots,"default")])),_:3},8,["wrappers"])):e.renderSlot(t.$slots,"default",{key:1}),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.value.utilities,((t,n)=>(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t),{key:`utility-${n}`})))),128))],64))}}),s=e.defineComponent({__name:"embed-pdf",props:{engine:{},logger:{},plugins:{},onInitialized:{},autoMountDomElements:{type:Boolean,default:!0}},setup(r){const o=r,l=e.shallowRef(null),s=e.ref(!0),i=e.ref(!1);return e.provide(n,{registry:l,isInitializing:s,pluginsReady:i}),e.onMounted((async()=>{var e;const n=new t.PluginRegistry(o.engine,{logger:o.logger});n.registerPluginBatch(o.plugins),await n.initialize(),await(null==(e=o.onInitialized)?void 0:e.call(o,n)),l.value=n,s.value=!1,n.pluginsReady().then((()=>i.value=!0))})),e.onBeforeUnmount((()=>{var e;return null==(e=l.value)?void 0:e.destroy()})),(t,n)=>i.value&&t.autoMountDomElements?(e.openBlock(),e.createBlock(u,{key:0,plugins:t.plugins},{default:e.withCtx((()=>[e.renderSlot(t.$slots,"default",{registry:l.value,isInitializing:s.value,pluginsReady:i.value})])),_:3},8,["plugins"])):e.renderSlot(t.$slots,"default",{key:1,registry:l.value,isInitializing:s.value,pluginsReady:i.value})}});exports.EmbedPDF=s,exports.useCapability=function(t){const{plugin:n,isLoading:r,ready:l}=o(t);return{provides:e.computed((()=>{if(!n.value)return null;if(!n.value.provides)throw new Error(`Plugin ${t} does not implement provides()`);return n.value.provides()})),isLoading:r,ready:l}},exports.useCoreState=function(){const{registry:n}=r(),o=e.ref();return e.onMounted((()=>{const r=n.value.getStore();o.value=r.getState().core;const l=r.subscribe(((e,n,l)=>{r.isCoreAction(e)&&!t.arePropsEqual(n.core,l.core)&&(o.value=n.core)}));e.onBeforeUnmount(l)})),o},exports.usePlugin=o,exports.useRegistry=r,exports.useStoreState=function(){const{registry:t}=r(),n=e.ref();function o(){return t.value?(n.value=t.value.getStore().getState(),t.value.getStore().subscribe(((e,t)=>n.value=t))):()=>{}}let l=o();return e.watch(t,(()=>{null==l||l(),l=o()})),e.onBeforeUnmount((()=>null==l?void 0:l())),n};
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),t=require("@embedpdf/core"),n=Symbol("pdfKey");function o(){const t=e.inject(n);if(!t)throw new Error("useRegistry must be used inside <EmbedPDF>");return t}function r(){const{coreState:e}=o();return e}function u(t){const{registry:n}=o(),r=e.shallowRef(null),u=e.ref(!0),l=e.ref(new Promise(()=>{})),a=()=>{var e;if(!n.value)return;const o=n.value.getPlugin(t);if(!o)throw new Error(`Plugin ${t} not found`);r.value=o,u.value=!1,l.value=(null==(e=o.ready)?void 0:e.call(o))??Promise.resolve()};return e.onMounted(a),e.watch(n,a),{plugin:r,isLoading:u,ready:l}}const l=e.defineComponent({__name:"nested-wrapper",props:{wrappers:{}},setup:t=>(n,o)=>{const r=e.resolveComponent("NestedWrapper",!0);return e.openBlock(),e.createBlock(e.resolveDynamicComponent(t.wrappers[0]),null,{default:e.withCtx(()=>[t.wrappers.length>1?(e.openBlock(),e.createBlock(r,{key:0,wrappers:t.wrappers.slice(1)},{default:e.withCtx(()=>[e.renderSlot(n.$slots,"default")]),_:3},8,["wrappers"])):e.renderSlot(n.$slots,"default",{key:1})]),_:3})}}),a=e.defineComponent({__name:"auto-mount",props:{plugins:{}},setup(n){const o=n,r=e.computed(()=>{const e=[],n=[];for(const r of o.plugins){const o=r.package;if(t.hasAutoMountElements(o)){const t=o.autoMountElements()||[];for(const o of t)"utility"===o.type?e.push(o.component):"wrapper"===o.type&&n.push(o.component)}}return{utilities:e,wrappers:n}});return(t,n)=>(e.openBlock(),e.createElementBlock(e.Fragment,null,[r.value.wrappers.length>0?(e.openBlock(),e.createBlock(l,{key:0,wrappers:r.value.wrappers},{default:e.withCtx(()=>[e.renderSlot(t.$slots,"default")]),_:3},8,["wrappers"])):e.renderSlot(t.$slots,"default",{key:1}),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(r.value.utilities,(t,n)=>(e.openBlock(),e.createBlock(e.resolveDynamicComponent(t),{key:`utility-${n}`}))),128))],64))}}),s=e.defineComponent({__name:"embed-pdf",props:{engine:{},logger:{},plugins:{},onInitialized:{},autoMountDomElements:{type:Boolean,default:!0}},setup(o){const r=o,u=e.shallowRef(null),l=e.ref(null),s=e.ref(!0),i=e.ref(!1),c=e.computed(()=>{var e;return(null==(e=l.value)?void 0:e.activeDocumentId)??null}),p=e.computed(()=>{var e;return(null==(e=l.value)?void 0:e.documents)??{}}),d=e.computed(()=>{var e;return(null==(e=l.value)?void 0:e.documentOrder)??[]}),v=e.computed(()=>{const e=c.value,t=p.value;return e&&t[e]?t[e]:null}),m=e.computed(()=>{const e=p.value;return d.value.map(t=>e[t]).filter(e=>null!=e)});return e.provide(n,{registry:u,coreState:l,isInitializing:s,pluginsReady:i,activeDocumentId:c,activeDocument:v,documents:p,documentStates:m}),e.onMounted(async()=>{var n;const o=new t.PluginRegistry(r.engine,{logger:r.logger});if(o.registerPluginBatch(r.plugins),await o.initialize(),o.isDestroyed())return;const a=o.getStore();l.value=a.getState().core;const c=a.subscribe((e,t,n)=>{a.isCoreAction(e)&&t.core!==n.core&&(l.value=t.core)});await(null==(n=r.onInitialized)?void 0:n.call(r,o)),o.isDestroyed()?c():(u.value=o,s.value=!1,o.pluginsReady().then(()=>{o.isDestroyed()||(i.value=!0)}),e.onBeforeUnmount(()=>{var e;c(),null==(e=u.value)||e.destroy()}))}),(t,n)=>i.value&&o.autoMountDomElements?(e.openBlock(),e.createBlock(a,{key:0,plugins:o.plugins},{default:e.withCtx(()=>[e.renderSlot(t.$slots,"default",{registry:u.value,coreState:l.value,isInitializing:s.value,pluginsReady:i.value,activeDocumentId:c.value,activeDocument:v.value,documents:p.value,documentStates:m.value})]),_:3},8,["plugins"])):e.renderSlot(t.$slots,"default",{key:1,registry:u.value,coreState:l.value,isInitializing:s.value,pluginsReady:i.value,activeDocumentId:c.value,activeDocument:v.value,documents:p.value,documentStates:m.value})}});exports.EmbedPDF=s,exports.useCapability=function(t){const{plugin:n,isLoading:o,ready:r}=u(t);return{provides:e.computed(()=>{if(!n.value)return null;if(!n.value.provides)throw new Error(`Plugin ${t} does not implement provides()`);return n.value.provides()}),isLoading:o,ready:r}},exports.useCoreState=r,exports.useDocumentState=function(t){const n=r();return e.computed(()=>{const o=n.value,r=e.toValue(t);return o&&r?o.documents[r]??null:null})},exports.usePlugin=u,exports.useRegistry=o,exports.useStoreState=function(){const{registry:t}=o(),n=e.ref();function r(){return t.value?(n.value=t.value.getStore().getState(),t.value.getStore().subscribe((e,t)=>n.value=t)):()=>{}}let u=r();return e.watch(t,()=>{null==u||u(),u=r()}),e.onBeforeUnmount(()=>null==u?void 0:u()),n};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/vue/context.ts","../../src/vue/composables/use-registry.ts","../../src/vue/composables/use-plugin.ts","../../src/vue/components/nested-wrapper.vue","../../src/vue/components/auto-mount.vue","../../src/vue/components/embed-pdf.vue","../../src/vue/composables/use-capability.ts","../../src/vue/composables/use-core-state.ts","../../src/vue/composables/use-store-state.ts"],"sourcesContent":["import { InjectionKey, Ref, ShallowRef } from 'vue';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: ShallowRef<PluginRegistry | null>;\n isInitializing: Ref<boolean>;\n pluginsReady: Ref<boolean>;\n}\n\nexport const pdfKey: InjectionKey<PDFContextState> = Symbol('pdfKey');\n","import { inject } from 'vue';\nimport { pdfKey } from '../context';\n\nexport function useRegistry() {\n const ctx = inject(pdfKey);\n if (!ctx) throw new Error('useRegistry must be used inside <EmbedPDF>');\n return ctx;\n}\n","import { shallowRef, ref, onMounted, watch, type ShallowRef, type Ref } from 'vue';\nimport type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\nexport interface PluginState<T extends BasePlugin> {\n plugin: ShallowRef<T | null>;\n isLoading: Ref<boolean>;\n ready: Ref<Promise<void>>;\n}\n\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n const plugin = shallowRef(null) as ShallowRef<T | null>;\n\n const isLoading = ref(true);\n const ready = ref<Promise<void>>(new Promise(() => {}));\n\n const load = () => {\n if (!registry.value) return;\n\n const p = registry.value.getPlugin<T>(pluginId);\n if (!p) throw new Error(`Plugin ${pluginId} not found`);\n\n plugin.value = p;\n isLoading.value = false;\n ready.value = p.ready?.() ?? Promise.resolve();\n };\n\n onMounted(load);\n watch(registry, load);\n\n return { plugin, isLoading, ready };\n}\n","<script setup lang=\"ts\">\ndefineProps<{\n wrappers: any[];\n}>();\n</script>\n\n<template>\n <component :is=\"wrappers[0]\">\n <NestedWrapper v-if=\"wrappers.length > 1\" :wrappers=\"wrappers.slice(1)\">\n <slot />\n </NestedWrapper>\n <slot v-else />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { hasAutoMountElements, type PluginBatchRegistration, type IPlugin } from '@embedpdf/core';\nimport NestedWrapper from './nested-wrapper.vue';\n\nconst props = defineProps<{\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n}>();\n\nconst elements = computed(() => {\n const utilities: any[] = [];\n const wrappers: any[] = [];\n\n for (const reg of props.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 wrappers.push(element.component);\n }\n }\n }\n }\n\n return { utilities, wrappers };\n});\n</script>\n\n<template>\n <NestedWrapper v-if=\"elements.wrappers.length > 0\" :wrappers=\"elements.wrappers\">\n <slot />\n </NestedWrapper>\n <slot v-else />\n\n <component\n v-for=\"(utility, index) in elements.utilities\"\n :key=\"`utility-${index}`\"\n :is=\"utility\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { ref, provide, onMounted, onBeforeUnmount, shallowRef } from 'vue';\nimport { PluginRegistry, PluginBatchRegistrations } from '@embedpdf/core';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { pdfKey, PDFContextState } from '../context';\nimport AutoMount from './auto-mount.vue';\n\nexport type { PluginBatchRegistrations };\n\nconst props = withDefaults(\n defineProps<{\n engine: PdfEngine;\n logger?: Logger;\n plugins: PluginBatchRegistrations;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n autoMountDomElements?: boolean;\n }>(),\n {\n autoMountDomElements: true,\n },\n);\n\n/* reactive state */\nconst registry = shallowRef<PluginRegistry | null>(null);\nconst isInit = ref(true);\nconst pluginsOk = ref(false);\n\n/* expose to children */\nprovide<PDFContextState>(pdfKey, { registry, isInitializing: isInit, pluginsReady: pluginsOk });\n\nonMounted(async () => {\n const reg = new PluginRegistry(props.engine, { logger: props.logger });\n reg.registerPluginBatch(props.plugins);\n await reg.initialize();\n await props.onInitialized?.(reg);\n\n registry.value = reg;\n isInit.value = false;\n\n reg.pluginsReady().then(() => (pluginsOk.value = true));\n});\n\nonBeforeUnmount(() => registry.value?.destroy());\n</script>\n\n<template>\n <AutoMount v-if=\"pluginsOk && autoMountDomElements\" :plugins=\"plugins\">\n <!-- scoped slot keeps API parity with React version -->\n <slot :registry=\"registry\" :isInitializing=\"isInit\" :pluginsReady=\"pluginsOk\" />\n </AutoMount>\n\n <!-- No auto-mount or not ready yet -->\n <slot v-else :registry=\"registry\" :isInitializing=\"isInit\" :pluginsReady=\"pluginsOk\" />\n</template>\n","import type { BasePlugin } from '@embedpdf/core';\nimport { computed, type Ref } from 'vue';\nimport { usePlugin } from './use-plugin';\n\nexport interface CapabilityState<C> {\n provides: Ref<C | null>;\n isLoading: Ref<boolean>;\n ready: Ref<Promise<void>>;\n}\n\n/**\n * Access the public capability exposed by a plugin.\n *\n * @example\n * const { provides: zoom } = useCapability<ZoomPlugin>(ZoomPlugin.id);\n * zoom.value?.zoomIn();\n */\nexport function useCapability<T extends BasePlugin>(\n pluginId: T['id'],\n): CapabilityState<ReturnType<NonNullable<T['provides']>>> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n const provides = computed(() => {\n if (!plugin.value) return null;\n if (!plugin.value.provides) {\n throw new Error(`Plugin ${pluginId} does not implement provides()`);\n }\n return plugin.value.provides() as ReturnType<NonNullable<T['provides']>>;\n });\n\n return { provides, isLoading, ready };\n}\n","import { ref, onMounted, onBeforeUnmount } from 'vue';\nimport { arePropsEqual, type CoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\nexport function useCoreState() {\n const { registry } = useRegistry();\n const core = ref<CoreState>();\n\n onMounted(() => {\n const store = registry.value!.getStore();\n core.value = store.getState().core;\n\n const unsub = store.subscribe((action, newSt, oldSt) => {\n if (store.isCoreAction(action) && !arePropsEqual(newSt.core, oldSt.core)) {\n core.value = newSt.core;\n }\n });\n onBeforeUnmount(unsub);\n });\n\n return core;\n}\n","import { ref, onMounted, onBeforeUnmount, watch } from 'vue';\nimport type { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Reactive getter for the *entire* global store.\n * Re‑emits whenever any slice changes.\n *\n * @example\n * const state = useStoreState(); // Ref<StoreState<CoreState>>\n * console.log(state.value.core.scale);\n */\nexport function useStoreState<T = CoreState>() {\n const { registry } = useRegistry();\n const state = ref<StoreState<T>>();\n\n function attach() {\n if (!registry.value) return () => {};\n\n // initial snapshot\n state.value = registry.value.getStore().getState() as StoreState<T>;\n\n // live updates\n return registry.value\n .getStore()\n .subscribe((_action, newState) => (state.value = newState as StoreState<T>));\n }\n\n /* attach now and re‑attach if registry instance ever changes */\n let unsubscribe = attach();\n watch(registry, () => {\n unsubscribe?.();\n unsubscribe = attach();\n });\n\n onBeforeUnmount(() => unsubscribe?.());\n\n return state;\n}\n"],"names":["pdfKey","Symbol","useRegistry","ctx","inject","Error","usePlugin","pluginId","registry","plugin","shallowRef","isLoading","ref","ready","Promise","load","value","p","getPlugin","_a","call","resolve","onMounted","vue","watch","_openBlock","openBlock","_createBlock","_resolveDynamicComponent","resolveDynamicComponent","wrappers","length","_component_NestedWrapper","slice","_renderSlot","_ctx","$slots","renderSlot","key","props","__props","elements","computed","utilities","reg","plugins","pkg","package","hasAutoMountElements","autoMountElements","element","type","push","component","NestedWrapper","_createElementBlock","createElementBlock","_Fragment","utility","index","isInit","pluginsOk","provide","isInitializing","pluginsReady","async","PluginRegistry","engine","logger","registerPluginBatch","initialize","onInitialized","then","onBeforeUnmount","destroy","autoMountDomElements","AutoMount","provides","core","store","getStore","core$1","getState","unsub","subscribe","action","newSt","oldSt","isCoreAction","arePropsEqual","state","attach","_action","newState","unsubscribe"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/vue/context.ts","../../src/vue/composables/use-registry.ts","../../src/vue/composables/use-core-state.ts","../../src/vue/composables/use-plugin.ts","../../src/vue/components/nested-wrapper.vue","../../src/vue/components/auto-mount.vue","../../src/vue/components/embed-pdf.vue","../../src/vue/composables/use-capability.ts","../../src/vue/composables/use-document-state.ts","../../src/vue/composables/use-store-state.ts"],"sourcesContent":["import { InjectionKey, Ref, ShallowRef } from 'vue';\nimport type { PluginRegistry, CoreState, DocumentState } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: ShallowRef<PluginRegistry | null>;\n coreState: Ref<CoreState | null>;\n isInitializing: Ref<boolean>;\n pluginsReady: Ref<boolean>;\n\n // Convenience accessors (always safe to use)\n activeDocumentId: Ref<string | null>;\n activeDocument: Ref<DocumentState | null>;\n documents: Ref<Record<string, DocumentState>>;\n documentStates: Ref<DocumentState[]>;\n}\n\nexport const pdfKey: InjectionKey<PDFContextState> = Symbol('pdfKey');\n","import { inject } from 'vue';\nimport { pdfKey } from '../context';\n\nexport function useRegistry() {\n const ctx = inject(pdfKey);\n if (!ctx) throw new Error('useRegistry must be used inside <EmbedPDF>');\n return ctx;\n}\n","import { Ref } from 'vue';\nimport { type CoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): Ref<CoreState | null> {\n const { coreState } = useRegistry();\n return coreState;\n}\n","import { shallowRef, ref, onMounted, watch, type ShallowRef, type Ref } from 'vue';\nimport type { BasePlugin } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\nexport interface PluginState<T extends BasePlugin> {\n plugin: ShallowRef<T | null>;\n isLoading: Ref<boolean>;\n ready: Ref<Promise<void>>;\n}\n\nexport function usePlugin<T extends BasePlugin>(pluginId: T['id']): PluginState<T> {\n const { registry } = useRegistry();\n\n const plugin = shallowRef(null) as ShallowRef<T | null>;\n\n const isLoading = ref(true);\n const ready = ref<Promise<void>>(new Promise(() => {}));\n\n const load = () => {\n if (!registry.value) return;\n\n const p = registry.value.getPlugin<T>(pluginId);\n if (!p) throw new Error(`Plugin ${pluginId} not found`);\n\n plugin.value = p;\n isLoading.value = false;\n ready.value = p.ready?.() ?? Promise.resolve();\n };\n\n onMounted(load);\n watch(registry, load);\n\n return { plugin, isLoading, ready };\n}\n","<script setup lang=\"ts\">\ndefineProps<{\n wrappers: any[];\n}>();\n</script>\n\n<template>\n <component :is=\"wrappers[0]\">\n <NestedWrapper v-if=\"wrappers.length > 1\" :wrappers=\"wrappers.slice(1)\">\n <slot />\n </NestedWrapper>\n <slot v-else />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { hasAutoMountElements, type PluginBatchRegistration, type IPlugin } from '@embedpdf/core';\nimport NestedWrapper from './nested-wrapper.vue';\n\nconst props = defineProps<{\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n}>();\n\nconst elements = computed(() => {\n const utilities: any[] = [];\n const wrappers: any[] = [];\n\n for (const reg of props.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 wrappers.push(element.component);\n }\n }\n }\n }\n\n return { utilities, wrappers };\n});\n</script>\n\n<template>\n <NestedWrapper v-if=\"elements.wrappers.length > 0\" :wrappers=\"elements.wrappers\">\n <slot />\n </NestedWrapper>\n <slot v-else />\n\n <component\n v-for=\"(utility, index) in elements.utilities\"\n :key=\"`utility-${index}`\"\n :is=\"utility\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { ref, provide, onMounted, onBeforeUnmount, shallowRef, computed } from 'vue';\nimport { PluginRegistry, PluginBatchRegistrations, CoreState, DocumentState } from '@embedpdf/core';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { pdfKey, PDFContextState } from '../context';\nimport AutoMount from './auto-mount.vue';\n\nexport type { PluginBatchRegistrations };\n\nconst props = withDefaults(\n defineProps<{\n engine: PdfEngine;\n logger?: Logger;\n plugins: PluginBatchRegistrations;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n autoMountDomElements?: boolean;\n }>(),\n {\n autoMountDomElements: true,\n },\n);\n\n/* reactive state */\nconst registry = shallowRef<PluginRegistry | null>(null);\nconst coreState = ref<CoreState | null>(null);\nconst isInit = ref(true);\nconst pluginsOk = ref(false);\n\n// Compute convenience accessors\nconst activeDocumentId = computed(() => coreState.value?.activeDocumentId ?? null);\nconst documents = computed(() => coreState.value?.documents ?? {});\nconst documentOrder = computed(() => coreState.value?.documentOrder ?? []);\n\nconst activeDocument = computed(() => {\n const docId = activeDocumentId.value;\n const docs = documents.value;\n return docId && docs[docId] ? docs[docId] : null;\n});\n\nconst documentStates = computed(() => {\n const docs = documents.value;\n const order = documentOrder.value;\n return order\n .map((docId) => docs[docId])\n .filter((doc): doc is DocumentState => doc !== null && doc !== undefined);\n});\n\n/* expose to children */\nprovide<PDFContextState>(pdfKey, {\n registry,\n coreState,\n isInitializing: isInit,\n pluginsReady: pluginsOk,\n activeDocumentId,\n activeDocument,\n documents,\n documentStates,\n});\n\nonMounted(async () => {\n const reg = new PluginRegistry(props.engine, { logger: props.logger });\n reg.registerPluginBatch(props.plugins);\n await reg.initialize();\n\n if (reg.isDestroyed()) {\n return;\n }\n\n const store = reg.getStore();\n coreState.value = 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 coreState.value = newState.core;\n }\n });\n\n await props.onInitialized?.(reg);\n\n if (reg.isDestroyed()) {\n unsubscribe();\n return;\n }\n\n registry.value = reg;\n isInit.value = false;\n\n reg.pluginsReady().then(() => {\n if (!reg.isDestroyed()) {\n pluginsOk.value = true;\n }\n });\n\n onBeforeUnmount(() => {\n unsubscribe();\n registry.value?.destroy();\n });\n});\n</script>\n\n<template>\n <AutoMount v-if=\"pluginsOk && autoMountDomElements\" :plugins=\"plugins\">\n <!-- scoped slot keeps API parity with React version -->\n <slot\n :registry=\"registry\"\n :coreState=\"coreState\"\n :isInitializing=\"isInit\"\n :pluginsReady=\"pluginsOk\"\n :activeDocumentId=\"activeDocumentId\"\n :activeDocument=\"activeDocument\"\n :documents=\"documents\"\n :documentStates=\"documentStates\"\n />\n </AutoMount>\n\n <!-- No auto-mount or not ready yet -->\n <slot\n v-else\n :registry=\"registry\"\n :coreState=\"coreState\"\n :isInitializing=\"isInit\"\n :pluginsReady=\"pluginsOk\"\n :activeDocumentId=\"activeDocumentId\"\n :activeDocument=\"activeDocument\"\n :documents=\"documents\"\n :documentStates=\"documentStates\"\n />\n</template>\n","import type { BasePlugin } from '@embedpdf/core';\nimport { computed, type Ref } from 'vue';\nimport { usePlugin } from './use-plugin';\n\nexport interface CapabilityState<C> {\n provides: Ref<C | null>;\n isLoading: Ref<boolean>;\n ready: Ref<Promise<void>>;\n}\n\n/**\n * Access the public capability exposed by a plugin.\n *\n * @example\n * const { provides: zoom } = useCapability<ZoomPlugin>(ZoomPlugin.id);\n * zoom.value?.zoomIn();\n */\nexport function useCapability<T extends BasePlugin>(\n pluginId: T['id'],\n): CapabilityState<ReturnType<NonNullable<T['provides']>>> {\n const { plugin, isLoading, ready } = usePlugin<T>(pluginId);\n\n const provides = computed(() => {\n if (!plugin.value) return null;\n if (!plugin.value.provides) {\n throw new Error(`Plugin ${pluginId} does not implement provides()`);\n }\n return plugin.value.provides() as ReturnType<NonNullable<T['provides']>>;\n });\n\n return { provides, isLoading, ready };\n}\n","import { computed, toValue, type MaybeRefOrGetter } from 'vue';\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 (can be ref, computed, getter, or plain value).\n * @returns A computed ref containing the DocumentState object or null if not found.\n */\nexport function useDocumentState(documentId: MaybeRefOrGetter<string | null>) {\n const coreState = useCoreState();\n\n const documentState = computed(() => {\n const core = coreState.value;\n const docId = toValue(documentId);\n\n if (!core || !docId) return null;\n return core.documents[docId] ?? null;\n });\n\n return documentState;\n}\n","import { ref, onMounted, onBeforeUnmount, watch } from 'vue';\nimport type { CoreState, StoreState } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\n\n/**\n * Reactive getter for the *entire* global store.\n * Re‑emits whenever any slice changes.\n *\n * @example\n * const state = useStoreState(); // Ref<StoreState<CoreState>>\n * console.log(state.value.core.scale);\n */\nexport function useStoreState<T = CoreState>() {\n const { registry } = useRegistry();\n const state = ref<StoreState<T>>();\n\n function attach() {\n if (!registry.value) return () => {};\n\n // initial snapshot\n state.value = registry.value.getStore().getState() as StoreState<T>;\n\n // live updates\n return registry.value\n .getStore()\n .subscribe((_action, newState) => (state.value = newState as StoreState<T>));\n }\n\n /* attach now and re‑attach if registry instance ever changes */\n let unsubscribe = attach();\n watch(registry, () => {\n unsubscribe?.();\n unsubscribe = attach();\n });\n\n onBeforeUnmount(() => unsubscribe?.());\n\n return state;\n}\n"],"names":["pdfKey","Symbol","useRegistry","ctx","inject","Error","useCoreState","coreState","usePlugin","pluginId","registry","plugin","shallowRef","isLoading","ref","ready","Promise","load","value","p","getPlugin","_a","call","resolve","onMounted","watch","_openBlock","_createBlock","_resolveDynamicComponent","__props","wrappers","length","_component_NestedWrapper","slice","_renderSlot","_ctx","$slots","key","props","elements","computed","utilities","reg","plugins","pkg","package","hasAutoMountElements","autoMountElements","element","type","push","component","NestedWrapper","_createElementBlock","_Fragment","utility","index","isInit","pluginsOk","activeDocumentId","documents","documentOrder","activeDocument","docId","docs","documentStates","map","filter","doc","provide","isInitializing","pluginsReady","async","PluginRegistry","engine","logger","registerPluginBatch","initialize","isDestroyed","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","onInitialized","then","onBeforeUnmount","destroy","autoMountDomElements","AutoMount","provides","documentId","toValue","state","attach","_action"],"mappings":"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"}