@embedpdf/plugin-rotate 1.5.0 → 2.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@embedpdf/core"),e="rotate",o={id:e,name:"Rotate Plugin",version:"1.0.0",provides:["rotate"],requires:["loader"],optional:["spread"],defaultConfig:{enabled:!0}};const r=class extends t.BasePlugin{constructor(e,o,r){super(e,o),this.rotate$=t.createBehaviorEmitter(),this.resetReady();const a=r.defaultRotation??this.coreState.core.rotation;this.setRotation(a),this.markReady()}async initialize(t){}setRotation(e){if(!this.coreState.core.pages)throw new Error("Pages not loaded");this.rotate$.emit(e),this.dispatchCoreAction(t.setRotation(e))}rotateForward(){const t=(this.coreState.core.rotation+1)%4;this.setRotation(t)}rotateBackward(){const t=(this.coreState.core.rotation+3)%4;this.setRotation(t)}buildCapability(){return{onRotateChange:this.rotate$.on,setRotation:t=>this.setRotation(t),getRotation:()=>this.coreState.core.rotation,rotateForward:()=>this.rotateForward(),rotateBackward:()=>this.rotateBackward()}}getMatrixAsString(t={w:0,h:0}){return function(t,e,o){const[r,a,i,s,n,c]=function(t,e,o){let r=1,a=0,i=0,s=1,n=0,c=0;switch(t){case 1:r=0,a=1,i=-1,s=0,n=o;break;case 2:r=-1,a=0,i=0,s=-1,n=e,c=o;break;case 3:r=0,a=-1,i=1,s=0,c=e}return[r,a,i,s,n,c]}(t,e,o);return`matrix(${r},${a},${i},${s},${n},${c})`}(this.coreState.core.rotation,t.w,t.h)}async destroy(){this.rotate$.clear(),super.destroy()}};r.id="rotate";let a=r;const i={manifest:o,create:(t,o)=>new a(e,t,o),reducer:()=>{},initialState:{}};exports.ROTATE_PLUGIN_ID=e,exports.RotatePlugin=a,exports.RotatePluginPackage=i,exports.manifest=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("@embedpdf/core"),o="rotate",e={id:o,name:"Rotate Plugin",version:"1.0.0",provides:["rotate"],requires:[],optional:[],defaultConfig:{enabled:!0}};function n(t,o,e){let n=1,a=0,i=0,r=1,s=0,c=0;switch(t){case 1:n=0,a=1,i=-1,r=0,s=e;break;case 2:n=-1,a=0,i=0,r=-1,s=o,c=e;break;case 3:n=0,a=-1,i=1,r=0,c=o}return[n,a,i,r,s,c]}function a(t,o,e){const[a,i,r,s,c,u]=n(t,o,e);return`matrix(${a},${i},${r},${s},${c},${u})`}function i(t){return(t+1)%4}function r(t){return(t+3)%4}const s="ROTATE/INIT_STATE",c="ROTATE/CLEANUP_STATE",u="ROTATE/SET_ACTIVE_DOCUMENT",d="ROTATE/SET_ROTATION";function m(t,o){return{type:s,payload:{documentId:t,state:o}}}function l(t){return{type:c,payload:t}}function h(t,o){return{type:d,payload:{documentId:t,rotation:o}}}const R=class extends t.BasePlugin{constructor(o,e,n){super(o,e),this.rotate$=t.createBehaviorEmitter(),this.defaultRotation=n.defaultRotation??0}onDocumentLoadingStarted(o){const e={rotation:this.defaultRotation};this.dispatch(m(o,e)),this.dispatchCoreAction(t.setRotation(this.defaultRotation,o)),this.logger.debug("RotatePlugin","DocumentOpened",`Initialized rotation state for document: ${o}`)}onDocumentClosed(t){this.dispatch(l(t)),this.logger.debug("RotatePlugin","DocumentClosed",`Cleaned up rotation state for document: ${t}`)}buildCapability(){return{setRotation:t=>this.setRotationForDocument(t),getRotation:()=>this.getRotationForDocument(),rotateForward:()=>this.rotateForward(),rotateBackward:()=>this.rotateBackward(),forDocument:t=>this.createRotateScope(t),onRotateChange:this.rotate$.on}}createRotateScope(t){return{setRotation:o=>this.setRotationForDocument(o,t),getRotation:()=>this.getRotationForDocument(t),rotateForward:()=>this.rotateForward(t),rotateBackward:()=>this.rotateBackward(t),onRotateChange:o=>this.rotate$.on(e=>{e.documentId===t&&o(e.rotation)})}}getDocumentState(t){const o=t??this.getActiveDocumentId();return this.state.documents[o]??null}getDocumentStateOrThrow(t){const o=this.getDocumentState(t);if(!o)throw new Error(`Rotation state not found for document: ${t??"active"}`);return o}setRotationForDocument(o,e){const n=e??this.getActiveDocumentId(),a=this.coreState.core.documents[n];if(!(null==a?void 0:a.document))throw new Error(`Document ${n} not loaded`);this.dispatch(h(n,o)),this.dispatchCoreAction(t.setRotation(o,n)),this.rotate$.emit({documentId:n,rotation:o})}getRotationForDocument(t){return this.getDocumentStateOrThrow(t).rotation}rotateForward(t){const o=t??this.getActiveDocumentId(),e=i(this.getRotationForDocument(o));this.setRotationForDocument(e,o)}rotateBackward(t){const o=t??this.getActiveDocumentId(),e=r(this.getRotationForDocument(o));this.setRotationForDocument(e,o)}getMatrixAsString(t){return a(t.rotation,t.width,t.height)}onStoreUpdated(t,o){for(const e in o.documents){const n=t.documents[e],a=o.documents[e];(null==n?void 0:n.rotation)!==a.rotation&&this.logger.debug("RotatePlugin","RotationChanged",`Rotation changed for document ${e}: ${(null==n?void 0:n.rotation)??0} -> ${a.rotation}`)}}async initialize(t){this.logger.info("RotatePlugin","Initialize","Rotate plugin initialized")}async destroy(){this.rotate$.clear(),super.destroy()}};R.id="rotate";let g=R;const p={documents:{},activeDocumentId:null},T=(t=p,o)=>{switch(o.type){case s:{const{documentId:e,state:n}=o.payload;return{...t,documents:{...t.documents,[e]:n},activeDocumentId:t.activeDocumentId??e}}case c:{const e=o.payload,{[e]:n,...a}=t.documents;return{...t,documents:a,activeDocumentId:t.activeDocumentId===e?null:t.activeDocumentId}}case u:return{...t,activeDocumentId:o.payload};case d:{const{documentId:e,rotation:n}=o.payload,a=t.documents[e];return a?{...t,documents:{...t.documents,[e]:{...a,rotation:n}}}:t}default:return t}},D={manifest:e,create:(t,e)=>new g(o,t,e),reducer:T,initialState:p};exports.CLEANUP_ROTATE_STATE=c,exports.INIT_ROTATE_STATE=s,exports.ROTATE_PLUGIN_ID=o,exports.RotatePlugin=g,exports.RotatePluginPackage=D,exports.SET_ACTIVE_ROTATE_DOCUMENT=u,exports.SET_ROTATION=d,exports.cleanupRotateState=l,exports.getNextRotation=i,exports.getPreviousRotation=r,exports.getRotationMatrix=n,exports.getRotationMatrixString=a,exports.initRotateState=m,exports.initialDocumentState={rotation:0},exports.initialState=p,exports.manifest=e,exports.rotateReducer=T,exports.setActiveRotateDocument=function(t){return{type:u,payload:t}},exports.setRotation=h;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/rotate-plugin.ts","../src/lib/utils.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { RotatePluginConfig } from './types';\n\nexport const ROTATE_PLUGIN_ID = 'rotate';\n\nexport const manifest: PluginManifest<RotatePluginConfig> = {\n id: ROTATE_PLUGIN_ID,\n name: 'Rotate Plugin',\n version: '1.0.0',\n provides: ['rotate'],\n requires: ['loader'],\n optional: ['spread'],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { BasePlugin, createBehaviorEmitter, PluginRegistry, setRotation } from '@embedpdf/core';\nimport { Rotation } from '@embedpdf/models';\nimport { GetMatrixOptions, RotateCapability, RotatePluginConfig } from './types';\nimport { getNextRotation, getPreviousRotation, getRotationMatrixString } from './utils';\n\nexport class RotatePlugin extends BasePlugin<RotatePluginConfig, RotateCapability> {\n static readonly id = 'rotate' as const;\n private readonly rotate$ = createBehaviorEmitter<Rotation>();\n\n constructor(id: string, registry: PluginRegistry, cfg: RotatePluginConfig) {\n super(id, registry);\n this.resetReady();\n const rotation = cfg.defaultRotation ?? this.coreState.core.rotation;\n this.setRotation(rotation);\n this.markReady();\n }\n\n async initialize(_config: RotatePluginConfig): Promise<void> {}\n\n private setRotation(rotation: Rotation): void {\n const pages = this.coreState.core.pages;\n if (!pages) {\n throw new Error('Pages not loaded');\n }\n\n this.rotate$.emit(rotation);\n this.dispatchCoreAction(setRotation(rotation));\n }\n\n private rotateForward(): void {\n const rotation = getNextRotation(this.coreState.core.rotation);\n this.setRotation(rotation);\n }\n\n private rotateBackward(): void {\n const rotation = getPreviousRotation(this.coreState.core.rotation);\n this.setRotation(rotation);\n }\n\n protected buildCapability(): RotateCapability {\n return {\n onRotateChange: this.rotate$.on,\n setRotation: (rotation) => this.setRotation(rotation),\n getRotation: () => this.coreState.core.rotation,\n rotateForward: () => this.rotateForward(),\n rotateBackward: () => this.rotateBackward(),\n };\n }\n\n public getMatrixAsString(options: GetMatrixOptions = { w: 0, h: 0 }): string {\n return getRotationMatrixString(this.coreState.core.rotation, options.w, options.h);\n }\n\n async destroy(): Promise<void> {\n this.rotate$.clear();\n super.destroy();\n }\n}\n","import { Rotation } from '@embedpdf/models';\n\n/**\n * Returns the 6-tuple transformation matrix for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n *\n * ── Note on e,f ───────────────────────────────\n * For 0°/180° no translation is needed.\n * For 90°/270° you may want to pass the page\n * height / width so the page stays in positive\n * coordinates. Keep them 0 and handle layout\n * elsewhere if that's what you do today.\n */\nexport function getRotationMatrix(\n rotation: Rotation,\n w: number,\n h: number,\n): [number, number, number, number, number, number] {\n let a = 1,\n b = 0,\n c = 0,\n d = 1,\n e = 0,\n f = 0;\n\n switch (rotation) {\n case 1: // 90°\n a = 0;\n b = 1;\n c = -1;\n d = 0;\n e = h;\n break;\n case 2: // 180°\n a = -1;\n b = 0;\n c = 0;\n d = -1;\n e = w;\n f = h;\n break;\n case 3: // 270°\n a = 0;\n b = -1;\n c = 1;\n d = 0;\n f = w;\n break;\n }\n\n return [a, b, c, d, e, f];\n}\n\n/**\n * Returns the CSS matrix transformation string for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n */\nexport function getRotationMatrixString(rotation: Rotation, w: number, h: number): string {\n const [a, b, c, d, e, f] = getRotationMatrix(rotation, w, h);\n return `matrix(${a},${b},${c},${d},${e},${f})`;\n}\n\n/**\n * Returns the next rotation.\n */\nexport function getNextRotation(current: Rotation): Rotation {\n return ((current + 1) % 4) as Rotation;\n}\n\n/**\n * Returns the previous rotation.\n */\nexport function getPreviousRotation(current: Rotation): Rotation {\n return ((current + 3) % 4) as Rotation; // +3 is equivalent to -1 in modulo 4\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, ROTATE_PLUGIN_ID } from './manifest';\nimport { RotatePluginConfig } from './types';\nimport { RotatePlugin } from './rotate-plugin';\n\nexport const RotatePluginPackage: PluginPackage<RotatePlugin, RotatePluginConfig> = {\n manifest,\n create: (registry, config) => new RotatePlugin(ROTATE_PLUGIN_ID, registry, config),\n reducer: () => {},\n initialState: {},\n};\n\nexport * from './rotate-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":["ROTATE_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","_RotatePlugin","BasePlugin","constructor","registry","cfg","super","this","rotate$","createBehaviorEmitter","resetReady","rotation","defaultRotation","coreState","core","setRotation","markReady","initialize","_config","pages","Error","emit","dispatchCoreAction","rotateForward","rotateBackward","buildCapability","onRotateChange","on","getRotation","getMatrixAsString","options","w","h","a","b","c","d","e","f","getRotationMatrix","getRotationMatrixString","destroy","clear","RotatePlugin","RotatePluginPackage","create","config","reducer","initialState"],"mappings":"kHAGaA,EAAmB,SAEnBC,EAA+C,CAC1DC,GAAIF,EACJG,KAAM,gBACNC,QAAS,QACTC,SAAU,CAAC,UACXC,SAAU,CAAC,UACXC,SAAU,CAAC,UACXC,cAAe,CACbC,SAAS,ICRN,MAAMC,EAAN,cAA2BC,EAAAA,WAIhC,WAAAC,CAAYV,EAAYW,EAA0BC,GAChDC,MAAMb,EAAIW,GAHKG,KAAAC,QAAUC,0BAIzBF,KAAKG,aACL,MAAMC,EAAWN,EAAIO,iBAAmBL,KAAKM,UAAUC,KAAKH,SAC5DJ,KAAKQ,YAAYJ,GACjBJ,KAAKS,WAAU,CAGjB,gBAAMC,CAAWC,GAA4C,CAErD,WAAAH,CAAYJ,GAElB,IADcJ,KAAKM,UAAUC,KAAKK,MAE1B,MAAA,IAAIC,MAAM,oBAGbb,KAAAC,QAAQa,KAAKV,GACbJ,KAAAe,mBAAmBP,cAAYJ,GAAS,CAGvC,aAAAY,GACN,MAAMZ,GAA2BJ,KAAKM,UAAUC,KAAKH,SCoCpC,GAAK,EDnCtBJ,KAAKQ,YAAYJ,EAAQ,CAGnB,cAAAa,GACN,MAAMb,GAA+BJ,KAAKM,UAAUC,KAAKH,SCsCxC,GAAK,EDrCtBJ,KAAKQ,YAAYJ,EAAQ,CAGjB,eAAAc,GACD,MAAA,CACLC,eAAgBnB,KAAKC,QAAQmB,GAC7BZ,YAAcJ,GAAaJ,KAAKQ,YAAYJ,GAC5CiB,YAAa,IAAMrB,KAAKM,UAAUC,KAAKH,SACvCY,cAAe,IAAMhB,KAAKgB,gBAC1BC,eAAgB,IAAMjB,KAAKiB,iBAC7B,CAGK,iBAAAK,CAAkBC,EAA4B,CAAEC,EAAG,EAAGC,EAAG,IACvD,OCOK,SAAwBrB,EAAoBoB,EAAWC,GAC/D,MAACC,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,GA7CR,SACd3B,EACAoB,EACAC,GAEI,IAAAC,EAAI,EACNC,EAAI,EACJC,EAAI,EACJC,EAAI,EACJC,EAAI,EACJC,EAAI,EAEN,OAAQ3B,GACN,KAAK,EACCsB,EAAA,EACAC,EAAA,EACAC,GAAA,EACAC,EAAA,EACAC,EAAAL,EACJ,MACF,KAAK,EACCC,GAAA,EACAC,EAAA,EACAC,EAAA,EACAC,GAAA,EACAC,EAAAN,EACAO,EAAAN,EACJ,MACF,KAAK,EACCC,EAAA,EACAC,GAAA,EACAC,EAAA,EACAC,EAAA,EACAE,EAAAP,EAIR,MAAO,CAACE,EAAGC,EAAGC,EAAGC,EAAGC,EAAGC,EACzB,CAO6BC,CAAkB5B,EAAUoB,EAAGC,GACnD,MAAA,UAAUC,KAAKC,KAAKC,KAAKC,KAAKC,KAAKC,IAC5C,CDVWE,CAAwBjC,KAAKM,UAAUC,KAAKH,SAAUmB,EAAQC,EAAGD,EAAQE,EAAC,CAGnF,aAAMS,GACJlC,KAAKC,QAAQkC,QACbpC,MAAMmC,SAAQ,GAjDhBxC,EAAgBR,GAAK,SADhB,IAAMkD,EAAN1C,EEAA,MAAM2C,EAAuE,CAClFpD,WACAqD,OAAQ,CAACzC,EAAU0C,IAAW,IAAIH,EAAapD,EAAkBa,EAAU0C,GAC3EC,QAAS,OACTC,aAAc,CAAA"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/utils.ts","../src/lib/actions.ts","../src/lib/rotate-plugin.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { RotatePluginConfig } from './types';\n\nexport const ROTATE_PLUGIN_ID = 'rotate';\n\nexport const manifest: PluginManifest<RotatePluginConfig> = {\n id: ROTATE_PLUGIN_ID,\n name: 'Rotate Plugin',\n version: '1.0.0',\n provides: ['rotate'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Rotation } from '@embedpdf/models';\n\n/**\n * Returns the 6-tuple transformation matrix for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n *\n * ── Note on e,f ───────────────────────────────\n * For 0°/180° no translation is needed.\n * For 90°/270° you may want to pass the page\n * height / width so the page stays in positive\n * coordinates. Keep them 0 and handle layout\n * elsewhere if that's what you do today.\n */\nexport function getRotationMatrix(\n rotation: Rotation,\n w: number,\n h: number,\n): [number, number, number, number, number, number] {\n let a = 1,\n b = 0,\n c = 0,\n d = 1,\n e = 0,\n f = 0;\n\n switch (rotation) {\n case 1: // 90°\n a = 0;\n b = 1;\n c = -1;\n d = 0;\n e = h;\n break;\n case 2: // 180°\n a = -1;\n b = 0;\n c = 0;\n d = -1;\n e = w;\n f = h;\n break;\n case 3: // 270°\n a = 0;\n b = -1;\n c = 1;\n d = 0;\n f = w;\n break;\n }\n\n return [a, b, c, d, e, f];\n}\n\n/**\n * Returns the CSS matrix transformation string for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n */\nexport function getRotationMatrixString(rotation: Rotation, w: number, h: number): string {\n const [a, b, c, d, e, f] = getRotationMatrix(rotation, w, h);\n return `matrix(${a},${b},${c},${d},${e},${f})`;\n}\n\n/**\n * Returns the next rotation.\n */\nexport function getNextRotation(current: Rotation): Rotation {\n return ((current + 1) % 4) as Rotation;\n}\n\n/**\n * Returns the previous rotation.\n */\nexport function getPreviousRotation(current: Rotation): Rotation {\n return ((current + 3) % 4) as Rotation; // +3 is equivalent to -1 in modulo 4\n}\n","import { Action } from '@embedpdf/core';\nimport { Rotation } from '@embedpdf/models';\nimport { RotateDocumentState } from './types';\n\n// Document lifecycle\nexport const INIT_ROTATE_STATE = 'ROTATE/INIT_STATE';\nexport const CLEANUP_ROTATE_STATE = 'ROTATE/CLEANUP_STATE';\nexport const SET_ACTIVE_ROTATE_DOCUMENT = 'ROTATE/SET_ACTIVE_DOCUMENT';\n\n// Rotation operations\nexport const SET_ROTATION = 'ROTATE/SET_ROTATION';\n\n// Document lifecycle actions\nexport interface InitRotateStateAction extends Action {\n type: typeof INIT_ROTATE_STATE;\n payload: {\n documentId: string;\n state: RotateDocumentState;\n };\n}\n\nexport interface CleanupRotateStateAction extends Action {\n type: typeof CLEANUP_ROTATE_STATE;\n payload: string; // documentId\n}\n\nexport interface SetActiveRotateDocumentAction extends Action {\n type: typeof SET_ACTIVE_ROTATE_DOCUMENT;\n payload: string | null; // documentId\n}\n\nexport interface SetRotationAction extends Action {\n type: typeof SET_ROTATION;\n payload: {\n documentId: string;\n rotation: Rotation;\n };\n}\n\nexport type RotateAction =\n | InitRotateStateAction\n | CleanupRotateStateAction\n | SetActiveRotateDocumentAction\n | SetRotationAction;\n\n// Action Creators\nexport function initRotateState(\n documentId: string,\n state: RotateDocumentState,\n): InitRotateStateAction {\n return { type: INIT_ROTATE_STATE, payload: { documentId, state } };\n}\n\nexport function cleanupRotateState(documentId: string): CleanupRotateStateAction {\n return { type: CLEANUP_ROTATE_STATE, payload: documentId };\n}\n\nexport function setActiveRotateDocument(documentId: string | null): SetActiveRotateDocumentAction {\n return { type: SET_ACTIVE_ROTATE_DOCUMENT, payload: documentId };\n}\n\nexport function setRotation(documentId: string, rotation: Rotation): SetRotationAction {\n return { type: SET_ROTATION, payload: { documentId, rotation } };\n}\n","import {\n BasePlugin,\n createBehaviorEmitter,\n Listener,\n PluginRegistry,\n setRotation as setCoreRotation,\n} from '@embedpdf/core';\nimport { Rotation } from '@embedpdf/models';\nimport {\n GetMatrixOptions,\n RotateCapability,\n RotatePluginConfig,\n RotateScope,\n RotationChangeEvent,\n RotateState,\n RotateDocumentState,\n} from './types';\nimport { getNextRotation, getPreviousRotation, getRotationMatrixString } from './utils';\nimport { initRotateState, cleanupRotateState, setRotation, RotateAction } from './actions';\n\nexport class RotatePlugin extends BasePlugin<\n RotatePluginConfig,\n RotateCapability,\n RotateState,\n RotateAction\n> {\n static readonly id = 'rotate' as const;\n\n private readonly rotate$ = createBehaviorEmitter<RotationChangeEvent>();\n private readonly defaultRotation: Rotation;\n\n constructor(id: string, registry: PluginRegistry, cfg: RotatePluginConfig) {\n super(id, registry);\n this.defaultRotation = cfg.defaultRotation ?? 0;\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Lifecycle Hooks (from BasePlugin)\n // ─────────────────────────────────────────────────────────\n\n protected override onDocumentLoadingStarted(documentId: string): void {\n // Initialize rotation state for this document\n const docState: RotateDocumentState = {\n rotation: this.defaultRotation,\n };\n\n this.dispatch(initRotateState(documentId, docState));\n\n // Also set in core state for backwards compatibility\n this.dispatchCoreAction(setCoreRotation(this.defaultRotation, documentId));\n\n this.logger.debug(\n 'RotatePlugin',\n 'DocumentOpened',\n `Initialized rotation state for document: ${documentId}`,\n );\n }\n\n protected override onDocumentClosed(documentId: string): void {\n this.dispatch(cleanupRotateState(documentId));\n\n this.logger.debug(\n 'RotatePlugin',\n 'DocumentClosed',\n `Cleaned up rotation state for document: ${documentId}`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Capability\n // ─────────────────────────────────────────────────────────\n\n protected buildCapability(): RotateCapability {\n return {\n // Active document operations\n setRotation: (rotation: Rotation) => this.setRotationForDocument(rotation),\n getRotation: () => this.getRotationForDocument(),\n rotateForward: () => this.rotateForward(),\n rotateBackward: () => this.rotateBackward(),\n\n // Document-scoped operations\n forDocument: (documentId: string) => this.createRotateScope(documentId),\n\n // Events\n onRotateChange: this.rotate$.on,\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Scoping\n // ─────────────────────────────────────────────────────────\n\n private createRotateScope(documentId: string): RotateScope {\n return {\n setRotation: (rotation: Rotation) => this.setRotationForDocument(rotation, documentId),\n getRotation: () => this.getRotationForDocument(documentId),\n rotateForward: () => this.rotateForward(documentId),\n rotateBackward: () => this.rotateBackward(documentId),\n onRotateChange: (listener: Listener<Rotation>) =>\n this.rotate$.on((event) => {\n if (event.documentId === documentId) listener(event.rotation);\n }),\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // State Helpers\n // ─────────────────────────────────────────────────────────\n private getDocumentState(documentId?: string): RotateDocumentState | null {\n const id = documentId ?? this.getActiveDocumentId();\n return this.state.documents[id] ?? null;\n }\n\n private getDocumentStateOrThrow(documentId?: string): RotateDocumentState {\n const state = this.getDocumentState(documentId);\n if (!state) {\n throw new Error(`Rotation state not found for document: ${documentId ?? 'active'}`);\n }\n return state;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations\n // ─────────────────────────────────────────────────────────\n\n private setRotationForDocument(rotation: Rotation, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n const coreDoc = this.coreState.core.documents[id];\n\n if (!coreDoc?.document) {\n throw new Error(`Document ${id} not loaded`);\n }\n\n // Update plugin state\n this.dispatch(setRotation(id, rotation));\n\n // Update core state for backwards compatibility\n this.dispatchCoreAction(setCoreRotation(rotation, id));\n\n // Emit event\n this.rotate$.emit({\n documentId: id,\n rotation,\n });\n }\n\n private getRotationForDocument(documentId?: string): Rotation {\n return this.getDocumentStateOrThrow(documentId).rotation;\n }\n\n private rotateForward(documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n const currentRotation = this.getRotationForDocument(id);\n const nextRotation = getNextRotation(currentRotation);\n this.setRotationForDocument(nextRotation, id);\n }\n\n private rotateBackward(documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n const currentRotation = this.getRotationForDocument(id);\n const prevRotation = getPreviousRotation(currentRotation);\n this.setRotationForDocument(prevRotation, id);\n }\n\n public getMatrixAsString(options: GetMatrixOptions): string {\n return getRotationMatrixString(options.rotation, options.width, options.height);\n }\n\n // ─────────────────────────────────────────────────────────\n // Store Update Handlers\n // ─────────────────────────────────────────────────────────\n\n override onStoreUpdated(prevState: RotateState, newState: RotateState): void {\n // Emit rotation change events for each changed document\n for (const documentId in newState.documents) {\n const prevDoc = prevState.documents[documentId];\n const newDoc = newState.documents[documentId];\n\n if (prevDoc?.rotation !== newDoc.rotation) {\n this.logger.debug(\n 'RotatePlugin',\n 'RotationChanged',\n `Rotation changed for document ${documentId}: ${prevDoc?.rotation ?? 0} -> ${newDoc.rotation}`,\n );\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────\n // Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(_config: RotatePluginConfig): Promise<void> {\n this.logger.info('RotatePlugin', 'Initialize', 'Rotate plugin initialized');\n }\n\n async destroy(): Promise<void> {\n this.rotate$.clear();\n super.destroy();\n }\n}\n","import { Reducer } from '@embedpdf/core';\nimport {\n RotateAction,\n INIT_ROTATE_STATE,\n CLEANUP_ROTATE_STATE,\n SET_ACTIVE_ROTATE_DOCUMENT,\n SET_ROTATION,\n} from './actions';\nimport { RotateState, RotateDocumentState } from './types';\n\nexport const initialDocumentState: RotateDocumentState = {\n rotation: 0,\n};\n\nexport const initialState: RotateState = {\n documents: {},\n activeDocumentId: null,\n};\n\nexport const rotateReducer: Reducer<RotateState, RotateAction> = (state = initialState, action) => {\n switch (action.type) {\n case INIT_ROTATE_STATE: {\n const { documentId, state: docState } = action.payload;\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: docState,\n },\n // Set as active if no active document\n activeDocumentId: state.activeDocumentId ?? documentId,\n };\n }\n\n case CLEANUP_ROTATE_STATE: {\n const documentId = action.payload;\n const { [documentId]: removed, ...remainingDocs } = state.documents;\n return {\n ...state,\n documents: remainingDocs,\n activeDocumentId: state.activeDocumentId === documentId ? null : state.activeDocumentId,\n };\n }\n\n case SET_ACTIVE_ROTATE_DOCUMENT: {\n return {\n ...state,\n activeDocumentId: action.payload,\n };\n }\n\n case SET_ROTATION: {\n const { documentId, rotation } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n rotation,\n },\n },\n };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, ROTATE_PLUGIN_ID } from './manifest';\nimport { RotatePluginConfig, RotateState } from './types';\nimport { RotatePlugin } from './rotate-plugin';\nimport { RotateAction } from './actions';\nimport { rotateReducer, initialState } from './reducer';\n\nexport const RotatePluginPackage: PluginPackage<\n RotatePlugin,\n RotatePluginConfig,\n RotateState,\n RotateAction\n> = {\n manifest,\n create: (registry, config) => new RotatePlugin(ROTATE_PLUGIN_ID, registry, config),\n reducer: rotateReducer,\n initialState,\n};\n\nexport * from './rotate-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './actions';\nexport * from './reducer';\nexport * from './utils';\n"],"names":["ROTATE_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","getRotationMatrix","rotation","w","h","a","b","c","d","e","f","getRotationMatrixString","getNextRotation","current","getPreviousRotation","INIT_ROTATE_STATE","CLEANUP_ROTATE_STATE","SET_ACTIVE_ROTATE_DOCUMENT","SET_ROTATION","initRotateState","documentId","state","type","payload","cleanupRotateState","setRotation","_RotatePlugin","BasePlugin","constructor","registry","cfg","super","this","rotate$","createBehaviorEmitter","defaultRotation","onDocumentLoadingStarted","docState","dispatch","dispatchCoreAction","setCoreRotation","logger","debug","onDocumentClosed","buildCapability","setRotationForDocument","getRotation","getRotationForDocument","rotateForward","rotateBackward","forDocument","createRotateScope","onRotateChange","on","listener","event","getDocumentState","getActiveDocumentId","documents","getDocumentStateOrThrow","Error","coreDoc","coreState","core","document","emit","nextRotation","prevRotation","getMatrixAsString","options","width","height","onStoreUpdated","prevState","newState","prevDoc","newDoc","initialize","_config","info","destroy","clear","RotatePlugin","initialState","activeDocumentId","rotateReducer","action","removed","remainingDocs","RotatePluginPackage","create","config","reducer"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import { BasePlugin, createBehaviorEmitter, setRotation } from "@embedpdf/core";
1
+ import { BasePlugin, createBehaviorEmitter, setRotation as setRotation$1 } from "@embedpdf/core";
2
2
  const ROTATE_PLUGIN_ID = "rotate";
3
3
  const manifest = {
4
4
  id: ROTATE_PLUGIN_ID,
5
5
  name: "Rotate Plugin",
6
6
  version: "1.0.0",
7
7
  provides: ["rotate"],
8
- requires: ["loader"],
9
- optional: ["spread"],
8
+ requires: [],
9
+ optional: [],
10
10
  defaultConfig: {
11
11
  enabled: true
12
12
  }
@@ -49,44 +49,150 @@ function getNextRotation(current) {
49
49
  function getPreviousRotation(current) {
50
50
  return (current + 3) % 4;
51
51
  }
52
+ const INIT_ROTATE_STATE = "ROTATE/INIT_STATE";
53
+ const CLEANUP_ROTATE_STATE = "ROTATE/CLEANUP_STATE";
54
+ const SET_ACTIVE_ROTATE_DOCUMENT = "ROTATE/SET_ACTIVE_DOCUMENT";
55
+ const SET_ROTATION = "ROTATE/SET_ROTATION";
56
+ function initRotateState(documentId, state) {
57
+ return { type: INIT_ROTATE_STATE, payload: { documentId, state } };
58
+ }
59
+ function cleanupRotateState(documentId) {
60
+ return { type: CLEANUP_ROTATE_STATE, payload: documentId };
61
+ }
62
+ function setActiveRotateDocument(documentId) {
63
+ return { type: SET_ACTIVE_ROTATE_DOCUMENT, payload: documentId };
64
+ }
65
+ function setRotation(documentId, rotation) {
66
+ return { type: SET_ROTATION, payload: { documentId, rotation } };
67
+ }
52
68
  const _RotatePlugin = class _RotatePlugin extends BasePlugin {
53
69
  constructor(id, registry, cfg) {
54
70
  super(id, registry);
55
71
  this.rotate$ = createBehaviorEmitter();
56
- this.resetReady();
57
- const rotation = cfg.defaultRotation ?? this.coreState.core.rotation;
58
- this.setRotation(rotation);
59
- this.markReady();
72
+ this.defaultRotation = cfg.defaultRotation ?? 0;
60
73
  }
61
- async initialize(_config) {
62
- }
63
- setRotation(rotation) {
64
- const pages = this.coreState.core.pages;
65
- if (!pages) {
66
- throw new Error("Pages not loaded");
67
- }
68
- this.rotate$.emit(rotation);
69
- this.dispatchCoreAction(setRotation(rotation));
70
- }
71
- rotateForward() {
72
- const rotation = getNextRotation(this.coreState.core.rotation);
73
- this.setRotation(rotation);
74
+ // ─────────────────────────────────────────────────────────
75
+ // Document Lifecycle Hooks (from BasePlugin)
76
+ // ─────────────────────────────────────────────────────────
77
+ onDocumentLoadingStarted(documentId) {
78
+ const docState = {
79
+ rotation: this.defaultRotation
80
+ };
81
+ this.dispatch(initRotateState(documentId, docState));
82
+ this.dispatchCoreAction(setRotation$1(this.defaultRotation, documentId));
83
+ this.logger.debug(
84
+ "RotatePlugin",
85
+ "DocumentOpened",
86
+ `Initialized rotation state for document: ${documentId}`
87
+ );
74
88
  }
75
- rotateBackward() {
76
- const rotation = getPreviousRotation(this.coreState.core.rotation);
77
- this.setRotation(rotation);
89
+ onDocumentClosed(documentId) {
90
+ this.dispatch(cleanupRotateState(documentId));
91
+ this.logger.debug(
92
+ "RotatePlugin",
93
+ "DocumentClosed",
94
+ `Cleaned up rotation state for document: ${documentId}`
95
+ );
78
96
  }
97
+ // ─────────────────────────────────────────────────────────
98
+ // Capability
99
+ // ─────────────────────────────────────────────────────────
79
100
  buildCapability() {
80
101
  return {
81
- onRotateChange: this.rotate$.on,
82
- setRotation: (rotation) => this.setRotation(rotation),
83
- getRotation: () => this.coreState.core.rotation,
102
+ // Active document operations
103
+ setRotation: (rotation) => this.setRotationForDocument(rotation),
104
+ getRotation: () => this.getRotationForDocument(),
84
105
  rotateForward: () => this.rotateForward(),
85
- rotateBackward: () => this.rotateBackward()
106
+ rotateBackward: () => this.rotateBackward(),
107
+ // Document-scoped operations
108
+ forDocument: (documentId) => this.createRotateScope(documentId),
109
+ // Events
110
+ onRotateChange: this.rotate$.on
86
111
  };
87
112
  }
88
- getMatrixAsString(options = { w: 0, h: 0 }) {
89
- return getRotationMatrixString(this.coreState.core.rotation, options.w, options.h);
113
+ // ─────────────────────────────────────────────────────────
114
+ // Document Scoping
115
+ // ─────────────────────────────────────────────────────────
116
+ createRotateScope(documentId) {
117
+ return {
118
+ setRotation: (rotation) => this.setRotationForDocument(rotation, documentId),
119
+ getRotation: () => this.getRotationForDocument(documentId),
120
+ rotateForward: () => this.rotateForward(documentId),
121
+ rotateBackward: () => this.rotateBackward(documentId),
122
+ onRotateChange: (listener) => this.rotate$.on((event) => {
123
+ if (event.documentId === documentId) listener(event.rotation);
124
+ })
125
+ };
126
+ }
127
+ // ─────────────────────────────────────────────────────────
128
+ // State Helpers
129
+ // ─────────────────────────────────────────────────────────
130
+ getDocumentState(documentId) {
131
+ const id = documentId ?? this.getActiveDocumentId();
132
+ return this.state.documents[id] ?? null;
133
+ }
134
+ getDocumentStateOrThrow(documentId) {
135
+ const state = this.getDocumentState(documentId);
136
+ if (!state) {
137
+ throw new Error(`Rotation state not found for document: ${documentId ?? "active"}`);
138
+ }
139
+ return state;
140
+ }
141
+ // ─────────────────────────────────────────────────────────
142
+ // Core Operations
143
+ // ─────────────────────────────────────────────────────────
144
+ setRotationForDocument(rotation, documentId) {
145
+ const id = documentId ?? this.getActiveDocumentId();
146
+ const coreDoc = this.coreState.core.documents[id];
147
+ if (!(coreDoc == null ? void 0 : coreDoc.document)) {
148
+ throw new Error(`Document ${id} not loaded`);
149
+ }
150
+ this.dispatch(setRotation(id, rotation));
151
+ this.dispatchCoreAction(setRotation$1(rotation, id));
152
+ this.rotate$.emit({
153
+ documentId: id,
154
+ rotation
155
+ });
156
+ }
157
+ getRotationForDocument(documentId) {
158
+ return this.getDocumentStateOrThrow(documentId).rotation;
159
+ }
160
+ rotateForward(documentId) {
161
+ const id = documentId ?? this.getActiveDocumentId();
162
+ const currentRotation = this.getRotationForDocument(id);
163
+ const nextRotation = getNextRotation(currentRotation);
164
+ this.setRotationForDocument(nextRotation, id);
165
+ }
166
+ rotateBackward(documentId) {
167
+ const id = documentId ?? this.getActiveDocumentId();
168
+ const currentRotation = this.getRotationForDocument(id);
169
+ const prevRotation = getPreviousRotation(currentRotation);
170
+ this.setRotationForDocument(prevRotation, id);
171
+ }
172
+ getMatrixAsString(options) {
173
+ return getRotationMatrixString(options.rotation, options.width, options.height);
174
+ }
175
+ // ─────────────────────────────────────────────────────────
176
+ // Store Update Handlers
177
+ // ─────────────────────────────────────────────────────────
178
+ onStoreUpdated(prevState, newState) {
179
+ for (const documentId in newState.documents) {
180
+ const prevDoc = prevState.documents[documentId];
181
+ const newDoc = newState.documents[documentId];
182
+ if ((prevDoc == null ? void 0 : prevDoc.rotation) !== newDoc.rotation) {
183
+ this.logger.debug(
184
+ "RotatePlugin",
185
+ "RotationChanged",
186
+ `Rotation changed for document ${documentId}: ${(prevDoc == null ? void 0 : prevDoc.rotation) ?? 0} -> ${newDoc.rotation}`
187
+ );
188
+ }
189
+ }
190
+ }
191
+ // ─────────────────────────────────────────────────────────
192
+ // Lifecycle
193
+ // ─────────────────────────────────────────────────────────
194
+ async initialize(_config) {
195
+ this.logger.info("RotatePlugin", "Initialize", "Rotate plugin initialized");
90
196
  }
91
197
  async destroy() {
92
198
  this.rotate$.clear();
@@ -95,17 +201,86 @@ const _RotatePlugin = class _RotatePlugin extends BasePlugin {
95
201
  };
96
202
  _RotatePlugin.id = "rotate";
97
203
  let RotatePlugin = _RotatePlugin;
204
+ const initialDocumentState = {
205
+ rotation: 0
206
+ };
207
+ const initialState = {
208
+ documents: {},
209
+ activeDocumentId: null
210
+ };
211
+ const rotateReducer = (state = initialState, action) => {
212
+ switch (action.type) {
213
+ case INIT_ROTATE_STATE: {
214
+ const { documentId, state: docState } = action.payload;
215
+ return {
216
+ ...state,
217
+ documents: {
218
+ ...state.documents,
219
+ [documentId]: docState
220
+ },
221
+ // Set as active if no active document
222
+ activeDocumentId: state.activeDocumentId ?? documentId
223
+ };
224
+ }
225
+ case CLEANUP_ROTATE_STATE: {
226
+ const documentId = action.payload;
227
+ const { [documentId]: removed, ...remainingDocs } = state.documents;
228
+ return {
229
+ ...state,
230
+ documents: remainingDocs,
231
+ activeDocumentId: state.activeDocumentId === documentId ? null : state.activeDocumentId
232
+ };
233
+ }
234
+ case SET_ACTIVE_ROTATE_DOCUMENT: {
235
+ return {
236
+ ...state,
237
+ activeDocumentId: action.payload
238
+ };
239
+ }
240
+ case SET_ROTATION: {
241
+ const { documentId, rotation } = action.payload;
242
+ const docState = state.documents[documentId];
243
+ if (!docState) return state;
244
+ return {
245
+ ...state,
246
+ documents: {
247
+ ...state.documents,
248
+ [documentId]: {
249
+ ...docState,
250
+ rotation
251
+ }
252
+ }
253
+ };
254
+ }
255
+ default:
256
+ return state;
257
+ }
258
+ };
98
259
  const RotatePluginPackage = {
99
260
  manifest,
100
261
  create: (registry, config) => new RotatePlugin(ROTATE_PLUGIN_ID, registry, config),
101
- reducer: () => {
102
- },
103
- initialState: {}
262
+ reducer: rotateReducer,
263
+ initialState
104
264
  };
105
265
  export {
266
+ CLEANUP_ROTATE_STATE,
267
+ INIT_ROTATE_STATE,
106
268
  ROTATE_PLUGIN_ID,
107
269
  RotatePlugin,
108
270
  RotatePluginPackage,
109
- manifest
271
+ SET_ACTIVE_ROTATE_DOCUMENT,
272
+ SET_ROTATION,
273
+ cleanupRotateState,
274
+ getNextRotation,
275
+ getPreviousRotation,
276
+ getRotationMatrix,
277
+ getRotationMatrixString,
278
+ initRotateState,
279
+ initialDocumentState,
280
+ initialState,
281
+ manifest,
282
+ rotateReducer,
283
+ setActiveRotateDocument,
284
+ setRotation
110
285
  };
111
286
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/manifest.ts","../src/lib/utils.ts","../src/lib/rotate-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { RotatePluginConfig } from './types';\n\nexport const ROTATE_PLUGIN_ID = 'rotate';\n\nexport const manifest: PluginManifest<RotatePluginConfig> = {\n id: ROTATE_PLUGIN_ID,\n name: 'Rotate Plugin',\n version: '1.0.0',\n provides: ['rotate'],\n requires: ['loader'],\n optional: ['spread'],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Rotation } from '@embedpdf/models';\n\n/**\n * Returns the 6-tuple transformation matrix for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n *\n * ── Note on e,f ───────────────────────────────\n * For 0°/180° no translation is needed.\n * For 90°/270° you may want to pass the page\n * height / width so the page stays in positive\n * coordinates. Keep them 0 and handle layout\n * elsewhere if that's what you do today.\n */\nexport function getRotationMatrix(\n rotation: Rotation,\n w: number,\n h: number,\n): [number, number, number, number, number, number] {\n let a = 1,\n b = 0,\n c = 0,\n d = 1,\n e = 0,\n f = 0;\n\n switch (rotation) {\n case 1: // 90°\n a = 0;\n b = 1;\n c = -1;\n d = 0;\n e = h;\n break;\n case 2: // 180°\n a = -1;\n b = 0;\n c = 0;\n d = -1;\n e = w;\n f = h;\n break;\n case 3: // 270°\n a = 0;\n b = -1;\n c = 1;\n d = 0;\n f = w;\n break;\n }\n\n return [a, b, c, d, e, f];\n}\n\n/**\n * Returns the CSS matrix transformation string for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n */\nexport function getRotationMatrixString(rotation: Rotation, w: number, h: number): string {\n const [a, b, c, d, e, f] = getRotationMatrix(rotation, w, h);\n return `matrix(${a},${b},${c},${d},${e},${f})`;\n}\n\n/**\n * Returns the next rotation.\n */\nexport function getNextRotation(current: Rotation): Rotation {\n return ((current + 1) % 4) as Rotation;\n}\n\n/**\n * Returns the previous rotation.\n */\nexport function getPreviousRotation(current: Rotation): Rotation {\n return ((current + 3) % 4) as Rotation; // +3 is equivalent to -1 in modulo 4\n}\n","import { BasePlugin, createBehaviorEmitter, PluginRegistry, setRotation } from '@embedpdf/core';\nimport { Rotation } from '@embedpdf/models';\nimport { GetMatrixOptions, RotateCapability, RotatePluginConfig } from './types';\nimport { getNextRotation, getPreviousRotation, getRotationMatrixString } from './utils';\n\nexport class RotatePlugin extends BasePlugin<RotatePluginConfig, RotateCapability> {\n static readonly id = 'rotate' as const;\n private readonly rotate$ = createBehaviorEmitter<Rotation>();\n\n constructor(id: string, registry: PluginRegistry, cfg: RotatePluginConfig) {\n super(id, registry);\n this.resetReady();\n const rotation = cfg.defaultRotation ?? this.coreState.core.rotation;\n this.setRotation(rotation);\n this.markReady();\n }\n\n async initialize(_config: RotatePluginConfig): Promise<void> {}\n\n private setRotation(rotation: Rotation): void {\n const pages = this.coreState.core.pages;\n if (!pages) {\n throw new Error('Pages not loaded');\n }\n\n this.rotate$.emit(rotation);\n this.dispatchCoreAction(setRotation(rotation));\n }\n\n private rotateForward(): void {\n const rotation = getNextRotation(this.coreState.core.rotation);\n this.setRotation(rotation);\n }\n\n private rotateBackward(): void {\n const rotation = getPreviousRotation(this.coreState.core.rotation);\n this.setRotation(rotation);\n }\n\n protected buildCapability(): RotateCapability {\n return {\n onRotateChange: this.rotate$.on,\n setRotation: (rotation) => this.setRotation(rotation),\n getRotation: () => this.coreState.core.rotation,\n rotateForward: () => this.rotateForward(),\n rotateBackward: () => this.rotateBackward(),\n };\n }\n\n public getMatrixAsString(options: GetMatrixOptions = { w: 0, h: 0 }): string {\n return getRotationMatrixString(this.coreState.core.rotation, options.w, options.h);\n }\n\n async destroy(): Promise<void> {\n this.rotate$.clear();\n super.destroy();\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, ROTATE_PLUGIN_ID } from './manifest';\nimport { RotatePluginConfig } from './types';\nimport { RotatePlugin } from './rotate-plugin';\n\nexport const RotatePluginPackage: PluginPackage<RotatePlugin, RotatePluginConfig> = {\n manifest,\n create: (registry, config) => new RotatePlugin(ROTATE_PLUGIN_ID, registry, config),\n reducer: () => {},\n initialState: {},\n};\n\nexport * from './rotate-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/manifest.ts","../src/lib/utils.ts","../src/lib/actions.ts","../src/lib/rotate-plugin.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\nimport { RotatePluginConfig } from './types';\n\nexport const ROTATE_PLUGIN_ID = 'rotate';\n\nexport const manifest: PluginManifest<RotatePluginConfig> = {\n id: ROTATE_PLUGIN_ID,\n name: 'Rotate Plugin',\n version: '1.0.0',\n provides: ['rotate'],\n requires: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n },\n};\n","import { Rotation } from '@embedpdf/models';\n\n/**\n * Returns the 6-tuple transformation matrix for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n *\n * ── Note on e,f ───────────────────────────────\n * For 0°/180° no translation is needed.\n * For 90°/270° you may want to pass the page\n * height / width so the page stays in positive\n * coordinates. Keep them 0 and handle layout\n * elsewhere if that's what you do today.\n */\nexport function getRotationMatrix(\n rotation: Rotation,\n w: number,\n h: number,\n): [number, number, number, number, number, number] {\n let a = 1,\n b = 0,\n c = 0,\n d = 1,\n e = 0,\n f = 0;\n\n switch (rotation) {\n case 1: // 90°\n a = 0;\n b = 1;\n c = -1;\n d = 0;\n e = h;\n break;\n case 2: // 180°\n a = -1;\n b = 0;\n c = 0;\n d = -1;\n e = w;\n f = h;\n break;\n case 3: // 270°\n a = 0;\n b = -1;\n c = 1;\n d = 0;\n f = w;\n break;\n }\n\n return [a, b, c, d, e, f];\n}\n\n/**\n * Returns the CSS matrix transformation string for rotation.\n * Rotation is clockwise, origin = top-left (0 0).\n */\nexport function getRotationMatrixString(rotation: Rotation, w: number, h: number): string {\n const [a, b, c, d, e, f] = getRotationMatrix(rotation, w, h);\n return `matrix(${a},${b},${c},${d},${e},${f})`;\n}\n\n/**\n * Returns the next rotation.\n */\nexport function getNextRotation(current: Rotation): Rotation {\n return ((current + 1) % 4) as Rotation;\n}\n\n/**\n * Returns the previous rotation.\n */\nexport function getPreviousRotation(current: Rotation): Rotation {\n return ((current + 3) % 4) as Rotation; // +3 is equivalent to -1 in modulo 4\n}\n","import { Action } from '@embedpdf/core';\nimport { Rotation } from '@embedpdf/models';\nimport { RotateDocumentState } from './types';\n\n// Document lifecycle\nexport const INIT_ROTATE_STATE = 'ROTATE/INIT_STATE';\nexport const CLEANUP_ROTATE_STATE = 'ROTATE/CLEANUP_STATE';\nexport const SET_ACTIVE_ROTATE_DOCUMENT = 'ROTATE/SET_ACTIVE_DOCUMENT';\n\n// Rotation operations\nexport const SET_ROTATION = 'ROTATE/SET_ROTATION';\n\n// Document lifecycle actions\nexport interface InitRotateStateAction extends Action {\n type: typeof INIT_ROTATE_STATE;\n payload: {\n documentId: string;\n state: RotateDocumentState;\n };\n}\n\nexport interface CleanupRotateStateAction extends Action {\n type: typeof CLEANUP_ROTATE_STATE;\n payload: string; // documentId\n}\n\nexport interface SetActiveRotateDocumentAction extends Action {\n type: typeof SET_ACTIVE_ROTATE_DOCUMENT;\n payload: string | null; // documentId\n}\n\nexport interface SetRotationAction extends Action {\n type: typeof SET_ROTATION;\n payload: {\n documentId: string;\n rotation: Rotation;\n };\n}\n\nexport type RotateAction =\n | InitRotateStateAction\n | CleanupRotateStateAction\n | SetActiveRotateDocumentAction\n | SetRotationAction;\n\n// Action Creators\nexport function initRotateState(\n documentId: string,\n state: RotateDocumentState,\n): InitRotateStateAction {\n return { type: INIT_ROTATE_STATE, payload: { documentId, state } };\n}\n\nexport function cleanupRotateState(documentId: string): CleanupRotateStateAction {\n return { type: CLEANUP_ROTATE_STATE, payload: documentId };\n}\n\nexport function setActiveRotateDocument(documentId: string | null): SetActiveRotateDocumentAction {\n return { type: SET_ACTIVE_ROTATE_DOCUMENT, payload: documentId };\n}\n\nexport function setRotation(documentId: string, rotation: Rotation): SetRotationAction {\n return { type: SET_ROTATION, payload: { documentId, rotation } };\n}\n","import {\n BasePlugin,\n createBehaviorEmitter,\n Listener,\n PluginRegistry,\n setRotation as setCoreRotation,\n} from '@embedpdf/core';\nimport { Rotation } from '@embedpdf/models';\nimport {\n GetMatrixOptions,\n RotateCapability,\n RotatePluginConfig,\n RotateScope,\n RotationChangeEvent,\n RotateState,\n RotateDocumentState,\n} from './types';\nimport { getNextRotation, getPreviousRotation, getRotationMatrixString } from './utils';\nimport { initRotateState, cleanupRotateState, setRotation, RotateAction } from './actions';\n\nexport class RotatePlugin extends BasePlugin<\n RotatePluginConfig,\n RotateCapability,\n RotateState,\n RotateAction\n> {\n static readonly id = 'rotate' as const;\n\n private readonly rotate$ = createBehaviorEmitter<RotationChangeEvent>();\n private readonly defaultRotation: Rotation;\n\n constructor(id: string, registry: PluginRegistry, cfg: RotatePluginConfig) {\n super(id, registry);\n this.defaultRotation = cfg.defaultRotation ?? 0;\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Lifecycle Hooks (from BasePlugin)\n // ─────────────────────────────────────────────────────────\n\n protected override onDocumentLoadingStarted(documentId: string): void {\n // Initialize rotation state for this document\n const docState: RotateDocumentState = {\n rotation: this.defaultRotation,\n };\n\n this.dispatch(initRotateState(documentId, docState));\n\n // Also set in core state for backwards compatibility\n this.dispatchCoreAction(setCoreRotation(this.defaultRotation, documentId));\n\n this.logger.debug(\n 'RotatePlugin',\n 'DocumentOpened',\n `Initialized rotation state for document: ${documentId}`,\n );\n }\n\n protected override onDocumentClosed(documentId: string): void {\n this.dispatch(cleanupRotateState(documentId));\n\n this.logger.debug(\n 'RotatePlugin',\n 'DocumentClosed',\n `Cleaned up rotation state for document: ${documentId}`,\n );\n }\n\n // ─────────────────────────────────────────────────────────\n // Capability\n // ─────────────────────────────────────────────────────────\n\n protected buildCapability(): RotateCapability {\n return {\n // Active document operations\n setRotation: (rotation: Rotation) => this.setRotationForDocument(rotation),\n getRotation: () => this.getRotationForDocument(),\n rotateForward: () => this.rotateForward(),\n rotateBackward: () => this.rotateBackward(),\n\n // Document-scoped operations\n forDocument: (documentId: string) => this.createRotateScope(documentId),\n\n // Events\n onRotateChange: this.rotate$.on,\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // Document Scoping\n // ─────────────────────────────────────────────────────────\n\n private createRotateScope(documentId: string): RotateScope {\n return {\n setRotation: (rotation: Rotation) => this.setRotationForDocument(rotation, documentId),\n getRotation: () => this.getRotationForDocument(documentId),\n rotateForward: () => this.rotateForward(documentId),\n rotateBackward: () => this.rotateBackward(documentId),\n onRotateChange: (listener: Listener<Rotation>) =>\n this.rotate$.on((event) => {\n if (event.documentId === documentId) listener(event.rotation);\n }),\n };\n }\n\n // ─────────────────────────────────────────────────────────\n // State Helpers\n // ─────────────────────────────────────────────────────────\n private getDocumentState(documentId?: string): RotateDocumentState | null {\n const id = documentId ?? this.getActiveDocumentId();\n return this.state.documents[id] ?? null;\n }\n\n private getDocumentStateOrThrow(documentId?: string): RotateDocumentState {\n const state = this.getDocumentState(documentId);\n if (!state) {\n throw new Error(`Rotation state not found for document: ${documentId ?? 'active'}`);\n }\n return state;\n }\n\n // ─────────────────────────────────────────────────────────\n // Core Operations\n // ─────────────────────────────────────────────────────────\n\n private setRotationForDocument(rotation: Rotation, documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n const coreDoc = this.coreState.core.documents[id];\n\n if (!coreDoc?.document) {\n throw new Error(`Document ${id} not loaded`);\n }\n\n // Update plugin state\n this.dispatch(setRotation(id, rotation));\n\n // Update core state for backwards compatibility\n this.dispatchCoreAction(setCoreRotation(rotation, id));\n\n // Emit event\n this.rotate$.emit({\n documentId: id,\n rotation,\n });\n }\n\n private getRotationForDocument(documentId?: string): Rotation {\n return this.getDocumentStateOrThrow(documentId).rotation;\n }\n\n private rotateForward(documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n const currentRotation = this.getRotationForDocument(id);\n const nextRotation = getNextRotation(currentRotation);\n this.setRotationForDocument(nextRotation, id);\n }\n\n private rotateBackward(documentId?: string): void {\n const id = documentId ?? this.getActiveDocumentId();\n const currentRotation = this.getRotationForDocument(id);\n const prevRotation = getPreviousRotation(currentRotation);\n this.setRotationForDocument(prevRotation, id);\n }\n\n public getMatrixAsString(options: GetMatrixOptions): string {\n return getRotationMatrixString(options.rotation, options.width, options.height);\n }\n\n // ─────────────────────────────────────────────────────────\n // Store Update Handlers\n // ─────────────────────────────────────────────────────────\n\n override onStoreUpdated(prevState: RotateState, newState: RotateState): void {\n // Emit rotation change events for each changed document\n for (const documentId in newState.documents) {\n const prevDoc = prevState.documents[documentId];\n const newDoc = newState.documents[documentId];\n\n if (prevDoc?.rotation !== newDoc.rotation) {\n this.logger.debug(\n 'RotatePlugin',\n 'RotationChanged',\n `Rotation changed for document ${documentId}: ${prevDoc?.rotation ?? 0} -> ${newDoc.rotation}`,\n );\n }\n }\n }\n\n // ─────────────────────────────────────────────────────────\n // Lifecycle\n // ─────────────────────────────────────────────────────────\n\n async initialize(_config: RotatePluginConfig): Promise<void> {\n this.logger.info('RotatePlugin', 'Initialize', 'Rotate plugin initialized');\n }\n\n async destroy(): Promise<void> {\n this.rotate$.clear();\n super.destroy();\n }\n}\n","import { Reducer } from '@embedpdf/core';\nimport {\n RotateAction,\n INIT_ROTATE_STATE,\n CLEANUP_ROTATE_STATE,\n SET_ACTIVE_ROTATE_DOCUMENT,\n SET_ROTATION,\n} from './actions';\nimport { RotateState, RotateDocumentState } from './types';\n\nexport const initialDocumentState: RotateDocumentState = {\n rotation: 0,\n};\n\nexport const initialState: RotateState = {\n documents: {},\n activeDocumentId: null,\n};\n\nexport const rotateReducer: Reducer<RotateState, RotateAction> = (state = initialState, action) => {\n switch (action.type) {\n case INIT_ROTATE_STATE: {\n const { documentId, state: docState } = action.payload;\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: docState,\n },\n // Set as active if no active document\n activeDocumentId: state.activeDocumentId ?? documentId,\n };\n }\n\n case CLEANUP_ROTATE_STATE: {\n const documentId = action.payload;\n const { [documentId]: removed, ...remainingDocs } = state.documents;\n return {\n ...state,\n documents: remainingDocs,\n activeDocumentId: state.activeDocumentId === documentId ? null : state.activeDocumentId,\n };\n }\n\n case SET_ACTIVE_ROTATE_DOCUMENT: {\n return {\n ...state,\n activeDocumentId: action.payload,\n };\n }\n\n case SET_ROTATION: {\n const { documentId, rotation } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...docState,\n rotation,\n },\n },\n };\n }\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, ROTATE_PLUGIN_ID } from './manifest';\nimport { RotatePluginConfig, RotateState } from './types';\nimport { RotatePlugin } from './rotate-plugin';\nimport { RotateAction } from './actions';\nimport { rotateReducer, initialState } from './reducer';\n\nexport const RotatePluginPackage: PluginPackage<\n RotatePlugin,\n RotatePluginConfig,\n RotateState,\n RotateAction\n> = {\n manifest,\n create: (registry, config) => new RotatePlugin(ROTATE_PLUGIN_ID, registry, config),\n reducer: rotateReducer,\n initialState,\n};\n\nexport * from './rotate-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './actions';\nexport * from './reducer';\nexport * from './utils';\n"],"names":["setCoreRotation"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { Action } from '@embedpdf/core';
2
+ import { Rotation } from '@embedpdf/models';
3
+ import { RotateDocumentState } from './types';
4
+ export declare const INIT_ROTATE_STATE = "ROTATE/INIT_STATE";
5
+ export declare const CLEANUP_ROTATE_STATE = "ROTATE/CLEANUP_STATE";
6
+ export declare const SET_ACTIVE_ROTATE_DOCUMENT = "ROTATE/SET_ACTIVE_DOCUMENT";
7
+ export declare const SET_ROTATION = "ROTATE/SET_ROTATION";
8
+ export interface InitRotateStateAction extends Action {
9
+ type: typeof INIT_ROTATE_STATE;
10
+ payload: {
11
+ documentId: string;
12
+ state: RotateDocumentState;
13
+ };
14
+ }
15
+ export interface CleanupRotateStateAction extends Action {
16
+ type: typeof CLEANUP_ROTATE_STATE;
17
+ payload: string;
18
+ }
19
+ export interface SetActiveRotateDocumentAction extends Action {
20
+ type: typeof SET_ACTIVE_ROTATE_DOCUMENT;
21
+ payload: string | null;
22
+ }
23
+ export interface SetRotationAction extends Action {
24
+ type: typeof SET_ROTATION;
25
+ payload: {
26
+ documentId: string;
27
+ rotation: Rotation;
28
+ };
29
+ }
30
+ export type RotateAction = InitRotateStateAction | CleanupRotateStateAction | SetActiveRotateDocumentAction | SetRotationAction;
31
+ export declare function initRotateState(documentId: string, state: RotateDocumentState): InitRotateStateAction;
32
+ export declare function cleanupRotateState(documentId: string): CleanupRotateStateAction;
33
+ export declare function setActiveRotateDocument(documentId: string | null): SetActiveRotateDocumentAction;
34
+ export declare function setRotation(documentId: string, rotation: Rotation): SetRotationAction;
@@ -1,7 +1,11 @@
1
1
  import { PluginPackage } from '@embedpdf/core';
2
- import { RotatePluginConfig } from './types';
2
+ import { RotatePluginConfig, RotateState } from './types';
3
3
  import { RotatePlugin } from './rotate-plugin';
4
- export declare const RotatePluginPackage: PluginPackage<RotatePlugin, RotatePluginConfig>;
4
+ import { RotateAction } from './actions';
5
+ export declare const RotatePluginPackage: PluginPackage<RotatePlugin, RotatePluginConfig, RotateState, RotateAction>;
5
6
  export * from './rotate-plugin';
6
7
  export * from './types';
7
8
  export * from './manifest';
9
+ export * from './actions';
10
+ export * from './reducer';
11
+ export * from './utils';
@@ -0,0 +1,6 @@
1
+ import { Reducer } from '@embedpdf/core';
2
+ import { RotateAction } from './actions';
3
+ import { RotateState, RotateDocumentState } from './types';
4
+ export declare const initialDocumentState: RotateDocumentState;
5
+ export declare const initialState: RotateState;
6
+ export declare const rotateReducer: Reducer<RotateState, RotateAction>;
@@ -1,14 +1,23 @@
1
1
  import { BasePlugin, PluginRegistry } from '@embedpdf/core';
2
- import { GetMatrixOptions, RotateCapability, RotatePluginConfig } from './types';
3
- export declare class RotatePlugin extends BasePlugin<RotatePluginConfig, RotateCapability> {
2
+ import { GetMatrixOptions, RotateCapability, RotatePluginConfig, RotateState } from './types';
3
+ import { RotateAction } from './actions';
4
+ export declare class RotatePlugin extends BasePlugin<RotatePluginConfig, RotateCapability, RotateState, RotateAction> {
4
5
  static readonly id: "rotate";
5
6
  private readonly rotate$;
7
+ private readonly defaultRotation;
6
8
  constructor(id: string, registry: PluginRegistry, cfg: RotatePluginConfig);
7
- initialize(_config: RotatePluginConfig): Promise<void>;
8
- private setRotation;
9
+ protected onDocumentLoadingStarted(documentId: string): void;
10
+ protected onDocumentClosed(documentId: string): void;
11
+ protected buildCapability(): RotateCapability;
12
+ private createRotateScope;
13
+ private getDocumentState;
14
+ private getDocumentStateOrThrow;
15
+ private setRotationForDocument;
16
+ private getRotationForDocument;
9
17
  private rotateForward;
10
18
  private rotateBackward;
11
- protected buildCapability(): RotateCapability;
12
- getMatrixAsString(options?: GetMatrixOptions): string;
19
+ getMatrixAsString(options: GetMatrixOptions): string;
20
+ onStoreUpdated(prevState: RotateState, newState: RotateState): void;
21
+ initialize(_config: RotatePluginConfig): Promise<void>;
13
22
  destroy(): Promise<void>;
14
23
  }
@@ -4,16 +4,33 @@ export interface RotatePluginConfig extends BasePluginConfig {
4
4
  defaultRotation?: Rotation;
5
5
  }
6
6
  export interface GetMatrixOptions {
7
- w: number;
8
- h: number;
7
+ width: number;
8
+ height: number;
9
+ rotation: Rotation;
9
10
  }
10
- export interface RotateCapability {
11
- onRotateChange: EventHook<Rotation>;
11
+ export interface RotateDocumentState {
12
+ rotation: Rotation;
13
+ }
14
+ export interface RotateState {
15
+ documents: Record<string, RotateDocumentState>;
16
+ activeDocumentId: string | null;
17
+ }
18
+ export interface RotationChangeEvent {
19
+ documentId: string;
20
+ rotation: Rotation;
21
+ }
22
+ export interface RotateScope {
12
23
  setRotation(rotation: Rotation): void;
13
24
  getRotation(): Rotation;
14
25
  rotateForward(): void;
15
26
  rotateBackward(): void;
27
+ onRotateChange: EventHook<Rotation>;
16
28
  }
17
- export interface RotateState {
18
- rotation: Rotation;
29
+ export interface RotateCapability {
30
+ setRotation(rotation: Rotation): void;
31
+ getRotation(): Rotation;
32
+ rotateForward(): void;
33
+ rotateBackward(): void;
34
+ forDocument(documentId: string): RotateScope;
35
+ onRotateChange: EventHook<RotationChangeEvent>;
19
36
  }
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-rotate");require("preact");const r=require("preact/hooks"),o=require("preact/jsx-runtime"),i=()=>e.usePlugin(t.RotatePlugin.id),s=()=>e.useCapability(t.RotatePlugin.id);exports.Rotate=function({children:e,pageSize:t,style:r,...s}){const{plugin:a}=i(),n=(null==a?void 0:a.getMatrixAsString({w:t.width,h:t.height}))||"matrix(1, 0, 0, 1, 0, 0)";return o.jsx("div",{...s,style:{position:"absolute",transformOrigin:"0 0",transform:n,...r},children:e})},exports.useRotate=()=>{const{provides:e}=s(),[t,o]=r.useState(0);return r.useEffect((()=>null==e?void 0:e.onRotateChange((e=>o(e)))),[e]),{rotation:t,provides:e}},exports.useRotateCapability=s,exports.useRotatePlugin=i,Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-rotate");require("preact");const o=require("preact/hooks"),r=require("preact/jsx-runtime"),i=()=>e.usePlugin(t.RotatePlugin.id),n=()=>e.useCapability(t.RotatePlugin.id);exports.Rotate=function({children:t,documentId:o,pageIndex:n,rotation:u,scale:l,style:a,...s}){var d,c,p,g;const{plugin:v}=i(),f=e.useDocumentState(o),m=null==(c=null==(d=null==f?void 0:f.document)?void 0:d.pages)?void 0:c[n],h=(null==(p=null==m?void 0:m.size)?void 0:p.width)??0,x=(null==(g=null==m?void 0:m.size)?void 0:g.height)??0,b=u??(null==f?void 0:f.rotation)??0,y=l??(null==f?void 0:f.scale)??1,R=(null==v?void 0:v.getMatrixAsString({width:h*y,height:x*y,rotation:b}))??"matrix(1, 0, 0, 1, 0, 0)";return m?r.jsx("div",{...s,style:{position:"absolute",transformOrigin:"0 0",transform:R,...a},children:t}):null},exports.useRotate=e=>{const{provides:r}=n(),[i,u]=o.useState(t.initialDocumentState.rotation);return o.useEffect(()=>{if(!r)return;const t=r.forDocument(e);return u(t.getRotation()),t.onRotateChange(e=>{u(e)})},[r,e]),{rotation:i,provides:(null==r?void 0:r.forDocument(e))??null}},exports.useRotateCapability=n,exports.useRotatePlugin=i,Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-rotate.ts","../../src/shared/components/rotate.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { Rotation } from '@embedpdf/models';\nimport { RotatePlugin } from '@embedpdf/plugin-rotate';\nimport { useEffect, useState } from '@framework';\n\nexport const useRotatePlugin = () => usePlugin<RotatePlugin>(RotatePlugin.id);\nexport const useRotateCapability = () => useCapability<RotatePlugin>(RotatePlugin.id);\n\nexport const useRotate = () => {\n const { provides } = useRotateCapability();\n const [rotation, setRotation] = useState<Rotation>(0);\n\n useEffect(() => {\n return provides?.onRotateChange((rotation) => setRotation(rotation));\n }, [provides]);\n\n return {\n rotation,\n provides,\n };\n};\n","import { ReactNode, HTMLAttributes, CSSProperties } from '@framework';\nimport { Size } from '@embedpdf/models';\n\nimport { useRotatePlugin } from '../hooks';\n\ntype RotateProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n children: ReactNode;\n pageSize: Size;\n style?: CSSProperties;\n};\n\nexport function Rotate({ children, pageSize, style, ...props }: RotateProps) {\n const { plugin: rotate } = useRotatePlugin();\n const matrix =\n rotate?.getMatrixAsString({\n w: pageSize.width,\n h: pageSize.height,\n }) || 'matrix(1, 0, 0, 1, 0, 0)';\n\n return (\n <div\n {...props}\n style={{\n position: 'absolute',\n transformOrigin: '0 0',\n transform: matrix,\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n"],"names":["useRotatePlugin","usePlugin","RotatePlugin","id","useRotateCapability","useCapability","children","pageSize","style","props","plugin","rotate","matrix","getMatrixAsString","w","width","h","height","jsxRuntime","jsx","position","transformOrigin","transform","provides","rotation","setRotation","useState","useEffect","onRotateChange"],"mappings":"gPAKaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,mBCK3E,UAAgBG,SAAEA,EAAAC,SAAUA,QAAUC,KAAUC,IACrD,MAAQC,OAAQC,GAAWX,IACrBY,SACJD,WAAQE,kBAAkB,CACxBC,EAAGP,EAASQ,MACZC,EAAGT,EAASU,WACR,2BAGN,OAAAC,EAAAC,IAAC,MAAA,IACKV,EACJD,MAAO,CACLY,SAAU,WACVC,gBAAiB,MACjBC,UAAWV,KACRJ,GAGJF,YAGP,oBDxByB,KACjB,MAAAiB,SAAEA,GAAanB,KACdoB,EAAUC,GAAeC,EAAAA,SAAmB,GAM5C,OAJPC,EAAAA,WAAU,IACS,MAAVJ,OAAU,EAAAA,EAAAK,gBAAgBJ,GAAaC,EAAYD,MACzD,CAACD,IAEG,CACLC,WACAD,WACF"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-rotate.ts","../../src/shared/components/rotate.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { Rotation } from '@embedpdf/models';\nimport { initialDocumentState, RotatePlugin } from '@embedpdf/plugin-rotate';\nimport { useEffect, useState } from '@framework';\n\nexport const useRotatePlugin = () => usePlugin<RotatePlugin>(RotatePlugin.id);\nexport const useRotateCapability = () => useCapability<RotatePlugin>(RotatePlugin.id);\n\n/**\n * Hook for rotation state for a specific document\n * @param documentId Document ID\n */\nexport const useRotate = (documentId: string) => {\n const { provides } = useRotateCapability();\n const [rotation, setRotation] = useState<Rotation>(initialDocumentState.rotation);\n\n useEffect(() => {\n if (!provides) return;\n\n const scope = provides.forDocument(documentId);\n\n // Get initial state\n setRotation(scope.getRotation());\n\n // Subscribe to rotation changes\n return scope.onRotateChange((newRotation) => {\n setRotation(newRotation);\n });\n }, [provides, documentId]);\n\n return {\n rotation,\n provides: provides?.forDocument(documentId) ?? null,\n };\n};\n","import { ReactNode, HTMLAttributes, CSSProperties } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { Rotation } from '@embedpdf/models';\n\nimport { useRotatePlugin } from '../hooks';\n\ntype RotateProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n children: ReactNode;\n documentId: string;\n pageIndex: number;\n rotation?: Rotation;\n scale?: number;\n style?: CSSProperties;\n};\n\nexport function Rotate({\n children,\n documentId,\n pageIndex,\n rotation: rotationOverride,\n scale: scaleOverride,\n style,\n ...props\n}: RotateProps) {\n const { plugin: rotatePlugin } = useRotatePlugin();\n const documentState = useDocumentState(documentId);\n\n const page = documentState?.document?.pages?.[pageIndex];\n const width = page?.size?.width ?? 0;\n const height = page?.size?.height ?? 0;\n const rotation = rotationOverride ?? documentState?.rotation ?? 0;\n const scale = scaleOverride ?? documentState?.scale ?? 1;\n\n const matrix =\n rotatePlugin?.getMatrixAsString({\n width: width * scale,\n height: height * scale,\n rotation: rotation,\n }) ?? 'matrix(1, 0, 0, 1, 0, 0)';\n\n if (!page) return null;\n\n return (\n <div\n {...props}\n style={{\n position: 'absolute',\n transformOrigin: '0 0',\n transform: matrix,\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n"],"names":["useRotatePlugin","usePlugin","RotatePlugin","id","useRotateCapability","useCapability","children","documentId","pageIndex","rotation","rotationOverride","scale","scaleOverride","style","props","plugin","rotatePlugin","documentState","useDocumentState","page","_b","_a","document","pages","width","_c","size","height","_d","matrix","getMatrixAsString","jsx","position","transformOrigin","transform","provides","setRotation","useState","initialDocumentState","useEffect","scope","forDocument","getRotation","onRotateChange","newRotation"],"mappings":"gPAKaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,mBCS3E,UAAgBG,SACrBA,EAAAC,WACAA,EAAAC,UACAA,EACAC,SAAUC,EACVC,MAAOC,EAAAC,MACPA,KACGC,gBAEH,MAAQC,OAAQC,GAAiBhB,IAC3BiB,EAAgBC,EAAAA,iBAAiBX,GAEjCY,EAAO,OAAAC,EAAA,OAAAC,EAAA,MAAAJ,OAAA,EAAAA,EAAeK,eAAf,EAAAD,EAAyBE,YAAzB,EAAAH,EAAiCZ,GACxCgB,GAAQ,OAAAC,EAAA,MAAAN,OAAA,EAAAA,EAAMO,WAAN,EAAAD,EAAYD,QAAS,EAC7BG,GAAS,OAAAC,EAAA,MAAAT,OAAA,EAAAA,EAAMO,WAAN,EAAAE,EAAYD,SAAU,EAC/BlB,EAAWC,IAAoB,MAAAO,OAAA,EAAAA,EAAeR,WAAY,EAC1DE,EAAQC,IAAiB,MAAAK,OAAA,EAAAA,EAAeN,QAAS,EAEjDkB,SACJb,WAAcc,kBAAkB,CAC9BN,MAAOA,EAAQb,EACfgB,OAAQA,EAAShB,EACjBF,eACI,2BAER,OAAKU,EAGHY,EAAAA,IAAC,MAAA,IACKjB,EACJD,MAAO,CACLmB,SAAU,WACVC,gBAAiB,MACjBC,UAAWL,KACRhB,GAGJP,aAZa,IAepB,oBD3C0BC,IACxB,MAAM4B,SAAEA,GAAa/B,KACdK,EAAU2B,GAAeC,EAAAA,SAAmBC,EAAAA,qBAAqB7B,UAgBxE,OAdA8B,EAAAA,UAAU,KACR,IAAKJ,EAAU,OAEf,MAAMK,EAAQL,EAASM,YAAYlC,GAMnC,OAHA6B,EAAYI,EAAME,eAGXF,EAAMG,eAAgBC,IAC3BR,EAAYQ,MAEb,CAACT,EAAU5B,IAEP,CACLE,WACA0B,UAAU,MAAAA,OAAA,EAAAA,EAAUM,YAAYlC,KAAe"}