@embedpdf/plugin-tiling 1.3.11 → 1.3.13

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 e=require("@embedpdf/core"),i=require("@embedpdf/models"),t="tiling",s={id:t,name:"Tiling Plugin",version:"1.0.0",provides:["tiling"],requires:["render","scroll","viewport"],optional:[],defaultConfig:{enabled:!0,tileSize:768,overlapPx:2.5,extraRings:0}},r="UPDATE_VISIBLE_TILES",a="MARK_TILE_STATUS",l=e=>({type:r,payload:e}),o=(e,i,t)=>({type:a,payload:{pageIndex:e,tileId:i,status:t}});function n({tileSize:e=768,overlapPx:t=2.5,extraRings:s=0,scale:r,rotation:a,page:l,metric:o}){const n=l.size.width*r,c=l.size.height*r,d=e-t,h=i.transformSize(l.size,a,r),g={origin:{x:o.scaled.pageX,y:o.scaled.pageY},size:{width:o.scaled.visibleWidth,height:o.scaled.visibleHeight}},p=i.restoreRect(h,g,a,1),u=p.origin.x,f=p.origin.y,b=u+p.size.width,y=f+p.size.height,v=Math.floor((n-1)/d),x=Math.floor((c-1)/d),m=Math.max(0,Math.floor(u/d)-s),S=Math.min(v,Math.floor((b-1)/d)+s),T=Math.max(0,Math.floor(f/d)-s),P=Math.min(x,Math.floor((y-1)/d)+s),w=[];for(let i=m;i<=S;i++){const t=i*d,s=Math.min(e,n-t),a=t/r,o=s/r;for(let n=T;n<=P;n++){const h=n*d,g=Math.min(e,c-h),p=h/r,u=g/r;w.push({id:`p${l.index}-${r}-x${t}-y${h}-w${s}-h${g}`,col:i,row:n,pageRect:{origin:{x:a,y:p},size:{width:o,height:u}},screenRect:{origin:{x:t,y:h},size:{width:s,height:g}},status:"queued",srcScale:r,isFallback:!1})}}return w}const c=class extends e.BasePlugin{constructor(i,t,s){super(i,t),this.tileRendering$=e.createBehaviorEmitter(),this.refreshPages$=e.createEmitter(),this.config=s,this.renderCapability=this.registry.getPlugin("render").provides(),this.scrollCapability=this.registry.getPlugin("scroll").provides(),this.viewportCapability=this.registry.getPlugin("viewport").provides(),this.scrollCapability.onScroll((e=>this.calculateVisibleTiles(e)),{mode:"throttle",wait:50,throttleMode:"trailing"}),this.coreStore.onAction(e.REFRESH_PAGES,(e=>{this.refreshPages$.emit(e.payload)}))}async initialize(){}onCoreStoreUpdated(e,i){e.core.scale!==i.core.scale&&this.calculateVisibleTiles(this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()))}onRefreshPages(e){return this.refreshPages$.on(e)}calculateVisibleTiles(e){var i;if(!this.config.enabled)return void this.dispatch(l([]));const t=this.coreState.core.scale,s=this.coreState.core.rotation,r={};for(const a of e.pageVisibilityMetrics){const e=a.pageNumber-1,l=null==(i=this.coreState.core.document)?void 0:i.pages[e];if(!l)continue;const o=n({page:l,metric:a,scale:t,rotation:s,tileSize:this.config.tileSize,overlapPx:this.config.overlapPx,extraRings:this.config.extraRings});r[e]=o}this.dispatch(l(r))}onStoreUpdated(e,i){this.tileRendering$.emit(i.visibleTiles)}buildCapability(){return{renderTile:this.renderTile.bind(this),onTileRendering:this.tileRendering$.on}}renderTile(e){if(!this.renderCapability)throw new Error("Render capability not available.");this.dispatch(o(e.pageIndex,e.tile.id,"rendering"));const t=this.renderCapability.renderPageRect({pageIndex:e.pageIndex,rect:e.tile.pageRect,options:{scaleFactor:e.tile.srcScale,dpr:e.dpr}});return t.wait((()=>{this.dispatch(o(e.pageIndex,e.tile.id,"ready"))}),i.ignore),t}};c.id="tiling";let d=c;const h={manifest:s,create:(e,i)=>new d(t,e,i),reducer:(e,i)=>((e,i)=>{var t,s;switch(i.type){case r:{const s=i.payload,r={...e.visibleTiles};for(const e in s){const i=Number(e),a=s[i],l=r[i]??[],o=null==(t=l.find((e=>!e.isFallback)))?void 0:t.srcScale,n=a[0].srcScale;if(void 0!==o&&o!==n){const e=l.filter((e=>!e.isFallback&&"ready"===e.status)).map((e=>({...e,isFallback:!0}))),t=e.length>0?[]:l.filter((e=>e.isFallback));r[i]=[...t,...e,...a]}else{const e=new Set(a.map((e=>e.id))),t=[],s=new Set;for(const i of l)(i.isFallback||e.has(i.id))&&(t.push(i),s.add(i.id));for(const i of a)s.has(i.id)||t.push(i);r[i]=t}}return{...e,visibleTiles:r}}case a:{const{pageIndex:t,tileId:r,status:a}=i.payload,l=(null==(s=e.visibleTiles[t])?void 0:s.map((e=>e.id===r?{...e,status:a}:e)))??[],o=l.filter((e=>!e.isFallback)),n=o.every((e=>"ready"===e.status))?o:l;return{...e,visibleTiles:{...e.visibleTiles,[t]:n}}}default:return e}})(e,i),initialState:{visibleTiles:{}}};exports.TILING_PLUGIN_ID=t,exports.TilingPlugin=d,exports.TilingPluginPackage=h,exports.manifest=s;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core"),i=require("@embedpdf/models"),t="tiling",s={id:t,name:"Tiling Plugin",version:"1.0.0",provides:["tiling"],requires:["render","scroll","viewport"],optional:[],defaultConfig:{enabled:!0,tileSize:768,overlapPx:2.5,extraRings:0}},a="UPDATE_VISIBLE_TILES",r="MARK_TILE_STATUS",l=e=>({type:a,payload:e}),o=(e,i,t)=>({type:r,payload:{pageIndex:e,tileId:i,status:t}});function n({tileSize:e=768,overlapPx:t=2.5,extraRings:s=0,scale:a,rotation:r,page:l,metric:o}){const n=l.size.width*a,c=l.size.height*a,d=e-t,h=i.transformSize(l.size,r,a),p={origin:{x:o.scaled.pageX,y:o.scaled.pageY},size:{width:o.scaled.visibleWidth,height:o.scaled.visibleHeight}},g=i.restoreRect(h,p,r,1),u=g.origin.x,b=g.origin.y,f=u+g.size.width,y=b+g.size.height,v=Math.floor((n-1)/d),x=Math.floor((c-1)/d),S=Math.max(0,Math.floor(u/d)-s),m=Math.min(v,Math.floor((f-1)/d)+s),T=Math.max(0,Math.floor(b/d)-s),w=Math.min(x,Math.floor((y-1)/d)+s),M=[];for(let i=S;i<=m;i++){const t=i*d,s=Math.min(e,n-t),r=t/a,o=s/a;for(let n=T;n<=w;n++){const h=n*d,p=Math.min(e,c-h),g=h/a,u=p/a;M.push({id:`p${l.index}-${a}-x${t}-y${h}-w${s}-h${p}`,col:i,row:n,pageRect:{origin:{x:r,y:g},size:{width:o,height:u}},screenRect:{origin:{x:t,y:h},size:{width:s,height:p}},status:"queued",srcScale:a,isFallback:!1})}}return M}const c=class extends e.BasePlugin{constructor(i,t,s){super(i,t),this.tileRendering$=e.createBehaviorEmitter(),this.config=s,this.renderCapability=this.registry.getPlugin("render").provides(),this.scrollCapability=this.registry.getPlugin("scroll").provides(),this.viewportCapability=this.registry.getPlugin("viewport").provides(),this.scrollCapability.onScroll((e=>this.calculateVisibleTiles(e)),{mode:"throttle",wait:50,throttleMode:"trailing"}),this.coreStore.onAction(e.REFRESH_PAGES,(e=>this.recalculateTiles(e.payload)))}async recalculateTiles(e){var i;const t=this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()),s={},a=Date.now();for(const r of e){const e=t.pageVisibilityMetrics.find((e=>e.pageNumber===r+1));if(!e)continue;const l=null==(i=this.coreState.core.document)?void 0:i.pages[r];l&&(s[r]=n({page:l,metric:e,scale:this.coreState.core.scale,rotation:this.coreState.core.rotation,tileSize:this.config.tileSize,overlapPx:this.config.overlapPx,extraRings:this.config.extraRings}).map((e=>({...e,id:`${e.id}-r${a}`}))))}Object.keys(s).length>0&&this.dispatch(l(s))}async initialize(){}onCoreStoreUpdated(e,i){e.core.scale!==i.core.scale&&this.calculateVisibleTiles(this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()))}calculateVisibleTiles(e){var i;if(!this.config.enabled)return void this.dispatch(l([]));const t=this.coreState.core.scale,s=this.coreState.core.rotation,a={};for(const r of e.pageVisibilityMetrics){const e=r.pageNumber-1,l=null==(i=this.coreState.core.document)?void 0:i.pages[e];if(!l)continue;const o=n({page:l,metric:r,scale:t,rotation:s,tileSize:this.config.tileSize,overlapPx:this.config.overlapPx,extraRings:this.config.extraRings});a[e]=o}this.dispatch(l(a))}onStoreUpdated(e,i){this.tileRendering$.emit(i.visibleTiles)}buildCapability(){return{renderTile:this.renderTile.bind(this),onTileRendering:this.tileRendering$.on}}renderTile(e){if(!this.renderCapability)throw new Error("Render capability not available.");this.dispatch(o(e.pageIndex,e.tile.id,"rendering"));const t=this.renderCapability.renderPageRect({pageIndex:e.pageIndex,rect:e.tile.pageRect,options:{scaleFactor:e.tile.srcScale,dpr:e.dpr}});return t.wait((()=>{this.dispatch(o(e.pageIndex,e.tile.id,"ready"))}),i.ignore),t}};c.id="tiling";let d=c;const h={manifest:s,create:(e,i)=>new d(t,e,i),reducer:(e,i)=>((e,i)=>{var t,s;switch(i.type){case a:{const s=i.payload,a={...e.visibleTiles};for(const e in s){const i=Number(e),r=s[i],l=a[i]??[],o=null==(t=l.find((e=>!e.isFallback)))?void 0:t.srcScale,n=r[0].srcScale;if(void 0!==o&&o!==n){const e=l.filter((e=>!e.isFallback&&"ready"===e.status)).map((e=>({...e,isFallback:!0}))),t=e.length>0?[]:l.filter((e=>e.isFallback));a[i]=[...t,...e,...r]}else{const e=new Set(r.map((e=>e.id))),t=[],s=new Set;for(const i of l)(i.isFallback||e.has(i.id))&&(t.push(i),s.add(i.id));for(const i of r)s.has(i.id)||t.push(i);a[i]=t}}return{...e,visibleTiles:a}}case r:{const{pageIndex:t,tileId:a,status:r}=i.payload,l=(null==(s=e.visibleTiles[t])?void 0:s.map((e=>e.id===a?{...e,status:r}:e)))??[],o=l.filter((e=>!e.isFallback)),n=o.every((e=>"ready"===e.status))?o:l;return{...e,visibleTiles:{...e.visibleTiles,[t]:n}}}default:return e}})(e,i),initialState:{visibleTiles:{}}};exports.TILING_PLUGIN_ID=t,exports.TilingPlugin=d,exports.TilingPluginPackage=h,exports.manifest=s;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/utils.ts","../src/lib/tiling-plugin.ts","../src/lib/index.ts","../src/lib/reducer.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\n\nimport { TilingPluginConfig } from './types';\n\nexport const TILING_PLUGIN_ID = 'tiling';\n\nexport const manifest: PluginManifest<TilingPluginConfig> = {\n id: TILING_PLUGIN_ID,\n name: 'Tiling Plugin',\n version: '1.0.0',\n provides: ['tiling'],\n requires: ['render', 'scroll', 'viewport'],\n optional: [],\n defaultConfig: {\n enabled: true,\n tileSize: 768,\n overlapPx: 2.5,\n extraRings: 0,\n },\n};\n","import { Tile, TileStatus } from './types';\n\nexport const UPDATE_VISIBLE_TILES = 'UPDATE_VISIBLE_TILES';\nexport const MARK_TILE_STATUS = 'MARK_TILE_STATUS';\n\nexport type UpdateVisibleTilesAction = {\n type: typeof UPDATE_VISIBLE_TILES;\n payload: Record<number, Tile[]>;\n};\n\nexport type MarkTileStatusAction = {\n type: typeof MARK_TILE_STATUS;\n payload: { pageIndex: number; tileId: string; status: TileStatus };\n};\n\nexport type TilingAction = UpdateVisibleTilesAction | MarkTileStatusAction;\n\nexport const updateVisibleTiles = (tiles: Record<number, Tile[]>): UpdateVisibleTilesAction => ({\n type: UPDATE_VISIBLE_TILES,\n payload: tiles,\n});\n\nexport const markTileStatus = (\n pageIndex: number,\n tileId: string,\n status: TileStatus,\n): MarkTileStatusAction => ({ type: MARK_TILE_STATUS, payload: { pageIndex, tileId, status } });\n","import { Rect, restoreRect, transformSize } from '@embedpdf/models';\nimport { CalculateTilesForPageOptions, Tile } from './types';\n\n/**\n * Build a grid where neighbouring tiles overlap by `overlapPx`\n * (screen pixels). Inner tiles keep the full `tileSize`, edge\n * tiles are clipped to the page bounds. All screen-space values\n * are rounded to **integers** to avoid sub-pixel seams.\n */\nexport function calculateTilesForPage({\n tileSize = 768,\n overlapPx = 2.5,\n extraRings = 0,\n scale,\n rotation,\n page,\n metric,\n}: CalculateTilesForPageOptions): Tile[] {\n /* ---- work in screen-pixel space -------------------------------- */\n const pageW = page.size.width * scale; // px\n const pageH = page.size.height * scale; // px\n\n const step = tileSize - overlapPx; // shift between tiles\n\n const containerSize = transformSize(page.size, rotation, scale);\n const rotatedVisRect: Rect = {\n origin: { x: metric.scaled.pageX, y: metric.scaled.pageY },\n size: { width: metric.scaled.visibleWidth, height: metric.scaled.visibleHeight },\n };\n const unrotatedVisRect = restoreRect(containerSize, rotatedVisRect, rotation, 1);\n\n const visLeft = unrotatedVisRect.origin.x;\n const visTop = unrotatedVisRect.origin.y;\n const visRight = visLeft + unrotatedVisRect.size.width;\n const visBottom = visTop + unrotatedVisRect.size.height;\n\n const maxCol = Math.floor((pageW - 1) / step);\n const maxRow = Math.floor((pageH - 1) / step);\n\n const startCol = Math.max(0, Math.floor(visLeft / step) - extraRings);\n const endCol = Math.min(maxCol, Math.floor((visRight - 1) / step) + extraRings);\n const startRow = Math.max(0, Math.floor(visTop / step) - extraRings);\n const endRow = Math.min(maxRow, Math.floor((visBottom - 1) / step) + extraRings);\n\n /* ---- build tiles ---------------------------------------------- */\n const tiles: Tile[] = [];\n\n for (let col = startCol; col <= endCol; col++) {\n const xScreen = col * step; // px (integer)\n const wScreen = Math.min(tileSize, pageW - xScreen); // px (≤ tileSize)\n\n const xPage = xScreen / scale; // pt (may be frac.)\n const wPage = wScreen / scale; // pt\n\n for (let row = startRow; row <= endRow; row++) {\n const yScreen = row * step;\n const hScreen = Math.min(tileSize, pageH - yScreen);\n\n const yPage = yScreen / scale;\n const hPage = hScreen / scale;\n\n tiles.push({\n id: `p${page.index}-${scale}-x${xScreen}-y${yScreen}-w${wScreen}-h${hScreen}`,\n col,\n row,\n pageRect: { origin: { x: xPage, y: yPage }, size: { width: wPage, height: hPage } },\n screenRect: {\n origin: { x: xScreen, y: yScreen },\n size: { width: wScreen, height: hScreen },\n },\n status: 'queued',\n srcScale: scale,\n isFallback: false,\n });\n }\n }\n\n return tiles;\n}\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n createEmitter,\n PluginRegistry,\n REFRESH_PAGES,\n StoreState,\n Unsubscribe,\n} from '@embedpdf/core';\nimport { ignore } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\nimport { ScrollCapability, ScrollMetrics, ScrollPlugin } from '@embedpdf/plugin-scroll';\nimport { ViewportCapability, ViewportPlugin } from '@embedpdf/plugin-viewport';\n\nimport { markTileStatus, updateVisibleTiles } from './actions';\nimport {\n TilingPluginConfig,\n TilingCapability,\n Tile,\n RenderTileOptions,\n TilingState,\n} from './types';\nimport { calculateTilesForPage } from './utils';\n\nexport class TilingPlugin extends BasePlugin<TilingPluginConfig, TilingCapability> {\n static readonly id = 'tiling' as const;\n\n private readonly tileRendering$ = createBehaviorEmitter<Record<number, Tile[]>>();\n private readonly refreshPages$ = createEmitter<number[]>();\n\n private config: TilingPluginConfig;\n private renderCapability: RenderCapability;\n private scrollCapability: ScrollCapability;\n private viewportCapability: ViewportCapability;\n\n constructor(id: string, registry: PluginRegistry, config: TilingPluginConfig) {\n super(id, registry);\n\n this.config = config;\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n this.scrollCapability = this.registry.getPlugin<ScrollPlugin>('scroll')!.provides();\n this.viewportCapability = this.registry.getPlugin<ViewportPlugin>('viewport')!.provides();\n\n this.scrollCapability.onScroll((scrollMetrics) => this.calculateVisibleTiles(scrollMetrics), {\n mode: 'throttle',\n wait: 50,\n throttleMode: 'trailing',\n });\n\n this.coreStore.onAction(REFRESH_PAGES, (action) => {\n this.refreshPages$.emit(action.payload);\n });\n }\n\n async initialize(): Promise<void> {\n // Fetch dependencies from the registry if needed\n }\n\n protected onCoreStoreUpdated(\n oldState: StoreState<CoreState>,\n newState: StoreState<CoreState>,\n ): void {\n if (oldState.core.scale !== newState.core.scale) {\n this.calculateVisibleTiles(\n this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()),\n );\n }\n }\n\n public onRefreshPages(fn: (pages: number[]) => void): Unsubscribe {\n return this.refreshPages$.on(fn);\n }\n\n private calculateVisibleTiles(scrollMetrics: ScrollMetrics): void {\n if (!this.config.enabled) {\n this.dispatch(updateVisibleTiles([]));\n return;\n }\n\n const scale = this.coreState.core.scale;\n const rotation = this.coreState.core.rotation;\n const visibleTiles: { [pageIndex: number]: Tile[] } = {};\n\n for (const scrollMetric of scrollMetrics.pageVisibilityMetrics) {\n const pageIndex = scrollMetric.pageNumber - 1; // Convert to 0-based index\n const page = this.coreState.core.document?.pages[pageIndex];\n if (!page) continue;\n\n // Calculate tiles for the page using the utility function\n const tiles = calculateTilesForPage({\n page,\n metric: scrollMetric,\n scale,\n rotation,\n tileSize: this.config.tileSize,\n overlapPx: this.config.overlapPx,\n extraRings: this.config.extraRings,\n });\n\n visibleTiles[pageIndex] = tiles;\n }\n\n this.dispatch(updateVisibleTiles(visibleTiles));\n }\n\n override onStoreUpdated(_prevState: TilingState, newState: TilingState): void {\n this.tileRendering$.emit(newState.visibleTiles);\n }\n\n protected buildCapability(): TilingCapability {\n return {\n renderTile: this.renderTile.bind(this),\n onTileRendering: this.tileRendering$.on,\n };\n }\n\n private renderTile(options: RenderTileOptions) {\n if (!this.renderCapability) {\n throw new Error('Render capability not available.');\n }\n\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'rendering'));\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: options.pageIndex,\n rect: options.tile.pageRect,\n options: {\n scaleFactor: options.tile.srcScale,\n dpr: options.dpr,\n },\n });\n\n task.wait(() => {\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'ready'));\n }, ignore);\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { TilingAction } from './actions';\nimport { manifest, TILING_PLUGIN_ID } from './manifest';\nimport { initialState, tilingReducer } from './reducer';\nimport { TilingPlugin } from './tiling-plugin';\nimport { TilingPluginConfig, TilingState } from './types';\n\nexport const TilingPluginPackage: PluginPackage<\n TilingPlugin,\n TilingPluginConfig,\n TilingState,\n TilingAction\n> = {\n manifest,\n create: (registry, config) => new TilingPlugin(TILING_PLUGIN_ID, registry, config),\n reducer: (state, action) => tilingReducer(state, action),\n initialState,\n};\n\nexport * from './tiling-plugin';\nexport * from './types';\nexport * from './manifest';\n","import { Reducer } from '@embedpdf/core';\n\nimport { UPDATE_VISIBLE_TILES, MARK_TILE_STATUS, TilingAction } from './actions';\nimport { Tile, TilingState } from './types';\n\nexport const initialState: TilingState = {\n visibleTiles: {},\n};\n\nexport const tilingReducer: Reducer<TilingState, TilingAction> = (state, action) => {\n switch (action.type) {\n case UPDATE_VISIBLE_TILES: {\n const incoming = action.payload; // Record<number, Tile[]>\n const nextPages = { ...state.visibleTiles };\n\n for (const key in incoming) {\n const pageIndex = Number(key);\n const newTiles = incoming[pageIndex]; // all isFallback=false\n const prevTiles = nextPages[pageIndex] ?? [];\n\n const prevScale = prevTiles.find((t) => !t.isFallback)?.srcScale;\n const newScale = newTiles[0].srcScale;\n const zoomChanged = prevScale !== undefined && prevScale !== newScale;\n\n if (zoomChanged) {\n /* 1️⃣ ready tiles from the old zoom → new fallback */\n const promoted = prevTiles\n .filter((t) => !t.isFallback && t.status === 'ready')\n .map((t) => ({ ...t, isFallback: true }));\n\n /* 2️⃣ decide which fallback tiles to keep */\n const fallbackToCarry = promoted.length > 0 ? [] : prevTiles.filter((t) => t.isFallback);\n\n /* 3️⃣ final list = (maybe-kept fallback) + promoted + newTiles */\n nextPages[pageIndex] = [...fallbackToCarry, ...promoted, ...newTiles];\n } else {\n /* same zoom → keep current fallback, replace visible */\n const newIds = new Set(newTiles.map((t) => t.id));\n const keepers: Tile[] = []; // where we’ll collect surviving tiles\n const seenIds = new Set<string>();\n\n /* 2️⃣ loop prevTiles once */\n for (const t of prevTiles) {\n if (t.isFallback) {\n keepers.push(t); // always keep fallback\n seenIds.add(t.id);\n } else if (newIds.has(t.id)) {\n keepers.push(t); // keep old visible tile (preserves status)\n seenIds.add(t.id);\n }\n }\n\n /* 3️⃣ append *brand-new* tiles (not yet kept) */\n for (const t of newTiles) {\n if (!seenIds.has(t.id)) keepers.push(t);\n }\n\n /* 4️⃣ store result */\n nextPages[pageIndex] = keepers;\n }\n }\n\n return { ...state, visibleTiles: nextPages };\n }\n\n case MARK_TILE_STATUS: {\n const { pageIndex, tileId, status } = action.payload;\n const tiles =\n state.visibleTiles[pageIndex]?.map((t) =>\n t.id === tileId ? ({ ...t, status } as Tile) : t,\n ) ?? [];\n\n const newTiles = tiles.filter((t) => !t.isFallback);\n const allReady = newTiles.every((t) => t.status === 'ready');\n const finalTiles = allReady ? newTiles : tiles;\n\n return {\n ...state,\n visibleTiles: { ...state.visibleTiles, [pageIndex]: finalTiles },\n };\n }\n\n default:\n return state;\n }\n};\n"],"names":["TILING_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","tileSize","overlapPx","extraRings","UPDATE_VISIBLE_TILES","MARK_TILE_STATUS","updateVisibleTiles","tiles","type","payload","markTileStatus","pageIndex","tileId","status","calculateTilesForPage","scale","rotation","page","metric","pageW","size","width","pageH","height","step","containerSize","transformSize","rotatedVisRect","origin","x","scaled","pageX","y","pageY","visibleWidth","visibleHeight","unrotatedVisRect","restoreRect","visLeft","visTop","visRight","visBottom","maxCol","Math","floor","maxRow","startCol","max","endCol","min","startRow","endRow","col","xScreen","wScreen","xPage","wPage","row","yScreen","hScreen","yPage","hPage","push","index","pageRect","screenRect","srcScale","isFallback","_TilingPlugin","BasePlugin","constructor","registry","config","super","this","tileRendering$","createBehaviorEmitter","refreshPages$","createEmitter","renderCapability","getPlugin","scrollCapability","viewportCapability","onScroll","scrollMetrics","calculateVisibleTiles","mode","wait","throttleMode","coreStore","onAction","REFRESH_PAGES","action","emit","initialize","onCoreStoreUpdated","oldState","newState","core","getMetrics","onRefreshPages","fn","on","dispatch","coreState","visibleTiles","scrollMetric","pageVisibilityMetrics","pageNumber","_a","document","pages","onStoreUpdated","_prevState","buildCapability","renderTile","bind","onTileRendering","options","Error","tile","task","renderPageRect","rect","scaleFactor","dpr","ignore","TilingPlugin","TilingPluginPackage","create","reducer","state","incoming","nextPages","key","Number","newTiles","prevTiles","prevScale","find","t","newScale","promoted","filter","map","fallbackToCarry","length","newIds","Set","keepers","seenIds","has","add","_b","finalTiles","every","tilingReducer","initialState"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/utils.ts","../src/lib/tiling-plugin.ts","../src/lib/index.ts","../src/lib/reducer.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\n\nimport { TilingPluginConfig } from './types';\n\nexport const TILING_PLUGIN_ID = 'tiling';\n\nexport const manifest: PluginManifest<TilingPluginConfig> = {\n id: TILING_PLUGIN_ID,\n name: 'Tiling Plugin',\n version: '1.0.0',\n provides: ['tiling'],\n requires: ['render', 'scroll', 'viewport'],\n optional: [],\n defaultConfig: {\n enabled: true,\n tileSize: 768,\n overlapPx: 2.5,\n extraRings: 0,\n },\n};\n","import { Tile, TileStatus } from './types';\n\nexport const UPDATE_VISIBLE_TILES = 'UPDATE_VISIBLE_TILES';\nexport const MARK_TILE_STATUS = 'MARK_TILE_STATUS';\n\nexport type UpdateVisibleTilesAction = {\n type: typeof UPDATE_VISIBLE_TILES;\n payload: Record<number, Tile[]>;\n};\n\nexport type MarkTileStatusAction = {\n type: typeof MARK_TILE_STATUS;\n payload: { pageIndex: number; tileId: string; status: TileStatus };\n};\n\nexport type TilingAction = UpdateVisibleTilesAction | MarkTileStatusAction;\n\nexport const updateVisibleTiles = (tiles: Record<number, Tile[]>): UpdateVisibleTilesAction => ({\n type: UPDATE_VISIBLE_TILES,\n payload: tiles,\n});\n\nexport const markTileStatus = (\n pageIndex: number,\n tileId: string,\n status: TileStatus,\n): MarkTileStatusAction => ({ type: MARK_TILE_STATUS, payload: { pageIndex, tileId, status } });\n","import { Rect, restoreRect, transformSize } from '@embedpdf/models';\nimport { CalculateTilesForPageOptions, Tile } from './types';\n\n/**\n * Build a grid where neighbouring tiles overlap by `overlapPx`\n * (screen pixels). Inner tiles keep the full `tileSize`, edge\n * tiles are clipped to the page bounds. All screen-space values\n * are rounded to **integers** to avoid sub-pixel seams.\n */\nexport function calculateTilesForPage({\n tileSize = 768,\n overlapPx = 2.5,\n extraRings = 0,\n scale,\n rotation,\n page,\n metric,\n}: CalculateTilesForPageOptions): Tile[] {\n /* ---- work in screen-pixel space -------------------------------- */\n const pageW = page.size.width * scale; // px\n const pageH = page.size.height * scale; // px\n\n const step = tileSize - overlapPx; // shift between tiles\n\n const containerSize = transformSize(page.size, rotation, scale);\n const rotatedVisRect: Rect = {\n origin: { x: metric.scaled.pageX, y: metric.scaled.pageY },\n size: { width: metric.scaled.visibleWidth, height: metric.scaled.visibleHeight },\n };\n const unrotatedVisRect = restoreRect(containerSize, rotatedVisRect, rotation, 1);\n\n const visLeft = unrotatedVisRect.origin.x;\n const visTop = unrotatedVisRect.origin.y;\n const visRight = visLeft + unrotatedVisRect.size.width;\n const visBottom = visTop + unrotatedVisRect.size.height;\n\n const maxCol = Math.floor((pageW - 1) / step);\n const maxRow = Math.floor((pageH - 1) / step);\n\n const startCol = Math.max(0, Math.floor(visLeft / step) - extraRings);\n const endCol = Math.min(maxCol, Math.floor((visRight - 1) / step) + extraRings);\n const startRow = Math.max(0, Math.floor(visTop / step) - extraRings);\n const endRow = Math.min(maxRow, Math.floor((visBottom - 1) / step) + extraRings);\n\n /* ---- build tiles ---------------------------------------------- */\n const tiles: Tile[] = [];\n\n for (let col = startCol; col <= endCol; col++) {\n const xScreen = col * step; // px (integer)\n const wScreen = Math.min(tileSize, pageW - xScreen); // px (≤ tileSize)\n\n const xPage = xScreen / scale; // pt (may be frac.)\n const wPage = wScreen / scale; // pt\n\n for (let row = startRow; row <= endRow; row++) {\n const yScreen = row * step;\n const hScreen = Math.min(tileSize, pageH - yScreen);\n\n const yPage = yScreen / scale;\n const hPage = hScreen / scale;\n\n tiles.push({\n id: `p${page.index}-${scale}-x${xScreen}-y${yScreen}-w${wScreen}-h${hScreen}`,\n col,\n row,\n pageRect: { origin: { x: xPage, y: yPage }, size: { width: wPage, height: hPage } },\n screenRect: {\n origin: { x: xScreen, y: yScreen },\n size: { width: wScreen, height: hScreen },\n },\n status: 'queued',\n srcScale: scale,\n isFallback: false,\n });\n }\n }\n\n return tiles;\n}\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n PluginRegistry,\n REFRESH_PAGES,\n StoreState,\n} from '@embedpdf/core';\nimport { ignore } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\nimport { ScrollCapability, ScrollMetrics, ScrollPlugin } from '@embedpdf/plugin-scroll';\nimport { ViewportCapability, ViewportPlugin } from '@embedpdf/plugin-viewport';\n\nimport { markTileStatus, updateVisibleTiles } from './actions';\nimport {\n TilingPluginConfig,\n TilingCapability,\n Tile,\n RenderTileOptions,\n TilingState,\n} from './types';\nimport { calculateTilesForPage } from './utils';\n\nexport class TilingPlugin extends BasePlugin<TilingPluginConfig, TilingCapability> {\n static readonly id = 'tiling' as const;\n\n private readonly tileRendering$ = createBehaviorEmitter<Record<number, Tile[]>>();\n\n private config: TilingPluginConfig;\n private renderCapability: RenderCapability;\n private scrollCapability: ScrollCapability;\n private viewportCapability: ViewportCapability;\n\n constructor(id: string, registry: PluginRegistry, config: TilingPluginConfig) {\n super(id, registry);\n\n this.config = config;\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n this.scrollCapability = this.registry.getPlugin<ScrollPlugin>('scroll')!.provides();\n this.viewportCapability = this.registry.getPlugin<ViewportPlugin>('viewport')!.provides();\n\n this.scrollCapability.onScroll((scrollMetrics) => this.calculateVisibleTiles(scrollMetrics), {\n mode: 'throttle',\n wait: 50,\n throttleMode: 'trailing',\n });\n\n this.coreStore.onAction(REFRESH_PAGES, (action) => this.recalculateTiles(action.payload));\n }\n\n async recalculateTiles(pagesToRefresh: number[]): Promise<void> {\n const currentMetrics = this.scrollCapability.getMetrics(this.viewportCapability.getMetrics());\n\n // Recalculate tiles for refreshed pages with a new timestamp\n const refreshedTiles: Record<number, Tile[]> = {};\n const refreshTimestamp = Date.now();\n\n for (const pageIndex of pagesToRefresh) {\n const metric = currentMetrics.pageVisibilityMetrics.find(\n (m) => m.pageNumber === pageIndex + 1,\n );\n if (!metric) continue;\n\n const page = this.coreState.core.document?.pages[pageIndex];\n if (!page) continue;\n\n refreshedTiles[pageIndex] = calculateTilesForPage({\n page,\n metric,\n scale: this.coreState.core.scale,\n rotation: this.coreState.core.rotation,\n tileSize: this.config.tileSize,\n overlapPx: this.config.overlapPx,\n extraRings: this.config.extraRings,\n }).map((tile) => ({\n ...tile,\n id: `${tile.id}-r${refreshTimestamp}`, // Add refresh token to force new render\n }));\n }\n\n if (Object.keys(refreshedTiles).length > 0) {\n this.dispatch(updateVisibleTiles(refreshedTiles));\n }\n }\n\n async initialize(): Promise<void> {\n // Fetch dependencies from the registry if needed\n }\n\n protected onCoreStoreUpdated(\n oldState: StoreState<CoreState>,\n newState: StoreState<CoreState>,\n ): void {\n if (oldState.core.scale !== newState.core.scale) {\n this.calculateVisibleTiles(\n this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()),\n );\n }\n }\n\n private calculateVisibleTiles(scrollMetrics: ScrollMetrics): void {\n if (!this.config.enabled) {\n this.dispatch(updateVisibleTiles([]));\n return;\n }\n\n const scale = this.coreState.core.scale;\n const rotation = this.coreState.core.rotation;\n const visibleTiles: { [pageIndex: number]: Tile[] } = {};\n\n for (const scrollMetric of scrollMetrics.pageVisibilityMetrics) {\n const pageIndex = scrollMetric.pageNumber - 1; // Convert to 0-based index\n const page = this.coreState.core.document?.pages[pageIndex];\n if (!page) continue;\n\n // Calculate tiles for the page using the utility function\n const tiles = calculateTilesForPage({\n page,\n metric: scrollMetric,\n scale,\n rotation,\n tileSize: this.config.tileSize,\n overlapPx: this.config.overlapPx,\n extraRings: this.config.extraRings,\n });\n\n visibleTiles[pageIndex] = tiles;\n }\n\n this.dispatch(updateVisibleTiles(visibleTiles));\n }\n\n override onStoreUpdated(_prevState: TilingState, newState: TilingState): void {\n this.tileRendering$.emit(newState.visibleTiles);\n }\n\n protected buildCapability(): TilingCapability {\n return {\n renderTile: this.renderTile.bind(this),\n onTileRendering: this.tileRendering$.on,\n };\n }\n\n private renderTile(options: RenderTileOptions) {\n if (!this.renderCapability) {\n throw new Error('Render capability not available.');\n }\n\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'rendering'));\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: options.pageIndex,\n rect: options.tile.pageRect,\n options: {\n scaleFactor: options.tile.srcScale,\n dpr: options.dpr,\n },\n });\n\n task.wait(() => {\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'ready'));\n }, ignore);\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { TilingAction } from './actions';\nimport { manifest, TILING_PLUGIN_ID } from './manifest';\nimport { initialState, tilingReducer } from './reducer';\nimport { TilingPlugin } from './tiling-plugin';\nimport { TilingPluginConfig, TilingState } from './types';\n\nexport const TilingPluginPackage: PluginPackage<\n TilingPlugin,\n TilingPluginConfig,\n TilingState,\n TilingAction\n> = {\n manifest,\n create: (registry, config) => new TilingPlugin(TILING_PLUGIN_ID, registry, config),\n reducer: (state, action) => tilingReducer(state, action),\n initialState,\n};\n\nexport * from './tiling-plugin';\nexport * from './types';\nexport * from './manifest';\n","import { Reducer } from '@embedpdf/core';\n\nimport { UPDATE_VISIBLE_TILES, MARK_TILE_STATUS, TilingAction } from './actions';\nimport { Tile, TilingState } from './types';\n\nexport const initialState: TilingState = {\n visibleTiles: {},\n};\n\nexport const tilingReducer: Reducer<TilingState, TilingAction> = (state, action) => {\n switch (action.type) {\n case UPDATE_VISIBLE_TILES: {\n const incoming = action.payload; // Record<number, Tile[]>\n const nextPages = { ...state.visibleTiles };\n\n for (const key in incoming) {\n const pageIndex = Number(key);\n const newTiles = incoming[pageIndex]; // all isFallback=false\n const prevTiles = nextPages[pageIndex] ?? [];\n\n const prevScale = prevTiles.find((t) => !t.isFallback)?.srcScale;\n const newScale = newTiles[0].srcScale;\n const zoomChanged = prevScale !== undefined && prevScale !== newScale;\n\n if (zoomChanged) {\n /* 1️⃣ ready tiles from the old zoom → new fallback */\n const promoted = prevTiles\n .filter((t) => !t.isFallback && t.status === 'ready')\n .map((t) => ({ ...t, isFallback: true }));\n\n /* 2️⃣ decide which fallback tiles to keep */\n const fallbackToCarry = promoted.length > 0 ? [] : prevTiles.filter((t) => t.isFallback);\n\n /* 3️⃣ final list = (maybe-kept fallback) + promoted + newTiles */\n nextPages[pageIndex] = [...fallbackToCarry, ...promoted, ...newTiles];\n } else {\n /* same zoom → keep current fallback, replace visible */\n const newIds = new Set(newTiles.map((t) => t.id));\n const keepers: Tile[] = []; // where we’ll collect surviving tiles\n const seenIds = new Set<string>();\n\n /* 2️⃣ loop prevTiles once */\n for (const t of prevTiles) {\n if (t.isFallback) {\n keepers.push(t); // always keep fallback\n seenIds.add(t.id);\n } else if (newIds.has(t.id)) {\n keepers.push(t); // keep old visible tile (preserves status)\n seenIds.add(t.id);\n }\n }\n\n /* 3️⃣ append *brand-new* tiles (not yet kept) */\n for (const t of newTiles) {\n if (!seenIds.has(t.id)) keepers.push(t);\n }\n\n /* 4️⃣ store result */\n nextPages[pageIndex] = keepers;\n }\n }\n\n return { ...state, visibleTiles: nextPages };\n }\n\n case MARK_TILE_STATUS: {\n const { pageIndex, tileId, status } = action.payload;\n const tiles =\n state.visibleTiles[pageIndex]?.map((t) =>\n t.id === tileId ? ({ ...t, status } as Tile) : t,\n ) ?? [];\n\n const newTiles = tiles.filter((t) => !t.isFallback);\n const allReady = newTiles.every((t) => t.status === 'ready');\n const finalTiles = allReady ? newTiles : tiles;\n\n return {\n ...state,\n visibleTiles: { ...state.visibleTiles, [pageIndex]: finalTiles },\n };\n }\n\n default:\n return state;\n }\n};\n"],"names":["TILING_PLUGIN_ID","manifest","id","name","version","provides","requires","optional","defaultConfig","enabled","tileSize","overlapPx","extraRings","UPDATE_VISIBLE_TILES","MARK_TILE_STATUS","updateVisibleTiles","tiles","type","payload","markTileStatus","pageIndex","tileId","status","calculateTilesForPage","scale","rotation","page","metric","pageW","size","width","pageH","height","step","containerSize","transformSize","rotatedVisRect","origin","x","scaled","pageX","y","pageY","visibleWidth","visibleHeight","unrotatedVisRect","restoreRect","visLeft","visTop","visRight","visBottom","maxCol","Math","floor","maxRow","startCol","max","endCol","min","startRow","endRow","col","xScreen","wScreen","xPage","wPage","row","yScreen","hScreen","yPage","hPage","push","index","pageRect","screenRect","srcScale","isFallback","_TilingPlugin","BasePlugin","constructor","registry","config","super","this","tileRendering$","createBehaviorEmitter","renderCapability","getPlugin","scrollCapability","viewportCapability","onScroll","scrollMetrics","calculateVisibleTiles","mode","wait","throttleMode","coreStore","onAction","REFRESH_PAGES","action","recalculateTiles","pagesToRefresh","currentMetrics","getMetrics","refreshedTiles","refreshTimestamp","Date","now","pageVisibilityMetrics","find","m","pageNumber","_a","coreState","core","document","pages","map","tile","Object","keys","length","dispatch","initialize","onCoreStoreUpdated","oldState","newState","visibleTiles","scrollMetric","onStoreUpdated","_prevState","emit","buildCapability","renderTile","bind","onTileRendering","on","options","Error","task","renderPageRect","rect","scaleFactor","dpr","ignore","TilingPlugin","TilingPluginPackage","create","reducer","state","incoming","nextPages","key","Number","newTiles","prevTiles","prevScale","t","newScale","promoted","filter","fallbackToCarry","newIds","Set","keepers","seenIds","has","add","_b","finalTiles","every","tilingReducer","initialState"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { BasePlugin, createBehaviorEmitter, createEmitter, REFRESH_PAGES } from "@embedpdf/core";
1
+ import { BasePlugin, createBehaviorEmitter, REFRESH_PAGES } from "@embedpdf/core";
2
2
  import { transformSize, restoreRect, ignore } from "@embedpdf/models";
3
3
  const TILING_PLUGIN_ID = "tiling";
4
4
  const manifest = {
@@ -140,7 +140,6 @@ const _TilingPlugin = class _TilingPlugin extends BasePlugin {
140
140
  constructor(id, registry, config) {
141
141
  super(id, registry);
142
142
  this.tileRendering$ = createBehaviorEmitter();
143
- this.refreshPages$ = createEmitter();
144
143
  this.config = config;
145
144
  this.renderCapability = this.registry.getPlugin("render").provides();
146
145
  this.scrollCapability = this.registry.getPlugin("scroll").provides();
@@ -150,9 +149,37 @@ const _TilingPlugin = class _TilingPlugin extends BasePlugin {
150
149
  wait: 50,
151
150
  throttleMode: "trailing"
152
151
  });
153
- this.coreStore.onAction(REFRESH_PAGES, (action) => {
154
- this.refreshPages$.emit(action.payload);
155
- });
152
+ this.coreStore.onAction(REFRESH_PAGES, (action) => this.recalculateTiles(action.payload));
153
+ }
154
+ async recalculateTiles(pagesToRefresh) {
155
+ var _a;
156
+ const currentMetrics = this.scrollCapability.getMetrics(this.viewportCapability.getMetrics());
157
+ const refreshedTiles = {};
158
+ const refreshTimestamp = Date.now();
159
+ for (const pageIndex of pagesToRefresh) {
160
+ const metric = currentMetrics.pageVisibilityMetrics.find(
161
+ (m) => m.pageNumber === pageIndex + 1
162
+ );
163
+ if (!metric) continue;
164
+ const page = (_a = this.coreState.core.document) == null ? void 0 : _a.pages[pageIndex];
165
+ if (!page) continue;
166
+ refreshedTiles[pageIndex] = calculateTilesForPage({
167
+ page,
168
+ metric,
169
+ scale: this.coreState.core.scale,
170
+ rotation: this.coreState.core.rotation,
171
+ tileSize: this.config.tileSize,
172
+ overlapPx: this.config.overlapPx,
173
+ extraRings: this.config.extraRings
174
+ }).map((tile) => ({
175
+ ...tile,
176
+ id: `${tile.id}-r${refreshTimestamp}`
177
+ // Add refresh token to force new render
178
+ }));
179
+ }
180
+ if (Object.keys(refreshedTiles).length > 0) {
181
+ this.dispatch(updateVisibleTiles(refreshedTiles));
182
+ }
156
183
  }
157
184
  async initialize() {
158
185
  }
@@ -163,9 +190,6 @@ const _TilingPlugin = class _TilingPlugin extends BasePlugin {
163
190
  );
164
191
  }
165
192
  }
166
- onRefreshPages(fn) {
167
- return this.refreshPages$.on(fn);
168
- }
169
193
  calculateVisibleTiles(scrollMetrics) {
170
194
  var _a;
171
195
  if (!this.config.enabled) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/utils.ts","../src/lib/tiling-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\n\nimport { TilingPluginConfig } from './types';\n\nexport const TILING_PLUGIN_ID = 'tiling';\n\nexport const manifest: PluginManifest<TilingPluginConfig> = {\n id: TILING_PLUGIN_ID,\n name: 'Tiling Plugin',\n version: '1.0.0',\n provides: ['tiling'],\n requires: ['render', 'scroll', 'viewport'],\n optional: [],\n defaultConfig: {\n enabled: true,\n tileSize: 768,\n overlapPx: 2.5,\n extraRings: 0,\n },\n};\n","import { Tile, TileStatus } from './types';\n\nexport const UPDATE_VISIBLE_TILES = 'UPDATE_VISIBLE_TILES';\nexport const MARK_TILE_STATUS = 'MARK_TILE_STATUS';\n\nexport type UpdateVisibleTilesAction = {\n type: typeof UPDATE_VISIBLE_TILES;\n payload: Record<number, Tile[]>;\n};\n\nexport type MarkTileStatusAction = {\n type: typeof MARK_TILE_STATUS;\n payload: { pageIndex: number; tileId: string; status: TileStatus };\n};\n\nexport type TilingAction = UpdateVisibleTilesAction | MarkTileStatusAction;\n\nexport const updateVisibleTiles = (tiles: Record<number, Tile[]>): UpdateVisibleTilesAction => ({\n type: UPDATE_VISIBLE_TILES,\n payload: tiles,\n});\n\nexport const markTileStatus = (\n pageIndex: number,\n tileId: string,\n status: TileStatus,\n): MarkTileStatusAction => ({ type: MARK_TILE_STATUS, payload: { pageIndex, tileId, status } });\n","import { Reducer } from '@embedpdf/core';\n\nimport { UPDATE_VISIBLE_TILES, MARK_TILE_STATUS, TilingAction } from './actions';\nimport { Tile, TilingState } from './types';\n\nexport const initialState: TilingState = {\n visibleTiles: {},\n};\n\nexport const tilingReducer: Reducer<TilingState, TilingAction> = (state, action) => {\n switch (action.type) {\n case UPDATE_VISIBLE_TILES: {\n const incoming = action.payload; // Record<number, Tile[]>\n const nextPages = { ...state.visibleTiles };\n\n for (const key in incoming) {\n const pageIndex = Number(key);\n const newTiles = incoming[pageIndex]; // all isFallback=false\n const prevTiles = nextPages[pageIndex] ?? [];\n\n const prevScale = prevTiles.find((t) => !t.isFallback)?.srcScale;\n const newScale = newTiles[0].srcScale;\n const zoomChanged = prevScale !== undefined && prevScale !== newScale;\n\n if (zoomChanged) {\n /* 1️⃣ ready tiles from the old zoom → new fallback */\n const promoted = prevTiles\n .filter((t) => !t.isFallback && t.status === 'ready')\n .map((t) => ({ ...t, isFallback: true }));\n\n /* 2️⃣ decide which fallback tiles to keep */\n const fallbackToCarry = promoted.length > 0 ? [] : prevTiles.filter((t) => t.isFallback);\n\n /* 3️⃣ final list = (maybe-kept fallback) + promoted + newTiles */\n nextPages[pageIndex] = [...fallbackToCarry, ...promoted, ...newTiles];\n } else {\n /* same zoom → keep current fallback, replace visible */\n const newIds = new Set(newTiles.map((t) => t.id));\n const keepers: Tile[] = []; // where we’ll collect surviving tiles\n const seenIds = new Set<string>();\n\n /* 2️⃣ loop prevTiles once */\n for (const t of prevTiles) {\n if (t.isFallback) {\n keepers.push(t); // always keep fallback\n seenIds.add(t.id);\n } else if (newIds.has(t.id)) {\n keepers.push(t); // keep old visible tile (preserves status)\n seenIds.add(t.id);\n }\n }\n\n /* 3️⃣ append *brand-new* tiles (not yet kept) */\n for (const t of newTiles) {\n if (!seenIds.has(t.id)) keepers.push(t);\n }\n\n /* 4️⃣ store result */\n nextPages[pageIndex] = keepers;\n }\n }\n\n return { ...state, visibleTiles: nextPages };\n }\n\n case MARK_TILE_STATUS: {\n const { pageIndex, tileId, status } = action.payload;\n const tiles =\n state.visibleTiles[pageIndex]?.map((t) =>\n t.id === tileId ? ({ ...t, status } as Tile) : t,\n ) ?? [];\n\n const newTiles = tiles.filter((t) => !t.isFallback);\n const allReady = newTiles.every((t) => t.status === 'ready');\n const finalTiles = allReady ? newTiles : tiles;\n\n return {\n ...state,\n visibleTiles: { ...state.visibleTiles, [pageIndex]: finalTiles },\n };\n }\n\n default:\n return state;\n }\n};\n","import { Rect, restoreRect, transformSize } from '@embedpdf/models';\nimport { CalculateTilesForPageOptions, Tile } from './types';\n\n/**\n * Build a grid where neighbouring tiles overlap by `overlapPx`\n * (screen pixels). Inner tiles keep the full `tileSize`, edge\n * tiles are clipped to the page bounds. All screen-space values\n * are rounded to **integers** to avoid sub-pixel seams.\n */\nexport function calculateTilesForPage({\n tileSize = 768,\n overlapPx = 2.5,\n extraRings = 0,\n scale,\n rotation,\n page,\n metric,\n}: CalculateTilesForPageOptions): Tile[] {\n /* ---- work in screen-pixel space -------------------------------- */\n const pageW = page.size.width * scale; // px\n const pageH = page.size.height * scale; // px\n\n const step = tileSize - overlapPx; // shift between tiles\n\n const containerSize = transformSize(page.size, rotation, scale);\n const rotatedVisRect: Rect = {\n origin: { x: metric.scaled.pageX, y: metric.scaled.pageY },\n size: { width: metric.scaled.visibleWidth, height: metric.scaled.visibleHeight },\n };\n const unrotatedVisRect = restoreRect(containerSize, rotatedVisRect, rotation, 1);\n\n const visLeft = unrotatedVisRect.origin.x;\n const visTop = unrotatedVisRect.origin.y;\n const visRight = visLeft + unrotatedVisRect.size.width;\n const visBottom = visTop + unrotatedVisRect.size.height;\n\n const maxCol = Math.floor((pageW - 1) / step);\n const maxRow = Math.floor((pageH - 1) / step);\n\n const startCol = Math.max(0, Math.floor(visLeft / step) - extraRings);\n const endCol = Math.min(maxCol, Math.floor((visRight - 1) / step) + extraRings);\n const startRow = Math.max(0, Math.floor(visTop / step) - extraRings);\n const endRow = Math.min(maxRow, Math.floor((visBottom - 1) / step) + extraRings);\n\n /* ---- build tiles ---------------------------------------------- */\n const tiles: Tile[] = [];\n\n for (let col = startCol; col <= endCol; col++) {\n const xScreen = col * step; // px (integer)\n const wScreen = Math.min(tileSize, pageW - xScreen); // px (≤ tileSize)\n\n const xPage = xScreen / scale; // pt (may be frac.)\n const wPage = wScreen / scale; // pt\n\n for (let row = startRow; row <= endRow; row++) {\n const yScreen = row * step;\n const hScreen = Math.min(tileSize, pageH - yScreen);\n\n const yPage = yScreen / scale;\n const hPage = hScreen / scale;\n\n tiles.push({\n id: `p${page.index}-${scale}-x${xScreen}-y${yScreen}-w${wScreen}-h${hScreen}`,\n col,\n row,\n pageRect: { origin: { x: xPage, y: yPage }, size: { width: wPage, height: hPage } },\n screenRect: {\n origin: { x: xScreen, y: yScreen },\n size: { width: wScreen, height: hScreen },\n },\n status: 'queued',\n srcScale: scale,\n isFallback: false,\n });\n }\n }\n\n return tiles;\n}\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n createEmitter,\n PluginRegistry,\n REFRESH_PAGES,\n StoreState,\n Unsubscribe,\n} from '@embedpdf/core';\nimport { ignore } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\nimport { ScrollCapability, ScrollMetrics, ScrollPlugin } from '@embedpdf/plugin-scroll';\nimport { ViewportCapability, ViewportPlugin } from '@embedpdf/plugin-viewport';\n\nimport { markTileStatus, updateVisibleTiles } from './actions';\nimport {\n TilingPluginConfig,\n TilingCapability,\n Tile,\n RenderTileOptions,\n TilingState,\n} from './types';\nimport { calculateTilesForPage } from './utils';\n\nexport class TilingPlugin extends BasePlugin<TilingPluginConfig, TilingCapability> {\n static readonly id = 'tiling' as const;\n\n private readonly tileRendering$ = createBehaviorEmitter<Record<number, Tile[]>>();\n private readonly refreshPages$ = createEmitter<number[]>();\n\n private config: TilingPluginConfig;\n private renderCapability: RenderCapability;\n private scrollCapability: ScrollCapability;\n private viewportCapability: ViewportCapability;\n\n constructor(id: string, registry: PluginRegistry, config: TilingPluginConfig) {\n super(id, registry);\n\n this.config = config;\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n this.scrollCapability = this.registry.getPlugin<ScrollPlugin>('scroll')!.provides();\n this.viewportCapability = this.registry.getPlugin<ViewportPlugin>('viewport')!.provides();\n\n this.scrollCapability.onScroll((scrollMetrics) => this.calculateVisibleTiles(scrollMetrics), {\n mode: 'throttle',\n wait: 50,\n throttleMode: 'trailing',\n });\n\n this.coreStore.onAction(REFRESH_PAGES, (action) => {\n this.refreshPages$.emit(action.payload);\n });\n }\n\n async initialize(): Promise<void> {\n // Fetch dependencies from the registry if needed\n }\n\n protected onCoreStoreUpdated(\n oldState: StoreState<CoreState>,\n newState: StoreState<CoreState>,\n ): void {\n if (oldState.core.scale !== newState.core.scale) {\n this.calculateVisibleTiles(\n this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()),\n );\n }\n }\n\n public onRefreshPages(fn: (pages: number[]) => void): Unsubscribe {\n return this.refreshPages$.on(fn);\n }\n\n private calculateVisibleTiles(scrollMetrics: ScrollMetrics): void {\n if (!this.config.enabled) {\n this.dispatch(updateVisibleTiles([]));\n return;\n }\n\n const scale = this.coreState.core.scale;\n const rotation = this.coreState.core.rotation;\n const visibleTiles: { [pageIndex: number]: Tile[] } = {};\n\n for (const scrollMetric of scrollMetrics.pageVisibilityMetrics) {\n const pageIndex = scrollMetric.pageNumber - 1; // Convert to 0-based index\n const page = this.coreState.core.document?.pages[pageIndex];\n if (!page) continue;\n\n // Calculate tiles for the page using the utility function\n const tiles = calculateTilesForPage({\n page,\n metric: scrollMetric,\n scale,\n rotation,\n tileSize: this.config.tileSize,\n overlapPx: this.config.overlapPx,\n extraRings: this.config.extraRings,\n });\n\n visibleTiles[pageIndex] = tiles;\n }\n\n this.dispatch(updateVisibleTiles(visibleTiles));\n }\n\n override onStoreUpdated(_prevState: TilingState, newState: TilingState): void {\n this.tileRendering$.emit(newState.visibleTiles);\n }\n\n protected buildCapability(): TilingCapability {\n return {\n renderTile: this.renderTile.bind(this),\n onTileRendering: this.tileRendering$.on,\n };\n }\n\n private renderTile(options: RenderTileOptions) {\n if (!this.renderCapability) {\n throw new Error('Render capability not available.');\n }\n\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'rendering'));\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: options.pageIndex,\n rect: options.tile.pageRect,\n options: {\n scaleFactor: options.tile.srcScale,\n dpr: options.dpr,\n },\n });\n\n task.wait(() => {\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'ready'));\n }, ignore);\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { TilingAction } from './actions';\nimport { manifest, TILING_PLUGIN_ID } from './manifest';\nimport { initialState, tilingReducer } from './reducer';\nimport { TilingPlugin } from './tiling-plugin';\nimport { TilingPluginConfig, TilingState } from './types';\n\nexport const TilingPluginPackage: PluginPackage<\n TilingPlugin,\n TilingPluginConfig,\n TilingState,\n TilingAction\n> = {\n manifest,\n create: (registry, config) => new TilingPlugin(TILING_PLUGIN_ID, registry, config),\n reducer: (state, action) => tilingReducer(state, action),\n initialState,\n};\n\nexport * from './tiling-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/actions.ts","../src/lib/reducer.ts","../src/lib/utils.ts","../src/lib/tiling-plugin.ts","../src/lib/index.ts"],"sourcesContent":["import { PluginManifest } from '@embedpdf/core';\n\nimport { TilingPluginConfig } from './types';\n\nexport const TILING_PLUGIN_ID = 'tiling';\n\nexport const manifest: PluginManifest<TilingPluginConfig> = {\n id: TILING_PLUGIN_ID,\n name: 'Tiling Plugin',\n version: '1.0.0',\n provides: ['tiling'],\n requires: ['render', 'scroll', 'viewport'],\n optional: [],\n defaultConfig: {\n enabled: true,\n tileSize: 768,\n overlapPx: 2.5,\n extraRings: 0,\n },\n};\n","import { Tile, TileStatus } from './types';\n\nexport const UPDATE_VISIBLE_TILES = 'UPDATE_VISIBLE_TILES';\nexport const MARK_TILE_STATUS = 'MARK_TILE_STATUS';\n\nexport type UpdateVisibleTilesAction = {\n type: typeof UPDATE_VISIBLE_TILES;\n payload: Record<number, Tile[]>;\n};\n\nexport type MarkTileStatusAction = {\n type: typeof MARK_TILE_STATUS;\n payload: { pageIndex: number; tileId: string; status: TileStatus };\n};\n\nexport type TilingAction = UpdateVisibleTilesAction | MarkTileStatusAction;\n\nexport const updateVisibleTiles = (tiles: Record<number, Tile[]>): UpdateVisibleTilesAction => ({\n type: UPDATE_VISIBLE_TILES,\n payload: tiles,\n});\n\nexport const markTileStatus = (\n pageIndex: number,\n tileId: string,\n status: TileStatus,\n): MarkTileStatusAction => ({ type: MARK_TILE_STATUS, payload: { pageIndex, tileId, status } });\n","import { Reducer } from '@embedpdf/core';\n\nimport { UPDATE_VISIBLE_TILES, MARK_TILE_STATUS, TilingAction } from './actions';\nimport { Tile, TilingState } from './types';\n\nexport const initialState: TilingState = {\n visibleTiles: {},\n};\n\nexport const tilingReducer: Reducer<TilingState, TilingAction> = (state, action) => {\n switch (action.type) {\n case UPDATE_VISIBLE_TILES: {\n const incoming = action.payload; // Record<number, Tile[]>\n const nextPages = { ...state.visibleTiles };\n\n for (const key in incoming) {\n const pageIndex = Number(key);\n const newTiles = incoming[pageIndex]; // all isFallback=false\n const prevTiles = nextPages[pageIndex] ?? [];\n\n const prevScale = prevTiles.find((t) => !t.isFallback)?.srcScale;\n const newScale = newTiles[0].srcScale;\n const zoomChanged = prevScale !== undefined && prevScale !== newScale;\n\n if (zoomChanged) {\n /* 1️⃣ ready tiles from the old zoom → new fallback */\n const promoted = prevTiles\n .filter((t) => !t.isFallback && t.status === 'ready')\n .map((t) => ({ ...t, isFallback: true }));\n\n /* 2️⃣ decide which fallback tiles to keep */\n const fallbackToCarry = promoted.length > 0 ? [] : prevTiles.filter((t) => t.isFallback);\n\n /* 3️⃣ final list = (maybe-kept fallback) + promoted + newTiles */\n nextPages[pageIndex] = [...fallbackToCarry, ...promoted, ...newTiles];\n } else {\n /* same zoom → keep current fallback, replace visible */\n const newIds = new Set(newTiles.map((t) => t.id));\n const keepers: Tile[] = []; // where we’ll collect surviving tiles\n const seenIds = new Set<string>();\n\n /* 2️⃣ loop prevTiles once */\n for (const t of prevTiles) {\n if (t.isFallback) {\n keepers.push(t); // always keep fallback\n seenIds.add(t.id);\n } else if (newIds.has(t.id)) {\n keepers.push(t); // keep old visible tile (preserves status)\n seenIds.add(t.id);\n }\n }\n\n /* 3️⃣ append *brand-new* tiles (not yet kept) */\n for (const t of newTiles) {\n if (!seenIds.has(t.id)) keepers.push(t);\n }\n\n /* 4️⃣ store result */\n nextPages[pageIndex] = keepers;\n }\n }\n\n return { ...state, visibleTiles: nextPages };\n }\n\n case MARK_TILE_STATUS: {\n const { pageIndex, tileId, status } = action.payload;\n const tiles =\n state.visibleTiles[pageIndex]?.map((t) =>\n t.id === tileId ? ({ ...t, status } as Tile) : t,\n ) ?? [];\n\n const newTiles = tiles.filter((t) => !t.isFallback);\n const allReady = newTiles.every((t) => t.status === 'ready');\n const finalTiles = allReady ? newTiles : tiles;\n\n return {\n ...state,\n visibleTiles: { ...state.visibleTiles, [pageIndex]: finalTiles },\n };\n }\n\n default:\n return state;\n }\n};\n","import { Rect, restoreRect, transformSize } from '@embedpdf/models';\nimport { CalculateTilesForPageOptions, Tile } from './types';\n\n/**\n * Build a grid where neighbouring tiles overlap by `overlapPx`\n * (screen pixels). Inner tiles keep the full `tileSize`, edge\n * tiles are clipped to the page bounds. All screen-space values\n * are rounded to **integers** to avoid sub-pixel seams.\n */\nexport function calculateTilesForPage({\n tileSize = 768,\n overlapPx = 2.5,\n extraRings = 0,\n scale,\n rotation,\n page,\n metric,\n}: CalculateTilesForPageOptions): Tile[] {\n /* ---- work in screen-pixel space -------------------------------- */\n const pageW = page.size.width * scale; // px\n const pageH = page.size.height * scale; // px\n\n const step = tileSize - overlapPx; // shift between tiles\n\n const containerSize = transformSize(page.size, rotation, scale);\n const rotatedVisRect: Rect = {\n origin: { x: metric.scaled.pageX, y: metric.scaled.pageY },\n size: { width: metric.scaled.visibleWidth, height: metric.scaled.visibleHeight },\n };\n const unrotatedVisRect = restoreRect(containerSize, rotatedVisRect, rotation, 1);\n\n const visLeft = unrotatedVisRect.origin.x;\n const visTop = unrotatedVisRect.origin.y;\n const visRight = visLeft + unrotatedVisRect.size.width;\n const visBottom = visTop + unrotatedVisRect.size.height;\n\n const maxCol = Math.floor((pageW - 1) / step);\n const maxRow = Math.floor((pageH - 1) / step);\n\n const startCol = Math.max(0, Math.floor(visLeft / step) - extraRings);\n const endCol = Math.min(maxCol, Math.floor((visRight - 1) / step) + extraRings);\n const startRow = Math.max(0, Math.floor(visTop / step) - extraRings);\n const endRow = Math.min(maxRow, Math.floor((visBottom - 1) / step) + extraRings);\n\n /* ---- build tiles ---------------------------------------------- */\n const tiles: Tile[] = [];\n\n for (let col = startCol; col <= endCol; col++) {\n const xScreen = col * step; // px (integer)\n const wScreen = Math.min(tileSize, pageW - xScreen); // px (≤ tileSize)\n\n const xPage = xScreen / scale; // pt (may be frac.)\n const wPage = wScreen / scale; // pt\n\n for (let row = startRow; row <= endRow; row++) {\n const yScreen = row * step;\n const hScreen = Math.min(tileSize, pageH - yScreen);\n\n const yPage = yScreen / scale;\n const hPage = hScreen / scale;\n\n tiles.push({\n id: `p${page.index}-${scale}-x${xScreen}-y${yScreen}-w${wScreen}-h${hScreen}`,\n col,\n row,\n pageRect: { origin: { x: xPage, y: yPage }, size: { width: wPage, height: hPage } },\n screenRect: {\n origin: { x: xScreen, y: yScreen },\n size: { width: wScreen, height: hScreen },\n },\n status: 'queued',\n srcScale: scale,\n isFallback: false,\n });\n }\n }\n\n return tiles;\n}\n","import {\n BasePlugin,\n CoreState,\n createBehaviorEmitter,\n PluginRegistry,\n REFRESH_PAGES,\n StoreState,\n} from '@embedpdf/core';\nimport { ignore } from '@embedpdf/models';\nimport { RenderCapability, RenderPlugin } from '@embedpdf/plugin-render';\nimport { ScrollCapability, ScrollMetrics, ScrollPlugin } from '@embedpdf/plugin-scroll';\nimport { ViewportCapability, ViewportPlugin } from '@embedpdf/plugin-viewport';\n\nimport { markTileStatus, updateVisibleTiles } from './actions';\nimport {\n TilingPluginConfig,\n TilingCapability,\n Tile,\n RenderTileOptions,\n TilingState,\n} from './types';\nimport { calculateTilesForPage } from './utils';\n\nexport class TilingPlugin extends BasePlugin<TilingPluginConfig, TilingCapability> {\n static readonly id = 'tiling' as const;\n\n private readonly tileRendering$ = createBehaviorEmitter<Record<number, Tile[]>>();\n\n private config: TilingPluginConfig;\n private renderCapability: RenderCapability;\n private scrollCapability: ScrollCapability;\n private viewportCapability: ViewportCapability;\n\n constructor(id: string, registry: PluginRegistry, config: TilingPluginConfig) {\n super(id, registry);\n\n this.config = config;\n\n this.renderCapability = this.registry.getPlugin<RenderPlugin>('render')!.provides();\n this.scrollCapability = this.registry.getPlugin<ScrollPlugin>('scroll')!.provides();\n this.viewportCapability = this.registry.getPlugin<ViewportPlugin>('viewport')!.provides();\n\n this.scrollCapability.onScroll((scrollMetrics) => this.calculateVisibleTiles(scrollMetrics), {\n mode: 'throttle',\n wait: 50,\n throttleMode: 'trailing',\n });\n\n this.coreStore.onAction(REFRESH_PAGES, (action) => this.recalculateTiles(action.payload));\n }\n\n async recalculateTiles(pagesToRefresh: number[]): Promise<void> {\n const currentMetrics = this.scrollCapability.getMetrics(this.viewportCapability.getMetrics());\n\n // Recalculate tiles for refreshed pages with a new timestamp\n const refreshedTiles: Record<number, Tile[]> = {};\n const refreshTimestamp = Date.now();\n\n for (const pageIndex of pagesToRefresh) {\n const metric = currentMetrics.pageVisibilityMetrics.find(\n (m) => m.pageNumber === pageIndex + 1,\n );\n if (!metric) continue;\n\n const page = this.coreState.core.document?.pages[pageIndex];\n if (!page) continue;\n\n refreshedTiles[pageIndex] = calculateTilesForPage({\n page,\n metric,\n scale: this.coreState.core.scale,\n rotation: this.coreState.core.rotation,\n tileSize: this.config.tileSize,\n overlapPx: this.config.overlapPx,\n extraRings: this.config.extraRings,\n }).map((tile) => ({\n ...tile,\n id: `${tile.id}-r${refreshTimestamp}`, // Add refresh token to force new render\n }));\n }\n\n if (Object.keys(refreshedTiles).length > 0) {\n this.dispatch(updateVisibleTiles(refreshedTiles));\n }\n }\n\n async initialize(): Promise<void> {\n // Fetch dependencies from the registry if needed\n }\n\n protected onCoreStoreUpdated(\n oldState: StoreState<CoreState>,\n newState: StoreState<CoreState>,\n ): void {\n if (oldState.core.scale !== newState.core.scale) {\n this.calculateVisibleTiles(\n this.scrollCapability.getMetrics(this.viewportCapability.getMetrics()),\n );\n }\n }\n\n private calculateVisibleTiles(scrollMetrics: ScrollMetrics): void {\n if (!this.config.enabled) {\n this.dispatch(updateVisibleTiles([]));\n return;\n }\n\n const scale = this.coreState.core.scale;\n const rotation = this.coreState.core.rotation;\n const visibleTiles: { [pageIndex: number]: Tile[] } = {};\n\n for (const scrollMetric of scrollMetrics.pageVisibilityMetrics) {\n const pageIndex = scrollMetric.pageNumber - 1; // Convert to 0-based index\n const page = this.coreState.core.document?.pages[pageIndex];\n if (!page) continue;\n\n // Calculate tiles for the page using the utility function\n const tiles = calculateTilesForPage({\n page,\n metric: scrollMetric,\n scale,\n rotation,\n tileSize: this.config.tileSize,\n overlapPx: this.config.overlapPx,\n extraRings: this.config.extraRings,\n });\n\n visibleTiles[pageIndex] = tiles;\n }\n\n this.dispatch(updateVisibleTiles(visibleTiles));\n }\n\n override onStoreUpdated(_prevState: TilingState, newState: TilingState): void {\n this.tileRendering$.emit(newState.visibleTiles);\n }\n\n protected buildCapability(): TilingCapability {\n return {\n renderTile: this.renderTile.bind(this),\n onTileRendering: this.tileRendering$.on,\n };\n }\n\n private renderTile(options: RenderTileOptions) {\n if (!this.renderCapability) {\n throw new Error('Render capability not available.');\n }\n\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'rendering'));\n\n const task = this.renderCapability.renderPageRect({\n pageIndex: options.pageIndex,\n rect: options.tile.pageRect,\n options: {\n scaleFactor: options.tile.srcScale,\n dpr: options.dpr,\n },\n });\n\n task.wait(() => {\n this.dispatch(markTileStatus(options.pageIndex, options.tile.id, 'ready'));\n }, ignore);\n\n return task;\n }\n}\n","import { PluginPackage } from '@embedpdf/core';\n\nimport { TilingAction } from './actions';\nimport { manifest, TILING_PLUGIN_ID } from './manifest';\nimport { initialState, tilingReducer } from './reducer';\nimport { TilingPlugin } from './tiling-plugin';\nimport { TilingPluginConfig, TilingState } from './types';\n\nexport const TilingPluginPackage: PluginPackage<\n TilingPlugin,\n TilingPluginConfig,\n TilingState,\n TilingAction\n> = {\n manifest,\n create: (registry, config) => new TilingPlugin(TILING_PLUGIN_ID, registry, config),\n reducer: (state, action) => tilingReducer(state, action),\n initialState,\n};\n\nexport * from './tiling-plugin';\nexport * from './types';\nexport * from './manifest';\n"],"names":[],"mappings":"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"}
@@ -1,17 +1,16 @@
1
- import { BasePlugin, CoreState, PluginRegistry, StoreState, Unsubscribe } from '@embedpdf/core';
1
+ import { BasePlugin, CoreState, PluginRegistry, StoreState } from '@embedpdf/core';
2
2
  import { TilingPluginConfig, TilingCapability, TilingState } from './types';
3
3
  export declare class TilingPlugin extends BasePlugin<TilingPluginConfig, TilingCapability> {
4
4
  static readonly id: "tiling";
5
5
  private readonly tileRendering$;
6
- private readonly refreshPages$;
7
6
  private config;
8
7
  private renderCapability;
9
8
  private scrollCapability;
10
9
  private viewportCapability;
11
10
  constructor(id: string, registry: PluginRegistry, config: TilingPluginConfig);
11
+ recalculateTiles(pagesToRefresh: number[]): Promise<void>;
12
12
  initialize(): Promise<void>;
13
13
  protected onCoreStoreUpdated(oldState: StoreState<CoreState>, newState: StoreState<CoreState>): void;
14
- onRefreshPages(fn: (pages: number[]) => void): Unsubscribe;
15
14
  private calculateVisibleTiles;
16
15
  onStoreUpdated(_prevState: TilingState, newState: TilingState): void;
17
16
  protected buildCapability(): TilingCapability;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),r=require("@embedpdf/plugin-tiling"),t=require("preact/jsx-runtime");require("preact");const i=require("preact/hooks"),n=require("@embedpdf/models"),s=()=>e.usePlugin(r.TilingPlugin.id),c=()=>e.useCapability(r.TilingPlugin.id);function l({pageIndex:e,tile:r,dpr:l,scale:u}){const{provides:o}=c(),{plugin:d}=s(),[a,p]=i.useState(),g=i.useRef(null),[f,b]=i.useState(0),x=u/r.srcScale;i.useEffect((()=>{if(d)return d.onRefreshPages((r=>{r.includes(e)&&b((e=>e+1))}))}),[d]),i.useEffect((()=>{if("ready"===r.status&&g.current)return;if(!o)return;const t=o.renderTile({pageIndex:e,tile:r,dpr:l});return t.wait((e=>{const r=URL.createObjectURL(e);g.current=r,p(r)}),n.ignore),()=>{g.current?(URL.revokeObjectURL(g.current),g.current=null):t.abort({code:n.PdfErrorCode.Cancelled,message:"canceled render task"})}}),[e,r.id,f]);return a?t.jsx("img",{src:a,onLoad:()=>{g.current&&(URL.revokeObjectURL(g.current),g.current=null)},style:{position:"absolute",left:r.screenRect.origin.x*x,top:r.screenRect.origin.y*x,width:r.screenRect.size.width*x,height:r.screenRect.size.height*x,display:"block"}}):null}exports.TilingLayer=function({pageIndex:e,scale:r,style:n,...s}){const{provides:u}=c(),[o,d]=i.useState([]);return i.useEffect((()=>{if(u)return u.onTileRendering((r=>d(r[e])))}),[u]),t.jsx("div",{style:{...n},...s,children:null==o?void 0:o.map((i=>t.jsx(l,{pageIndex:e,tile:i,dpr:window.devicePixelRatio,scale:r},i.id)))})},exports.useTilingCapability=c,exports.useTilingPlugin=s,Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),r=require("@embedpdf/plugin-tiling"),t=require("preact/jsx-runtime");require("preact");const i=require("preact/hooks"),n=require("@embedpdf/models"),c=()=>e.useCapability(r.TilingPlugin.id);function s({pageIndex:e,tile:r,dpr:s,scale:l}){const{provides:o}=c(),[u,d]=i.useState(),a=i.useRef(null),p=l/r.srcScale;i.useEffect((()=>{if("ready"===r.status&&a.current)return;if(!o)return;const t=o.renderTile({pageIndex:e,tile:r,dpr:s});return t.wait((e=>{const r=URL.createObjectURL(e);a.current=r,d(r)}),n.ignore),()=>{a.current?(URL.revokeObjectURL(a.current),a.current=null):t.abort({code:n.PdfErrorCode.Cancelled,message:"canceled render task"})}}),[e,r.id]);return u?t.jsx("img",{src:u,onLoad:()=>{a.current&&(URL.revokeObjectURL(a.current),a.current=null)},style:{position:"absolute",left:r.screenRect.origin.x*p,top:r.screenRect.origin.y*p,width:r.screenRect.size.width*p,height:r.screenRect.size.height*p,display:"block"}}):null}exports.TilingLayer=function({pageIndex:e,scale:r,style:n,...l}){const{provides:o}=c(),[u,d]=i.useState([]);return i.useEffect((()=>{if(o)return o.onTileRendering((r=>d(r[e])))}),[o]),t.jsx("div",{style:{...n},...l,children:null==u?void 0:u.map((i=>t.jsx(s,{pageIndex:e,tile:i,dpr:window.devicePixelRatio,scale:r},i.id)))})},exports.useTilingCapability=c,exports.useTilingPlugin=()=>e.usePlugin(r.TilingPlugin.id),Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability, useTilingPlugin } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n const { plugin: tilingPlugin } = useTilingPlugin();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n const [refreshTick, setRefreshTick] = useState(0);\n\n const relativeScale = scale / tile.srcScale;\n\n useEffect(() => {\n if (!tilingPlugin) return;\n return tilingPlugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n setRefreshTick((tick) => tick + 1);\n }\n });\n }, [tilingPlugin]);\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id, refreshTick]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["useTilingPlugin","usePlugin","TilingPlugin","id","useTilingCapability","useCapability","TileImg","pageIndex","tile","dpr","scale","provides","tilingCapability","plugin","tilingPlugin","url","setUrl","useState","urlRef","useRef","refreshTick","setRefreshTick","relativeScale","srcScale","useEffect","onRefreshPages","pages","includes","tick","status","current","task","renderTile","wait","blob","objectUrl","URL","createObjectURL","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","jsxRuntime","jsx","src","onLoad","style","position","left","screenRect","origin","x","top","y","width","size","height","display","props","tilingProvides","tiles","setTiles","onTileRendering","children","map","window","devicePixelRatio"],"mappings":"8QAGaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,ICS3E,SAASG,GAAQC,UAAEA,EAAAC,KAAWA,EAAMC,IAAAA,EAAAC,MAAKA,IAC9C,MAAQC,SAAUC,GAAqBR,KAC/BS,OAAQC,GAAiBd,KAE1Be,EAAKC,GAAUC,aAChBC,EAASC,SAAsB,OAC9BC,EAAaC,GAAkBJ,EAAAA,SAAS,GAEzCK,EAAgBZ,EAAQF,EAAKe,SAEnCC,EAAAA,WAAU,KACR,GAAKV,EACE,OAAAA,EAAaW,gBAAgBC,IAC9BA,EAAMC,SAASpB,IACFc,GAACO,GAASA,EAAO,GAAC,GAEpC,GACA,CAACd,IAGJU,EAAAA,WAAU,KACR,GAAoB,UAAhBhB,EAAKqB,QAAsBX,EAAOY,QAAS,OAC/C,IAAKlB,EAAkB,OACvB,MAAMmB,EAAOnB,EAAiBoB,WAAW,CAAEzB,YAAWC,OAAMC,QAO5D,OANKsB,EAAAE,MAAMC,IACH,MAAAC,EAAYC,IAAIC,gBAAgBH,GACtChB,EAAOY,QAAUK,EACjBnB,EAAOmB,EAAS,GACfG,UAEI,KACDpB,EAAOY,SACLM,IAAAG,gBAAgBrB,EAAOY,SAC3BZ,EAAOY,QAAU,MAEjBC,EAAKS,MAAM,CACTC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,CAEL,GACC,CAACrC,EAAWC,EAAKL,GAAIiB,IASpB,OAACL,EAEH8B,EAAAC,IAAC,MAAA,CACCC,IAAKhC,EACLiC,OAXoB,KAClB9B,EAAOY,UACLM,IAAAG,gBAAgBrB,EAAOY,SAC3BZ,EAAOY,QAAU,KAAA,EASjBmB,MAAO,CACLC,SAAU,WACVC,KAAM3C,EAAK4C,WAAWC,OAAOC,EAAIhC,EACjCiC,IAAK/C,EAAK4C,WAAWC,OAAOG,EAAIlC,EAChCmC,MAAOjD,EAAK4C,WAAWM,KAAKD,MAAQnC,EACpCqC,OAAQnD,EAAK4C,WAAWM,KAAKC,OAASrC,EACtCsC,QAAS,WAXE,IAenB,qBClEO,UAAqBrD,UAAEA,EAAAG,MAAWA,QAAOuC,KAAUY,IACxD,MAAQlD,SAAUmD,GAAmB1D,KAC9B2D,EAAOC,GAAY/C,EAAAA,SAAiB,IASzC,OAPFO,EAAAA,WAAU,KACR,GAAIsC,EACK,OAAAA,EAAeG,iBAAiBF,GAAUC,EAASD,EAAMxD,KAAW,GAE5E,CAACuD,IAGFjB,EAAAC,IAAC,MAAA,CACCG,MAAO,IACFA,MAEDY,EAEHK,SAAA,MAAAH,OAAA,EAAAA,EAAOI,KAAK3D,GACXqC,EAAAC,IAACxC,EAAA,CAECC,YACAC,OACAC,IAAK2D,OAAOC,iBACZ3D,SAJKF,EAAKL,OASpB"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n const relativeScale = scale / tile.srcScale;\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["useTilingCapability","useCapability","TilingPlugin","id","TileImg","pageIndex","tile","dpr","scale","provides","tilingCapability","url","setUrl","useState","urlRef","useRef","relativeScale","srcScale","useEffect","status","current","task","renderTile","wait","blob","objectUrl","URL","createObjectURL","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","jsxRuntime","jsx","src","onLoad","style","position","left","screenRect","origin","x","top","y","width","size","height","display","props","tilingProvides","tiles","setTiles","onTileRendering","children","map","window","devicePixelRatio","usePlugin"],"mappings":"8QAIaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,ICS3E,SAASC,GAAQC,UAAEA,EAAAC,KAAWA,EAAMC,IAAAA,EAAAC,MAAKA,IAC9C,MAAQC,SAAUC,GAAqBV,KAEhCW,EAAKC,GAAUC,aAChBC,EAASC,SAAsB,MAE/BC,EAAgBR,EAAQF,EAAKW,SAGnCC,EAAAA,WAAU,KACR,GAAoB,UAAhBZ,EAAKa,QAAsBL,EAAOM,QAAS,OAC/C,IAAKV,EAAkB,OACvB,MAAMW,EAAOX,EAAiBY,WAAW,CAAEjB,YAAWC,OAAMC,QAO5D,OANKc,EAAAE,MAAMC,IACH,MAAAC,EAAYC,IAAIC,gBAAgBH,GACtCV,EAAOM,QAAUK,EACjBb,EAAOa,EAAS,GACfG,UAEI,KACDd,EAAOM,SACLM,IAAAG,gBAAgBf,EAAOM,SAC3BN,EAAOM,QAAU,MAEjBC,EAAKS,MAAM,CACTC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,CAEL,GACC,CAAC7B,EAAWC,EAAKH,KAShB,OAACQ,EAEHwB,EAAAC,IAAC,MAAA,CACCC,IAAK1B,EACL2B,OAXoB,KAClBxB,EAAOM,UACLM,IAAAG,gBAAgBf,EAAOM,SAC3BN,EAAOM,QAAU,KAAA,EASjBmB,MAAO,CACLC,SAAU,WACVC,KAAMnC,EAAKoC,WAAWC,OAAOC,EAAI5B,EACjC6B,IAAKvC,EAAKoC,WAAWC,OAAOG,EAAI9B,EAChC+B,MAAOzC,EAAKoC,WAAWM,KAAKD,MAAQ/B,EACpCiC,OAAQ3C,EAAKoC,WAAWM,KAAKC,OAASjC,EACtCkC,QAAS,WAXE,IAenB,qBCvDO,UAAqB7C,UAAEA,EAAAG,MAAWA,QAAO+B,KAAUY,IACxD,MAAQ1C,SAAU2C,GAAmBpD,KAC9BqD,EAAOC,GAAYzC,EAAAA,SAAiB,IASzC,OAPFK,EAAAA,WAAU,KACR,GAAIkC,EACK,OAAAA,EAAeG,iBAAiBF,GAAUC,EAASD,EAAMhD,KAAW,GAE5E,CAAC+C,IAGFjB,EAAAC,IAAC,MAAA,CACCG,MAAO,IACFA,MAEDY,EAEHK,SAAA,MAAAH,OAAA,EAAAA,EAAOI,KAAKnD,GACX6B,EAAAC,IAAChC,EAAA,CAECC,YACAC,OACAC,IAAKmD,OAAOC,iBACZnD,SAJKF,EAAKH,OASpB,wDFrC+B,IAAMyD,YAAwB1D,EAAAA,aAAaC"}
