@sangwonl/pocato-react 0.7.0 → 0.7.1

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/dist/index.d.ts CHANGED
@@ -59,7 +59,10 @@ interface PocaCardHandle {
59
59
  flip(): void;
60
60
  wiggle(): void;
61
61
  reset(): void;
62
- exportImage(options: ExportImageOptions): Promise<Blob>;
62
+ exportImage(options: PocaCardExportImageOptions): Promise<Blob>;
63
+ }
64
+ interface PocaCardExportImageOptions extends ExportImageOptions {
65
+ includeContent?: boolean;
63
66
  }
64
67
  interface FaceProps {
65
68
  shader?: string;
@@ -147,4 +150,4 @@ interface UsePocatoConfigResult {
147
150
  }
148
151
  declare function usePocatoConfig(input: UsePocatoConfigInput): UsePocatoConfigResult;
149
152
 
150
- export { type FaceProps, PocaCard, type PocaCardConfig, type PocaCardFaceConfig, type PocaCardHandle, type PocaCardImagePreview, type PocaCardPreview, type PocaCardProps, type PublishedConfigResponse, type UsePocatoConfigInput, type UsePocatoConfigResult, usePocatoConfig };
153
+ export { type FaceProps, PocaCard, type PocaCardConfig, type PocaCardExportImageOptions, type PocaCardFaceConfig, type PocaCardHandle, type PocaCardImagePreview, type PocaCardPreview, type PocaCardProps, type PublishedConfigResponse, type UsePocatoConfigInput, type UsePocatoConfigResult, usePocatoConfig };
package/dist/index.js CHANGED
@@ -8,6 +8,74 @@ import {
8
8
  useState as useState2
9
9
  } from "react";
10
10
  import { createPortal } from "react-dom";
11
+
12
+ // src/export-image.ts
13
+ import html2canvas from "html2canvas";
14
+ var MIME_TYPES = {
15
+ png: "image/png",
16
+ webp: "image/webp",
17
+ jpeg: "image/jpeg"
18
+ };
19
+ async function captureFaceWithEffect(face, effect, options) {
20
+ await document.fonts?.ready;
21
+ await Promise.all(
22
+ Array.from(face.querySelectorAll("img"), (image) => image.decode?.().catch(() => void 0))
23
+ );
24
+ const bounds = face.getBoundingClientRect();
25
+ if (!bounds.width || !bounds.height) {
26
+ throw new Error("Failed to export Pocato image: card face has no size");
27
+ }
28
+ const effectDataUrl = await blobToDataUrl(effect);
29
+ const capturedFace = await html2canvas(face, {
30
+ backgroundColor: null,
31
+ foreignObjectRendering: true,
32
+ height: bounds.height,
33
+ logging: false,
34
+ scale: options.width / bounds.width,
35
+ useCORS: true,
36
+ width: bounds.width,
37
+ onclone: (_document, clonedFace) => {
38
+ const canvas = clonedFace.querySelector(".pocato-canvas");
39
+ if (!canvas) throw new Error("Failed to export Pocato image: effect canvas is missing");
40
+ const image = clonedFace.ownerDocument.createElement("img");
41
+ image.className = canvas.className;
42
+ image.style.cssText = canvas.style.cssText;
43
+ image.src = effectDataUrl;
44
+ image.alt = "";
45
+ image.setAttribute("aria-hidden", "true");
46
+ canvas.replaceWith(image);
47
+ }
48
+ });
49
+ const output = document.createElement("canvas");
50
+ output.width = options.width;
51
+ output.height = options.height;
52
+ const context = output.getContext("2d");
53
+ if (!context) throw new Error("Failed to export Pocato image: canvas context is unavailable");
54
+ context.drawImage(capturedFace, 0, 0, output.width, output.height);
55
+ const format = options.format ?? "png";
56
+ return canvasToBlob(output, MIME_TYPES[format], options.quality);
57
+ }
58
+ function blobToDataUrl(blob) {
59
+ return new Promise((resolve, reject) => {
60
+ const reader = new FileReader();
61
+ reader.onload = () => {
62
+ if (typeof reader.result === "string") resolve(reader.result);
63
+ else reject(new Error("Failed to export Pocato image: effect image could not be read"));
64
+ };
65
+ reader.onerror = () => reject(new Error("Failed to export Pocato image: effect image could not be read"));
66
+ reader.readAsDataURL(blob);
67
+ });
68
+ }
69
+ function canvasToBlob(canvas, type, quality) {
70
+ return new Promise((resolve, reject) => {
71
+ canvas.toBlob((blob) => {
72
+ if (blob) resolve(blob);
73
+ else reject(new Error("Failed to export Pocato image: image encoding failed"));
74
+ }, type, quality);
75
+ });
76
+ }
77
+
78
+ // src/PocaCard.tsx
11
79
  import {
12
80
  PocaCard as CorePocaCard
13
81
  } from "@sangwonl/pocato-core";
@@ -347,11 +415,20 @@ function PocaCardRenderer({
347
415
  flip: () => cardRef.current?.flip(),
348
416
  wiggle: () => cardRef.current?.wiggle(),
349
417
  reset: () => cardRef.current?.reset(),
350
- exportImage: (options) => {
351
- if (!cardRef.current) {
418
+ exportImage: async (options) => {
419
+ const card = cardRef.current;
420
+ if (!card) {
352
421
  return Promise.reject(new Error("Failed to export Pocato image: card is not mounted"));
353
422
  }
354
- return cardRef.current.exportImage(options);
423
+ const { includeContent = false, ...renderOptions } = options;
424
+ const effect = await card.exportImage(renderOptions);
425
+ if (!includeContent) return effect;
426
+ const content = renderOptions.face === "back" ? portalTargets.back : portalTargets.front;
427
+ const face = content?.parentElement;
428
+ if (!face) {
429
+ throw new Error("Failed to export Pocato image: card face is not mounted");
430
+ }
431
+ return captureFaceWithEffect(face, effect, renderOptions);
355
432
  }
356
433
  }));
357
434
  const preview = renderPreview(props.preview);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/PocaCard.tsx","../src/pocato-client.ts","../src/use-pocato-config.ts"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ForwardedRef,\n type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport {\n PocaCard as CorePocaCard,\n type EffectUniformValue,\n type ExportImageOptions,\n type FaceFrameOptions,\n type LayerSource,\n type PocaCardOptions,\n} from '@sangwonl/pocato-core'\nimport { trackCardEvent, type PocaCardConfig, type PocaCardEffectConfig } from './pocato-client'\nimport { usePocatoConfig } from './use-pocato-config'\n\nexport interface PocaCardHandle {\n flip(): void\n wiggle(): void\n reset(): void\n exportImage(options: ExportImageOptions): Promise<Blob>\n}\n\nexport interface FaceProps {\n shader?: string\n uniforms?: Record<string, EffectUniformValue>\n frame?: FaceFrameOptions\n layers: LayerSource[]\n content?: ReactNode\n}\n\nexport interface PocaCardImagePreview {\n interaction?: 'block' | 'pass-through'\n src?: string\n backgroundColor?: string\n mode?: 'cover' | 'contain'\n blur?: boolean\n render?: never\n}\n\nexport interface PocaCardCustomPreview {\n interaction?: 'block' | 'pass-through'\n render: ReactNode\n}\n\nexport type PocaCardPreview = PocaCardImagePreview | PocaCardCustomPreview\n\ninterface CommonPocaCardProps {\n flippable?: boolean\n initialFlipped?: boolean\n flipSpeed?: number\n interactive?: boolean\n touchAction?: PocaCardOptions['touchAction']\n preventNativeScroll?: PocaCardOptions['preventNativeScroll']\n interactionScrollMode?: PocaCardOptions['interactionScrollMode']\n stopPointerPropagation?: PocaCardOptions['stopPointerPropagation']\n preventPointerDefault?: PocaCardOptions['preventPointerDefault']\n maxTiltDegrees?: number\n onRotate?: (rotate: { x: number; y: number }) => void\n onFlip?: (flipped: boolean) => void\n onReady?: () => void\n onFirstFrame?: () => void\n onError?: (error: Error) => void\n preview?: PocaCardPreview\n error?: ReactNode | ((error: Error) => ReactNode)\n style?: CSSProperties\n className?: string\n}\n\ninterface DirectPocaCardProps extends CommonPocaCardProps {\n front: FaceProps\n back?: FaceProps\n config?: never\n cardId?: never\n publishableKey?: never\n releaseId?: never\n apiBaseUrl?: never\n}\n\ninterface ConfigPocaCardProps extends CommonPocaCardProps {\n config: PocaCardConfig\n front?: Partial<FaceProps>\n back?: Partial<FaceProps>\n cardId?: never\n publishableKey?: never\n releaseId?: never\n apiBaseUrl?: never\n}\n\ninterface ConnectedPocaCardProps extends CommonPocaCardProps {\n cardId: string\n publishableKey: string\n releaseId?: string | null\n apiBaseUrl?: string\n front?: Partial<FaceProps>\n back?: Partial<FaceProps>\n config?: never\n}\n\nexport type PocaCardProps = DirectPocaCardProps | ConfigPocaCardProps | ConnectedPocaCardProps\n\ninterface ResolvedPocaCardProps extends CommonPocaCardProps {\n front: FaceProps\n back?: FaceProps\n}\n\nfunction isConnectedProps(props: PocaCardProps): props is ConnectedPocaCardProps {\n return typeof props.cardId === 'string' && typeof props.publishableKey === 'string'\n}\n\nfunction isConfigProps(props: PocaCardProps): props is ConfigPocaCardProps {\n return 'config' in props && props.config != null\n}\n\nfunction resolveConfigProps(\n config: PocaCardConfig,\n props: ConfigPocaCardProps | ConnectedPocaCardProps,\n): ResolvedPocaCardProps {\n return {\n ...props,\n front: {\n ...config.front,\n shader: config.front.effect?.shader ?? config.front.shader,\n uniforms: config.front.uniforms ?? getEffectUniforms(config.front.effect),\n frame: props.front?.frame ?? config.front.frame,\n content: props.front?.content,\n },\n back: config.back\n ? {\n ...config.back,\n shader: config.back.effect?.shader ?? config.back.shader,\n uniforms: config.back.uniforms ?? getEffectUniforms(config.back.effect),\n frame: props.back?.frame ?? config.back.frame,\n content: props.back?.content,\n }\n : props.back?.layers\n ? props.back as FaceProps\n : undefined,\n flippable: props.flippable ?? config.flippable,\n initialFlipped: props.initialFlipped ?? config.initialFlipped,\n flipSpeed: props.flipSpeed ?? config.flipSpeed,\n preview: props.preview ?? config.preview,\n }\n}\n\nfunction getEffectUniforms(effect?: PocaCardEffectConfig) {\n if (!effect) return undefined\n return Object.fromEntries(\n effect.schema.map((item) => [\n item.uniform,\n effect.params[item.key] ?? item.defaultValue,\n ]),\n )\n}\n\nfunction renderError(errorView: CommonPocaCardProps['error'], error: Error) {\n if (typeof errorView === 'function') return errorView(error)\n return errorView ?? null\n}\n\nfunction renderPreview(preview?: PocaCardPreview) {\n if (!preview) return null\n if ('render' in preview && preview.render) return preview.render\n\n const imagePreview = preview as PocaCardImagePreview\n const backgroundColor = imagePreview.backgroundColor ?? '#f3f4f6'\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n borderRadius: '2%',\n background: backgroundColor,\n }}\n >\n {imagePreview.src ? (\n <img\n src={imagePreview.src}\n alt=\"\"\n draggable={false}\n style={{\n width: '100%',\n height: '100%',\n objectFit: imagePreview.mode ?? 'cover',\n filter: imagePreview.blur ? 'blur(12px)' : undefined,\n transform: imagePreview.blur ? 'scale(1.04)' : undefined,\n }}\n />\n ) : null}\n </div>\n )\n}\n\nfunction ConnectedPocaCard(\n props: ConnectedPocaCardProps,\n ref: ForwardedRef<PocaCardHandle>,\n) {\n const { config, loading, error } = usePocatoConfig({\n cardId: props.cardId,\n publishableKey: props.publishableKey,\n releaseId: props.releaseId,\n apiBaseUrl: props.apiBaseUrl,\n })\n const readyTracked = useRef(false)\n\n useEffect(() => {\n if (error && !props.error) {\n props.onError?.(error)\n }\n }, [error, props.error, props.onError])\n\n if (error) {\n return renderError(props.error, error)\n }\n\n if (loading || !config) {\n return renderPreview(props.preview)\n }\n\n const resolved = resolveConfigProps(config, {\n ...props,\n onFirstFrame: () => {\n if (!readyTracked.current) {\n readyTracked.current = true\n void trackCardEvent(props.cardId, {\n apiBaseUrl: props.apiBaseUrl,\n publishableKey: props.publishableKey,\n eventType: 'card_ready',\n })\n }\n props.onFirstFrame?.()\n },\n onError: (runtimeError) => {\n void trackCardEvent(props.cardId, {\n apiBaseUrl: props.apiBaseUrl,\n publishableKey: props.publishableKey,\n eventType: 'render_error',\n })\n props.onError?.(runtimeError)\n },\n })\n\n return <PocaCardRenderer props={resolved} refHandle={ref} />\n}\n\nfunction PocaCardRenderer({\n props,\n refHandle,\n}: {\n props: ResolvedPocaCardProps\n refHandle: ForwardedRef<PocaCardHandle>\n}) {\n const containerRef = useRef<HTMLDivElement>(null)\n const cardRef = useRef<CorePocaCard | null>(null)\n const [runtimeReady, setRuntimeReady] = useState(false)\n const [portalTargets, setPortalTargets] = useState<{\n front: HTMLElement | null\n back: HTMLElement | null\n }>({ front: null, back: null })\n const layersMounted = useRef(false)\n\n useLayoutEffect(() => {\n if (!containerRef.current) return\n\n layersMounted.current = false\n setRuntimeReady(false)\n const card = new CorePocaCard(containerRef.current, {\n front: { shader: props.front.shader, uniforms: props.front.uniforms, frame: props.front.frame, layers: props.front.layers },\n back: props.back ? { shader: props.back.shader, uniforms: props.back.uniforms, frame: props.back.frame, layers: props.back.layers } : undefined,\n flippable: props.flippable,\n initialFlipped: props.initialFlipped,\n flipSpeed: props.flipSpeed,\n interactive: props.interactive,\n touchAction: props.touchAction,\n preventNativeScroll: props.preventNativeScroll,\n interactionScrollMode: props.interactionScrollMode,\n stopPointerPropagation: props.stopPointerPropagation,\n preventPointerDefault: props.preventPointerDefault,\n maxTiltDegrees: props.maxTiltDegrees,\n onRotate: props.onRotate,\n })\n\n cardRef.current = card\n setPortalTargets({\n front: card.getFrontContentEl(),\n back: card.getBackContentEl(),\n })\n\n return () => {\n card.destroy()\n cardRef.current = null\n setPortalTargets({ front: null, back: null })\n }\n // Re-create when shader config changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.front.shader, props.back?.shader])\n\n const frontLayersKey = JSON.stringify(props.front.layers)\n const backLayersKey = JSON.stringify(props.back?.layers)\n useEffect(() => {\n if (!layersMounted.current) {\n layersMounted.current = true\n return\n }\n cardRef.current?.updateOptions({\n front: { layers: props.front.layers },\n back: props.back ? { layers: props.back.layers } : undefined,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frontLayersKey, backLayersKey])\n\n useEffect(() => {\n if (props.flipSpeed != null) {\n cardRef.current?.updateOptions({ flipSpeed: props.flipSpeed })\n }\n }, [props.flipSpeed])\n\n const frontUniformsKey = JSON.stringify(props.front.uniforms ?? {})\n const backUniformsKey = JSON.stringify(props.back?.uniforms ?? {})\n useEffect(() => {\n cardRef.current?.updateOptions({\n front: { uniforms: props.front.uniforms },\n back: props.back ? { uniforms: props.back.uniforms } : undefined,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frontUniformsKey, backUniformsKey])\n\n const frontFrameKey = JSON.stringify(props.front.frame ?? {})\n const backFrameKey = JSON.stringify(props.back?.frame ?? {})\n useEffect(() => {\n cardRef.current?.updateOptions({\n front: { frame: props.front.frame },\n back: props.back ? { frame: props.back.frame } : undefined,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frontFrameKey, backFrameKey])\n\n useEffect(() => {\n const card = cardRef.current\n if (!card) return\n\n const onFlip = props.onFlip\n const onReady = props.onReady\n const onFirstFrame = props.onFirstFrame\n const onError = props.onError\n const handleFirstFrame = () => {\n setRuntimeReady(true)\n onFirstFrame?.()\n }\n\n if (onFlip) card.on('flip', onFlip)\n if (onReady) card.on('ready', onReady)\n card.on('firstFrame', handleFirstFrame)\n if (onError) card.on('error', onError)\n\n return () => {\n if (onFlip) card.off('flip', onFlip)\n if (onReady) card.off('ready', onReady)\n card.off('firstFrame', handleFirstFrame)\n if (onError) card.off('error', onError)\n }\n }, [props.onFlip, props.onReady, props.onFirstFrame, props.onError])\n\n useImperativeHandle(refHandle, () => ({\n flip: () => cardRef.current?.flip(),\n wiggle: () => cardRef.current?.wiggle(),\n reset: () => cardRef.current?.reset(),\n exportImage: (options) => {\n if (!cardRef.current) {\n return Promise.reject(new Error('Failed to export Pocato image: card is not mounted'))\n }\n return cardRef.current.exportImage(options)\n },\n }))\n\n const preview = renderPreview(props.preview)\n const previewPointerEvents: CSSProperties['pointerEvents'] =\n props.preview?.interaction === 'pass-through' ? 'none' : undefined\n\n return (\n <div\n style={{\n ...props.style,\n position: props.style?.position ?? 'relative',\n }}\n className={props.className}\n >\n <div\n ref={containerRef}\n style={{\n position: 'absolute',\n inset: 0,\n }}\n />\n {!runtimeReady && preview ? (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n inset: 0,\n zIndex: 1,\n pointerEvents: previewPointerEvents,\n }}\n >\n {preview}\n </div>\n ) : null}\n {portalTargets.front && props.front.content && createPortal(props.front.content, portalTargets.front)}\n {portalTargets.back && props.back?.content && createPortal(props.back.content, portalTargets.back)}\n </div>\n )\n}\n\nexport const PocaCard = forwardRef<PocaCardHandle, PocaCardProps>(\n (props, ref) => {\n if (isConnectedProps(props)) {\n return ConnectedPocaCard(props, ref)\n }\n\n const resolved = isConfigProps(props) ? resolveConfigProps(props.config, props) : props\n return <PocaCardRenderer props={resolved} refHandle={ref} />\n },\n)\n\nPocaCard.displayName = 'PocaCard'\n","import type { FaceProps, PocaCardImagePreview } from './PocaCard'\n\nconst DEFAULT_API_BASE_URL = 'https://pocato-api.gamzabaw.workers.dev'\n\nexport type EffectParamValue = string | number | boolean\n\nexport interface EffectParamSchema {\n key: string\n label: string\n uniform: string\n type: 'number' | 'boolean' | 'color' | 'select'\n defaultValue: EffectParamValue\n min?: number\n max?: number\n step?: number\n options?: Array<{ label: string; value: EffectParamValue }>\n}\n\nexport interface PocaCardEffectConfig {\n id: string\n label: string\n shader: string\n minLayers: number\n params: Record<string, EffectParamValue>\n schema: EffectParamSchema[]\n customizedShader?: boolean\n}\n\nexport interface PocaCardFaceConfig extends Omit<FaceProps, 'content'> {\n effect?: PocaCardEffectConfig\n html?: string\n}\n\nexport interface PocaCardConfig {\n preview?: PocaCardImagePreview\n cardSize?: {\n width: number\n height: number\n preset?: string\n }\n front: PocaCardFaceConfig\n back?: PocaCardFaceConfig\n flippable?: boolean\n initialFlipped?: boolean\n flipSpeed?: number\n}\n\nexport interface PublishedConfigResponse {\n cardId: string\n releaseId: string\n config: PocaCardConfig\n}\n\nexport interface PocatoClientOptions {\n apiBaseUrl?: string\n publishableKey: string\n releaseId?: string | null\n}\n\nfunction getApiBaseUrl(apiBaseUrl?: string): string {\n return apiBaseUrl ?? DEFAULT_API_BASE_URL\n}\n\nexport async function fetchPublishedConfig(\n cardId: string,\n options: PocatoClientOptions,\n): Promise<PublishedConfigResponse> {\n const baseUrl = getApiBaseUrl(options.apiBaseUrl)\n const url = new URL(`${baseUrl}/api/v1/public/cards/${cardId}/config`)\n if (options.releaseId) url.searchParams.set('release', options.releaseId)\n const res = await fetch(url.toString(), {\n headers: {\n 'X-Pocato-Key': options.publishableKey,\n },\n })\n\n if (!res.ok) {\n throw new Error(`Failed to load Pocato card config: ${res.status}`)\n }\n\n return res.json()\n}\n\nexport async function trackCardEvent(\n cardId: string,\n options: PocatoClientOptions & { eventType: 'card_ready' | 'render_error' },\n): Promise<void> {\n const baseUrl = getApiBaseUrl(options.apiBaseUrl)\n await fetch(`${baseUrl}/api/v1/public/cards/${cardId}/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Pocato-Key': options.publishableKey,\n },\n body: JSON.stringify({ eventType: options.eventType }),\n keepalive: true,\n }).catch(() => {\n // Usage metering must not break customer rendering.\n })\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n fetchPublishedConfig,\n type PocatoClientOptions,\n type PocaCardConfig,\n type PublishedConfigResponse,\n} from './pocato-client'\n\nconst cache = new Map<string, PublishedConfigResponse>()\n\nexport function getPocatoConfigCacheKey(\n apiBaseUrl: string | undefined,\n publishableKey: string,\n cardId: string,\n releaseId?: string | null,\n): string {\n return `${apiBaseUrl ?? ''}:${publishableKey}:${cardId}:${releaseId ?? ''}`\n}\n\nexport interface UsePocatoConfigInput extends PocatoClientOptions {\n cardId: string\n}\n\nexport interface UsePocatoConfigResult {\n data: PublishedConfigResponse | null\n config: PocaCardConfig | null\n loading: boolean\n error: Error | null\n refetch: () => Promise<PublishedConfigResponse | null>\n}\n\nexport function usePocatoConfig(input: UsePocatoConfigInput): UsePocatoConfigResult {\n const cacheKey = useMemo(() => {\n return getPocatoConfigCacheKey(input.apiBaseUrl, input.publishableKey, input.cardId, input.releaseId)\n }, [input.apiBaseUrl, input.publishableKey, input.cardId, input.releaseId])\n\n const [data, setData] = useState<PublishedConfigResponse | null>(() => {\n return cache.get(cacheKey) ?? null\n })\n const [loading, setLoading] = useState(!data)\n const [error, setError] = useState<Error | null>(null)\n\n const load = useCallback(async (options?: { force?: boolean }) => {\n if (!options?.force) {\n const cached = cache.get(cacheKey)\n if (cached) {\n setData(cached)\n setLoading(false)\n setError(null)\n return cached\n }\n }\n\n setData(null)\n setLoading(true)\n setError(null)\n\n try {\n const response = await fetchPublishedConfig(input.cardId, {\n apiBaseUrl: input.apiBaseUrl,\n publishableKey: input.publishableKey,\n releaseId: input.releaseId,\n })\n cache.set(cacheKey, response)\n setData(response)\n setLoading(false)\n return response\n } catch (err) {\n const nextError = err instanceof Error ? err : new Error('Failed to load Pocato config')\n setError(nextError)\n setLoading(false)\n return null\n }\n }, [cacheKey, input.apiBaseUrl, input.cardId, input.publishableKey, input.releaseId])\n\n useEffect(() => {\n let cancelled = false\n const cached = cache.get(cacheKey)\n\n if (cached) {\n setData(cached)\n setLoading(false)\n setError(null)\n return\n }\n\n setData(null)\n setLoading(true)\n setError(null)\n\n fetchPublishedConfig(input.cardId, {\n apiBaseUrl: input.apiBaseUrl,\n publishableKey: input.publishableKey,\n releaseId: input.releaseId,\n })\n .then((response) => {\n if (cancelled) return\n cache.set(cacheKey, response)\n setData(response)\n setLoading(false)\n })\n .catch((err) => {\n if (cancelled) return\n setError(err instanceof Error ? err : new Error('Failed to load Pocato config'))\n setLoading(false)\n })\n\n return () => {\n cancelled = true\n }\n }, [cacheKey, input.apiBaseUrl, input.publishableKey, input.cardId, input.releaseId])\n\n return {\n data,\n config: data?.config ?? null,\n loading,\n error,\n refetch: () => load({ force: true }),\n }\n}\n"],"mappings":"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","names":["useEffect","useState","useEffect","useState"]}
