@embedpdf/plugin-signature 2.15.0 → 3.0.0-next.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +192 -21
  2. package/README.md +38 -0
  3. package/dist/contract-BvHa9Zl_.d.cts +176 -0
  4. package/dist/contract-C3nQtwGf.js +14 -0
  5. package/dist/contract-C3nQtwGf.js.map +1 -0
  6. package/dist/contract-CojqGdMH.cjs +43 -0
  7. package/dist/contract-CojqGdMH.cjs.map +1 -0
  8. package/dist/contract-Dg50puf7.d.ts +176 -0
  9. package/dist/contract.cjs +7 -0
  10. package/dist/contract.d.cts +2 -0
  11. package/dist/contract.d.ts +2 -0
  12. package/dist/contract.js +2 -0
  13. package/dist/index.cjs +498 -2
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +35 -0
  16. package/dist/index.d.ts +35 -1
  17. package/dist/index.js +450 -511
  18. package/dist/index.js.map +1 -1
  19. package/package.json +28 -58
  20. package/dist/lib/actions.d.ts +0 -14
  21. package/dist/lib/handlers/signature-ink.handler.d.ts +0 -4
  22. package/dist/lib/handlers/signature-stamp.handler.d.ts +0 -4
  23. package/dist/lib/index.d.ts +0 -12
  24. package/dist/lib/manifest.d.ts +0 -4
  25. package/dist/lib/reducer.d.ts +0 -5
  26. package/dist/lib/serialization.d.ts +0 -30
  27. package/dist/lib/signature-plugin.d.ts +0 -27
  28. package/dist/lib/tools.d.ts +0 -113
  29. package/dist/lib/types.d.ts +0 -114
  30. package/dist/preact/adapter.d.ts +0 -5
  31. package/dist/preact/annotation.d.ts +0 -1
  32. package/dist/preact/core.d.ts +0 -1
  33. package/dist/preact/index.cjs +0 -2
  34. package/dist/preact/index.cjs.map +0 -1
  35. package/dist/preact/index.d.ts +0 -1
  36. package/dist/preact/index.js +0 -464
  37. package/dist/preact/index.js.map +0 -1
  38. package/dist/react/adapter.d.ts +0 -2
  39. package/dist/react/annotation.d.ts +0 -1
  40. package/dist/react/core.d.ts +0 -1
  41. package/dist/react/index.cjs +0 -2
  42. package/dist/react/index.cjs.map +0 -1
  43. package/dist/react/index.d.ts +0 -1
  44. package/dist/react/index.js +0 -463
  45. package/dist/react/index.js.map +0 -1
  46. package/dist/shared/components/crop-canvas.d.ts +0 -14
  47. package/dist/shared/components/index.d.ts +0 -2
  48. package/dist/shared/components/signature-draw-pad.d.ts +0 -12
  49. package/dist/shared/components/signature-type-pad.d.ts +0 -14
  50. package/dist/shared/hooks/index.d.ts +0 -2
  51. package/dist/shared/hooks/use-signature-upload.d.ts +0 -21
  52. package/dist/shared/hooks/use-signature.d.ts +0 -16
  53. package/dist/shared/index.d.ts +0 -4
  54. package/dist/shared-preact/components/crop-canvas.d.ts +0 -14
  55. package/dist/shared-preact/components/index.d.ts +0 -2
  56. package/dist/shared-preact/components/signature-draw-pad.d.ts +0 -12
  57. package/dist/shared-preact/components/signature-type-pad.d.ts +0 -14
  58. package/dist/shared-preact/hooks/index.d.ts +0 -2
  59. package/dist/shared-preact/hooks/use-signature-upload.d.ts +0 -21
  60. package/dist/shared-preact/hooks/use-signature.d.ts +0 -16
  61. package/dist/shared-preact/index.d.ts +0 -4
  62. package/dist/shared-react/components/crop-canvas.d.ts +0 -14
  63. package/dist/shared-react/components/index.d.ts +0 -2
  64. package/dist/shared-react/components/signature-draw-pad.d.ts +0 -12
  65. package/dist/shared-react/components/signature-type-pad.d.ts +0 -14
  66. package/dist/shared-react/hooks/index.d.ts +0 -2
  67. package/dist/shared-react/hooks/use-signature-upload.d.ts +0 -21
  68. package/dist/shared-react/hooks/use-signature.d.ts +0 -16
  69. package/dist/shared-react/index.d.ts +0 -4
  70. package/dist/shared-vue/components/crop-canvas.d.ts +0 -14
  71. package/dist/svelte/components/SignatureDrawPad.svelte.d.ts +0 -12
  72. package/dist/svelte/components/SignatureTypePad.svelte.d.ts +0 -14
  73. package/dist/svelte/components/index.d.ts +0 -2
  74. package/dist/svelte/hooks/index.d.ts +0 -2
  75. package/dist/svelte/hooks/use-signature-upload.svelte.d.ts +0 -21
  76. package/dist/svelte/hooks/use-signature.svelte.d.ts +0 -17
  77. package/dist/svelte/index.cjs +0 -2
  78. package/dist/svelte/index.cjs.map +0 -1
  79. package/dist/svelte/index.d.ts +0 -4
  80. package/dist/svelte/index.js +0 -415
  81. package/dist/svelte/index.js.map +0 -1
  82. package/dist/vue/components/SignatureDrawPad.vue.d.ts +0 -15
  83. package/dist/vue/components/SignatureTypePad.vue.d.ts +0 -19
  84. package/dist/vue/components/index.d.ts +0 -2
  85. package/dist/vue/hooks/index.d.ts +0 -2
  86. package/dist/vue/hooks/use-signature-upload.d.ts +0 -20
  87. package/dist/vue/hooks/use-signature.d.ts +0 -176
  88. package/dist/vue/index.cjs +0 -2
  89. package/dist/vue/index.cjs.map +0 -1
  90. package/dist/vue/index.d.ts +0 -4
  91. package/dist/vue/index.js +0 -453
  92. package/dist/vue/index.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/types.ts","../src/lib/manifest.ts","../src/lib/actions.ts","../src/lib/handlers/signature-stamp.handler.ts","../src/lib/handlers/signature-ink.handler.ts","../src/lib/tools.ts","../src/lib/signature-plugin.ts","../src/lib/reducer.ts","../src/lib/serialization.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePluginConfig, EventHook } from '@embedpdf/core';\n\n// ---------------------------------------------------------------------------\n// Enums\n// ---------------------------------------------------------------------------\n\nexport enum SignatureMode {\n SignatureOnly = 'signature-only',\n SignatureAndInitials = 'signature-and-initials',\n}\n\nexport enum SignatureCreationType {\n Draw = 'draw',\n Type = 'type',\n Upload = 'upload',\n}\n\nexport enum SignatureFieldKind {\n Signature = 'signature',\n Initials = 'initials',\n}\n\n// ---------------------------------------------------------------------------\n// Data model\n// ---------------------------------------------------------------------------\n\nexport interface SignatureInkData {\n inkList: Array<{ points: Array<{ x: number; y: number }> }>;\n strokeWidth: number;\n strokeColor: string;\n size: { width: number; height: number };\n}\n\ninterface SignatureFieldBase {\n label?: string;\n previewDataUrl: string;\n}\n\nexport interface SignatureInkFieldDefinition extends SignatureFieldBase {\n creationType: SignatureCreationType.Draw;\n inkData: SignatureInkData;\n}\n\nexport interface SignatureStampFieldDefinition extends SignatureFieldBase {\n creationType: SignatureCreationType.Type | SignatureCreationType.Upload;\n imageMimeType?: string;\n imageSize?: { width: number; height: number };\n imageData?: ArrayBuffer;\n}\n\nexport type SignatureFieldDefinition = SignatureInkFieldDefinition | SignatureStampFieldDefinition;\n\nexport interface SignatureEntry {\n id: string;\n createdAt: number;\n signature: SignatureFieldDefinition;\n initials?: SignatureFieldDefinition;\n}\n\n// ---------------------------------------------------------------------------\n// Plugin config\n// ---------------------------------------------------------------------------\n\nexport interface SignaturePluginConfig extends BasePluginConfig {\n mode: SignatureMode;\n defaultSize?: { width: number; height: number };\n}\n\n// ---------------------------------------------------------------------------\n// State\n// ---------------------------------------------------------------------------\n\nexport interface SignatureState {\n entryIds: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Tool context types (declaration-merged into ToolContextMap)\n// ---------------------------------------------------------------------------\n\nexport interface SignatureStampToolContext {\n imageData: ArrayBuffer;\n ghostUrl: string;\n targetSize: { width: number; height: number };\n entryId: string;\n kind: SignatureFieldKind;\n}\n\nexport interface SignatureInkToolContext {\n inkData: SignatureInkData;\n targetSize: { width: number; height: number };\n entryId: string;\n kind: SignatureFieldKind;\n}\n\ndeclare module '@embedpdf/plugin-annotation' {\n interface ToolContextMap {\n signatureStamp: SignatureStampToolContext;\n signatureInk: SignatureInkToolContext;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Capability / Scope\n// ---------------------------------------------------------------------------\n\nexport interface ActivePlacementInfo {\n entryId: string;\n kind: SignatureFieldKind;\n}\n\nexport interface ActivePlacementChangeEvent {\n documentId: string;\n activePlacement: ActivePlacementInfo | null;\n}\n\nexport interface SignatureScope {\n activateSignaturePlacement(entryId: string): void;\n activateInitialsPlacement(entryId: string): void;\n deactivatePlacement(): void;\n getActivePlacement(): ActivePlacementInfo | null;\n onActivePlacementChange: EventHook<ActivePlacementInfo | null>;\n}\n\nexport interface SignatureCapability {\n readonly mode: SignatureMode;\n getEntries(): SignatureEntry[];\n addEntry(entry: Omit<SignatureEntry, 'id' | 'createdAt'>): string;\n removeEntry(id: string): void;\n loadEntries(entries: SignatureEntry[]): void;\n exportEntries(): SignatureEntry[];\n onEntriesChange: EventHook<SignatureEntry[]>;\n forDocument(documentId: string): SignatureScope;\n onActivePlacementChange: EventHook<ActivePlacementChangeEvent>;\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SignatureMode, SignaturePluginConfig } from './types';\n\nexport const SIGNATURE_PLUGIN_ID = 'signature';\n\nexport const manifest: PluginManifest<SignaturePluginConfig> = {\n id: SIGNATURE_PLUGIN_ID,\n name: 'Signature Plugin',\n version: '1.0.0',\n provides: ['signature'],\n requires: ['annotation'],\n optional: [],\n defaultConfig: {\n mode: SignatureMode.SignatureOnly,\n },\n};\n","import { Action } from '@embedpdf/core';\n\nexport const ADD_SIGNATURE_ENTRY = 'SIGNATURE/ADD_ENTRY';\nexport const REMOVE_SIGNATURE_ENTRY = 'SIGNATURE/REMOVE_ENTRY';\n\nexport interface AddSignatureEntryAction extends Action {\n type: typeof ADD_SIGNATURE_ENTRY;\n payload: string;\n}\n\nexport interface RemoveSignatureEntryAction extends Action {\n type: typeof REMOVE_SIGNATURE_ENTRY;\n payload: string;\n}\n\nexport type SignatureAction = AddSignatureEntryAction | RemoveSignatureEntryAction;\n\nexport function addSignatureEntry(id: string): AddSignatureEntryAction {\n return { type: ADD_SIGNATURE_ENTRY, payload: id };\n}\n\nexport function removeSignatureEntry(id: string): RemoveSignatureEntryAction {\n return { type: REMOVE_SIGNATURE_ENTRY, payload: id };\n}\n","import {\n PdfAnnotationName,\n PdfAnnotationSubtype,\n PdfStampAnnoObject,\n Rect,\n uuidV4,\n} from '@embedpdf/models';\nimport { HandlerFactory } from '@embedpdf/plugin-annotation';\nimport { applyInsertUpright, clampAnnotationToPage } from '@embedpdf/plugin-annotation';\nimport { SIGNATURE_STAMP_TOOL_ID } from '../tools';\nimport { SignatureFieldKind } from '../types';\n\nexport const signatureStampHandlerFactory: HandlerFactory<\n PdfStampAnnoObject,\n typeof SIGNATURE_STAMP_TOOL_ID\n> = {\n annotationType: PdfAnnotationSubtype.STAMP,\n create(context) {\n const { onPreview, onCommit, getTool, pageSize, pageRotation, getToolContext } = context;\n\n return {\n onPointerMove: (pos) => {\n const ctx = getToolContext();\n if (!ctx?.targetSize) return;\n const { width, height } = ctx.targetSize;\n onPreview({\n type: PdfAnnotationSubtype.STAMP,\n bounds: {\n origin: { x: pos.x - width / 2, y: pos.y - height / 2 },\n size: { width, height },\n },\n data: {\n rect: {\n origin: { x: pos.x - width / 2, y: pos.y - height / 2 },\n size: { width, height },\n },\n ghostUrl: ctx.ghostUrl,\n pageRotation,\n },\n });\n },\n\n onPointerDown: (pos) => {\n const tool = getTool();\n const ctx = getToolContext();\n if (!tool || !ctx?.targetSize) return;\n\n const { width, height } = ctx.targetSize;\n const rect: Rect = {\n origin: { x: pos.x - width / 2, y: pos.y - height / 2 },\n size: { width, height },\n };\n\n let anno: PdfStampAnnoObject = {\n ...tool.defaults,\n rect,\n type: PdfAnnotationSubtype.STAMP,\n name: PdfAnnotationName.Custom,\n subject: 'Signature',\n flags: tool.defaults.flags ?? ['print'],\n pageIndex: context.pageIndex,\n id: uuidV4(),\n created: new Date(),\n };\n\n if (tool.behavior?.insertUpright) {\n anno = applyInsertUpright(anno, pageRotation, false);\n }\n anno = clampAnnotationToPage(anno, pageSize);\n\n onCommit(anno, { data: ctx.imageData });\n onPreview(null);\n },\n\n onPointerLeave: () => {\n onPreview(null);\n },\n };\n },\n};\n","import { PdfAnnotationSubtype, PdfInkAnnoObject, Rect, expandRect, uuidV4 } from '@embedpdf/models';\nimport { HandlerFactory } from '@embedpdf/plugin-annotation';\nimport { clampAnnotationToPage } from '@embedpdf/plugin-annotation';\nimport { SIGNATURE_INK_TOOL_ID } from '../tools';\nimport { SignatureFieldKind, SignatureInkData } from '../types';\n\nfunction translateAndScaleInk(\n inkData: SignatureInkData,\n targetSize: { width: number; height: number },\n centerPos: { x: number; y: number },\n): { inkList: Array<{ points: Array<{ x: number; y: number }> }>; strokeWidth: number } {\n const scaleX = targetSize.width / inkData.size.width;\n const scaleY = targetSize.height / inkData.size.height;\n const scale = Math.min(scaleX, scaleY);\n const scaledW = inkData.size.width * scale;\n const scaledH = inkData.size.height * scale;\n const offsetX = centerPos.x - scaledW / 2;\n const offsetY = centerPos.y - scaledH / 2;\n\n const inkList = inkData.inkList.map((stroke) => ({\n points: stroke.points.map((p) => ({\n x: p.x * scale + offsetX,\n y: p.y * scale + offsetY,\n })),\n }));\n\n return { inkList, strokeWidth: Math.round(inkData.strokeWidth * scale * 10) / 10 };\n}\n\nexport const signatureInkHandlerFactory: HandlerFactory<\n PdfInkAnnoObject,\n typeof SIGNATURE_INK_TOOL_ID\n> = {\n annotationType: PdfAnnotationSubtype.INK,\n create(context) {\n const { onPreview, onCommit, getTool, pageSize, getToolContext } = context;\n\n return {\n onPointerMove: (pos) => {\n const ctx = getToolContext();\n if (!ctx?.inkData || !ctx?.targetSize) return;\n\n const { inkList, strokeWidth } = translateAndScaleInk(ctx.inkData, ctx.targetSize, pos);\n\n const allPoints = inkList.flatMap((s) => s.points);\n if (allPoints.length === 0) return;\n\n const rect = expandRect(\n {\n origin: {\n x: Math.min(...allPoints.map((p) => p.x)),\n y: Math.min(...allPoints.map((p) => p.y)),\n },\n size: {\n width:\n Math.max(...allPoints.map((p) => p.x)) - Math.min(...allPoints.map((p) => p.x)),\n height:\n Math.max(...allPoints.map((p) => p.y)) - Math.min(...allPoints.map((p) => p.y)),\n },\n },\n strokeWidth / 2,\n );\n\n onPreview({\n type: PdfAnnotationSubtype.INK,\n bounds: rect,\n data: {\n rect,\n inkList,\n strokeWidth,\n strokeColor: ctx.inkData.strokeColor,\n opacity: 0.5,\n },\n });\n },\n\n onPointerDown: (pos) => {\n const tool = getTool();\n const ctx = getToolContext();\n if (!tool || !ctx?.inkData || !ctx?.targetSize) return;\n\n const { inkList, strokeWidth } = translateAndScaleInk(ctx.inkData, ctx.targetSize, pos);\n\n const allPoints = inkList.flatMap((s) => s.points);\n if (allPoints.length === 0) return;\n\n const rect = expandRect(\n {\n origin: {\n x: Math.min(...allPoints.map((p) => p.x)),\n y: Math.min(...allPoints.map((p) => p.y)),\n },\n size: {\n width:\n Math.max(...allPoints.map((p) => p.x)) - Math.min(...allPoints.map((p) => p.x)),\n height:\n Math.max(...allPoints.map((p) => p.y)) - Math.min(...allPoints.map((p) => p.y)),\n },\n },\n strokeWidth / 2,\n );\n\n let anno: PdfInkAnnoObject = {\n ...tool.defaults,\n inkList,\n rect,\n strokeWidth,\n strokeColor: ctx.inkData.strokeColor,\n opacity: 1,\n type: PdfAnnotationSubtype.INK,\n subject: 'Signature',\n flags: tool.defaults.flags ?? ['print'],\n pageIndex: context.pageIndex,\n id: uuidV4(),\n created: new Date(),\n };\n\n const unclamped = anno.rect;\n anno = clampAnnotationToPage(anno, pageSize);\n const dx = anno.rect.origin.x - unclamped.origin.x;\n const dy = anno.rect.origin.y - unclamped.origin.y;\n if (dx !== 0 || dy !== 0) {\n anno = {\n ...anno,\n inkList: anno.inkList.map((s) => ({\n points: s.points.map((p) => ({ x: p.x + dx, y: p.y + dy })),\n })),\n };\n }\n\n onCommit(anno);\n onPreview(null);\n },\n\n onPointerLeave: () => {\n onPreview(null);\n },\n };\n },\n};\n","import { PdfAnnotationSubtype } from '@embedpdf/models';\nimport { defineAnnotationTool, patching } from '@embedpdf/plugin-annotation';\nimport { signatureStampHandlerFactory } from './handlers/signature-stamp.handler';\nimport { signatureInkHandlerFactory } from './handlers/signature-ink.handler';\n\nexport const SIGNATURE_STAMP_TOOL_ID = 'signatureStamp' as const;\nexport const SIGNATURE_INK_TOOL_ID = 'signatureInk' as const;\n\nexport const signatureStampTool = defineAnnotationTool({\n id: SIGNATURE_STAMP_TOOL_ID,\n name: 'Signature Stamp',\n labelKey: 'signature.stamp',\n categories: ['annotation', 'signature', 'insert'],\n matchScore: () => 0,\n interaction: {\n exclusive: true,\n cursor: 'copy',\n isDraggable: true,\n isResizable: true,\n isRotatable: false,\n lockAspectRatio: true,\n isGroupDraggable: true,\n isGroupResizable: false,\n isGroupRotatable: false,\n },\n defaults: {\n type: PdfAnnotationSubtype.STAMP,\n },\n behavior: {\n deactivateToolAfterCreate: true,\n selectAfterCreate: true,\n insertUpright: true,\n useAppearanceStream: true,\n },\n pointerHandler: signatureStampHandlerFactory,\n});\n\nexport const signatureInkTool = defineAnnotationTool({\n id: SIGNATURE_INK_TOOL_ID,\n name: 'Signature Ink',\n labelKey: 'signature.ink',\n categories: ['annotation', 'signature', 'insert'],\n matchScore: (a) => (a.type === PdfAnnotationSubtype.INK && a.subject === 'Signature' ? 20 : 0),\n interaction: {\n exclusive: true,\n cursor: 'copy',\n isDraggable: true,\n isResizable: true,\n isRotatable: false,\n lockAspectRatio: true,\n isGroupDraggable: true,\n isGroupResizable: false,\n isGroupRotatable: false,\n },\n defaults: {\n type: PdfAnnotationSubtype.INK,\n },\n behavior: {\n deactivateToolAfterCreate: true,\n selectAfterCreate: true,\n },\n transform: patching.patchInk,\n pointerHandler: signatureInkHandlerFactory,\n});\n\nexport const signatureTools = [signatureStampTool, signatureInkTool];\n","import { BasePlugin, createEmitter, createScopedEmitter, PluginRegistry } from '@embedpdf/core';\nimport { uuidV4 } from '@embedpdf/models';\nimport { AnnotationCapability, AnnotationPlugin } from '@embedpdf/plugin-annotation';\nimport {\n SignatureCapability,\n SignatureScope,\n SignatureEntry,\n SignatureFieldKind,\n SignatureCreationType,\n SignaturePluginConfig,\n SignatureState,\n ActivePlacementInfo,\n ActivePlacementChangeEvent,\n} from './types';\nimport { addSignatureEntry, removeSignatureEntry, SignatureAction } from './actions';\nimport { SIGNATURE_PLUGIN_ID } from './manifest';\nimport { SIGNATURE_STAMP_TOOL_ID, SIGNATURE_INK_TOOL_ID, signatureTools } from './tools';\n\nexport class SignaturePlugin extends BasePlugin<\n SignaturePluginConfig,\n SignatureCapability,\n SignatureState,\n SignatureAction\n> {\n static readonly id = SIGNATURE_PLUGIN_ID;\n\n private readonly entries = new Map<string, SignatureEntry>();\n private readonly entriesChange$ = createEmitter<SignatureEntry[]>();\n private readonly activePlacement$ = createScopedEmitter<\n ActivePlacementInfo | null,\n ActivePlacementChangeEvent,\n string\n >((documentId, activePlacement) => ({ documentId, activePlacement }));\n\n private annotation: AnnotationCapability | null = null;\n private toolChangeUnsubscribe: (() => void) | null = null;\n private currentGhostUrl: string | null = null;\n\n constructor(\n id: string,\n registry: PluginRegistry,\n private config: SignaturePluginConfig,\n ) {\n super(id, registry);\n\n this.annotation = registry.getPlugin<AnnotationPlugin>('annotation')?.provides() ?? null;\n if (this.annotation) {\n for (const tool of signatureTools) {\n this.annotation.addTool(tool);\n }\n this.toolChangeUnsubscribe = this.annotation.onActiveToolChange(({ documentId, tool }) => {\n if (tool?.id !== SIGNATURE_STAMP_TOOL_ID && tool?.id !== SIGNATURE_INK_TOOL_ID) {\n this.revokeGhostUrl();\n this.activePlacement$.emit(documentId, null);\n }\n });\n }\n }\n\n async initialize(): Promise<void> {}\n\n protected buildCapability(): SignatureCapability {\n return {\n mode: this.config.mode,\n getEntries: () => this.getEntries(),\n addEntry: (entry) => this.addEntry(entry),\n removeEntry: (id) => this.removeEntry(id),\n loadEntries: (entries) => this.loadEntries(entries),\n exportEntries: () => this.exportEntries(),\n onEntriesChange: this.entriesChange$.on,\n forDocument: (documentId) => this.createSignatureScope(documentId),\n onActivePlacementChange: this.activePlacement$.onGlobal,\n };\n }\n\n getEntries(): SignatureEntry[] {\n return Array.from(this.entries.values());\n }\n\n addEntry(entry: Omit<SignatureEntry, 'id' | 'createdAt'>): string {\n const id = uuidV4();\n const fullEntry: SignatureEntry = {\n ...entry,\n id,\n createdAt: Date.now(),\n };\n\n this.entries.set(id, fullEntry);\n this.dispatch(addSignatureEntry(id));\n this.emitEntriesChange();\n\n return id;\n }\n\n removeEntry(id: string): void {\n if (!this.entries.has(id)) return;\n\n this.entries.delete(id);\n this.dispatch(removeSignatureEntry(id));\n this.emitEntriesChange();\n }\n\n loadEntries(entries: SignatureEntry[]): void {\n for (const entry of entries) {\n this.entries.set(entry.id, entry);\n this.dispatch(addSignatureEntry(entry.id));\n }\n\n this.emitEntriesChange();\n }\n\n exportEntries(): SignatureEntry[] {\n return this.getEntries();\n }\n\n private createSignatureScope(documentId: string): SignatureScope {\n return {\n activateSignaturePlacement: (entryId) =>\n this.activatePlacement(documentId, entryId, SignatureFieldKind.Signature),\n activateInitialsPlacement: (entryId) =>\n this.activatePlacement(documentId, entryId, SignatureFieldKind.Initials),\n deactivatePlacement: () => this.deactivatePlacement(documentId),\n getActivePlacement: () => this.activePlacement$.getValue(documentId) ?? null,\n onActivePlacementChange: this.activePlacement$.forScope(documentId),\n };\n }\n\n private activatePlacement(documentId: string, entryId: string, kind: SignatureFieldKind): void {\n const entry = this.entries.get(entryId);\n if (!entry || !this.annotation) return;\n\n const field = kind === SignatureFieldKind.Initials ? entry.initials : entry.signature;\n if (!field) return;\n\n this.revokeGhostUrl();\n\n if (field.creationType === SignatureCreationType.Draw) {\n if (entry.signature.creationType !== SignatureCreationType.Draw) return;\n const defaultSize = this.config.defaultSize ?? { width: 150, height: 50 };\n const referenceSize = entry.signature.inkData.size;\n const scale = Math.min(\n defaultSize.width / referenceSize.width,\n defaultSize.height / referenceSize.height,\n );\n const targetSize = {\n width: field.inkData.size.width * scale,\n height: field.inkData.size.height * scale,\n };\n\n this.annotation.setActiveTool(SIGNATURE_INK_TOOL_ID, {\n inkData: field.inkData,\n targetSize,\n entryId,\n kind,\n });\n } else {\n if (!field.imageData) return;\n\n const ghostUrl = URL.createObjectURL(\n new Blob([field.imageData], { type: field.imageMimeType ?? 'image/png' }),\n );\n this.currentGhostUrl = ghostUrl;\n\n const defaultSize = this.config.defaultSize ?? { width: 150, height: 50 };\n let targetSize = defaultSize;\n if (field.imageSize) {\n const referenceSize =\n entry.signature.creationType !== SignatureCreationType.Draw\n ? (entry.signature.imageSize ?? field.imageSize)\n : field.imageSize;\n const scale = Math.min(\n defaultSize.width / referenceSize.width,\n defaultSize.height / referenceSize.height,\n );\n targetSize = {\n width: field.imageSize.width * scale,\n height: field.imageSize.height * scale,\n };\n }\n\n this.annotation.setActiveTool(SIGNATURE_STAMP_TOOL_ID, {\n imageData: field.imageData,\n ghostUrl,\n targetSize,\n entryId,\n kind,\n });\n }\n\n this.activePlacement$.emit(documentId, { entryId, kind });\n }\n\n private deactivatePlacement(documentId: string): void {\n if (!this.annotation) return;\n this.annotation.setActiveTool(null);\n this.revokeGhostUrl();\n this.activePlacement$.emit(documentId, null);\n }\n\n private revokeGhostUrl(): void {\n if (this.currentGhostUrl) {\n URL.revokeObjectURL(this.currentGhostUrl);\n this.currentGhostUrl = null;\n }\n }\n\n private emitEntriesChange(): void {\n this.entriesChange$.emit(this.getEntries());\n }\n\n override async destroy(): Promise<void> {\n this.revokeGhostUrl();\n this.toolChangeUnsubscribe?.();\n this.entries.clear();\n }\n}\n","import { Reducer } from '@embedpdf/core';\nimport { SignatureAction, ADD_SIGNATURE_ENTRY, REMOVE_SIGNATURE_ENTRY } from './actions';\nimport { SignatureState } from './types';\n\nexport const initialState: SignatureState = {\n entryIds: [],\n};\n\nexport const signatureReducer: Reducer<SignatureState, SignatureAction> = (\n state = initialState,\n action,\n) => {\n switch (action.type) {\n case ADD_SIGNATURE_ENTRY:\n return {\n ...state,\n entryIds: [...state.entryIds, action.payload],\n };\n\n case REMOVE_SIGNATURE_ENTRY:\n return {\n ...state,\n entryIds: state.entryIds.filter((id) => id !== action.payload),\n };\n\n default:\n return state;\n }\n};\n","import {\n SignatureEntry,\n SignatureFieldDefinition,\n SignatureCreationType,\n SignatureStampFieldDefinition,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Serialized types (JSON-safe — ArrayBuffer replaced with base64 strings)\n// ---------------------------------------------------------------------------\n\nexport interface SerializedSignatureStampField {\n creationType: SignatureCreationType.Type | SignatureCreationType.Upload;\n label?: string;\n previewDataUrl: string;\n imageMimeType?: string;\n imageSize?: { width: number; height: number };\n imageData?: string;\n}\n\nexport type SerializedSignatureFieldDefinition =\n | import('./types').SignatureInkFieldDefinition\n | SerializedSignatureStampField;\n\nexport interface SerializedSignatureEntry {\n id: string;\n createdAt: number;\n signature: SerializedSignatureFieldDefinition;\n initials?: SerializedSignatureFieldDefinition;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction arrayBufferToBase64(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\nfunction base64ToArrayBuffer(base64: string): ArrayBuffer {\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\nfunction serializeField(field: SignatureFieldDefinition): SerializedSignatureFieldDefinition {\n if (field.creationType === SignatureCreationType.Draw) {\n return field;\n }\n const { imageData, ...rest } = field;\n return {\n ...rest,\n imageData: imageData ? arrayBufferToBase64(imageData) : undefined,\n };\n}\n\nfunction deserializeField(field: SerializedSignatureFieldDefinition): SignatureFieldDefinition {\n if (field.creationType === SignatureCreationType.Draw) {\n return field;\n }\n const { imageData, ...rest } = field;\n return {\n ...rest,\n imageData: imageData ? base64ToArrayBuffer(imageData) : undefined,\n } as SignatureStampFieldDefinition;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Converts signature entries into a JSON-safe format by encoding\n * ArrayBuffer fields as base64 strings. Use with `JSON.stringify`\n * for persistence (e.g. localStorage, IndexedDB, or a backend API).\n */\nexport function serializeEntries(entries: SignatureEntry[]): SerializedSignatureEntry[] {\n return entries.map((entry) => ({\n id: entry.id,\n createdAt: entry.createdAt,\n signature: serializeField(entry.signature),\n ...(entry.initials && { initials: serializeField(entry.initials) }),\n }));\n}\n\n/**\n * Restores signature entries from the JSON-safe format produced by\n * `serializeEntries`, converting base64 strings back to ArrayBuffers.\n */\nexport function deserializeEntries(data: SerializedSignatureEntry[]): SignatureEntry[] {\n return data.map((entry) => ({\n id: entry.id,\n createdAt: entry.createdAt,\n signature: deserializeField(entry.signature),\n ...(entry.initials && { initials: deserializeField(entry.initials) }),\n }));\n}\n","import { PluginPackage } from '@embedpdf/core';\nimport { manifest, SIGNATURE_PLUGIN_ID } from './manifest';\nimport { SignaturePluginConfig, SignatureState } from './types';\nimport { SignaturePlugin } from './signature-plugin';\nimport { signatureReducer, initialState } from './reducer';\nimport { SignatureAction } from './actions';\n\nexport const SignaturePluginPackage: PluginPackage<\n SignaturePlugin,\n SignaturePluginConfig,\n SignatureState,\n SignatureAction\n> = {\n manifest,\n create: (registry, config) => new SignaturePlugin(SIGNATURE_PLUGIN_ID, registry, config),\n reducer: signatureReducer,\n initialState,\n};\n\nexport * from './signature-plugin';\nexport * from './types';\nexport * from './manifest';\nexport * from './actions';\nexport * from './reducer';\nexport { SIGNATURE_STAMP_TOOL_ID, SIGNATURE_INK_TOOL_ID } from './tools';\nexport * from './serialization';\n"],"names":["SignatureMode","SignatureCreationType","SignatureFieldKind"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/blank-page.ts","../src/capability.ts","../src/handler.ts","../src/reducer.ts","../src/signature.plugin.ts"],"sourcesContent":["/** A one-page blank PDF: the appearance that clears a visual fill. */\n// A content stream that draws NOTHING but is not empty (`q Q`): the engine\n// turns the page into a form XObject, and a page with no content at all has\n// nothing to turn — it refuses; a saved/restored state passes and paints\n// nothing.\nconst CONTENT = 'q Q';\nconst OBJECTS = [\n '<< /Type /Catalog /Pages 2 0 R >>',\n '<< /Type /Pages /Kids [3 0 R] /Count 1 >>',\n '<< /Type /Page /Parent 2 0 R /MediaBox [0 0 200 60] /Contents 4 0 R /Resources << >> >>',\n `<< /Length ${CONTENT.length} >>\\nstream\\n${CONTENT}\\nendstream`,\n];\n\nlet cached: Uint8Array | null = null;\n\nexport function blankPagePdf(): Uint8Array {\n if (cached) return new Uint8Array(cached);\n let body = '%PDF-1.7\\n';\n const offsets: number[] = [];\n OBJECTS.forEach((object, index) => {\n offsets.push(body.length);\n body += `${index + 1} 0 obj\\n${object}\\nendobj\\n`;\n });\n const xref = body.length;\n body += `xref\\n0 ${OBJECTS.length + 1}\\n0000000000 65535 f \\n`;\n for (const offset of offsets) body += `${String(offset).padStart(10, '0')} 00000 n \\n`;\n body += `trailer\\n<< /Size ${OBJECTS.length + 1} /Root 1 0 R >>\\nstartxref\\n${xref}\\n%%EOF\\n`;\n cached = new TextEncoder().encode(body);\n return new Uint8Array(cached);\n}\n","import { createEventHook, type PluginContext } from '@embedpdf/core';\nimport {\n certificateCommonName,\n sign,\n validateSignatures,\n type SignatureVerdict,\n type SignerPort,\n type ValidationTime,\n} from '@embedpdf/core-signature';\nimport {\n resolveBinarySource,\n type AnalyzeInput,\n type BinarySource,\n type ChangeAnalysis,\n type DocumentEvent,\n type DocumentProtection,\n type FormFieldRef,\n type SignatureCompleteResult,\n type SignatureDTO,\n type SignatureSnapshot,\n} from '@embedpdf/engine-core/runtime';\nimport { AnnotationToken, type StampPlacement } from '@embedpdf/plugin-annotation/contract';\nimport { FormToken } from '@embedpdf/plugin-form/contract';\nimport { StampToken } from '@embedpdf/plugin-stamp/contract';\n\nimport { blankPagePdf } from './blank-page';\nimport type {\n Mark,\n SignatureAction,\n SignatureCapability,\n SignatureChange,\n SignatureConfig,\n SignatureMode,\n SignatureState,\n SignFieldInput,\n} from './types';\n\nconst sameRef = (a: FormFieldRef, b: FormFieldRef): boolean =>\n a.kind === 'objectNumber' && b.kind === 'objectNumber'\n ? a.fieldObjectNumber === b.fieldObjectNumber\n : a.kind === 'fqn' && b.kind === 'fqn'\n ? a.name === b.name\n : false;\n\nconst sameProtection = (a: DocumentProtection | null, b: DocumentProtection | null): boolean =>\n JSON.stringify(a) === JSON.stringify(b);\n\nexport function createSignatureCapability(\n ctx: PluginContext<SignatureState, SignatureAction>,\n config: SignatureConfig = {},\n): SignatureCapability {\n const form = ctx.get(FormToken);\n const changed = createEventHook<SignatureChange>((error) =>\n globalThis.console?.error('[signature] listener failed:', error),\n );\n ctx.cleanup(() => changed.dispose());\n\n const state = () => ctx.getState();\n const requireDoc = () => {\n const doc = ctx.doc;\n if (!doc) throw new Error('[signature] no document bound');\n return doc;\n };\n const requireSignatures = () => {\n const doc = requireDoc();\n if (!doc.signatures) throw new Error('[signature] this engine does not implement signatures');\n return { doc, signatures: doc.signatures };\n };\n const stamp = () => ctx.tryGet(StampToken);\n const documentId = () => {\n const id = ctx.documentId;\n if (!id) throw new Error('[signature] no document id');\n return id;\n };\n\n // ── mode and signer ─────────────────────────────────────────────────────\n const mode = (): SignatureMode => config.mode ?? (config.signer ? 'sign' : 'visual');\n const resolveSigner = async (): Promise<SignerPort> => {\n const signer = config.signer;\n if (!signer) throw new Error('[signature] no signer configured (mode \"sign\" needs one)');\n return typeof signer === 'function' ? signer() : signer;\n };\n const allows = (cap: 'doc.sign' | 'doc.sign.certify' | 'doc.forms.fill'): boolean =>\n ctx.doc?.security.allows(cap) ?? false;\n\n // ── snapshot + verdicts ─────────────────────────────────────────────────\n const refresh = async (): Promise<SignatureSnapshot | null> => {\n const doc = ctx.doc;\n if (!doc?.signatures) {\n ctx.dispatch({ type: 'SNAPSHOT', snapshot: null });\n return null;\n }\n const before = state().snapshot?.protection ?? null;\n const snapshot = await doc.signatures.list();\n ctx.dispatch({ type: 'SNAPSHOT', snapshot });\n if (!sameProtection(before, snapshot.protection)) {\n changed.emit({ type: 'protectionChanged', protection: snapshot.protection });\n }\n return snapshot;\n };\n\n const validate = async (opts?: {\n at?: ValidationTime;\n until?: 'persisted' | 'working-copy';\n }): Promise<SignatureVerdict[]> => {\n const doc = ctx.doc;\n if (!doc?.signatures) return [];\n const verdicts = await validateSignatures(doc, {\n trust: config.trust ?? null,\n at: opts?.at,\n until: opts?.until ?? 'working-copy',\n });\n const before = state().verdicts;\n ctx.dispatch({ type: 'VERDICTS', verdicts });\n changed.emit({ type: 'validated', verdicts });\n // Acrobat's warning, after the fact and only on the edge: a signature that\n // held (or was never judged) now reads invalid because of unsaved edits.\n for (const v of verdicts) {\n if (v.modifications.basis !== 'working-copy' || v.summary !== 'invalid') continue;\n const was = before?.find((b) => b.signature.index === v.signature.index);\n if (was && was.summary === 'invalid') continue;\n changed.emit({\n type: 'invalidating',\n field: v.signature.field,\n detail: v.modifications.detail ?? '',\n });\n }\n return verdicts;\n };\n\n // Every edit that could count as a modification re-judges the working copy.\n // Coalesced: a pen stroke is many events, one analysis.\n let revalidateTimer: ReturnType<typeof setTimeout> | null = null;\n const revalidateSoon = (): void => {\n if (!state().snapshot?.signatures.some((s) => s.signed)) return;\n if (revalidateTimer) clearTimeout(revalidateTimer);\n revalidateTimer = setTimeout(() => {\n revalidateTimer = null;\n void validate().catch((error) =>\n globalThis.console?.error('[signature] re-validation failed:', error),\n );\n }, 300);\n };\n ctx.cleanup(() => {\n if (revalidateTimer) clearTimeout(revalidateTimer);\n });\n\n const analyze = (input: AnalyzeInput): Promise<ChangeAnalysis> =>\n requireSignatures().signatures.analyze(input);\n\n const signatureOf = (\n field: FormFieldRef | { annotObjectNumber: number },\n ): SignatureDTO | null => {\n const snapshot = state().snapshot;\n if (!snapshot) return null;\n if ('annotObjectNumber' in field) {\n const byWidget = snapshot.signatures.find(\n (s) => s.widget?.annotObjectNumber === field.annotObjectNumber,\n );\n if (byWidget) return byWidget;\n const owner = form.fieldForWidget(field.annotObjectNumber);\n return owner ? signatureOf(owner.ref) : null;\n }\n return (\n snapshot.signatures.find((s) =>\n field.kind === 'fqn' ? s.fieldName === field.name : sameRef(s.field, field),\n ) ?? null\n );\n };\n const verdictOf = (\n field: FormFieldRef | { annotObjectNumber: number },\n ): SignatureVerdict | null => {\n const signature = signatureOf(field);\n if (!signature) return null;\n return state().verdicts?.find((v) => v.signature.index === signature.index) ?? null;\n };\n\n // ── marks → bytes ───────────────────────────────────────────────────────\n const bytesOf = async (source: BinarySource): Promise<Uint8Array> =>\n new Uint8Array((await resolveBinarySource(source)).bytes);\n const markBytes = async (mark: Mark): Promise<Uint8Array> => {\n if ('assetId' in mark) {\n const bytes = stamp()?.assetBytes(mark.assetId);\n if (!bytes) throw new Error(`[signature] unknown mark '${mark.assetId}'`);\n return bytes;\n }\n return bytesOf(mark.source);\n };\n\n const withBusy = async <T>(work: () => Promise<T>): Promise<T> => {\n ctx.dispatch({ type: 'BUSY', busy: true });\n try {\n return await work();\n } finally {\n ctx.dispatch({ type: 'BUSY', busy: false });\n }\n };\n\n // ── the act ─────────────────────────────────────────────────────────────\n const signField = (input: SignFieldInput): Promise<SignatureCompleteResult> =>\n withBusy(async () => {\n const { doc } = requireSignatures();\n const signer = await resolveSigner();\n // The certificate's subject is the default /Name; the caller's facts win.\n const subject =\n signer.kind === 'raw' && signer.certificateChain[0]\n ? certificateCommonName(signer.certificateChain[0])\n : null;\n const attribution = { ...(subject ? { name: subject } : {}), ...input.attribution };\n // The appearance IS the mark: its page is drawn into the widget by the engine.\n const appearance = input.appearance\n ? await bytesOf(input.appearance)\n : await markBytes(input.mark);\n const result = await sign(doc, {\n field: input.field,\n signer,\n attribution,\n certify: input.certify,\n lock: input.lock,\n appearance: { pdf: appearance, pageIndex: 0 },\n });\n if (state().target && sameRef(state().target!, input.field)) setTarget(null);\n await refresh();\n void validate().catch((error) =>\n globalThis.console?.error('[signature] validation after signing failed:', error),\n );\n changed.emit({ type: 'signed', field: input.field, result });\n return result;\n });\n\n const setAppearance = async (field: FormFieldRef, pdf: Uint8Array): Promise<void> => {\n const doc = requireDoc();\n if (!doc.forms.setSignatureAppearance) {\n throw new Error('[signature] this engine cannot draw into a signature field');\n }\n const signature = signatureOf(field);\n if (signature?.signed) throw new Error(`[signature] '${signature.fieldName}' is signed`);\n await doc.forms.setSignatureAppearance(field, { pdf, pageIndex: 0 });\n await form.refresh();\n };\n\n const fillField = (field: FormFieldRef, mark: Mark): Promise<void> =>\n withBusy(async () => {\n await setAppearance(field, await markBytes(mark));\n if (state().target && sameRef(state().target!, field)) setTarget(null);\n changed.emit({ type: 'filled', field });\n });\n\n const clearField = (field: FormFieldRef): Promise<void> =>\n withBusy(async () => {\n await setAppearance(field, blankPagePdf());\n changed.emit({ type: 'cleared', field });\n });\n\n const placeMark = async (\n mark: Mark,\n target: { field: FormFieldRef } | StampPlacement,\n ): Promise<void> => {\n if (!('field' in target)) {\n // Free placement: a stamp, as in Preview — one placement law, the stamp plugin's.\n if ('assetId' in mark) {\n const library = stamp();\n if (!library) throw new Error('[signature] no stamp plugin to place an asset');\n await library.placeAsset(documentId(), mark.assetId, target);\n } else {\n await ctx.get(AnnotationToken).placeStamp({ source: mark.source }, target);\n }\n return;\n }\n switch (mode()) {\n case 'sign':\n // The first signature is the one that can certify: when the config\n // allows a certification, let the chrome offer the choice (its sign\n // dialog) instead of sealing a plain approval on the spot.\n if (config.allowCertify && !state().snapshot?.signatures.some((s) => s.signed)) {\n changed.emit({ type: 'ask', field: target.field, mark });\n return;\n }\n await signField({ field: target.field, mark });\n return;\n case 'visual':\n await fillField(target.field, mark);\n return;\n case 'ask':\n changed.emit({ type: 'ask', field: target.field, mark });\n return;\n }\n };\n\n const setTarget = (field: FormFieldRef | null): void => {\n const current = state().target;\n if (current === field || (current && field && sameRef(current, field))) return;\n ctx.dispatch({ type: 'TARGET', field });\n changed.emit({ type: 'target', field });\n };\n\n // ── live: pendings, versions, remote signings ───────────────────────────\n const doc = ctx.doc;\n if (doc) {\n const unsubscribe = doc.events.subscribe((event: DocumentEvent) => {\n switch (event.type) {\n case 'signature.prepared':\n ctx.dispatch({\n type: 'PENDING',\n pending: { signingId: event.signingId, field: event.field },\n });\n return;\n case 'signature.aborted':\n ctx.dispatch({ type: 'PENDING', pending: null });\n return;\n case 'signature.completed':\n ctx.dispatch({ type: 'PENDING', pending: null });\n return;\n case 'document.versioned':\n case 'stream.desynced':\n // Byte-level facts moved: re-read them and re-judge.\n void refresh()\n .then(() => validate())\n .catch((error) => globalThis.console?.error('[signature] refresh failed:', error));\n return;\n case 'form.fieldCreated':\n case 'form.fieldDeleted':\n case 'form.widgetAttached':\n case 'form.widgetDetached':\n case 'form.imported':\n case 'form.repaired':\n // The field set changed (a signature field authored or removed, here\n // or remotely): the snapshot lists fields, so re-read it — and the\n // change is a modification of the working copy, so re-judge.\n void refresh()\n .then(() => revalidateSoon())\n .catch((error) => globalThis.console?.error('[signature] refresh failed:', error));\n return;\n case 'annotation.created':\n case 'annotation.updated':\n case 'annotation.deleted':\n case 'annotation.moved':\n case 'form.valueChanged':\n case 'form.fieldUpdated':\n case 'form.effectsApplied':\n // An edit of the working copy: what a save would write changed, so\n // what a validator would say about it may have too.\n revalidateSoon();\n return;\n default:\n return;\n }\n });\n ctx.cleanup(unsubscribe);\n }\n\n return {\n snapshot: () => state().snapshot,\n verdicts: () => state().verdicts,\n protection: () => state().snapshot?.protection ?? null,\n pending: () => state().pending,\n target: () => state().target,\n busy: () => state().busy,\n mode,\n signatureOf,\n verdictOf,\n canSign: () => allows('doc.sign') && config.signer != null,\n canFill: () => allows('doc.forms.fill') && ctx.doc?.forms.setSignatureAppearance != null,\n canCertify: () => config.allowCertify === true && allows('doc.sign.certify'),\n signField,\n fillField,\n clearField,\n placeMark,\n setTarget,\n inspect: (field) => changed.emit({ type: 'inspect', field }),\n refresh,\n validate,\n analyze,\n revisionBytes: (revisionIndex) => requireSignatures().signatures.revisionBytes(revisionIndex),\n onChanged: changed.on,\n };\n}\n","import type { InteractionHandler } from '@embedpdf/plugin-interaction/contract';\nimport {\n ANNOTATION_EDIT_PRIORITY,\n ARMED_STAMP_TOOL_ID,\n} from '@embedpdf/plugin-annotation/contract';\nimport type { FormCapability } from '@embedpdf/plugin-form/contract';\nimport type { StampCapability } from '@embedpdf/plugin-stamp/contract';\n\nimport { SIGNATURES_LIBRARY_KIND, type SignatureCapability } from './types';\n\n/**\n * The armed mark over a field. The annotation plugin places an armed stamp\n * on click (`annotation-place`, priority 95) and selects an existing\n * annotation under the pointer before that (`annotation-edit`, 100 — a\n * widget is an annotation). This handler sits above BOTH, enabled for the\n * armed stamp's tool only, and captures exactly when the armed asset is a\n * person's mark (a library of kind `signatures`) and the pointer is over a\n * signature field: then the destination decides — the mark goes INTO the\n * field (`placeMark` by mode) instead of onto the page. Everywhere else it\n * declines and the click stays a stamp placement, as in Preview.\n */\nexport function createArmedMarkHandler(\n documentId: string,\n signature: SignatureCapability,\n form: FormCapability,\n stamp: StampCapability,\n): InteractionHandler {\n return {\n id: 'signature:armed-mark-on-field',\n priority: ANNOTATION_EDIT_PRIORITY + 1,\n enabledFor: (tool) => tool.id === ARMED_STAMP_TOOL_ID,\n onDown: (sample) => {\n if (!sample.page) return false;\n const armed = stamp.armedAsset(documentId);\n if (!armed || stamp.library(armed.libraryId)?.kind !== SIGNATURES_LIBRARY_KIND) return false;\n const hit = form.widgetAt(sample.page.pon, sample.page.point);\n if (!hit || hit.field.family !== 'signature') return false;\n // A signed field is final: consume the click (no stamp lands on it) and do nothing.\n if (signature.signatureOf(hit.field.ref)?.signed || hit.field.valueEntry.kind !== 'none') {\n return true;\n }\n stamp.disarm(documentId);\n void signature\n .placeMark({ assetId: armed.id }, { field: hit.field.ref })\n .catch((error) => globalThis.console?.error('[signature] placing the mark failed:', error));\n return true;\n },\n };\n}\n","import type { SignatureAction, SignatureState } from './types';\n\nexport const initialSignatureState = (): SignatureState => ({\n snapshot: null,\n verdicts: null,\n target: null,\n pending: null,\n busy: false,\n});\n\nexport function signatureReducer(state: SignatureState, action: SignatureAction): SignatureState {\n switch (action.type) {\n case 'SNAPSHOT':\n return { ...state, snapshot: action.snapshot };\n case 'VERDICTS':\n return { ...state, verdicts: action.verdicts };\n case 'TARGET':\n return { ...state, target: action.field };\n case 'PENDING':\n return { ...state, pending: action.pending };\n case 'BUSY':\n return { ...state, busy: action.busy };\n default:\n return state;\n }\n}\n","import { definePlugin } from '@embedpdf/core';\nimport { FormToken } from '@embedpdf/plugin-form/contract';\nimport { InteractionToken } from '@embedpdf/plugin-interaction/contract';\nimport { StampToken } from '@embedpdf/plugin-stamp/contract';\nimport { AnnotationToken } from '@embedpdf/plugin-annotation/contract';\n\nimport { createSignatureCapability } from './capability';\nimport { createArmedMarkHandler } from './handler';\nimport { initialSignatureState, signatureReducer } from './reducer';\nimport { SignatureToken } from './types';\nimport type {\n SignatureAction,\n SignatureCapability,\n SignatureConfig,\n SignatureState,\n} from './types';\n\n/**\n * The signature plugin — the ACT of signing, document-scoped. It owns no\n * mark: marks are stamp-library assets (or bytes the embedder brings), and\n * the mark IS the appearance the engine draws into the field. Signing goes\n * through `@embedpdf/core-signature` with the configured signer port; the\n * engine seals; on the cloud the server publishes the new version.\n *\n * With the interaction hub and the stamp plugin present, an armed mark from\n * a `signatures` library dropped over an unsigned signature field goes into\n * the field (sign / visual fill / ask, by mode) instead of onto the page.\n */\nexport const signaturePlugin = (config: SignatureConfig = {}) =>\n definePlugin<SignatureState, SignatureAction, SignatureCapability>({\n id: 'signature',\n token: SignatureToken,\n scope: 'document',\n requires: [FormToken],\n optional: [InteractionToken, StampToken, AnnotationToken],\n initialState: initialSignatureState,\n reduce: signatureReducer,\n capability: (ctx) => createSignatureCapability(ctx, config),\n init: (ctx) => {\n const signature = ctx.get(SignatureToken);\n void signature\n .refresh()\n .then((snapshot) =>\n snapshot?.signatures.some((s) => s.signed) ? signature.validate() : null,\n )\n .catch((error) => globalThis.console?.error('[signature] initial read failed:', error));\n const interaction = ctx.tryGet(InteractionToken);\n const stamp = ctx.tryGet(StampToken);\n if (interaction && stamp && ctx.documentId) {\n ctx.cleanup(\n interaction.registerHandler(\n createArmedMarkHandler(ctx.documentId, signature, ctx.get(FormToken), stamp),\n ),\n );\n }\n },\n });\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,82 +1,52 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-signature",
