@embedpdf/plugin-page-edit 3.0.0-next.10 → 3.0.0-next.12

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.
@@ -0,0 +1,82 @@
1
+ import { AbortablePromise, PageDeleteResult, PageInsertResult, PageMoveResult, PageObjectNumber, PageRotateResult, PageRotation, PdfSize } from "@embedpdf/core";
2
+ //#region src/types.d.ts
3
+ /**
4
+ * Where added pages land. The PON anchors are the thumbnail gestures ("+
5
+ * after this page") and stay correct across a concurrent reorder between
6
+ * click and call — a raw index does not; `index` remains for absolute
7
+ * positions ("at the start"). Omitted → append. Resolved to the engine's
8
+ * index wire by the capability at call time, from the registry.
9
+ */
10
+ type PagePlacement = {
11
+ after: PageObjectNumber;
12
+ } | {
13
+ before: PageObjectNumber;
14
+ } | {
15
+ index: number;
16
+ };
17
+ /**
18
+ * Structural page edits, addressed by durable PON (never display index — an
19
+ * index shifts the moment a sibling is moved or deleted). Mirrors the engine's
20
+ * `DocumentPagesService` 1:1, with one addition the engine can't have: the
21
+ * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a
22
+ * "+90° on this thumbnail" click into an absolute value needs the page's
23
+ * current rotation, so that read+arithmetic lives HERE — once — instead of
24
+ * being re-derived in every framework adapter's click handler.
25
+ *
26
+ * Document-scoped: rotation is shared document metadata, so editing through the
27
+ * sidebar lens and seeing it in the main lens is automatic (both read the same
28
+ * registry, which the kernel keeps in sync from the engine's event stream).
29
+ */
30
+ interface PageEditCapability {
31
+ /**
32
+ * Whether this caller is authorized to perform structural page edits —
33
+ * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate
34
+ * ALL their edit affordances on this, the add verbs included (rotate,
35
+ * move, delete, addBlank, and insert share the one capability); the
36
+ * engine independently enforces the same capability and throws
37
+ * `PermissionDenied` if a call slips through.
38
+ */
39
+ canEdit(): boolean;
40
+ /**
41
+ * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button
42
+ * gesture. Reads the page's current rotation from the registry and forwards
43
+ * the resulting absolute rotation to the engine.
44
+ */
45
+ rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;
46
+ /**
47
+ * Set the ABSOLUTE rotation of one or more pages to a single shared value —
48
+ * the multi-select gesture. Maps 1:1 to the engine.
49
+ */
50
+ setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;
51
+ /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */
52
+ move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;
53
+ /** Delete pages by PON. The engine rejects deleting every page. */
54
+ delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;
55
+ /**
56
+ * Create blank pages — gate the affordance on `canEdit()`, like every
57
+ * other structure verb (the add verbs share the `doc.pages.assemble`
58
+ * capability and are mandatory on the engine contract). `size` defaults
59
+ * to the page the new pages sit beside — the anchor for PON placements,
60
+ * else the insertion point's predecessor, else the last page — so "add
61
+ * page" matches the document without an A4-vs-Letter guess. That default
62
+ * is a registry read, which is why it lives HERE and the engine wire
63
+ * stays explicit (the `rotateBy` law). `count` defaults to 1.
64
+ */
65
+ addBlank(opts?: {
66
+ size?: PdfSize;
67
+ count?: number;
68
+ placement?: PagePlacement;
69
+ }): AbortablePromise<PageInsertResult>;
70
+ /**
71
+ * Copy every page of a standalone PDF (`bytes`) in at the placement —
72
+ * the merge/import gesture. Forwards to `pages.insert`; the inserted
73
+ * copies get fresh PONs, returned in insertion order.
74
+ */
75
+ insert(bytes: Uint8Array | ArrayBuffer, opts?: {
76
+ placement?: PagePlacement;
77
+ }): AbortablePromise<PageInsertResult>;
78
+ }
79
+ declare const PageEditToken: import("@embedpdf/core").CapabilityToken<PageEditCapability>;
80
+ //#endregion
81
+ export { PageEditToken as n, PageEditCapability as t };
82
+ //# sourceMappingURL=contract-BnXi11KD.d.cts.map
@@ -0,0 +1,82 @@
1
+ import { AbortablePromise, PageDeleteResult, PageInsertResult, PageMoveResult, PageObjectNumber, PageRotateResult, PageRotation, PdfSize } from "@embedpdf/core";
2
+ //#region src/types.d.ts
3
+ /**
4
+ * Where added pages land. The PON anchors are the thumbnail gestures ("+
5
+ * after this page") and stay correct across a concurrent reorder between
6
+ * click and call — a raw index does not; `index` remains for absolute
7
+ * positions ("at the start"). Omitted → append. Resolved to the engine's
8
+ * index wire by the capability at call time, from the registry.
9
+ */
10
+ type PagePlacement = {
11
+ after: PageObjectNumber;
12
+ } | {
13
+ before: PageObjectNumber;
14
+ } | {
15
+ index: number;
16
+ };
17
+ /**
18
+ * Structural page edits, addressed by durable PON (never display index — an
19
+ * index shifts the moment a sibling is moved or deleted). Mirrors the engine's
20
+ * `DocumentPagesService` 1:1, with one addition the engine can't have: the
21
+ * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a
22
+ * "+90° on this thumbnail" click into an absolute value needs the page's
23
+ * current rotation, so that read+arithmetic lives HERE — once — instead of
24
+ * being re-derived in every framework adapter's click handler.
25
+ *
26
+ * Document-scoped: rotation is shared document metadata, so editing through the
27
+ * sidebar lens and seeing it in the main lens is automatic (both read the same
28
+ * registry, which the kernel keeps in sync from the engine's event stream).
29
+ */
30
+ interface PageEditCapability {
31
+ /**
32
+ * Whether this caller is authorized to perform structural page edits —
33
+ * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate
34
+ * ALL their edit affordances on this, the add verbs included (rotate,
35
+ * move, delete, addBlank, and insert share the one capability); the
36
+ * engine independently enforces the same capability and throws
37
+ * `PermissionDenied` if a call slips through.
38
+ */
39
+ canEdit(): boolean;
40
+ /**
41
+ * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button
42
+ * gesture. Reads the page's current rotation from the registry and forwards
43
+ * the resulting absolute rotation to the engine.
44
+ */
45
+ rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;
46
+ /**
47
+ * Set the ABSOLUTE rotation of one or more pages to a single shared value —
48
+ * the multi-select gesture. Maps 1:1 to the engine.
49
+ */
50
+ setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;
51
+ /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */
52
+ move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;
53
+ /** Delete pages by PON. The engine rejects deleting every page. */
54
+ delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;
55
+ /**
56
+ * Create blank pages — gate the affordance on `canEdit()`, like every
57
+ * other structure verb (the add verbs share the `doc.pages.assemble`
58
+ * capability and are mandatory on the engine contract). `size` defaults
59
+ * to the page the new pages sit beside — the anchor for PON placements,
60
+ * else the insertion point's predecessor, else the last page — so "add
61
+ * page" matches the document without an A4-vs-Letter guess. That default
62
+ * is a registry read, which is why it lives HERE and the engine wire
63
+ * stays explicit (the `rotateBy` law). `count` defaults to 1.
64
+ */
65
+ addBlank(opts?: {
66
+ size?: PdfSize;
67
+ count?: number;
68
+ placement?: PagePlacement;
69
+ }): AbortablePromise<PageInsertResult>;
70
+ /**
71
+ * Copy every page of a standalone PDF (`bytes`) in at the placement —
72
+ * the merge/import gesture. Forwards to `pages.insert`; the inserted
73
+ * copies get fresh PONs, returned in insertion order.
74
+ */
75
+ insert(bytes: Uint8Array | ArrayBuffer, opts?: {
76
+ placement?: PagePlacement;
77
+ }): AbortablePromise<PageInsertResult>;
78
+ }
79
+ declare const PageEditToken: import("@embedpdf/core").CapabilityToken<PageEditCapability>;
80
+ //#endregion
81
+ export { PageEditToken as n, PageEditCapability as t };
82
+ //# sourceMappingURL=contract-BnXi11KD.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { createCapabilityToken } from "@embedpdf/core";
2
+ //#region src/types.ts
3
+ const PageEditToken = createCapabilityToken("page-edit");
4
+ //#endregion
5
+ export { PageEditToken as t };
6
+
7
+ //# sourceMappingURL=contract-BsNelyd8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-BsNelyd8.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["import {\n createCapabilityToken,\n type AbortablePromise,\n type PageObjectNumber,\n type PageRotation,\n type PageRotateResult,\n type PageMoveResult,\n type PageDeleteResult,\n type PageInsertResult,\n type PdfSize,\n} from '@embedpdf/core';\n\n/**\n * Where added pages land. The PON anchors are the thumbnail gestures (\"+\n * after this page\") and stay correct across a concurrent reorder between\n * click and call — a raw index does not; `index` remains for absolute\n * positions (\"at the start\"). Omitted → append. Resolved to the engine's\n * index wire by the capability at call time, from the registry.\n */\nexport type PagePlacement =\n | { after: PageObjectNumber }\n | { before: PageObjectNumber }\n | { index: number };\n\n/**\n * Structural page edits, addressed by durable PON (never display index — an\n * index shifts the moment a sibling is moved or deleted). Mirrors the engine's\n * `DocumentPagesService` 1:1, with one addition the engine can't have: the\n * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a\n * \"+90° on this thumbnail\" click into an absolute value needs the page's\n * current rotation, so that read+arithmetic lives HERE — once — instead of\n * being re-derived in every framework adapter's click handler.\n *\n * Document-scoped: rotation is shared document metadata, so editing through the\n * sidebar lens and seeing it in the main lens is automatic (both read the same\n * registry, which the kernel keeps in sync from the engine's event stream).\n */\nexport interface PageEditCapability {\n /**\n * Whether this caller is authorized to perform structural page edits —\n * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate\n * ALL their edit affordances on this, the add verbs included (rotate,\n * move, delete, addBlank, and insert share the one capability); the\n * engine independently enforces the same capability and throws\n * `PermissionDenied` if a call slips through.\n */\n canEdit(): boolean;\n\n /**\n * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button\n * gesture. Reads the page's current rotation from the registry and forwards\n * the resulting absolute rotation to the engine.\n */\n rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;\n\n /**\n * Set the ABSOLUTE rotation of one or more pages to a single shared value —\n * the multi-select gesture. Maps 1:1 to the engine.\n */\n setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;\n\n /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */\n move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;\n\n /** Delete pages by PON. The engine rejects deleting every page. */\n delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;\n\n /**\n * Create blank pages — gate the affordance on `canEdit()`, like every\n * other structure verb (the add verbs share the `doc.pages.assemble`\n * capability and are mandatory on the engine contract). `size` defaults\n * to the page the new pages sit beside — the anchor for PON placements,\n * else the insertion point's predecessor, else the last page — so \"add\n * page\" matches the document without an A4-vs-Letter guess. That default\n * is a registry read, which is why it lives HERE and the engine wire\n * stays explicit (the `rotateBy` law). `count` defaults to 1.\n */\n addBlank(opts?: {\n size?: PdfSize;\n count?: number;\n placement?: PagePlacement;\n }): AbortablePromise<PageInsertResult>;\n\n /**\n * Copy every page of a standalone PDF (`bytes`) in at the placement —\n * the merge/import gesture. Forwards to `pages.insert`; the inserted\n * copies get fresh PONs, returned in insertion order.\n */\n insert(\n bytes: Uint8Array | ArrayBuffer,\n opts?: { placement?: PagePlacement },\n ): AbortablePromise<PageInsertResult>;\n}\n\nexport const PageEditToken = createCapabilityToken<PageEditCapability>('page-edit');\n"],"mappings":";;AA8FA,MAAa,gBAAgB,sBAA0C,WAAW"}
@@ -0,0 +1,11 @@
1
+ //#region src/types.ts
2
+ const PageEditToken = (0, require("@embedpdf/core").createCapabilityToken)("page-edit");
3
+ //#endregion
4
+ Object.defineProperty(exports, "PageEditToken", {
5
+ enumerable: true,
6
+ get: function() {
7
+ return PageEditToken;
8
+ }
9
+ });
10
+
11
+ //# sourceMappingURL=contract-UeGRCn-t.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-UeGRCn-t.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["import {\n createCapabilityToken,\n type AbortablePromise,\n type PageObjectNumber,\n type PageRotation,\n type PageRotateResult,\n type PageMoveResult,\n type PageDeleteResult,\n type PageInsertResult,\n type PdfSize,\n} from '@embedpdf/core';\n\n/**\n * Where added pages land. The PON anchors are the thumbnail gestures (\"+\n * after this page\") and stay correct across a concurrent reorder between\n * click and call — a raw index does not; `index` remains for absolute\n * positions (\"at the start\"). Omitted → append. Resolved to the engine's\n * index wire by the capability at call time, from the registry.\n */\nexport type PagePlacement =\n | { after: PageObjectNumber }\n | { before: PageObjectNumber }\n | { index: number };\n\n/**\n * Structural page edits, addressed by durable PON (never display index — an\n * index shifts the moment a sibling is moved or deleted). Mirrors the engine's\n * `DocumentPagesService` 1:1, with one addition the engine can't have: the\n * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a\n * \"+90° on this thumbnail\" click into an absolute value needs the page's\n * current rotation, so that read+arithmetic lives HERE — once — instead of\n * being re-derived in every framework adapter's click handler.\n *\n * Document-scoped: rotation is shared document metadata, so editing through the\n * sidebar lens and seeing it in the main lens is automatic (both read the same\n * registry, which the kernel keeps in sync from the engine's event stream).\n */\nexport interface PageEditCapability {\n /**\n * Whether this caller is authorized to perform structural page edits —\n * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate\n * ALL their edit affordances on this, the add verbs included (rotate,\n * move, delete, addBlank, and insert share the one capability); the\n * engine independently enforces the same capability and throws\n * `PermissionDenied` if a call slips through.\n */\n canEdit(): boolean;\n\n /**\n * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button\n * gesture. Reads the page's current rotation from the registry and forwards\n * the resulting absolute rotation to the engine.\n */\n rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;\n\n /**\n * Set the ABSOLUTE rotation of one or more pages to a single shared value —\n * the multi-select gesture. Maps 1:1 to the engine.\n */\n setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;\n\n /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */\n move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;\n\n /** Delete pages by PON. The engine rejects deleting every page. */\n delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;\n\n /**\n * Create blank pages — gate the affordance on `canEdit()`, like every\n * other structure verb (the add verbs share the `doc.pages.assemble`\n * capability and are mandatory on the engine contract). `size` defaults\n * to the page the new pages sit beside — the anchor for PON placements,\n * else the insertion point's predecessor, else the last page — so \"add\n * page\" matches the document without an A4-vs-Letter guess. That default\n * is a registry read, which is why it lives HERE and the engine wire\n * stays explicit (the `rotateBy` law). `count` defaults to 1.\n */\n addBlank(opts?: {\n size?: PdfSize;\n count?: number;\n placement?: PagePlacement;\n }): AbortablePromise<PageInsertResult>;\n\n /**\n * Copy every page of a standalone PDF (`bytes`) in at the placement —\n * the merge/import gesture. Forwards to `pages.insert`; the inserted\n * copies get fresh PONs, returned in insertion order.\n */\n insert(\n bytes: Uint8Array | ArrayBuffer,\n opts?: { placement?: PagePlacement },\n ): AbortablePromise<PageInsertResult>;\n}\n\nexport const PageEditToken = createCapabilityToken<PageEditCapability>('page-edit');\n"],"mappings":";AA8FA,MAAa,iBAAA,2BAAA,CAAA,CAAA,sBAAA,CAA0D,WAAW"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_contract = require("./contract-UeGRCn-t.cjs");
3
+ exports.PageEditToken = require_contract.PageEditToken;
@@ -0,0 +1,2 @@
1
+ import { n as PageEditToken, t as PageEditCapability } from "./contract-BnXi11KD.cjs";
2
+ export { type PageEditCapability, PageEditToken };
@@ -0,0 +1,2 @@
1
+ import { n as PageEditToken, t as PageEditCapability } from "./contract-BnXi11KD.js";
2
+ export { type PageEditCapability, PageEditToken };
@@ -0,0 +1,2 @@
1
+ import { t as PageEditToken } from "./contract-BsNelyd8.js";
2
+ export { PageEditToken };
package/dist/index.cjs CHANGED
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_contract = require("./contract-UeGRCn-t.cjs");
2
3
  let _embedpdf_core = require("@embedpdf/core");