1
+ {"version":3,"sources":["../src/PocaCard.tsx","../src/export-image.ts","../src/pocato-client.ts","../src/use-pocato-config.ts"],"sourcesContent":["import {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ForwardedRef,\n type ReactNode,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { captureFaceWithEffect } from './export-image'\nimport {\n PocaCard as CorePocaCard,\n type EffectUniformValue,\n type ExportImageOptions,\n type FaceFrameOptions,\n type LayerSource,\n type PocaCardOptions,\n} from '@sangwonl/pocato-core'\nimport { trackCardEvent, type PocaCardConfig, type PocaCardEffectConfig } from './pocato-client'\nimport { usePocatoConfig } from './use-pocato-config'\n\nexport interface PocaCardHandle {\n flip(): void\n wiggle(): void\n reset(): void\n exportImage(options: PocaCardExportImageOptions): Promise<Blob>\n}\n\nexport interface PocaCardExportImageOptions extends ExportImageOptions {\n includeContent?: boolean\n}\n\nexport interface FaceProps {\n shader?: string\n uniforms?: Record<string, EffectUniformValue>\n frame?: FaceFrameOptions\n layers: LayerSource[]\n content?: ReactNode\n}\n\nexport interface PocaCardImagePreview {\n interaction?: 'block' | 'pass-through'\n src?: string\n backgroundColor?: string\n mode?: 'cover' | 'contain'\n blur?: boolean\n render?: never\n}\n\nexport interface PocaCardCustomPreview {\n interaction?: 'block' | 'pass-through'\n render: ReactNode\n}\n\nexport type PocaCardPreview = PocaCardImagePreview | PocaCardCustomPreview\n\ninterface CommonPocaCardProps {\n flippable?: boolean\n initialFlipped?: boolean\n flipSpeed?: number\n interactive?: boolean\n touchAction?: PocaCardOptions['touchAction']\n preventNativeScroll?: PocaCardOptions['preventNativeScroll']\n interactionScrollMode?: PocaCardOptions['interactionScrollMode']\n stopPointerPropagation?: PocaCardOptions['stopPointerPropagation']\n preventPointerDefault?: PocaCardOptions['preventPointerDefault']\n maxTiltDegrees?: number\n onRotate?: (rotate: { x: number; y: number }) => void\n onFlip?: (flipped: boolean) => void\n onReady?: () => void\n onFirstFrame?: () => void\n onError?: (error: Error) => void\n preview?: PocaCardPreview\n error?: ReactNode | ((error: Error) => ReactNode)\n style?: CSSProperties\n className?: string\n}\n\ninterface DirectPocaCardProps extends CommonPocaCardProps {\n front: FaceProps\n back?: FaceProps\n config?: never\n cardId?: never\n publishableKey?: never\n releaseId?: never\n apiBaseUrl?: never\n}\n\ninterface ConfigPocaCardProps extends CommonPocaCardProps {\n config: PocaCardConfig\n front?: Partial<FaceProps>\n back?: Partial<FaceProps>\n cardId?: never\n publishableKey?: never\n releaseId?: never\n apiBaseUrl?: never\n}\n\ninterface ConnectedPocaCardProps extends CommonPocaCardProps {\n cardId: string\n publishableKey: string\n releaseId?: string | null\n apiBaseUrl?: string\n front?: Partial<FaceProps>\n back?: Partial<FaceProps>\n config?: never\n}\n\nexport type PocaCardProps = DirectPocaCardProps | ConfigPocaCardProps | ConnectedPocaCardProps\n\ninterface ResolvedPocaCardProps extends CommonPocaCardProps {\n front: FaceProps\n back?: FaceProps\n}\n\nfunction isConnectedProps(props: PocaCardProps): props is ConnectedPocaCardProps {\n return typeof props.cardId === 'string' && typeof props.publishableKey === 'string'\n}\n\nfunction isConfigProps(props: PocaCardProps): props is ConfigPocaCardProps {\n return 'config' in props && props.config != null\n}\n\nfunction resolveConfigProps(\n config: PocaCardConfig,\n props: ConfigPocaCardProps | ConnectedPocaCardProps,\n): ResolvedPocaCardProps {\n return {\n ...props,\n front: {\n ...config.front,\n shader: config.front.effect?.shader ?? config.front.shader,\n uniforms: config.front.uniforms ?? getEffectUniforms(config.front.effect),\n frame: props.front?.frame ?? config.front.frame,\n content: props.front?.content,\n },\n back: config.back\n ? {\n ...config.back,\n shader: config.back.effect?.shader ?? config.back.shader,\n uniforms: config.back.uniforms ?? getEffectUniforms(config.back.effect),\n frame: props.back?.frame ?? config.back.frame,\n content: props.back?.content,\n }\n : props.back?.layers\n ? props.back as FaceProps\n : undefined,\n flippable: props.flippable ?? config.flippable,\n initialFlipped: props.initialFlipped ?? config.initialFlipped,\n flipSpeed: props.flipSpeed ?? config.flipSpeed,\n preview: props.preview ?? config.preview,\n }\n}\n\nfunction getEffectUniforms(effect?: PocaCardEffectConfig) {\n if (!effect) return undefined\n return Object.fromEntries(\n effect.schema.map((item) => [\n item.uniform,\n effect.params[item.key] ?? item.defaultValue,\n ]),\n )\n}\n\nfunction renderError(errorView: CommonPocaCardProps['error'], error: Error) {\n if (typeof errorView === 'function') return errorView(error)\n return errorView ?? null\n}\n\nfunction renderPreview(preview?: PocaCardPreview) {\n if (!preview) return null\n if ('render' in preview && preview.render) return preview.render\n\n const imagePreview = preview as PocaCardImagePreview\n const backgroundColor = imagePreview.backgroundColor ?? '#f3f4f6'\n return (\n <div\n style={{\n width: '100%',\n height: '100%',\n overflow: 'hidden',\n borderRadius: '2%',\n background: backgroundColor,\n }}\n >\n {imagePreview.src ? (\n <img\n src={imagePreview.src}\n alt=\"\"\n draggable={false}\n style={{\n width: '100%',\n height: '100%',\n objectFit: imagePreview.mode ?? 'cover',\n filter: imagePreview.blur ? 'blur(12px)' : undefined,\n transform: imagePreview.blur ? 'scale(1.04)' : undefined,\n }}\n />\n ) : null}\n </div>\n )\n}\n\nfunction ConnectedPocaCard(\n props: ConnectedPocaCardProps,\n ref: ForwardedRef<PocaCardHandle>,\n) {\n const { config, loading, error } = usePocatoConfig({\n cardId: props.cardId,\n publishableKey: props.publishableKey,\n releaseId: props.releaseId,\n apiBaseUrl: props.apiBaseUrl,\n })\n const readyTracked = useRef(false)\n\n useEffect(() => {\n if (error && !props.error) {\n props.onError?.(error)\n }\n }, [error, props.error, props.onError])\n\n if (error) {\n return renderError(props.error, error)\n }\n\n if (loading || !config) {\n return renderPreview(props.preview)\n }\n\n const resolved = resolveConfigProps(config, {\n ...props,\n onFirstFrame: () => {\n if (!readyTracked.current) {\n readyTracked.current = true\n void trackCardEvent(props.cardId, {\n apiBaseUrl: props.apiBaseUrl,\n publishableKey: props.publishableKey,\n eventType: 'card_ready',\n })\n }\n props.onFirstFrame?.()\n },\n onError: (runtimeError) => {\n void trackCardEvent(props.cardId, {\n apiBaseUrl: props.apiBaseUrl,\n publishableKey: props.publishableKey,\n eventType: 'render_error',\n })\n props.onError?.(runtimeError)\n },\n })\n\n return <PocaCardRenderer props={resolved} refHandle={ref} />\n}\n\nfunction PocaCardRenderer({\n props,\n refHandle,\n}: {\n props: ResolvedPocaCardProps\n refHandle: ForwardedRef<PocaCardHandle>\n}) {\n const containerRef = useRef<HTMLDivElement>(null)\n const cardRef = useRef<CorePocaCard | null>(null)\n const [runtimeReady, setRuntimeReady] = useState(false)\n const [portalTargets, setPortalTargets] = useState<{\n front: HTMLElement | null\n back: HTMLElement | null\n }>({ front: null, back: null })\n const layersMounted = useRef(false)\n\n useLayoutEffect(() => {\n if (!containerRef.current) return\n\n layersMounted.current = false\n setRuntimeReady(false)\n const card = new CorePocaCard(containerRef.current, {\n front: { shader: props.front.shader, uniforms: props.front.uniforms, frame: props.front.frame, layers: props.front.layers },\n back: props.back ? { shader: props.back.shader, uniforms: props.back.uniforms, frame: props.back.frame, layers: props.back.layers } : undefined,\n flippable: props.flippable,\n initialFlipped: props.initialFlipped,\n flipSpeed: props.flipSpeed,\n interactive: props.interactive,\n touchAction: props.touchAction,\n preventNativeScroll: props.preventNativeScroll,\n interactionScrollMode: props.interactionScrollMode,\n stopPointerPropagation: props.stopPointerPropagation,\n preventPointerDefault: props.preventPointerDefault,\n maxTiltDegrees: props.maxTiltDegrees,\n onRotate: props.onRotate,\n })\n\n cardRef.current = card\n setPortalTargets({\n front: card.getFrontContentEl(),\n back: card.getBackContentEl(),\n })\n\n return () => {\n card.destroy()\n cardRef.current = null\n setPortalTargets({ front: null, back: null })\n }\n // Re-create when shader config changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.front.shader, props.back?.shader])\n\n const frontLayersKey = JSON.stringify(props.front.layers)\n const backLayersKey = JSON.stringify(props.back?.layers)\n useEffect(() => {\n if (!layersMounted.current) {\n layersMounted.current = true\n return\n }\n cardRef.current?.updateOptions({\n front: { layers: props.front.layers },\n back: props.back ? { layers: props.back.layers } : undefined,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frontLayersKey, backLayersKey])\n\n useEffect(() => {\n if (props.flipSpeed != null) {\n cardRef.current?.updateOptions({ flipSpeed: props.flipSpeed })\n }\n }, [props.flipSpeed])\n\n const frontUniformsKey = JSON.stringify(props.front.uniforms ?? {})\n const backUniformsKey = JSON.stringify(props.back?.uniforms ?? {})\n useEffect(() => {\n cardRef.current?.updateOptions({\n front: { uniforms: props.front.uniforms },\n back: props.back ? { uniforms: props.back.uniforms } : undefined,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frontUniformsKey, backUniformsKey])\n\n const frontFrameKey = JSON.stringify(props.front.frame ?? {})\n const backFrameKey = JSON.stringify(props.back?.frame ?? {})\n useEffect(() => {\n cardRef.current?.updateOptions({\n front: { frame: props.front.frame },\n back: props.back ? { frame: props.back.frame } : undefined,\n })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [frontFrameKey, backFrameKey])\n\n useEffect(() => {\n const card = cardRef.current\n if (!card) return\n\n const onFlip = props.onFlip\n const onReady = props.onReady\n const onFirstFrame = props.onFirstFrame\n const onError = props.onError\n const handleFirstFrame = () => {\n setRuntimeReady(true)\n onFirstFrame?.()\n }\n\n if (onFlip) card.on('flip', onFlip)\n if (onReady) card.on('ready', onReady)\n card.on('firstFrame', handleFirstFrame)\n if (onError) card.on('error', onError)\n\n return () => {\n if (onFlip) card.off('flip', onFlip)\n if (onReady) card.off('ready', onReady)\n card.off('firstFrame', handleFirstFrame)\n if (onError) card.off('error', onError)\n }\n }, [props.onFlip, props.onReady, props.onFirstFrame, props.onError])\n\n useImperativeHandle(refHandle, () => ({\n flip: () => cardRef.current?.flip(),\n wiggle: () => cardRef.current?.wiggle(),\n reset: () => cardRef.current?.reset(),\n exportImage: async (options) => {\n const card = cardRef.current\n if (!card) {\n return Promise.reject(new Error('Failed to export Pocato image: card is not mounted'))\n }\n\n const { includeContent = false, ...renderOptions } = options\n const effect = await card.exportImage(renderOptions)\n if (!includeContent) return effect\n\n const content = renderOptions.face === 'back' ? portalTargets.back : portalTargets.front\n const face = content?.parentElement\n if (!face) {\n throw new Error('Failed to export Pocato image: card face is not mounted')\n }\n\n return captureFaceWithEffect(face, effect, renderOptions)\n },\n }))\n\n const preview = renderPreview(props.preview)\n const previewPointerEvents: CSSProperties['pointerEvents'] =\n props.preview?.interaction === 'pass-through' ? 'none' : undefined\n\n return (\n <div\n style={{\n ...props.style,\n position: props.style?.position ?? 'relative',\n }}\n className={props.className}\n >\n <div\n ref={containerRef}\n style={{\n position: 'absolute',\n inset: 0,\n }}\n />\n {!runtimeReady && preview ? (\n <div\n aria-hidden=\"true\"\n style={{\n position: 'absolute',\n inset: 0,\n zIndex: 1,\n pointerEvents: previewPointerEvents,\n }}\n >\n {preview}\n </div>\n ) : null}\n {portalTargets.front && props.front.content && createPortal(props.front.content, portalTargets.front)}\n {portalTargets.back && props.back?.content && createPortal(props.back.content, portalTargets.back)}\n </div>\n )\n}\n\nexport const PocaCard = forwardRef<PocaCardHandle, PocaCardProps>(\n (props, ref) => {\n if (isConnectedProps(props)) {\n return ConnectedPocaCard(props, ref)\n }\n\n const resolved = isConfigProps(props) ? resolveConfigProps(props.config, props) : props\n return <PocaCardRenderer props={resolved} refHandle={ref} />\n },\n)\n\nPocaCard.displayName = 'PocaCard'\n","import html2canvas from 'html2canvas'\nimport type { ExportImageOptions } from '@sangwonl/pocato-core'\n\nconst MIME_TYPES: Record<NonNullable<ExportImageOptions['format']>, string> = {\n png: 'image/png',\n webp: 'image/webp',\n jpeg: 'image/jpeg',\n}\n\nexport async function captureFaceWithEffect(\n face: HTMLElement,\n effect: Blob,\n options: ExportImageOptions,\n): Promise<Blob> {\n await document.fonts?.ready\n await Promise.all(\n Array.from(face.querySelectorAll('img'), (image) => image.decode?.().catch(() => undefined)),\n )\n\n const bounds = face.getBoundingClientRect()\n if (!bounds.width || !bounds.height) {\n throw new Error('Failed to export Pocato image: card face has no size')\n }\n\n const effectDataUrl = await blobToDataUrl(effect)\n const capturedFace = await html2canvas(face, {\n backgroundColor: null,\n foreignObjectRendering: true,\n height: bounds.height,\n logging: false,\n scale: options.width / bounds.width,\n useCORS: true,\n width: bounds.width,\n onclone: (_document, clonedFace) => {\n const canvas = clonedFace.querySelector<HTMLCanvasElement>('.pocato-canvas')\n if (!canvas) throw new Error('Failed to export Pocato image: effect canvas is missing')\n\n const image = clonedFace.ownerDocument.createElement('img')\n image.className = canvas.className\n image.style.cssText = canvas.style.cssText\n image.src = effectDataUrl\n image.alt = ''\n image.setAttribute('aria-hidden', 'true')\n canvas.replaceWith(image)\n },\n })\n\n const output = document.createElement('canvas')\n output.width = options.width\n output.height = options.height\n const context = output.getContext('2d')\n if (!context) throw new Error('Failed to export Pocato image: canvas context is unavailable')\n context.drawImage(capturedFace, 0, 0, output.width, output.height)\n\n const format = options.format ?? 'png'\n return canvasToBlob(output, MIME_TYPES[format], options.quality)\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result === 'string') resolve(reader.result)\n else reject(new Error('Failed to export Pocato image: effect image could not be read'))\n }\n reader.onerror = () => reject(new Error('Failed to export Pocato image: effect image could not be read'))\n reader.readAsDataURL(blob)\n })\n}\n\nfunction canvasToBlob(canvas: HTMLCanvasElement, type: string, quality?: number): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob((blob) => {\n if (blob) resolve(blob)\n else reject(new Error('Failed to export Pocato image: image encoding failed'))\n }, type, quality)\n })\n}\n","import type { FaceProps, PocaCardImagePreview } from './PocaCard'\n\nconst DEFAULT_API_BASE_URL = 'https://pocato-api.gamzabaw.workers.dev'\n\nexport type EffectParamValue = string | number | boolean\n\nexport interface EffectParamSchema {\n key: string\n label: string\n uniform: string\n type: 'number' | 'boolean' | 'color' | 'select'\n defaultValue: EffectParamValue\n min?: number\n max?: number\n step?: number\n options?: Array<{ label: string; value: EffectParamValue }>\n}\n\nexport interface PocaCardEffectConfig {\n id: string\n label: string\n shader: string\n minLayers: number\n params: Record<string, EffectParamValue>\n schema: EffectParamSchema[]\n customizedShader?: boolean\n}\n\nexport interface PocaCardFaceConfig extends Omit<FaceProps, 'content'> {\n effect?: PocaCardEffectConfig\n html?: string\n}\n\nexport interface PocaCardConfig {\n preview?: PocaCardImagePreview\n cardSize?: {\n width: number\n height: number\n preset?: string\n }\n front: PocaCardFaceConfig\n back?: PocaCardFaceConfig\n flippable?: boolean\n initialFlipped?: boolean\n flipSpeed?: number\n}\n\nexport interface PublishedConfigResponse {\n cardId: string\n releaseId: string\n config: PocaCardConfig\n}\n\nexport interface PocatoClientOptions {\n apiBaseUrl?: string\n publishableKey: string\n releaseId?: string | null\n}\n\nfunction getApiBaseUrl(apiBaseUrl?: string): string {\n return apiBaseUrl ?? DEFAULT_API_BASE_URL\n}\n\nexport async function fetchPublishedConfig(\n cardId: string,\n options: PocatoClientOptions,\n): Promise<PublishedConfigResponse> {\n const baseUrl = getApiBaseUrl(options.apiBaseUrl)\n const url = new URL(`${baseUrl}/api/v1/public/cards/${cardId}/config`)\n if (options.releaseId) url.searchParams.set('release', options.releaseId)\n const res = await fetch(url.toString(), {\n headers: {\n 'X-Pocato-Key': options.publishableKey,\n },\n })\n\n if (!res.ok) {\n throw new Error(`Failed to load Pocato card config: ${res.status}`)\n }\n\n return res.json()\n}\n\nexport async function trackCardEvent(\n cardId: string,\n options: PocatoClientOptions & { eventType: 'card_ready' | 'render_error' },\n): Promise<void> {\n const baseUrl = getApiBaseUrl(options.apiBaseUrl)\n await fetch(`${baseUrl}/api/v1/public/cards/${cardId}/events`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Pocato-Key': options.publishableKey,\n },\n body: JSON.stringify({ eventType: options.eventType }),\n keepalive: true,\n }).catch(() => {\n // Usage metering must not break customer rendering.\n })\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react'\nimport {\n fetchPublishedConfig,\n type PocatoClientOptions,\n type PocaCardConfig,\n type PublishedConfigResponse,\n} from './pocato-client'\n\nconst cache = new Map<string, PublishedConfigResponse>()\n\nexport function getPocatoConfigCacheKey(\n apiBaseUrl: string | undefined,\n publishableKey: string,\n cardId: string,\n releaseId?: string | null,\n): string {\n return `${apiBaseUrl ?? ''}:${publishableKey}:${cardId}:${releaseId ?? ''}`\n}\n\nexport interface UsePocatoConfigInput extends PocatoClientOptions {\n cardId: string\n}\n\nexport interface UsePocatoConfigResult {\n data: PublishedConfigResponse | null\n config: PocaCardConfig | null\n loading: boolean\n error: Error | null\n refetch: () => Promise<PublishedConfigResponse | null>\n}\n\nexport function usePocatoConfig(input: UsePocatoConfigInput): UsePocatoConfigResult {\n const cacheKey = useMemo(() => {\n return getPocatoConfigCacheKey(input.apiBaseUrl, input.publishableKey, input.cardId, input.releaseId)\n }, [input.apiBaseUrl, input.publishableKey, input.cardId, input.releaseId])\n\n const [data, setData] = useState<PublishedConfigResponse | null>(() => {\n return cache.get(cacheKey) ?? null\n })\n const [loading, setLoading] = useState(!data)\n const [error, setError] = useState<Error | null>(null)\n\n const load = useCallback(async (options?: { force?: boolean }) => {\n if (!options?.force) {\n const cached = cache.get(cacheKey)\n if (cached) {\n setData(cached)\n setLoading(false)\n setError(null)\n return cached\n }\n }\n\n setData(null)\n setLoading(true)\n setError(null)\n\n try {\n const response = await fetchPublishedConfig(input.cardId, {\n apiBaseUrl: input.apiBaseUrl,\n publishableKey: input.publishableKey,\n releaseId: input.releaseId,\n })\n cache.set(cacheKey, response)\n setData(response)\n setLoading(false)\n return response\n } catch (err) {\n const nextError = err instanceof Error ? err : new Error('Failed to load Pocato config')\n setError(nextError)\n setLoading(false)\n return null\n }\n }, [cacheKey, input.apiBaseUrl, input.cardId, input.publishableKey, input.releaseId])\n\n useEffect(() => {\n let cancelled = false\n const cached = cache.get(cacheKey)\n\n if (cached) {\n setData(cached)\n setLoading(false)\n setError(null)\n return\n }\n\n setData(null)\n setLoading(true)\n setError(null)\n\n fetchPublishedConfig(input.cardId, {\n apiBaseUrl: input.apiBaseUrl,\n publishableKey: input.publishableKey,\n releaseId: input.releaseId,\n })\n .then((response) => {\n if (cancelled) return\n cache.set(cacheKey, response)\n setData(response)\n setLoading(false)\n })\n .catch((err) => {\n if (cancelled) return\n setError(err instanceof Error ? err : new Error('Failed to load Pocato config'))\n setLoading(false)\n })\n\n return () => {\n cancelled = true\n }\n }, [cacheKey, input.apiBaseUrl, input.publishableKey, input.cardId, input.releaseId])\n\n return {\n data,\n config: data?.config ?? null,\n loading,\n error,\n refetch: () => load({ force: true }),\n }\n}\n"],"mappings":"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","names":["useEffect","useState","useEffect","useState"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sangwonl/pocato-react",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "author": "Sangwon Lee <gamzabaw@gmail.com>",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -27,7 +27,8 @@
27
27
  "dev": "tsup --watch"
28
28
  },
29
29
  "dependencies": {
30
- "@sangwonl/pocato-core": "0.7.0"
30
+ "@sangwonl/pocato-core": "0.7.1",
31
+ "html2canvas": "^1.4.1"
31
32
  },
32
33
  "peerDependencies": {
33
34
  "react": "^18.0.0 || ^19.0.0",