3
- "version": "2.15.0",
3
+ "version": "3.0.0-next.13",
4
+ "private": false,
5
+ "description": "Document-scoped digital signing: sign a signature field with a mark (a stamp-library asset or bytes you bring) through a signer port, fill it visually without sealing, validate what is signed, and drop an armed mark onto a field. Owns the act, never a mark — marks are the stamp plugin's.",
4
6
  "type": "module",
5
- "license": "MIT",
6
- "main": "./dist/index.cjs",
7
+ "main": "./dist/index.js",
7
8
  "module": "./dist/index.js",
8
9
  "types": "./dist/index.d.ts",
9
10
  "exports": {
10
11
  ".": {
11
- "types": "./dist/index.d.ts",
12
12
  "import": "./dist/index.js",
13
13
  "require": "./dist/index.cjs"
14
14
  },
15
- "./preact": {
16
- "types": "./dist/preact/index.d.ts",
17
- "import": "./dist/preact/index.js",
18
- "require": "./dist/preact/index.cjs"
15
+ "./contract": {
16
+ "import": "./dist/contract.js",
17
+ "require": "./dist/contract.cjs"
19
18
  },
20
- "./react": {
21
- "types": "./dist/react/index.d.ts",
22
- "import": "./dist/react/index.js",
23
- "require": "./dist/react/index.cjs"
24
- },
25
- "./vue": {
26
- "types": "./dist/vue/index.d.ts",
27
- "import": "./dist/vue/index.js",
28
- "require": "./dist/vue/index.cjs"
29
- },
30
- "./svelte": {
31
- "types": "./dist/svelte/index.d.ts",
32
- "import": "./dist/svelte/index.js",
33
- "require": "./dist/svelte/index.cjs"
34
- }
19
+ "./package.json": "./package.json"
35
20
  },
21
+ "files": [
22
+ "dist"
23
+ ],
36
24
  "dependencies": {
37
- "@embedpdf/models": "2.15.0"
25
+ "@embedpdf/core": "3.0.0-next.13",
26
+ "@embedpdf/core-signature": "3.0.0-next.13",
27
+ "@embedpdf/engine-core": "3.0.0-next.13",
28
+ "@embedpdf/plugin-annotation": "3.0.0-next.13",
29
+ "@embedpdf/plugin-interaction": "3.0.0-next.13",
30
+ "@embedpdf/plugin-stamp": "3.0.0-next.13",
31
+ "@embedpdf/plugin-form": "3.0.0-next.13"
38
32
  },
39
33
  "devDependencies": {
40
- "@types/react": "^18.2.0",
41
34
  "typescript": "^5.0.0",
42
- "@embedpdf/core": "2.15.0",
43
- "@embedpdf/build": "1.1.0",
44
- "@embedpdf/plugin-annotation": "2.15.0"
45
- },
46
- "peerDependencies": {
47
- "react": ">=16.8.0",
48
- "react-dom": ">=16.8.0",
49
- "preact": "^10.26.4",
50
- "vue": ">=3.2.0",
51
- "svelte": ">=5 <6",
52
- "@embedpdf/core": "2.15.0",
53
- "@embedpdf/plugin-annotation": "2.15.0"
35
+ "vitest": "^2.1.9",
36
+ "@embedpdf/engine": "3.0.0-next.13",
37
+ "@embedpdf/tooling-build": "0.0.0"
54
38
  },
55
- "files": [
56
- "dist",
57
- "README.md"
58
- ],
39
+ "license": "Apache-2.0",
40
+ "sideEffects": false,
59
41
  "repository": {
60
42
  "type": "git",
61
- "url": "https://github.com/embedpdf/embed-pdf-viewer",
62
- "directory": "packages/plugin-signature"
63
- },
64
- "homepage": "https://www.embedpdf.com/docs",
65
- "bugs": {
66
- "url": "https://github.com/embedpdf/embed-pdf-viewer/issues"
67
- },
68
- "publishConfig": {
69
- "access": "public"
43
+ "url": "git+https://github.com/embedpdf/embed-pdf-viewer.git",
44
+ "directory": "packages/plugin/signature"
70
45
  },
71
46
  "scripts": {
72
- "build:base": "vite build --mode base",
73
- "build:react": "vite build --mode react",
74
- "build:preact": "vite build --mode preact",
75
- "build:vue": "vite build --mode vue",
76
- "build:svelte": "vite build --mode svelte",
77
- "build": "pnpm run clean && concurrently -c auto -n base,react,preact,vue,svelte \"vite build --mode base\" \"vite build --mode react\" \"vite build --mode preact\" \"vite build --mode vue\" \"vite build --mode svelte\"",
47
+ "build": "epdf-build",
78
48
  "clean": "rimraf dist",
79
- "lint": "eslint src --color",
80
- "lint:fix": "eslint src --color --fix"
49
+ "typecheck": "tsc -p tsconfig.json --noEmit",
50
+ "test": "vitest run --passWithNoTests"
81
51
  }
82
52
  }