@@ -9,19 +9,9 @@ const useTilingPlugin = () => usePlugin(TilingPlugin.id);
9
9
  const useTilingCapability = () => useCapability(TilingPlugin.id);
10
10
  function TileImg({ pageIndex, tile, dpr, scale }) {
11
11
  const { provides: tilingCapability } = useTilingCapability();
12
- const { plugin: tilingPlugin } = useTilingPlugin();
13
12
  const [url, setUrl] = useState();
14
13
  const urlRef = useRef(null);
15
- const [refreshTick, setRefreshTick] = useState(0);
16
14
  const relativeScale = scale / tile.srcScale;
17
- useEffect(() => {
18
- if (!tilingPlugin) return;
19
- return tilingPlugin.onRefreshPages((pages) => {
20
- if (pages.includes(pageIndex)) {
21
- setRefreshTick((tick) => tick + 1);
22
- }
23
- });
24
- }, [tilingPlugin]);
25
15
  useEffect(() => {
26
16
  if (tile.status === "ready" && urlRef.current) return;
27
17
  if (!tilingCapability) return;
@@ -42,7 +32,7 @@ function TileImg({ pageIndex, tile, dpr, scale }) {
42
32
  });
43
33
  }
44
34
  };
45
- }, [pageIndex, tile.id, refreshTick]);
35
+ }, [pageIndex, tile.id]);
46
36
  const handleImageLoad = () => {
47
37
  if (urlRef.current) {
48
38
  URL.revokeObjectURL(urlRef.current);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability, useTilingPlugin } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n const { plugin: tilingPlugin } = useTilingPlugin();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n const [refreshTick, setRefreshTick] = useState(0);\n\n const relativeScale = scale / tile.srcScale;\n\n useEffect(() => {\n if (!tilingPlugin) return;\n return tilingPlugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n setRefreshTick((tick) => tick + 1);\n }\n });\n }, [tilingPlugin]);\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id, refreshTick]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["tiles"],"mappings":";;;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;ACS7E,SAAS,QAAQ,EAAE,WAAW,MAAM,KAAK,SAAuB;AACrE,QAAM,EAAE,UAAU,iBAAiB,IAAI,oBAAoB;AAC3D,QAAM,EAAE,QAAQ,aAAa,IAAI,gBAAgB;AAEjD,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiB;AACjC,QAAA,SAAS,OAAsB,IAAI;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC;AAE1C,QAAA,gBAAgB,QAAQ,KAAK;AAEnC,YAAU,MAAM;AACd,QAAI,CAAC,aAAc;AACZ,WAAA,aAAa,eAAe,CAAC,UAAU;AACxC,UAAA,MAAM,SAAS,SAAS,GAAG;AACd,uBAAA,CAAC,SAAS,OAAO,CAAC;AAAA,MAAA;AAAA,IACnC,CACD;AAAA,EAAA,GACA,CAAC,YAAY,CAAC;AAGjB,YAAU,MAAM;AACd,QAAI,KAAK,WAAW,WAAW,OAAO,QAAS;AAC/C,QAAI,CAAC,iBAAkB;AACvB,UAAM,OAAO,iBAAiB,WAAW,EAAE,WAAW,MAAM,KAAK;AAC5D,SAAA,KAAK,CAAC,SAAS;AACZ,YAAA,YAAY,IAAI,gBAAgB,IAAI;AAC1C,aAAO,UAAU;AACjB,aAAO,SAAS;AAAA,OACf,MAAM;AAET,WAAO,MAAM;AACX,UAAI,OAAO,SAAS;AACd,YAAA,gBAAgB,OAAO,OAAO;AAClC,eAAO,UAAU;AAAA,MAAA,OACZ;AACL,aAAK,MAAM;AAAA,UACT,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IAEL;AAAA,KACC,CAAC,WAAW,KAAK,IAAI,WAAW,CAAC;AAEpC,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AACd,UAAA,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IAAA;AAAA,EAErB;AAEI,MAAA,CAAC,IAAY,QAAA;AAEf,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,KAAK,WAAW,OAAO,IAAI;AAAA,QACjC,KAAK,KAAK,WAAW,OAAO,IAAI;AAAA,QAChC,OAAO,KAAK,WAAW,KAAK,QAAQ;AAAA,QACpC,QAAQ,KAAK,WAAW,KAAK,SAAS;AAAA,QACtC,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,EACF;AAEJ;AClEO,SAAS,YAAY,EAAE,WAAW,OAAO,OAAO,GAAG,SAA4B;AACpF,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAE7C,YAAU,MAAM;AACd,QAAI,gBAAgB;AACX,aAAA,eAAe,gBAAgB,CAACA,WAAU,SAASA,OAAM,SAAS,CAAC,CAAC;AAAA,IAAA;AAAA,EAC7E,GACC,CAAC,cAAc,CAAC;AAGjB,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAA,+BAAO,IAAI,CAAC,SACX;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,KAAK,OAAO;AAAA,UACZ;AAAA,QAAA;AAAA,QAJK,KAAK;AAAA,MAMb;AAAA,IAAA;AAAA,EACH;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n const relativeScale = scale / tile.srcScale;\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["tiles"],"mappings":";;;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;ACS7E,SAAS,QAAQ,EAAE,WAAW,MAAM,KAAK,SAAuB;AACrE,QAAM,EAAE,UAAU,iBAAiB,IAAI,oBAAoB;AAE3D,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiB;AACjC,QAAA,SAAS,OAAsB,IAAI;AAEnC,QAAA,gBAAgB,QAAQ,KAAK;AAGnC,YAAU,MAAM;AACd,QAAI,KAAK,WAAW,WAAW,OAAO,QAAS;AAC/C,QAAI,CAAC,iBAAkB;AACvB,UAAM,OAAO,iBAAiB,WAAW,EAAE,WAAW,MAAM,KAAK;AAC5D,SAAA,KAAK,CAAC,SAAS;AACZ,YAAA,YAAY,IAAI,gBAAgB,IAAI;AAC1C,aAAO,UAAU;AACjB,aAAO,SAAS;AAAA,OACf,MAAM;AAET,WAAO,MAAM;AACX,UAAI,OAAO,SAAS;AACd,YAAA,gBAAgB,OAAO,OAAO;AAClC,eAAO,UAAU;AAAA,MAAA,OACZ;AACL,aAAK,MAAM;AAAA,UACT,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IAEL;AAAA,EACC,GAAA,CAAC,WAAW,KAAK,EAAE,CAAC;AAEvB,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AACd,UAAA,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IAAA;AAAA,EAErB;AAEI,MAAA,CAAC,IAAY,QAAA;AAEf,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,KAAK,WAAW,OAAO,IAAI;AAAA,QACjC,KAAK,KAAK,WAAW,OAAO,IAAI;AAAA,QAChC,OAAO,KAAK,WAAW,KAAK,QAAQ;AAAA,QACpC,QAAQ,KAAK,WAAW,KAAK,SAAS;AAAA,QACtC,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,EACF;AAEJ;ACvDO,SAAS,YAAY,EAAE,WAAW,OAAO,OAAO,GAAG,SAA4B;AACpF,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAE7C,YAAU,MAAM;AACd,QAAI,gBAAgB;AACX,aAAA,eAAe,gBAAgB,CAACA,WAAU,SAASA,OAAM,SAAS,CAAC,CAAC;AAAA,IAAA;AAAA,EAC7E,GACC,CAAC,cAAc,CAAC;AAGjB,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAA,+BAAO,IAAI,CAAC,SACX;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,KAAK,OAAO;AAAA,UACZ;AAAA,QAAA;AAAA,QAJK,KAAK;AAAA,MAMb;AAAA,IAAA;AAAA,EACH;AAEJ;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),r=require("@embedpdf/plugin-tiling"),t=require("react/jsx-runtime"),i=require("react"),n=require("@embedpdf/models"),s=()=>e.usePlugin(r.TilingPlugin.id),c=()=>e.useCapability(r.TilingPlugin.id);function l({pageIndex:e,tile:r,dpr:l,scale:u}){const{provides:o}=c(),{plugin:d}=s(),[a,p]=i.useState(),g=i.useRef(null),[f,b]=i.useState(0),x=u/r.srcScale;i.useEffect((()=>{if(d)return d.onRefreshPages((r=>{r.includes(e)&&b((e=>e+1))}))}),[d]),i.useEffect((()=>{if("ready"===r.status&&g.current)return;if(!o)return;const t=o.renderTile({pageIndex:e,tile:r,dpr:l});return t.wait((e=>{const r=URL.createObjectURL(e);g.current=r,p(r)}),n.ignore),()=>{g.current?(URL.revokeObjectURL(g.current),g.current=null):t.abort({code:n.PdfErrorCode.Cancelled,message:"canceled render task"})}}),[e,r.id,f]);return a?t.jsx("img",{src:a,onLoad:()=>{g.current&&(URL.revokeObjectURL(g.current),g.current=null)},style:{position:"absolute",left:r.screenRect.origin.x*x,top:r.screenRect.origin.y*x,width:r.screenRect.size.width*x,height:r.screenRect.size.height*x,display:"block"}}):null}exports.TilingLayer=function({pageIndex:e,scale:r,style:n,...s}){const{provides:u}=c(),[o,d]=i.useState([]);return i.useEffect((()=>{if(u)return u.onTileRendering((r=>d(r[e])))}),[u]),t.jsx("div",{style:{...n},...s,children:null==o?void 0:o.map((i=>t.jsx(l,{pageIndex:e,tile:i,dpr:window.devicePixelRatio,scale:r},i.id)))})},exports.useTilingCapability=c,exports.useTilingPlugin=s,Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/react"),r=require("@embedpdf/plugin-tiling"),t=require("react/jsx-runtime"),i=require("react"),n=require("@embedpdf/models"),c=()=>e.useCapability(r.TilingPlugin.id);function s({pageIndex:e,tile:r,dpr:s,scale:l}){const{provides:u}=c(),[o,d]=i.useState(),a=i.useRef(null),p=l/r.srcScale;i.useEffect((()=>{if("ready"===r.status&&a.current)return;if(!u)return;const t=u.renderTile({pageIndex:e,tile:r,dpr:s});return t.wait((e=>{const r=URL.createObjectURL(e);a.current=r,d(r)}),n.ignore),()=>{a.current?(URL.revokeObjectURL(a.current),a.current=null):t.abort({code:n.PdfErrorCode.Cancelled,message:"canceled render task"})}}),[e,r.id]);return o?t.jsx("img",{src:o,onLoad:()=>{a.current&&(URL.revokeObjectURL(a.current),a.current=null)},style:{position:"absolute",left:r.screenRect.origin.x*p,top:r.screenRect.origin.y*p,width:r.screenRect.size.width*p,height:r.screenRect.size.height*p,display:"block"}}):null}exports.TilingLayer=function({pageIndex:e,scale:r,style:n,...l}){const{provides:u}=c(),[o,d]=i.useState([]);return i.useEffect((()=>{if(u)return u.onTileRendering((r=>d(r[e])))}),[u]),t.jsx("div",{style:{...n},...l,children:null==o?void 0:o.map((i=>t.jsx(s,{pageIndex:e,tile:i,dpr:window.devicePixelRatio,scale:r},i.id)))})},exports.useTilingCapability=c,exports.useTilingPlugin=()=>e.usePlugin(r.TilingPlugin.id),Object.keys(r).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>r[e]})}));
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability, useTilingPlugin } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n const { plugin: tilingPlugin } = useTilingPlugin();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n const [refreshTick, setRefreshTick] = useState(0);\n\n const relativeScale = scale / tile.srcScale;\n\n useEffect(() => {\n if (!tilingPlugin) return;\n return tilingPlugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n setRefreshTick((tick) => tick + 1);\n }\n });\n }, [tilingPlugin]);\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id, refreshTick]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["useTilingPlugin","usePlugin","TilingPlugin","id","useTilingCapability","useCapability","TileImg","pageIndex","tile","dpr","scale","provides","tilingCapability","plugin","tilingPlugin","url","setUrl","useState","urlRef","useRef","refreshTick","setRefreshTick","relativeScale","srcScale","useEffect","onRefreshPages","pages","includes","tick","status","current","task","renderTile","wait","blob","objectUrl","URL","createObjectURL","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","jsxRuntime","jsx","src","onLoad","style","position","left","screenRect","origin","x","top","y","width","size","height","display","props","tilingProvides","tiles","setTiles","onTileRendering","children","map","window","devicePixelRatio"],"mappings":"6OAGaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,ICS3E,SAASG,GAAQC,UAAEA,EAAAC,KAAWA,EAAMC,IAAAA,EAAAC,MAAKA,IAC9C,MAAQC,SAAUC,GAAqBR,KAC/BS,OAAQC,GAAiBd,KAE1Be,EAAKC,GAAUC,aAChBC,EAASC,SAAsB,OAC9BC,EAAaC,GAAkBJ,EAAAA,SAAS,GAEzCK,EAAgBZ,EAAQF,EAAKe,SAEnCC,EAAAA,WAAU,KACR,GAAKV,EACE,OAAAA,EAAaW,gBAAgBC,IAC9BA,EAAMC,SAASpB,IACFc,GAACO,GAASA,EAAO,GAAC,GAEpC,GACA,CAACd,IAGJU,EAAAA,WAAU,KACR,GAAoB,UAAhBhB,EAAKqB,QAAsBX,EAAOY,QAAS,OAC/C,IAAKlB,EAAkB,OACvB,MAAMmB,EAAOnB,EAAiBoB,WAAW,CAAEzB,YAAWC,OAAMC,QAO5D,OANKsB,EAAAE,MAAMC,IACH,MAAAC,EAAYC,IAAIC,gBAAgBH,GACtChB,EAAOY,QAAUK,EACjBnB,EAAOmB,EAAS,GACfG,UAEI,KACDpB,EAAOY,SACLM,IAAAG,gBAAgBrB,EAAOY,SAC3BZ,EAAOY,QAAU,MAEjBC,EAAKS,MAAM,CACTC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,CAEL,GACC,CAACrC,EAAWC,EAAKL,GAAIiB,IASpB,OAACL,EAEH8B,EAAAC,IAAC,MAAA,CACCC,IAAKhC,EACLiC,OAXoB,KAClB9B,EAAOY,UACLM,IAAAG,gBAAgBrB,EAAOY,SAC3BZ,EAAOY,QAAU,KAAA,EASjBmB,MAAO,CACLC,SAAU,WACVC,KAAM3C,EAAK4C,WAAWC,OAAOC,EAAIhC,EACjCiC,IAAK/C,EAAK4C,WAAWC,OAAOG,EAAIlC,EAChCmC,MAAOjD,EAAK4C,WAAWM,KAAKD,MAAQnC,EACpCqC,OAAQnD,EAAK4C,WAAWM,KAAKC,OAASrC,EACtCsC,QAAS,WAXE,IAenB,qBClEO,UAAqBrD,UAAEA,EAAAG,MAAWA,QAAOuC,KAAUY,IACxD,MAAQlD,SAAUmD,GAAmB1D,KAC9B2D,EAAOC,GAAY/C,EAAAA,SAAiB,IASzC,OAPFO,EAAAA,WAAU,KACR,GAAIsC,EACK,OAAAA,EAAeG,iBAAiBF,GAAUC,EAASD,EAAMxD,KAAW,GAE5E,CAACuD,IAGFjB,EAAAC,IAAC,MAAA,CACCG,MAAO,IACFA,MAEDY,EAEHK,SAAA,MAAAH,OAAA,EAAAA,EAAOI,KAAK3D,GACXqC,EAAAC,IAACxC,EAAA,CAECC,YACAC,OACAC,IAAK2D,OAAOC,iBACZ3D,SAJKF,EAAKL,OASpB"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n const relativeScale = scale / tile.srcScale;\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["useTilingCapability","useCapability","TilingPlugin","id","TileImg","pageIndex","tile","dpr","scale","provides","tilingCapability","url","setUrl","useState","urlRef","useRef","relativeScale","srcScale","useEffect","status","current","task","renderTile","wait","blob","objectUrl","URL","createObjectURL","ignore","revokeObjectURL","abort","code","PdfErrorCode","Cancelled","message","jsxRuntime","jsx","src","onLoad","style","position","left","screenRect","origin","x","top","y","width","size","height","display","props","tilingProvides","tiles","setTiles","onTileRendering","children","map","window","devicePixelRatio","usePlugin"],"mappings":"6OAIaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,ICS3E,SAASC,GAAQC,UAAEA,EAAAC,KAAWA,EAAMC,IAAAA,EAAAC,MAAKA,IAC9C,MAAQC,SAAUC,GAAqBV,KAEhCW,EAAKC,GAAUC,aAChBC,EAASC,SAAsB,MAE/BC,EAAgBR,EAAQF,EAAKW,SAGnCC,EAAAA,WAAU,KACR,GAAoB,UAAhBZ,EAAKa,QAAsBL,EAAOM,QAAS,OAC/C,IAAKV,EAAkB,OACvB,MAAMW,EAAOX,EAAiBY,WAAW,CAAEjB,YAAWC,OAAMC,QAO5D,OANKc,EAAAE,MAAMC,IACH,MAAAC,EAAYC,IAAIC,gBAAgBH,GACtCV,EAAOM,QAAUK,EACjBb,EAAOa,EAAS,GACfG,UAEI,KACDd,EAAOM,SACLM,IAAAG,gBAAgBf,EAAOM,SAC3BN,EAAOM,QAAU,MAEjBC,EAAKS,MAAM,CACTC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,CAEL,GACC,CAAC7B,EAAWC,EAAKH,KAShB,OAACQ,EAEHwB,EAAAC,IAAC,MAAA,CACCC,IAAK1B,EACL2B,OAXoB,KAClBxB,EAAOM,UACLM,IAAAG,gBAAgBf,EAAOM,SAC3BN,EAAOM,QAAU,KAAA,EASjBmB,MAAO,CACLC,SAAU,WACVC,KAAMnC,EAAKoC,WAAWC,OAAOC,EAAI5B,EACjC6B,IAAKvC,EAAKoC,WAAWC,OAAOG,EAAI9B,EAChC+B,MAAOzC,EAAKoC,WAAWM,KAAKD,MAAQ/B,EACpCiC,OAAQ3C,EAAKoC,WAAWM,KAAKC,OAASjC,EACtCkC,QAAS,WAXE,IAenB,qBCvDO,UAAqB7C,UAAEA,EAAAG,MAAWA,QAAO+B,KAAUY,IACxD,MAAQ1C,SAAU2C,GAAmBpD,KAC9BqD,EAAOC,GAAYzC,EAAAA,SAAiB,IASzC,OAPFK,EAAAA,WAAU,KACR,GAAIkC,EACK,OAAAA,EAAeG,iBAAiBF,GAAUC,EAASD,EAAMhD,KAAW,GAE5E,CAAC+C,IAGFjB,EAAAC,IAAC,MAAA,CACCG,MAAO,IACFA,MAEDY,EAEHK,SAAA,MAAAH,OAAA,EAAAA,EAAOI,KAAKnD,GACX6B,EAAAC,IAAChC,EAAA,CAECC,YACAC,OACAC,IAAKmD,OAAOC,iBACZnD,SAJKF,EAAKH,OASpB,wDFrC+B,IAAMyD,YAAwB1D,EAAAA,aAAaC"}
@@ -8,19 +8,9 @@ const useTilingPlugin = () => usePlugin(TilingPlugin.id);
8
8
  const useTilingCapability = () => useCapability(TilingPlugin.id);
