@schnsrw/casual-sheets 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +200 -0
- package/dist/embed.cjs +211 -0
- package/dist/embed.cjs.map +1 -0
- package/dist/embed.d.cts +193 -0
- package/dist/embed.d.ts +193 -0
- package/dist/embed.js +183 -0
- package/dist/embed.js.map +1 -0
- package/dist/index.cjs +899 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +864 -0
- package/dist/index.js.map +1 -0
- package/dist/signing.cjs +716 -0
- package/dist/signing.cjs.map +1 -0
- package/dist/signing.d.cts +141 -0
- package/dist/signing.d.ts +141 -0
- package/dist/signing.js +683 -0
- package/dist/signing.js.map +1 -0
- package/dist/types-s_O0u6Cg.d.cts +90 -0
- package/dist/types-s_O0u6Cg.d.ts +90 -0
- package/package.json +77 -0
- package/src/embed/EmbedTransport.ts +295 -0
- package/src/embed/EmbedTransport.unit.test.ts +161 -0
- package/src/embed/index.ts +40 -0
- package/src/embed/protocol.ts +161 -0
- package/src/index.ts +13 -0
- package/src/signing/SigningPane.tsx +374 -0
- package/src/signing/SigningProvider.tsx +126 -0
- package/src/signing/captures.tsx +316 -0
- package/src/signing/controller.ts +151 -0
- package/src/signing/controller.unit.test.ts +133 -0
- package/src/signing/index.ts +44 -0
- package/src/signing/types.ts +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/signing/SigningProvider.tsx","../src/signing/controller.ts","../src/signing/SigningPane.tsx","../src/signing/captures.tsx","../src/embed/protocol.ts","../src/embed/EmbedTransport.ts"],"sourcesContent":["/**\n * @schnsrw/casual-sheets — Casual Sheets SDK\n *\n * Two surfaces shipped in v0.1.0:\n * - `./signing` — anchored cell signatures (drawn / typed / uploaded)\n * - `./embed` — iframe postMessage protocol for host integrations\n *\n * A `CasualSheets` React component that wraps the Univer-Sheets bootstrap\n * is planned for a follow-up release.\n */\n\nexport * from './signing';\nexport * from './embed';\n","/**\n * SigningProvider — wraps a signing session in React context so\n * descendant components (SigningPane, capture surfaces, and the\n * editor's field-highlight decorations) all see the same snapshot.\n *\n * The pure state machine lives in `./controller.ts`; this file\n * just bridges it to React.\n */\n\nimport { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react';\n\nimport {\n createSigningController,\n type SigningController,\n type SigningSnapshot,\n} from './controller';\nimport type {\n CancelReason,\n SignatureCompletePayload,\n SignedFieldPayload,\n SigningSessionConfig,\n} from './types';\n\ninterface SigningContextValue {\n controller: SigningController;\n snapshot: SigningSnapshot;\n /** Convenience wrapper around controller.signField that also fires the host's onFieldSigned. */\n signField: (payload: SignedFieldPayload) => Promise<void>;\n /** Convenience wrapper around controller.complete + host's onComplete. */\n completeIfReady: () => Promise<void>;\n /** Convenience wrapper around controller.cancel + host's onCancel. */\n cancel: (reason: CancelReason) => void;\n /** Source-of-truth document bytes the editor renders. Captured at\n * signing-session open; persists for the lifetime of the session. */\n baseDocumentBytes: ArrayBuffer | null;\n}\n\nconst SigningContext = createContext<SigningContextValue | null>(null);\n\nexport interface SigningProviderProps {\n /** Active signing session config. When null, signing is off and\n * children render unchanged. */\n session: SigningSessionConfig | null;\n /** Current document bytes the editor is rendering. Captured into\n * the context so the eventual `complete` payload carries the\n * right base buffer. */\n documentBytes: ArrayBuffer | null;\n children: ReactNode;\n}\n\nexport function SigningProvider({ session, documentBytes, children }: SigningProviderProps) {\n if (!session) {\n return <>{children}</>;\n }\n return (\n <SigningProviderInner session={session} documentBytes={documentBytes}>\n {children}\n </SigningProviderInner>\n );\n}\n\nfunction SigningProviderInner({\n session,\n documentBytes,\n children,\n}: {\n session: SigningSessionConfig;\n documentBytes: ArrayBuffer | null;\n children: ReactNode;\n}) {\n // Controller is constructed once per session-config identity.\n // Hosts that swap sessions mid-tree must change the React `key`\n // on the provider — otherwise stale state would leak.\n const controller = useMemo(\n () => createSigningController(session.fields, session.mode),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [session.fields, session.mode],\n );\n\n const [snapshot, setSnapshot] = useState<SigningSnapshot>(() => controller.snapshot());\n\n useEffect(() => {\n const unsub = controller.subscribe(setSnapshot);\n return unsub;\n }, [controller]);\n\n const value = useMemo<SigningContextValue>(\n () => ({\n controller,\n snapshot,\n signField: async (payload) => {\n controller.signField(payload);\n await session.onFieldSigned?.(payload);\n },\n completeIfReady: async () => {\n if (!controller.snapshot().canComplete) return;\n const final = controller.complete();\n const completePayload: SignatureCompletePayload = {\n fieldIds: final.fields\n .map((f) => f.fieldId)\n .filter((id) => final.signed[id] !== undefined),\n bytes: documentBytes ?? new ArrayBuffer(0),\n fields: final.signed,\n };\n await session.onComplete?.(completePayload);\n },\n cancel: (reason) => {\n controller.cancel();\n session.onCancel?.({ reason });\n },\n baseDocumentBytes: documentBytes,\n }),\n [controller, snapshot, session, documentBytes],\n );\n\n return <SigningContext.Provider value={value}>{children}</SigningContext.Provider>;\n}\n\n/**\n * Hook for descendants of <SigningProvider>. Returns null when\n * no signing session is active — caller renders its non-signing\n * shape.\n */\nexport function useSigning(): SigningContextValue | null {\n return useContext(SigningContext);\n}\n","/**\n * Signing state machine — pure with respect to React so bun-test\n * can exercise it without a renderer. The React wrappers\n * (SigningProvider / SigningPane) sit on top of this.\n *\n * Single source of truth for \"which field is the signer on,\n * which fields are done, can we complete yet\" — the React layer\n * never recomputes these from scratch.\n */\n\nimport type { SignedFieldPayload, SignatureField, SignatureMode } from './types';\n\nexport interface SigningSnapshot {\n fields: SignatureField[];\n mode: SignatureMode;\n /** Fields completed in order they were signed. */\n signed: Record<string, SignedFieldPayload>;\n /** Index into `fields` of the field the signer should focus on\n * next. -1 once everything required is done. */\n activeFieldIndex: number;\n /** True once every required field has a payload. */\n canComplete: boolean;\n /** True once the controller has received a completion command. */\n isComplete: boolean;\n /** True if a cancel has been emitted. */\n isCancelled: boolean;\n}\n\nexport interface SigningController {\n snapshot(): SigningSnapshot;\n subscribe(listener: (s: SigningSnapshot) => void): () => void;\n /** Record a signed field. Throws if the field id is unknown. */\n signField(payload: SignedFieldPayload): void;\n /** Move focus to a specific field (concurrent mode let users\n * pick); in sequential mode the controller silently no-ops if\n * the requested field isn't the next required. */\n focusField(fieldId: string): void;\n /** Mark the session complete. Returns the snapshot at the\n * moment of completion; throws if not yet canComplete. */\n complete(): SigningSnapshot;\n /** Mark the session cancelled. Idempotent. */\n cancel(): void;\n}\n\nexport function createSigningController(\n fields: SignatureField[],\n mode: SignatureMode,\n): SigningController {\n if (fields.length === 0) {\n throw new Error('createSigningController: at least one field required');\n }\n const fieldIds = new Set(fields.map((f) => f.fieldId));\n if (fieldIds.size !== fields.length) {\n throw new Error('createSigningController: duplicate fieldId');\n }\n\n const signed: Record<string, SignedFieldPayload> = {};\n let activeFieldIndex = nextRequiredIndex(fields, signed);\n let isComplete = false;\n let isCancelled = false;\n const listeners = new Set<(s: SigningSnapshot) => void>();\n\n function emit() {\n const snap = snapshotInternal();\n for (const l of listeners) l(snap);\n }\n\n function snapshotInternal(): SigningSnapshot {\n return {\n fields,\n mode,\n signed: { ...signed },\n activeFieldIndex,\n canComplete: allRequiredSigned(fields, signed),\n isComplete,\n isCancelled,\n };\n }\n\n return {\n snapshot: snapshotInternal,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n signField(payload) {\n if (isComplete || isCancelled) return;\n if (!fieldIds.has(payload.fieldId)) {\n throw new Error(`signField: unknown fieldId ${payload.fieldId}`);\n }\n signed[payload.fieldId] = payload;\n activeFieldIndex = nextRequiredIndex(fields, signed);\n emit();\n },\n focusField(fieldId) {\n if (isComplete || isCancelled) return;\n const idx = fields.findIndex((f) => f.fieldId === fieldId);\n if (idx < 0) return;\n if (mode === 'sequential') {\n // Sequential mode: only the next-required field is focusable.\n const next = nextRequiredIndex(fields, signed);\n if (idx !== next) return;\n }\n activeFieldIndex = idx;\n emit();\n },\n complete() {\n if (!allRequiredSigned(fields, signed)) {\n throw new Error('complete: required fields are still unsigned');\n }\n isComplete = true;\n activeFieldIndex = -1;\n emit();\n return snapshotInternal();\n },\n cancel() {\n if (isComplete || isCancelled) return;\n isCancelled = true;\n activeFieldIndex = -1;\n emit();\n },\n };\n}\n\n// ---------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------\n\nfunction allRequiredSigned(\n fields: SignatureField[],\n signed: Record<string, SignedFieldPayload>,\n): boolean {\n return fields.every((f) => !f.required || signed[f.fieldId] !== undefined);\n}\n\nfunction nextRequiredIndex(\n fields: SignatureField[],\n signed: Record<string, SignedFieldPayload>,\n): number {\n for (let i = 0; i < fields.length; i++) {\n if (fields[i].required && !signed[fields[i].fieldId]) return i;\n }\n // Either all required are done OR no required exists; pick the\n // first unsigned optional.\n for (let i = 0; i < fields.length; i++) {\n if (!signed[fields[i].fieldId]) return i;\n }\n return -1;\n}\n","/**\n * SigningPane — the floating sidebar that walks the signer through\n * fields. Lives inside <SigningProvider>; uses the controller via\n * `useSigning()`.\n *\n * Layout: a right-anchored panel showing\n * - Banner (optional, from session config)\n * - Field list with state markers (active / signed / pending)\n * - Method picker for the active field\n * - Capture surface (Drawn / Typed / Uploaded) depending on method\n * - Footer: Cancel + Complete\n *\n * The pane is presentation-only — every action routes through the\n * SigningProvider's helpers (signField, completeIfReady, cancel)\n * so the controller stays the single source of truth.\n */\n\nimport { useEffect, useState, type CSSProperties } from 'react';\n\nimport { useSigning } from './SigningProvider';\nimport type { SignatureField, SignatureMethod, SignedFieldPayload } from './types';\nimport {\n DrawnSignaturePad,\n TypedSignatureField,\n UploadedSignatureField,\n type CapturedSignature,\n} from './captures';\n\nexport interface SigningPaneProps {\n /** Optional banner override; falls back to session.banner. */\n banner?: string;\n /** Optional data-testid root. */\n testId?: string;\n}\n\nexport function SigningPane({ banner, testId = 'signing-pane' }: SigningPaneProps) {\n const ctx = useSigning();\n if (!ctx) return null;\n\n const { snapshot, signField, completeIfReady, cancel } = ctx;\n if (snapshot.isComplete || snapshot.isCancelled) return null;\n\n const active: SignatureField | null =\n snapshot.activeFieldIndex >= 0 ? snapshot.fields[snapshot.activeFieldIndex] : null;\n\n return (\n <aside style={paneStyle} role=\"region\" aria-label=\"Signing pane\" data-testid={testId}>\n {banner && (\n <div style={bannerStyle} data-testid={`${testId}-banner`}>\n {banner}\n </div>\n )}\n <div style={listStyle} data-testid={`${testId}-fields`}>\n {snapshot.fields.map((f, i) => {\n const isSigned = !!snapshot.signed[f.fieldId];\n const isActive = i === snapshot.activeFieldIndex;\n return (\n <div\n key={f.fieldId}\n style={listItemStyle(isActive, isSigned)}\n data-testid={`${testId}-field-${f.fieldId}`}\n data-state={isSigned ? 'signed' : isActive ? 'active' : 'pending'}\n >\n <span style={listIconStyle(isSigned)} aria-hidden=\"true\">\n {isSigned ? '✓' : i + 1}\n </span>\n <span style={listLabelStyle}>{f.label}</span>\n {!f.required && (\n <span style={optionalChipStyle} aria-label=\"Optional\">\n optional\n </span>\n )}\n </div>\n );\n })}\n </div>\n\n {active && (\n <ActiveFieldEditor\n field={active}\n testId={testId}\n onCapture={async (cap, method) => {\n const payload: SignedFieldPayload = {\n fieldId: active.fieldId,\n method,\n bytes: cap.bytes,\n mime: cap.mime,\n signedAt: new Date().toISOString(),\n };\n await signField(payload);\n }}\n />\n )}\n\n {!active && snapshot.canComplete && (\n <div style={completeBlockStyle} data-testid={`${testId}-complete-block`}>\n All required signatures collected. Ready to finalise.\n </div>\n )}\n\n <footer style={footerStyle}>\n <button\n type=\"button\"\n onClick={() => cancel('signer_cancelled')}\n style={secondaryBtnStyle()}\n data-testid={`${testId}-cancel`}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void completeIfReady()}\n disabled={!snapshot.canComplete}\n style={primaryBtnStyle(!snapshot.canComplete)}\n data-testid={`${testId}-complete`}\n >\n Complete\n </button>\n </footer>\n </aside>\n );\n}\n\n// ---------------------------------------------------------------\n// Active field editor — method picker + capture surface\n// ---------------------------------------------------------------\n\nfunction ActiveFieldEditor({\n field,\n testId,\n onCapture,\n}: {\n field: SignatureField;\n testId: string;\n onCapture: (cap: CapturedSignature, method: SignatureMethod) => void | Promise<void>;\n}) {\n const [method, setMethod] = useState<SignatureMethod>(field.methods[0]);\n\n // Reset the method picker whenever the active field changes — a\n // method that was valid for the previous field may not be in this\n // field's list.\n useEffect(() => {\n setMethod(field.methods[0]);\n }, [field]);\n\n return (\n <div style={editorStyle} data-testid={`${testId}-editor`}>\n <div style={editorHeaderStyle}>\n <div style={editorLabelStyle}>{field.label}</div>\n {field.signer?.name && <div style={editorSignerStyle}>{field.signer.name}</div>}\n </div>\n {field.methods.length > 1 && (\n <div style={methodTabsStyle} role=\"tablist\" data-testid={`${testId}-methods`}>\n {field.methods.map((m) => (\n <button\n key={m}\n type=\"button\"\n role=\"tab\"\n aria-selected={method === m}\n onClick={() => setMethod(m)}\n style={methodTabStyle(method === m)}\n data-testid={`${testId}-method-${m}`}\n >\n {methodLabel(m)}\n </button>\n ))}\n </div>\n )}\n <div style={captureWrapStyle}>\n {method === 'drawn' && <DrawnSignaturePad onCapture={(c) => onCapture(c, 'drawn')} />}\n {method === 'typed' && (\n <TypedSignatureField\n defaultText={field.signer?.name ?? ''}\n onCapture={(c) => onCapture(c, 'typed')}\n />\n )}\n {method === 'uploaded' && (\n <UploadedSignatureField onCapture={(c) => onCapture(c, 'uploaded')} />\n )}\n </div>\n </div>\n );\n}\n\nfunction methodLabel(m: SignatureMethod): string {\n switch (m) {\n case 'drawn':\n return 'Draw';\n case 'typed':\n return 'Type';\n case 'uploaded':\n return 'Upload';\n }\n}\n\n// ---------------------------------------------------------------\n// Styles\n// ---------------------------------------------------------------\n\nconst paneStyle: CSSProperties = {\n position: 'fixed',\n top: 16,\n right: 16,\n bottom: 16,\n width: 360,\n maxWidth: '100vw',\n display: 'flex',\n flexDirection: 'column',\n gap: 14,\n padding: 16,\n background: 'var(--doc-surface, #fff)',\n border: '1px solid var(--doc-border, #cbd5e1)',\n borderRadius: 12,\n boxShadow: '0 1px 1px rgba(0, 0, 0, 0.04), 0 6px 24px rgba(15, 23, 42, 0.12)',\n fontFamily: 'inherit',\n zIndex: 9000,\n};\n\nconst bannerStyle: CSSProperties = {\n padding: '8px 10px',\n background: 'var(--doc-surface-2, #f1f5f9)',\n border: '1px solid var(--doc-border-light, #e2e8f0)',\n borderRadius: 6,\n fontSize: 12,\n color: 'var(--doc-text-muted, #475569)',\n};\n\nconst listStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 4,\n};\n\nfunction listItemStyle(active: boolean, signed: boolean): CSSProperties {\n return {\n display: 'flex',\n alignItems: 'center',\n gap: 10,\n padding: '8px 10px',\n borderRadius: 6,\n background: active ? 'var(--doc-surface-2, #f1f5f9)' : signed ? 'transparent' : 'transparent',\n border: active ? '1px solid var(--doc-border, #cbd5e1)' : '1px solid transparent',\n opacity: signed && !active ? 0.7 : 1,\n };\n}\n\nfunction listIconStyle(signed: boolean): CSSProperties {\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: 22,\n height: 22,\n borderRadius: '50%',\n background: signed ? 'var(--doc-accent, #2563eb)' : 'var(--doc-surface-2, #f1f5f9)',\n color: signed ? '#fff' : 'var(--doc-text-muted, #475569)',\n fontSize: 12,\n fontWeight: 600,\n flexShrink: 0,\n };\n}\n\nconst listLabelStyle: CSSProperties = {\n flex: 1,\n fontSize: 13,\n color: 'var(--doc-text, #0f172a)',\n fontWeight: 500,\n};\n\nconst optionalChipStyle: CSSProperties = {\n fontSize: 11,\n color: 'var(--doc-text-muted, #64748b)',\n padding: '2px 6px',\n background: 'var(--doc-surface-2, #f1f5f9)',\n borderRadius: 4,\n};\n\nconst editorStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 12,\n};\n\nconst editorHeaderStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 2,\n};\n\nconst editorLabelStyle: CSSProperties = {\n fontSize: 13,\n fontWeight: 600,\n color: 'var(--doc-text, #0f172a)',\n};\n\nconst editorSignerStyle: CSSProperties = {\n fontSize: 12,\n color: 'var(--doc-text-muted, #64748b)',\n};\n\nconst methodTabsStyle: CSSProperties = {\n display: 'flex',\n gap: 4,\n padding: 2,\n background: 'var(--doc-surface-2, #f1f5f9)',\n borderRadius: 6,\n};\n\nfunction methodTabStyle(selected: boolean): CSSProperties {\n return {\n flex: 1,\n padding: '6px 10px',\n background: selected ? 'var(--doc-surface, #fff)' : 'transparent',\n border: 'none',\n borderRadius: 4,\n fontSize: 12,\n fontWeight: 500,\n color: selected ? 'var(--doc-text, #0f172a)' : 'var(--doc-text-muted, #475569)',\n cursor: 'pointer',\n fontFamily: 'inherit',\n };\n}\n\nconst captureWrapStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 8,\n};\n\nconst completeBlockStyle: CSSProperties = {\n padding: '10px 12px',\n background: 'rgba(34, 197, 94, 0.08)',\n border: '1px solid rgba(34, 197, 94, 0.28)',\n borderRadius: 6,\n fontSize: 12,\n color: 'rgb(20, 83, 45)',\n};\n\nconst footerStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n marginTop: 'auto',\n paddingTop: 12,\n borderTop: '1px solid var(--doc-border-light, #e2e8f0)',\n};\n\nfunction primaryBtnStyle(disabled: boolean): CSSProperties {\n return {\n padding: '8px 16px',\n borderRadius: 6,\n border: '1px solid transparent',\n background: disabled ? 'var(--doc-border, #cbd5e1)' : 'var(--doc-accent, #2563eb)',\n color: disabled ? 'var(--doc-text-muted, #64748b)' : '#fff',\n fontSize: 13,\n fontWeight: 600,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n };\n}\n\nfunction secondaryBtnStyle(): CSSProperties {\n return {\n padding: '8px 16px',\n borderRadius: 6,\n border: '1px solid var(--doc-border, #cbd5e1)',\n background: 'transparent',\n color: 'var(--doc-text, #0f172a)',\n fontSize: 13,\n fontWeight: 500,\n cursor: 'pointer',\n fontFamily: 'inherit',\n };\n}\n","/**\n * Three signature-capture surfaces: drawn (canvas), typed (input\n * rendered in a script font), uploaded (image file picker).\n *\n * Each one emits an `{ bytes, mime }` pair that the parent feeds\n * into SigningContext.signField. The components are presentation +\n * input only — they don't know about the controller or the field\n * they're capturing for.\n */\n\nimport { useEffect, useRef, useState, type CSSProperties } from 'react';\n\nexport interface CapturedSignature {\n bytes: ArrayBuffer;\n mime: string;\n}\n\n// ---------------------------------------------------------------\n// Drawn — canvas\n// ---------------------------------------------------------------\n\nexport interface DrawnSignaturePadProps {\n /** Fired when the user clicks \"Use this signature\". */\n onCapture: (sig: CapturedSignature) => void;\n /** Optional clear-button label override. */\n clearLabel?: string;\n /** Optional save-button label override. */\n saveLabel?: string;\n /** Canvas pixel size. Default 480 × 160. */\n width?: number;\n height?: number;\n}\n\nexport function DrawnSignaturePad({\n onCapture,\n clearLabel = 'Clear',\n saveLabel = 'Use this signature',\n width = 480,\n height = 160,\n}: DrawnSignaturePadProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const drawingRef = useRef(false);\n const [hasInk, setHasInk] = useState(false);\n\n // Set up a clean canvas on mount. Background is transparent so\n // the stamped image composites cleanly over the document.\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.strokeStyle = '#0f172a';\n ctx.lineWidth = 2;\n ctx.lineCap = 'round';\n ctx.lineJoin = 'round';\n }, []);\n\n const start = (e: React.PointerEvent<HTMLCanvasElement>) => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n const { x, y } = pointerPos(e, canvas);\n ctx.beginPath();\n ctx.moveTo(x, y);\n drawingRef.current = true;\n canvas.setPointerCapture(e.pointerId);\n };\n\n const move = (e: React.PointerEvent<HTMLCanvasElement>) => {\n if (!drawingRef.current) return;\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n const { x, y } = pointerPos(e, canvas);\n ctx.lineTo(x, y);\n ctx.stroke();\n if (!hasInk) setHasInk(true);\n };\n\n const end = (e: React.PointerEvent<HTMLCanvasElement>) => {\n drawingRef.current = false;\n canvasRef.current?.releasePointerCapture(e.pointerId);\n };\n\n const clear = () => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n setHasInk(false);\n };\n\n const save = async () => {\n const canvas = canvasRef.current;\n if (!canvas || !hasInk) return;\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob((b) => resolve(b), 'image/png');\n });\n if (!blob) return;\n const bytes = await blob.arrayBuffer();\n onCapture({ bytes, mime: 'image/png' });\n clear();\n };\n\n return (\n <div style={padWrapStyle} data-testid=\"drawn-signature-pad\">\n <canvas\n ref={canvasRef}\n width={width}\n height={height}\n style={padCanvasStyle(width, height)}\n onPointerDown={start}\n onPointerMove={move}\n onPointerUp={end}\n onPointerLeave={end}\n data-testid=\"drawn-signature-canvas\"\n />\n <div style={padActionsStyle}>\n <button type=\"button\" onClick={clear} style={secondaryBtnStyle(false)}>\n {clearLabel}\n </button>\n <button\n type=\"button\"\n onClick={save}\n disabled={!hasInk}\n style={primaryBtnStyle(!hasInk)}\n data-testid=\"drawn-signature-save\"\n >\n {saveLabel}\n </button>\n </div>\n </div>\n );\n}\n\nfunction pointerPos(e: React.PointerEvent<HTMLCanvasElement>, canvas: HTMLCanvasElement) {\n const rect = canvas.getBoundingClientRect();\n const scaleX = canvas.width / rect.width;\n const scaleY = canvas.height / rect.height;\n return {\n x: (e.clientX - rect.left) * scaleX,\n y: (e.clientY - rect.top) * scaleY,\n };\n}\n\n// ---------------------------------------------------------------\n// Typed\n// ---------------------------------------------------------------\n\nexport interface TypedSignatureFieldProps {\n onCapture: (sig: CapturedSignature) => void;\n defaultText?: string;\n saveLabel?: string;\n}\n\nexport function TypedSignatureField({\n onCapture,\n defaultText = '',\n saveLabel = 'Use this signature',\n}: TypedSignatureFieldProps) {\n const [value, setValue] = useState(defaultText);\n const save = () => {\n const trimmed = value.trim();\n if (!trimmed) return;\n const bytes = new TextEncoder().encode(trimmed).buffer;\n onCapture({ bytes, mime: 'text/plain' });\n setValue('');\n };\n return (\n <div style={padWrapStyle} data-testid=\"typed-signature-field\">\n <input\n type=\"text\"\n value={value}\n onChange={(e) => setValue(e.target.value)}\n placeholder=\"Type your full name\"\n style={typedInputStyle}\n data-testid=\"typed-signature-input\"\n autoFocus\n />\n <div style={padActionsStyle}>\n <button\n type=\"button\"\n onClick={save}\n disabled={!value.trim()}\n style={primaryBtnStyle(!value.trim())}\n data-testid=\"typed-signature-save\"\n >\n {saveLabel}\n </button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------\n// Uploaded\n// ---------------------------------------------------------------\n\nexport interface UploadedSignatureFieldProps {\n onCapture: (sig: CapturedSignature) => void;\n /** Accept attribute. Default image/*. */\n accept?: string;\n}\n\nexport function UploadedSignatureField({\n onCapture,\n accept = 'image/png,image/jpeg,image/svg+xml',\n}: UploadedSignatureFieldProps) {\n const inputRef = useRef<HTMLInputElement>(null);\n const [fileName, setFileName] = useState<string | null>(null);\n const onChange = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n const bytes = await file.arrayBuffer();\n onCapture({ bytes, mime: file.type || 'application/octet-stream' });\n setFileName(file.name);\n if (inputRef.current) inputRef.current.value = '';\n };\n return (\n <div style={padWrapStyle} data-testid=\"uploaded-signature-field\">\n <label style={uploadLabelStyle}>\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n onChange={onChange}\n style={{ display: 'none' }}\n data-testid=\"uploaded-signature-input\"\n />\n <span>{fileName ?? 'Choose image…'}</span>\n </label>\n </div>\n );\n}\n\n// ---------------------------------------------------------------\n// Shared styles\n// ---------------------------------------------------------------\n\nconst padWrapStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n gap: 10,\n};\n\nconst padCanvasStyle = (w: number, h: number): CSSProperties => ({\n width: w,\n height: h,\n maxWidth: '100%',\n border: '1px dashed var(--doc-border, #cbd5e1)',\n borderRadius: 8,\n background: 'var(--doc-surface, #fff)',\n cursor: 'crosshair',\n touchAction: 'none',\n});\n\nconst padActionsStyle: CSSProperties = {\n display: 'flex',\n justifyContent: 'flex-end',\n gap: 8,\n};\n\nconst typedInputStyle: CSSProperties = {\n width: '100%',\n padding: '10px 12px',\n border: '1px solid var(--doc-border, #cbd5e1)',\n borderRadius: 6,\n fontSize: 18,\n fontFamily: '\"Caveat\", \"Dancing Script\", \"Brush Script MT\", cursive',\n background: 'var(--doc-surface, #fff)',\n color: 'var(--doc-text, #0f172a)',\n};\n\nconst uploadLabelStyle: CSSProperties = {\n display: 'inline-flex',\n padding: '8px 14px',\n border: '1px dashed var(--doc-border, #cbd5e1)',\n borderRadius: 6,\n background: 'var(--doc-surface, #fff)',\n color: 'var(--doc-text, #0f172a)',\n fontSize: 13,\n cursor: 'pointer',\n alignSelf: 'flex-start',\n};\n\nfunction primaryBtnStyle(disabled: boolean): CSSProperties {\n return {\n padding: '8px 16px',\n borderRadius: 6,\n border: '1px solid transparent',\n background: disabled ? 'var(--doc-border, #cbd5e1)' : 'var(--doc-accent, #2563eb)',\n color: disabled ? 'var(--doc-text-muted, #64748b)' : '#fff',\n fontSize: 13,\n fontWeight: 600,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n };\n}\n\nfunction secondaryBtnStyle(disabled: boolean): CSSProperties {\n return {\n padding: '8px 16px',\n borderRadius: 6,\n border: '1px solid var(--doc-border, #cbd5e1)',\n background: 'transparent',\n color: 'var(--doc-text, #0f172a)',\n fontSize: 13,\n fontWeight: 500,\n cursor: disabled ? 'not-allowed' : 'pointer',\n fontFamily: 'inherit',\n };\n}\n","/**\n * Iframe protocol — wire envelopes that match\n * `docs/internal/13-iframe-protocol.md`.\n *\n * Mirror updates to the doc whenever a new envelope shape lands.\n * The discriminator on `type` (always starts with `casual.`) and\n * the per-envelope `data` shape are the contract.\n */\n\nimport type {\n CancelReason,\n SignatureCompletePayload,\n SignatureField,\n SignatureMode,\n SignedFieldPayload,\n} from '../signing/types';\n\nexport type CasualApp = 'docs' | 'sheet';\n\n/** Common envelope shape — every postMessage on the wire matches this. */\nexport interface CasualEnvelope<T = unknown> {\n type: string;\n app: CasualApp;\n /** Per-request id for request/response correlation. Empty for fire-and-forget. */\n id?: string;\n /** Protocol version. Bumped only on breaking changes. */\n v: 1;\n data: T;\n}\n\n// ---------------------------------------------------------------\n// Handshake\n// ---------------------------------------------------------------\n\nexport interface EditorHelloData {\n capabilities: string[];\n version: string;\n commit: string;\n}\n\nexport interface HostHelloData {\n capabilities: string[];\n authToken?: string;\n}\n\n// ---------------------------------------------------------------\n// Load + save (editor → host requests; host → editor responses)\n// ---------------------------------------------------------------\n\nexport interface LoadRequestData {\n docId: string;\n}\n\nexport interface LoadResponseDataOk {\n ok: true;\n bytes: ArrayBuffer;\n etag?: string;\n fileName: string;\n readOnly?: boolean;\n}\n\nexport interface LoadResponseDataErr {\n ok: false;\n code: string;\n message?: string;\n}\n\nexport type LoadResponseData = LoadResponseDataOk | LoadResponseDataErr;\n\nexport interface SaveRequestData {\n docId: string;\n bytes: ArrayBuffer;\n baseEtag?: string;\n}\n\nexport interface SaveResponseDataOk {\n ok: true;\n etag: string;\n}\n\nexport interface SaveResponseDataErr {\n ok: false;\n code: string;\n etag?: string;\n message?: string;\n}\n\nexport type SaveResponseData = SaveResponseDataOk | SaveResponseDataErr;\n\n// ---------------------------------------------------------------\n// Selection + telemetry + lock (editor → host notifications)\n// ---------------------------------------------------------------\n\nexport interface SelectionChangedData {\n docs?: { paraId: string; from: number; to: number; selectedText: string };\n sheet?: { sheet: string; from: string; to: string };\n}\n\nexport interface TelemetryEventData {\n kind: string;\n /** Arbitrary metric fields. */\n [k: string]: unknown;\n}\n\nexport interface LockLostData {\n reason: 'taken_by_other' | 'expired' | 'host_revoked';\n}\n\n// ---------------------------------------------------------------\n// Commands (host → editor)\n// ---------------------------------------------------------------\n\nexport interface CommandSetReadOnlyData {\n readOnly: boolean;\n}\n\nexport interface CommandSetThemeData {\n theme: 'light' | 'dark' | 'system';\n}\n\nexport interface CommandSetLocaleData {\n locale: string;\n}\n\n// ---------------------------------------------------------------\n// Signing (uniform with the SDK `signing` prop)\n// ---------------------------------------------------------------\n\nexport interface SignatureRequestData {\n fields: SignatureField[];\n mode: SignatureMode;\n banner?: string;\n}\n\nexport interface SignatureRequestAckData {\n ok: boolean;\n code?: string;\n}\n\nexport type SignatureFieldSignedData = SignedFieldPayload;\nexport type SignatureCompleteData = SignatureCompletePayload;\n\nexport interface SignatureCancelData {\n reason: CancelReason;\n}\n\n// ---------------------------------------------------------------\n// Type guards\n// ---------------------------------------------------------------\n\nexport function isCasualEnvelope(value: unknown): value is CasualEnvelope {\n if (!value || typeof value !== 'object') return false;\n const v = value as Record<string, unknown>;\n return (\n typeof v.type === 'string' &&\n v.type.startsWith('casual.') &&\n (v.app === 'docs' || v.app === 'sheet') &&\n v.v === 1 &&\n 'data' in v\n );\n}\n","/**\n * EmbedTransport — postMessage bridge for the iframe-embedded\n * editor. Validates origin, dispatches envelopes to handlers,\n * sends responses back to the host. Pure TypeScript — no React.\n *\n * Wire shape defined in\n * `docs/internal/13-iframe-protocol.md` + `./protocol.ts`.\n *\n * Lifetime: constructed once when the /embed page mounts.\n * Destroyed when the page unloads. Concurrent calls into the same\n * handler are the host's responsibility (well-behaved hosts\n * serialise requests by id).\n */\n\nimport {\n isCasualEnvelope,\n type CasualApp,\n type CasualEnvelope,\n type EditorHelloData,\n type HostHelloData,\n type LoadResponseData,\n type LoadRequestData,\n type SaveRequestData,\n type SaveResponseData,\n type SelectionChangedData,\n type TelemetryEventData,\n type CommandSetReadOnlyData,\n type CommandSetThemeData,\n type CommandSetLocaleData,\n type SignatureRequestData,\n type SignatureRequestAckData,\n type SignatureFieldSignedData,\n type SignatureCompleteData,\n type SignatureCancelData,\n} from './protocol';\n\nexport interface EmbedTransportOptions {\n app: CasualApp;\n /** Origin allowed to send messages. Required — no `*` default. */\n hostOrigin: string;\n /** Editor build identity, surfaced in the editor.hello handshake. */\n version: string;\n commit: string;\n /** Editor-side capabilities advertised at handshake. */\n capabilities: string[];\n /** Optional injection for `window.parent` — tests pass a stub. */\n parentWindow?: {\n postMessage: (msg: unknown, targetOrigin: string, transfer?: Transferable[]) => void;\n };\n /** Optional injection for the window receiving messages — tests pass a stub. */\n hostWindow?: Pick<Window, 'addEventListener' | 'removeEventListener'>;\n}\n\nexport interface EmbedTransportHandlers {\n /** Host → editor handshake. Editor responds with `editor.ready`. */\n onHostHello?: (data: HostHelloData) => void | Promise<void>;\n /** Host → editor: command.* messages. */\n onCommandSetReadOnly?: (data: CommandSetReadOnlyData) => void | Promise<void>;\n onCommandSetTheme?: (data: CommandSetThemeData) => void | Promise<void>;\n onCommandSetLocale?: (data: CommandSetLocaleData) => void | Promise<void>;\n onCommandFocus?: () => void | Promise<void>;\n onCommandSave?: () => void | Promise<void>;\n onCommandLoad?: () => void | Promise<void>;\n /** Host → editor signing session. Editor responds with `signature.request.ack`. */\n onSignatureRequest?: (\n data: SignatureRequestData,\n ) => SignatureRequestAckData | Promise<SignatureRequestAckData>;\n onSignatureCancel?: (data: SignatureCancelData) => void | Promise<void>;\n /** Host → editor: response to a prior load.request the editor issued. */\n onLoadResponse?: (id: string, data: LoadResponseData) => void;\n /** Host → editor: response to a prior save.request the editor issued. */\n onSaveResponse?: (id: string, data: SaveResponseData) => void;\n}\n\nexport class EmbedTransport {\n private readonly opts: Required<Omit<EmbedTransportOptions, 'parentWindow' | 'hostWindow'>> & {\n parentWindow: NonNullable<EmbedTransportOptions['parentWindow']>;\n hostWindow: NonNullable<EmbedTransportOptions['hostWindow']>;\n };\n private handlers: EmbedTransportHandlers = {};\n private destroyed = false;\n private pendingRequests = new Map<string, (env: CasualEnvelope) => void>();\n\n constructor(opts: EmbedTransportOptions) {\n this.opts = {\n ...opts,\n parentWindow:\n opts.parentWindow ??\n (typeof window !== 'undefined'\n ? (window.parent as unknown as NonNullable<EmbedTransportOptions['parentWindow']>)\n : { postMessage: () => undefined }),\n hostWindow:\n opts.hostWindow ??\n (typeof window !== 'undefined'\n ? window\n : ({\n addEventListener: () => undefined,\n removeEventListener: () => undefined,\n } as unknown as NonNullable<EmbedTransportOptions['hostWindow']>)),\n };\n this.boundMessage = this.boundMessage.bind(this);\n this.opts.hostWindow.addEventListener('message', this.boundMessage as EventListener);\n }\n\n /** Replaces the handler set. Idempotent — call multiple times. */\n on(handlers: EmbedTransportHandlers): void {\n this.handlers = { ...this.handlers, ...handlers };\n }\n\n /** Editor → Host: announce ourselves. Call once after handlers are wired. */\n sendHello(): void {\n const data: EditorHelloData = {\n capabilities: this.opts.capabilities,\n version: this.opts.version,\n commit: this.opts.commit,\n };\n this.post('casual.hello', data);\n }\n\n /** Editor → Host: editor is ready to receive commands. */\n sendReady(): void {\n this.post('casual.ready', {});\n }\n\n /** Editor → Host: ask the host to supply document bytes for `docId`. */\n async requestLoad(docId: string, timeoutMs = 30000): Promise<LoadResponseData> {\n return this.request<LoadResponseData>(\n 'casual.load.request',\n { docId } as LoadRequestData,\n timeoutMs,\n );\n }\n\n /** Editor → Host: ask the host to persist `bytes`. */\n async requestSave(req: SaveRequestData, timeoutMs = 30000): Promise<SaveResponseData> {\n return this.request<SaveResponseData>('casual.save.request', req, timeoutMs, [req.bytes]);\n }\n\n /** Editor → Host: selection moved. Fire-and-forget. */\n sendSelectionChanged(data: SelectionChangedData): void {\n this.post('casual.selection.changed', data);\n }\n\n /** Editor → Host: a noteworthy event. */\n sendTelemetry(data: TelemetryEventData): void {\n this.post('casual.telemetry.event', data);\n }\n\n /** Editor → Host: per-field progress during a signing session. */\n sendSignatureFieldSigned(data: SignatureFieldSignedData): void {\n // Bytes ride the transfer list.\n this.post('casual.signature.field.signed', data, [data.bytes]);\n }\n\n /** Editor → Host: signing session is finished. */\n sendSignatureComplete(data: SignatureCompleteData): void {\n this.post('casual.signature.complete', data, [data.bytes]);\n }\n\n /** Editor → Host: editor-side cancel of a signing session. */\n sendSignatureCancel(reason: SignatureCancelData['reason']): void {\n this.post('casual.signature.cancel', { reason });\n }\n\n /** Tear down listeners. Idempotent. */\n destroy(): void {\n if (this.destroyed) return;\n this.opts.hostWindow.removeEventListener('message', this.boundMessage as EventListener);\n this.pendingRequests.clear();\n this.destroyed = true;\n }\n\n // ---------------------------------------------------------------\n // Internals\n // ---------------------------------------------------------------\n\n private boundMessage(ev: Event): void {\n // MessageEvent isn't always available on the typing side when\n // a stub window is injected; cast pragmatically.\n const msg = ev as unknown as MessageEvent;\n if (msg.origin && msg.origin !== this.opts.hostOrigin) return;\n if (!isCasualEnvelope(msg.data)) return;\n void this.dispatch(msg.data as CasualEnvelope);\n }\n\n private async dispatch(env: CasualEnvelope): Promise<void> {\n // Responses to outbound requests route through the correlation map.\n if (env.id && this.pendingRequests.has(env.id)) {\n const resolve = this.pendingRequests.get(env.id)!;\n this.pendingRequests.delete(env.id);\n resolve(env);\n return;\n }\n\n switch (env.type) {\n case 'casual.hello':\n await this.handlers.onHostHello?.(env.data as HostHelloData);\n this.sendReady();\n return;\n case 'casual.command.setReadOnly':\n await this.handlers.onCommandSetReadOnly?.(env.data as CommandSetReadOnlyData);\n return;\n case 'casual.command.setTheme':\n await this.handlers.onCommandSetTheme?.(env.data as CommandSetThemeData);\n return;\n case 'casual.command.setLocale':\n await this.handlers.onCommandSetLocale?.(env.data as CommandSetLocaleData);\n return;\n case 'casual.command.focus':\n await this.handlers.onCommandFocus?.();\n return;\n case 'casual.command.save':\n await this.handlers.onCommandSave?.();\n return;\n case 'casual.command.load':\n await this.handlers.onCommandLoad?.();\n return;\n case 'casual.signature.request': {\n const ack = (await this.handlers.onSignatureRequest?.(\n env.data as SignatureRequestData,\n )) ?? {\n ok: false,\n code: 'unhandled',\n };\n if (env.id) {\n this.postReply(env.id, 'casual.signature.request.ack', ack);\n }\n return;\n }\n case 'casual.signature.cancel':\n await this.handlers.onSignatureCancel?.(env.data as SignatureCancelData);\n return;\n default:\n // Unknown envelope — silently drop per the forward-compat\n // convention in the protocol doc.\n return;\n }\n }\n\n private post(type: string, data: unknown, transfer?: Transferable[]): void {\n const env: CasualEnvelope = { type, app: this.opts.app, v: 1, data };\n try {\n this.opts.parentWindow.postMessage(env, this.opts.hostOrigin, transfer);\n } catch {\n // Cross-origin postMessage can throw if the parent went away;\n // silently swallow — the next user action will retry.\n }\n }\n\n private postReply(id: string, type: string, data: unknown): void {\n const env: CasualEnvelope = { type, app: this.opts.app, id, v: 1, data };\n try {\n this.opts.parentWindow.postMessage(env, this.opts.hostOrigin);\n } catch {\n // see post()\n }\n }\n\n private async request<T>(\n type: string,\n data: unknown,\n timeoutMs: number,\n transfer?: Transferable[],\n ): Promise<T> {\n const id = newRequestId();\n return new Promise<T>((resolve, reject) => {\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Embed request ${type} timed out after ${timeoutMs}ms`));\n }, timeoutMs)\n : null;\n this.pendingRequests.set(id, (env) => {\n if (timer) clearTimeout(timer);\n resolve(env.data as T);\n });\n const env: CasualEnvelope = { type, app: this.opts.app, id, v: 1, data };\n try {\n this.opts.parentWindow.postMessage(env, this.opts.hostOrigin, transfer);\n } catch (err) {\n if (timer) clearTimeout(timer);\n this.pendingRequests.delete(id);\n reject(err);\n }\n });\n }\n}\n\nfunction newRequestId(): string {\n // 8 hex chars is plenty — IDs only need to be unique within a\n // single editor session. Math.random is fine; the host can't\n // use these for security.\n return Math.random().toString(16).slice(2, 10);\n}\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_jsx_runtime","secondaryBtnStyle","primaryBtnStyle","env"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { CapturedSignature, DrawnSignaturePad, DrawnSignaturePadProps, SigningController, SigningPane, SigningPaneProps, SigningProvider, SigningProviderProps, SigningSnapshot, TypedSignatureField, TypedSignatureFieldProps, UploadedSignatureField, UploadedSignatureFieldProps, createSigningController, useSigning } from './signing.cjs';
|
|
2
|
+
export { C as CancelReason, D as DocAnchor, S as SheetAnchor, a as SignatureAnchor, b as SignatureCompletePayload, c as SignatureField, d as SignatureMethod, e as SignatureMode, f as SignedFieldPayload, g as SigningSessionConfig } from './types-s_O0u6Cg.cjs';
|
|
3
|
+
export { CasualApp, CasualEnvelope, CommandSetLocaleData, CommandSetReadOnlyData, CommandSetThemeData, EditorHelloData, EmbedTransport, EmbedTransportHandlers, EmbedTransportOptions, HostHelloData, LoadRequestData, LoadResponseData, LoadResponseDataErr, LoadResponseDataOk, LockLostData, SaveRequestData, SaveResponseData, SaveResponseDataErr, SaveResponseDataOk, SelectionChangedData, SignatureCancelData, SignatureCompleteData, SignatureFieldSignedData, SignatureRequestAckData, SignatureRequestData, TelemetryEventData, isCasualEnvelope } from './embed.cjs';
|
|
4
|
+
import 'react';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { CapturedSignature, DrawnSignaturePad, DrawnSignaturePadProps, SigningController, SigningPane, SigningPaneProps, SigningProvider, SigningProviderProps, SigningSnapshot, TypedSignatureField, TypedSignatureFieldProps, UploadedSignatureField, UploadedSignatureFieldProps, createSigningController, useSigning } from './signing.js';
|
|
2
|
+
export { C as CancelReason, D as DocAnchor, S as SheetAnchor, a as SignatureAnchor, b as SignatureCompletePayload, c as SignatureField, d as SignatureMethod, e as SignatureMode, f as SignedFieldPayload, g as SigningSessionConfig } from './types-s_O0u6Cg.js';
|
|
3
|
+
export { CasualApp, CasualEnvelope, CommandSetLocaleData, CommandSetReadOnlyData, CommandSetThemeData, EditorHelloData, EmbedTransport, EmbedTransportHandlers, EmbedTransportOptions, HostHelloData, LoadRequestData, LoadResponseData, LoadResponseDataErr, LoadResponseDataOk, LockLostData, SaveRequestData, SaveResponseData, SaveResponseDataErr, SaveResponseDataOk, SelectionChangedData, SignatureCancelData, SignatureCompleteData, SignatureFieldSignedData, SignatureRequestAckData, SignatureRequestData, TelemetryEventData, isCasualEnvelope } from './embed.js';
|
|
4
|
+
import 'react';
|