3
4
  //#region src/capability.ts
4
5
  /**
@@ -97,9 +98,6 @@ function createPageEditCapability(ctx) {
97
98
  };
98
99
  }
99
100
  //#endregion
100
- //#region src/types.ts
101
- const PageEditToken = (0, _embedpdf_core.createCapabilityToken)("page-edit");
102
- //#endregion
103
101
  //#region src/page-edit.plugin.ts
104
102
  /**
105
103
  * Document-scoped, stateless: turns the engine handle's page service into a
@@ -111,11 +109,11 @@ const PageEditToken = (0, _embedpdf_core.createCapabilityToken)("page-edit");
111
109
  const pageEditPlugin = () => (0, _embedpdf_core.definePlugin)({
112
110
  id: "page-edit",
113
111
  scope: "document",
114
- token: PageEditToken,
112
+ token: require_contract.PageEditToken,
115
113
  capability: createPageEditCapability
116
114
  });
117
115
  //#endregion
118
- exports.PageEditToken = PageEditToken;
116
+ exports.PageEditToken = require_contract.PageEditToken;
119
117
  exports.pageEditPlugin = pageEditPlugin;
120
118
 
121
119
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/capability.ts","../src/types.ts","../src/page-edit.plugin.ts"],"sourcesContent":["import type {\n PluginContext,\n PageObjectNumber,\n PageRotation,\n DocCapability,\n PdfSize,\n} from '@embedpdf/core';\nimport type { PageEditCapability, PagePlacement } from './types';\n\n/**\n * Authorization for structural page edits. Maps to PDF bit 11 (ASSEMBLE =\n * insert/rotate/delete pages). The engine ALSO enforces this — every\n * page-structure verb throws `PermissionDenied` without it, identically on\n * local and cloud — so `canEdit()` is the UI mirror of a real guard, not the\n * guard itself. Typed as `DocCapability` so a typo is a compile error.\n */\nconst ASSEMBLE_CAPABILITY: DocCapability = 'doc.pages.assemble';\n\n/**\n * Forwards structural edits to the document's engine handle, addressed by PON.\n * The handle (`ctx.doc`) and the page registry (`ctx.document()`, kept in sync\n * by the kernel's event→registry bridge) are both already on the plugin\n * context — this capability is the thin layer that turns the relative rotate\n * gesture into the engine's absolute wire.\n */\nexport function createPageEditCapability(ctx: PluginContext<unknown>): PageEditCapability {\n const requireDoc = () => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[page-edit] no document bound');\n return doc;\n };\n\n /** Current absolute rotation of a page from the registry; 0 if unknown. */\n const rotationOf = (pon: PageObjectNumber): PageRotation => {\n const page = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n return page?.rotation ?? 0;\n };\n\n /**\n * Resolve a placement to the engine's index wire, from the registry at\n * call time — the PON anchors are why \"add after this thumbnail\" survives\n * a concurrent reorder. Returns the anchor page too, so `addBlank` can\n * default its size without a second lookup.\n */\n const resolvePlacement = (placement?: PagePlacement) => {\n if (!placement) return { destIndex: undefined, anchor: undefined };\n if ('index' in placement) return { destIndex: placement.index, anchor: undefined };\n const pon = 'after' in placement ? placement.after : placement.before;\n const anchor = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n if (!anchor) throw new Error(`[page-edit] placement page not found: ${pon}`);\n return { destIndex: 'after' in placement ? anchor.index + 1 : anchor.index, anchor };\n };\n\n /**\n * Default blank-page size: the insertion point's predecessor (the page\n * the new one will follow), else the first page, else — only reachable\n * with an empty registry, which an open document never has — US Letter.\n */\n const neighbourSize = (destIndex: number | undefined): PdfSize => {\n const pages = ctx.document()?.pages ?? [];\n if (pages.length === 0) return { width: 612, height: 792 };\n if (destIndex === undefined) return pages[pages.length - 1].size;\n return pages[Math.max(0, Math.min(destIndex - 1, pages.length - 1))].size;\n };\n\n return {\n canEdit() {\n // Wildcard-aware predicate (mirrors the engine's own enforcement),\n // identical on both engines. NOT `effectiveScope.includes(...)` — that\n // enumeration drops the `*` admin grant, so it would hide the UI on a\n // default admin open even though the engine allows the edit.\n return ctx.doc?.security.allows(ASSEMBLE_CAPABILITY) ?? false;\n },\n\n rotateBy(pon, delta) {\n // Wrap to [0, 360) — the double-mod keeps -90 from current 0 landing on 270.\n const next = ((((rotationOf(pon) + delta) % 360) + 360) % 360) as PageRotation;\n return requireDoc().pages.rotate([pon], next);\n },\n\n setRotation(pons, rotation) {\n return requireDoc().pages.rotate(pons, rotation);\n },\n\n move(pons, destIndex) {\n return requireDoc().pages.move(pons, destIndex);\n },\n\n delete(pons) {\n return requireDoc().pages.delete(pons);\n },\n\n addBlank(opts = {}) {\n const doc = requireDoc();\n const { destIndex, anchor } = resolvePlacement(opts.placement);\n // PON placements match the anchor the user is looking at; everything\n // else matches the neighbour the new page will follow.\n const size = opts.size ?? anchor?.size ?? neighbourSize(destIndex);\n return doc.pages.insertBlank({ size, count: opts.count }, destIndex);\n },\n\n insert(bytes, opts = {}) {\n const doc = requireDoc();\n const { destIndex } = resolvePlacement(opts.placement);\n return doc.pages.insert(bytes, destIndex);\n },\n };\n}\n","import {\n createCapabilityToken,\n type AbortablePromise,\n type PageObjectNumber,\n type PageRotation,\n type PageRotateResult,\n type PageMoveResult,\n type PageDeleteResult,\n type PageInsertResult,\n type PdfSize,\n} from '@embedpdf/core';\n\n/**\n * Where added pages land. The PON anchors are the thumbnail gestures (\"+\n * after this page\") and stay correct across a concurrent reorder between\n * click and call — a raw index does not; `index` remains for absolute\n * positions (\"at the start\"). Omitted → append. Resolved to the engine's\n * index wire by the capability at call time, from the registry.\n */\nexport type PagePlacement =\n | { after: PageObjectNumber }\n | { before: PageObjectNumber }\n | { index: number };\n\n/**\n * Structural page edits, addressed by durable PON (never display index — an\n * index shifts the moment a sibling is moved or deleted). Mirrors the engine's\n * `DocumentPagesService` 1:1, with one addition the engine can't have: the\n * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a\n * \"+90° on this thumbnail\" click into an absolute value needs the page's\n * current rotation, so that read+arithmetic lives HERE — once — instead of\n * being re-derived in every framework adapter's click handler.\n *\n * Document-scoped: rotation is shared document metadata, so editing through the\n * sidebar lens and seeing it in the main lens is automatic (both read the same\n * registry, which the kernel keeps in sync from the engine's event stream).\n */\nexport interface PageEditCapability {\n /**\n * Whether this caller is authorized to perform structural page edits —\n * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate\n * ALL their edit affordances on this, the add verbs included (rotate,\n * move, delete, addBlank, and insert share the one capability); the\n * engine independently enforces the same capability and throws\n * `PermissionDenied` if a call slips through.\n */\n canEdit(): boolean;\n\n /**\n * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button\n * gesture. Reads the page's current rotation from the registry and forwards\n * the resulting absolute rotation to the engine.\n */\n rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;\n\n /**\n * Set the ABSOLUTE rotation of one or more pages to a single shared value —\n * the multi-select gesture. Maps 1:1 to the engine.\n */\n setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;\n\n /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */\n move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;\n\n /** Delete pages by PON. The engine rejects deleting every page. */\n delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;\n\n /**\n * Create blank pages — gate the affordance on `canEdit()`, like every\n * other structure verb (the add verbs share the `doc.pages.assemble`\n * capability and are mandatory on the engine contract). `size` defaults\n * to the page the new pages sit beside — the anchor for PON placements,\n * else the insertion point's predecessor, else the last page — so \"add\n * page\" matches the document without an A4-vs-Letter guess. That default\n * is a registry read, which is why it lives HERE and the engine wire\n * stays explicit (the `rotateBy` law). `count` defaults to 1.\n */\n addBlank(opts?: {\n size?: PdfSize;\n count?: number;\n placement?: PagePlacement;\n }): AbortablePromise<PageInsertResult>;\n\n /**\n * Copy every page of a standalone PDF (`bytes`) in at the placement —\n * the merge/import gesture. Forwards to `pages.insert`; the inserted\n * copies get fresh PONs, returned in insertion order.\n */\n insert(\n bytes: Uint8Array | ArrayBuffer,\n opts?: { placement?: PagePlacement },\n ): AbortablePromise<PageInsertResult>;\n}\n\nexport const PageEditToken = createCapabilityToken<PageEditCapability>('page-edit');\n","import { definePlugin } from '@embedpdf/core';\nimport { createPageEditCapability } from './capability';\nimport { PageEditToken } from './types';\n\n/**\n * Document-scoped, stateless: turns the engine handle's page service into a\n * PON-addressed edit capability. The relative→absolute rotation lives in the\n * capability so the four framework adapters never re-derive it, and this is the\n * home for client-side edit state (pending/optimistic/undo) when it lands —\n * adapters keep their thin hook over `PageEditToken` unchanged.\n */\nexport const pageEditPlugin = () =>\n definePlugin({\n id: 'page-edit',\n scope: 'document',\n token: PageEditToken,\n capability: createPageEditCapability,\n });\n"],"mappings":";;;;;;;;;;AAgBA,MAAM,sBAAqC;;;;;;;;AAS3C,SAAgB,yBAAyB,KAAiD;CACxF,MAAM,mBAAmB;EACvB,MAAM,MAAM,IAAI;EAChB,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,+BAA+B;EACzD,OAAO;CACT;;CAGA,MAAM,cAAc,QAAwC;EAE1D,QADa,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG,EAAA,EAC5D,YAAY;CAC3B;;;;;;;CAQA,MAAM,oBAAoB,cAA8B;EACtD,IAAI,CAAC,WAAW,OAAO;GAAE,WAAW,KAAA;GAAW,QAAQ,KAAA;EAAU;EACjE,IAAI,WAAW,WAAW,OAAO;GAAE,WAAW,UAAU;GAAO,QAAQ,KAAA;EAAU;EACjF,MAAM,MAAM,WAAW,YAAY,UAAU,QAAQ,UAAU;EAC/D,MAAM,SAAS,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG;EAC3E,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,yCAAyC,KAAK;EAC3E,OAAO;GAAE,WAAW,WAAW,YAAY,OAAO,QAAQ,IAAI,OAAO;GAAO;EAAO;CACrF;;;;;;CAOA,MAAM,iBAAiB,cAA2C;EAChE,MAAM,QAAQ,IAAI,SAAS,CAAC,EAAE,SAAS,CAAC;EACxC,IAAI,MAAM,WAAW,GAAG,OAAO;GAAE,OAAO;GAAK,QAAQ;EAAI;EACzD,IAAI,cAAc,KAAA,GAAW,OAAO,MAAM,MAAM,SAAS,EAAE,CAAC;EAC5D,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC;CACvE;CAEA,OAAO;EACL,UAAU;GAKR,OAAO,IAAI,KAAK,SAAS,OAAO,mBAAmB,KAAK;EAC1D;EAEA,SAAS,KAAK,OAAO;GAEnB,MAAM,SAAW,WAAW,GAAG,IAAI,SAAS,MAAO,OAAO;GAC1D,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI;EAC9C;EAEA,YAAY,MAAM,UAAU;GAC1B,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,MAAM,QAAQ;EACjD;EAEA,KAAK,MAAM,WAAW;GACpB,OAAO,WAAW,CAAC,CAAC,MAAM,KAAK,MAAM,SAAS;EAChD;EAEA,OAAO,MAAM;GACX,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,IAAI;EACvC;EAEA,SAAS,OAAO,CAAC,GAAG;GAClB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,WAAW,WAAW,iBAAiB,KAAK,SAAS;GAG7D,MAAM,OAAO,KAAK,QAAQ,QAAQ,QAAQ,cAAc,SAAS;GACjE,OAAO,IAAI,MAAM,YAAY;IAAE;IAAM,OAAO,KAAK;GAAM,GAAG,SAAS;EACrE;EAEA,OAAO,OAAO,OAAO,CAAC,GAAG;GACvB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,cAAc,iBAAiB,KAAK,SAAS;GACrD,OAAO,IAAI,MAAM,OAAO,OAAO,SAAS;EAC1C;CACF;AACF;;;ACbA,MAAa,iBAAA,GAAA,eAAA,sBAAA,CAA0D,WAAW;;;;;;;;;;ACnFlF,MAAa,wBAAA,GAAA,eAAA,aAAA,CACE;CACX,IAAI;CACJ,OAAO;CACP,OAAO;CACP,YAAY;AACd,CAAC"}
1
+ {"version":3,"file":"index.cjs","names":["PageEditToken"],"sources":["../src/capability.ts","../src/page-edit.plugin.ts"],"sourcesContent":["import type {\n PluginContext,\n PageObjectNumber,\n PageRotation,\n DocCapability,\n PdfSize,\n} from '@embedpdf/core';\nimport type { PageEditCapability, PagePlacement } from './types';\n\n/**\n * Authorization for structural page edits. Maps to PDF bit 11 (ASSEMBLE =\n * insert/rotate/delete pages). The engine ALSO enforces this — every\n * page-structure verb throws `PermissionDenied` without it, identically on\n * local and cloud — so `canEdit()` is the UI mirror of a real guard, not the\n * guard itself. Typed as `DocCapability` so a typo is a compile error.\n */\nconst ASSEMBLE_CAPABILITY: DocCapability = 'doc.pages.assemble';\n\n/**\n * Forwards structural edits to the document's engine handle, addressed by PON.\n * The handle (`ctx.doc`) and the page registry (`ctx.document()`, kept in sync\n * by the kernel's event→registry bridge) are both already on the plugin\n * context — this capability is the thin layer that turns the relative rotate\n * gesture into the engine's absolute wire.\n */\nexport function createPageEditCapability(ctx: PluginContext<unknown>): PageEditCapability {\n const requireDoc = () => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[page-edit] no document bound');\n return doc;\n };\n\n /** Current absolute rotation of a page from the registry; 0 if unknown. */\n const rotationOf = (pon: PageObjectNumber): PageRotation => {\n const page = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n return page?.rotation ?? 0;\n };\n\n /**\n * Resolve a placement to the engine's index wire, from the registry at\n * call time — the PON anchors are why \"add after this thumbnail\" survives\n * a concurrent reorder. Returns the anchor page too, so `addBlank` can\n * default its size without a second lookup.\n */\n const resolvePlacement = (placement?: PagePlacement) => {\n if (!placement) return { destIndex: undefined, anchor: undefined };\n if ('index' in placement) return { destIndex: placement.index, anchor: undefined };\n const pon = 'after' in placement ? placement.after : placement.before;\n const anchor = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n if (!anchor) throw new Error(`[page-edit] placement page not found: ${pon}`);\n return { destIndex: 'after' in placement ? anchor.index + 1 : anchor.index, anchor };\n };\n\n /**\n * Default blank-page size: the insertion point's predecessor (the page\n * the new one will follow), else the first page, else — only reachable\n * with an empty registry, which an open document never has — US Letter.\n */\n const neighbourSize = (destIndex: number | undefined): PdfSize => {\n const pages = ctx.document()?.pages ?? [];\n if (pages.length === 0) return { width: 612, height: 792 };\n if (destIndex === undefined) return pages[pages.length - 1].size;\n return pages[Math.max(0, Math.min(destIndex - 1, pages.length - 1))].size;\n };\n\n return {\n canEdit() {\n // Wildcard-aware predicate (mirrors the engine's own enforcement),\n // identical on both engines. NOT `effectiveScope.includes(...)` — that\n // enumeration drops the `*` admin grant, so it would hide the UI on a\n // default admin open even though the engine allows the edit.\n return ctx.doc?.security.allows(ASSEMBLE_CAPABILITY) ?? false;\n },\n\n rotateBy(pon, delta) {\n // Wrap to [0, 360) — the double-mod keeps -90 from current 0 landing on 270.\n const next = ((((rotationOf(pon) + delta) % 360) + 360) % 360) as PageRotation;\n return requireDoc().pages.rotate([pon], next);\n },\n\n setRotation(pons, rotation) {\n return requireDoc().pages.rotate(pons, rotation);\n },\n\n move(pons, destIndex) {\n return requireDoc().pages.move(pons, destIndex);\n },\n\n delete(pons) {\n return requireDoc().pages.delete(pons);\n },\n\n addBlank(opts = {}) {\n const doc = requireDoc();\n const { destIndex, anchor } = resolvePlacement(opts.placement);\n // PON placements match the anchor the user is looking at; everything\n // else matches the neighbour the new page will follow.\n const size = opts.size ?? anchor?.size ?? neighbourSize(destIndex);\n return doc.pages.insertBlank({ size, count: opts.count }, destIndex);\n },\n\n insert(bytes, opts = {}) {\n const doc = requireDoc();\n const { destIndex } = resolvePlacement(opts.placement);\n return doc.pages.insert(bytes, destIndex);\n },\n };\n}\n","import { definePlugin } from '@embedpdf/core';\nimport { createPageEditCapability } from './capability';\nimport { PageEditToken } from './types';\n\n/**\n * Document-scoped, stateless: turns the engine handle's page service into a\n * PON-addressed edit capability. The relative→absolute rotation lives in the\n * capability so the four framework adapters never re-derive it, and this is the\n * home for client-side edit state (pending/optimistic/undo) when it lands —\n * adapters keep their thin hook over `PageEditToken` unchanged.\n */\nexport const pageEditPlugin = () =>\n definePlugin({\n id: 'page-edit',\n scope: 'document',\n token: PageEditToken,\n capability: createPageEditCapability,\n });\n"],"mappings":";;;;;;;;;;;AAgBA,MAAM,sBAAqC;;;;;;;;AAS3C,SAAgB,yBAAyB,KAAiD;CACxF,MAAM,mBAAmB;EACvB,MAAM,MAAM,IAAI;EAChB,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,+BAA+B;EACzD,OAAO;CACT;;CAGA,MAAM,cAAc,QAAwC;EAE1D,QADa,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG,EAAA,EAC5D,YAAY;CAC3B;;;;;;;CAQA,MAAM,oBAAoB,cAA8B;EACtD,IAAI,CAAC,WAAW,OAAO;GAAE,WAAW,KAAA;GAAW,QAAQ,KAAA;EAAU;EACjE,IAAI,WAAW,WAAW,OAAO;GAAE,WAAW,UAAU;GAAO,QAAQ,KAAA;EAAU;EACjF,MAAM,MAAM,WAAW,YAAY,UAAU,QAAQ,UAAU;EAC/D,MAAM,SAAS,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG;EAC3E,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,yCAAyC,KAAK;EAC3E,OAAO;GAAE,WAAW,WAAW,YAAY,OAAO,QAAQ,IAAI,OAAO;GAAO;EAAO;CACrF;;;;;;CAOA,MAAM,iBAAiB,cAA2C;EAChE,MAAM,QAAQ,IAAI,SAAS,CAAC,EAAE,SAAS,CAAC;EACxC,IAAI,MAAM,WAAW,GAAG,OAAO;GAAE,OAAO;GAAK,QAAQ;EAAI;EACzD,IAAI,cAAc,KAAA,GAAW,OAAO,MAAM,MAAM,SAAS,EAAE,CAAC;EAC5D,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC;CACvE;CAEA,OAAO;EACL,UAAU;GAKR,OAAO,IAAI,KAAK,SAAS,OAAO,mBAAmB,KAAK;EAC1D;EAEA,SAAS,KAAK,OAAO;GAEnB,MAAM,SAAW,WAAW,GAAG,IAAI,SAAS,MAAO,OAAO;GAC1D,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI;EAC9C;EAEA,YAAY,MAAM,UAAU;GAC1B,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,MAAM,QAAQ;EACjD;EAEA,KAAK,MAAM,WAAW;GACpB,OAAO,WAAW,CAAC,CAAC,MAAM,KAAK,MAAM,SAAS;EAChD;EAEA,OAAO,MAAM;GACX,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,IAAI;EACvC;EAEA,SAAS,OAAO,CAAC,GAAG;GAClB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,WAAW,WAAW,iBAAiB,KAAK,SAAS;GAG7D,MAAM,OAAO,KAAK,QAAQ,QAAQ,QAAQ,cAAc,SAAS;GACjE,OAAO,IAAI,MAAM,YAAY;IAAE;IAAM,OAAO,KAAK;GAAM,GAAG,SAAS;EACrE;EAEA,OAAO,OAAO,OAAO,CAAC,GAAG;GACvB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,cAAc,iBAAiB,KAAK,SAAS;GACrD,OAAO,IAAI,MAAM,OAAO,OAAO,SAAS;EAC1C;CACF;AACF;;;;;;;;;;AChGA,MAAa,wBAAA,GAAA,eAAA,aAAA,CACE;CACX,IAAI;CACJ,OAAO;CACP,OAAOA,iBAAAA;CACP,YAAY;AACd,CAAC"}
package/dist/index.d.cts CHANGED
@@ -1,83 +1,4 @@
1
- import { AbortablePromise, PageDeleteResult, PageInsertResult, PageMoveResult, PageObjectNumber, PageRotateResult, PageRotation, PdfSize } from "@embedpdf/core";
2
- //#region src/types.d.ts
3
- /**
4
- * Where added pages land. The PON anchors are the thumbnail gestures ("+
5
- * after this page") and stay correct across a concurrent reorder between
6
- * click and call — a raw index does not; `index` remains for absolute
7
- * positions ("at the start"). Omitted → append. Resolved to the engine's
8
- * index wire by the capability at call time, from the registry.
9
- */
10
- type PagePlacement = {
11
- after: PageObjectNumber;
12
- } | {
13
- before: PageObjectNumber;
14
- } | {
15
- index: number;
16
- };
17
- /**
18
- * Structural page edits, addressed by durable PON (never display index — an
19
- * index shifts the moment a sibling is moved or deleted). Mirrors the engine's
20
- * `DocumentPagesService` 1:1, with one addition the engine can't have: the
21
- * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a
22
- * "+90° on this thumbnail" click into an absolute value needs the page's
23
- * current rotation, so that read+arithmetic lives HERE — once — instead of
24
- * being re-derived in every framework adapter's click handler.
25
- *
26
- * Document-scoped: rotation is shared document metadata, so editing through the
27
- * sidebar lens and seeing it in the main lens is automatic (both read the same
28
- * registry, which the kernel keeps in sync from the engine's event stream).
29
- */
30
- interface PageEditCapability {
31
- /**
32
- * Whether this caller is authorized to perform structural page edits —
33
- * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate
34
- * ALL their edit affordances on this, the add verbs included (rotate,
35
- * move, delete, addBlank, and insert share the one capability); the
36
- * engine independently enforces the same capability and throws
37
- * `PermissionDenied` if a call slips through.
38
- */
39
- canEdit(): boolean;
40
- /**
41
- * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button
42
- * gesture. Reads the page's current rotation from the registry and forwards
43
- * the resulting absolute rotation to the engine.
44
- */
45
- rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;
46
- /**
47
- * Set the ABSOLUTE rotation of one or more pages to a single shared value —
48
- * the multi-select gesture. Maps 1:1 to the engine.
49
- */
50
- setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;
51
- /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */
52
- move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;
53
- /** Delete pages by PON. The engine rejects deleting every page. */
54
- delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;
55
- /**
56
- * Create blank pages — gate the affordance on `canEdit()`, like every
57
- * other structure verb (the add verbs share the `doc.pages.assemble`
58
- * capability and are mandatory on the engine contract). `size` defaults
59
- * to the page the new pages sit beside — the anchor for PON placements,
60
- * else the insertion point's predecessor, else the last page — so "add
61
- * page" matches the document without an A4-vs-Letter guess. That default
62
- * is a registry read, which is why it lives HERE and the engine wire
63
- * stays explicit (the `rotateBy` law). `count` defaults to 1.
64
- */
65
- addBlank(opts?: {
66
- size?: PdfSize;
67
- count?: number;
68
- placement?: PagePlacement;
69
- }): AbortablePromise<PageInsertResult>;
70
- /**
71
- * Copy every page of a standalone PDF (`bytes`) in at the placement —
72
- * the merge/import gesture. Forwards to `pages.insert`; the inserted
73
- * copies get fresh PONs, returned in insertion order.
74
- */
75
- insert(bytes: Uint8Array | ArrayBuffer, opts?: {
76
- placement?: PagePlacement;
77
- }): AbortablePromise<PageInsertResult>;
78
- }
79
- declare const PageEditToken: import("@embedpdf/core").CapabilityToken<PageEditCapability>;
80
- //#endregion
1
+ import { n as PageEditToken, t as PageEditCapability } from "./contract-BnXi11KD.cjs";
81
2
  //#region src/page-edit.plugin.d.ts
