@embedpdf/core 1.0.17 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +53 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/base/base-plugin.d.ts +3 -0
- package/dist/lib/registry/plugin-registry.d.ts +6 -1
- package/dist/lib/store/actions.d.ts +14 -2
- package/dist/lib/types/plugin.d.ts +3 -2
- package/dist/preact/adapter.d.ts +8 -2
- package/dist/preact/index.cjs +1 -1
- package/dist/preact/index.cjs.map +1 -1
- package/dist/preact/index.js +62 -3
- package/dist/preact/index.js.map +1 -1
- package/dist/react/adapter.d.ts +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +62 -3
- package/dist/react/index.js.map +1 -1
- package/dist/shared-preact/components/counter-rotate-container.d.ts +33 -0
- package/dist/shared-preact/components/embed-pdf.d.ts +3 -2
- package/dist/shared-preact/components/index.d.ts +1 -0
- package/dist/shared-react/components/counter-rotate-container.d.ts +33 -0
- package/dist/shared-react/components/embed-pdf.d.ts +3 -2
- package/dist/shared-react/components/index.d.ts +1 -0
- package/dist/vue/components/embed-pdf.vue.d.ts +2 -1
- package/dist/vue/index.cjs +1 -1
- package/dist/vue/index.cjs.map +1 -1
- package/dist/vue/index.js +2 -1
- package/dist/vue/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PluginRegistry } from '../registry/plugin-registry';
|
|
2
|
-
import {
|
|
2
|
+
import { Logger, Rotation } from '@embedpdf/models';
|
|
3
3
|
import { Action, Reducer } from '../store/types';
|
|
4
4
|
import { CoreState } from '../store';
|
|
5
5
|
export interface IPlugin<TConfig = unknown> {
|
|
@@ -16,6 +16,7 @@ export interface BasePluginConfig {
|
|
|
16
16
|
export interface PluginRegistryConfig {
|
|
17
17
|
rotation?: Rotation;
|
|
18
18
|
scale?: number;
|
|
19
|
+
logger?: Logger;
|
|
19
20
|
}
|
|
20
21
|
export interface PluginManifest<TConfig = unknown> {
|
|
21
22
|
id: string;
|
|
@@ -34,7 +35,7 @@ export interface PluginManifest<TConfig = unknown> {
|
|
|
34
35
|
}
|
|
35
36
|
export interface PluginPackage<T extends IPlugin<TConfig>, TConfig = unknown, TState = unknown, TAction extends Action = Action> {
|
|
36
37
|
manifest: PluginManifest<TConfig>;
|
|
37
|
-
create(registry: PluginRegistry,
|
|
38
|
+
create(registry: PluginRegistry, config: TConfig): T;
|
|
38
39
|
reducer: Reducer<TState, TAction>;
|
|
39
40
|
initialState: TState | ((coreState: CoreState, config: TConfig) => TState);
|
|
40
41
|
}
|
package/dist/preact/adapter.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import { createContext } from 'preact';
|
|
1
|
+
import { createContext, JSX, Fragment } from 'preact';
|
|
2
2
|
export { useEffect, useRef, useState, useCallback, useMemo, useContext } from 'preact/hooks';
|
|
3
3
|
export type { ComponentChildren as ReactNode, JSX } from 'preact';
|
|
4
|
-
export { createContext };
|
|
4
|
+
export { createContext, Fragment };
|
|
5
|
+
export type CSSProperties = import('preact').JSX.CSSProperties;
|
|
6
|
+
export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
|
|
7
|
+
export type MouseEvent<T = Element> = JSX.TargetedMouseEvent<T extends EventTarget ? T : never>;
|
|
8
|
+
export type PointerEvent<T = Element> = JSX.TargetedPointerEvent<T extends EventTarget ? T : never>;
|
|
9
|
+
export type ChangeEvent<T = Element> = JSX.TargetedInputEvent<T extends EventTarget ? T : never>;
|
|
10
|
+
export type TouchEvent<T = Element> = JSX.TargetedTouchEvent<T extends EventTarget ? T : never>;
|
package/dist/preact/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("preact"),t=require("preact/hooks"),r=require("preact/jsx-runtime"),i=require("@embedpdf/core"),n=e.createContext({registry:null,isInitializing:!0,pluginsReady:!1});function o(e,t){const{width:r,height:i}=e.size;switch(t%4){case 1:return{matrix:`matrix(0, -1, 1, 0, 0, ${i})`,width:i,height:r};case 2:return{matrix:`matrix(-1, 0, 0, -1, ${r}, ${i})`,width:r,height:i};case 3:return{matrix:`matrix(0, 1, -1, 0, ${r}, 0)`,width:i,height:r};default:return{matrix:"matrix(1, 0, 0, 1, 0, 0)",width:r,height:i}}}function s(){const e=t.useContext(n);if(void 0===e)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:r,isInitializing:i}=e;if(i)return e;if(null===r)throw new Error("PDF registry failed to initialize properly");return e}function u(e){const{registry:t}=s();if(null===t)return{plugin:null,isLoading:!0,ready:new Promise((()=>{}))};const r=t.getPlugin(e);if(!r)throw new Error(`Plugin ${e} not found`);return{plugin:r,isLoading:!1,ready:r.ready()}}exports.CounterRotate=function({children:t,...i}){const{rect:n,rotation:s}=i,{matrix:u,width:a,height:g}=o(n,s),l={style:{position:"absolute",left:n.origin.x,top:n.origin.y,transform:u,transformOrigin:"0 0",width:a,height:g,pointerEvents:"none",zIndex:3},onPointerDown:e=>e.stopPropagation(),onTouchStart:e=>e.stopPropagation()};return r.jsx(e.Fragment,{children:t({menuWrapperProps:l,matrix:u,rect:{origin:{x:n.origin.x,y:n.origin.y},size:{width:a,height:g}}})})},exports.EmbedPDF=function({engine:e,logger:o,onInitialized:s,plugins:u,children:a}){const[g,l]=t.useState(null),[c,d]=t.useState(!0),[p,h]=t.useState(!1),f=t.useRef(s);return t.useEffect((()=>{f.current=s}),[s]),t.useEffect((()=>{const t=new i.PluginRegistry(e,{logger:o});t.registerPluginBatch(u);return(async()=>{var e;await t.initialize(),t.isDestroyed()||(await(null==(e=f.current)?void 0:e.call(f,t)),t.isDestroyed()||(t.pluginsReady().then((()=>{t.isDestroyed()||h(!0)})),l(t),d(!1)))})().catch(console.error),()=>{t.destroy(),l(null),d(!0),h(!1)}}),[e,u]),r.jsx(n.Provider,{value:{registry:g,isInitializing:c,pluginsReady:p},children:"function"==typeof a?a({registry:g,isInitializing:c,pluginsReady:p}):a})},exports.PDFContext=n,exports.getCounterRotation=o,exports.useCapability=function(e){const{plugin:t,isLoading:r,ready:i}=u(e);if(!t)return{provides:null,isLoading:r,ready:i};if(!t.provides)throw new Error(`Plugin ${e} does not provide a capability`);return{provides:t.provides(),isLoading:r,ready:i}},exports.useCoreState=function(){const{registry:e}=s(),[r,n]=t.useState(null);return t.useEffect((()=>{if(!e)return;const t=e.getStore();n(t.getState().core);const r=t.subscribe(((e,r,o)=>{t.isCoreAction(e)&&!i.arePropsEqual(r.core,o.core)&&n(r.core)}));return()=>r()}),[e]),r},exports.usePlugin=u,exports.useRegistry=s,exports.useStoreState=function(){const{registry:e}=s(),[r,i]=t.useState(null);return t.useEffect((()=>{if(!e)return;i(e.getStore().getState());const t=e.getStore().subscribe(((e,t)=>{i(t)}));return()=>t()}),[e]),r};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-core-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\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 { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\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","isInitializing","pluginsReady","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","engine","onInitialized","plugins","children","setRegistry","useState","setIsInitializing","setPluginsReady","initRef","useRef","jsx","useEffect","current","pdfViewer","PluginRegistry","registerPluginBatch","async","initialize","isDestroyed","_a","call","then","catch","console","error","destroy","Provider","value","provides","coreState","setCoreState","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","arePropsEqual","state","setState","_action"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/components/counter-rotate-container.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-core-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n","import { Rect, Rotation } from '@embedpdf/models';\nimport { ReactNode, CSSProperties, PointerEvent, Fragment, TouchEvent } from '@framework';\n\ninterface CounterRotateProps {\n rect: Rect;\n rotation: Rotation;\n}\n\ninterface CounterTransformResult {\n matrix: string; // CSS matrix(a,b,c,d,e,f)\n width: number; // new width\n height: number; // new height\n}\n\n/**\n * Given an already-placed rect (left/top/width/height in px) and the page rotation,\n * return the counter-rotation matrix + adjusted width/height.\n *\n * transform-origin is expected to be \"0 0\".\n * left/top DO NOT change, apply them as-is.\n */\nexport function getCounterRotation(rect: Rect, rotation: Rotation): CounterTransformResult {\n const { width: w, height: h } = rect.size;\n\n switch (rotation % 4) {\n case 1: // 90° cw → need matrix(0,-1,1,0,0,h) and swap w/h\n return {\n matrix: `matrix(0, -1, 1, 0, 0, ${h})`,\n width: h,\n height: w,\n };\n\n case 2: // 180° → matrix(-1,0,0,-1,w,h), width/height unchanged\n return {\n matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,\n width: w,\n height: h,\n };\n\n case 3: // 270° cw → matrix(0,1,-1,0,w,0), swap w/h\n return {\n matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,\n width: h,\n height: w,\n };\n\n default:\n return {\n matrix: `matrix(1, 0, 0, 1, 0, 0)`,\n width: w,\n height: h,\n };\n }\n}\n\nexport interface MenuWrapperProps {\n style: CSSProperties;\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => void;\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => void;\n}\n\ninterface CounterRotateComponentProps extends CounterRotateProps {\n children: (props: {\n matrix: string;\n rect: Rect;\n menuWrapperProps: MenuWrapperProps;\n }) => ReactNode;\n}\n\nexport function CounterRotate({ children, ...props }: CounterRotateComponentProps) {\n const { rect, rotation } = props;\n const { matrix, width, height } = getCounterRotation(rect, rotation);\n\n const menuWrapperStyle: CSSProperties = {\n position: 'absolute',\n left: rect.origin.x,\n top: rect.origin.y,\n transform: matrix,\n transformOrigin: '0 0',\n width: width,\n height: height,\n pointerEvents: 'none',\n zIndex: 3,\n };\n\n const menuWrapperProps = {\n style: menuWrapperStyle,\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => e.stopPropagation(),\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => e.stopPropagation(),\n };\n\n return (\n <Fragment>\n {children({\n menuWrapperProps,\n matrix,\n rect: {\n origin: { x: rect.origin.x, y: rect.origin.y },\n size: { width: width, height: height },\n },\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 { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n logger?: Logger;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, logger, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine, { logger });\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\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","isInitializing","pluginsReady","getCounterRotation","rect","rotation","width","w","height","h","size","matrix","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","children","props","menuWrapperProps","style","position","left","origin","x","top","y","transform","transformOrigin","pointerEvents","zIndex","onPointerDown","e","stopPropagation","onTouchStart","Fragment","engine","logger","onInitialized","plugins","setRegistry","useState","setIsInitializing","setPluginsReady","initRef","useRef","jsx","useEffect","current","pdfViewer","PluginRegistry","registerPluginBatch","async","initialize","isDestroyed","_a","call","then","catch","console","error","destroy","Provider","value","provides","coreState","setCoreState","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","arePropsEqual","state","setState","_action"],"mappings":"gMASaA,EAAaC,EAAAA,cAA+B,CACvDC,SAAU,KACVC,gBAAgB,EAChBC,cAAc,ICSA,SAAAC,EAAmBC,EAAYC,GAC7C,MAAQC,MAAOC,EAAGC,OAAQC,GAAML,EAAKM,KAErC,OAAQL,EAAW,GACjB,KAAK,EACI,MAAA,CACLM,OAAQ,0BAA0BF,KAClCH,MAAOG,EACPD,OAAQD,GAGZ,KAAK,EACI,MAAA,CACLI,OAAQ,wBAAwBJ,MAAME,KACtCH,MAAOC,EACPC,OAAQC,GAGZ,KAAK,EACI,MAAA,CACLE,OAAQ,uBAAuBJ,QAC/BD,MAAOG,EACPD,OAAQD,GAGZ,QACS,MAAA,CACLI,OAAQ,2BACRL,MAAOC,EACPC,OAAQC,GAGhB,CC9CO,SAASG,IACR,MAAAC,EAAeC,aAAWhB,GAGhC,QAAqB,IAAjBe,EACI,MAAA,IAAIE,MAAM,2DAGZ,MAAAf,SAAEA,EAAUC,eAAAA,GAAmBY,EAGrC,GAAIZ,EACK,OAAAY,EAIT,GAAiB,OAAbb,EACI,MAAA,IAAIe,MAAM,8CAGX,OAAAF,CACT,CCXO,SAASG,EAAgCC,GACxC,MAAAjB,SAAEA,GAAaY,IAErB,GAAiB,OAAbZ,EACK,MAAA,CACLkB,OAAQ,KACRC,WAAW,EACXC,MAAO,IAAIC,SAAQ,UAIjB,MAAAH,EAASlB,EAASsB,UAAaL,GAErC,IAAKC,EACH,MAAM,IAAIH,MAAM,UAAUE,eAGrB,MAAA,CACLC,SACAC,WAAW,EACXC,MAAOF,EAAOE,QAElB,uBF8BO,UAAuBG,SAAEA,KAAaC,IACrC,MAAApB,KAAEA,EAAMC,SAAAA,GAAamB,GACrBb,OAAEA,EAAQL,MAAAA,EAAAE,OAAOA,GAAWL,EAAmBC,EAAMC,GAcrDoB,EAAmB,CACvBC,MAbsC,CACtCC,SAAU,WACVC,KAAMxB,EAAKyB,OAAOC,EAClBC,IAAK3B,EAAKyB,OAAOG,EACjBC,UAAWtB,EACXuB,gBAAiB,MACjB5B,QACAE,SACA2B,cAAe,OACfC,OAAQ,GAKRC,cAAgBC,GAAoCA,EAAEC,kBACtDC,aAAeF,GAAkCA,EAAEC,mBAInD,aAACE,EAAAA,UACElB,SAASA,EAAA,CACRE,mBACAd,SACAP,KAAM,CACJyB,OAAQ,CAAEC,EAAG1B,EAAKyB,OAAOC,EAAGE,EAAG5B,EAAKyB,OAAOG,GAC3CtB,KAAM,CAAEJ,QAAcE,cAKhC,mBGxFO,UAAkBkC,OAAEA,EAAAC,OAAQA,gBAAQC,EAAeC,QAAAA,EAAAtB,SAASA,IACjE,MAAOvB,EAAU8C,GAAeC,EAAAA,SAAgC,OACzD9C,EAAgB+C,GAAqBD,EAAAA,UAAkB,IACvD7C,EAAc+C,GAAmBF,EAAAA,UAAkB,GACpDG,EAAUC,SAAuCP,GA+CrDQ,OA7CFC,EAAAA,WAAU,KACRH,EAAQI,QAAUV,CAAA,GACjB,CAACA,IAEJS,EAAAA,WAAU,KACR,MAAME,EAAY,IAAIC,EAAAA,eAAed,EAAQ,CAAEC,WAC/CY,EAAUE,oBAAoBZ,GA8B9B,MA5BmBa,uBACXH,EAAUI,aAEZJ,EAAUK,sBAKR,OAAAC,EAAAX,EAAQI,cAAU,EAAAO,EAAAC,KAAAZ,EAAAK,IAGpBA,EAAUK,gBAIJL,EAAArD,eAAe6D,MAAK,KACvBR,EAAUK,eACbX,GAAgB,EAAI,IAKxBH,EAAYS,GACZP,GAAkB,IAAK,KAGZgB,MAAMC,QAAQC,OAEpB,KACLX,EAAUY,UACVrB,EAAY,MACZE,GAAkB,GAClBC,GAAgB,EAAK,CACvB,GACC,CAACP,EAAQG,IAGVO,EAAAA,IAACtD,EAAWsE,SAAX,CAAoBC,MAAO,CAAErE,WAAUC,iBAAgBC,gBACrDqB,SAAoB,mBAAbA,EACJA,EAAS,CAAEvB,WAAUC,iBAAgBC,iBACrCqB,GAGV,0ECvDO,SAA6CN,GAClD,MAAMC,OAAEA,EAAQC,UAAAA,EAAAC,MAAWA,GAAUJ,EAAaC,GAElD,IAAKC,EACI,MAAA,CACLoD,SAAU,KACVnD,YACAC,SAIA,IAACF,EAAOoD,SACV,MAAM,IAAIvD,MAAM,UAAUE,mCAGrB,MAAA,CACLqD,SAAUpD,EAAOoD,WACjBnD,YACAC,QAEJ,uBC7BO,WACC,MAAApB,SAAEA,GAAaY,KACd2D,EAAWC,GAAgBzB,EAAAA,SAA2B,MAqBtD,OAnBPM,EAAAA,WAAU,KACR,IAAKrD,EAAU,OAET,MAAAyE,EAAQzE,EAAS0E,WAGVF,EAAAC,EAAME,WAAWC,MAG9B,MAAMC,EAAcJ,EAAMK,WAAU,CAACC,EAAQC,EAAUC,KAEjDR,EAAMS,aAAaH,KAAYI,gBAAcH,EAASJ,KAAMK,EAASL,OACvEJ,EAAaQ,EAASJ,KAAI,IAI9B,MAAO,IAAMC,GAAY,GACxB,CAAC7E,IAEGuE,CACT,kECxBO,WACC,MAAAvE,SAAEA,GAAaY,KACdwE,EAAOC,GAAYtC,EAAAA,SAA+B,MAgBlD,OAdPM,EAAAA,WAAU,KACR,IAAKrD,EAAU,OAGfqF,EAASrF,EAAS0E,WAAWC,YAG7B,MAAME,EAAc7E,EAAS0E,WAAWI,WAAU,CAACQ,EAASN,KAC1DK,EAASL,EAAyB,IAGpC,MAAO,IAAMH,GAAY,GACxB,CAAC7E,IAEGoF,CACT"}
|
package/dist/preact/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext } from "preact";
|
|
1
|
+
import { createContext, Fragment } from "preact";
|
|
2
2
|
import { useState, useRef, useEffect, useContext } from "preact/hooks";
|
|
3
3
|
import { jsx } from "preact/jsx-runtime";
|
|
4
4
|
import { PluginRegistry, arePropsEqual } from "@embedpdf/core";
|
|
@@ -7,7 +7,7 @@ const PDFContext = createContext({
|
|
|
7
7
|
isInitializing: true,
|
|
8
8
|
pluginsReady: false
|
|
9
9
|
});
|
|
10
|
-
function EmbedPDF({ engine, onInitialized, plugins, children }) {
|
|
10
|
+
function EmbedPDF({ engine, logger, onInitialized, plugins, children }) {
|
|
11
11
|
const [registry, setRegistry] = useState(null);
|
|
12
12
|
const [isInitializing, setIsInitializing] = useState(true);
|
|
13
13
|
const [pluginsReady, setPluginsReady] = useState(false);
|
|
@@ -16,7 +16,7 @@ function EmbedPDF({ engine, onInitialized, plugins, children }) {
|
|
|
16
16
|
initRef.current = onInitialized;
|
|
17
17
|
}, [onInitialized]);
|
|
18
18
|
useEffect(() => {
|
|
19
|
-
const pdfViewer = new PluginRegistry(engine);
|
|
19
|
+
const pdfViewer = new PluginRegistry(engine, { logger });
|
|
20
20
|
pdfViewer.registerPluginBatch(plugins);
|
|
21
21
|
const initialize = async () => {
|
|
22
22
|
var _a;
|
|
@@ -46,6 +46,63 @@ function EmbedPDF({ engine, onInitialized, plugins, children }) {
|
|
|
46
46
|
}, [engine, plugins]);
|
|
47
47
|
return /* @__PURE__ */ jsx(PDFContext.Provider, { value: { registry, isInitializing, pluginsReady }, children: typeof children === "function" ? children({ registry, isInitializing, pluginsReady }) : children });
|
|
48
48
|
}
|
|
49
|
+
function getCounterRotation(rect, rotation) {
|
|
50
|
+
const { width: w, height: h } = rect.size;
|
|
51
|
+
switch (rotation % 4) {
|
|
52
|
+
case 1:
|
|
53
|
+
return {
|
|
54
|
+
matrix: `matrix(0, -1, 1, 0, 0, ${h})`,
|
|
55
|
+
width: h,
|
|
56
|
+
height: w
|
|
57
|
+
};
|
|
58
|
+
case 2:
|
|
59
|
+
return {
|
|
60
|
+
matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,
|
|
61
|
+
width: w,
|
|
62
|
+
height: h
|
|
63
|
+
};
|
|
64
|
+
case 3:
|
|
65
|
+
return {
|
|
66
|
+
matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,
|
|
67
|
+
width: h,
|
|
68
|
+
height: w
|
|
69
|
+
};
|
|
70
|
+
default:
|
|
71
|
+
return {
|
|
72
|
+
matrix: `matrix(1, 0, 0, 1, 0, 0)`,
|
|
73
|
+
width: w,
|
|
74
|
+
height: h
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function CounterRotate({ children, ...props }) {
|
|
79
|
+
const { rect, rotation } = props;
|
|
80
|
+
const { matrix, width, height } = getCounterRotation(rect, rotation);
|
|
81
|
+
const menuWrapperStyle = {
|
|
82
|
+
position: "absolute",
|
|
83
|
+
left: rect.origin.x,
|
|
84
|
+
top: rect.origin.y,
|
|
85
|
+
transform: matrix,
|
|
86
|
+
transformOrigin: "0 0",
|
|
87
|
+
width,
|
|
88
|
+
height,
|
|
89
|
+
pointerEvents: "none",
|
|
90
|
+
zIndex: 3
|
|
91
|
+
};
|
|
92
|
+
const menuWrapperProps = {
|
|
93
|
+
style: menuWrapperStyle,
|
|
94
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
95
|
+
onTouchStart: (e) => e.stopPropagation()
|
|
96
|
+
};
|
|
97
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children({
|
|
98
|
+
menuWrapperProps,
|
|
99
|
+
matrix,
|
|
100
|
+
rect: {
|
|
101
|
+
origin: { x: rect.origin.x, y: rect.origin.y },
|
|
102
|
+
size: { width, height }
|
|
103
|
+
}
|
|
104
|
+
}) });
|
|
105
|
+
}
|
|
49
106
|
function useRegistry() {
|
|
50
107
|
const contextValue = useContext(PDFContext);
|
|
51
108
|
if (contextValue === void 0) {
|
|
@@ -128,8 +185,10 @@ function useCoreState() {
|
|
|
128
185
|
return coreState;
|
|
129
186
|
}
|
|
130
187
|
export {
|
|
188
|
+
CounterRotate,
|
|
131
189
|
EmbedPDF,
|
|
132
190
|
PDFContext,
|
|
191
|
+
getCounterRotation,
|
|
133
192
|
useCapability,
|
|
134
193
|
useCoreState,
|
|
135
194
|
usePlugin,
|
package/dist/preact/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/context.ts","../../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"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n","import { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/context.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/components/counter-rotate-container.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"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n","import { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n logger?: Logger;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, logger, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine, { logger });\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\n </PDFContext.Provider>\n );\n}\n","import { Rect, Rotation } from '@embedpdf/models';\nimport { ReactNode, CSSProperties, PointerEvent, Fragment, TouchEvent } from '@framework';\n\ninterface CounterRotateProps {\n rect: Rect;\n rotation: Rotation;\n}\n\ninterface CounterTransformResult {\n matrix: string; // CSS matrix(a,b,c,d,e,f)\n width: number; // new width\n height: number; // new height\n}\n\n/**\n * Given an already-placed rect (left/top/width/height in px) and the page rotation,\n * return the counter-rotation matrix + adjusted width/height.\n *\n * transform-origin is expected to be \"0 0\".\n * left/top DO NOT change, apply them as-is.\n */\nexport function getCounterRotation(rect: Rect, rotation: Rotation): CounterTransformResult {\n const { width: w, height: h } = rect.size;\n\n switch (rotation % 4) {\n case 1: // 90° cw → need matrix(0,-1,1,0,0,h) and swap w/h\n return {\n matrix: `matrix(0, -1, 1, 0, 0, ${h})`,\n width: h,\n height: w,\n };\n\n case 2: // 180° → matrix(-1,0,0,-1,w,h), width/height unchanged\n return {\n matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,\n width: w,\n height: h,\n };\n\n case 3: // 270° cw → matrix(0,1,-1,0,w,0), swap w/h\n return {\n matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,\n width: h,\n height: w,\n };\n\n default:\n return {\n matrix: `matrix(1, 0, 0, 1, 0, 0)`,\n width: w,\n height: h,\n };\n }\n}\n\nexport interface MenuWrapperProps {\n style: CSSProperties;\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => void;\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => void;\n}\n\ninterface CounterRotateComponentProps extends CounterRotateProps {\n children: (props: {\n matrix: string;\n rect: Rect;\n menuWrapperProps: MenuWrapperProps;\n }) => ReactNode;\n}\n\nexport function CounterRotate({ children, ...props }: CounterRotateComponentProps) {\n const { rect, rotation } = props;\n const { matrix, width, height } = getCounterRotation(rect, rotation);\n\n const menuWrapperStyle: CSSProperties = {\n position: 'absolute',\n left: rect.origin.x,\n top: rect.origin.y,\n transform: matrix,\n transformOrigin: '0 0',\n width: width,\n height: height,\n pointerEvents: 'none',\n zIndex: 3,\n };\n\n const menuWrapperProps = {\n style: menuWrapperStyle,\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => e.stopPropagation(),\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => e.stopPropagation(),\n };\n\n return (\n <Fragment>\n {children({\n menuWrapperProps,\n matrix,\n rect: {\n origin: { x: rect.origin.x, y: rect.origin.y },\n size: { width: width, height: height },\n },\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 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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\n}\n"],"names":[],"mappings":"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"}
|
package/dist/react/adapter.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { Fragment, useEffect, useRef, useState, useCallback, useMemo, JSX, createContext, useContext, } from 'react';
|
|
2
|
-
export type { ReactNode, HTMLAttributes, CSSProperties, MouseEvent, PointerEvent } from 'react';
|
|
2
|
+
export type { ReactNode, HTMLAttributes, CSSProperties, MouseEvent, PointerEvent, TouchEvent, } from 'react';
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),t=require("react/jsx-runtime"),r=require("@embedpdf/core"),i=e.createContext({registry:null,isInitializing:!0,pluginsReady:!1});function n(){const t=e.useContext(i);if(void 0===t)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:r,isInitializing:n}=t;if(n)return t;if(null===r)throw new Error("PDF registry failed to initialize properly");return t}function s(e){const{registry:t}=
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react"),t=require("react/jsx-runtime"),r=require("@embedpdf/core"),i=e.createContext({registry:null,isInitializing:!0,pluginsReady:!1});function n(e,t){const{width:r,height:i}=e.size;switch(t%4){case 1:return{matrix:`matrix(0, -1, 1, 0, 0, ${i})`,width:i,height:r};case 2:return{matrix:`matrix(-1, 0, 0, -1, ${r}, ${i})`,width:r,height:i};case 3:return{matrix:`matrix(0, 1, -1, 0, ${r}, 0)`,width:i,height:r};default:return{matrix:"matrix(1, 0, 0, 1, 0, 0)",width:r,height:i}}}function o(){const t=e.useContext(i);if(void 0===t)throw new Error("useCapability must be used within a PDFContext.Provider");const{registry:r,isInitializing:n}=t;if(n)return t;if(null===r)throw new Error("PDF registry failed to initialize properly");return t}function s(e){const{registry:t}=o();if(null===t)return{plugin:null,isLoading:!0,ready:new Promise((()=>{}))};const r=t.getPlugin(e);if(!r)throw new Error(`Plugin ${e} not found`);return{plugin:r,isLoading:!1,ready:r.ready()}}exports.CounterRotate=function({children:r,...i}){const{rect:o,rotation:s}=i,{matrix:u,width:a,height:g}=n(o,s),l={style:{position:"absolute",left:o.origin.x,top:o.origin.y,transform:u,transformOrigin:"0 0",width:a,height:g,pointerEvents:"none",zIndex:3},onPointerDown:e=>e.stopPropagation(),onTouchStart:e=>e.stopPropagation()};return t.jsx(e.Fragment,{children:r({menuWrapperProps:l,matrix:u,rect:{origin:{x:o.origin.x,y:o.origin.y},size:{width:a,height:g}}})})},exports.EmbedPDF=function({engine:n,logger:o,onInitialized:s,plugins:u,children:a}){const[g,l]=e.useState(null),[c,d]=e.useState(!0),[p,h]=e.useState(!1),f=e.useRef(s);return e.useEffect((()=>{f.current=s}),[s]),e.useEffect((()=>{const e=new r.PluginRegistry(n,{logger:o});e.registerPluginBatch(u);return(async()=>{var t;await e.initialize(),e.isDestroyed()||(await(null==(t=f.current)?void 0:t.call(f,e)),e.isDestroyed()||(e.pluginsReady().then((()=>{e.isDestroyed()||h(!0)})),l(e),d(!1)))})().catch(console.error),()=>{e.destroy(),l(null),d(!0),h(!1)}}),[n,u]),t.jsx(i.Provider,{value:{registry:g,isInitializing:c,pluginsReady:p},children:"function"==typeof a?a({registry:g,isInitializing:c,pluginsReady:p}):a})},exports.PDFContext=i,exports.getCounterRotation=n,exports.useCapability=function(e){const{plugin:t,isLoading:r,ready:i}=s(e);if(!t)return{provides:null,isLoading:r,ready:i};if(!t.provides)throw new Error(`Plugin ${e} does not provide a capability`);return{provides:t.provides(),isLoading:r,ready:i}},exports.useCoreState=function(){const{registry:t}=o(),[i,n]=e.useState(null);return e.useEffect((()=>{if(!t)return;const e=t.getStore();n(e.getState().core);const i=e.subscribe(((t,i,o)=>{e.isCoreAction(t)&&!r.arePropsEqual(i.core,o.core)&&n(i.core)}));return()=>i()}),[t]),i},exports.usePlugin=s,exports.useRegistry=o,exports.useStoreState=function(){const{registry:t}=o(),[r,i]=e.useState(null);return e.useEffect((()=>{if(!t)return;i(t.getStore().getState());const e=t.getStore().subscribe(((e,t)=>{i(t)}));return()=>e()}),[t]),r};
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-core-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\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 { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\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","isInitializing","pluginsReady","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","engine","onInitialized","plugins","children","setRegistry","useState","setIsInitializing","setPluginsReady","initRef","useRef","jsx","useEffect","current","pdfViewer","PluginRegistry","registerPluginBatch","async","initialize","isDestroyed","_a","call","then","catch","console","error","destroy","Provider","value","provides","coreState","setCoreState","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","arePropsEqual","state","setState","_action"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/shared/context.ts","../../src/shared/components/counter-rotate-container.tsx","../../src/shared/hooks/use-registry.ts","../../src/shared/hooks/use-plugin.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/hooks/use-capability.ts","../../src/shared/hooks/use-core-state.ts","../../src/shared/hooks/use-store-state.ts"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n","import { Rect, Rotation } from '@embedpdf/models';\nimport { ReactNode, CSSProperties, PointerEvent, Fragment, TouchEvent } from '@framework';\n\ninterface CounterRotateProps {\n rect: Rect;\n rotation: Rotation;\n}\n\ninterface CounterTransformResult {\n matrix: string; // CSS matrix(a,b,c,d,e,f)\n width: number; // new width\n height: number; // new height\n}\n\n/**\n * Given an already-placed rect (left/top/width/height in px) and the page rotation,\n * return the counter-rotation matrix + adjusted width/height.\n *\n * transform-origin is expected to be \"0 0\".\n * left/top DO NOT change, apply them as-is.\n */\nexport function getCounterRotation(rect: Rect, rotation: Rotation): CounterTransformResult {\n const { width: w, height: h } = rect.size;\n\n switch (rotation % 4) {\n case 1: // 90° cw → need matrix(0,-1,1,0,0,h) and swap w/h\n return {\n matrix: `matrix(0, -1, 1, 0, 0, ${h})`,\n width: h,\n height: w,\n };\n\n case 2: // 180° → matrix(-1,0,0,-1,w,h), width/height unchanged\n return {\n matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,\n width: w,\n height: h,\n };\n\n case 3: // 270° cw → matrix(0,1,-1,0,w,0), swap w/h\n return {\n matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,\n width: h,\n height: w,\n };\n\n default:\n return {\n matrix: `matrix(1, 0, 0, 1, 0, 0)`,\n width: w,\n height: h,\n };\n }\n}\n\nexport interface MenuWrapperProps {\n style: CSSProperties;\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => void;\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => void;\n}\n\ninterface CounterRotateComponentProps extends CounterRotateProps {\n children: (props: {\n matrix: string;\n rect: Rect;\n menuWrapperProps: MenuWrapperProps;\n }) => ReactNode;\n}\n\nexport function CounterRotate({ children, ...props }: CounterRotateComponentProps) {\n const { rect, rotation } = props;\n const { matrix, width, height } = getCounterRotation(rect, rotation);\n\n const menuWrapperStyle: CSSProperties = {\n position: 'absolute',\n left: rect.origin.x,\n top: rect.origin.y,\n transform: matrix,\n transformOrigin: '0 0',\n width: width,\n height: height,\n pointerEvents: 'none',\n zIndex: 3,\n };\n\n const menuWrapperProps = {\n style: menuWrapperStyle,\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => e.stopPropagation(),\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => e.stopPropagation(),\n };\n\n return (\n <Fragment>\n {children({\n menuWrapperProps,\n matrix,\n rect: {\n origin: { x: rect.origin.x, y: rect.origin.y },\n size: { width: width, height: height },\n },\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 { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n logger?: Logger;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, logger, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine, { logger });\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\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","isInitializing","pluginsReady","getCounterRotation","rect","rotation","width","w","height","h","size","matrix","useRegistry","contextValue","useContext","Error","usePlugin","pluginId","plugin","isLoading","ready","Promise","getPlugin","children","props","menuWrapperProps","style","position","left","origin","x","top","y","transform","transformOrigin","pointerEvents","zIndex","onPointerDown","e","stopPropagation","onTouchStart","Fragment","engine","logger","onInitialized","plugins","setRegistry","useState","setIsInitializing","setPluginsReady","initRef","useRef","jsx","useEffect","current","pdfViewer","PluginRegistry","registerPluginBatch","async","initialize","isDestroyed","_a","call","then","catch","console","error","destroy","Provider","value","provides","coreState","setCoreState","store","getStore","getState","core","unsubscribe","subscribe","action","newState","oldState","isCoreAction","arePropsEqual","state","setState","_action"],"mappings":"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"}
|
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createContext, useState, useRef, useEffect, useContext } from "react";
|
|
1
|
+
import { createContext, useState, useRef, useEffect, Fragment, useContext } from "react";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { PluginRegistry, arePropsEqual } from "@embedpdf/core";
|
|
4
4
|
const PDFContext = createContext({
|
|
@@ -6,7 +6,7 @@ const PDFContext = createContext({
|
|
|
6
6
|
isInitializing: true,
|
|
7
7
|
pluginsReady: false
|
|
8
8
|
});
|
|
9
|
-
function EmbedPDF({ engine, onInitialized, plugins, children }) {
|
|
9
|
+
function EmbedPDF({ engine, logger, onInitialized, plugins, children }) {
|
|
10
10
|
const [registry, setRegistry] = useState(null);
|
|
11
11
|
const [isInitializing, setIsInitializing] = useState(true);
|
|
12
12
|
const [pluginsReady, setPluginsReady] = useState(false);
|
|
@@ -15,7 +15,7 @@ function EmbedPDF({ engine, onInitialized, plugins, children }) {
|
|
|
15
15
|
initRef.current = onInitialized;
|
|
16
16
|
}, [onInitialized]);
|
|
17
17
|
useEffect(() => {
|
|
18
|
-
const pdfViewer = new PluginRegistry(engine);
|
|
18
|
+
const pdfViewer = new PluginRegistry(engine, { logger });
|
|
19
19
|
pdfViewer.registerPluginBatch(plugins);
|
|
20
20
|
const initialize = async () => {
|
|
21
21
|
var _a;
|
|
@@ -45,6 +45,63 @@ function EmbedPDF({ engine, onInitialized, plugins, children }) {
|
|
|
45
45
|
}, [engine, plugins]);
|
|
46
46
|
return /* @__PURE__ */ jsx(PDFContext.Provider, { value: { registry, isInitializing, pluginsReady }, children: typeof children === "function" ? children({ registry, isInitializing, pluginsReady }) : children });
|
|
47
47
|
}
|
|
48
|
+
function getCounterRotation(rect, rotation) {
|
|
49
|
+
const { width: w, height: h } = rect.size;
|
|
50
|
+
switch (rotation % 4) {
|
|
51
|
+
case 1:
|
|
52
|
+
return {
|
|
53
|
+
matrix: `matrix(0, -1, 1, 0, 0, ${h})`,
|
|
54
|
+
width: h,
|
|
55
|
+
height: w
|
|
56
|
+
};
|
|
57
|
+
case 2:
|
|
58
|
+
return {
|
|
59
|
+
matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,
|
|
60
|
+
width: w,
|
|
61
|
+
height: h
|
|
62
|
+
};
|
|
63
|
+
case 3:
|
|
64
|
+
return {
|
|
65
|
+
matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,
|
|
66
|
+
width: h,
|
|
67
|
+
height: w
|
|
68
|
+
};
|
|
69
|
+
default:
|
|
70
|
+
return {
|
|
71
|
+
matrix: `matrix(1, 0, 0, 1, 0, 0)`,
|
|
72
|
+
width: w,
|
|
73
|
+
height: h
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function CounterRotate({ children, ...props }) {
|
|
78
|
+
const { rect, rotation } = props;
|
|
79
|
+
const { matrix, width, height } = getCounterRotation(rect, rotation);
|
|
80
|
+
const menuWrapperStyle = {
|
|
81
|
+
position: "absolute",
|
|
82
|
+
left: rect.origin.x,
|
|
83
|
+
top: rect.origin.y,
|
|
84
|
+
transform: matrix,
|
|
85
|
+
transformOrigin: "0 0",
|
|
86
|
+
width,
|
|
87
|
+
height,
|
|
88
|
+
pointerEvents: "none",
|
|
89
|
+
zIndex: 3
|
|
90
|
+
};
|
|
91
|
+
const menuWrapperProps = {
|
|
92
|
+
style: menuWrapperStyle,
|
|
93
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
94
|
+
onTouchStart: (e) => e.stopPropagation()
|
|
95
|
+
};
|
|
96
|
+
return /* @__PURE__ */ jsx(Fragment, { children: children({
|
|
97
|
+
menuWrapperProps,
|
|
98
|
+
matrix,
|
|
99
|
+
rect: {
|
|
100
|
+
origin: { x: rect.origin.x, y: rect.origin.y },
|
|
101
|
+
size: { width, height }
|
|
102
|
+
}
|
|
103
|
+
}) });
|
|
104
|
+
}
|
|
48
105
|
function useRegistry() {
|
|
49
106
|
const contextValue = useContext(PDFContext);
|
|
50
107
|
if (contextValue === void 0) {
|
|
@@ -127,8 +184,10 @@ function useCoreState() {
|
|
|
127
184
|
return coreState;
|
|
128
185
|
}
|
|
129
186
|
export {
|
|
187
|
+
CounterRotate,
|
|
130
188
|
EmbedPDF,
|
|
131
189
|
PDFContext,
|
|
190
|
+
getCounterRotation,
|
|
132
191
|
useCapability,
|
|
133
192
|
useCoreState,
|
|
134
193
|
usePlugin,
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/shared/context.ts","../../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"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n","import { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine);\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/shared/context.ts","../../src/shared/components/embed-pdf.tsx","../../src/shared/components/counter-rotate-container.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"],"sourcesContent":["import { createContext } from '@framework';\nimport type { PluginRegistry } from '@embedpdf/core';\n\nexport interface PDFContextState {\n registry: PluginRegistry | null;\n isInitializing: boolean;\n pluginsReady: boolean;\n}\n\nexport const PDFContext = createContext<PDFContextState>({\n registry: null,\n isInitializing: true,\n pluginsReady: false,\n});\n","import { useState, useEffect, useRef, ReactNode } from '@framework';\nimport { Logger, PdfEngine } from '@embedpdf/models';\nimport { PluginRegistry } from '@embedpdf/core';\nimport type { IPlugin, PluginBatchRegistration } from '@embedpdf/core';\n\nimport { PDFContext, PDFContextState } from '../context';\n\ninterface EmbedPDFProps {\n engine: PdfEngine;\n logger?: Logger;\n onInitialized?: (registry: PluginRegistry) => Promise<void>;\n plugins: PluginBatchRegistration<IPlugin<any>, any>[];\n children: ReactNode | ((state: PDFContextState) => ReactNode);\n}\n\nexport function EmbedPDF({ engine, logger, onInitialized, plugins, children }: EmbedPDFProps) {\n const [registry, setRegistry] = useState<PluginRegistry | 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; // update without triggering re-runs\n }, [onInitialized]);\n\n useEffect(() => {\n const pdfViewer = new PluginRegistry(engine, { logger });\n pdfViewer.registerPluginBatch(plugins);\n\n const initialize = async () => {\n await pdfViewer.initialize();\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\n return;\n }\n\n /* always call the *latest* callback */\n await initRef.current?.(pdfViewer);\n\n // if the registry is destroyed, don't do anything\n if (pdfViewer.isDestroyed()) {\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\n initialize().catch(console.error);\n\n return () => {\n pdfViewer.destroy();\n setRegistry(null);\n setIsInitializing(true);\n setPluginsReady(false);\n };\n }, [engine, plugins]);\n\n return (\n <PDFContext.Provider value={{ registry, isInitializing, pluginsReady }}>\n {typeof children === 'function'\n ? children({ registry, isInitializing, pluginsReady })\n : children}\n </PDFContext.Provider>\n );\n}\n","import { Rect, Rotation } from '@embedpdf/models';\nimport { ReactNode, CSSProperties, PointerEvent, Fragment, TouchEvent } from '@framework';\n\ninterface CounterRotateProps {\n rect: Rect;\n rotation: Rotation;\n}\n\ninterface CounterTransformResult {\n matrix: string; // CSS matrix(a,b,c,d,e,f)\n width: number; // new width\n height: number; // new height\n}\n\n/**\n * Given an already-placed rect (left/top/width/height in px) and the page rotation,\n * return the counter-rotation matrix + adjusted width/height.\n *\n * transform-origin is expected to be \"0 0\".\n * left/top DO NOT change, apply them as-is.\n */\nexport function getCounterRotation(rect: Rect, rotation: Rotation): CounterTransformResult {\n const { width: w, height: h } = rect.size;\n\n switch (rotation % 4) {\n case 1: // 90° cw → need matrix(0,-1,1,0,0,h) and swap w/h\n return {\n matrix: `matrix(0, -1, 1, 0, 0, ${h})`,\n width: h,\n height: w,\n };\n\n case 2: // 180° → matrix(-1,0,0,-1,w,h), width/height unchanged\n return {\n matrix: `matrix(-1, 0, 0, -1, ${w}, ${h})`,\n width: w,\n height: h,\n };\n\n case 3: // 270° cw → matrix(0,1,-1,0,w,0), swap w/h\n return {\n matrix: `matrix(0, 1, -1, 0, ${w}, 0)`,\n width: h,\n height: w,\n };\n\n default:\n return {\n matrix: `matrix(1, 0, 0, 1, 0, 0)`,\n width: w,\n height: h,\n };\n }\n}\n\nexport interface MenuWrapperProps {\n style: CSSProperties;\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => void;\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => void;\n}\n\ninterface CounterRotateComponentProps extends CounterRotateProps {\n children: (props: {\n matrix: string;\n rect: Rect;\n menuWrapperProps: MenuWrapperProps;\n }) => ReactNode;\n}\n\nexport function CounterRotate({ children, ...props }: CounterRotateComponentProps) {\n const { rect, rotation } = props;\n const { matrix, width, height } = getCounterRotation(rect, rotation);\n\n const menuWrapperStyle: CSSProperties = {\n position: 'absolute',\n left: rect.origin.x,\n top: rect.origin.y,\n transform: matrix,\n transformOrigin: '0 0',\n width: width,\n height: height,\n pointerEvents: 'none',\n zIndex: 3,\n };\n\n const menuWrapperProps = {\n style: menuWrapperStyle,\n onPointerDown: (e: PointerEvent<HTMLDivElement>) => e.stopPropagation(),\n onTouchStart: (e: TouchEvent<HTMLDivElement>) => e.stopPropagation(),\n };\n\n return (\n <Fragment>\n {children({\n menuWrapperProps,\n matrix,\n rect: {\n origin: { x: rect.origin.x, y: rect.origin.y },\n size: { width: width, height: height },\n },\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 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 { useState, useEffect } from '@framework';\nimport { CoreState, arePropsEqual } from '@embedpdf/core';\nimport { useRegistry } from './use-registry';\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(): CoreState | null {\n const { registry } = useRegistry();\n const [coreState, setCoreState] = useState<CoreState | null>(null);\n\n useEffect(() => {\n if (!registry) return;\n\n const store = registry.getStore();\n\n // Get initial core state\n setCoreState(store.getState().core);\n\n // Create a single subscription that handles all core actions\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) && !arePropsEqual(newState.core, oldState.core)) {\n setCoreState(newState.core);\n }\n });\n\n return () => unsubscribe();\n }, [registry]);\n\n return coreState;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Rect, Rotation } from '@embedpdf/models';
|
|
2
|
+
import { ReactNode, CSSProperties, PointerEvent, TouchEvent } from '../../preact/adapter.ts';
|
|
3
|
+
interface CounterRotateProps {
|
|
4
|
+
rect: Rect;
|
|
5
|
+
rotation: Rotation;
|
|
6
|
+
}
|
|
7
|
+
interface CounterTransformResult {
|
|
8
|
+
matrix: string;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Given an already-placed rect (left/top/width/height in px) and the page rotation,
|
|
14
|
+
* return the counter-rotation matrix + adjusted width/height.
|
|
15
|
+
*
|
|
16
|
+
* transform-origin is expected to be "0 0".
|
|
17
|
+
* left/top DO NOT change, apply them as-is.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getCounterRotation(rect: Rect, rotation: Rotation): CounterTransformResult;
|
|
20
|
+
export interface MenuWrapperProps {
|
|
21
|
+
style: CSSProperties;
|
|
22
|
+
onPointerDown: (e: PointerEvent<HTMLDivElement>) => void;
|
|
23
|
+
onTouchStart: (e: TouchEvent<HTMLDivElement>) => void;
|
|
24
|
+
}
|
|
25
|
+
interface CounterRotateComponentProps extends CounterRotateProps {
|
|
26
|
+
children: (props: {
|
|
27
|
+
matrix: string;
|
|
28
|
+
rect: Rect;
|
|
29
|
+
menuWrapperProps: MenuWrapperProps;
|
|
30
|
+
}) => ReactNode;
|
|
31
|
+
}
|
|
32
|
+
export declare function CounterRotate({ children, ...props }: CounterRotateComponentProps): import("preact").JSX.Element;
|
|
33
|
+
export {};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ReactNode } from '../../preact/adapter.ts';
|
|
2
|
-
import { PdfEngine } from '@embedpdf/models';
|
|
2
|
+
import { Logger, PdfEngine } from '@embedpdf/models';
|
|
3
3
|
import { PluginRegistry, IPlugin, PluginBatchRegistration } from '../../lib/index.ts';
|
|
4
4
|
import { PDFContextState } from '../context';
|
|
5
5
|
interface EmbedPDFProps {
|
|
6
6
|
engine: PdfEngine;
|
|
7
|
+
logger?: Logger;
|
|
7
8
|
onInitialized?: (registry: PluginRegistry) => Promise<void>;
|
|
8
9
|
plugins: PluginBatchRegistration<IPlugin<any>, any>[];
|
|
9
10
|
children: ReactNode | ((state: PDFContextState) => ReactNode);
|
|
10
11
|
}
|
|
11
|
-
export declare function EmbedPDF({ engine, onInitialized, plugins, children }: EmbedPDFProps): import("preact").JSX.Element;
|
|
12
|
+
export declare function EmbedPDF({ engine, logger, onInitialized, plugins, children }: EmbedPDFProps): import("preact").JSX.Element;
|
|
12
13
|
export {};
|