@embedpdf/plugin-stamp 3.0.0-next.1 → 3.0.0-next.11

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,190 @@
1
+ import { BinarySource, Engine } from "@embedpdf/engine-core/runtime";
2
+ import { ScriptDiagnostic, ScriptExecutionError, ScriptUiEffect } from "@embedpdf/core-acrojs";
3
+ import { FormScriptingOptions } from "@embedpdf/plugin-form/contract";
4
+ //#region src/types.d.ts
5
+ /**
6
+ * The stamp plugin: a workspace-scoped ASSET substrate.
7
+ *
8
+ * The design law ("documents have a home; assets ride the wire"): imported
9
+ * PDF libraries retain one canonical PDF whose catalog/page `/PieceInfo`
10
+ * carries their metadata. Per-asset PDFs and previews are derived caches used
11
+ * for placement. Standalone PNG/JPEG assets remain loose because the engine
12
+ * intentionally has no raster-to-PDF-page authoring primitive.
13
+ */
14
+ type StampAssetKind = 'stamp' | 'signature' | 'initials';
15
+ /**
16
+ * One asset's SERIALIZABLE descriptor. The bytes and the cached preview are
17
+ * deliberately NOT here — the reducer state stays pure/serializable (kernel
18
+ * rule 1); binary lives in the capability and crosses only as call
19
+ * arguments/returns, mirroring the engine's own BinarySource rule.
20
+ */
21
+ interface StampAsset {
22
+ id: string;
23
+ libraryId: string;
24
+ kind: StampAssetKind;
25
+ name: string;
26
+ /** Intrinsic size in PDF points (the source page's crop box / image pixels 1:1). */
27
+ size: {
28
+ width: number;
29
+ height: number;
30
+ };
31
+ /** What the asset bytes are: a single-page vector PDF, or a raster image. */
32
+ format: 'pdf' | 'png' | 'jpeg';
33
+ /** Canonical library page identity; present for PDF-backed libraries. */
34
+ pageObjectNumber?: number;
35
+ subject?: string;
36
+ categories?: string[];
37
+ }
38
+ /** A named group of assets — one imported PDF becomes one library. */
39
+ interface StampLibrary {
40
+ id: string;
41
+ name: string;
42
+ /** PDF-backed libraries own canonical bytes; loose libraries are raster/pre-sliced conveniences. */
43
+ storage: 'canonical-pdf' | 'loose';
44
+ categories?: string[];
45
+ /** Asset ids in display order. */
46
+ assetIds: string[];
47
+ }
48
+ interface StampState {
49
+ libraries: Record<string, StampLibrary>;
50
+ /** Library display order (insertion order). */
51
+ libraryOrder: string[];
52
+ assets: Record<string, StampAsset>;
53
+ }
54
+ type StampAction = {
55
+ type: 'LIBRARY_ADDED';
56
+ library: StampLibrary;
57
+ } | {
58
+ type: 'LIBRARY_REMOVED';
59
+ libraryId: string;
60
+ } | {
61
+ type: 'ASSET_ADDED';
62
+ asset: StampAsset;
63
+ } | {
64
+ type: 'ASSET_REMOVED';
65
+ assetId: string;
66
+ };
67
+ interface StampConfig {
68
+ /**
69
+ * The ASSET ENGINE port: any `Engine` that can open `{ kind: 'bytes' }` —
70
+ * used only to slice an imported library PDF into per-page assets and
71
+ * render their previews.
72
+ *
73
+ * Omitted → the kernel's own engine is used, which is exactly right for a
74
+ * local deployment (same WASM instance, zero extra cost). In a CLOUD
75
+ * deployment the kernel engine cannot open local bytes, so pass a factory —
76
+ * it is called (and memoized) on the first import, never at viewer boot:
77
+ *
78
+ * ```ts
79
+ * stampPlugin({
80
+ * assetEngine: () => import('@embedpdf/engine').then((m) => m.createLocalEngine()),
81
+ * })
82
+ * ```
83
+ */
84
+ assetEngine?: Engine | (() => Engine | Promise<Engine>);
85
+ /** Cached preview width in device px (import-time render). Default 256. */
86
+ previewWidth?: number;
87
+ /**
88
+ * Opt-in Acrobat JavaScript evaluation for form-backed PDF stamp assets.
89
+ * On arm, the plugin recalculates a temporary copy using the target
90
+ * document's identity/name/clock, flattens it, and arms the resulting
91
+ * static page. Canonical library and derived base bytes stay unchanged.
92
+ */
93
+ scripting?: StampScriptingOptions;
94
+ }
95
+ /**
96
+ * Stamp evaluates dynamic assets in its OWN standalone realm (a detached
97
+ * stamp-asset document is never the viewer document's shared host), so the
98
+ * opt-in switch and the script observers live HERE — deliberately not on
99
+ * `actionsPlugin({ javascript })`, whose port serves the viewer document.
100
+ */
101
+ interface StampScriptingOptions extends FormScriptingOptions {
102
+ /** Explicit opt-in for evaluating dynamic (form-backed) stamp assets. */
103
+ enabled: boolean;
104
+ onUiEffect?: (effect: ScriptUiEffect) => void;
105
+ onDiagnostic?: (diagnostic: ScriptDiagnostic) => void;
106
+ onError?: (error: ScriptExecutionError) => void;
107
+ }
108
+ interface ImportLibraryOptions {
109
+ /** Library display name. Default `'Stamps'`. */
110
+ name?: string;
111
+ /** Library categories written to catalog `/PieceInfo`. */
112
+ categories?: string[];
113
+ /** Kind stamped onto every imported asset. Default `'stamp'`. */
114
+ kind?: StampAssetKind;
115
+ /** Per-page asset names; default `Stamp <n>`. */
116
+ assetName?: (pageIndex: number) => string;
117
+ }
118
+ interface AddAssetInput {
119
+ /** Target library; omitted → a new single-asset library named after the asset. */
120
+ libraryId?: string;
121
+ name: string;
122
+ kind?: StampAssetKind;
123
+ subject?: string;
124
+ categories?: string[];
125
+ /** Single-page PDF (vector) or PNG/JPEG bytes. */
126
+ source: BinarySource;
127
+ /**
128
+ * Paintable preview for pickers + the hover ghost. Loose PDF assets cannot
129
+ * derive one without opening the PDF; canonical libraries render it after
130
+ * insertion. Raster sources default to their own bytes.
131
+ */
132
+ preview?: BinarySource;
133
+ /** Intrinsic size in PDF points. Required for PDF sources; rasters are sniffed. */
134
+ size?: {
135
+ width: number;
136
+ height: number;
137
+ };
138
+ }
139
+ /** A cached, browser-paintable render of an asset (PNG from import; raster assets as-is). */
140
+ interface StampAssetPreview {
141
+ bytes: Uint8Array;
142
+ mimeType: string;
143
+ }
144
+ interface StampCapability {
145
+ libraries(): StampLibrary[];
146
+ library(id: string): StampLibrary | null;
147
+ /** Assets of one library, in library order — or every asset when omitted. */
148
+ assets(libraryId?: string): StampAsset[];
149
+ asset(id: string): StampAsset | null;
150
+ /** The asset's paintable preview, or null while none is cached. */
151
+ assetPreview(id: string): StampAssetPreview | null;
152
+ /** Placement bytes; derived from the canonical page for PDF-backed libraries. */
153
+ assetBytes(id: string): Uint8Array | null;
154
+ /** Canonical library PDF bytes, or null for a loose library/unknown id. */
155
+ libraryBytes(id: string): Uint8Array | null;
156
+ /**
157
+ * Import a PDF as a stamp library: every page becomes one vector asset
158
+ * (single-page PDF bytes + a cached preview render). Uses the asset
159
+ * engine; in a cloud deployment without one configured this rejects with
160
+ * an actionable error. Resolves to the new library id.
161
+ */
162
+ importLibraryPdf(source: BinarySource, opts?: ImportLibraryOptions): Promise<string>;
163
+ /**
164
+ * Add a single asset. A PDF added to a canonical library is inserted as a
165
+ * page and receives `/PieceInfo`; loose assets keep their bytes directly.
166
+ * Raster input cannot be appended to a canonical PDF library.
167
+ */
168
+ addAsset(input: AddAssetInput): Promise<string>;
169
+ /** Remove an asset, deleting its canonical page before state changes when PDF-backed. */
170
+ removeAsset(id: string): Promise<void>;
171
+ /** Remove a library and every asset in it, ordered with in-flight library mutations. */
172
+ removeLibrary(id: string): Promise<void>;
173
+ /**
174
+ * Arm an asset on a document: the next click on that document's pages
175
+ * places it (and the hover ghost previews the exact placement). With
176
+ * scripting enabled, form-backed PDFs are evaluated against that target
177
+ * document and flattened first. Rides `annotation.armStamp` — bytes,
178
+ * preview, and intrinsic size all travel along, so vector stamps keep
179
+ * their true aspect.
180
+ */
181
+ armAsset(documentId: string, assetId: string, opts?: {
182
+ targetWidth?: number;
183
+ }): Promise<void>;
184
+ /** Disarm the stamp tool on a document. */
185
+ disarm(documentId: string): void;
186
+ }
187
+ declare const StampToken: import("@embedpdf/core").CapabilityToken<StampCapability>;
188
+ //#endregion
189
+ export { StampAssetKind as a, StampConfig as c, StampToken as d, StampAsset as i, StampLibrary as l, ImportLibraryOptions as n, StampAssetPreview as o, StampAction as r, StampCapability as s, AddAssetInput as t, StampState as u };
190
+ //# sourceMappingURL=contract-BaN6-ypU.d.cts.map
@@ -0,0 +1,190 @@
1
+ import { BinarySource, Engine } from "@embedpdf/engine-core/runtime";
2
+ import { ScriptDiagnostic, ScriptExecutionError, ScriptUiEffect } from "@embedpdf/core-acrojs";
3
+ import { FormScriptingOptions } from "@embedpdf/plugin-form/contract";
4
+ //#region src/types.d.ts
5
+ /**
6
+ * The stamp plugin: a workspace-scoped ASSET substrate.
7
+ *
8
+ * The design law ("documents have a home; assets ride the wire"): imported
9
+ * PDF libraries retain one canonical PDF whose catalog/page `/PieceInfo`
10
+ * carries their metadata. Per-asset PDFs and previews are derived caches used
11
+ * for placement. Standalone PNG/JPEG assets remain loose because the engine
12
+ * intentionally has no raster-to-PDF-page authoring primitive.
13
+ */
14
+ type StampAssetKind = 'stamp' | 'signature' | 'initials';
15
+ /**
16
+ * One asset's SERIALIZABLE descriptor. The bytes and the cached preview are
17
+ * deliberately NOT here — the reducer state stays pure/serializable (kernel
18
+ * rule 1); binary lives in the capability and crosses only as call
19
+ * arguments/returns, mirroring the engine's own BinarySource rule.
20
+ */
21
+ interface StampAsset {
22
+ id: string;
23
+ libraryId: string;
24
+ kind: StampAssetKind;
25
+ name: string;
26
+ /** Intrinsic size in PDF points (the source page's crop box / image pixels 1:1). */
27
+ size: {
28
+ width: number;
29
+ height: number;
30
+ };
31
+ /** What the asset bytes are: a single-page vector PDF, or a raster image. */
32
+ format: 'pdf' | 'png' | 'jpeg';
33
+ /** Canonical library page identity; present for PDF-backed libraries. */
34
+ pageObjectNumber?: number;
35
+ subject?: string;
36
+ categories?: string[];
37
+ }
38
+ /** A named group of assets — one imported PDF becomes one library. */
39
+ interface StampLibrary {
40
+ id: string;
41
+ name: string;
42
+ /** PDF-backed libraries own canonical bytes; loose libraries are raster/pre-sliced conveniences. */
43
+ storage: 'canonical-pdf' | 'loose';
44
+ categories?: string[];
45
+ /** Asset ids in display order. */
46
+ assetIds: string[];
47
+ }
48
+ interface StampState {
49
+ libraries: Record<string, StampLibrary>;
50
+ /** Library display order (insertion order). */
51
+ libraryOrder: string[];
52
+ assets: Record<string, StampAsset>;
53
+ }
54
+ type StampAction = {
55
+ type: 'LIBRARY_ADDED';
56
+ library: StampLibrary;
57
+ } | {
58
+ type: 'LIBRARY_REMOVED';
59
+ libraryId: string;
60
+ } | {
61
+ type: 'ASSET_ADDED';
62
+ asset: StampAsset;
63
+ } | {
64
+ type: 'ASSET_REMOVED';
65
+ assetId: string;
66
+ };
67
+ interface StampConfig {
68
+ /**
69
+ * The ASSET ENGINE port: any `Engine` that can open `{ kind: 'bytes' }` —
70
+ * used only to slice an imported library PDF into per-page assets and
71
+ * render their previews.
72
+ *
73
+ * Omitted → the kernel's own engine is used, which is exactly right for a
74
+ * local deployment (same WASM instance, zero extra cost). In a CLOUD
75
+ * deployment the kernel engine cannot open local bytes, so pass a factory —
76
+ * it is called (and memoized) on the first import, never at viewer boot:
77
+ *
78
+ * ```ts
79
+ * stampPlugin({
80
+ * assetEngine: () => import('@embedpdf/engine').then((m) => m.createLocalEngine()),
81
+ * })
82
+ * ```
83
+ */
84
+ assetEngine?: Engine | (() => Engine | Promise<Engine>);
85
+ /** Cached preview width in device px (import-time render). Default 256. */
86
+ previewWidth?: number;
87
+ /**
88
+ * Opt-in Acrobat JavaScript evaluation for form-backed PDF stamp assets.
89
+ * On arm, the plugin recalculates a temporary copy using the target
90
+ * document's identity/name/clock, flattens it, and arms the resulting
91
+ * static page. Canonical library and derived base bytes stay unchanged.
92
+ */
93
+ scripting?: StampScriptingOptions;
94
+ }
95
+ /**
96
+ * Stamp evaluates dynamic assets in its OWN standalone realm (a detached
97
+ * stamp-asset document is never the viewer document's shared host), so the
98
+ * opt-in switch and the script observers live HERE — deliberately not on
99
+ * `actionsPlugin({ javascript })`, whose port serves the viewer document.
100
+ */
101
+ interface StampScriptingOptions extends FormScriptingOptions {
102
+ /** Explicit opt-in for evaluating dynamic (form-backed) stamp assets. */
103
+ enabled: boolean;
104
+ onUiEffect?: (effect: ScriptUiEffect) => void;
105
+ onDiagnostic?: (diagnostic: ScriptDiagnostic) => void;
106
+ onError?: (error: ScriptExecutionError) => void;
107
+ }
108
+ interface ImportLibraryOptions {
109
+ /** Library display name. Default `'Stamps'`. */
110
+ name?: string;
111
+ /** Library categories written to catalog `/PieceInfo`. */
112
+ categories?: string[];
113
+ /** Kind stamped onto every imported asset. Default `'stamp'`. */
114
+ kind?: StampAssetKind;
115
+ /** Per-page asset names; default `Stamp <n>`. */
116
+ assetName?: (pageIndex: number) => string;
117
+ }
118
+ interface AddAssetInput {
119
+ /** Target library; omitted → a new single-asset library named after the asset. */
120
+ libraryId?: string;
121
+ name: string;
122
+ kind?: StampAssetKind;
123
+ subject?: string;
124
+ categories?: string[];
125
+ /** Single-page PDF (vector) or PNG/JPEG bytes. */
126
+ source: BinarySource;
127
+ /**
128
+ * Paintable preview for pickers + the hover ghost. Loose PDF assets cannot
129
+ * derive one without opening the PDF; canonical libraries render it after
130
+ * insertion. Raster sources default to their own bytes.
131
+ */
132
+ preview?: BinarySource;
133
+ /** Intrinsic size in PDF points. Required for PDF sources; rasters are sniffed. */
134
+ size?: {
135
+ width: number;
136
+ height: number;
137
+ };
138
+ }
139
+ /** A cached, browser-paintable render of an asset (PNG from import; raster assets as-is). */
140
+ interface StampAssetPreview {
141
+ bytes: Uint8Array;
142
+ mimeType: string;
143
+ }
144
+ interface StampCapability {
145
+ libraries(): StampLibrary[];
146
+ library(id: string): StampLibrary | null;
147
+ /** Assets of one library, in library order — or every asset when omitted. */
148
+ assets(libraryId?: string): StampAsset[];
149
+ asset(id: string): StampAsset | null;
150
+ /** The asset's paintable preview, or null while none is cached. */
151
+ assetPreview(id: string): StampAssetPreview | null;
152
+ /** Placement bytes; derived from the canonical page for PDF-backed libraries. */
153
+ assetBytes(id: string): Uint8Array | null;
154
+ /** Canonical library PDF bytes, or null for a loose library/unknown id. */
155
+ libraryBytes(id: string): Uint8Array | null;
156
+ /**
157
+ * Import a PDF as a stamp library: every page becomes one vector asset
158
+ * (single-page PDF bytes + a cached preview render). Uses the asset
159
+ * engine; in a cloud deployment without one configured this rejects with
160
+ * an actionable error. Resolves to the new library id.
161
+ */
162
+ importLibraryPdf(source: BinarySource, opts?: ImportLibraryOptions): Promise<string>;
163
+ /**
164
+ * Add a single asset. A PDF added to a canonical library is inserted as a
165
+ * page and receives `/PieceInfo`; loose assets keep their bytes directly.
166
+ * Raster input cannot be appended to a canonical PDF library.
167
+ */
168
+ addAsset(input: AddAssetInput): Promise<string>;
169
+ /** Remove an asset, deleting its canonical page before state changes when PDF-backed. */
170
+ removeAsset(id: string): Promise<void>;
171
+ /** Remove a library and every asset in it, ordered with in-flight library mutations. */
172
+ removeLibrary(id: string): Promise<void>;
173
+ /**
174
+ * Arm an asset on a document: the next click on that document's pages
175
+ * places it (and the hover ghost previews the exact placement). With
176
+ * scripting enabled, form-backed PDFs are evaluated against that target
177
+ * document and flattened first. Rides `annotation.armStamp` — bytes,
178
+ * preview, and intrinsic size all travel along, so vector stamps keep
179
+ * their true aspect.
180
+ */
181
+ armAsset(documentId: string, assetId: string, opts?: {
182
+ targetWidth?: number;
183
+ }): Promise<void>;
184
+ /** Disarm the stamp tool on a document. */
185
+ disarm(documentId: string): void;
186
+ }
187
+ declare const StampToken: import("@embedpdf/core").CapabilityToken<StampCapability>;
188
+ //#endregion
189
+ export { StampAssetKind as a, StampConfig as c, StampToken as d, StampAsset as i, StampLibrary as l, ImportLibraryOptions as n, StampAssetPreview as o, StampAction as r, StampCapability as s, AddAssetInput as t, StampState as u };
190
+ //# sourceMappingURL=contract-BaN6-ypU.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { createCapabilityToken } from "@embedpdf/core";
2
+ //#region src/types.ts
3
+ const StampToken = createCapabilityToken("stamp");
4
+ //#endregion
5
+ export { StampToken as t };
6
+
7
+ //# sourceMappingURL=contract-CkPaVNAJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-CkPaVNAJ.js","names":[],"sources":["../src/types.ts"],"sourcesContent":["import type { BinarySource, Engine } from '@embedpdf/engine-core/runtime';\nimport { createCapabilityToken } from '@embedpdf/core';\nimport type {\n ScriptDiagnostic,\n ScriptExecutionError,\n ScriptUiEffect,\n} from '@embedpdf/core-acrojs';\nimport type { FormScriptingOptions } from '@embedpdf/plugin-form/contract';\n\n/**\n * The stamp plugin: a workspace-scoped ASSET substrate.\n *\n * The design law (\"documents have a home; assets ride the wire\"): imported\n * PDF libraries retain one canonical PDF whose catalog/page `/PieceInfo`\n * carries their metadata. Per-asset PDFs and previews are derived caches used\n * for placement. Standalone PNG/JPEG assets remain loose because the engine\n * intentionally has no raster-to-PDF-page authoring primitive.\n */\n\nexport type StampAssetKind = 'stamp' | 'signature' | 'initials';\n\n/**\n * One asset's SERIALIZABLE descriptor. The bytes and the cached preview are\n * deliberately NOT here — the reducer state stays pure/serializable (kernel\n * rule 1); binary lives in the capability and crosses only as call\n * arguments/returns, mirroring the engine's own BinarySource rule.\n */\nexport interface StampAsset {\n id: string;\n libraryId: string;\n kind: StampAssetKind;\n name: string;\n /** Intrinsic size in PDF points (the source page's crop box / image pixels 1:1). */\n size: { width: number; height: number };\n /** What the asset bytes are: a single-page vector PDF, or a raster image. */\n format: 'pdf' | 'png' | 'jpeg';\n /** Canonical library page identity; present for PDF-backed libraries. */\n pageObjectNumber?: number;\n subject?: string;\n categories?: string[];\n}\n\n/** A named group of assets — one imported PDF becomes one library. */\nexport interface StampLibrary {\n id: string;\n name: string;\n /** PDF-backed libraries own canonical bytes; loose libraries are raster/pre-sliced conveniences. */\n storage: 'canonical-pdf' | 'loose';\n categories?: string[];\n /** Asset ids in display order. */\n assetIds: string[];\n}\n\nexport interface StampState {\n libraries: Record<string, StampLibrary>;\n /** Library display order (insertion order). */\n libraryOrder: string[];\n assets: Record<string, StampAsset>;\n}\n\nexport type StampAction =\n | { type: 'LIBRARY_ADDED'; library: StampLibrary }\n | { type: 'LIBRARY_REMOVED'; libraryId: string }\n | { type: 'ASSET_ADDED'; asset: StampAsset }\n | { type: 'ASSET_REMOVED'; assetId: string };\n\nexport interface StampConfig {\n /**\n * The ASSET ENGINE port: any `Engine` that can open `{ kind: 'bytes' }` —\n * used only to slice an imported library PDF into per-page assets and\n * render their previews.\n *\n * Omitted → the kernel's own engine is used, which is exactly right for a\n * local deployment (same WASM instance, zero extra cost). In a CLOUD\n * deployment the kernel engine cannot open local bytes, so pass a factory —\n * it is called (and memoized) on the first import, never at viewer boot:\n *\n * ```ts\n * stampPlugin({\n * assetEngine: () => import('@embedpdf/engine').then((m) => m.createLocalEngine()),\n * })\n * ```\n */\n assetEngine?: Engine | (() => Engine | Promise<Engine>);\n /** Cached preview width in device px (import-time render). Default 256. */\n previewWidth?: number;\n /**\n * Opt-in Acrobat JavaScript evaluation for form-backed PDF stamp assets.\n * On arm, the plugin recalculates a temporary copy using the target\n * document's identity/name/clock, flattens it, and arms the resulting\n * static page. Canonical library and derived base bytes stay unchanged.\n */\n scripting?: StampScriptingOptions;\n}\n\n/**\n * Stamp evaluates dynamic assets in its OWN standalone realm (a detached\n * stamp-asset document is never the viewer document's shared host), so the\n * opt-in switch and the script observers live HERE — deliberately not on\n * `actionsPlugin({ javascript })`, whose port serves the viewer document.\n */\nexport interface StampScriptingOptions extends FormScriptingOptions {\n /** Explicit opt-in for evaluating dynamic (form-backed) stamp assets. */\n enabled: boolean;\n onUiEffect?: (effect: ScriptUiEffect) => void;\n onDiagnostic?: (diagnostic: ScriptDiagnostic) => void;\n onError?: (error: ScriptExecutionError) => void;\n}\n\nexport interface ImportLibraryOptions {\n /** Library display name. Default `'Stamps'`. */\n name?: string;\n /** Library categories written to catalog `/PieceInfo`. */\n categories?: string[];\n /** Kind stamped onto every imported asset. Default `'stamp'`. */\n kind?: StampAssetKind;\n /** Per-page asset names; default `Stamp <n>`. */\n assetName?: (pageIndex: number) => string;\n}\n\nexport interface AddAssetInput {\n /** Target library; omitted → a new single-asset library named after the asset. */\n libraryId?: string;\n name: string;\n kind?: StampAssetKind;\n subject?: string;\n categories?: string[];\n /** Single-page PDF (vector) or PNG/JPEG bytes. */\n source: BinarySource;\n /**\n * Paintable preview for pickers + the hover ghost. Loose PDF assets cannot\n * derive one without opening the PDF; canonical libraries render it after\n * insertion. Raster sources default to their own bytes.\n */\n preview?: BinarySource;\n /** Intrinsic size in PDF points. Required for PDF sources; rasters are sniffed. */\n size?: { width: number; height: number };\n}\n\n/** A cached, browser-paintable render of an asset (PNG from import; raster assets as-is). */\nexport interface StampAssetPreview {\n bytes: Uint8Array;\n mimeType: string;\n}\n\nexport interface StampCapability {\n // ── selectors (pure reads over serializable state) ──\n libraries(): StampLibrary[];\n library(id: string): StampLibrary | null;\n /** Assets of one library, in library order — or every asset when omitted. */\n assets(libraryId?: string): StampAsset[];\n asset(id: string): StampAsset | null;\n // ── binary reads (capability-held, never store state) ──\n /** The asset's paintable preview, or null while none is cached. */\n assetPreview(id: string): StampAssetPreview | null;\n /** Placement bytes; derived from the canonical page for PDF-backed libraries. */\n assetBytes(id: string): Uint8Array | null;\n /** Canonical library PDF bytes, or null for a loose library/unknown id. */\n libraryBytes(id: string): Uint8Array | null;\n // ── library intents ──\n /**\n * Import a PDF as a stamp library: every page becomes one vector asset\n * (single-page PDF bytes + a cached preview render). Uses the asset\n * engine; in a cloud deployment without one configured this rejects with\n * an actionable error. Resolves to the new library id.\n */\n importLibraryPdf(source: BinarySource, opts?: ImportLibraryOptions): Promise<string>;\n /**\n * Add a single asset. A PDF added to a canonical library is inserted as a\n * page and receives `/PieceInfo`; loose assets keep their bytes directly.\n * Raster input cannot be appended to a canonical PDF library.\n */\n addAsset(input: AddAssetInput): Promise<string>;\n /** Remove an asset, deleting its canonical page before state changes when PDF-backed. */\n removeAsset(id: string): Promise<void>;\n /** Remove a library and every asset in it, ordered with in-flight library mutations. */\n removeLibrary(id: string): Promise<void>;\n // ── placement (delegates to the annotation plugin of the named document) ──\n /**\n * Arm an asset on a document: the next click on that document's pages\n * places it (and the hover ghost previews the exact placement). With\n * scripting enabled, form-backed PDFs are evaluated against that target\n * document and flattened first. Rides `annotation.armStamp` — bytes,\n * preview, and intrinsic size all travel along, so vector stamps keep\n * their true aspect.\n */\n armAsset(documentId: string, assetId: string, opts?: { targetWidth?: number }): Promise<void>;\n /** Disarm the stamp tool on a document. */\n disarm(documentId: string): void;\n}\n\nexport const StampToken = createCapabilityToken<StampCapability>('stamp');\n"],"mappings":";;AA+LA,MAAa,aAAa,sBAAuC,OAAO"}
@@ -0,0 +1,11 @@
1
+ //#region src/types.ts
2
+ const StampToken = (0, require("@embedpdf/core").createCapabilityToken)("stamp");
3
+ //#endregion
4
+ Object.defineProperty(exports, "StampToken", {
5
+ enumerable: true,
6
+ get: function() {
7
+ return StampToken;
8
+ }
9
+ });
10
+
11
+ //# sourceMappingURL=contract-DmQ4peF2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract-DmQ4peF2.cjs","names":[],"sources":["../src/types.ts"],"sourcesContent":["import type { BinarySource, Engine } from '@embedpdf/engine-core/runtime';\nimport { createCapabilityToken } from '@embedpdf/core';\nimport type {\n ScriptDiagnostic,\n ScriptExecutionError,\n ScriptUiEffect,\n} from '@embedpdf/core-acrojs';\nimport type { FormScriptingOptions } from '@embedpdf/plugin-form/contract';\n\n/**\n * The stamp plugin: a workspace-scoped ASSET substrate.\n *\n * The design law (\"documents have a home; assets ride the wire\"): imported\n * PDF libraries retain one canonical PDF whose catalog/page `/PieceInfo`\n * carries their metadata. Per-asset PDFs and previews are derived caches used\n * for placement. Standalone PNG/JPEG assets remain loose because the engine\n * intentionally has no raster-to-PDF-page authoring primitive.\n */\n\nexport type StampAssetKind = 'stamp' | 'signature' | 'initials';\n\n/**\n * One asset's SERIALIZABLE descriptor. The bytes and the cached preview are\n * deliberately NOT here — the reducer state stays pure/serializable (kernel\n * rule 1); binary lives in the capability and crosses only as call\n * arguments/returns, mirroring the engine's own BinarySource rule.\n */\nexport interface StampAsset {\n id: string;\n libraryId: string;\n kind: StampAssetKind;\n name: string;\n /** Intrinsic size in PDF points (the source page's crop box / image pixels 1:1). */\n size: { width: number; height: number };\n /** What the asset bytes are: a single-page vector PDF, or a raster image. */\n format: 'pdf' | 'png' | 'jpeg';\n /** Canonical library page identity; present for PDF-backed libraries. */\n pageObjectNumber?: number;\n subject?: string;\n categories?: string[];\n}\n\n/** A named group of assets — one imported PDF becomes one library. */\nexport interface StampLibrary {\n id: string;\n name: string;\n /** PDF-backed libraries own canonical bytes; loose libraries are raster/pre-sliced conveniences. */\n storage: 'canonical-pdf' | 'loose';\n categories?: string[];\n /** Asset ids in display order. */\n assetIds: string[];\n}\n\nexport interface StampState {\n libraries: Record<string, StampLibrary>;\n /** Library display order (insertion order). */\n libraryOrder: string[];\n assets: Record<string, StampAsset>;\n}\n\nexport type StampAction =\n | { type: 'LIBRARY_ADDED'; library: StampLibrary }\n | { type: 'LIBRARY_REMOVED'; libraryId: string }\n | { type: 'ASSET_ADDED'; asset: StampAsset }\n | { type: 'ASSET_REMOVED'; assetId: string };\n\nexport interface StampConfig {\n /**\n * The ASSET ENGINE port: any `Engine` that can open `{ kind: 'bytes' }` —\n * used only to slice an imported library PDF into per-page assets and\n * render their previews.\n *\n * Omitted → the kernel's own engine is used, which is exactly right for a\n * local deployment (same WASM instance, zero extra cost). In a CLOUD\n * deployment the kernel engine cannot open local bytes, so pass a factory —\n * it is called (and memoized) on the first import, never at viewer boot:\n *\n * ```ts\n * stampPlugin({\n * assetEngine: () => import('@embedpdf/engine').then((m) => m.createLocalEngine()),\n * })\n * ```\n */\n assetEngine?: Engine | (() => Engine | Promise<Engine>);\n /** Cached preview width in device px (import-time render). Default 256. */\n previewWidth?: number;\n /**\n * Opt-in Acrobat JavaScript evaluation for form-backed PDF stamp assets.\n * On arm, the plugin recalculates a temporary copy using the target\n * document's identity/name/clock, flattens it, and arms the resulting\n * static page. Canonical library and derived base bytes stay unchanged.\n */\n scripting?: StampScriptingOptions;\n}\n\n/**\n * Stamp evaluates dynamic assets in its OWN standalone realm (a detached\n * stamp-asset document is never the viewer document's shared host), so the\n * opt-in switch and the script observers live HERE — deliberately not on\n * `actionsPlugin({ javascript })`, whose port serves the viewer document.\n */\nexport interface StampScriptingOptions extends FormScriptingOptions {\n /** Explicit opt-in for evaluating dynamic (form-backed) stamp assets. */\n enabled: boolean;\n onUiEffect?: (effect: ScriptUiEffect) => void;\n onDiagnostic?: (diagnostic: ScriptDiagnostic) => void;\n onError?: (error: ScriptExecutionError) => void;\n}\n\nexport interface ImportLibraryOptions {\n /** Library display name. Default `'Stamps'`. */\n name?: string;\n /** Library categories written to catalog `/PieceInfo`. */\n categories?: string[];\n /** Kind stamped onto every imported asset. Default `'stamp'`. */\n kind?: StampAssetKind;\n /** Per-page asset names; default `Stamp <n>`. */\n assetName?: (pageIndex: number) => string;\n}\n\nexport interface AddAssetInput {\n /** Target library; omitted → a new single-asset library named after the asset. */\n libraryId?: string;\n name: string;\n kind?: StampAssetKind;\n subject?: string;\n categories?: string[];\n /** Single-page PDF (vector) or PNG/JPEG bytes. */\n source: BinarySource;\n /**\n * Paintable preview for pickers + the hover ghost. Loose PDF assets cannot\n * derive one without opening the PDF; canonical libraries render it after\n * insertion. Raster sources default to their own bytes.\n */\n preview?: BinarySource;\n /** Intrinsic size in PDF points. Required for PDF sources; rasters are sniffed. */\n size?: { width: number; height: number };\n}\n\n/** A cached, browser-paintable render of an asset (PNG from import; raster assets as-is). */\nexport interface StampAssetPreview {\n bytes: Uint8Array;\n mimeType: string;\n}\n\nexport interface StampCapability {\n // ── selectors (pure reads over serializable state) ──\n libraries(): StampLibrary[];\n library(id: string): StampLibrary | null;\n /** Assets of one library, in library order — or every asset when omitted. */\n assets(libraryId?: string): StampAsset[];\n asset(id: string): StampAsset | null;\n // ── binary reads (capability-held, never store state) ──\n /** The asset's paintable preview, or null while none is cached. */\n assetPreview(id: string): StampAssetPreview | null;\n /** Placement bytes; derived from the canonical page for PDF-backed libraries. */\n assetBytes(id: string): Uint8Array | null;\n /** Canonical library PDF bytes, or null for a loose library/unknown id. */\n libraryBytes(id: string): Uint8Array | null;\n // ── library intents ──\n /**\n * Import a PDF as a stamp library: every page becomes one vector asset\n * (single-page PDF bytes + a cached preview render). Uses the asset\n * engine; in a cloud deployment without one configured this rejects with\n * an actionable error. Resolves to the new library id.\n */\n importLibraryPdf(source: BinarySource, opts?: ImportLibraryOptions): Promise<string>;\n /**\n * Add a single asset. A PDF added to a canonical library is inserted as a\n * page and receives `/PieceInfo`; loose assets keep their bytes directly.\n * Raster input cannot be appended to a canonical PDF library.\n */\n addAsset(input: AddAssetInput): Promise<string>;\n /** Remove an asset, deleting its canonical page before state changes when PDF-backed. */\n removeAsset(id: string): Promise<void>;\n /** Remove a library and every asset in it, ordered with in-flight library mutations. */\n removeLibrary(id: string): Promise<void>;\n // ── placement (delegates to the annotation plugin of the named document) ──\n /**\n * Arm an asset on a document: the next click on that document's pages\n * places it (and the hover ghost previews the exact placement). With\n * scripting enabled, form-backed PDFs are evaluated against that target\n * document and flattened first. Rides `annotation.armStamp` — bytes,\n * preview, and intrinsic size all travel along, so vector stamps keep\n * their true aspect.\n */\n armAsset(documentId: string, assetId: string, opts?: { targetWidth?: number }): Promise<void>;\n /** Disarm the stamp tool on a document. */\n disarm(documentId: string): void;\n}\n\nexport const StampToken = createCapabilityToken<StampCapability>('stamp');\n"],"mappings":";AA+LA,MAAa,cAAA,2BAAA,CAAA,CAAA,sBAAA,CAAoD,OAAO"}
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_contract = require("./contract-DmQ4peF2.cjs");
3
+ exports.StampToken = require_contract.StampToken;
@@ -0,0 +1,2 @@
1
+ import { a as StampAssetKind, c as StampConfig, d as StampToken, i as StampAsset, l as StampLibrary, n as ImportLibraryOptions, o as StampAssetPreview, s as StampCapability, t as AddAssetInput, u as StampState } from "./contract-BaN6-ypU.cjs";
2
+ export { type AddAssetInput, type ImportLibraryOptions, type StampAsset, type StampAssetKind, type StampAssetPreview, type StampCapability, type StampConfig, type StampLibrary, type StampState, StampToken };
@@ -0,0 +1,2 @@
1
+ import { a as StampAssetKind, c as StampConfig, d as StampToken, i as StampAsset, l as StampLibrary, n as ImportLibraryOptions, o as StampAssetPreview, s as StampCapability, t as AddAssetInput, u as StampState } from "./contract-BaN6-ypU.js";
2
+ export { type AddAssetInput, type ImportLibraryOptions, type StampAsset, type StampAssetKind, type StampAssetPreview, type StampCapability, type StampConfig, type StampLibrary, type StampState, StampToken };
@@ -0,0 +1,2 @@
1
+ import { t as StampToken } from "./contract-CkPaVNAJ.js";
2
+ export { StampToken };
package/dist/index.cjs CHANGED
@@ -1,8 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_contract = require("./contract-DmQ4peF2.cjs");
2
3
  let _embedpdf_core = require("@embedpdf/core");
