@embedpdf/react 3.0.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +192 -0
- package/dist/AnnotationListSnapshot-W0RCsyDE-dWna4TTJ.d.cts +2593 -0
- package/dist/AnnotationListSnapshot-W0RCsyDE-dWna4TTJ.d.ts +2593 -0
- package/dist/annotation-B6jwfTCh.d.cts +173 -0
- package/dist/annotation-Ct6dFtzJ.cjs +913 -0
- package/dist/annotation-Ct6dFtzJ.cjs.map +1 -0
- package/dist/annotation-DjGWJljY.js +829 -0
- package/dist/annotation-DjGWJljY.js.map +1 -0
- package/dist/annotation-menu.cjs +115 -0
- package/dist/annotation-menu.cjs.map +1 -0
- package/dist/annotation-menu.d.cts +7 -0
- package/dist/annotation-menu.d.ts +7 -0
- package/dist/annotation-menu.js +99 -0
- package/dist/annotation-menu.js.map +1 -0
- package/dist/annotation-nUMefyjw.d.ts +173 -0
- package/dist/annotation.cjs +25 -0
- package/dist/annotation.d.cts +3 -0
- package/dist/annotation.d.ts +3 -0
- package/dist/annotation.js +4 -0
- package/dist/commands.cjs +59 -0
- package/dist/commands.cjs.map +1 -0
- package/dist/commands.d.cts +20 -0
- package/dist/commands.d.ts +20 -0
- package/dist/commands.js +47 -0
- package/dist/commands.js.map +1 -0
- package/dist/form.cjs +560 -0
- package/dist/form.cjs.map +1 -0
- package/dist/form.d.cts +52 -0
- package/dist/form.d.ts +52 -0
- package/dist/form.js +545 -0
- package/dist/form.js.map +1 -0
- package/dist/i18n.cjs +52 -0
- package/dist/i18n.cjs.map +1 -0
- package/dist/i18n.d.cts +30 -0
- package/dist/i18n.d.ts +30 -0
- package/dist/i18n.js +42 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.cjs +240 -0
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +37 -0
- package/dist/interaction.cjs +152 -0
- package/dist/interaction.cjs.map +1 -0
- package/dist/interaction.d.cts +46 -0
- package/dist/interaction.d.ts +46 -0
- package/dist/interaction.js +139 -0
- package/dist/interaction.js.map +1 -0
- package/dist/link.cjs +108 -0
- package/dist/link.cjs.map +1 -0
- package/dist/link.d.cts +16 -0
- package/dist/link.d.ts +16 -0
- package/dist/link.js +98 -0
- package/dist/link.js.map +1 -0
- package/dist/metadata.cjs +25 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.cts +11 -0
- package/dist/metadata.d.ts +11 -0
- package/dist/metadata.js +16 -0
- package/dist/metadata.js.map +1 -0
- package/dist/page-edit.cjs +20 -0
- package/dist/page-edit.cjs.map +1 -0
- package/dist/page-edit.d.cts +7 -0
- package/dist/page-edit.d.ts +7 -0
- package/dist/page-edit.js +11 -0
- package/dist/page-edit.js.map +1 -0
- package/dist/page-view.cjs +107 -0
- package/dist/page-view.cjs.map +1 -0
- package/dist/page-view.d.cts +23 -0
- package/dist/page-view.d.ts +23 -0
- package/dist/page-view.js +95 -0
- package/dist/page-view.js.map +1 -0
- package/dist/redaction.cjs +35 -0
- package/dist/redaction.cjs.map +1 -0
- package/dist/redaction.d.cts +14 -0
- package/dist/redaction.d.ts +14 -0
- package/dist/redaction.js +25 -0
- package/dist/redaction.js.map +1 -0
- package/dist/render.cjs +142 -0
- package/dist/render.cjs.map +1 -0
- package/dist/render.d.cts +32 -0
- package/dist/render.d.ts +32 -0
- package/dist/render.js +131 -0
- package/dist/render.js.map +1 -0
- package/dist/rolldown-runtime-DDXJien1.cjs +50 -0
- package/dist/runtime-CMxIuF2O.d.cts +195 -0
- package/dist/runtime-DV98q7I0.d.ts +195 -0
- package/dist/runtime.cjs +314 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +3 -0
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.js +287 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scrollbar.cjs +241 -0
- package/dist/scrollbar.cjs.map +1 -0
- package/dist/scrollbar.d.cts +42 -0
- package/dist/scrollbar.d.ts +42 -0
- package/dist/scrollbar.js +213 -0
- package/dist/scrollbar.js.map +1 -0
- package/dist/search.cjs +70 -0
- package/dist/search.cjs.map +1 -0
- package/dist/search.d.cts +35 -0
- package/dist/search.d.ts +35 -0
- package/dist/search.js +58 -0
- package/dist/search.js.map +1 -0
- package/dist/selection.cjs +60 -0
- package/dist/selection.cjs.map +1 -0
- package/dist/selection.d.cts +12 -0
- package/dist/selection.d.ts +12 -0
- package/dist/selection.js +49 -0
- package/dist/selection.js.map +1 -0
- package/dist/shell.cjs +57 -0
- package/dist/shell.cjs.map +1 -0
- package/dist/shell.d.cts +27 -0
- package/dist/shell.d.ts +27 -0
- package/dist/shell.js +46 -0
- package/dist/shell.js.map +1 -0
- package/dist/stage.cjs +343 -0
- package/dist/stage.cjs.map +1 -0
- package/dist/stage.d.cts +104 -0
- package/dist/stage.d.ts +104 -0
- package/dist/stage.js +327 -0
- package/dist/stage.js.map +1 -0
- package/dist/stamp.cjs +76 -0
- package/dist/stamp.cjs.map +1 -0
- package/dist/stamp.d.cts +28 -0
- package/dist/stamp.d.ts +28 -0
- package/dist/stamp.js +63 -0
- package/dist/stamp.js.map +1 -0
- package/dist/toolbar.cjs +515 -0
- package/dist/toolbar.cjs.map +1 -0
- package/dist/toolbar.d.cts +100 -0
- package/dist/toolbar.d.ts +100 -0
- package/dist/toolbar.js +505 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/views.cjs +35 -0
- package/dist/views.cjs.map +1 -0
- package/dist/views.d.cts +21 -0
- package/dist/views.d.ts +21 -0
- package/dist/views.js +26 -0
- package/dist/views.js.map +1 -0
- package/package.json +158 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.js","names":[],"sources":["../src/redaction.tsx"],"sourcesContent":["import { RedactionToken } from '@embedpdf/plugin-redaction';\nimport type {\n RedactionApplyResult,\n RedactionCapability,\n RedactionPendingItem,\n} from '@embedpdf/plugin-redaction';\nimport { useCapability, useSelector } from './runtime';\n\n/**\n * Redaction for the surrounding `DocumentScope`: the pending-marks view plus\n * the destructive apply. Marking rides the annotation plane (the composed\n * `redact` tool); `useRedaction` surfaces the workflow around it.\n *\n * const redaction = useRedaction();\n * redaction.toggleRedact();\n * await redaction.applyAll(); // irreversible — confirm first\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-redaction';\n\nexport function useRedaction(): RedactionCapability & {\n applying: boolean;\n lastApplyResult: RedactionApplyResult | null;\n} {\n const cap = useCapability(RedactionToken);\n const applying = useSelector(RedactionToken, (c) => c.isApplying());\n const lastApplyResult = useSelector(RedactionToken, (c) => c.lastResult());\n return { ...cap, applying, lastApplyResult };\n}\n\n/** The pending marks, reactive against the annotation plane. Note the view\n * covers LOADED pages — call `preparePending()` (e.g. on panel open) to load\n * the whole document. */\nexport function usePendingRedactions(): RedactionPendingItem[] {\n return useSelector(RedactionToken, (c) => c.getPending(), pendingEqual);\n}\n\nconst pendingEqual = (a: RedactionPendingItem[], b: RedactionPendingItem[]): boolean =>\n a.length === b.length &&\n a.every((item, i) => item.id === b[i]!.id && item.overlayText === b[i]!.overlayText);\n"],"mappings":";;;;AAqBA,SAAgB,eAGd;CACA,MAAM,MAAM,cAAc,cAAc;CACxC,MAAM,WAAW,YAAY,iBAAiB,MAAM,EAAE,WAAW,CAAC;CAClE,MAAM,kBAAkB,YAAY,iBAAiB,MAAM,EAAE,WAAW,CAAC;CACzE,OAAO;EAAE,GAAG;EAAK;EAAU;CAAgB;AAC7C;;;;AAKA,SAAgB,uBAA+C;CAC7D,OAAO,YAAY,iBAAiB,MAAM,EAAE,WAAW,GAAG,YAAY;AACxE;AAEA,MAAM,gBAAgB,GAA2B,MAC/C,EAAE,WAAW,EAAE,UACf,EAAE,OAAO,MAAM,MAAM,KAAK,OAAO,EAAE,EAAE,CAAE,MAAM,KAAK,gBAAgB,EAAE,EAAE,CAAE,WAAW"}
|
package/dist/render.cjs
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_rolldown_runtime = require("./rolldown-runtime-DDXJien1.cjs");
|
|
3
|
+
const require_runtime = require("./runtime.cjs");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
let react = require("react");
|
|
6
|
+
react = require_rolldown_runtime.__toESM(react, 1);
|
|
7
|
+
let _embedpdf_plugin_render = require("@embedpdf/plugin-render");
|
|
8
|
+
//#region src/render.tsx
|
|
9
|
+
function RenderLayer({ annotations = true } = {}) {
|
|
10
|
+
const page = require_runtime.usePage();
|
|
11
|
+
const render = require_runtime.useCapability(_embedpdf_plugin_render.RenderToken);
|
|
12
|
+
const ref = (0, react.useRef)(null);
|
|
13
|
+
const sourceKey = require_runtime.useSelector(_embedpdf_plugin_render.RenderToken, (c) => c.renderSourceKey(page.pon, {
|
|
14
|
+
scale: page.transform.renderScale,
|
|
15
|
+
includeAnnotations: annotations
|
|
16
|
+
}));
|
|
17
|
+
(0, react.useEffect)(() => {
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
let revoke;
|
|
20
|
+
(async () => {
|
|
21
|
+
try {
|
|
22
|
+
const obj = await (await render.renderPage(page.pon, {
|
|
23
|
+
scale: page.transform.renderScale,
|
|
24
|
+
includeAnnotations: annotations,
|
|
25
|
+
signal: controller.signal
|
|
26
|
+
})).objectUrl(controller.signal);
|
|
27
|
+
if (controller.signal.aborted) {
|
|
28
|
+
obj.revoke();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
revoke = obj.revoke;
|
|
32
|
+
if (ref.current) ref.current.src = obj.url;
|
|
33
|
+
} catch {}
|
|
34
|
+
})();
|
|
35
|
+
return () => {
|
|
36
|
+
controller.abort();
|
|
37
|
+
revoke?.();
|
|
38
|
+
};
|
|
39
|
+
}, [
|
|
40
|
+
render,
|
|
41
|
+
page.pon,
|
|
42
|
+
sourceKey
|
|
43
|
+
]);
|
|
44
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
45
|
+
ref,
|
|
46
|
+
alt: "",
|
|
47
|
+
draggable: false,
|
|
48
|
+
style: {
|
|
49
|
+
position: "absolute",
|
|
50
|
+
inset: 0,
|
|
51
|
+
width: "100%",
|
|
52
|
+
height: "100%",
|
|
53
|
+
pointerEvents: "none"
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* TileLayer — the sharp plane above the base rung.
|
|
59
|
+
*
|
|
60
|
+
* Mounting it is the per-lens OPT-IN; whether it spends anything is demand
|
|
61
|
+
* arithmetic (a thumbnail rail's demand never engages). The paint list is the
|
|
62
|
+
* plugin's retention-safe plan: keyed <img>s inside ONE container that carries
|
|
63
|
+
* the page scale as a single transform (one rounding context — no tile seams),
|
|
64
|
+
* with `onLoad` reporting the decode boundary back so retained coarser
|
|
65
|
+
* generations release only when their replacement is truly on screen.
|
|
66
|
+
*/
|
|
67
|
+
function TileLayer({ annotations = true } = {}) {
|
|
68
|
+
const page = require_runtime.usePage();
|
|
69
|
+
const render = require_runtime.useCapability(_embedpdf_plugin_render.RenderToken);
|
|
70
|
+
const demand = page.getViewDemand?.() ?? { desiredDeviceWidth: page.transform.deviceWidth };
|
|
71
|
+
const plan = require_runtime.useSelector(_embedpdf_plugin_render.RenderToken, (c) => c.tilePlan(page.pon, demand, { includeAnnotations: annotations }));
|
|
72
|
+
(0, react.useEffect)(() => () => render.releaseTiles(page.pon), [render, page.pon]);
|
|
73
|
+
if (plan.paint.length === 0) return null;
|
|
74
|
+
const t = page.transform;
|
|
75
|
+
const scale = t.viewScale;
|
|
76
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
77
|
+
style: {
|
|
78
|
+
position: "absolute",
|
|
79
|
+
left: 0,
|
|
80
|
+
top: 0,
|
|
81
|
+
width: t.contentWidth / scale,
|
|
82
|
+
height: t.contentHeight / scale,
|
|
83
|
+
transform: `scale(${scale})`,
|
|
84
|
+
transformOrigin: "0 0",
|
|
85
|
+
pointerEvents: "none"
|
|
86
|
+
},
|
|
87
|
+
children: plan.paint.map((source) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TileImg, {
|
|
88
|
+
source,
|
|
89
|
+
onPainted: () => render.tilePainted(page.pon, source.key)
|
|
90
|
+
}, source.key))
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** One tile: object-URL lifecycle + the painted (decode-boundary) report. */
|
|
94
|
+
function TileImg({ source, onPainted }) {
|
|
95
|
+
const ref = (0, react.useRef)(null);
|
|
96
|
+
(0, react.useEffect)(() => {
|
|
97
|
+
const controller = new AbortController();
|
|
98
|
+
let revoke;
|
|
99
|
+
(async () => {
|
|
100
|
+
try {
|
|
101
|
+
const obj = await source.handle.objectUrl(controller.signal);
|
|
102
|
+
if (controller.signal.aborted) {
|
|
103
|
+
obj.revoke();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
revoke = obj.revoke;
|
|
107
|
+
if (ref.current) ref.current.src = obj.url;
|
|
108
|
+
} catch {}
|
|
109
|
+
})();
|
|
110
|
+
return () => {
|
|
111
|
+
controller.abort();
|
|
112
|
+
revoke?.();
|
|
113
|
+
};
|
|
114
|
+
}, [source.handle]);
|
|
115
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
116
|
+
ref,
|
|
117
|
+
alt: "",
|
|
118
|
+
draggable: false,
|
|
119
|
+
onLoad: onPainted,
|
|
120
|
+
style: {
|
|
121
|
+
position: "absolute",
|
|
122
|
+
left: source.rect.x,
|
|
123
|
+
top: source.rect.y,
|
|
124
|
+
width: source.rect.width,
|
|
125
|
+
height: source.rect.height,
|
|
126
|
+
zIndex: source.z
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
exports.RenderLayer = RenderLayer;
|
|
132
|
+
exports.TileLayer = TileLayer;
|
|
133
|
+
Object.keys(_embedpdf_plugin_render).forEach(function(k) {
|
|
134
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
135
|
+
enumerable: true,
|
|
136
|
+
get: function() {
|
|
137
|
+
return _embedpdf_plugin_render[k];
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
//# sourceMappingURL=render.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.cjs","names":["usePage","useCapability","RenderToken","useSelector"],"sources":["../src/render.tsx"],"sourcesContent":["/**\n * RenderLayer + TileLayer — the React views of @embedpdf/plugin-render.\n *\n * RenderLayer paints the BASE rung to an <img> from the engine's ENCODED\n * image() (identical for local & cloud). TileLayer paints the tile paint-plan\n * ABOVE it when the deployment lattice caps the base below the demand — mount\n * it per lens (the main stage yes, a thumbnail rail no); where the demand is\n * small it engages nothing. Both are dumb painters: every decision (policy\n * conformance, want sets, retention, release) is plugin-render's.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-render';\nimport * as React from 'react';\nimport { useEffect, useRef } from 'react';\nimport { RenderToken } from '@embedpdf/plugin-render';\nimport type { PageViewDemand, TilePaintSource } from '@embedpdf/plugin-render';\nimport { useCapability, usePage, useSelector } from './runtime';\n\nexport interface RenderLayerProps {\n /**\n * Bake annotations into the page bitmap (default true). Pass false when an\n * <AnnotationLayer> owns annotation rendering, so they aren't drawn twice.\n */\n annotations?: boolean;\n}\n\nexport function RenderLayer({ annotations = true }: RenderLayerProps = {}) {\n const page = usePage();\n const render = useCapability(RenderToken);\n const ref = useRef<HTMLImageElement>(null);\n // ONE dependency: the raster's canonical identity — conformed viewport +\n // annotations flag + epoch. Inside a lattice\n // rung, zoom changes don't move it: no refetch, no DOM churn — the stage's\n // CSS transform does the scaling. It changes exactly at rung crossings and\n // on CONFIRMED mutations (epoch bumps at commit, never mid-gesture). Under\n // `continuous` it embeds the exact scale — v2 behavior byte-for-byte. The\n // policy behind it is a document fact the kernel materialized before\n // publish, so the key is always computable.\n const sourceKey = useSelector(RenderToken, (c) =>\n c.renderSourceKey(page.pon, {\n scale: page.transform.renderScale,\n includeAnnotations: annotations,\n }),\n );\n useEffect(() => {\n const controller = new AbortController();\n let revoke: (() => void) | undefined;\n (async () => {\n try {\n // The capability conforms this to the policy (lattice → ladder width,\n // continuous → this exact scale) and collapses same-key asks in its\n // raster store. A stale-closure scale is harmless by construction:\n // any scale in this rung produces this key's canonical request.\n const image = await render.renderPage(page.pon, {\n scale: page.transform.renderScale,\n includeAnnotations: annotations,\n signal: controller.signal,\n });\n const obj = await image.objectUrl(controller.signal);\n if (controller.signal.aborted) {\n obj.revoke();\n return;\n }\n revoke = obj.revoke;\n if (ref.current) ref.current.src = obj.url;\n } catch {\n /* aborted (camera moved / unmounted) or render failed */\n }\n })();\n return () => {\n controller.abort();\n revoke?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- sourceKey IS the\n // render identity; scale/annotations/epoch are folded into it upstream.\n }, [render, page.pon, sourceKey]);\n return (\n <img\n ref={ref}\n alt=\"\"\n draggable={false}\n style={{\n position: 'absolute',\n inset: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n }}\n />\n );\n}\n\nexport interface TileLayerProps {\n /**\n * Bake annotations into tile bitmaps (default true). Pass false when an\n * <AnnotationLayer> owns annotation rendering — the composition that keeps\n * tile artifacts annotation-version-free (CDN-stable across edits).\n */\n annotations?: boolean;\n}\n\n/**\n * TileLayer — the sharp plane above the base rung.\n *\n * Mounting it is the per-lens OPT-IN; whether it spends anything is demand\n * arithmetic (a thumbnail rail's demand never engages). The paint list is the\n * plugin's retention-safe plan: keyed <img>s inside ONE container that carries\n * the page scale as a single transform (one rounding context — no tile seams),\n * with `onLoad` reporting the decode boundary back so retained coarser\n * generations release only when their replacement is truly on screen.\n */\nexport function TileLayer({ annotations = true }: TileLayerProps = {}) {\n const page = usePage();\n const render = useCapability(RenderToken);\n // Demand: the host's live camera view (Stage) or whole-page (PageView).\n const demand: PageViewDemand = page.getViewDemand?.() ?? {\n desiredDeviceWidth: page.transform.deviceWidth,\n };\n const plan = useSelector(RenderToken, (c) =>\n c.tilePlan(page.pon, demand, { includeAnnotations: annotations }),\n );\n // Lens unmounted: stop in-flight tile fetches; resolved bytes stay cached.\n useEffect(() => () => render.releaseTiles(page.pon), [render, page.pon]);\n if (plan.paint.length === 0) return null;\n const t = page.transform;\n const scale = t.viewScale;\n return (\n <div\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: t.contentWidth / scale,\n height: t.contentHeight / scale,\n transform: `scale(${scale})`,\n transformOrigin: '0 0',\n pointerEvents: 'none',\n }}\n >\n {plan.paint.map((source) => (\n <TileImg\n key={source.key}\n source={source}\n onPainted={() => render.tilePainted(page.pon, source.key)}\n />\n ))}\n </div>\n );\n}\n\n/** One tile: object-URL lifecycle + the painted (decode-boundary) report. */\nfunction TileImg({ source, onPainted }: { source: TilePaintSource; onPainted: () => void }) {\n const ref = useRef<HTMLImageElement>(null);\n useEffect(() => {\n const controller = new AbortController();\n let revoke: (() => void) | undefined;\n (async () => {\n try {\n const obj = await source.handle.objectUrl(controller.signal);\n if (controller.signal.aborted) {\n obj.revoke();\n return;\n }\n revoke = obj.revoke;\n if (ref.current) ref.current.src = obj.url;\n } catch {\n /* aborted (plan moved on) */\n }\n })();\n return () => {\n controller.abort();\n revoke?.();\n };\n }, [source.handle]);\n return (\n <img\n ref={ref}\n alt=\"\"\n draggable={false}\n onLoad={onPainted}\n style={{\n position: 'absolute',\n left: source.rect.x,\n top: source.rect.y,\n width: source.rect.width,\n height: source.rect.height,\n zIndex: source.z,\n }}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export * from "@embedpdf/plugin-render";
|
|
2
|
+
//#region src/render.d.ts
|
|
3
|
+
interface RenderLayerProps {
|
|
4
|
+
/**
|
|
5
|
+
* Bake annotations into the page bitmap (default true). Pass false when an
|
|
6
|
+
* <AnnotationLayer> owns annotation rendering, so they aren't drawn twice.
|
|
7
|
+
*/
|
|
8
|
+
annotations?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare function RenderLayer({ annotations }?: RenderLayerProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
interface TileLayerProps {
|
|
12
|
+
/**
|
|
13
|
+
* Bake annotations into tile bitmaps (default true). Pass false when an
|
|
14
|
+
* <AnnotationLayer> owns annotation rendering — the composition that keeps
|
|
15
|
+
* tile artifacts annotation-version-free (CDN-stable across edits).
|
|
16
|
+
*/
|
|
17
|
+
annotations?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* TileLayer — the sharp plane above the base rung.
|
|
21
|
+
*
|
|
22
|
+
* Mounting it is the per-lens OPT-IN; whether it spends anything is demand
|
|
23
|
+
* arithmetic (a thumbnail rail's demand never engages). The paint list is the
|
|
24
|
+
* plugin's retention-safe plan: keyed <img>s inside ONE container that carries
|
|
25
|
+
* the page scale as a single transform (one rounding context — no tile seams),
|
|
26
|
+
* with `onLoad` reporting the decode boundary back so retained coarser
|
|
27
|
+
* generations release only when their replacement is truly on screen.
|
|
28
|
+
*/
|
|
29
|
+
declare function TileLayer({ annotations }?: TileLayerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { RenderLayer, RenderLayerProps, TileLayer, TileLayerProps };
|
|
32
|
+
//# sourceMappingURL=render.d.cts.map
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export * from "@embedpdf/plugin-render";
|
|
2
|
+
//#region src/render.d.ts
|
|
3
|
+
interface RenderLayerProps {
|
|
4
|
+
/**
|
|
5
|
+
* Bake annotations into the page bitmap (default true). Pass false when an
|
|
6
|
+
* <AnnotationLayer> owns annotation rendering, so they aren't drawn twice.
|
|
7
|
+
*/
|
|
8
|
+
annotations?: boolean;
|
|
9
|
+
}
|
|
10
|
+
declare function RenderLayer({ annotations }?: RenderLayerProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
interface TileLayerProps {
|
|
12
|
+
/**
|
|
13
|
+
* Bake annotations into tile bitmaps (default true). Pass false when an
|
|
14
|
+
* <AnnotationLayer> owns annotation rendering — the composition that keeps
|
|
15
|
+
* tile artifacts annotation-version-free (CDN-stable across edits).
|
|
16
|
+
*/
|
|
17
|
+
annotations?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* TileLayer — the sharp plane above the base rung.
|
|
21
|
+
*
|
|
22
|
+
* Mounting it is the per-lens OPT-IN; whether it spends anything is demand
|
|
23
|
+
* arithmetic (a thumbnail rail's demand never engages). The paint list is the
|
|
24
|
+
* plugin's retention-safe plan: keyed <img>s inside ONE container that carries
|
|
25
|
+
* the page scale as a single transform (one rounding context — no tile seams),
|
|
26
|
+
* with `onLoad` reporting the decode boundary back so retained coarser
|
|
27
|
+
* generations release only when their replacement is truly on screen.
|
|
28
|
+
*/
|
|
29
|
+
declare function TileLayer({ annotations }?: TileLayerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { RenderLayer, RenderLayerProps, TileLayer, TileLayerProps };
|
|
32
|
+
//# sourceMappingURL=render.d.ts.map
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { useCapability, usePage, useSelector } from "./runtime.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { RenderToken } from "@embedpdf/plugin-render";
|
|
5
|
+
export * from "@embedpdf/plugin-render";
|
|
6
|
+
//#region src/render.tsx
|
|
7
|
+
function RenderLayer({ annotations = true } = {}) {
|
|
8
|
+
const page = usePage();
|
|
9
|
+
const render = useCapability(RenderToken);
|
|
10
|
+
const ref = useRef(null);
|
|
11
|
+
const sourceKey = useSelector(RenderToken, (c) => c.renderSourceKey(page.pon, {
|
|
12
|
+
scale: page.transform.renderScale,
|
|
13
|
+
includeAnnotations: annotations
|
|
14
|
+
}));
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
const controller = new AbortController();
|
|
17
|
+
let revoke;
|
|
18
|
+
(async () => {
|
|
19
|
+
try {
|
|
20
|
+
const obj = await (await render.renderPage(page.pon, {
|
|
21
|
+
scale: page.transform.renderScale,
|
|
22
|
+
includeAnnotations: annotations,
|
|
23
|
+
signal: controller.signal
|
|
24
|
+
})).objectUrl(controller.signal);
|
|
25
|
+
if (controller.signal.aborted) {
|
|
26
|
+
obj.revoke();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
revoke = obj.revoke;
|
|
30
|
+
if (ref.current) ref.current.src = obj.url;
|
|
31
|
+
} catch {}
|
|
32
|
+
})();
|
|
33
|
+
return () => {
|
|
34
|
+
controller.abort();
|
|
35
|
+
revoke?.();
|
|
36
|
+
};
|
|
37
|
+
}, [
|
|
38
|
+
render,
|
|
39
|
+
page.pon,
|
|
40
|
+
sourceKey
|
|
41
|
+
]);
|
|
42
|
+
return /* @__PURE__ */ jsx("img", {
|
|
43
|
+
ref,
|
|
44
|
+
alt: "",
|
|
45
|
+
draggable: false,
|
|
46
|
+
style: {
|
|
47
|
+
position: "absolute",
|
|
48
|
+
inset: 0,
|
|
49
|
+
width: "100%",
|
|
50
|
+
height: "100%",
|
|
51
|
+
pointerEvents: "none"
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* TileLayer — the sharp plane above the base rung.
|
|
57
|
+
*
|
|
58
|
+
* Mounting it is the per-lens OPT-IN; whether it spends anything is demand
|
|
59
|
+
* arithmetic (a thumbnail rail's demand never engages). The paint list is the
|
|
60
|
+
* plugin's retention-safe plan: keyed <img>s inside ONE container that carries
|
|
61
|
+
* the page scale as a single transform (one rounding context — no tile seams),
|
|
62
|
+
* with `onLoad` reporting the decode boundary back so retained coarser
|
|
63
|
+
* generations release only when their replacement is truly on screen.
|
|
64
|
+
*/
|
|
65
|
+
function TileLayer({ annotations = true } = {}) {
|
|
66
|
+
const page = usePage();
|
|
67
|
+
const render = useCapability(RenderToken);
|
|
68
|
+
const demand = page.getViewDemand?.() ?? { desiredDeviceWidth: page.transform.deviceWidth };
|
|
69
|
+
const plan = useSelector(RenderToken, (c) => c.tilePlan(page.pon, demand, { includeAnnotations: annotations }));
|
|
70
|
+
useEffect(() => () => render.releaseTiles(page.pon), [render, page.pon]);
|
|
71
|
+
if (plan.paint.length === 0) return null;
|
|
72
|
+
const t = page.transform;
|
|
73
|
+
const scale = t.viewScale;
|
|
74
|
+
return /* @__PURE__ */ jsx("div", {
|
|
75
|
+
style: {
|
|
76
|
+
position: "absolute",
|
|
77
|
+
left: 0,
|
|
78
|
+
top: 0,
|
|
79
|
+
width: t.contentWidth / scale,
|
|
80
|
+
height: t.contentHeight / scale,
|
|
81
|
+
transform: `scale(${scale})`,
|
|
82
|
+
transformOrigin: "0 0",
|
|
83
|
+
pointerEvents: "none"
|
|
84
|
+
},
|
|
85
|
+
children: plan.paint.map((source) => /* @__PURE__ */ jsx(TileImg, {
|
|
86
|
+
source,
|
|
87
|
+
onPainted: () => render.tilePainted(page.pon, source.key)
|
|
88
|
+
}, source.key))
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
/** One tile: object-URL lifecycle + the painted (decode-boundary) report. */
|
|
92
|
+
function TileImg({ source, onPainted }) {
|
|
93
|
+
const ref = useRef(null);
|
|
94
|
+
useEffect(() => {
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
let revoke;
|
|
97
|
+
(async () => {
|
|
98
|
+
try {
|
|
99
|
+
const obj = await source.handle.objectUrl(controller.signal);
|
|
100
|
+
if (controller.signal.aborted) {
|
|
101
|
+
obj.revoke();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
revoke = obj.revoke;
|
|
105
|
+
if (ref.current) ref.current.src = obj.url;
|
|
106
|
+
} catch {}
|
|
107
|
+
})();
|
|
108
|
+
return () => {
|
|
109
|
+
controller.abort();
|
|
110
|
+
revoke?.();
|
|
111
|
+
};
|
|
112
|
+
}, [source.handle]);
|
|
113
|
+
return /* @__PURE__ */ jsx("img", {
|
|
114
|
+
ref,
|
|
115
|
+
alt: "",
|
|
116
|
+
draggable: false,
|
|
117
|
+
onLoad: onPainted,
|
|
118
|
+
style: {
|
|
119
|
+
position: "absolute",
|
|
120
|
+
left: source.rect.x,
|
|
121
|
+
top: source.rect.y,
|
|
122
|
+
width: source.rect.width,
|
|
123
|
+
height: source.rect.height,
|
|
124
|
+
zIndex: source.z
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
export { RenderLayer, TileLayer };
|
|
130
|
+
|
|
131
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","names":[],"sources":["../src/render.tsx"],"sourcesContent":["/**\n * RenderLayer + TileLayer — the React views of @embedpdf/plugin-render.\n *\n * RenderLayer paints the BASE rung to an <img> from the engine's ENCODED\n * image() (identical for local & cloud). TileLayer paints the tile paint-plan\n * ABOVE it when the deployment lattice caps the base below the demand — mount\n * it per lens (the main stage yes, a thumbnail rail no); where the demand is\n * small it engages nothing. Both are dumb painters: every decision (policy\n * conformance, want sets, retention, release) is plugin-render's.\n */\n\n// One-line-per-feature: registration travels with the UI.\nexport * from '@embedpdf/plugin-render';\nimport * as React from 'react';\nimport { useEffect, useRef } from 'react';\nimport { RenderToken } from '@embedpdf/plugin-render';\nimport type { PageViewDemand, TilePaintSource } from '@embedpdf/plugin-render';\nimport { useCapability, usePage, useSelector } from './runtime';\n\nexport interface RenderLayerProps {\n /**\n * Bake annotations into the page bitmap (default true). Pass false when an\n * <AnnotationLayer> owns annotation rendering, so they aren't drawn twice.\n */\n annotations?: boolean;\n}\n\nexport function RenderLayer({ annotations = true }: RenderLayerProps = {}) {\n const page = usePage();\n const render = useCapability(RenderToken);\n const ref = useRef<HTMLImageElement>(null);\n // ONE dependency: the raster's canonical identity — conformed viewport +\n // annotations flag + epoch. Inside a lattice\n // rung, zoom changes don't move it: no refetch, no DOM churn — the stage's\n // CSS transform does the scaling. It changes exactly at rung crossings and\n // on CONFIRMED mutations (epoch bumps at commit, never mid-gesture). Under\n // `continuous` it embeds the exact scale — v2 behavior byte-for-byte. The\n // policy behind it is a document fact the kernel materialized before\n // publish, so the key is always computable.\n const sourceKey = useSelector(RenderToken, (c) =>\n c.renderSourceKey(page.pon, {\n scale: page.transform.renderScale,\n includeAnnotations: annotations,\n }),\n );\n useEffect(() => {\n const controller = new AbortController();\n let revoke: (() => void) | undefined;\n (async () => {\n try {\n // The capability conforms this to the policy (lattice → ladder width,\n // continuous → this exact scale) and collapses same-key asks in its\n // raster store. A stale-closure scale is harmless by construction:\n // any scale in this rung produces this key's canonical request.\n const image = await render.renderPage(page.pon, {\n scale: page.transform.renderScale,\n includeAnnotations: annotations,\n signal: controller.signal,\n });\n const obj = await image.objectUrl(controller.signal);\n if (controller.signal.aborted) {\n obj.revoke();\n return;\n }\n revoke = obj.revoke;\n if (ref.current) ref.current.src = obj.url;\n } catch {\n /* aborted (camera moved / unmounted) or render failed */\n }\n })();\n return () => {\n controller.abort();\n revoke?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- sourceKey IS the\n // render identity; scale/annotations/epoch are folded into it upstream.\n }, [render, page.pon, sourceKey]);\n return (\n <img\n ref={ref}\n alt=\"\"\n draggable={false}\n style={{\n position: 'absolute',\n inset: 0,\n width: '100%',\n height: '100%',\n pointerEvents: 'none',\n }}\n />\n );\n}\n\nexport interface TileLayerProps {\n /**\n * Bake annotations into tile bitmaps (default true). Pass false when an\n * <AnnotationLayer> owns annotation rendering — the composition that keeps\n * tile artifacts annotation-version-free (CDN-stable across edits).\n */\n annotations?: boolean;\n}\n\n/**\n * TileLayer — the sharp plane above the base rung.\n *\n * Mounting it is the per-lens OPT-IN; whether it spends anything is demand\n * arithmetic (a thumbnail rail's demand never engages). The paint list is the\n * plugin's retention-safe plan: keyed <img>s inside ONE container that carries\n * the page scale as a single transform (one rounding context — no tile seams),\n * with `onLoad` reporting the decode boundary back so retained coarser\n * generations release only when their replacement is truly on screen.\n */\nexport function TileLayer({ annotations = true }: TileLayerProps = {}) {\n const page = usePage();\n const render = useCapability(RenderToken);\n // Demand: the host's live camera view (Stage) or whole-page (PageView).\n const demand: PageViewDemand = page.getViewDemand?.() ?? {\n desiredDeviceWidth: page.transform.deviceWidth,\n };\n const plan = useSelector(RenderToken, (c) =>\n c.tilePlan(page.pon, demand, { includeAnnotations: annotations }),\n );\n // Lens unmounted: stop in-flight tile fetches; resolved bytes stay cached.\n useEffect(() => () => render.releaseTiles(page.pon), [render, page.pon]);\n if (plan.paint.length === 0) return null;\n const t = page.transform;\n const scale = t.viewScale;\n return (\n <div\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n width: t.contentWidth / scale,\n height: t.contentHeight / scale,\n transform: `scale(${scale})`,\n transformOrigin: '0 0',\n pointerEvents: 'none',\n }}\n >\n {plan.paint.map((source) => (\n <TileImg\n key={source.key}\n source={source}\n onPainted={() => render.tilePainted(page.pon, source.key)}\n />\n ))}\n </div>\n );\n}\n\n/** One tile: object-URL lifecycle + the painted (decode-boundary) report. */\nfunction TileImg({ source, onPainted }: { source: TilePaintSource; onPainted: () => void }) {\n const ref = useRef<HTMLImageElement>(null);\n useEffect(() => {\n const controller = new AbortController();\n let revoke: (() => void) | undefined;\n (async () => {\n try {\n const obj = await source.handle.objectUrl(controller.signal);\n if (controller.signal.aborted) {\n obj.revoke();\n return;\n }\n revoke = obj.revoke;\n if (ref.current) ref.current.src = obj.url;\n } catch {\n /* aborted (plan moved on) */\n }\n })();\n return () => {\n controller.abort();\n revoke?.();\n };\n }, [source.handle]);\n return (\n <img\n ref={ref}\n alt=\"\"\n draggable={false}\n onLoad={onPainted}\n style={{\n position: 'absolute',\n left: source.rect.x,\n top: source.rect.y,\n width: source.rect.width,\n height: source.rect.height,\n zIndex: source.z,\n }}\n />\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __exportAll = (all, no_symbols) => {
|
|
9
|
+
let target = {};
|
|
10
|
+
for (var name in all) __defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
15
|
+
return target;
|
|
16
|
+
};
|
|
17
|
+
var __copyProps = (to, from, except, desc) => {
|
|
18
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
19
|
+
key = keys[i];
|
|
20
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
21
|
+
get: ((k) => from[k]).bind(null, key),
|
|
22
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
29
|
+
value: mod,
|
|
30
|
+
enumerable: true
|
|
31
|
+
}) : target, mod));
|
|
32
|
+
//#endregion
|
|
33
|
+
Object.defineProperty(exports, "__exportAll", {
|
|
34
|
+
enumerable: true,
|
|
35
|
+
get: function() {
|
|
36
|
+
return __exportAll;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
Object.defineProperty(exports, "__reExport", {
|
|
40
|
+
enumerable: true,
|
|
41
|
+
get: function() {
|
|
42
|
+
return __reExport;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
Object.defineProperty(exports, "__toESM", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
get: function() {
|
|
48
|
+
return __toESM;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { AnyPlugin, CapabilityToken, Engine, EngineFactory, InitialDocument, Kernel } from "@embedpdf/core";
|
|
3
|
+
import { PageFrame, PageTransform, Point, Rect } from "@embedpdf/core-geometry";
|
|
4
|
+
import { PageViewDemand } from "@embedpdf/plugin-render";
|
|
5
|
+
//#region src/runtime.d.ts
|
|
6
|
+
declare function useKernel(): Kernel;
|
|
7
|
+
declare const shallowArray: <T>(a: readonly T[], b: readonly T[]) => boolean;
|
|
8
|
+
/** Read a value derived from the kernel, cached by equality (no tearing loop). */
|
|
9
|
+
declare function useKernelValue<R>(select: (k: Kernel) => R, isEqual?: (a: R, b: R) => boolean): R;
|
|
10
|
+
declare function useActiveDocumentId(): string | null;
|
|
11
|
+
/** The document id for this subtree: the nearest <DocumentScope>, else the active doc. */
|
|
12
|
+
declare function useDocumentId(): string | null;
|
|
13
|
+
interface DocumentScopeProps {
|
|
14
|
+
id: string;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/** Bind a subtree to a specific document (panes, comparison). */
|
|
18
|
+
declare function DocumentScope({ id, children }: DocumentScopeProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
interface DocumentGateProps {
|
|
20
|
+
/** Shown while this subtree has NO document (empty workspace, docs still opening). */
|
|
21
|
+
fallback?: React.ReactNode;
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Render children only while this subtree has a READY document — the
|
|
26
|
+
* structural way to say "this UI is defined over a document". An empty
|
|
27
|
+
* workspace is a legitimate, designable state (the Viewer no longer blocks on
|
|
28
|
+
* documents so chrome can render at t≈0): workspace-scoped UI (toolbars,
|
|
29
|
+
* commands, i18n) lives OUTSIDE the gate; document-scoped UI (Stage, panels,
|
|
30
|
+
* page chrome) lives inside it, or reads through `useOptionalSelector`.
|
|
31
|
+
* A `loading`/`locked`/`error` tab renders `fallback` — so the gate's
|
|
32
|
+
* fallback doubles as the per-tab boot state; richer chrome (a password
|
|
33
|
+
* prompt, an error pane) branches on `useDocumentStatus()` beside the gate.
|
|
34
|
+
* Sibling of <DocumentScope>, which picks WHICH document; this one handles
|
|
35
|
+
* WHETHER.
|
|
36
|
+
*/
|
|
37
|
+
declare function DocumentGate({ fallback, children }: DocumentGateProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
/** Lifecycle status of this subtree's document (loading/locked/ready/error),
|
|
39
|
+
* or null with no document. The password prompt and error panes key off it. */
|
|
40
|
+
declare function useDocumentStatus(): import("@embedpdf/core").DocStatus | null;
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a capability by token, binding document-scoped ones to this
|
|
43
|
+
* subtree's document. Resolution is a REACTIVE read (`tryCapability` through
|
|
44
|
+
* the kernel's one change stream), not a memoized call — under the
|
|
45
|
+
* request-time lifecycle a document can become resolvable while its id stays
|
|
46
|
+
* the same, so any id-keyed cache goes stale; subscribing makes staleness
|
|
47
|
+
* structurally impossible. Fail-fast: while unresolvable, this re-runs the
|
|
48
|
+
* strict resolver so the kernel's truthful reason (`no capability` / `no
|
|
49
|
+
* document` / `document is loading|locked`) is what throws.
|
|
50
|
+
*/
|
|
51
|
+
declare function useCapability<T>(token: CapabilityToken<T>): T;
|
|
52
|
+
/** Like `useCapability`, but null while the token can't resolve (no plugin,
|
|
53
|
+
* no document, or a document that isn't ready yet). */
|
|
54
|
+
declare function useOptionalCapability<T>(token: CapabilityToken<T>): T | null;
|
|
55
|
+
/** Subscribe to a selector over a (document-resolved) capability. */
|
|
56
|
+
declare function useSelector<C, R>(token: CapabilityToken<C>, select: (cap: C) => R, isEqual?: (a: R, b: R) => boolean): R;
|
|
57
|
+
/**
|
|
58
|
+
* Null-safe `useSelector`: `fallback` whenever the token can't resolve — no
|
|
59
|
+
* provider, or a document-scoped token with no document. For chrome that stays
|
|
60
|
+
* mounted across the empty-workspace state (a zoom readout, a mode band).
|
|
61
|
+
* `useSelector` stays strict (fail-fast) for code that KNOWS a document exists
|
|
62
|
+
* — e.g. anything inside a <DocumentGate>.
|
|
63
|
+
*
|
|
64
|
+
* The `select` guard also swallows reads through a capability whose document
|
|
65
|
+
* closed between the store notification and this render — that teardown race
|
|
66
|
+
* resolves to `fallback` for one frame, then re-renders against the new state.
|
|
67
|
+
*/
|
|
68
|
+
declare function useOptionalSelector<C, R>(token: CapabilityToken<C>, select: (cap: C) => R, fallback: R, isEqual?: (a: R, b: R) => boolean): R;
|
|
69
|
+
/** The document registry (open/close/active/list), reactive. */
|
|
70
|
+
declare function useDocuments(): {
|
|
71
|
+
docs: import("@embedpdf/core").DocInfo[];
|
|
72
|
+
activeId: string | null;
|
|
73
|
+
open: (input: import("@embedpdf/core").OpenSource, options?: import("@embedpdf/core").OpenDocumentOptions) => Promise<string>;
|
|
74
|
+
unlock: (id: string, input: {
|
|
75
|
+
password: string;
|
|
76
|
+
}) => Promise<void>;
|
|
77
|
+
close: (id: string) => Promise<void>;
|
|
78
|
+
setActive: (id: string) => void;
|
|
79
|
+
move: (id: string, toIndex: number) => void;
|
|
80
|
+
swap: (a: string, b: string) => void;
|
|
81
|
+
download: (id?: string, opts?: {
|
|
82
|
+
mode?: import("@embedpdf/core").PdfSaveMode;
|
|
83
|
+
}) => Promise<Uint8Array>;
|
|
84
|
+
downloadLayer: (id?: string) => Promise<Uint8Array>;
|
|
85
|
+
};
|
|
86
|
+
interface ViewerProps {
|
|
87
|
+
/**
|
|
88
|
+
* The engine, as an instance or a thunk. Engines construct synchronously and
|
|
89
|
+
* boot lazily (`localEngine()` allocates nothing until first use), so
|
|
90
|
+
* ownership follows the SHAPE of what you pass:
|
|
91
|
+
*
|
|
92
|
+
* - An **instance** (`engine={engine}`) is BORROWED: the Viewer uses it and
|
|
93
|
+
* never destroys it, because you acquired it and therefore own it. The
|
|
94
|
+
* common path — a module-scope `const engine = localEngine()` shared
|
|
95
|
+
* across viewers and route changes. The Viewer calls `engine.warmup?.()`
|
|
96
|
+
* on mount so the boot overlaps app initialization.
|
|
97
|
+
* - A **thunk** (`engine={() => localEngine()}`) is VIEWER-OWNED: the
|
|
98
|
+
* Viewer calls it on mount and `destroy()`s the result on unmount. Use it
|
|
99
|
+
* for per-mount isolation (StrictMode/HMR-clean teardown, independent
|
|
100
|
+
* multi-viewer engines).
|
|
101
|
+
*
|
|
102
|
+
* Init-only: captured on first render; later identity changes are ignored (dev warns).
|
|
103
|
+
*/
|
|
104
|
+
engine: Engine | EngineFactory;
|
|
105
|
+
/** Init-only: captured on first render; later identity changes are ignored (dev warns). */
|
|
106
|
+
plugins: AnyPlugin[];
|
|
107
|
+
/** Documents to open on startup (with optional tab names). Init-only. */
|
|
108
|
+
initialDocuments?: InitialDocument[];
|
|
109
|
+
fallback?: React.ReactNode;
|
|
110
|
+
/** Rendered when kernel construction or `start()` fails. Without it a boot
|
|
111
|
+
* failure renders nothing — but never a silent forever-fallback. */
|
|
112
|
+
renderError?: (error: unknown) => React.ReactNode;
|
|
113
|
+
children: React.ReactNode;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Owns the kernel as an EFFECT-scoped resource: each effect setup creates and
|
|
117
|
+
* starts exactly one kernel; each cleanup destroys exactly that one. That is
|
|
118
|
+
* the contract StrictMode exercises (two kernels in dev, the first fully
|
|
119
|
+
* destroyed) — the kernel itself is never restarted after destroy.
|
|
120
|
+
*
|
|
121
|
+
* The kernel is published to context the moment it exists — before `start()`
|
|
122
|
+
* resolves — so the `fallback` can use workspace capabilities (i18n copy on a
|
|
123
|
+
* loading screen) exactly as before. The one exception is the very first
|
|
124
|
+
* render, which happens before the effect: it renders nothing. Children mount
|
|
125
|
+
* once `start()` resolves — which never touches the engine, so the shell is
|
|
126
|
+
* alive while WASM compiles or the transport connects. `initialDocuments`
|
|
127
|
+
* open in the BACKGROUND and stream into the registry (`useDocuments()` is
|
|
128
|
+
* reactive); per-document loading UI is the Stage's job, not a root gate.
|
|
129
|
+
*
|
|
130
|
+
* ENGINE OWNERSHIP. When `engine` is a thunk, the Viewer OWNS it: each effect
|
|
131
|
+
* setup constructs one engine (construction is synchronous and inert — boot
|
|
132
|
+
* happens lazily inside the engine) and each cleanup destroys exactly that one
|
|
133
|
+
* — after the kernel, so handles close first. When `engine` is an instance it
|
|
134
|
+
* is BORROWED and never destroyed here; the Viewer only calls `warmup?.()` so
|
|
135
|
+
* the WASM/transport boot overlaps plugin initialization. StrictMode's
|
|
136
|
+
* double-mount therefore constructs two independent thunk engines and tears
|
|
137
|
+
* the first fully down, matching the kernel's own effect-scoped lifecycle.
|
|
138
|
+
* That means dev-only double resource use (two worker spawns, two font
|
|
139
|
+
* fetches, briefly overlapping) — deliberate, because it is exactly the
|
|
140
|
+
* leak-detection contract StrictMode exists to exercise; production mounts
|
|
141
|
+
* once and boots once.
|
|
142
|
+
*/
|
|
143
|
+
declare function Viewer({ engine, plugins, initialDocuments, fallback, renderError, children }: ViewerProps): import("react/jsx-runtime").JSX.Element | null;
|
|
144
|
+
declare const EmbedPDF: typeof Viewer;
|
|
145
|
+
/**
|
|
146
|
+
* PageContext — the seam. A layer depends ONLY on this, never on the Stage. So the
|
|
147
|
+
* same layer works inside a virtualized Stage and in a standalone <PageView>.
|
|
148
|
+
*/
|
|
149
|
+
interface PageContextValue {
|
|
150
|
+
documentId: string;
|
|
151
|
+
/** Durable page identity (PDF object number) — use for keys / render / annotations. */
|
|
152
|
+
pon: number;
|
|
153
|
+
/** Display index (page N) — use for ordering / human-facing page numbers. */
|
|
154
|
+
pageIndex: number;
|
|
155
|
+
/**
|
|
156
|
+
* Reserved chrome bands around the page (screen px per side). The page-chrome
|
|
157
|
+
* slot renders into the outer box (content + frame); these thicknesses size
|
|
158
|
+
* the bands — a label in the bottom band is `bottom:0; height: frame.bottom`.
|
|
159
|
+
*/
|
|
160
|
+
frame: PageFrame;
|
|
161
|
+
/**
|
|
162
|
+
* The single bridge between PDF points, view px, and device px for this page.
|
|
163
|
+
* Layers do ALL coordinate work through it — `pageToContent` to place content-
|
|
164
|
+
* space overlays, `renderScale`/`deviceWidth` to render, `contentWidth` for
|
|
165
|
+
* page-relative sizing. Never re-derive `x * scale` or `* dpr`.
|
|
166
|
+
*/
|
|
167
|
+
transform: PageTransform;
|
|
168
|
+
/** Client (screen) point → PDF point — the one platform-bound hit-test. */
|
|
169
|
+
toPagePoint(clientX: number, clientY: number): Point;
|
|
170
|
+
/** PDF/content point → client (screen) px — the exact inverse of `toPagePoint`
|
|
171
|
+
* (rotation applied). Lets viewport-space UI (e.g. a selection menu) anchor to a
|
|
172
|
+
* page point WITHOUT a Stage camera, so it works the same in `<PageView>`. */
|
|
173
|
+
toClientPoint(p: Point): Point;
|
|
174
|
+
/** PDF/content rect → client (screen) px AABB. Rect analog of `toClientPoint`
|
|
175
|
+
* for upright viewport-space UI that frames a selected page region. */
|
|
176
|
+
toClientRect(rect: Rect): Rect;
|
|
177
|
+
/**
|
|
178
|
+
* The page-view DEMAND for raster planning uses dependency inversion:
|
|
179
|
+
* plugin-render defines the shape; the host that CREATED this
|
|
180
|
+
* context fills it — as a PULL. The Stage host's getter closes over the
|
|
181
|
+
* stage capability and reads `VisiblePage.visibleRect` live at call time
|
|
182
|
+
* (visibility is the STAGE's data; adapters never re-derive camera math or
|
|
183
|
+
* cache a copy). Three states, three meanings: a real sub-rect (visible),
|
|
184
|
+
* a ZERO rect (stage host, page currently off-screen — want nothing), and
|
|
185
|
+
* an undefined getter (stage-less `<PageView>` — whole page visible, which
|
|
186
|
+
* a thumbnail-sized demand turns into "never engages" by arithmetic).
|
|
187
|
+
*/
|
|
188
|
+
getViewDemand?: () => PageViewDemand;
|
|
189
|
+
}
|
|
190
|
+
declare const PageProvider: React.Provider<PageContextValue | null>;
|
|
191
|
+
declare function usePage(): PageContextValue;
|
|
192
|
+
declare function makePageContext(documentId: string, pon: number, pageIndex: number, frame: PageFrame, transform: PageTransform, getRect: () => DOMRect, getViewDemand?: () => PageViewDemand): PageContextValue;
|
|
193
|
+
//#endregion
|
|
194
|
+
export { useSelector as S, useKernel as _, EmbedPDF as a, useOptionalSelector as b, Viewer as c, shallowArray as d, useActiveDocumentId as f, useDocuments as g, useDocumentStatus as h, DocumentScopeProps as i, ViewerProps as l, useDocumentId as m, DocumentGateProps as n, PageContextValue as o, useCapability as p, DocumentScope as r, PageProvider as s, DocumentGate as t, makePageContext as u, useKernelValue as v, usePage as x, useOptionalCapability as y };
|
|
195
|
+
//# sourceMappingURL=runtime-CMxIuF2O.d.cts.map
|