9
9
  function TileImg({ pageIndex, tile, dpr, scale }) {
10
10
  const { provides: tilingCapability } = useTilingCapability();
11
- const { plugin: tilingPlugin } = useTilingPlugin();
12
11
  const [url, setUrl] = useState();
13
12
  const urlRef = useRef(null);
14
- const [refreshTick, setRefreshTick] = useState(0);
15
13
  const relativeScale = scale / tile.srcScale;
16
- useEffect(() => {
17
- if (!tilingPlugin) return;
18
- return tilingPlugin.onRefreshPages((pages) => {
19
- if (pages.includes(pageIndex)) {
20
- setRefreshTick((tick) => tick + 1);
21
- }
22
- });
23
- }, [tilingPlugin]);
24
14
  useEffect(() => {
25
15
  if (tile.status === "ready" && urlRef.current) return;
26
16
  if (!tilingCapability) return;
@@ -41,7 +31,7 @@ function TileImg({ pageIndex, tile, dpr, scale }) {
41
31
  });
42
32
  }
43
33
  };
44
- }, [pageIndex, tile.id, refreshTick]);
34
+ }, [pageIndex, tile.id]);
45
35
  const handleImageLoad = () => {
46
36
  if (urlRef.current) {
47
37
  URL.revokeObjectURL(urlRef.current);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability, useTilingPlugin } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n const { plugin: tilingPlugin } = useTilingPlugin();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n const [refreshTick, setRefreshTick] = useState(0);\n\n const relativeScale = scale / tile.srcScale;\n\n useEffect(() => {\n if (!tilingPlugin) return;\n return tilingPlugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n setRefreshTick((tick) => tick + 1);\n }\n });\n }, [tilingPlugin]);\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id, refreshTick]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["tiles"],"mappings":";;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;ACS7E,SAAS,QAAQ,EAAE,WAAW,MAAM,KAAK,SAAuB;AACrE,QAAM,EAAE,UAAU,iBAAiB,IAAI,oBAAoB;AAC3D,QAAM,EAAE,QAAQ,aAAa,IAAI,gBAAgB;AAEjD,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiB;AACjC,QAAA,SAAS,OAAsB,IAAI;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC;AAE1C,QAAA,gBAAgB,QAAQ,KAAK;AAEnC,YAAU,MAAM;AACd,QAAI,CAAC,aAAc;AACZ,WAAA,aAAa,eAAe,CAAC,UAAU;AACxC,UAAA,MAAM,SAAS,SAAS,GAAG;AACd,uBAAA,CAAC,SAAS,OAAO,CAAC;AAAA,MAAA;AAAA,IACnC,CACD;AAAA,EAAA,GACA,CAAC,YAAY,CAAC;AAGjB,YAAU,MAAM;AACd,QAAI,KAAK,WAAW,WAAW,OAAO,QAAS;AAC/C,QAAI,CAAC,iBAAkB;AACvB,UAAM,OAAO,iBAAiB,WAAW,EAAE,WAAW,MAAM,KAAK;AAC5D,SAAA,KAAK,CAAC,SAAS;AACZ,YAAA,YAAY,IAAI,gBAAgB,IAAI;AAC1C,aAAO,UAAU;AACjB,aAAO,SAAS;AAAA,OACf,MAAM;AAET,WAAO,MAAM;AACX,UAAI,OAAO,SAAS;AACd,YAAA,gBAAgB,OAAO,OAAO;AAClC,eAAO,UAAU;AAAA,MAAA,OACZ;AACL,aAAK,MAAM;AAAA,UACT,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IAEL;AAAA,KACC,CAAC,WAAW,KAAK,IAAI,WAAW,CAAC;AAEpC,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AACd,UAAA,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IAAA;AAAA,EAErB;AAEI,MAAA,CAAC,IAAY,QAAA;AAEf,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,KAAK,WAAW,OAAO,IAAI;AAAA,QACjC,KAAK,KAAK,WAAW,OAAO,IAAI;AAAA,QAChC,OAAO,KAAK,WAAW,KAAK,QAAQ;AAAA,QACpC,QAAQ,KAAK,WAAW,KAAK,SAAS;AAAA,QACtC,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,EACF;AAEJ;AClEO,SAAS,YAAY,EAAE,WAAW,OAAO,OAAO,GAAG,SAA4B;AACpF,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAE7C,YAAU,MAAM;AACd,QAAI,gBAAgB;AACX,aAAA,eAAe,gBAAgB,CAACA,WAAU,SAASA,OAAM,SAAS,CAAC,CAAC;AAAA,IAAA;AAAA,EAC7E,GACC,CAAC,cAAc,CAAC;AAGjB,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAA,+BAAO,IAAI,CAAC,SACX;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,KAAK,OAAO;AAAA,UACZ;AAAA,QAAA;AAAA,QAJK,KAAK;AAAA,MAMb;AAAA,IAAA;AAAA,EACH;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-tiling.ts","../../src/shared/components/tile-img.tsx","../../src/shared/components/tiling-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","import { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useRef, useState } from '@framework';\n\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ninterface TileImgProps {\n pageIndex: number;\n tile: Tile;\n dpr: number;\n scale: number;\n}\n\nexport function TileImg({ pageIndex, tile, dpr, scale }: TileImgProps) {\n const { provides: tilingCapability } = useTilingCapability();\n\n const [url, setUrl] = useState<string>();\n const urlRef = useRef<string | null>(null);\n\n const relativeScale = scale / tile.srcScale;\n\n /* kick off render exactly once per tile */\n useEffect(() => {\n if (tile.status === 'ready' && urlRef.current) return; // already done\n if (!tilingCapability) return;\n const task = tilingCapability.renderTile({ pageIndex, tile, dpr });\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef.current = objectUrl;\n setUrl(objectUrl);\n }, ignore);\n\n return () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n }, [pageIndex, tile.id]); // id includes scale, so unique\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n if (!url) return null; // could render a placeholder\n return (\n <img\n src={url}\n onLoad={handleImageLoad}\n style={{\n position: 'absolute',\n left: tile.screenRect.origin.x * relativeScale,\n top: tile.screenRect.origin.y * relativeScale,\n width: tile.screenRect.size.width * relativeScale,\n height: tile.screenRect.size.height * relativeScale,\n display: 'block',\n }}\n />\n );\n}\n","import { Tile } from '@embedpdf/plugin-tiling';\nimport { useEffect, useState, HTMLAttributes, CSSProperties } from '@framework';\n\nimport { TileImg } from './tile-img';\nimport { useTilingCapability } from '../hooks/use-tiling';\n\ntype TilingLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n style?: CSSProperties;\n};\n\nexport function TilingLayer({ pageIndex, scale, style, ...props }: TilingLayoutProps) {\n const { provides: tilingProvides } = useTilingCapability();\n const [tiles, setTiles] = useState<Tile[]>([]);\n\n useEffect(() => {\n if (tilingProvides) {\n return tilingProvides.onTileRendering((tiles) => setTiles(tiles[pageIndex]));\n }\n }, [tilingProvides]);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {tiles?.map((tile) => (\n <TileImg\n key={tile.id}\n pageIndex={pageIndex}\n tile={tile}\n dpr={window.devicePixelRatio}\n scale={scale}\n />\n ))}\n </div>\n );\n}\n"],"names":["tiles"],"mappings":";;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;ACS7E,SAAS,QAAQ,EAAE,WAAW,MAAM,KAAK,SAAuB;AACrE,QAAM,EAAE,UAAU,iBAAiB,IAAI,oBAAoB;AAE3D,QAAM,CAAC,KAAK,MAAM,IAAI,SAAiB;AACjC,QAAA,SAAS,OAAsB,IAAI;AAEnC,QAAA,gBAAgB,QAAQ,KAAK;AAGnC,YAAU,MAAM;AACd,QAAI,KAAK,WAAW,WAAW,OAAO,QAAS;AAC/C,QAAI,CAAC,iBAAkB;AACvB,UAAM,OAAO,iBAAiB,WAAW,EAAE,WAAW,MAAM,KAAK;AAC5D,SAAA,KAAK,CAAC,SAAS;AACZ,YAAA,YAAY,IAAI,gBAAgB,IAAI;AAC1C,aAAO,UAAU;AACjB,aAAO,SAAS;AAAA,OACf,MAAM;AAET,WAAO,MAAM;AACX,UAAI,OAAO,SAAS;AACd,YAAA,gBAAgB,OAAO,OAAO;AAClC,eAAO,UAAU;AAAA,MAAA,OACZ;AACL,aAAK,MAAM;AAAA,UACT,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IAEL;AAAA,EACC,GAAA,CAAC,WAAW,KAAK,EAAE,CAAC;AAEvB,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AACd,UAAA,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IAAA;AAAA,EAErB;AAEI,MAAA,CAAC,IAAY,QAAA;AAEf,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,OAAO;AAAA,QACL,UAAU;AAAA,QACV,MAAM,KAAK,WAAW,OAAO,IAAI;AAAA,QACjC,KAAK,KAAK,WAAW,OAAO,IAAI;AAAA,QAChC,OAAO,KAAK,WAAW,KAAK,QAAQ;AAAA,QACpC,QAAQ,KAAK,WAAW,KAAK,SAAS;AAAA,QACtC,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,EACF;AAEJ;ACvDO,SAAS,YAAY,EAAE,WAAW,OAAO,OAAO,GAAG,SAA4B;AACpF,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAiB,CAAA,CAAE;AAE7C,YAAU,MAAM;AACd,QAAI,gBAAgB;AACX,aAAA,eAAe,gBAAgB,CAACA,WAAU,SAASA,OAAM,SAAS,CAAC,CAAC;AAAA,IAAA;AAAA,EAC7E,GACC,CAAC,cAAc,CAAC;AAGjB,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,UAAA,+BAAO,IAAI,CAAC,SACX;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA,KAAK,OAAO;AAAA,UACZ;AAAA,QAAA;AAAA,QAJK,KAAK;AAAA,MAMb;AAAA,IAAA;AAAA,EACH;AAEJ;"}