82
3
  /**
83
4
  * Document-scoped, stateless: turns the engine handle's page service into a
package/dist/index.d.ts CHANGED
@@ -1,83 +1,4 @@
1
- import { AbortablePromise, PageDeleteResult, PageInsertResult, PageMoveResult, PageObjectNumber, PageRotateResult, PageRotation, PdfSize } from "@embedpdf/core";
2
- //#region src/types.d.ts
3
- /**
4
- * Where added pages land. The PON anchors are the thumbnail gestures ("+
5
- * after this page") and stay correct across a concurrent reorder between
6
- * click and call — a raw index does not; `index` remains for absolute
7
- * positions ("at the start"). Omitted → append. Resolved to the engine's
8
- * index wire by the capability at call time, from the registry.
9
- */
10
- type PagePlacement = {
11
- after: PageObjectNumber;
12
- } | {
13
- before: PageObjectNumber;
14
- } | {
15
- index: number;
16
- };
17
- /**
18
- * Structural page edits, addressed by durable PON (never display index — an
19
- * index shifts the moment a sibling is moved or deleted). Mirrors the engine's
20
- * `DocumentPagesService` 1:1, with one addition the engine can't have: the
21
- * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a
22
- * "+90° on this thumbnail" click into an absolute value needs the page's
23
- * current rotation, so that read+arithmetic lives HERE — once — instead of
24
- * being re-derived in every framework adapter's click handler.
25
- *
26
- * Document-scoped: rotation is shared document metadata, so editing through the
27
- * sidebar lens and seeing it in the main lens is automatic (both read the same
28
- * registry, which the kernel keeps in sync from the engine's event stream).
29
- */
30
- interface PageEditCapability {
31
- /**
32
- * Whether this caller is authorized to perform structural page edits —
33
- * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate
34
- * ALL their edit affordances on this, the add verbs included (rotate,
35
- * move, delete, addBlank, and insert share the one capability); the
36
- * engine independently enforces the same capability and throws
37
- * `PermissionDenied` if a call slips through.
38
- */
39
- canEdit(): boolean;
40
- /**
41
- * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button
42
- * gesture. Reads the page's current rotation from the registry and forwards
43
- * the resulting absolute rotation to the engine.
44
- */
45
- rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;
46
- /**
47
- * Set the ABSOLUTE rotation of one or more pages to a single shared value —
48
- * the multi-select gesture. Maps 1:1 to the engine.
49
- */
50
- setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;
51
- /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */
52
- move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;
53
- /** Delete pages by PON. The engine rejects deleting every page. */
54
- delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;
55
- /**
56
- * Create blank pages — gate the affordance on `canEdit()`, like every
57
- * other structure verb (the add verbs share the `doc.pages.assemble`
58
- * capability and are mandatory on the engine contract). `size` defaults
59
- * to the page the new pages sit beside — the anchor for PON placements,
60
- * else the insertion point's predecessor, else the last page — so "add
61
- * page" matches the document without an A4-vs-Letter guess. That default
62
- * is a registry read, which is why it lives HERE and the engine wire
63
- * stays explicit (the `rotateBy` law). `count` defaults to 1.
64
- */
65
- addBlank(opts?: {
66
- size?: PdfSize;
67
- count?: number;
68
- placement?: PagePlacement;
69
- }): AbortablePromise<PageInsertResult>;
70
- /**
71
- * Copy every page of a standalone PDF (`bytes`) in at the placement —
72
- * the merge/import gesture. Forwards to `pages.insert`; the inserted
73
- * copies get fresh PONs, returned in insertion order.
74
- */
75
- insert(bytes: Uint8Array | ArrayBuffer, opts?: {
76
- placement?: PagePlacement;
77
- }): AbortablePromise<PageInsertResult>;
78
- }
79
- declare const PageEditToken: import("@embedpdf/core").CapabilityToken<PageEditCapability>;
80
- //#endregion
1
+ import { n as PageEditToken, t as PageEditCapability } from "./contract-BnXi11KD.js";
81
2
  //#region src/page-edit.plugin.d.ts
