@embedpdf/plugin-render 1.4.1 → 2.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,57 +1,61 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useState, useRef, useEffect, Fragment } from "react";
2
+ import { useState, useRef, useMemo, useEffect, Fragment } from "react";
3
3
  import { ignore, PdfErrorCode } from "@embedpdf/models";
4
- import { usePlugin, useCapability } from "@embedpdf/core/react";
4
+ import { usePlugin, useCapability, useDocumentState } from "@embedpdf/core/react";
5
5
  import { RenderPlugin } from "@embedpdf/plugin-render";
6
6
  export * from "@embedpdf/plugin-render";
7
7
  const useRenderPlugin = () => usePlugin(RenderPlugin.id);
8
8
  const useRenderCapability = () => useCapability(RenderPlugin.id);
9
9
  function RenderLayer({
10
+ documentId,
10
11
  pageIndex,
11
- scale,
12
- scaleFactor,
13
- dpr,
12
+ scale: scaleOverride,
13
+ dpr: dprOverride,
14
14
  style,
15
15
  ...props
16
16
  }) {
17
17
  const { provides: renderProvides } = useRenderCapability();
18
- const { plugin: renderPlugin } = useRenderPlugin();
19
- const actualScale = scale ?? scaleFactor ?? 1;
18
+ const documentState = useDocumentState(documentId);
20
19
  const [imageUrl, setImageUrl] = useState(null);
21
20
  const urlRef = useRef(null);
22
- const [refreshTick, setRefreshTick] = useState(0);
21
+ const refreshVersion = useMemo(() => {
22
+ if (!documentState) return 0;
23
+ return documentState.pageRefreshVersions[pageIndex] || 0;
24
+ }, [documentState, pageIndex]);
25
+ const actualScale = useMemo(() => {
26
+ if (scaleOverride !== void 0) return scaleOverride;
27
+ return (documentState == null ? void 0 : documentState.scale) ?? 1;
28
+ }, [scaleOverride, documentState == null ? void 0 : documentState.scale]);
29
+ const actualDpr = useMemo(() => {
30
+ if (dprOverride !== void 0) return dprOverride;
31
+ return window.devicePixelRatio;
32
+ }, [dprOverride]);
23
33
  useEffect(() => {
24
- if (!renderPlugin) return;
25
- return renderPlugin.onRefreshPages((pages) => {
26
- if (pages.includes(pageIndex)) {
27
- setRefreshTick((tick) => tick + 1);
34
+ if (!renderProvides) return;
35
+ const task = renderProvides.forDocument(documentId).renderPage({
36
+ pageIndex,
37
+ options: {
38
+ scaleFactor: actualScale,
39
+ dpr: actualDpr
28
40
  }
29
41
  });
30
- }, [renderPlugin]);
31
- useEffect(() => {
32
- if (renderProvides) {
33
- const task = renderProvides.renderPage({
34
- pageIndex,
35
- options: { scaleFactor: actualScale, dpr: dpr || window.devicePixelRatio }
36
- });
37
- task.wait((blob) => {
38
- const url = URL.createObjectURL(blob);
39
- setImageUrl(url);
40
- urlRef.current = url;
41
- }, ignore);
42
- return () => {
43
- if (urlRef.current) {
44
- URL.revokeObjectURL(urlRef.current);
45
- urlRef.current = null;
46
- } else {
47
- task.abort({
48
- code: PdfErrorCode.Cancelled,
49
- message: "canceled render task"
50
- });
51
- }
52
- };
53
- }
54
- }, [pageIndex, actualScale, dpr, renderProvides, refreshTick]);
42
+ task.wait((blob) => {
43
+ const url = URL.createObjectURL(blob);
44
+ setImageUrl(url);
45
+ urlRef.current = url;
46
+ }, ignore);
47
+ return () => {
48
+ if (urlRef.current) {
49
+ URL.revokeObjectURL(urlRef.current);
50
+ urlRef.current = null;
51
+ } else {
52
+ task.abort({
53
+ code: PdfErrorCode.Cancelled,
54
+ message: "canceled render task"
55
+ });
56
+ }
57
+ };
58
+ }, [documentId, pageIndex, actualScale, actualDpr, renderProvides, refreshVersion]);
55
59
  const handleImageLoad = () => {
56
60
  if (urlRef.current) {
57
61
  URL.revokeObjectURL(urlRef.current);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-render.ts","../../src/shared/components/render-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","import { Fragment, useEffect, useRef, useState } from '@framework';\nimport type { CSSProperties, HTMLAttributes } from '@framework';\n\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\n\nimport { useRenderCapability, useRenderPlugin } from '../hooks/use-render';\n\ntype RenderLayerProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n pageIndex: number;\n /**\n * The scale factor for rendering the page.\n */\n scale?: number;\n /**\n * @deprecated Use `scale` instead. Will be removed in the next major release.\n */\n scaleFactor?: number;\n dpr?: number;\n style?: CSSProperties;\n};\n\nexport function RenderLayer({\n pageIndex,\n scale,\n scaleFactor,\n dpr,\n style,\n ...props\n}: RenderLayerProps) {\n const { provides: renderProvides } = useRenderCapability();\n const { plugin: renderPlugin } = useRenderPlugin();\n\n // Handle deprecation: prefer scale over scaleFactor, but fall back to scaleFactor if scale is not provided\n const actualScale = scale ?? scaleFactor ?? 1;\n\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const urlRef = useRef<string | null>(null);\n const [refreshTick, setRefreshTick] = useState(0);\n\n useEffect(() => {\n if (!renderPlugin) return;\n return renderPlugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n setRefreshTick((tick) => tick + 1);\n }\n });\n }, [renderPlugin]);\n\n useEffect(() => {\n if (renderProvides) {\n const task = renderProvides.renderPage({\n pageIndex,\n options: { scaleFactor: actualScale, dpr: dpr || window.devicePixelRatio },\n });\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n setImageUrl(url);\n urlRef.current = url;\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 }\n }, [pageIndex, actualScale, dpr, renderProvides, refreshTick]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return (\n <Fragment>\n {imageUrl && (\n <img\n src={imageUrl}\n onLoad={handleImageLoad}\n {...props}\n style={{\n width: '100%',\n height: '100%',\n ...(style || {}),\n }}\n />\n )}\n </Fragment>\n );\n}\n"],"names":[],"mappings":";;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;ACiB7E,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAqB;AACnB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,EAAE,QAAQ,aAAa,IAAI,gBAAgB;AAG3C,QAAA,cAAc,SAAS,eAAe;AAE5C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAwB,IAAI;AACtD,QAAA,SAAS,OAAsB,IAAI;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC;AAEhD,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;AAEjB,YAAU,MAAM;AACd,QAAI,gBAAgB;AACZ,YAAA,OAAO,eAAe,WAAW;AAAA,QACrC;AAAA,QACA,SAAS,EAAE,aAAa,aAAa,KAAK,OAAO,OAAO,iBAAiB;AAAA,MAAA,CAC1E;AACI,WAAA,KAAK,CAAC,SAAS;AACZ,cAAA,MAAM,IAAI,gBAAgB,IAAI;AACpC,oBAAY,GAAG;AACf,eAAO,UAAU;AAAA,SAChB,MAAM;AAET,aAAO,MAAM;AACX,YAAI,OAAO,SAAS;AACd,cAAA,gBAAgB,OAAO,OAAO;AAClC,iBAAO,UAAU;AAAA,QAAA,OACZ;AACL,eAAK,MAAM;AAAA,YACT,MAAM,aAAa;AAAA,YACnB,SAAS;AAAA,UAAA,CACV;AAAA,QAAA;AAAA,MAEL;AAAA,IAAA;AAAA,EACF,GACC,CAAC,WAAW,aAAa,KAAK,gBAAgB,WAAW,CAAC;AAE7D,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AACd,UAAA,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IAAA;AAAA,EAErB;AAGE,SAAA,oBAAC,YACE,UACC,YAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,QAAQ;AAAA,MACP,GAAG;AAAA,MACJ,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,GAAI,SAAS,CAAA;AAAA,MAAC;AAAA,IAChB;AAAA,EAAA,GAGN;AAEJ;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/shared/hooks/use-render.ts","../../src/shared/components/render-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","import { Fragment, useEffect, useRef, useState, useMemo } from '@framework';\nimport type { CSSProperties, HTMLAttributes } from '@framework';\n\nimport { ignore, PdfErrorCode, Rotation } from '@embedpdf/models';\n\nimport { useRenderCapability } from '../hooks/use-render';\nimport { useDocumentState } from '@embedpdf/core/@framework';\n\ntype RenderLayerProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {\n /**\n * The ID of the document to render from\n */\n documentId: string;\n /**\n * The page index to render (0-based)\n */\n pageIndex: number;\n /**\n * Optional scale override. If not provided, uses document's current scale.\n */\n scale?: number;\n /**\n * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.\n */\n dpr?: number;\n /**\n * Additional styles for the image element\n */\n style?: CSSProperties;\n};\n\n/**\n * RenderLayer Component\n *\n * Renders a PDF page with smart prop handling:\n * - If scale/dpr/rotation props are provided, they override document state\n * - If not provided, component uses document's current state values\n * - Automatically re-renders when:\n * 1. Document state changes (scale, rotation)\n * 2. Page is refreshed (via REFRESH_PAGES action in core)\n */\nexport function RenderLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\n dpr: dprOverride,\n style,\n ...props\n}: RenderLayerProps) {\n const { provides: renderProvides } = useRenderCapability();\n const documentState = useDocumentState(documentId);\n\n const [imageUrl, setImageUrl] = useState<string | null>(null);\n const urlRef = useRef<string | null>(null);\n\n // Get refresh version from core state\n const refreshVersion = useMemo(() => {\n if (!documentState) return 0;\n return documentState.pageRefreshVersions[pageIndex] || 0;\n }, [documentState, pageIndex]);\n\n // Determine actual render options: use overrides if provided, otherwise fall back to document state\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n const actualDpr = useMemo(() => {\n if (dprOverride !== undefined) return dprOverride;\n return window.devicePixelRatio;\n }, [dprOverride]);\n\n useEffect(() => {\n if (!renderProvides) return;\n\n const task = renderProvides.forDocument(documentId).renderPage({\n pageIndex,\n options: {\n scaleFactor: actualScale,\n dpr: actualDpr,\n },\n });\n\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n setImageUrl(url);\n urlRef.current = url;\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 }, [documentId, pageIndex, actualScale, actualDpr, renderProvides, refreshVersion]);\n\n const handleImageLoad = () => {\n if (urlRef.current) {\n URL.revokeObjectURL(urlRef.current);\n urlRef.current = null;\n }\n };\n\n return (\n <Fragment>\n {imageUrl && (\n <img\n src={imageUrl}\n onLoad={handleImageLoad}\n {...props}\n style={{\n width: '100%',\n height: '100%',\n ...(style || {}),\n }}\n />\n )}\n </Fragment>\n );\n}\n"],"names":[],"mappings":";;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;ACqC7E,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,KAAK;AAAA,EACL;AAAA,EACA,GAAG;AACL,GAAqB;AACnB,QAAM,EAAE,UAAU,eAAA,IAAmB,oBAAA;AACrC,QAAM,gBAAgB,iBAAiB,UAAU;AAEjD,QAAM,CAAC,UAAU,WAAW,IAAI,SAAwB,IAAI;AAC5D,QAAM,SAAS,OAAsB,IAAI;AAGzC,QAAM,iBAAiB,QAAQ,MAAM;AACnC,QAAI,CAAC,cAAe,QAAO;AAC3B,WAAO,cAAc,oBAAoB,SAAS,KAAK;AAAA,EACzD,GAAG,CAAC,eAAe,SAAS,CAAC;AAG7B,QAAM,cAAc,QAAQ,MAAM;AAChC,QAAI,kBAAkB,OAAW,QAAO;AACxC,YAAO,+CAAe,UAAS;AAAA,EACjC,GAAG,CAAC,eAAe,+CAAe,KAAK,CAAC;AAExC,QAAM,YAAY,QAAQ,MAAM;AAC9B,QAAI,gBAAgB,OAAW,QAAO;AACtC,WAAO,OAAO;AAAA,EAChB,GAAG,CAAC,WAAW,CAAC;AAEhB,YAAU,MAAM;AACd,QAAI,CAAC,eAAgB;AAErB,UAAM,OAAO,eAAe,YAAY,UAAU,EAAE,WAAW;AAAA,MAC7D;AAAA,MACA,SAAS;AAAA,QACP,aAAa;AAAA,QACb,KAAK;AAAA,MAAA;AAAA,IACP,CACD;AAED,SAAK,KAAK,CAAC,SAAS;AAClB,YAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,kBAAY,GAAG;AACf,aAAO,UAAU;AAAA,IACnB,GAAG,MAAM;AAET,WAAO,MAAM;AACX,UAAI,OAAO,SAAS;AAClB,YAAI,gBAAgB,OAAO,OAAO;AAClC,eAAO,UAAU;AAAA,MACnB,OAAO;AACL,aAAK,MAAM;AAAA,UACT,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA,QAAA,CACV;AAAA,MACH;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,WAAW,aAAa,WAAW,gBAAgB,cAAc,CAAC;AAElF,QAAM,kBAAkB,MAAM;AAC5B,QAAI,OAAO,SAAS;AAClB,UAAI,gBAAgB,OAAO,OAAO;AAClC,aAAO,UAAU;AAAA,IACnB;AAAA,EACF;AAEA,SACE,oBAAC,YACE,UAAA,YACC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,QAAQ;AAAA,MACP,GAAG;AAAA,MACJ,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,GAAI,SAAS,CAAA;AAAA,MAAC;AAAA,IAChB;AAAA,EAAA,GAGN;AAEJ;"}
@@ -1,16 +1,35 @@
1
1
  import { CSSProperties, HTMLAttributes } from '../../react/adapter.ts';
2
2
  type RenderLayerProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {
3
+ /**
4
+ * The ID of the document to render from
5
+ */
6
+ documentId: string;
7
+ /**
8
+ * The page index to render (0-based)
9
+ */
3
10
  pageIndex: number;
4
11
  /**
5
- * The scale factor for rendering the page.
12
+ * Optional scale override. If not provided, uses document's current scale.
6
13
  */
7
14
  scale?: number;
8
15
  /**
9
- * @deprecated Use `scale` instead. Will be removed in the next major release.
16
+ * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.
10
17
  */
11
- scaleFactor?: number;
12
18
  dpr?: number;
19
+ /**
20
+ * Additional styles for the image element
21
+ */
13
22
  style?: CSSProperties;
14
23
  };
15
- export declare function RenderLayer({ pageIndex, scale, scaleFactor, dpr, style, ...props }: RenderLayerProps): import("react/jsx-runtime").JSX.Element;
24
+ /**
25
+ * RenderLayer Component
26
+ *
27
+ * Renders a PDF page with smart prop handling:
28
+ * - If scale/dpr/rotation props are provided, they override document state
29
+ * - If not provided, component uses document's current state values
30
+ * - Automatically re-renders when:
31
+ * 1. Document state changes (scale, rotation)
32
+ * 2. Page is refreshed (via REFRESH_PAGES action in core)
33
+ */
34
+ export declare function RenderLayer({ documentId, pageIndex, scale: scaleOverride, dpr: dprOverride, style, ...props }: RenderLayerProps): import("react/jsx-runtime").JSX.Element;
16
35
  export {};
@@ -1,16 +1,35 @@
1
1
  import { CSSProperties, HTMLAttributes } from '../../preact/adapter.ts';
2
2
  type RenderLayerProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {
3
+ /**
4
+ * The ID of the document to render from
5
+ */
6
+ documentId: string;
7
+ /**
8
+ * The page index to render (0-based)
9
+ */
3
10
  pageIndex: number;
4
11
  /**
5
- * The scale factor for rendering the page.
12
+ * Optional scale override. If not provided, uses document's current scale.
6
13
  */
7
14
  scale?: number;
8
15
  /**
9
- * @deprecated Use `scale` instead. Will be removed in the next major release.
16
+ * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.
10
17
  */
11
- scaleFactor?: number;
12
18
  dpr?: number;
19
+ /**
20
+ * Additional styles for the image element
21
+ */
13
22
  style?: CSSProperties;
14
23
  };
15
- export declare function RenderLayer({ pageIndex, scale, scaleFactor, dpr, style, ...props }: RenderLayerProps): import("preact").JSX.Element;
24
+ /**
25
+ * RenderLayer Component
26
+ *
27
+ * Renders a PDF page with smart prop handling:
28
+ * - If scale/dpr/rotation props are provided, they override document state
29
+ * - If not provided, component uses document's current state values
30
+ * - Automatically re-renders when:
31
+ * 1. Document state changes (scale, rotation)
32
+ * 2. Page is refreshed (via REFRESH_PAGES action in core)
33
+ */
34
+ export declare function RenderLayer({ documentId, pageIndex, scale: scaleOverride, dpr: dprOverride, style, ...props }: RenderLayerProps): import("preact").JSX.Element;
16
35
  export {};
@@ -1,16 +1,35 @@
1
1
  import { CSSProperties, HTMLAttributes } from '../../react/adapter.ts';
2
2
  type RenderLayerProps = Omit<HTMLAttributes<HTMLImageElement>, 'style'> & {
3
+ /**
4
+ * The ID of the document to render from
5
+ */
6
+ documentId: string;
7
+ /**
8
+ * The page index to render (0-based)
9
+ */
3
10
  pageIndex: number;
4
11
  /**
5
- * The scale factor for rendering the page.
12
+ * Optional scale override. If not provided, uses document's current scale.
6
13
  */
7
14
  scale?: number;
8
15
  /**
9
- * @deprecated Use `scale` instead. Will be removed in the next major release.
16
+ * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.
10
17
  */
11
- scaleFactor?: number;
12
18
  dpr?: number;
19
+ /**
20
+ * Additional styles for the image element
21
+ */
13
22
  style?: CSSProperties;
14
23
  };
15
- export declare function RenderLayer({ pageIndex, scale, scaleFactor, dpr, style, ...props }: RenderLayerProps): import("react/jsx-runtime").JSX.Element;
24
+ /**
25
+ * RenderLayer Component
26
+ *
27
+ * Renders a PDF page with smart prop handling:
28
+ * - If scale/dpr/rotation props are provided, they override document state
29
+ * - If not provided, component uses document's current state values
30
+ * - Automatically re-renders when:
31
+ * 1. Document state changes (scale, rotation)
32
+ * 2. Page is refreshed (via REFRESH_PAGES action in core)
33
+ */
34
+ export declare function RenderLayer({ documentId, pageIndex, scale: scaleOverride, dpr: dprOverride, style, ...props }: RenderLayerProps): import("react/jsx-runtime").JSX.Element;
16
35
  export {};
@@ -1,9 +1,23 @@
1
1
  import { HTMLImgAttributes } from 'svelte/elements';
2
2
  interface RenderLayerProps extends Omit<HTMLImgAttributes, 'style'> {
3
+ /**
4
+ * The ID of the document to render from
5
+ */
6
+ documentId: string;
7
+ /**
8
+ * The page index to render (0-based)
9
+ */
3
10
  pageIndex: number;
11
+ /**
12
+ * Optional scale override. If not provided, uses document's current scale.
13
+ */
4
14
  scale?: number;
15
+ /**
16
+ * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.
17
+ */
5
18
  dpr?: number;
6
19
  class?: string;
20
+ style?: string;
7
21
  }
8
22
  declare const RenderLayer: import('svelte', { with: { "resolution-mode": "import" } }).Component<RenderLayerProps, {}, "">;
9
23
  type RenderLayer = ReturnType<typeof RenderLayer>;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("svelte/internal/disclose-version");const e=require("svelte/internal/client"),t=require("@embedpdf/models"),r=require("@embedpdf/core/svelte"),n=require("@embedpdf/plugin-render");function s(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const l=s(e),o=()=>r.usePlugin(n.RenderPlugin.id),i=()=>r.useCapability(n.RenderPlugin.id);var a=l.from_html("<img/>");exports.RenderLayer=function(e,r){l.push(r,!0);let n=l.rest_props(r,["$$slots","$$events","$$legacy","pageIndex","scale","dpr","class"]);const s=i(),c=o(),d=l.derived((()=>r.scale??1));let u=l.state(null),p=null,f=l.state(0);function g(){p&&(URL.revokeObjectURL(p),p=null)}l.user_effect((()=>{if(c.plugin)return c.plugin.onRefreshPages((e=>{e.includes(r.pageIndex)&&l.update(f)}))})),l.user_effect((()=>{l.get(f);const e=s.provides;if(!e)return;const n=e.renderPage({pageIndex:r.pageIndex,options:{scaleFactor:l.get(d),dpr:r.dpr||window.devicePixelRatio}});return n.wait((e=>{const t=URL.createObjectURL(e);p&&URL.revokeObjectURL(p),l.set(u,t,!0),p=t}),t.ignore),()=>{p?(URL.revokeObjectURL(p),p=null):n.abort({code:t.PdfErrorCode.Cancelled,message:"canceled render task"})}}));var b=l.comment(),v=l.first_child(b),y=e=>{var t=a();l.attribute_effect(t,(()=>({src:l.get(u),onload:g,...n,style:"width: 100%; height: 100%;",class:r.class,alt:""}))),l.replay_events(t),l.append(e,t)};l.if(v,(e=>{l.get(u)&&e(y)})),l.append(e,b),l.pop()},exports.useRenderCapability=i,exports.useRenderPlugin=o,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"}),require("svelte/internal/disclose-version");const e=require("svelte/internal/client"),t=require("@embedpdf/models"),r=require("@embedpdf/core/svelte"),n=require("@embedpdf/plugin-render");function o(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const l=o(e),s=()=>r.useCapability(n.RenderPlugin.id);var c=l.from_html("<img/>");exports.RenderLayer=function(e,n){l.push(n,!0);const o=l.rest_props(n,["$$slots","$$events","$$legacy"]);let{documentId:i,scale:d,dpr:a,class:u,style:p,pageIndex:f,...g}=o,v=l.state(l.proxy(f));l.user_effect(()=>{f!==l.get(v)&&l.set(v,f,!0)});const b=s(),m=r.useDocumentState(()=>i);let y=l.state(null),R=null;const O=l.derived(()=>{var e,t;return(null==(t=null==(e=m.current)?void 0:e.pageRefreshVersions)?void 0:t[f])??0}),j=l.derived(()=>{var e;return void 0!==d?d:(null==(e=m.current)?void 0:e.scale)??1}),P=l.derived(()=>void 0!==a?a:window.devicePixelRatio);function L(){R&&(URL.revokeObjectURL(R),R=null)}l.user_effect(()=>{const e=b.provides,r=i,n=l.get(j),o=l.get(P);l.get(O);const s=l.get(v);if(!e||!r)return R&&(URL.revokeObjectURL(R),R=null),void l.set(y,null);const c=e.forDocument(r).renderPage({pageIndex:s,options:{scaleFactor:n,dpr:o}});return c.wait(e=>{const t=URL.createObjectURL(e);R&&URL.revokeObjectURL(R),R=t,l.set(y,t,!0)},t.ignore),()=>{R?(URL.revokeObjectURL(R),R=null,l.set(y,null)):c.abort({code:t.PdfErrorCode.Cancelled,message:"canceled render task"})}});var x=l.comment(),U=l.first_child(x),h=e=>{var t=c();l.attribute_effect(t,()=>({src:l.get(y),onload:L,style:`width: 100%; height: 100%; ${p??""}`,...g,class:u,alt:""})),l.replay_events(t),l.append(e,t)};l.if(U,e=>{l.get(y)&&e(h)}),l.append(e,x),l.pop()},exports.useRenderCapability=s,exports.useRenderPlugin=()=>r.usePlugin(n.RenderPlugin.id),Object.keys(n).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>n[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-render.ts","../../src/svelte/components/RenderLayer.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","<script lang=\"ts\">\n import type { HTMLImgAttributes } from 'svelte/elements';\n import { ignore, type PdfDocumentObject, PdfErrorCode } from '@embedpdf/models';\n import { useRenderCapability, useRenderPlugin } from '../hooks';\n\n interface RenderLayerProps extends Omit<HTMLImgAttributes, 'style'> {\n pageIndex: number;\n scale?: number;\n dpr?: number;\n class?: string;\n }\n\n let { pageIndex, scale, dpr, class: propsClass, ...props }: RenderLayerProps = $props();\n\n const renderCapability = useRenderCapability();\n const renderPlugin = useRenderPlugin();\n\n const actualScale = $derived(scale ?? 1);\n\n let imageUrl = $state<string | null>(null);\n let urlRef: string | null = null;\n let refreshTick = $state(0);\n\n // Subscribe/unsubscribe whenever the plugin instance changes (not just on mount)\n $effect(() => {\n if (!renderPlugin.plugin) return; // nothing yet; try again when it appears\n return renderPlugin.plugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n refreshTick++; // trigger a re-render\n }\n });\n });\n\n // Render whenever inputs change (pageIndex, scale, dpr, provides, refreshTick)\n $effect(() => {\n // Explicitly read refreshTick so the effect tracks it\n const _tick = refreshTick;\n\n const provides = renderCapability.provides;\n if (!provides) return;\n\n const task = provides.renderPage({\n pageIndex,\n options: { scaleFactor: actualScale, dpr: dpr || window.devicePixelRatio },\n });\n\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n // revoke any previous URL before swapping to avoid leaks\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n }\n\n imageUrl = url;\n urlRef = url;\n }, ignore);\n\n return () => {\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n });\n\n function handleImageLoad() {\n // Additional safety: once the image has loaded, revoke the last ref if still present\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n }\n</script>\n\n{#if imageUrl}\n <img\n src={imageUrl}\n onload={handleImageLoad}\n {...props}\n style=\"width: 100%; height: 100%;\"\n class={propsClass}\n alt=\"\"\n />\n{/if}\n"],"names":["useRenderPlugin","usePlugin","RenderPlugin","id","useRenderCapability","useCapability","props","$","rest_props","$$props","renderCapability","renderPlugin","actualScale","imageUrl","urlRef","refreshTick","handleImageLoad","URL","revokeObjectURL","user_effect","plugin","onRefreshPages","pages","includes","pageIndex","provides","task","renderPage","options","scaleFactor","dpr","window","devicePixelRatio","wait","blob","url","createObjectURL","$__namespace","set","ignore","abort","code","PdfErrorCode","Cancelled","message","consequent"],"mappings":"oiBAGaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,+ECQ7B,IAAAG,EAAKC,EAAAC,WAAAC,EAAA,qEAElD,MAAAC,EAAmBN,IACnBO,EAAeX,IAEfY,0BAAgC,IAElC,IAAAC,UAAiC,MACjCC,EAAwB,KACxBC,UAAqB,GAiDhB,SAAAC,IAEHF,IACFG,IAAIC,gBAAgBJ,GACXA,EAAA,KAEb,CApDAP,EAAAY,aAAc,KACP,GAAAR,EAAaS,OACX,OAAAT,EAAaS,OAAOC,gBAAgBC,IACrCA,EAAMC,SAAqBd,EAAAe,qBAC7BT,EACF,GACD,IAIHR,EAAAY,aAAc,WAEEJ,SAERU,EAAWf,EAAiBe,aAC7BA,EAAQ,OAEP,MAAAC,EAAOD,EAASE,WAAU,CAC9BH,UAASf,EAAAe,UACTI,QAAO,CAAIC,kBAAajB,GAAakB,IAAGrB,EAAAqB,KAASC,OAAOC,oBAc7C,OAXRN,EAAAO,MAAMC,IACH,MAAAC,EAAMlB,IAAImB,gBAAgBF,GAE5BpB,GACFG,IAAIC,gBAAgBJ,GAGtBuB,EAAAC,IAAAzB,EAAWsB,GAAG,GACLrB,EAAAqB,CAAA,GACRI,EAAAA,QAEU,KACPzB,GACFG,IAAIC,gBAAgBJ,GACXA,EAAA,MAETY,EAAKc,MAAK,CACRC,KAAMC,EAAYA,aAACC,UACnBC,QAAS,wBAEb,CACD,+FAcI/B,UACGG,KACJV,kHAJHO,MAAQgC,EAAA,yBAFb"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/svelte/hooks/use-render.ts","../../src/svelte/components/RenderLayer.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","<script lang=\"ts\">\n import type { HTMLImgAttributes } from 'svelte/elements';\n import { ignore, PdfErrorCode } from '@embedpdf/models';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import { useRenderCapability } from '../hooks';\n\n interface RenderLayerProps extends Omit<HTMLImgAttributes, 'style'> {\n /**\n * The ID of the document to render from\n */\n documentId: string;\n /**\n * The page index to render (0-based)\n */\n pageIndex: number;\n /**\n * Optional scale override. If not provided, uses document's current scale.\n */\n scale?: number;\n /**\n * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.\n */\n dpr?: number;\n class?: string;\n style?: string;\n }\n\n // Single allowed $props() call\n const allProps: RenderLayerProps = $props();\n\n // Keep the rest reactive (Svelte will wire these to prop updates)\n let {\n documentId,\n scale: scaleOverride,\n dpr: dprOverride,\n class: propsClass,\n style: propsStyle,\n pageIndex,\n ...attrs\n } = allProps;\n\n // Local non-reactive page index that only updates on actual change\n let localPageIndex = $state(pageIndex);\n\n // Watcher effect: only update localPageIndex if prop actually changes\n $effect(() => {\n if (pageIndex !== localPageIndex) {\n localPageIndex = pageIndex;\n }\n });\n\n const renderCapability = useRenderCapability();\n\n // Make document state follow the (reactive) documentId\n const documentState = useDocumentState(() => documentId);\n\n let imageUrl = $state<string | null>(null);\n let urlRef: string | null = null;\n\n // Track page refreshes from core\n const refreshVersion = $derived(documentState.current?.pageRefreshVersions?.[pageIndex] ?? 0);\n\n // Resolve actual scale / dpr (overrides win, otherwise follow document state)\n const actualScale = $derived(\n scaleOverride !== undefined ? scaleOverride : (documentState.current?.scale ?? 1),\n );\n\n const actualDpr = $derived(dprOverride !== undefined ? dprOverride : window.devicePixelRatio);\n\n // Effect: reruns when:\n // - documentId changes\n // - actualScale changes\n // - actualDpr changes\n // - refreshVersion changes\n // - renderCapability.provides changes\n // It does NOT track pageIndex reactively.\n $effect(() => {\n const capability = renderCapability.provides;\n const docId = documentId;\n const scale = actualScale;\n const dpr = actualDpr;\n const refresh = refreshVersion;\n const page = localPageIndex;\n\n if (!capability || !docId) {\n // Cleanup if no capability/doc\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n imageUrl = null;\n return;\n }\n\n const scoped = capability.forDocument(docId);\n\n const task = scoped.renderPage({\n pageIndex: page,\n options: {\n scaleFactor: scale,\n dpr,\n },\n });\n\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n\n // Revoke previous URL if it existed\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n }\n\n urlRef = url;\n imageUrl = url;\n }, ignore);\n\n return () => {\n // Cleanup for this render run\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n imageUrl = null;\n } else {\n // If render not finished, abort task\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n });\n\n function handleImageLoad() {\n // Once image is loaded, we can drop the objectURL reference\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n }\n</script>\n\n{#if imageUrl}\n <img\n src={imageUrl}\n onload={handleImageLoad}\n style={`width: 100%; height: 100%; ${propsStyle ?? ''}`}\n {...attrs}\n class={propsClass}\n alt=\"\"\n />\n{/if}\n"],"names":["useRenderCapability","useCapability","RenderPlugin","id","allProps","$","rest_props","$$props","documentId","scale","scaleOverride","dpr","dprOverride","class","propsClass","style","propsStyle","pageIndex","attrs","localPageIndex","user_effect","get","set","renderCapability","documentState","useDocumentState","imageUrl","urlRef","refreshVersion","derived","_b","_a","current","pageRefreshVersions","actualScale","actualDpr","window","devicePixelRatio","handleImageLoad","URL","revokeObjectURL","capability","provides","docId","page","task","forDocument","renderPage","options","scaleFactor","wait","blob","url","createObjectURL","ignore","abort","code","PdfErrorCode","Cancelled","message","consequent","usePlugin"],"mappings":"oiBAIaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,qFCwB1EC,EAA0BC,EAAAC,WAAAC,EAAA,CAAA,UAAA,WAAA,4BAI9BC,EACAC,MAAOC,EACPC,IAAKC,EACLC,MAAOC,EACPC,MAAOC,EAAAC,UACPA,KACGC,GACDd,EAGAe,kBAAwBF,IAG5BZ,EAAAe,YAAO,KACDH,IAASZ,EAAAgB,IAAKF,IAChBd,EAAAiB,IAAAH,EAAiBF,GAAS,KAIxB,MAAAM,EAAmBvB,IAGnBwB,EAAgBC,mBAAgB,IAAOjB,GAEzC,IAAAkB,UAAiC,MACjCC,EAAwB,WAGtBC,EAAcvB,EAAAwB,QAAA,aAAY,OAAA,OAAAC,EAAA,OAAAC,EAAAP,EAAcQ,cAAd,EAAAD,EAAuBE,0BAAvB,EAAAH,EAA6Cb,KAAc,IAGrFiB,EAAW7B,EAAAwB,QAAA,WACf,YAAkB,IAAlBnB,EAA8BA,GAAiB,OAAAqB,EAAAP,EAAcQ,kBAASvB,QAAS,IAG3E0B,EAAS9B,EAAAwB,QAAA,SAA4B,IAAhBjB,EAA4BA,EAAcwB,OAAOC,kBAiEnE,SAAAC,IAEHX,IACFY,IAAIC,gBAAgBb,GACpBA,EAAS,KAEb,CA9DAtB,EAAAe,YAAO,WACCqB,EAAalB,EAAiBmB,SAC9BC,EAAQnC,EACRC,QAAQyB,GACRvB,QAAMwB,SACIP,GACV,MAAAgB,QAAOzB,OAERsB,IAAeE,SAEdhB,IACFY,IAAIC,gBAAgBb,GACpBA,EAAS,WAEXtB,EAAAiB,IAAAI,EAAW,MAIP,MAEAmB,EAFSJ,EAAWK,YAAYH,GAElBI,YAClB9B,UAAW2B,EACXI,QAAO,CACLC,YAAaxC,EACbE,SAgBS,OAZbkC,EAAKK,KAAMC,IACH,MAAAC,EAAMb,IAAIc,gBAAgBF,GAG5BxB,GACFY,IAAIC,gBAAgBb,GAGtBA,EAASyB,EACT/C,EAAAiB,IAAAI,EAAW0B,GAAG,IACbE,EAAAA,QAEU,KAEP3B,GACFY,IAAIC,gBAAgBb,GACpBA,EAAS,KACTtB,EAAAiB,IAAAI,EAAW,OAGXmB,EAAKU,MAAK,CACRC,KAAMC,EAAAA,aAAaC,UACnBC,QAAS,sHAiBVjC,UACGY,EAC6BvB,MAAA,8BAAAC,GAAc,QAC/CE,QACGJ,+DANNY,MAAQkC,0BAFb,wDDxI+B,IAAMC,YAAwB3D,EAAAA,aAAaC"}
@@ -1,7 +1,7 @@
1
1
  import "svelte/internal/disclose-version";
2
2
  import * as $ from "svelte/internal/client";
3
3
  import { ignore, PdfErrorCode } from "@embedpdf/models";
4
- import { useCapability, usePlugin } from "@embedpdf/core/svelte";
4
+ import { useCapability, usePlugin, useDocumentState } from "@embedpdf/core/svelte";
5
5
  import { RenderPlugin } from "@embedpdf/plugin-render";
6
6
  export * from "@embedpdf/plugin-render";
7
7
  const useRenderPlugin = () => usePlugin(RenderPlugin.id);
@@ -9,51 +9,60 @@ const useRenderCapability = () => useCapability(RenderPlugin.id);
9
9
  var root_1 = $.from_html(`<img/>`);
10
10
  function RenderLayer($$anchor, $$props) {
11
11
  $.push($$props, true);
12
- let props = $.rest_props($$props, [
13
- "$$slots",
14
- "$$events",
15
- "$$legacy",
16
- "pageIndex",
17
- "scale",
18
- "dpr",
19
- "class"
20
- ]);
12
+ const allProps = $.rest_props($$props, ["$$slots", "$$events", "$$legacy"]);
13
+ let {
14
+ documentId,
15
+ scale: scaleOverride,
16
+ dpr: dprOverride,
17
+ class: propsClass,
18
+ style: propsStyle,
19
+ pageIndex,
20
+ ...attrs
21
+ } = allProps;
22
+ let localPageIndex = $.state($.proxy(pageIndex));
23
+ $.user_effect(() => {
24
+ if (pageIndex !== $.get(localPageIndex)) {
25
+ $.set(localPageIndex, pageIndex, true);
26
+ }
27
+ });
21
28
  const renderCapability = useRenderCapability();
22
- const renderPlugin = useRenderPlugin();
23
- const actualScale = $.derived(() => $$props.scale ?? 1);
29
+ const documentState = useDocumentState(() => documentId);
24
30
  let imageUrl = $.state(null);
25
31
  let urlRef = null;
26
- let refreshTick = $.state(0);
27
- $.user_effect(() => {
28
- if (!renderPlugin.plugin) return;
29
- return renderPlugin.plugin.onRefreshPages((pages) => {
30
- if (pages.includes($$props.pageIndex)) {
31
- $.update(
32
- refreshTick
33
- // trigger a re-render
34
- );
35
- }
36
- });
32
+ const refreshVersion = $.derived(() => {
33
+ var _a, _b;
34
+ return ((_b = (_a = documentState.current) == null ? void 0 : _a.pageRefreshVersions) == null ? void 0 : _b[pageIndex]) ?? 0;
35
+ });
36
+ const actualScale = $.derived(() => {
37
+ var _a;
38
+ return scaleOverride !== void 0 ? scaleOverride : ((_a = documentState.current) == null ? void 0 : _a.scale) ?? 1;
37
39
  });
40
+ const actualDpr = $.derived(() => dprOverride !== void 0 ? dprOverride : window.devicePixelRatio);
38
41
  $.user_effect(() => {
39
- $.get(refreshTick);
40
- const provides = renderCapability.provides;
41
- if (!provides) return;
42
- const task = provides.renderPage({
43
- pageIndex: $$props.pageIndex,
44
- options: {
45
- scaleFactor: $.get(actualScale),
46
- dpr: $$props.dpr || window.devicePixelRatio
42
+ const capability = renderCapability.provides;
43
+ const docId = documentId;
44
+ const scale = $.get(actualScale);
45
+ const dpr = $.get(actualDpr);
46
+ $.get(refreshVersion);
47
+ const page = $.get(localPageIndex);
48
+ if (!capability || !docId) {
49
+ if (urlRef) {
50
+ URL.revokeObjectURL(urlRef);
51
+ urlRef = null;
47
52
  }
48
- });
53
+ $.set(imageUrl, null);
54
+ return;
55
+ }
56
+ const scoped = capability.forDocument(docId);
57
+ const task = scoped.renderPage({ pageIndex: page, options: { scaleFactor: scale, dpr } });
49
58
  task.wait(
50
59
  (blob) => {
51
60
  const url = URL.createObjectURL(blob);
52
61
  if (urlRef) {
53
62
  URL.revokeObjectURL(urlRef);
54
63
  }
55
- $.set(imageUrl, url, true);
56
64
  urlRef = url;
65
+ $.set(imageUrl, url, true);
57
66
  },
58
67
  ignore
59
68
  );
@@ -61,6 +70,7 @@ function RenderLayer($$anchor, $$props) {
61
70
  if (urlRef) {
62
71
  URL.revokeObjectURL(urlRef);
63
72
  urlRef = null;
73
+ $.set(imageUrl, null);
64
74
  } else {
65
75
  task.abort({
66
76
  code: PdfErrorCode.Cancelled,
@@ -83,9 +93,9 @@ function RenderLayer($$anchor, $$props) {
83
93
  $.attribute_effect(img, () => ({
84
94
  src: $.get(imageUrl),
85
95
  onload: handleImageLoad,
86
- ...props,
87
- style: "width: 100%; height: 100%;",
88
- class: $$props.class,
96
+ style: `width: 100%; height: 100%; ${propsStyle ?? ""}`,
97
+ ...attrs,
98
+ class: propsClass,
89
99
  alt: ""
90
100
  }));
91
101
  $.replay_events(img);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/svelte/hooks/use-render.ts","../../src/svelte/components/RenderLayer.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","<script lang=\"ts\">\n import type { HTMLImgAttributes } from 'svelte/elements';\n import { ignore, type PdfDocumentObject, PdfErrorCode } from '@embedpdf/models';\n import { useRenderCapability, useRenderPlugin } from '../hooks';\n\n interface RenderLayerProps extends Omit<HTMLImgAttributes, 'style'> {\n pageIndex: number;\n scale?: number;\n dpr?: number;\n class?: string;\n }\n\n let { pageIndex, scale, dpr, class: propsClass, ...props }: RenderLayerProps = $props();\n\n const renderCapability = useRenderCapability();\n const renderPlugin = useRenderPlugin();\n\n const actualScale = $derived(scale ?? 1);\n\n let imageUrl = $state<string | null>(null);\n let urlRef: string | null = null;\n let refreshTick = $state(0);\n\n // Subscribe/unsubscribe whenever the plugin instance changes (not just on mount)\n $effect(() => {\n if (!renderPlugin.plugin) return; // nothing yet; try again when it appears\n return renderPlugin.plugin.onRefreshPages((pages) => {\n if (pages.includes(pageIndex)) {\n refreshTick++; // trigger a re-render\n }\n });\n });\n\n // Render whenever inputs change (pageIndex, scale, dpr, provides, refreshTick)\n $effect(() => {\n // Explicitly read refreshTick so the effect tracks it\n const _tick = refreshTick;\n\n const provides = renderCapability.provides;\n if (!provides) return;\n\n const task = provides.renderPage({\n pageIndex,\n options: { scaleFactor: actualScale, dpr: dpr || window.devicePixelRatio },\n });\n\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n // revoke any previous URL before swapping to avoid leaks\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n }\n\n imageUrl = url;\n urlRef = url;\n }, ignore);\n\n return () => {\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n } else {\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n });\n\n function handleImageLoad() {\n // Additional safety: once the image has loaded, revoke the last ref if still present\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n }\n</script>\n\n{#if imageUrl}\n <img\n src={imageUrl}\n onload={handleImageLoad}\n {...props}\n style=\"width: 100%; height: 100%;\"\n class={propsClass}\n alt=\"\"\n />\n{/if}\n"],"names":[],"mappings":";;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;;wCCJpF;;MAYqD,QAAK,EAAA,WAAA,SAAA;AAAA;;;;;;;;AAElD,QAAA,mBAAmB,oBAAmB;AACtC,QAAA,eAAe,gBAAe;AAE9B,QAAA,+CAAgC,CAAC;AAEnC,MAAA,mBAAiC,IAAI;AACrC,MAAA,SAAwB;AACxB,MAAA,sBAAqB,CAAC;AAG1B,IAAA,YAAc,MAAA;AACP,QAAA,CAAA,aAAa,OAAM;AACjB,WAAA,aAAa,OAAO,eAAc,CAAE,UAAU;UAC/C,MAAM,SAAqB,QAAA,SAAA,GAAA;;UAC7B;AAAA;AAAA;MACF;AAAA,KACD;AAAA,GACF;AAGD,IAAA,YAAc,MAAA;UAEE,WAAW;UAEnB,WAAW,iBAAiB;SAC7B,SAAQ;UAEP,OAAO,SAAS,WAAU;AAAA,MAC9B,WAAS,QAAA;AAAA,MACT,SAAO;AAAA,QAAI,mBAAa,WAAW;AAAA,QAAE,KAAG,QAAA,OAAS,OAAO;AAAA;;AAG1D,SAAK;AAAA,MAAM,CAAA,SAAS;AACZ,cAAA,MAAM,IAAI,gBAAgB,IAAI;AAEhC,YAAA,QAAQ;AACV,cAAI,gBAAgB,MAAM;AAAA,QAC5B;AAEA,UAAA,IAAA,UAAW,KAAG,IAAA;AACd,iBAAS;AAAA,MACV;AAAA,MAAE;AAAA;AAEU,WAAA,MAAA;AACP,UAAA,QAAQ;AACV,YAAI,gBAAgB,MAAM;AAC1B,iBAAS;AAAA,MACX,OAAO;AACL,aAAK,MAAK;AAAA,UACR,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA;MAEb;AAAA,IACD;AAAA,GACF;AAEQ,WAAA,kBAAkB;AAErB,QAAA,QAAQ;AACV,UAAI,gBAAgB,MAAM;AAC1B,eAAS;AAAA,IACX;AAAA,EACF;;;;;;;mBAKO,QAAQ;AAAA,gBACL;AAAA,WACJ;AAAA;;;;;;;;gBAJH,QAAQ,EAAA,UAAA,UAAA;AAAA;;;;AAFb;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/svelte/hooks/use-render.ts","../../src/svelte/components/RenderLayer.svelte"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/svelte';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","<script lang=\"ts\">\n import type { HTMLImgAttributes } from 'svelte/elements';\n import { ignore, PdfErrorCode } from '@embedpdf/models';\n import { useDocumentState } from '@embedpdf/core/svelte';\n import { useRenderCapability } from '../hooks';\n\n interface RenderLayerProps extends Omit<HTMLImgAttributes, 'style'> {\n /**\n * The ID of the document to render from\n */\n documentId: string;\n /**\n * The page index to render (0-based)\n */\n pageIndex: number;\n /**\n * Optional scale override. If not provided, uses document's current scale.\n */\n scale?: number;\n /**\n * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.\n */\n dpr?: number;\n class?: string;\n style?: string;\n }\n\n // Single allowed $props() call\n const allProps: RenderLayerProps = $props();\n\n // Keep the rest reactive (Svelte will wire these to prop updates)\n let {\n documentId,\n scale: scaleOverride,\n dpr: dprOverride,\n class: propsClass,\n style: propsStyle,\n pageIndex,\n ...attrs\n } = allProps;\n\n // Local non-reactive page index that only updates on actual change\n let localPageIndex = $state(pageIndex);\n\n // Watcher effect: only update localPageIndex if prop actually changes\n $effect(() => {\n if (pageIndex !== localPageIndex) {\n localPageIndex = pageIndex;\n }\n });\n\n const renderCapability = useRenderCapability();\n\n // Make document state follow the (reactive) documentId\n const documentState = useDocumentState(() => documentId);\n\n let imageUrl = $state<string | null>(null);\n let urlRef: string | null = null;\n\n // Track page refreshes from core\n const refreshVersion = $derived(documentState.current?.pageRefreshVersions?.[pageIndex] ?? 0);\n\n // Resolve actual scale / dpr (overrides win, otherwise follow document state)\n const actualScale = $derived(\n scaleOverride !== undefined ? scaleOverride : (documentState.current?.scale ?? 1),\n );\n\n const actualDpr = $derived(dprOverride !== undefined ? dprOverride : window.devicePixelRatio);\n\n // Effect: reruns when:\n // - documentId changes\n // - actualScale changes\n // - actualDpr changes\n // - refreshVersion changes\n // - renderCapability.provides changes\n // It does NOT track pageIndex reactively.\n $effect(() => {\n const capability = renderCapability.provides;\n const docId = documentId;\n const scale = actualScale;\n const dpr = actualDpr;\n const refresh = refreshVersion;\n const page = localPageIndex;\n\n if (!capability || !docId) {\n // Cleanup if no capability/doc\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n imageUrl = null;\n return;\n }\n\n const scoped = capability.forDocument(docId);\n\n const task = scoped.renderPage({\n pageIndex: page,\n options: {\n scaleFactor: scale,\n dpr,\n },\n });\n\n task.wait((blob) => {\n const url = URL.createObjectURL(blob);\n\n // Revoke previous URL if it existed\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n }\n\n urlRef = url;\n imageUrl = url;\n }, ignore);\n\n return () => {\n // Cleanup for this render run\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n imageUrl = null;\n } else {\n // If render not finished, abort task\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n };\n });\n\n function handleImageLoad() {\n // Once image is loaded, we can drop the objectURL reference\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n }\n</script>\n\n{#if imageUrl}\n <img\n src={imageUrl}\n onload={handleImageLoad}\n style={`width: 100%; height: 100%; ${propsStyle ?? ''}`}\n {...attrs}\n class={propsClass}\n alt=\"\"\n />\n{/if}\n"],"names":[],"mappings":";;;;;;AAGO,MAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,MAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;;wCCJpF;;QA4BQ,WAA0B,EAAA,WAAA,SAAA,CAAA,WAAA,YAAA,UAAA,CAAA;;IAI9B;AAAA,IACA,OAAO;AAAA,IACP,KAAK;AAAA,IACL,OAAO;AAAA,IACP,OAAO;AAAA,IACP;AAAA,OACG;AAAA,MACD;AAGA,MAAA,iCAAwB,SAAS,CAAA;AAGrC,IAAA,YAAO,MAAO;QACR,cAAS,EAAA,IAAK,cAAc,GAAE;AAChC,QAAA,IAAA,gBAAiB,WAAS,IAAA;AAAA,IAC5B;AAAA,EACF,CAAC;AAEK,QAAA,mBAAmB,oBAAmB;QAGtC,gBAAgB,iBAAgB,MAAO,UAAU;AAEnD,MAAA,mBAAiC,IAAI;AACrC,MAAA,SAAwB;QAGtB,iBAAc,EAAA,QAAA,MAAA;;AAAY,sCAAc,YAAd,mBAAuB,wBAAvB,mBAA6C,eAAc;AAAA,GAAC;AAGtF,QAAA,cAAW,EAAA,QAAA;;AACf,6BAAkB,SAAY,kBAAiB,mBAAc,YAAd,mBAAuB,UAAS;AAAA,GAAC;QAG5E,YAAS,EAAA,QAAA,MAAY,gBAAgB,SAAY,cAAc,OAAO,gBAAgB;AAS5F,IAAA,YAAO,MAAO;UACN,aAAa,iBAAiB;AAC9B,UAAA,QAAQ;AACR,UAAA,cAAQ,WAAW;AACnB,UAAA,YAAM,SAAS;UACL,cAAc;AACxB,UAAA,aAAO,cAAc;SAEtB,cAAU,CAAK,OAAO;AAErB,UAAA,QAAQ;AACV,YAAI,gBAAgB,MAAM;AAC1B,iBAAS;AAAA,MACX;AACA,QAAA,IAAA,UAAW,IAAI;;IAEjB;AAEM,UAAA,SAAS,WAAW,YAAY,KAAK;AAErC,UAAA,OAAO,OAAO,aAClB,WAAW,MACX,SAAO,EACL,aAAa,OACb,IAAG,EAAA,CAAA;AAIP,SAAK;AAAA,MAAM,CAAA,SAAS;AACZ,cAAA,MAAM,IAAI,gBAAgB,IAAI;AAGhC,YAAA,QAAQ;AACV,cAAI,gBAAgB,MAAM;AAAA,QAC5B;AAEA,iBAAS;AACT,UAAA,IAAA,UAAW,KAAG,IAAA;AAAA,MAChB;AAAA,MAAG;AAAA;AAEU,WAAA,MAAA;AAEP,UAAA,QAAQ;AACV,YAAI,gBAAgB,MAAM;AAC1B,iBAAS;AACT,UAAA,IAAA,UAAW,IAAI;AAAA,MACjB,OAAO;AAEL,aAAK,MAAK;AAAA,UACR,MAAM,aAAa;AAAA,UACnB,SAAS;AAAA;MAEb;AAAA,IACF;AAAA,EACF,CAAC;AAEQ,WAAA,kBAAkB;AAErB,QAAA,QAAQ;AACV,UAAI,gBAAgB,MAAM;AAC1B,eAAS;AAAA,IACX;AAAA,EACF;;;;;;;mBAKO,QAAQ;AAAA,gBACL;AAAA,QAC6B,OAAA,8BAAA,cAAc,EAAE;AAAA,WACjD;AAAA,eACG;AAAA;;;;;;gBANN,QAAQ,EAAA,UAAA,UAAA;AAAA;;;;AAFb;"}
@@ -1,14 +1,21 @@
1
- interface Props {
1
+ interface RenderLayerProps {
2
+ /**
3
+ * The ID of the document to render from
4
+ */
5
+ documentId: string;
6
+ /**
7
+ * The page index to render (0-based)
8
+ */
2
9
  pageIndex: number;
3
10
  /**
4
- * The scale factor for rendering the page.
11
+ * Optional scale override. If not provided, uses document's current scale.
5
12
  */
6
13
  scale?: number;
7
14
  /**
8
- * @deprecated Use `scale` instead. Will be removed in the next major release.
15
+ * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.
9
16
  */
10
- scaleFactor?: number;
11
17
  dpr?: number;
12
18
  }
13
- 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>;
19
+ declare const __VLS_export: import('vue').DefineComponent<RenderLayerProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<RenderLayerProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
20
+ declare const _default: typeof __VLS_export;
14
21
  export default _default;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),r=require("@embedpdf/models"),t=require("@embedpdf/core/vue"),n=require("@embedpdf/plugin-render"),o=()=>t.usePlugin(n.RenderPlugin.id),l=()=>t.useCapability(n.RenderPlugin.id),a=["src"],c=e.defineComponent({__name:"render-layer",props:{pageIndex:{},scale:{},scaleFactor:{},dpr:{}},setup(t){const n=t,c=e.computed((()=>n.scale??n.scaleFactor??1)),u=e.computed((()=>n.dpr??window.devicePixelRatio)),{provides:d}=l(),{plugin:s}=o(),i=e.ref(null),p=e.ref(0);let f=null,g=!1;function v(){g=!0}return e.watchEffect((e=>{if(!s.value)return;e(s.value.onRefreshPages((e=>{e.includes(n.pageIndex)&&p.value++})))})),e.watchEffect((e=>{const t=n.pageIndex,o=c.value,l=u.value;p.value;const a=d.value;if(!a)return;f&&g&&(URL.revokeObjectURL(f),f=null,g=!1);const s=a.renderPage({pageIndex:t,options:{scaleFactor:o,dpr:l}});s.wait((e=>{const r=URL.createObjectURL(e);f=r,i.value=r,g=!1}),r.ignore),e((()=>{f?g&&(URL.revokeObjectURL(f),f=null,g=!1):s.abort({code:r.PdfErrorCode.Cancelled,message:"canceled render task"})}))})),e.onBeforeUnmount((()=>{f&&(URL.revokeObjectURL(f),f=null)})),(r,t)=>i.value?(e.openBlock(),e.createElementBlock("img",{key:0,src:i.value,style:{width:"100%",height:"100%"},onLoad:v},null,40,a)):e.createCommentVNode("",!0)}});exports.RenderLayer=c,exports.useRenderCapability=l,exports.useRenderPlugin=o,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"),r=require("@embedpdf/models"),t=require("@embedpdf/core/vue"),o=require("@embedpdf/plugin-render"),n=()=>t.useCapability(o.RenderPlugin.id),d=["src"],l=e.defineComponent({__name:"render-layer",props:{documentId:{},pageIndex:{},scale:{},dpr:{}},setup(o){const l=o,{provides:u}=n(),a=t.useDocumentState(()=>l.documentId),c=e.ref(null);let i=null,s=!1;const p=e.computed(()=>a.value&&a.value.pageRefreshVersions[l.pageIndex]||0),m=e.computed(()=>{var e;return void 0!==l.scale?l.scale:(null==(e=a.value)?void 0:e.scale)??1}),v=e.computed(()=>void 0!==l.dpr?l.dpr:window.devicePixelRatio);function g(){s=!0}return e.watch([()=>l.documentId,()=>l.pageIndex,m,v,u,p],([e,t,o,n,d],[l],u)=>{if(!d)return void(c.value=null);void 0!==l&&l!==e&&(c.value=null,i&&s&&(URL.revokeObjectURL(i),i=null,s=!1)),i&&s&&l===e&&(URL.revokeObjectURL(i),i=null,s=!1);const a=d.forDocument(e).renderPage({pageIndex:t,options:{scaleFactor:o,dpr:n}});a.wait(e=>{const r=URL.createObjectURL(e);i=r,c.value=r,s=!1},r.ignore),u(()=>{i?s&&(URL.revokeObjectURL(i),i=null,s=!1):a.abort({code:r.PdfErrorCode.Cancelled,message:"canceled render task"})})},{immediate:!0}),(r,t)=>c.value?(e.openBlock(),e.createElementBlock("img",e.mergeProps({key:0,src:c.value,style:{width:"100%",height:"100%"},onLoad:g},r.$attrs),null,16,d)):e.createCommentVNode("",!0)}});exports.RenderLayer=l,exports.useRenderCapability=n,exports.useRenderPlugin=()=>t.usePlugin(o.RenderPlugin.id),Object.keys(o).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>o[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-render.ts","../../src/vue/components/render-layer.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, onBeforeUnmount, computed, watchEffect } from 'vue';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\n\nimport { useRenderCapability, useRenderPlugin } from '../hooks';\n\ninterface Props {\n pageIndex: number;\n /**\n * The scale factor for rendering the page.\n */\n scale?: number;\n /**\n * @deprecated Use `scale` instead. Will be removed in the next major release.\n */\n scaleFactor?: number;\n dpr?: number;\n}\n\nconst props = defineProps<Props>();\n\n// Handle deprecation: prefer scale over scaleFactor, but fall back to scaleFactor if scale is not provided\nconst actualScale = computed(() => props.scale ?? props.scaleFactor ?? 1);\nconst actualDpr = computed(() => props.dpr ?? window.devicePixelRatio);\n\nconst { provides: renderProvides } = useRenderCapability();\nconst { plugin: renderPlugin } = useRenderPlugin();\n\nconst imageUrl = ref<string | null>(null);\nconst refreshTick = ref(0);\n\nlet urlRef: string | null = null;\nlet hasLoaded = false;\n\n// Listen for external page refresh events\nwatchEffect((onCleanup) => {\n if (!renderPlugin.value) return;\n\n const unsubscribe = renderPlugin.value.onRefreshPages((pages: number[]) => {\n if (pages.includes(props.pageIndex)) {\n refreshTick.value++;\n }\n });\n\n onCleanup(unsubscribe);\n});\n\n// Render page when dependencies change\nwatchEffect((onCleanup) => {\n // Capture reactive dependencies\n const pageIndex = props.pageIndex;\n const scale = actualScale.value;\n const dpr = actualDpr.value;\n const tick = refreshTick.value;\n const capability = renderProvides.value;\n\n if (!capability) return;\n\n // Revoke old URL before creating new one (if it's been loaded)\n if (urlRef && hasLoaded) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n hasLoaded = false;\n }\n\n const task = capability.renderPage({\n pageIndex,\n options: {\n scaleFactor: scale,\n dpr,\n },\n });\n\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef = objectUrl;\n imageUrl.value = objectUrl;\n hasLoaded = false;\n }, ignore);\n\n onCleanup(() => {\n if (urlRef) {\n // Only revoke if image has loaded\n if (hasLoaded) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n hasLoaded = false;\n }\n } else {\n // Task still in progress, abort it\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n });\n});\n\nonBeforeUnmount(() => {\n if (urlRef) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n }\n});\n\nfunction handleImageLoad() {\n hasLoaded = true;\n}\n</script>\n\n<template>\n <img\n v-if=\"imageUrl\"\n :src=\"imageUrl\"\n :style=\"{ width: '100%', height: '100%' }\"\n @load=\"handleImageLoad\"\n />\n</template>\n"],"names":["useRenderPlugin","usePlugin","RenderPlugin","id","useRenderCapability","useCapability","props","__props","actualScale","computed","scale","scaleFactor","actualDpr","dpr","window","devicePixelRatio","provides","renderProvides","plugin","renderPlugin","imageUrl","ref","refreshTick","urlRef","hasLoaded","handleImageLoad","vue$1","watchEffect","onCleanup","value","onRefreshPages","pages","includes","pageIndex","capability","URL","revokeObjectURL","task","renderPage","options","wait","blob","objectUrl","createObjectURL","ignore","abort","code","PdfErrorCode","Cancelled","message","onBeforeUnmount","_createElementBlock","src","style","width","height","onLoad"],"mappings":"0MAGaA,EAAkB,IAAMC,YAAwBC,EAAAA,aAAaC,IAC7DC,EAAsB,IAAMC,gBAA4BH,EAAAA,aAAaC,sHCelF,MAAMG,EAAQC,EAGRC,EAAcC,EAAAA,UAAS,IAAMH,EAAMI,OAASJ,EAAMK,aAAe,IACjEC,EAAYH,EAAAA,UAAS,IAAMH,EAAMO,KAAOC,OAAOC,oBAE7CC,SAAUC,GAAmBb,KAC7Bc,OAAQC,GAAiBnB,IAE3BoB,EAAWC,MAAmB,MAC9BC,EAAcD,MAAI,GAExB,IAAIE,EAAwB,KACxBC,GAAY,EAyEhB,SAASC,IACKD,GAAA,CAAA,QAvEdE,EAAAC,aAAaC,IACP,IAACT,EAAaU,MAAO,OAQzBD,EANoBT,EAAaU,MAAMC,gBAAgBC,IACjDA,EAAMC,SAAS1B,EAAM2B,YACXX,EAAAO,OAAA,IAIK,IAIvBH,EAAAC,aAAaC,IAEX,MAAMK,EAAY3B,EAAM2B,UAClBvB,EAAQF,EAAYqB,MACpBhB,EAAMD,EAAUiB,MACGP,EAAAO,MACzB,MAAMK,EAAajB,EAAeY,MAElC,IAAKK,EAAY,OAGbX,GAAUC,IACZW,IAAIC,gBAAgBb,GACXA,EAAA,KACGC,GAAA,GAGR,MAAAa,EAAOH,EAAWI,WAAW,CACjCL,YACAM,QAAS,CACP5B,YAAaD,EACbG,SAICwB,EAAAG,MAAMC,IACH,MAAAC,EAAYP,IAAIQ,gBAAgBF,GAC7BlB,EAAAmB,EACTtB,EAASS,MAAQa,EACLlB,GAAA,CAAA,GACXoB,UAEHhB,GAAU,KACJL,EAEEC,IACFW,IAAIC,gBAAgBb,GACXA,EAAA,KACGC,GAAA,GAIda,EAAKQ,MAAM,CACTC,KAAMC,EAAaA,aAAAC,UACnBC,QAAS,wBACV,GAEJ,IAGHC,EAAAA,iBAAgB,KACV3B,IACFY,IAAIC,gBAAgBb,GACXA,EAAA,KAAA,WAWHH,EAAQS,qBADhBsB,EAAAA,mBAKE,MAAA,OAHCC,IAAKhC,EAAQS,MACbwB,MAAO,CAAiCC,MAAA,OAAAC,OAAA,QACxCC,OAAM/B"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/vue/hooks/use-render.ts","../../src/vue/components/render-layer.vue"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/vue';\nimport { RenderPlugin } from '@embedpdf/plugin-render';\n\nexport const useRenderPlugin = () => usePlugin<RenderPlugin>(RenderPlugin.id);\nexport const useRenderCapability = () => useCapability<RenderPlugin>(RenderPlugin.id);\n","<script setup lang=\"ts\">\nimport { ref, computed, watch } from 'vue';\nimport { ignore, PdfErrorCode } from '@embedpdf/models';\nimport { useDocumentState } from '@embedpdf/core/vue';\nimport { useRenderCapability } from '../hooks';\n\ninterface RenderLayerProps {\n /**\n * The ID of the document to render from\n */\n documentId: string;\n /**\n * The page index to render (0-based)\n */\n pageIndex: number;\n /**\n * Optional scale override. If not provided, uses document's current scale.\n */\n scale?: number;\n /**\n * Optional device pixel ratio override. If not provided, uses window.devicePixelRatio.\n */\n dpr?: number;\n}\n\nconst props = defineProps<RenderLayerProps>();\n\nconst { provides: renderProvides } = useRenderCapability();\nconst documentState = useDocumentState(() => props.documentId);\n\nconst imageUrl = ref<string | null>(null);\nlet urlRef: string | null = null;\nlet hasLoaded = false;\n\n// Get refresh version from core state\nconst refreshVersion = computed(() => {\n if (!documentState.value) return 0;\n return documentState.value.pageRefreshVersions[props.pageIndex] || 0;\n});\n\n// Determine actual render options: use overrides if provided, otherwise fall back to document state\nconst actualScale = computed(() => {\n if (props.scale !== undefined) return props.scale;\n return documentState.value?.scale ?? 1;\n});\n\nconst actualDpr = computed(() => {\n if (props.dpr !== undefined) return props.dpr;\n return window.devicePixelRatio;\n});\n\n// Render page when dependencies change\nwatch(\n [\n () => props.documentId,\n () => props.pageIndex,\n actualScale,\n actualDpr,\n renderProvides,\n refreshVersion,\n ],\n ([docId, pageIdx, scale, dpr, capability], [prevDocId], onCleanup) => {\n if (!capability) {\n imageUrl.value = null;\n return;\n }\n\n // CRITICAL: Clear image immediately when documentId changes (not for zoom/scale)\n if (prevDocId !== undefined && prevDocId !== docId) {\n imageUrl.value = null;\n if (urlRef && hasLoaded) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n hasLoaded = false;\n }\n }\n\n // Revoke old URL before creating new one (if it's been loaded)\n if (urlRef && hasLoaded && prevDocId === docId) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n hasLoaded = false;\n }\n\n const task = capability.forDocument(docId).renderPage({\n pageIndex: pageIdx,\n options: {\n scaleFactor: scale,\n dpr,\n },\n });\n\n task.wait((blob) => {\n const objectUrl = URL.createObjectURL(blob);\n urlRef = objectUrl;\n imageUrl.value = objectUrl;\n hasLoaded = false;\n }, ignore);\n\n onCleanup(() => {\n if (urlRef) {\n // Only revoke if image has loaded\n if (hasLoaded) {\n URL.revokeObjectURL(urlRef);\n urlRef = null;\n hasLoaded = false;\n }\n } else {\n // Task still in progress, abort it\n task.abort({\n code: PdfErrorCode.Cancelled,\n message: 'canceled render task',\n });\n }\n });\n },\n { immediate: true },\n);\n\nfunction handleImageLoad() {\n hasLoaded = true;\n}\n</script>\n\n<template>\n <img\n v-if=\"imageUrl\"\n :src=\"imageUrl\"\n :style=\"{ width: '100%', height: '100%' }\"\n @load=\"handleImageLoad\"\n v-bind=\"$attrs\"\n />\n</template>\n"],"names":["useRenderCapability","useCapability","RenderPlugin","id","props","__props","provides","renderProvides","documentState","useDocumentState","documentId","imageUrl","ref","urlRef","hasLoaded","refreshVersion","computed","value","pageRefreshVersions","pageIndex","actualScale","scale","_a","actualDpr","dpr","window","devicePixelRatio","handleImageLoad","watch","docId","pageIdx","capability","prevDocId","onCleanup","URL","revokeObjectURL","task","forDocument","renderPage","options","scaleFactor","wait","blob","objectUrl","createObjectURL","ignore","abort","code","PdfErrorCode","Cancelled","message","immediate","_openBlock","_createElementBlock","_mergeProps","src","style","width","height","onLoad","$attrs","_hoisted_1","usePlugin"],"mappings":"0MAIaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,qHCqBlF,MAAMC,EAAQC,GAENC,SAAUC,GAAmBP,IAC/BQ,EAAgBC,EAAAA,iBAAiB,IAAML,EAAMM,YAE7CC,EAAWC,EAAAA,IAAmB,MACpC,IAAIC,EAAwB,KACxBC,GAAY,EAGhB,MAAMC,EAAiBC,EAAAA,SAAS,IACzBR,EAAcS,OACZT,EAAcS,MAAMC,oBAAoBd,EAAMe,YADpB,GAK7BC,EAAcJ,EAAAA,SAAS,WAC3B,YAAoB,IAAhBZ,EAAMiB,MAA4BjB,EAAMiB,OACrC,OAAAC,EAAAd,EAAcS,YAAd,EAAAK,EAAqBD,QAAS,IAGjCE,EAAYP,EAAAA,SAAS,SACP,IAAdZ,EAAMoB,IAA0BpB,EAAMoB,IACnCC,OAAOC,kBAuEhB,SAASC,IACPb,GAAY,CACd,QArEAc,EAAAA,MACE,CACE,IAAMxB,EAAMM,WACZ,IAAMN,EAAMe,UACZC,EACAG,EACAhB,EACAQ,GAEF,EAAEc,EAAOC,EAAST,EAAOG,EAAKO,IAAcC,GAAYC,KACtD,IAAKF,EAEH,YADApB,EAASM,MAAQ,WAKD,IAAde,GAA2BA,IAAcH,IAC3ClB,EAASM,MAAQ,KACbJ,GAAUC,IACZoB,IAAIC,gBAAgBtB,GACpBA,EAAS,KACTC,GAAY,IAKZD,GAAUC,GAAakB,IAAcH,IACvCK,IAAIC,gBAAgBtB,GACpBA,EAAS,KACTC,GAAY,GAGd,MAAMsB,EAAOL,EAAWM,YAAYR,GAAOS,WAAW,CACpDnB,UAAWW,EACXS,QAAS,CACPC,YAAanB,EACbG,SAIJY,EAAKK,KAAMC,IACT,MAAMC,EAAYT,IAAIU,gBAAgBF,GACtC7B,EAAS8B,EACThC,EAASM,MAAQ0B,EACjB7B,GAAY,GACX+B,EAAAA,QAEHZ,EAAU,KACJpB,EAEEC,IACFoB,IAAIC,gBAAgBtB,GACpBA,EAAS,KACTC,GAAY,GAIdsB,EAAKU,MAAM,CACTC,KAAMC,EAAAA,aAAaC,UACnBC,QAAS,4BAKjB,CAAEC,WAAW,WAULxC,EAAAM,OADRmC,EAAAA,YAAAC,EAAAA,mBAME,MANFC,aAME,OAJCC,IAAK5C,EAAAM,MACLuC,MAAO,CAAAC,MAAA,OAAAC,OAAA,QACPC,OAAMhC,GACCiC,EAAAA,QAAM,KAAA,GAAAC,+GD/Ha,IAAMC,YAAwB5D,EAAAA,aAAaC"}