@@ -1,11 +1,9 @@
1
- import { StyleValue } from 'vue';
2
1
  import { Tile } from '../../lib/index.ts';
3
2
  interface Props {
4
3
  pageIndex: number;
5
4
  tile: Tile;
6
5
  scale: number;
7
6
  dpr?: number;
8
- style?: StyleValue;
9
7
  }
10
8
  declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {
11
9
  dpr: number;
@@ -1,8 +1,6 @@
1
- import { StyleValue } from 'vue';
2
1
  interface Props {
3
2
  pageIndex: number;
4
3
  scale: number;
5
- style?: StyleValue;
6
4
  }
7
5
  declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
8
6
  export default _default;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=require("@embedpdf/models"),t=require("@embedpdf/core/vue"),n=require("@embedpdf/plugin-tiling"),r=()=>t.useCapability(n.TilingPlugin.id),i=["src"],o=e.defineComponent({__name:"tile-img",props:{pageIndex:{},tile:{},scale:{},dpr:{default:()=>window.devicePixelRatio},style:{type:[Boolean,null,String,Object,Array]}},setup(t){const n=t,{provides:o}=r(),a=e.ref();let c=null,s=null;function u(){c&&(URL.revokeObjectURL(c),c=null)}e.onMounted((()=>{if(!o.value)return;const t=o.value.renderTile({pageIndex:n.pageIndex,tile:e.toRaw(n.tile),dpr:n.dpr});s=t,t.wait((e=>{c=URL.createObjectURL(e),a.value=c,s=null}),l.ignore)})),e.onBeforeUnmount((()=>{s&&!c&&s.abort({code:l.PdfErrorCode.Cancelled,message:"canceled tile render"}),u()}));const p=e.computed((()=>n.scale/n.tile.srcScale));return(l,t)=>a.value?(e.openBlock(),e.createElementBlock("img",{key:0,src:a.value,style:e.normalizeStyle([{position:"absolute",left:l.tile.screenRect.origin.x*p.value+"px",top:l.tile.screenRect.origin.y*p.value+"px",width:l.tile.screenRect.size.width*p.value+"px",height:l.tile.screenRect.size.height*p.value+"px",display:"block"},n.style]),onLoad:u},null,44,i)):e.createCommentVNode("",!0)}}),a=e.defineComponent({__name:"tiling-layer",props:{pageIndex:{},scale:{},style:{type:[Boolean,null,String,Object,Array]}},setup(l){const t=l,n=e.ref([]),{provides:i}=r();let a;return e.onMounted((()=>{i.value&&(a=i.value.onTileRendering((e=>{n.value=e[t.pageIndex]??[]})))})),e.onBeforeUnmount((()=>{null==a||a()})),(l,t)=>(e.openBlock(),e.createElementBlock("div",e.mergeProps({style:l.style},l.$attrs),[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(n.value,(t=>(e.openBlock(),e.createBlock(o,{key:t.id,pageIndex:l.pageIndex,tile:t,scale:l.scale},null,8,["pageIndex","tile","scale"])))),128))],16))}});exports.TileImg=o,exports.TilingLayer=a,exports.useTilingCapability=r,exports.useTilingPlugin=()=>t.usePlugin(n.TilingPlugin.id),Object.keys(n).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>n[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),l=require("@embedpdf/models"),t=require("@embedpdf/core/vue"),i=require("@embedpdf/plugin-tiling"),n=()=>t.useCapability(i.TilingPlugin.id),o=["src"],r=e.defineComponent({__name:"tile-img",props:{pageIndex:{},tile:{},scale:{},dpr:{default:()=>"undefined"!=typeof window?window.devicePixelRatio:1}},setup(t){const i=t,{provides:r}=n(),a=e.ref(),d=e.computed((()=>i.scale/i.tile.srcScale));let u,c=null;return e.watch([()=>i.tile.id,r],(([t,n])=>{n&&u!==t&&(c&&(c.abort({code:l.PdfErrorCode.Cancelled,message:"switching tiles"}),c=null),a.value&&(URL.revokeObjectURL(a.value),a.value=void 0),u=t,c=n.renderTile({pageIndex:i.pageIndex,tile:e.toRaw(i.tile),dpr:i.dpr}),c.wait((e=>{a.value=URL.createObjectURL(e),c=null}),l.ignore))}),{immediate:!0}),e.onBeforeUnmount((()=>{c&&c.abort({code:l.PdfErrorCode.Cancelled,message:"unmounting"}),a.value&&URL.revokeObjectURL(a.value)})),(l,t)=>a.value?(e.openBlock(),e.createElementBlock("img",{key:0,src:a.value,style:e.normalizeStyle({position:"absolute",left:l.tile.screenRect.origin.x*d.value+"px",top:l.tile.screenRect.origin.y*d.value+"px",width:l.tile.screenRect.size.width*d.value+"px",height:l.tile.screenRect.size.height*d.value+"px",display:"block"})},null,12,o)):e.createCommentVNode("",!0)}}),a=e.defineComponent({__name:"tiling-layer",props:{pageIndex:{},scale:{}},setup(l){const t=l,i=e.ref([]),{provides:o}=n();let a;return e.onMounted((()=>{o.value&&(a=o.value.onTileRendering((e=>{i.value=e[t.pageIndex]??[]})))})),e.onBeforeUnmount((()=>{null==a||a()})),(l,t)=>(e.openBlock(),e.createElementBlock("div",e.normalizeProps(e.guardReactiveProps(l.$attrs)),[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(i.value,(t=>(e.openBlock(),e.createBlock(r,{key:t.id,pageIndex:l.pageIndex,tile:t,scale:l.scale},null,8,["pageIndex","tile","scale"])))),128))],16))}});exports.TileImg=r,exports.TilingLayer=a,exports.useTilingCapability=n,exports.useTilingPlugin=()=>t.usePlugin(i.TilingPlugin.id),Object.keys(i).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>i[e]})}));
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-tiling.ts","../../src/vue/components/tile-img.vue","../../src/vue/components/tiling-layer.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\n/** Get the plugin instance itself (e.g. to read config) */\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\n/** Get the *capability* the plugin exposes (renderTile, onTileRendering) */\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onBeforeUnmount, toRaw, computed } from 'vue';\nimport { ignore, PdfErrorCode, PdfErrorReason, Task } from '@embedpdf/models';\nimport type { StyleValue } from 'vue';\n\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { useTilingCapability } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n tile: Tile;\n scale: number;\n dpr?: number;\n style?: StyleValue;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n dpr: () => window.devicePixelRatio,\n});\n\nconst { provides: tilingCapability } = useTilingCapability();\n\nconst url = ref<string>();\nlet blobUrl: string | null = null;\nlet renderTask: Task<Blob, PdfErrorReason> | null = null;\n\n/* -------------------------------------------------- */\n/* Helper functions */\n/* -------------------------------------------------- */\nfunction revoke() {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n}\n\nfunction abortCurrentTask() {\n if (renderTask && !blobUrl) {\n renderTask.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled tile render',\n });\n }\n}\n\n/* -------------------------------------------------- */\n/* start one render task when component mounts */\n/* -------------------------------------------------- */\nonMounted(() => {\n if (!tilingCapability.value) return;\n\n const task = tilingCapability.value.renderTile({\n pageIndex: props.pageIndex,\n tile: toRaw(props.tile),\n dpr: props.dpr,\n });\n\n renderTask = task;\n task.wait((blob) => {\n blobUrl = URL.createObjectURL(blob);\n url.value = blobUrl;\n renderTask = null; // Task completed\n }, ignore);\n});\n\n/* -------------------------------------------------- */\n/* cleanup */\n/* -------------------------------------------------- */\nonBeforeUnmount(() => {\n abortCurrentTask();\n revoke();\n});\n\n/* -------------------------------------------------- */\n/* helpers */\n/* -------------------------------------------------- */\nconst relScale = computed(() => props.scale / props.tile.srcScale);\n</script>\n\n<template>\n <img\n v-if=\"url\"\n :src=\"url\"\n :style=\"[\n {\n position: 'absolute',\n left: tile.screenRect.origin.x * relScale + 'px',\n top: tile.screenRect.origin.y * relScale + 'px',\n width: tile.screenRect.size.width * relScale + 'px',\n height: tile.screenRect.size.height * relScale + 'px',\n display: 'block',\n },\n props.style,\n ]\"\n @load=\"revoke\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { ref, onMounted, onBeforeUnmount } from 'vue';\nimport type { StyleValue } from 'vue';\n\nimport { useTilingCapability } from '../hooks';\nimport TileImg from './tile-img.vue';\n\ninterface Props {\n pageIndex: number;\n scale: number;\n style?: StyleValue;\n}\n\nconst props = defineProps<Props>();\n\nconst tiles = ref<Tile[]>([]);\nconst { provides: tilingProvides } = useTilingCapability();\n\nlet unsubscribe: (() => void) | undefined;\n\nonMounted(() => {\n if (tilingProvides.value) {\n unsubscribe = tilingProvides.value.onTileRendering((tilesMap) => {\n tiles.value = tilesMap[props.pageIndex] ?? [];\n });\n }\n});\n\nonBeforeUnmount(() => {\n unsubscribe?.();\n});\n</script>\n\n<template>\n <div :style=\"style\" v-bind=\"$attrs\">\n <TileImg\n v-for=\"tile in tiles\"\n :key=\"tile.id\"\n :pageIndex=\"pageIndex\"\n :tile=\"tile\"\n :scale=\"scale\"\n />\n </div>\n</template>\n"],"names":["useTilingCapability","useCapability","TilingPlugin","id","props","__props","provides","tilingCapability","url","ref","blobUrl","renderTask","revoke","URL","revokeObjectURL","onMounted","value","task","renderTile","pageIndex","tile","toRaw","dpr","wait","blob","createObjectURL","ignore","onBeforeUnmount","abort","code","PdfErrorCode","Cancelled","message","relScale","computed","scale","srcScale","_createElementBlock","src","style","_normalizeStyle","screenRect","origin","x","y","size","width","height","onLoad","tiles","tilingProvides","unsubscribe","onTileRendering","tilesMap","_openBlock","_mergeProps","$attrs","_Fragment","Fragment","_renderList","_createBlock","createBlock","TileImg","key","usePlugin"],"mappings":"0MAMaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,8LCUlF,MAAMC,EAAQC,GAINC,SAAUC,GAAqBP,IAEjCQ,EAAMC,EAAAA,MACZ,IAAIC,EAAyB,KACzBC,EAAgD,KAKpD,SAASC,IACHF,IACFG,IAAIC,gBAAgBJ,GACVA,EAAA,KACZ,CAeFK,EAAAA,WAAU,KACJ,IAACR,EAAiBS,MAAO,OAEvB,MAAAC,EAAOV,EAAiBS,MAAME,WAAW,CAC7CC,UAAWf,EAAMe,UACjBC,KAAMC,EAAAA,MAAMjB,EAAMgB,MAClBE,IAAKlB,EAAMkB,MAGAX,EAAAM,EACRA,EAAAM,MAAMC,IACCd,EAAAG,IAAIY,gBAAgBD,GAC9BhB,EAAIQ,MAAQN,EACCC,EAAA,IAAA,GACZe,SAAM,IAMXC,EAAAA,iBAAgB,KA/BVhB,IAAeD,GACjBC,EAAWiB,MAAM,CACfC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,yBA8BNpB,GAAA,IAMH,MAAAqB,EAAWC,EAAAA,UAAS,IAAM9B,EAAM+B,MAAQ/B,EAAMgB,KAAKgB,wBAK/C5B,EAAGQ,qBADXqB,EAAAA,mBAeE,MAAA,OAbCC,IAAK9B,EAAGQ,MACRuB,MAAKC,EAAAA,eAAA,sBAAwDpB,KAAAA,EAAAA,KAAKqB,WAAWC,OAAOC,EAAIV,EAAQjB,MAAA,KAAsBI,IAAAA,EAAAA,KAAKqB,WAAWC,OAAOE,EAAIX,EAAQjB,MAAA,KAAwBI,MAAAA,EAAAA,KAAKqB,WAAWI,KAAKC,MAAQb,EAAQjB,MAAA,KAAyBI,OAAAA,EAAAA,KAAKqB,WAAWI,KAAKE,OAASd,EAAQjB,MAAA,sBAAkDZ,EAAMmC,QAW7US,OAAMpC,gLChFX,MAAMR,EAAQC,EAER4C,EAAQxC,EAAYA,IAAA,KAClBH,SAAU4C,GAAmBlD,IAEjC,IAAAmD,SAEJpC,EAAAA,WAAU,KACJmC,EAAelC,QACjBmC,EAAcD,EAAelC,MAAMoC,iBAAiBC,IAClDJ,EAAMjC,MAAQqC,EAASjD,EAAMe,YAAc,EAAC,IAC7C,IAILQ,EAAAA,iBAAgB,KACA,MAAAwB,GAAAA,GAAA,YAKdG,cAAAjB,qBAQM,MARNkB,EAAAA,WAQM,CARAhB,MAAOA,EAAAA,OAAeiB,EAAMA,QAAA,kBAChCnB,EAAAA,mBAMEoB,EAAAC,SAAA,KAAAC,EAAAA,WALeV,EAAKjC,OAAbI,kBADTwC,EAAAC,YAMEC,EAAA,CAJCC,IAAK3C,EAAKjB,GACVgB,UAAWA,EAASA,UACpBC,OACAe,MAAOA,EAAKA,4JFrCY,IAAM6B,YAAwB9D,EAAAA,aAAaC"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-tiling.ts","../../src/vue/components/tile-img.vue","../../src/vue/components/tiling-layer.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\n/** Get the plugin instance itself (e.g. to read config) */\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\n/** Get the *capability* the plugin exposes (renderTile, onTileRendering) */\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onBeforeUnmount, toRaw } from 'vue';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\n\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { useTilingCapability } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n tile: Tile;\n scale: number;\n dpr?: number;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n dpr: () => (typeof window !== 'undefined' ? window.devicePixelRatio : 1),\n});\n\nconst { provides: tilingCapability } = useTilingCapability();\nconst url = ref<string>();\nconst relScale = computed(() => props.scale / props.tile.srcScale);\n\n// Track last rendered tile ID to prevent duplicates\nlet lastRenderedId: string | undefined;\nlet currentTask: any = null;\n\nwatch(\n [() => props.tile.id, tilingCapability],\n ([tileId, capability]) => {\n if (!capability) return;\n\n // Already rendered this exact tile\n if (lastRenderedId === tileId) return;\n\n // Cancel previous task if any\n if (currentTask) {\n currentTask.abort({ code: PdfErrorCode.Cancelled, message: 'switching tiles' });\n currentTask = null;\n }\n\n // Clean up old URL\n if (url.value) {\n URL.revokeObjectURL(url.value);\n url.value = undefined;\n }\n\n lastRenderedId = tileId;\n\n currentTask = capability.renderTile({\n pageIndex: props.pageIndex,\n tile: toRaw(props.tile),\n dpr: props.dpr,\n });\n\n currentTask.wait((blob: Blob) => {\n url.value = URL.createObjectURL(blob);\n currentTask = null;\n }, ignore);\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n if (currentTask) {\n currentTask.abort({ code: PdfErrorCode.Cancelled, message: 'unmounting' });\n }\n if (url.value) {\n URL.revokeObjectURL(url.value);\n }\n});\n</script>\n\n<template>\n <img\n v-if=\"url\"\n :src=\"url\"\n :style=\"{\n position: 'absolute',\n left: `${tile.screenRect.origin.x * relScale}px`,\n top: `${tile.screenRect.origin.y * relScale}px`,\n width: `${tile.screenRect.size.width * relScale}px`,\n height: `${tile.screenRect.size.height * relScale}px`,\n display: 'block',\n }\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { ref, onMounted, onBeforeUnmount } from 'vue';\n\nimport { useTilingCapability } from '../hooks';\nimport TileImg from './tile-img.vue';\n\ninterface Props {\n pageIndex: number;\n scale: number;\n}\n\nconst props = defineProps<Props>();\n\nconst tiles = ref<Tile[]>([]);\nconst { provides: tilingProvides } = useTilingCapability();\n\nlet unsubscribe: (() => void) | undefined;\n\nonMounted(() => {\n if (tilingProvides.value) {\n unsubscribe = tilingProvides.value.onTileRendering((tilesMap) => {\n tiles.value = tilesMap[props.pageIndex] ?? [];\n });\n }\n});\n\nonBeforeUnmount(() => {\n unsubscribe?.();\n});\n</script>\n\n<template>\n <div v-bind=\"$attrs\">\n <TileImg\n v-for=\"tile in tiles\"\n :key=\"tile.id\"\n :pageIndex=\"pageIndex\"\n :tile=\"tile\"\n :scale=\"scale\"\n />\n </div>\n</template>\n"],"names":["useTilingCapability","useCapability","TilingPlugin","id","props","__props","provides","tilingCapability","url","ref","relScale","computed","scale","tile","srcScale","lastRenderedId","currentTask","vue$1","watch","tileId","capability","abort","code","PdfErrorCode","Cancelled","message","value","URL","revokeObjectURL","renderTile","pageIndex","toRaw","dpr","wait","blob","createObjectURL","ignore","immediate","onBeforeUnmount","_createElementBlock","src","style","_normalizeStyle","screenRect","origin","x","y","size","width","height","tiles","tilingProvides","unsubscribe","onMounted","onTileRendering","tilesMap","_openBlock","openBlock","$attrs","_Fragment","Fragment","_renderList","_createBlock","createBlock","TileImg","key","usePlugin"],"mappings":"0MAMaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,2KCQlF,MAAMC,EAAQC,GAINC,SAAUC,GAAqBP,IACjCQ,EAAMC,EAAAA,MACNC,EAAWC,EAAAA,UAAS,IAAMP,EAAMQ,MAAQR,EAAMS,KAAKC,WAGrD,IAAAC,EACAC,EAAmB,YAEvBC,EAAAC,MACE,CAAC,IAAMd,EAAMS,KAAKV,GAAII,IACtB,EAAEY,EAAQC,MACHA,GAGDL,IAAmBI,IAGnBH,IACUA,EAAAK,MAAM,CAAEC,KAAMC,eAAaC,UAAWC,QAAS,oBAC7CT,EAAA,MAIZR,EAAIkB,QACFC,IAAAC,gBAAgBpB,EAAIkB,OACxBlB,EAAIkB,WAAQ,GAGGX,EAAAI,EAEjBH,EAAcI,EAAWS,WAAW,CAClCC,UAAW1B,EAAM0B,UACjBjB,KAAMkB,EAAAA,MAAM3B,EAAMS,MAClBmB,IAAK5B,EAAM4B,MAGDhB,EAAAiB,MAAMC,IACZ1B,EAAAkB,MAAQC,IAAIQ,gBAAgBD,GAClBlB,EAAA,IAAA,GACboB,UAAM,GAEX,CAAEC,WAAW,IAGfC,EAAAA,iBAAgB,KACVtB,GACUA,EAAAK,MAAM,CAAEC,KAAMC,eAAaC,UAAWC,QAAS,eAEzDjB,EAAIkB,OACFC,IAAAC,gBAAgBpB,EAAIkB,MAAK,WAOvBlB,EAAGkB,qBADXa,EAAAA,mBAWE,MAAA,OATCC,IAAKhC,EAAGkB,MACRe,MAAKC,EAAAA,eAAA,qBAA+C7B,KAAAA,EAAAA,KAAK8B,WAAWC,OAAOC,EAAInC,EAAQgB,MAAnCb,KAAuDA,IAAAA,EAAAA,KAAK8B,WAAWC,OAAOE,EAAIpC,EAAQgB,MAAnCb,KAAyDA,MAAAA,EAAAA,KAAK8B,WAAWI,KAAKC,MAAQtC,EAAQgB,MAArCb,KAA4DA,OAAAA,EAAAA,KAAK8B,WAAWI,KAAKE,OAASvC,EAAQgB,MAAtCb,qJChErO,MAAMT,EAAQC,EAER6C,EAAQzC,EAAYA,IAAA,KAClBH,SAAU6C,GAAmBnD,IAEjC,IAAAoD,SAEJC,EAAAA,WAAU,KACJF,EAAezB,QACjB0B,EAAcD,EAAezB,MAAM4B,iBAAiBC,IAClDL,EAAMxB,MAAQ6B,EAASnD,EAAM0B,YAAc,EAAC,IAC7C,IAILQ,EAAAA,iBAAgB,KACA,MAAAc,GAAAA,GAAA,YAKdI,EAAAC,YAAAlB,EAAAA,mBAQM,4CAROmB,EAAMA,SAAA,kBACjBnB,EAAAA,mBAMEoB,EAAAC,SAAA,KAAAC,EAAAA,WALeX,EAAKxB,OAAbb,kBADTiD,EAAAC,YAMEC,EAAA,CAJCC,IAAKpD,EAAKV,GACV2B,UAAWA,EAASA,UACpBjB,OACAD,MAAOA,EAAKA,4JFnCY,IAAMsD,YAAwBhE,EAAAA,aAAaC"}
package/dist/vue/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, onMounted, toRaw, onBeforeUnmount, computed, createElementBlock, createCommentVNode, openBlock, normalizeStyle, mergeProps, Fragment, renderList, createBlock } from "vue";
1
+ import { defineComponent, ref, computed, watch, toRaw, onBeforeUnmount, createElementBlock, createCommentVNode, openBlock, normalizeStyle, onMounted, normalizeProps, guardReactiveProps, Fragment, renderList, createBlock } from "vue";
2
2
  import { ignore, PdfErrorCode } from "@embedpdf/models";
3
3
  import { useCapability, usePlugin } from "@embedpdf/core/vue";
4
4
  import { TilingPlugin } from "@embedpdf/plugin-tiling";
@@ -12,65 +12,62 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
12
12
  pageIndex: {},
13
13
  tile: {},
14
14
  scale: {},
15
- dpr: { default: () => window.devicePixelRatio },
16
- style: { type: [Boolean, null, String, Object, Array] }
15
+ dpr: { default: () => typeof window !== "undefined" ? window.devicePixelRatio : 1 }
17
16
  },