3
4
  let _embedpdf_engine_core_runtime = require("@embedpdf/engine-core/runtime");
4
- let _embedpdf_plugin_annotation = require("@embedpdf/plugin-annotation");
5
- let _embedpdf_plugin_form = require("@embedpdf/plugin-form");
5
+ let _embedpdf_plugin_annotation_contract = require("@embedpdf/plugin-annotation/contract");
6
+ let _embedpdf_plugin_form_scripting = require("@embedpdf/plugin-form/scripting");
6
7
  //#region src/capability.ts
7
8
  const DEFAULT_PREVIEW_WIDTH = 256;
8
9
  const LIBRARY_PIECEINFO_APP = "EMBD_StampLibrary";
@@ -125,7 +126,7 @@ function createStampCapability(ctx, config = {}) {
125
126
  const doc = await openAssetDocument(new Uint8Array(resolved.bytes));
126
127
  let imported;
127
128
  try {
128
- if (!doc.pieceInfo || !doc.pages.extract) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotImplemented, "[stamp] canonical PDF libraries need an asset engine with pieceInfo and pages.extract");
129
+ if (!doc.pieceInfo) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotImplemented, "[stamp] canonical PDF libraries need an asset engine with pieceInfo");
129
130
  const snapshot = await doc.pages.list();