82
3
  /**
83
4
  * Document-scoped, stateless: turns the engine handle's page service into a
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { createCapabilityToken, definePlugin } from "@embedpdf/core";
1
+ import { t as PageEditToken } from "./contract-BsNelyd8.js";
2
+ import { definePlugin } from "@embedpdf/core";
2
3
  //#region src/capability.ts
3
4
  /**
4
5
  * Authorization for structural page edits. Maps to PDF bit 11 (ASSEMBLE =
@@ -96,9 +97,6 @@ function createPageEditCapability(ctx) {
96
97
  };
97
98
  }
98
99
  //#endregion
99
- //#region src/types.ts
100
- const PageEditToken = createCapabilityToken("page-edit");
101
- //#endregion
102
100
  //#region src/page-edit.plugin.ts
103
101
  /**
104
102
  * Document-scoped, stateless: turns the engine handle's page service into a
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/capability.ts","../src/types.ts","../src/page-edit.plugin.ts"],"sourcesContent":["import type {\n PluginContext,\n PageObjectNumber,\n PageRotation,\n DocCapability,\n PdfSize,\n} from '@embedpdf/core';\nimport type { PageEditCapability, PagePlacement } from './types';\n\n/**\n * Authorization for structural page edits. Maps to PDF bit 11 (ASSEMBLE =\n * insert/rotate/delete pages). The engine ALSO enforces this — every\n * page-structure verb throws `PermissionDenied` without it, identically on\n * local and cloud — so `canEdit()` is the UI mirror of a real guard, not the\n * guard itself. Typed as `DocCapability` so a typo is a compile error.\n */\nconst ASSEMBLE_CAPABILITY: DocCapability = 'doc.pages.assemble';\n\n/**\n * Forwards structural edits to the document's engine handle, addressed by PON.\n * The handle (`ctx.doc`) and the page registry (`ctx.document()`, kept in sync\n * by the kernel's event→registry bridge) are both already on the plugin\n * context — this capability is the thin layer that turns the relative rotate\n * gesture into the engine's absolute wire.\n */\nexport function createPageEditCapability(ctx: PluginContext<unknown>): PageEditCapability {\n const requireDoc = () => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[page-edit] no document bound');\n return doc;\n };\n\n /** Current absolute rotation of a page from the registry; 0 if unknown. */\n const rotationOf = (pon: PageObjectNumber): PageRotation => {\n const page = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n return page?.rotation ?? 0;\n };\n\n /**\n * Resolve a placement to the engine's index wire, from the registry at\n * call time — the PON anchors are why \"add after this thumbnail\" survives\n * a concurrent reorder. Returns the anchor page too, so `addBlank` can\n * default its size without a second lookup.\n */\n const resolvePlacement = (placement?: PagePlacement) => {\n if (!placement) return { destIndex: undefined, anchor: undefined };\n if ('index' in placement) return { destIndex: placement.index, anchor: undefined };\n const pon = 'after' in placement ? placement.after : placement.before;\n const anchor = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n if (!anchor) throw new Error(`[page-edit] placement page not found: ${pon}`);\n return { destIndex: 'after' in placement ? anchor.index + 1 : anchor.index, anchor };\n };\n\n /**\n * Default blank-page size: the insertion point's predecessor (the page\n * the new one will follow), else the first page, else — only reachable\n * with an empty registry, which an open document never has — US Letter.\n */\n const neighbourSize = (destIndex: number | undefined): PdfSize => {\n const pages = ctx.document()?.pages ?? [];\n if (pages.length === 0) return { width: 612, height: 792 };\n if (destIndex === undefined) return pages[pages.length - 1].size;\n return pages[Math.max(0, Math.min(destIndex - 1, pages.length - 1))].size;\n };\n\n return {\n canEdit() {\n // Wildcard-aware predicate (mirrors the engine's own enforcement),\n // identical on both engines. NOT `effectiveScope.includes(...)` — that\n // enumeration drops the `*` admin grant, so it would hide the UI on a\n // default admin open even though the engine allows the edit.\n return ctx.doc?.security.allows(ASSEMBLE_CAPABILITY) ?? false;\n },\n\n rotateBy(pon, delta) {\n // Wrap to [0, 360) — the double-mod keeps -90 from current 0 landing on 270.\n const next = ((((rotationOf(pon) + delta) % 360) + 360) % 360) as PageRotation;\n return requireDoc().pages.rotate([pon], next);\n },\n\n setRotation(pons, rotation) {\n return requireDoc().pages.rotate(pons, rotation);\n },\n\n move(pons, destIndex) {\n return requireDoc().pages.move(pons, destIndex);\n },\n\n delete(pons) {\n return requireDoc().pages.delete(pons);\n },\n\n addBlank(opts = {}) {\n const doc = requireDoc();\n const { destIndex, anchor } = resolvePlacement(opts.placement);\n // PON placements match the anchor the user is looking at; everything\n // else matches the neighbour the new page will follow.\n const size = opts.size ?? anchor?.size ?? neighbourSize(destIndex);\n return doc.pages.insertBlank({ size, count: opts.count }, destIndex);\n },\n\n insert(bytes, opts = {}) {\n const doc = requireDoc();\n const { destIndex } = resolvePlacement(opts.placement);\n return doc.pages.insert(bytes, destIndex);\n },\n };\n}\n","import {\n createCapabilityToken,\n type AbortablePromise,\n type PageObjectNumber,\n type PageRotation,\n type PageRotateResult,\n type PageMoveResult,\n type PageDeleteResult,\n type PageInsertResult,\n type PdfSize,\n} from '@embedpdf/core';\n\n/**\n * Where added pages land. The PON anchors are the thumbnail gestures (\"+\n * after this page\") and stay correct across a concurrent reorder between\n * click and call — a raw index does not; `index` remains for absolute\n * positions (\"at the start\"). Omitted → append. Resolved to the engine's\n * index wire by the capability at call time, from the registry.\n */\nexport type PagePlacement =\n | { after: PageObjectNumber }\n | { before: PageObjectNumber }\n | { index: number };\n\n/**\n * Structural page edits, addressed by durable PON (never display index — an\n * index shifts the moment a sibling is moved or deleted). Mirrors the engine's\n * `DocumentPagesService` 1:1, with one addition the engine can't have: the\n * relative `rotateBy` gesture. The engine wire is always ABSOLUTE; turning a\n * \"+90° on this thumbnail\" click into an absolute value needs the page's\n * current rotation, so that read+arithmetic lives HERE — once — instead of\n * being re-derived in every framework adapter's click handler.\n *\n * Document-scoped: rotation is shared document metadata, so editing through the\n * sidebar lens and seeing it in the main lens is automatic (both read the same\n * registry, which the kernel keeps in sync from the engine's event stream).\n */\nexport interface PageEditCapability {\n /**\n * Whether this caller is authorized to perform structural page edits —\n * `effectiveScope` includes `doc.pages.assemble` (PDF bit 11). UIs gate\n * ALL their edit affordances on this, the add verbs included (rotate,\n * move, delete, addBlank, and insert share the one capability); the\n * engine independently enforces the same capability and throws\n * `PermissionDenied` if a call slips through.\n */\n canEdit(): boolean;\n\n /**\n * Rotate a SINGLE page by a relative quarter-turn — the per-thumbnail button\n * gesture. Reads the page's current rotation from the registry and forwards\n * the resulting absolute rotation to the engine.\n */\n rotateBy(pon: PageObjectNumber, delta: 90 | -90): AbortablePromise<PageRotateResult>;\n\n /**\n * Set the ABSOLUTE rotation of one or more pages to a single shared value —\n * the multi-select gesture. Maps 1:1 to the engine.\n */\n setRotation(pons: PageObjectNumber[], rotation: PageRotation): AbortablePromise<PageRotateResult>;\n\n /** Reorder pages (by PON) as a contiguous block starting at `destIndex`. */\n move(pons: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;\n\n /** Delete pages by PON. The engine rejects deleting every page. */\n delete(pons: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;\n\n /**\n * Create blank pages — gate the affordance on `canEdit()`, like every\n * other structure verb (the add verbs share the `doc.pages.assemble`\n * capability and are mandatory on the engine contract). `size` defaults\n * to the page the new pages sit beside — the anchor for PON placements,\n * else the insertion point's predecessor, else the last page — so \"add\n * page\" matches the document without an A4-vs-Letter guess. That default\n * is a registry read, which is why it lives HERE and the engine wire\n * stays explicit (the `rotateBy` law). `count` defaults to 1.\n */\n addBlank(opts?: {\n size?: PdfSize;\n count?: number;\n placement?: PagePlacement;\n }): AbortablePromise<PageInsertResult>;\n\n /**\n * Copy every page of a standalone PDF (`bytes`) in at the placement —\n * the merge/import gesture. Forwards to `pages.insert`; the inserted\n * copies get fresh PONs, returned in insertion order.\n */\n insert(\n bytes: Uint8Array | ArrayBuffer,\n opts?: { placement?: PagePlacement },\n ): AbortablePromise<PageInsertResult>;\n}\n\nexport const PageEditToken = createCapabilityToken<PageEditCapability>('page-edit');\n","import { definePlugin } from '@embedpdf/core';\nimport { createPageEditCapability } from './capability';\nimport { PageEditToken } from './types';\n\n/**\n * Document-scoped, stateless: turns the engine handle's page service into a\n * PON-addressed edit capability. The relative→absolute rotation lives in the\n * capability so the four framework adapters never re-derive it, and this is the\n * home for client-side edit state (pending/optimistic/undo) when it lands —\n * adapters keep their thin hook over `PageEditToken` unchanged.\n */\nexport const pageEditPlugin = () =>\n definePlugin({\n id: 'page-edit',\n scope: 'document',\n token: PageEditToken,\n capability: createPageEditCapability,\n });\n"],"mappings":";;;;;;;;;AAgBA,MAAM,sBAAqC;;;;;;;;AAS3C,SAAgB,yBAAyB,KAAiD;CACxF,MAAM,mBAAmB;EACvB,MAAM,MAAM,IAAI;EAChB,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,+BAA+B;EACzD,OAAO;CACT;;CAGA,MAAM,cAAc,QAAwC;EAE1D,QADa,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG,EAAA,EAC5D,YAAY;CAC3B;;;;;;;CAQA,MAAM,oBAAoB,cAA8B;EACtD,IAAI,CAAC,WAAW,OAAO;GAAE,WAAW,KAAA;GAAW,QAAQ,KAAA;EAAU;EACjE,IAAI,WAAW,WAAW,OAAO;GAAE,WAAW,UAAU;GAAO,QAAQ,KAAA;EAAU;EACjF,MAAM,MAAM,WAAW,YAAY,UAAU,QAAQ,UAAU;EAC/D,MAAM,SAAS,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG;EAC3E,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,yCAAyC,KAAK;EAC3E,OAAO;GAAE,WAAW,WAAW,YAAY,OAAO,QAAQ,IAAI,OAAO;GAAO;EAAO;CACrF;;;;;;CAOA,MAAM,iBAAiB,cAA2C;EAChE,MAAM,QAAQ,IAAI,SAAS,CAAC,EAAE,SAAS,CAAC;EACxC,IAAI,MAAM,WAAW,GAAG,OAAO;GAAE,OAAO;GAAK,QAAQ;EAAI;EACzD,IAAI,cAAc,KAAA,GAAW,OAAO,MAAM,MAAM,SAAS,EAAE,CAAC;EAC5D,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC;CACvE;CAEA,OAAO;EACL,UAAU;GAKR,OAAO,IAAI,KAAK,SAAS,OAAO,mBAAmB,KAAK;EAC1D;EAEA,SAAS,KAAK,OAAO;GAEnB,MAAM,SAAW,WAAW,GAAG,IAAI,SAAS,MAAO,OAAO;GAC1D,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI;EAC9C;EAEA,YAAY,MAAM,UAAU;GAC1B,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,MAAM,QAAQ;EACjD;EAEA,KAAK,MAAM,WAAW;GACpB,OAAO,WAAW,CAAC,CAAC,MAAM,KAAK,MAAM,SAAS;EAChD;EAEA,OAAO,MAAM;GACX,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,IAAI;EACvC;EAEA,SAAS,OAAO,CAAC,GAAG;GAClB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,WAAW,WAAW,iBAAiB,KAAK,SAAS;GAG7D,MAAM,OAAO,KAAK,QAAQ,QAAQ,QAAQ,cAAc,SAAS;GACjE,OAAO,IAAI,MAAM,YAAY;IAAE;IAAM,OAAO,KAAK;GAAM,GAAG,SAAS;EACrE;EAEA,OAAO,OAAO,OAAO,CAAC,GAAG;GACvB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,cAAc,iBAAiB,KAAK,SAAS;GACrD,OAAO,IAAI,MAAM,OAAO,OAAO,SAAS;EAC1C;CACF;AACF;;;ACbA,MAAa,gBAAgB,sBAA0C,WAAW;;;;;;;;;;ACnFlF,MAAa,uBACX,aAAa;CACX,IAAI;CACJ,OAAO;CACP,OAAO;CACP,YAAY;AACd,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/capability.ts","../src/page-edit.plugin.ts"],"sourcesContent":["import type {\n PluginContext,\n PageObjectNumber,\n PageRotation,\n DocCapability,\n PdfSize,\n} from '@embedpdf/core';\nimport type { PageEditCapability, PagePlacement } from './types';\n\n/**\n * Authorization for structural page edits. Maps to PDF bit 11 (ASSEMBLE =\n * insert/rotate/delete pages). The engine ALSO enforces this — every\n * page-structure verb throws `PermissionDenied` without it, identically on\n * local and cloud — so `canEdit()` is the UI mirror of a real guard, not the\n * guard itself. Typed as `DocCapability` so a typo is a compile error.\n */\nconst ASSEMBLE_CAPABILITY: DocCapability = 'doc.pages.assemble';\n\n/**\n * Forwards structural edits to the document's engine handle, addressed by PON.\n * The handle (`ctx.doc`) and the page registry (`ctx.document()`, kept in sync\n * by the kernel's event→registry bridge) are both already on the plugin\n * context — this capability is the thin layer that turns the relative rotate\n * gesture into the engine's absolute wire.\n */\nexport function createPageEditCapability(ctx: PluginContext<unknown>): PageEditCapability {\n const requireDoc = () => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[page-edit] no document bound');\n return doc;\n };\n\n /** Current absolute rotation of a page from the registry; 0 if unknown. */\n const rotationOf = (pon: PageObjectNumber): PageRotation => {\n const page = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n return page?.rotation ?? 0;\n };\n\n /**\n * Resolve a placement to the engine's index wire, from the registry at\n * call time — the PON anchors are why \"add after this thumbnail\" survives\n * a concurrent reorder. Returns the anchor page too, so `addBlank` can\n * default its size without a second lookup.\n */\n const resolvePlacement = (placement?: PagePlacement) => {\n if (!placement) return { destIndex: undefined, anchor: undefined };\n if ('index' in placement) return { destIndex: placement.index, anchor: undefined };\n const pon = 'after' in placement ? placement.after : placement.before;\n const anchor = ctx.document()?.pages.find((p) => p.pageObjectNumber === pon);\n if (!anchor) throw new Error(`[page-edit] placement page not found: ${pon}`);\n return { destIndex: 'after' in placement ? anchor.index + 1 : anchor.index, anchor };\n };\n\n /**\n * Default blank-page size: the insertion point's predecessor (the page\n * the new one will follow), else the first page, else — only reachable\n * with an empty registry, which an open document never has — US Letter.\n */\n const neighbourSize = (destIndex: number | undefined): PdfSize => {\n const pages = ctx.document()?.pages ?? [];\n if (pages.length === 0) return { width: 612, height: 792 };\n if (destIndex === undefined) return pages[pages.length - 1].size;\n return pages[Math.max(0, Math.min(destIndex - 1, pages.length - 1))].size;\n };\n\n return {\n canEdit() {\n // Wildcard-aware predicate (mirrors the engine's own enforcement),\n // identical on both engines. NOT `effectiveScope.includes(...)` — that\n // enumeration drops the `*` admin grant, so it would hide the UI on a\n // default admin open even though the engine allows the edit.\n return ctx.doc?.security.allows(ASSEMBLE_CAPABILITY) ?? false;\n },\n\n rotateBy(pon, delta) {\n // Wrap to [0, 360) — the double-mod keeps -90 from current 0 landing on 270.\n const next = ((((rotationOf(pon) + delta) % 360) + 360) % 360) as PageRotation;\n return requireDoc().pages.rotate([pon], next);\n },\n\n setRotation(pons, rotation) {\n return requireDoc().pages.rotate(pons, rotation);\n },\n\n move(pons, destIndex) {\n return requireDoc().pages.move(pons, destIndex);\n },\n\n delete(pons) {\n return requireDoc().pages.delete(pons);\n },\n\n addBlank(opts = {}) {\n const doc = requireDoc();\n const { destIndex, anchor } = resolvePlacement(opts.placement);\n // PON placements match the anchor the user is looking at; everything\n // else matches the neighbour the new page will follow.\n const size = opts.size ?? anchor?.size ?? neighbourSize(destIndex);\n return doc.pages.insertBlank({ size, count: opts.count }, destIndex);\n },\n\n insert(bytes, opts = {}) {\n const doc = requireDoc();\n const { destIndex } = resolvePlacement(opts.placement);\n return doc.pages.insert(bytes, destIndex);\n },\n };\n}\n","import { definePlugin } from '@embedpdf/core';\nimport { createPageEditCapability } from './capability';\nimport { PageEditToken } from './types';\n\n/**\n * Document-scoped, stateless: turns the engine handle's page service into a\n * PON-addressed edit capability. The relative→absolute rotation lives in the\n * capability so the four framework adapters never re-derive it, and this is the\n * home for client-side edit state (pending/optimistic/undo) when it lands —\n * adapters keep their thin hook over `PageEditToken` unchanged.\n */\nexport const pageEditPlugin = () =>\n definePlugin({\n id: 'page-edit',\n scope: 'document',\n token: PageEditToken,\n capability: createPageEditCapability,\n });\n"],"mappings":";;;;;;;;;;AAgBA,MAAM,sBAAqC;;;;;;;;AAS3C,SAAgB,yBAAyB,KAAiD;CACxF,MAAM,mBAAmB;EACvB,MAAM,MAAM,IAAI;EAChB,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,+BAA+B;EACzD,OAAO;CACT;;CAGA,MAAM,cAAc,QAAwC;EAE1D,QADa,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG,EAAA,EAC5D,YAAY;CAC3B;;;;;;;CAQA,MAAM,oBAAoB,cAA8B;EACtD,IAAI,CAAC,WAAW,OAAO;GAAE,WAAW,KAAA;GAAW,QAAQ,KAAA;EAAU;EACjE,IAAI,WAAW,WAAW,OAAO;GAAE,WAAW,UAAU;GAAO,QAAQ,KAAA;EAAU;EACjF,MAAM,MAAM,WAAW,YAAY,UAAU,QAAQ,UAAU;EAC/D,MAAM,SAAS,IAAI,SAAS,CAAC,EAAE,MAAM,MAAM,MAAM,EAAE,qBAAqB,GAAG;EAC3E,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,yCAAyC,KAAK;EAC3E,OAAO;GAAE,WAAW,WAAW,YAAY,OAAO,QAAQ,IAAI,OAAO;GAAO;EAAO;CACrF;;;;;;CAOA,MAAM,iBAAiB,cAA2C;EAChE,MAAM,QAAQ,IAAI,SAAS,CAAC,EAAE,SAAS,CAAC;EACxC,IAAI,MAAM,WAAW,GAAG,OAAO;GAAE,OAAO;GAAK,QAAQ;EAAI;EACzD,IAAI,cAAc,KAAA,GAAW,OAAO,MAAM,MAAM,SAAS,EAAE,CAAC;EAC5D,OAAO,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC;CACvE;CAEA,OAAO;EACL,UAAU;GAKR,OAAO,IAAI,KAAK,SAAS,OAAO,mBAAmB,KAAK;EAC1D;EAEA,SAAS,KAAK,OAAO;GAEnB,MAAM,SAAW,WAAW,GAAG,IAAI,SAAS,MAAO,OAAO;GAC1D,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI;EAC9C;EAEA,YAAY,MAAM,UAAU;GAC1B,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,MAAM,QAAQ;EACjD;EAEA,KAAK,MAAM,WAAW;GACpB,OAAO,WAAW,CAAC,CAAC,MAAM,KAAK,MAAM,SAAS;EAChD;EAEA,OAAO,MAAM;GACX,OAAO,WAAW,CAAC,CAAC,MAAM,OAAO,IAAI;EACvC;EAEA,SAAS,OAAO,CAAC,GAAG;GAClB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,WAAW,WAAW,iBAAiB,KAAK,SAAS;GAG7D,MAAM,OAAO,KAAK,QAAQ,QAAQ,QAAQ,cAAc,SAAS;GACjE,OAAO,IAAI,MAAM,YAAY;IAAE;IAAM,OAAO,KAAK;GAAM,GAAG,SAAS;EACrE;EAEA,OAAO,OAAO,OAAO,CAAC,GAAG;GACvB,MAAM,MAAM,WAAW;GACvB,MAAM,EAAE,cAAc,iBAAiB,KAAK,SAAS;GACrD,OAAO,IAAI,MAAM,OAAO,OAAO,SAAS;EAC1C;CACF;AACF;;;;;;;;;;AChGA,MAAa,uBACX,aAAa;CACX,IAAI;CACJ,OAAO;CACP,OAAO;CACP,YAAY;AACd,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-page-edit",
3
- "version": "3.0.0-next.10",
3
+ "version": "3.0.0-next.12",
4
4
  "private": false,
5
5
  "description": "Document-scoped page-edit capability: PON-addressed rotate/move/delete over the engine DocumentHandle. Owns relative→absolute rotation so framework adapters never re-derive it; the home for pending/undo/gating state.",
6
6
  "type": "module",
@@ -12,13 +12,17 @@
12
12
  "import": "./dist/index.js",
13
13
  "require": "./dist/index.cjs"
14
14
  },
15
+ "./contract": {
16
+ "import": "./dist/contract.js",
17
+ "require": "./dist/contract.cjs"
18
+ },
15
19
  "./package.json": "./package.json"
16
20
  },
17
21
  "files": [
18
22
  "dist"
19
23
  ],
20
24
  "dependencies": {
21
- "@embedpdf/core": "3.0.0-next.10"
25
+ "@embedpdf/core": "3.0.0-next.12"
22
26
  },
23
27
  "devDependencies": {
24
28
  "typescript": "^5.0.0",