18
17
  setup(__props) {
19
18
  const props = __props;
20
19
  const { provides: tilingCapability } = useTilingCapability();
21
20
  const url = ref();
22
- let blobUrl = null;
23
- let renderTask = null;
24
- function revoke() {
25
- if (blobUrl) {
26
- URL.revokeObjectURL(blobUrl);
27
- blobUrl = null;
28
- }
29
- }
30
- function abortCurrentTask() {
31
- if (renderTask && !blobUrl) {
32
- renderTask.abort({
33
- code: PdfErrorCode.Cancelled,
34
- message: "canceled tile render"
21
+ const relScale = computed(() => props.scale / props.tile.srcScale);
22
+ let lastRenderedId;
23
+ let currentTask = null;
24
+ watch(
25
+ [() => props.tile.id, tilingCapability],
26
+ ([tileId, capability]) => {
27
+ if (!capability) return;
28
+ if (lastRenderedId === tileId) return;
29
+ if (currentTask) {
30
+ currentTask.abort({ code: PdfErrorCode.Cancelled, message: "switching tiles" });
31
+ currentTask = null;
32
+ }
33
+ if (url.value) {
34
+ URL.revokeObjectURL(url.value);
35
+ url.value = void 0;
36
+ }
37
+ lastRenderedId = tileId;
38
+ currentTask = capability.renderTile({
39
+ pageIndex: props.pageIndex,
40
+ tile: toRaw(props.tile),
41
+ dpr: props.dpr
35
42
  });
36
- }
37
- }
38
- onMounted(() => {
39
- if (!tilingCapability.value) return;
40
- const task = tilingCapability.value.renderTile({
41
- pageIndex: props.pageIndex,
42
- tile: toRaw(props.tile),
43
- dpr: props.dpr
44
- });
45
- renderTask = task;
46
- task.wait((blob) => {
47
- blobUrl = URL.createObjectURL(blob);
48
- url.value = blobUrl;
49
- renderTask = null;
50
- }, ignore);
51
- });
43
+ currentTask.wait((blob) => {
44
+ url.value = URL.createObjectURL(blob);
45
+ currentTask = null;
46
+ }, ignore);
47
+ },
48
+ { immediate: true }
49
+ );
52
50
  onBeforeUnmount(() => {
53
- abortCurrentTask();
54
- revoke();
51
+ if (currentTask) {
52
+ currentTask.abort({ code: PdfErrorCode.Cancelled, message: "unmounting" });
53
+ }
54
+ if (url.value) {
55
+ URL.revokeObjectURL(url.value);
56
+ }
55
57
  });
56
- const relScale = computed(() => props.scale / props.tile.srcScale);
57
58
  return (_ctx, _cache) => {
58
59
  return url.value ? (openBlock(), createElementBlock("img", {
59
60
  key: 0,
60
61
  src: url.value,
61
- style: normalizeStyle([
62
- {
63
- position: "absolute",
64
- left: _ctx.tile.screenRect.origin.x * relScale.value + "px",
65
- top: _ctx.tile.screenRect.origin.y * relScale.value + "px",
66
- width: _ctx.tile.screenRect.size.width * relScale.value + "px",
67
- height: _ctx.tile.screenRect.size.height * relScale.value + "px",
68
- display: "block"
69
- },
70
- props.style
71
- ]),
72
- onLoad: revoke
73
- }, null, 44, _hoisted_1)) : createCommentVNode("", true);
62
+ style: normalizeStyle({
63
+ position: "absolute",
64
+ left: `${_ctx.tile.screenRect.origin.x * relScale.value}px`,
65
+ top: `${_ctx.tile.screenRect.origin.y * relScale.value}px`,
66
+ width: `${_ctx.tile.screenRect.size.width * relScale.value}px`,
67
+ height: `${_ctx.tile.screenRect.size.height * relScale.value}px`,
68
+ display: "block"
69
+ })
70
+ }, null, 12, _hoisted_1)) : createCommentVNode("", true);
74
71
  };