@@ -1,14 +0,0 @@
1
- import { Action } from '@embedpdf/core';
2
- export declare const ADD_SIGNATURE_ENTRY = "SIGNATURE/ADD_ENTRY";
3
- export declare const REMOVE_SIGNATURE_ENTRY = "SIGNATURE/REMOVE_ENTRY";
4
- export interface AddSignatureEntryAction extends Action {
5
- type: typeof ADD_SIGNATURE_ENTRY;
6
- payload: string;
7
- }
8
- export interface RemoveSignatureEntryAction extends Action {
9
- type: typeof REMOVE_SIGNATURE_ENTRY;
10
- payload: string;
11
- }
12
- export type SignatureAction = AddSignatureEntryAction | RemoveSignatureEntryAction;
13
- export declare function addSignatureEntry(id: string): AddSignatureEntryAction;
14
- export declare function removeSignatureEntry(id: string): RemoveSignatureEntryAction;
@@ -1,4 +0,0 @@
1
- import { PdfInkAnnoObject } from '@embedpdf/models';
2
- import { HandlerFactory } from '@embedpdf/plugin-annotation';
3
- import { SIGNATURE_INK_TOOL_ID } from '../tools';
4
- export declare const signatureInkHandlerFactory: HandlerFactory<PdfInkAnnoObject, typeof SIGNATURE_INK_TOOL_ID>;
@@ -1,4 +0,0 @@
1
- import { PdfStampAnnoObject } from '@embedpdf/models';
2
- import { HandlerFactory } from '@embedpdf/plugin-annotation';
3
- import { SIGNATURE_STAMP_TOOL_ID } from '../tools';
4
- export declare const signatureStampHandlerFactory: HandlerFactory<PdfStampAnnoObject, typeof SIGNATURE_STAMP_TOOL_ID>;
@@ -1,12 +0,0 @@
1
- import { PluginPackage } from '@embedpdf/core';
2
- import { SignaturePluginConfig, SignatureState } from './types';
3
- import { SignaturePlugin } from './signature-plugin';
4
- import { SignatureAction } from './actions';
5
- export declare const SignaturePluginPackage: PluginPackage<SignaturePlugin, SignaturePluginConfig, SignatureState, SignatureAction>;
6
- export * from './signature-plugin';
7
- export * from './types';
8
- export * from './manifest';
9
- export * from './actions';
10
- export * from './reducer';
11
- export { SIGNATURE_STAMP_TOOL_ID, SIGNATURE_INK_TOOL_ID } from './tools';
12
- export * from './serialization';
@@ -1,4 +0,0 @@
1
- import { PluginManifest } from '@embedpdf/core';
2
- import { SignaturePluginConfig } from './types';
3
- export declare const SIGNATURE_PLUGIN_ID = "signature";
4
- export declare const manifest: PluginManifest<SignaturePluginConfig>;
@@ -1,5 +0,0 @@
1
- import { Reducer } from '@embedpdf/core';
2
- import { SignatureAction } from './actions';
3
- import { SignatureState } from './types';
4
- export declare const initialState: SignatureState;
5
- export declare const signatureReducer: Reducer<SignatureState, SignatureAction>;
@@ -1,30 +0,0 @@
1
- import { SignatureEntry, SignatureCreationType } from './types';
2
- export interface SerializedSignatureStampField {
3
- creationType: SignatureCreationType.Type | SignatureCreationType.Upload;
4
- label?: string;
5
- previewDataUrl: string;
6
- imageMimeType?: string;
7
- imageSize?: {
8
- width: number;
9
- height: number;
10
- };
11
- imageData?: string;
12
- }
13
- export type SerializedSignatureFieldDefinition = import('./types').SignatureInkFieldDefinition | SerializedSignatureStampField;
14
- export interface SerializedSignatureEntry {
15
- id: string;
16
- createdAt: number;
17
- signature: SerializedSignatureFieldDefinition;
18
- initials?: SerializedSignatureFieldDefinition;
19
- }
20
- /**
21
- * Converts signature entries into a JSON-safe format by encoding
22
- * ArrayBuffer fields as base64 strings. Use with `JSON.stringify`
23
- * for persistence (e.g. localStorage, IndexedDB, or a backend API).
24
- */
25
- export declare function serializeEntries(entries: SignatureEntry[]): SerializedSignatureEntry[];
26
- /**
27
- * Restores signature entries from the JSON-safe format produced by
28
- * `serializeEntries`, converting base64 strings back to ArrayBuffers.
29
- */
30
- export declare function deserializeEntries(data: SerializedSignatureEntry[]): SignatureEntry[];
@@ -1,27 +0,0 @@
1
- import { BasePlugin, PluginRegistry } from '@embedpdf/core';
2
- import { SignatureCapability, SignatureEntry, SignaturePluginConfig, SignatureState } from './types';
3
- import { SignatureAction } from './actions';
4
- export declare class SignaturePlugin extends BasePlugin<SignaturePluginConfig, SignatureCapability, SignatureState, SignatureAction> {
5
- private config;
6
- static readonly id = "signature";
7
- private readonly entries;
8
- private readonly entriesChange$;
9
- private readonly activePlacement$;
10
- private annotation;
11
- private toolChangeUnsubscribe;
12
- private currentGhostUrl;
13
- constructor(id: string, registry: PluginRegistry, config: SignaturePluginConfig);
14
- initialize(): Promise<void>;
15
- protected buildCapability(): SignatureCapability;
16
- getEntries(): SignatureEntry[];
17
- addEntry(entry: Omit<SignatureEntry, 'id' | 'createdAt'>): string;
18
- removeEntry(id: string): void;
19
- loadEntries(entries: SignatureEntry[]): void;
20
- exportEntries(): SignatureEntry[];
21
- private createSignatureScope;
22
- private activatePlacement;
23
- private deactivatePlacement;
24
- private revokeGhostUrl;
25
- private emitEntriesChange;
26
- destroy(): Promise<void>;
27
- }
@@ -1,113 +0,0 @@
1
- import { PdfAnnotationSubtype } from '@embedpdf/models';
2
- import { patching } from '@embedpdf/plugin-annotation';
3
- export declare const SIGNATURE_STAMP_TOOL_ID: "signatureStamp";
4
- export declare const SIGNATURE_INK_TOOL_ID: "signatureInk";
5
- export declare const signatureStampTool: {
6
- readonly id: "signatureStamp";
7
- readonly name: "Signature Stamp";
8
- readonly labelKey: "signature.stamp";
9
- readonly categories: ["annotation", "signature", "insert"];
10
- readonly matchScore: () => number;
11
- readonly interaction: {
12
- readonly exclusive: true;
13
- readonly cursor: "copy";
14
- readonly isDraggable: true;
15
- readonly isResizable: true;
16
- readonly isRotatable: false;
17
- readonly lockAspectRatio: true;
18
- readonly isGroupDraggable: true;
19
- readonly isGroupResizable: false;
20
- readonly isGroupRotatable: false;
21
- };
22
- readonly defaults: {
23
- readonly type: PdfAnnotationSubtype.STAMP;
24
- };
25
- readonly behavior: {
26
- readonly deactivateToolAfterCreate: true;
27
- readonly selectAfterCreate: true;
28
- readonly insertUpright: true;
29
- readonly useAppearanceStream: true;
30
- };
31
- readonly pointerHandler: import('@embedpdf/plugin-annotation').HandlerFactory<import('@embedpdf/models').PdfStampAnnoObject, "signatureStamp">;
32
- };
33
- export declare const signatureInkTool: {
34
- readonly id: "signatureInk";
35
- readonly name: "Signature Ink";
36
- readonly labelKey: "signature.ink";
37
- readonly categories: ["annotation", "signature", "insert"];
38
- readonly matchScore: (a: import('@embedpdf/models').PdfAnnotationObject) => 0 | 20;
39
- readonly interaction: {
40
- readonly exclusive: true;
41
- readonly cursor: "copy";
42
- readonly isDraggable: true;
43
- readonly isResizable: true;
44
- readonly isRotatable: false;
45
- readonly lockAspectRatio: true;
46
- readonly isGroupDraggable: true;
47
- readonly isGroupResizable: false;
48
- readonly isGroupRotatable: false;
49
- };
50
- readonly defaults: {
51
- readonly type: PdfAnnotationSubtype.INK;
52
- };
53
- readonly behavior: {
54
- readonly deactivateToolAfterCreate: true;
55
- readonly selectAfterCreate: true;
56
- };
57
- readonly transform: patching.PatchFunction<import('@embedpdf/models').PdfInkAnnoObject>;
58
- readonly pointerHandler: import('@embedpdf/plugin-annotation').HandlerFactory<import('@embedpdf/models').PdfInkAnnoObject, "signatureInk">;
59
- };
60
- export declare const signatureTools: ({
61
- readonly id: "signatureStamp";
62
- readonly name: "Signature Stamp";
63
- readonly labelKey: "signature.stamp";
64
- readonly categories: ["annotation", "signature", "insert"];
65
- readonly matchScore: () => number;
66
- readonly interaction: {
67
- readonly exclusive: true;
68
- readonly cursor: "copy";
69
- readonly isDraggable: true;
70
- readonly isResizable: true;
71
- readonly isRotatable: false;
72
- readonly lockAspectRatio: true;
73
- readonly isGroupDraggable: true;
74
- readonly isGroupResizable: false;
75
- readonly isGroupRotatable: false;
76
- };
77
- readonly defaults: {
78
- readonly type: PdfAnnotationSubtype.STAMP;
79
- };
80
- readonly behavior: {
81
- readonly deactivateToolAfterCreate: true;
82
- readonly selectAfterCreate: true;
83
- readonly insertUpright: true;
84
- readonly useAppearanceStream: true;
85
- };
86
- readonly pointerHandler: import('@embedpdf/plugin-annotation').HandlerFactory<import('@embedpdf/models').PdfStampAnnoObject, "signatureStamp">;
87
- } | {
88
- readonly id: "signatureInk";
89
- readonly name: "Signature Ink";
90
- readonly labelKey: "signature.ink";
91
- readonly categories: ["annotation", "signature", "insert"];
92
- readonly matchScore: (a: import('@embedpdf/models').PdfAnnotationObject) => 0 | 20;
93
- readonly interaction: {
94
- readonly exclusive: true;
95
- readonly cursor: "copy";
96
- readonly isDraggable: true;
97
- readonly isResizable: true;
98
- readonly isRotatable: false;
99
- readonly lockAspectRatio: true;
100
- readonly isGroupDraggable: true;
101
- readonly isGroupResizable: false;
102
- readonly isGroupRotatable: false;
103
- };
104
- readonly defaults: {
105
- readonly type: PdfAnnotationSubtype.INK;
106
- };
107
- readonly behavior: {
108
- readonly deactivateToolAfterCreate: true;
109
- readonly selectAfterCreate: true;
110
- };
111
- readonly transform: patching.PatchFunction<import('@embedpdf/models').PdfInkAnnoObject>;
112
- readonly pointerHandler: import('@embedpdf/plugin-annotation').HandlerFactory<import('@embedpdf/models').PdfInkAnnoObject, "signatureInk">;
113
- })[];
@@ -1,114 +0,0 @@
1
- import { BasePluginConfig, EventHook } from '@embedpdf/core';
2
- export declare enum SignatureMode {
3
- SignatureOnly = "signature-only",
4
- SignatureAndInitials = "signature-and-initials"
5
- }
6
- export declare enum SignatureCreationType {
7
- Draw = "draw",
8
- Type = "type",
9
- Upload = "upload"
10
- }
11
- export declare enum SignatureFieldKind {
12
- Signature = "signature",
13
- Initials = "initials"
14
- }
15
- export interface SignatureInkData {
16
- inkList: Array<{
17
- points: Array<{
18
- x: number;
19
- y: number;
20
- }>;
21
- }>;
22
- strokeWidth: number;
23
- strokeColor: string;
24
- size: {
25
- width: number;
26
- height: number;
27
- };
28
- }
29
- interface SignatureFieldBase {
30
- label?: string;
31
- previewDataUrl: string;
32
- }
33
- export interface SignatureInkFieldDefinition extends SignatureFieldBase {
34
- creationType: SignatureCreationType.Draw;
35
- inkData: SignatureInkData;
36
- }
37
- export interface SignatureStampFieldDefinition extends SignatureFieldBase {
38
- creationType: SignatureCreationType.Type | SignatureCreationType.Upload;
39
- imageMimeType?: string;
40
- imageSize?: {
41
- width: number;
42
- height: number;
43
- };
44
- imageData?: ArrayBuffer;
45
- }
46
- export type SignatureFieldDefinition = SignatureInkFieldDefinition | SignatureStampFieldDefinition;
47
- export interface SignatureEntry {
48
- id: string;
49
- createdAt: number;
50
- signature: SignatureFieldDefinition;
51
- initials?: SignatureFieldDefinition;
52
- }
53
- export interface SignaturePluginConfig extends BasePluginConfig {
54
- mode: SignatureMode;
55
- defaultSize?: {
56
- width: number;
57
- height: number;
58
- };
59
- }
60
- export interface SignatureState {
61
- entryIds: string[];
62
- }
63
- export interface SignatureStampToolContext {
64
- imageData: ArrayBuffer;
65
- ghostUrl: string;
66
- targetSize: {
67
- width: number;
68
- height: number;
69
- };
70
- entryId: string;
71
- kind: SignatureFieldKind;
72
- }
73
- export interface SignatureInkToolContext {
74
- inkData: SignatureInkData;
75
- targetSize: {
76
- width: number;
77
- height: number;
78
- };
79
- entryId: string;
80
- kind: SignatureFieldKind;
81
- }
82
- declare module '@embedpdf/plugin-annotation' {
83
- interface ToolContextMap {
84
- signatureStamp: SignatureStampToolContext;
85
- signatureInk: SignatureInkToolContext;
86
- }
87
- }
88
- export interface ActivePlacementInfo {
89
- entryId: string;
90
- kind: SignatureFieldKind;
91
- }
92
- export interface ActivePlacementChangeEvent {
93
- documentId: string;
94
- activePlacement: ActivePlacementInfo | null;
95
- }
96
- export interface SignatureScope {
97
- activateSignaturePlacement(entryId: string): void;
98
- activateInitialsPlacement(entryId: string): void;
99
- deactivatePlacement(): void;
100
- getActivePlacement(): ActivePlacementInfo | null;
101
- onActivePlacementChange: EventHook<ActivePlacementInfo | null>;
102
- }
103
- export interface SignatureCapability {
104
- readonly mode: SignatureMode;
105
- getEntries(): SignatureEntry[];
106
- addEntry(entry: Omit<SignatureEntry, 'id' | 'createdAt'>): string;
107
- removeEntry(id: string): void;
108
- loadEntries(entries: SignatureEntry[]): void;
109
- exportEntries(): SignatureEntry[];
110
- onEntriesChange: EventHook<SignatureEntry[]>;
111
- forDocument(documentId: string): SignatureScope;
112
- onActivePlacementChange: EventHook<ActivePlacementChangeEvent>;
113
- }
114
- export {};
@@ -1,5 +0,0 @@
1
- export { Fragment } from 'preact';
2
- export { useEffect, useRef, useState, useCallback, useMemo } from 'preact/hooks';
3
- export type { ComponentChildren as ReactNode } from 'preact';
4
- export type CSSProperties = import('preact').JSX.CSSProperties;
5
- export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
@@ -1 +0,0 @@
1
- export * from '@embedpdf/plugin-annotation/preact';
@@ -1 +0,0 @@
1
- export * from '@embedpdf/core/preact';