130
131
  if (snapshot.pageCount === 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, "[stamp] a canonical stamp library PDF must contain at least one page");
131
132
  const pages = snapshot.pages.map((layout) => {
@@ -246,7 +247,6 @@ function createStampCapability(ctx, config = {}) {
246
247
  const doc = await openAssetDocument(canonicalBytes);
247
248
  let appended;
248
249
  try {
249
- if (!doc.pages.insert || !doc.pages.extract) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotImplemented, "[stamp] appending to a canonical library needs pages.insert and pages.extract");
250
250
  const result = await doc.pages.insert(new Uint8Array(resolved.bytes));
251
251
  if (result.insertedPageObjectNumbers.length !== 1) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, "[stamp] a canonical library asset must be a single-page PDF");
252
252
  const pageObjectNumber = result.insertedPageObjectNumbers[0];
@@ -407,17 +407,14 @@ function createStampCapability(ctx, config = {}) {
407
407
  const layout = await doc.pages.list();
408
408
  const selectedPage = asset.pageObjectNumber === void 0 ? layout.pageCount === 1 ? layout.pages[0] : void 0 : layout.pages.find(({ pageObjectNumber }) => pageObjectNumber === asset.pageObjectNumber);
409
409
  if (!selectedPage) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, canonicalBytes ? `[stamp] canonical page ${asset.pageObjectNumber ?? "unknown"} no longer exists` : "[stamp] a loose dynamic stamp asset must contain exactly one page");
410
- const snapshot = await doc.forms.list();
411
- if (!snapshot.fields.some((field) => field.widgets.some(({ pageObjectNumber }) => pageObjectNumber === selectedPage.pageObjectNumber))) return bin;
410
+ if (!(await doc.forms.list()).fields.some((field) => field.widgets.some(({ pageObjectNumber }) => pageObjectNumber === selectedPage.pageObjectNumber))) return bin;
412
411
  if (!doc.pages.flatten || !doc.pages.extract) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotImplemented, "[stamp] dynamic PDF stamps need an asset engine with pages.flatten and pages.extract");
413
- const scriptingConfig = config.scripting;
414
- scripting = (0, _embedpdf_plugin_form.createFormScriptingController)({
412
+ scripting = (0, _embedpdf_plugin_form_scripting.createFormScriptingController)({
415
413
  doc,
416
414
  document: () => targetMeta,
417
- config: scriptingConfig,
418
- sandboxFactory: scriptingConfig.sandboxFactory ?? (() => import("@embedpdf/core-js-sandbox").then(({ createQuickJsSandbox }) => createQuickJsSandbox()))
415
+ config: config.scripting
419
416
  });
420
- const result = await scripting.recalculate(snapshot);
417
+ const result = await scripting.recalculate();
421
418
  surfaceScriptingResult(result);
422
419
  if (result.status === "failed") throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, `[stamp] dynamic stamp scripting failed: ${result.error?.message ?? "native form effect failed"}`);
423
420
  const pageObjectNumber = selectedPage.pageObjectNumber;
@@ -447,7 +444,7 @@ function createStampCapability(ctx, config = {}) {
447
444
  const bin = binaries.get(assetId);
448
445
  if (!asset || !bin) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotFound, `[stamp] unknown asset '${assetId}'`);
449
446
  const placement = await materializeForPlacement(documentId, asset, bin);
450
- await ctx.forDocument(_embedpdf_plugin_annotation.AnnotationToken, documentId).armStamp({
447
+ await ctx.forDocument(_embedpdf_plugin_annotation_contract.AnnotationToken, documentId).armStamp({
451
448
  source: placement.bytes,
452
449
  preview: placement.preview ? {
453
450
  data: placement.preview.bytes,
@@ -488,7 +485,7 @@ function createStampCapability(ctx, config = {}) {
488
485
  removeAsset,
489
486
  removeLibrary,
490
487
  armAsset,
491
- disarm: (documentId) => ctx.forDocument(_embedpdf_plugin_annotation.AnnotationToken, documentId).disarmStamp()
488
+ disarm: (documentId) => ctx.forDocument(_embedpdf_plugin_annotation_contract.AnnotationToken, documentId).disarmStamp()
492
489
  };
493
490
  }
494
491
  //#endregion
@@ -564,9 +561,6 @@ const stampReducer = (state, action) => {
564
561
  }
565
562
  };
566
563
  //#endregion
567
- //#region src/types.ts
568
- const StampToken = (0, _embedpdf_core.createCapabilityToken)("stamp");
569
- //#endregion
570
564
  //#region src/stamp.plugin.ts
571
565
  /**
572
566
  * The stamp plugin. WORKSPACE-scoped: libraries are shared across every open
@@ -578,14 +572,14 @@ const StampToken = (0, _embedpdf_core.createCapabilityToken)("stamp");
578
572
  */
579
573
  const stampPlugin = (config = {}) => (0, _embedpdf_core.definePlugin)({
580
574
  id: "stamp",
581
- token: StampToken,
575
+ token: require_contract.StampToken,
582
576
  scope: "workspace",
583
577
  initialState: initialStampState,
584
578
  reduce: stampReducer,
585
579
  capability: (ctx) => createStampCapability(ctx, config)
586
580
  });
587
581
  //#endregion
588
- exports.StampToken = StampToken;
582
+ exports.StampToken = require_contract.StampToken;
589
583
  exports.stampPlugin = stampPlugin;
590
584
 
591
585
  //# sourceMappingURL=index.cjs.map