75
72
  }
76
73
  });
@@ -78,8 +75,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
78
75
  __name: "tiling-layer",
79
76
  props: {
80
77
  pageIndex: {},
81
- scale: {},
82
- style: { type: [Boolean, null, String, Object, Array] }
78
+ scale: {}
83
79
  },
84
80
  setup(__props) {
85
81
  const props = __props;
@@ -97,7 +93,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
97
93
  unsubscribe == null ? void 0 : unsubscribe();
98
94
  });
99
95
  return (_ctx, _cache) => {
100
- return openBlock(), createElementBlock("div", mergeProps({ style: _ctx.style }, _ctx.$attrs), [
96
+ return openBlock(), createElementBlock("div", normalizeProps(guardReactiveProps(_ctx.$attrs)), [
101
97
  (openBlock(true), createElementBlock(Fragment, null, renderList(tiles.value, (tile) => {
102
98
  return openBlock(), createBlock(_sfc_main$1, {
103
99
  key: tile.id,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/vue/hooks/use-tiling.ts","../../src/vue/components/tile-img.vue","../../src/vue/components/tiling-layer.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\n/** Get the plugin instance itself (e.g. to read config) */\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\n/** Get the *capability* the plugin exposes (renderTile, onTileRendering) */\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onBeforeUnmount, toRaw, computed } from 'vue';\nimport { ignore, PdfErrorCode, PdfErrorReason, Task } from '@embedpdf/models';\nimport type { StyleValue } from 'vue';\n\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { useTilingCapability } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n tile: Tile;\n scale: number;\n dpr?: number;\n style?: StyleValue;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n dpr: () => window.devicePixelRatio,\n});\n\nconst { provides: tilingCapability } = useTilingCapability();\n\nconst url = ref<string>();\nlet blobUrl: string | null = null;\nlet renderTask: Task<Blob, PdfErrorReason> | null = null;\n\n/* -------------------------------------------------- */\n/* Helper functions */\n/* -------------------------------------------------- */\nfunction revoke() {\n if (blobUrl) {\n URL.revokeObjectURL(blobUrl);\n blobUrl = null;\n }\n}\n\nfunction abortCurrentTask() {\n if (renderTask && !blobUrl) {\n renderTask.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled tile render',\n });\n }\n}\n\n/* -------------------------------------------------- */\n/* start one render task when component mounts */\n/* -------------------------------------------------- */\nonMounted(() => {\n if (!tilingCapability.value) return;\n\n const task = tilingCapability.value.renderTile({\n pageIndex: props.pageIndex,\n tile: toRaw(props.tile),\n dpr: props.dpr,\n });\n\n renderTask = task;\n task.wait((blob) => {\n blobUrl = URL.createObjectURL(blob);\n url.value = blobUrl;\n renderTask = null; // Task completed\n }, ignore);\n});\n\n/* -------------------------------------------------- */\n/* cleanup */\n/* -------------------------------------------------- */\nonBeforeUnmount(() => {\n abortCurrentTask();\n revoke();\n});\n\n/* -------------------------------------------------- */\n/* helpers */\n/* -------------------------------------------------- */\nconst relScale = computed(() => props.scale / props.tile.srcScale);\n</script>\n\n<template>\n <img\n v-if=\"url\"\n :src=\"url\"\n :style=\"[\n {\n position: 'absolute',\n left: tile.screenRect.origin.x * relScale + 'px',\n top: tile.screenRect.origin.y * relScale + 'px',\n width: tile.screenRect.size.width * relScale + 'px',\n height: tile.screenRect.size.height * relScale + 'px',\n display: 'block',\n },\n props.style,\n ]\"\n @load=\"revoke\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { ref, onMounted, onBeforeUnmount } from 'vue';\nimport type { StyleValue } from 'vue';\n\nimport { useTilingCapability } from '../hooks';\nimport TileImg from './tile-img.vue';\n\ninterface Props {\n pageIndex: number;\n scale: number;\n style?: StyleValue;\n}\n\nconst props = defineProps<Props>();\n\nconst tiles = ref<Tile[]>([]);\nconst { provides: tilingProvides } = useTilingCapability();\n\nlet unsubscribe: (() => void) | undefined;\n\nonMounted(() => {\n if (tilingProvides.value) {\n unsubscribe = tilingProvides.value.onTileRendering((tilesMap) => {\n tiles.value = tilesMap[props.pageIndex] ?? [];\n });\n }\n});\n\nonBeforeUnmount(() => {\n unsubscribe?.();\n});\n</script>\n\n<template>\n <div :style=\"style\" v-bind=\"$attrs\">\n <TileImg\n v-for=\"tile in tiles\"\n :key=\"tile.id\"\n :pageIndex=\"pageIndex\"\n :tile=\"tile\"\n :scale=\"scale\"\n />\n </div>\n</template>\n"],"names":["_createElementBlock","_normalizeStyle","tile","_openBlock","_mergeProps","style","$attrs","_Fragment","_renderList","_createBlock","TileImg","pageIndex","scale"],"mappings":";;;;;AAIO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AAErE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;;;;;;;;;;;;ACUpF,UAAM,QAAQ;AAId,UAAM,EAAE,UAAU,iBAAiB,IAAI,oBAAoB;AAE3D,UAAM,MAAM,IAAY;AACxB,QAAI,UAAyB;AAC7B,QAAI,aAAgD;AAKpD,aAAS,SAAS;AAChB,UAAI,SAAS;AACX,YAAI,gBAAgB,OAAO;AACjB,kBAAA;AAAA,MAAA;AAAA,IACZ;AAGF,aAAS,mBAAmB;AACtB,UAAA,cAAc,CAAC,SAAS;AAC1B,mBAAW,MAAM;AAAA,UACf,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MAAA;AAAA,IACH;AAMF,cAAU,MAAM;AACV,UAAA,CAAC,iBAAiB,MAAO;AAEvB,YAAA,OAAO,iBAAiB,MAAM,WAAW;AAAA,QAC7C,WAAW,MAAM;AAAA,QACjB,MAAM,MAAM,MAAM,IAAI;AAAA,QACtB,KAAK,MAAM;AAAA,MAAA,CACZ;AAEY,mBAAA;AACR,WAAA,KAAK,CAAC,SAAS;AACR,kBAAA,IAAI,gBAAgB,IAAI;AAClC,YAAI,QAAQ;AACC,qBAAA;AAAA,SACZ,MAAM;AAAA,IAAA,CACV;AAKD,oBAAgB,MAAM;AACH,uBAAA;AACV,aAAA;AAAA,IAAA,CACR;AAKD,UAAM,WAAW,SAAS,MAAM,MAAM,QAAQ,MAAM,KAAK,QAAQ;;aAKvD,IAAG,sBADXA,mBAeE,OAAA;AAAA;QAbC,KAAK,IAAG;AAAA,QACR,OAAKC,eAAA;AAAA;;YAAwDC,MAAAA,KAAAA,KAAK,WAAW,OAAO,IAAI,SAAQ,QAAA;AAAA,YAAsBA,KAAAA,KAAAA,KAAK,WAAW,OAAO,IAAI,SAAQ,QAAA;AAAA,YAAwBA,OAAAA,KAAAA,KAAK,WAAW,KAAK,QAAQ,SAAQ,QAAA;AAAA,YAAyBA,QAAAA,KAAAA,KAAK,WAAW,KAAK,SAAS,SAAQ,QAAA;AAAA;;UAAkD,MAAM;AAAA,QAAA;QAW7U,QAAM;AAAA,MAAA;;;;;;;;;;;;AChFX,UAAM,QAAQ;AAER,UAAA,QAAQ,IAAY,EAAE;AAC5B,UAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AAErD,QAAA;AAEJ,cAAU,MAAM;AACd,UAAI,eAAe,OAAO;AACxB,sBAAc,eAAe,MAAM,gBAAgB,CAAC,aAAa;AAC/D,gBAAM,QAAQ,SAAS,MAAM,SAAS,KAAK,CAAC;AAAA,QAAA,CAC7C;AAAA,MAAA;AAAA,IACH,CACD;AAED,oBAAgB,MAAM;AACN;AAAA,IAAA,CACf;;AAIC,aAAAC,UAAA,GAAAH,mBAQM,OARNI,WAQM,EARA,OAAOC,KAAAA,SAAeC,KAAM,MAAA,GAAA;AAAA,0BAChCN,mBAMEO,UAAA,MAAAC,WALe,MAAK,OAAA,CAAb,SAAI;8BADbC,YAMEC,aAAA;AAAA,YAJC,KAAK,KAAK;AAAA,YACV,WAAWC,KAAS;AAAA,YACpB;AAAA,YACA,OAAOC,KAAK;AAAA,UAAA;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/vue/hooks/use-tiling.ts","../../src/vue/components/tile-img.vue","../../src/vue/components/tiling-layer.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { TilingPlugin } from '@embedpdf/plugin-tiling';\n\n/** Get the plugin instance itself (e.g. to read config) */\nexport const useTilingPlugin = () => usePlugin<TilingPlugin>(TilingPlugin.id);\n/** Get the *capability* the plugin exposes (renderTile, onTileRendering) */\nexport const useTilingCapability = () => useCapability<TilingPlugin>(TilingPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, computed, watch, onBeforeUnmount, toRaw } from 'vue';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\n\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { useTilingCapability } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n tile: Tile;\n scale: number;\n dpr?: number;\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n dpr: () => (typeof window !== 'undefined' ? window.devicePixelRatio : 1),\n});\n\nconst { provides: tilingCapability } = useTilingCapability();\nconst url = ref<string>();\nconst relScale = computed(() => props.scale / props.tile.srcScale);\n\n// Track last rendered tile ID to prevent duplicates\nlet lastRenderedId: string | undefined;\nlet currentTask: any = null;\n\nwatch(\n [() => props.tile.id, tilingCapability],\n ([tileId, capability]) => {\n if (!capability) return;\n\n // Already rendered this exact tile\n if (lastRenderedId === tileId) return;\n\n // Cancel previous task if any\n if (currentTask) {\n currentTask.abort({ code: PdfErrorCode.Cancelled, message: 'switching tiles' });\n currentTask = null;\n }\n\n // Clean up old URL\n if (url.value) {\n URL.revokeObjectURL(url.value);\n url.value = undefined;\n }\n\n lastRenderedId = tileId;\n\n currentTask = capability.renderTile({\n pageIndex: props.pageIndex,\n tile: toRaw(props.tile),\n dpr: props.dpr,\n });\n\n currentTask.wait((blob: Blob) => {\n url.value = URL.createObjectURL(blob);\n currentTask = null;\n }, ignore);\n },\n { immediate: true },\n);\n\nonBeforeUnmount(() => {\n if (currentTask) {\n currentTask.abort({ code: PdfErrorCode.Cancelled, message: 'unmounting' });\n }\n if (url.value) {\n URL.revokeObjectURL(url.value);\n }\n});\n</script>\n\n<template>\n <img\n v-if=\"url\"\n :src=\"url\"\n :style=\"{\n position: 'absolute',\n left: `${tile.screenRect.origin.x * relScale}px`,\n top: `${tile.screenRect.origin.y * relScale}px`,\n width: `${tile.screenRect.size.width * relScale}px`,\n height: `${tile.screenRect.size.height * relScale}px`,\n display: 'block',\n }\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { Tile } from '@embedpdf/plugin-tiling';\nimport { ref, onMounted, onBeforeUnmount } from 'vue';\n\nimport { useTilingCapability } from '../hooks';\nimport TileImg from './tile-img.vue';\n\ninterface Props {\n pageIndex: number;\n scale: number;\n}\n\nconst props = defineProps<Props>();\n\nconst tiles = ref<Tile[]>([]);\nconst { provides: tilingProvides } = useTilingCapability();\n\nlet unsubscribe: (() => void) | undefined;\n\nonMounted(() => {\n if (tilingProvides.value) {\n unsubscribe = tilingProvides.value.onTileRendering((tilesMap) => {\n tiles.value = tilesMap[props.pageIndex] ?? [];\n });\n }\n});\n\nonBeforeUnmount(() => {\n unsubscribe?.();\n});\n</script>\n\n<template>\n <div v-bind=\"$attrs\">\n <TileImg\n v-for=\"tile in tiles\"\n :key=\"tile.id\"\n :pageIndex=\"pageIndex\"\n :tile=\"tile\"\n :scale=\"scale\"\n />\n </div>\n</template>\n"],"names":["_createElementBlock","_normalizeStyle","tile","_openBlock","$attrs","_Fragment","_renderList","_createBlock","TileImg","pageIndex","scale"],"mappings":";;;;;AAIO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AAErE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;;;;;;;;;;;ACQpF,UAAM,QAAQ;AAId,UAAM,EAAE,UAAU,iBAAiB,IAAI,oBAAoB;AAC3D,UAAM,MAAM,IAAY;AACxB,UAAM,WAAW,SAAS,MAAM,MAAM,QAAQ,MAAM,KAAK,QAAQ;AAG7D,QAAA;AACJ,QAAI,cAAmB;AAEvB;AAAA,MACE,CAAC,MAAM,MAAM,KAAK,IAAI,gBAAgB;AAAA,MACtC,CAAC,CAAC,QAAQ,UAAU,MAAM;AACxB,YAAI,CAAC,WAAY;AAGjB,YAAI,mBAAmB,OAAQ;AAG/B,YAAI,aAAa;AACf,sBAAY,MAAM,EAAE,MAAM,aAAa,WAAW,SAAS,mBAAmB;AAChE,wBAAA;AAAA,QAAA;AAIhB,YAAI,IAAI,OAAO;AACT,cAAA,gBAAgB,IAAI,KAAK;AAC7B,cAAI,QAAQ;AAAA,QAAA;AAGG,yBAAA;AAEjB,sBAAc,WAAW,WAAW;AAAA,UAClC,WAAW,MAAM;AAAA,UACjB,MAAM,MAAM,MAAM,IAAI;AAAA,UACtB,KAAK,MAAM;AAAA,QAAA,CACZ;AAEW,oBAAA,KAAK,CAAC,SAAe;AAC3B,cAAA,QAAQ,IAAI,gBAAgB,IAAI;AACtB,wBAAA;AAAA,WACb,MAAM;AAAA,MACX;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACpB;AAEA,oBAAgB,MAAM;AACpB,UAAI,aAAa;AACf,oBAAY,MAAM,EAAE,MAAM,aAAa,WAAW,SAAS,cAAc;AAAA,MAAA;AAE3E,UAAI,IAAI,OAAO;AACT,YAAA,gBAAgB,IAAI,KAAK;AAAA,MAAA;AAAA,IAC/B,CACD;;aAKS,IAAG,sBADXA,mBAWE,OAAA;AAAA;QATC,KAAK,IAAG;AAAA,QACR,OAAKC,eAAA;AAAA;UAA+CC,MAAAA,GAAAA,KAAAA,KAAK,WAAW,OAAO,IAAI,SAAQ,KAAA;AAAA,UAAoBA,KAAAA,GAAAA,KAAAA,KAAK,WAAW,OAAO,IAAI,SAAQ,KAAA;AAAA,UAAsBA,OAAAA,GAAAA,KAAAA,KAAK,WAAW,KAAK,QAAQ,SAAQ,KAAA;AAAA,UAAuBA,QAAAA,GAAAA,KAAAA,KAAK,WAAW,KAAK,SAAS,SAAQ,KAAA;AAAA;;;;;;;;;;;;;AChE3Q,UAAM,QAAQ;AAER,UAAA,QAAQ,IAAY,EAAE;AAC5B,UAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AAErD,QAAA;AAEJ,cAAU,MAAM;AACd,UAAI,eAAe,OAAO;AACxB,sBAAc,eAAe,MAAM,gBAAgB,CAAC,aAAa;AAC/D,gBAAM,QAAQ,SAAS,MAAM,SAAS,KAAK,CAAC;AAAA,QAAA,CAC7C;AAAA,MAAA;AAAA,IACH,CACD;AAED,oBAAgB,MAAM;AACN;AAAA,IAAA,CACf;;AAIC,aAAAC,UAAA,GAAAH,mBAQM,yCAROI,KAAM,MAAA,CAAA,GAAA;AAAA,0BACjBJ,mBAMEK,UAAA,MAAAC,WALe,MAAK,OAAA,CAAb,SAAI;8BADbC,YAMEC,aAAA;AAAA,YAJC,KAAK,KAAK;AAAA,YACV,WAAWC,KAAS;AAAA,YACpB;AAAA,YACA,OAAOC,KAAK;AAAA,UAAA;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-tiling",
3
- "version": "1.3.11",
3
+ "version": "1.3.13",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.cjs",
@@ -29,26 +29,26 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@embedpdf/models": "1.3.11"
32
+ "@embedpdf/models": "1.3.13"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/react": "^18.2.0",
36
36
  "typescript": "^5.0.0",
37
- "@embedpdf/core": "1.3.11",
37
+ "@embedpdf/core": "1.3.13",
38
38
  "@embedpdf/build": "1.0.1",
39
- "@embedpdf/plugin-render": "1.3.11",
40
- "@embedpdf/plugin-viewport": "1.3.11",
41
- "@embedpdf/plugin-scroll": "1.3.11"
39
+ "@embedpdf/plugin-render": "1.3.13",
40
+ "@embedpdf/plugin-scroll": "1.3.13",
41
+ "@embedpdf/plugin-viewport": "1.3.13"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "react": ">=16.8.0",
45
45
  "react-dom": ">=16.8.0",
46
46
  "preact": "^10.26.4",
47
47
  "vue": ">=3.2.0",
48
- "@embedpdf/core": "1.3.11",
49
- "@embedpdf/plugin-scroll": "1.3.11",
50
- "@embedpdf/plugin-render": "1.3.11",
51
- "@embedpdf/plugin-viewport": "1.3.11"
48
+ "@embedpdf/core": "1.3.13",
49
+ "@embedpdf/plugin-render": "1.3.13",
50
+ "@embedpdf/plugin-scroll": "1.3.13",
51
+ "@embedpdf/plugin-viewport": "1.3.13"
52
52
  },
53
53
  "files": [
54
54
  "dist",