@kiryl.pekarski/payload-plugin-ab 1.2.0 → 1.2.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.
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/analytics/components/ABAnalyticsProvider.tsx
2
4
  import { createContext, useContext } from "react";
3
5
  import { jsx } from "react/jsx-runtime";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/analytics/components/ABAnalyticsProvider.tsx","../../src/analytics/components/ExperimentTracker.tsx","../../src/analytics/utils/getCookie.ts","../../src/analytics/constants.ts","../../src/analytics/hooks/useABConversion.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport { createContext, useContext } from \"react\";\r\nimport type { AnalyticsAdapter } from \"../types\";\r\n\r\nexport const ABAnalyticsContext = createContext<AnalyticsAdapter | null>(null);\r\n\r\nexport function useABAnalytics() {\r\n return useContext(ABAnalyticsContext);\r\n}\r\n\r\nexport function ABAnalyticsProvider({\r\n adapter,\r\n children,\r\n}: {\r\n adapter: AnalyticsAdapter;\r\n children: React.ReactNode;\r\n}): React.ReactNode {\r\n return <ABAnalyticsContext.Provider value={adapter}>{children}</ABAnalyticsContext.Provider>;\r\n}\r\n","\"use client\";\r\n\r\nimport { useEffect } from \"react\";\r\nimport { getCookie } from \"../utils/getCookie\";\r\nimport { useABAnalytics } from \"./ABAnalyticsProvider\";\r\nimport { DEFAULT_A_B_VISITOR_ID } from \"../constants\";\r\n\r\nexport interface ExperimentTrackerProps {\r\n experimentId: string;\r\n /**\r\n * Name of the cookie that holds the assigned variant bucket.\r\n * Default: `exp_${experimentId}`\r\n */\r\n variantCookieName?: string;\r\n /** Default: 'ab_visitor_id' */\r\n visitorCookieName?: string;\r\n}\r\n\r\nexport function ExperimentTracker({\r\n experimentId,\r\n variantCookieName,\r\n visitorCookieName = DEFAULT_A_B_VISITOR_ID,\r\n}: ExperimentTrackerProps) {\r\n const adapter = useABAnalytics();\r\n\r\n useEffect(() => {\r\n if (!adapter) return;\r\n\r\n const sessionKey = `ab_tracked_${experimentId}`;\r\n if (typeof sessionStorage !== \"undefined\" && sessionStorage.getItem(sessionKey)) {\r\n return;\r\n }\r\n\r\n const resolvedVariantCookie = variantCookieName ?? `exp_${experimentId}`;\r\n const variantBucket = getCookie(resolvedVariantCookie);\r\n const visitorId = getCookie(visitorCookieName);\r\n\r\n if (!variantBucket || !visitorId) return;\r\n\r\n adapter.trackImpression({ experimentId, variantBucket, visitorId });\r\n\r\n sessionStorage.setItem(sessionKey, \"1\");\r\n }, [adapter, experimentId, variantCookieName, visitorCookieName]);\r\n\r\n return null;\r\n}\r\n","export function getCookie(name: string) {\r\n if (typeof document === \"undefined\") return null;\r\n\r\n const escaped = name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n const match = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`));\r\n\r\n if (!match) return null;\r\n\r\n const value = match[1];\r\n\r\n return value != null ? decodeURIComponent(value) : null;\r\n}\r\n","export const DEFAULT_A_B_VISITOR_ID = \"ab_visitor_id\";\r\n","\"use client\";\r\n\r\nimport { useCallback } from \"react\";\r\nimport { useABAnalytics } from \"../components/ABAnalyticsProvider\";\r\nimport { getCookie } from \"../utils/getCookie\";\r\nimport { DEFAULT_A_B_VISITOR_ID } from \"../constants\";\r\n\r\nexport interface UseABConversionOptions {\r\n experimentId: string;\r\n variantCookieName?: string;\r\n visitorCookieName?: string;\r\n}\r\n\r\nexport type TrackConversionFn = (args: { goalId: string; goalValue?: number }) => void;\r\n\r\nexport function useABConversion({\r\n experimentId,\r\n variantCookieName,\r\n visitorCookieName = DEFAULT_A_B_VISITOR_ID,\r\n}: UseABConversionOptions): TrackConversionFn {\r\n const adapter = useABAnalytics();\r\n\r\n return useCallback(\r\n ({ goalId, goalValue }: { goalId: string; goalValue?: number }) => {\r\n if (!adapter) return;\r\n\r\n const cookieName = variantCookieName ?? `exp_${experimentId}`;\r\n const variantBucket = getCookie(cookieName);\r\n const visitorId = getCookie(visitorCookieName);\r\n\r\n if (!variantBucket || !visitorId) return;\r\n\r\n adapter.trackConversion({\r\n experimentId,\r\n variantBucket,\r\n visitorId,\r\n goalId,\r\n goalValue,\r\n });\r\n },\r\n [adapter, experimentId, variantCookieName, visitorCookieName],\r\n );\r\n}\r\n"],"mappings":";AAEA,SAAS,eAAe,kBAAkB;AAgBjC;AAbF,IAAM,qBAAqB,cAAuC,IAAI;AAEtE,SAAS,iBAAiB;AAC/B,SAAO,WAAW,kBAAkB;AACtC;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAGoB;AAClB,SAAO,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,SAAU,UAAS;AAChE;;;ACjBA,SAAS,iBAAiB;;;ACFnB,SAAS,UAAU,MAAc;AACtC,MAAI,OAAO,aAAa,YAAa,QAAO;AAE5C,QAAM,UAAU,KAAK,QAAQ,uBAAuB,MAAM;AAC1D,QAAM,QAAQ,SAAS,OAAO,MAAM,IAAI,OAAO,WAAW,OAAO,UAAU,CAAC;AAE5E,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,MAAM,CAAC;AAErB,SAAO,SAAS,OAAO,mBAAmB,KAAK,IAAI;AACrD;;;ACXO,IAAM,yBAAyB;;;AFkB/B,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,GAA2B;AACzB,QAAM,UAAU,eAAe;AAE/B,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,UAAM,aAAa,cAAc,YAAY;AAC7C,QAAI,OAAO,mBAAmB,eAAe,eAAe,QAAQ,UAAU,GAAG;AAC/E;AAAA,IACF;AAEA,UAAM,wBAAwB,qBAAqB,OAAO,YAAY;AACtE,UAAM,gBAAgB,UAAU,qBAAqB;AACrD,UAAM,YAAY,UAAU,iBAAiB;AAE7C,QAAI,CAAC,iBAAiB,CAAC,UAAW;AAElC,YAAQ,gBAAgB,EAAE,cAAc,eAAe,UAAU,CAAC;AAElE,mBAAe,QAAQ,YAAY,GAAG;AAAA,EACxC,GAAG,CAAC,SAAS,cAAc,mBAAmB,iBAAiB,CAAC;AAEhE,SAAO;AACT;;;AG3CA,SAAS,mBAAmB;AAarB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,GAA8C;AAC5C,QAAM,UAAU,eAAe;AAE/B,SAAO;AAAA,IACL,CAAC,EAAE,QAAQ,UAAU,MAA8C;AACjE,UAAI,CAAC,QAAS;AAEd,YAAM,aAAa,qBAAqB,OAAO,YAAY;AAC3D,YAAM,gBAAgB,UAAU,UAAU;AAC1C,YAAM,YAAY,UAAU,iBAAiB;AAE7C,UAAI,CAAC,iBAAiB,CAAC,UAAW;AAElC,cAAQ,gBAAgB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS,cAAc,mBAAmB,iBAAiB;AAAA,EAC9D;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/analytics/components/ABAnalyticsProvider.tsx","../../src/analytics/components/ExperimentTracker.tsx","../../src/analytics/utils/getCookie.ts","../../src/analytics/constants.ts","../../src/analytics/hooks/useABConversion.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport { createContext, useContext } from \"react\";\r\nimport type { AnalyticsAdapter } from \"../types\";\r\n\r\nexport const ABAnalyticsContext = createContext<AnalyticsAdapter | null>(null);\r\n\r\nexport function useABAnalytics() {\r\n return useContext(ABAnalyticsContext);\r\n}\r\n\r\nexport function ABAnalyticsProvider({\r\n adapter,\r\n children,\r\n}: {\r\n adapter: AnalyticsAdapter;\r\n children: React.ReactNode;\r\n}): React.ReactNode {\r\n return <ABAnalyticsContext.Provider value={adapter}>{children}</ABAnalyticsContext.Provider>;\r\n}\r\n","\"use client\";\r\n\r\nimport { useEffect } from \"react\";\r\nimport { getCookie } from \"../utils/getCookie\";\r\nimport { useABAnalytics } from \"./ABAnalyticsProvider\";\r\nimport { DEFAULT_A_B_VISITOR_ID } from \"../constants\";\r\n\r\nexport interface ExperimentTrackerProps {\r\n experimentId: string;\r\n /**\r\n * Name of the cookie that holds the assigned variant bucket.\r\n * Default: `exp_${experimentId}`\r\n */\r\n variantCookieName?: string;\r\n /** Default: 'ab_visitor_id' */\r\n visitorCookieName?: string;\r\n}\r\n\r\nexport function ExperimentTracker({\r\n experimentId,\r\n variantCookieName,\r\n visitorCookieName = DEFAULT_A_B_VISITOR_ID,\r\n}: ExperimentTrackerProps) {\r\n const adapter = useABAnalytics();\r\n\r\n useEffect(() => {\r\n if (!adapter) return;\r\n\r\n const sessionKey = `ab_tracked_${experimentId}`;\r\n if (typeof sessionStorage !== \"undefined\" && sessionStorage.getItem(sessionKey)) {\r\n return;\r\n }\r\n\r\n const resolvedVariantCookie = variantCookieName ?? `exp_${experimentId}`;\r\n const variantBucket = getCookie(resolvedVariantCookie);\r\n const visitorId = getCookie(visitorCookieName);\r\n\r\n if (!variantBucket || !visitorId) return;\r\n\r\n adapter.trackImpression({ experimentId, variantBucket, visitorId });\r\n\r\n sessionStorage.setItem(sessionKey, \"1\");\r\n }, [adapter, experimentId, variantCookieName, visitorCookieName]);\r\n\r\n return null;\r\n}\r\n","export function getCookie(name: string) {\r\n if (typeof document === \"undefined\") return null;\r\n\r\n const escaped = name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\r\n const match = document.cookie.match(new RegExp(`(?:^|; )${escaped}=([^;]*)`));\r\n\r\n if (!match) return null;\r\n\r\n const value = match[1];\r\n\r\n return value != null ? decodeURIComponent(value) : null;\r\n}\r\n","export const DEFAULT_A_B_VISITOR_ID = \"ab_visitor_id\";\r\n","\"use client\";\r\n\r\nimport { useCallback } from \"react\";\r\nimport { useABAnalytics } from \"../components/ABAnalyticsProvider\";\r\nimport { getCookie } from \"../utils/getCookie\";\r\nimport { DEFAULT_A_B_VISITOR_ID } from \"../constants\";\r\n\r\nexport interface UseABConversionOptions {\r\n experimentId: string;\r\n variantCookieName?: string;\r\n visitorCookieName?: string;\r\n}\r\n\r\nexport type TrackConversionFn = (args: { goalId: string; goalValue?: number }) => void;\r\n\r\nexport function useABConversion({\r\n experimentId,\r\n variantCookieName,\r\n visitorCookieName = DEFAULT_A_B_VISITOR_ID,\r\n}: UseABConversionOptions): TrackConversionFn {\r\n const adapter = useABAnalytics();\r\n\r\n return useCallback(\r\n ({ goalId, goalValue }: { goalId: string; goalValue?: number }) => {\r\n if (!adapter) return;\r\n\r\n const cookieName = variantCookieName ?? `exp_${experimentId}`;\r\n const variantBucket = getCookie(cookieName);\r\n const visitorId = getCookie(visitorCookieName);\r\n\r\n if (!variantBucket || !visitorId) return;\r\n\r\n adapter.trackConversion({\r\n experimentId,\r\n variantBucket,\r\n visitorId,\r\n goalId,\r\n goalValue,\r\n });\r\n },\r\n [adapter, experimentId, variantCookieName, visitorCookieName],\r\n );\r\n}\r\n"],"mappings":";;;AAEA,SAAS,eAAe,kBAAkB;AAgBjC;AAbF,IAAM,qBAAqB,cAAuC,IAAI;AAEtE,SAAS,iBAAiB;AAC/B,SAAO,WAAW,kBAAkB;AACtC;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAGoB;AAClB,SAAO,oBAAC,mBAAmB,UAAnB,EAA4B,OAAO,SAAU,UAAS;AAChE;;;ACjBA,SAAS,iBAAiB;;;ACFnB,SAAS,UAAU,MAAc;AACtC,MAAI,OAAO,aAAa,YAAa,QAAO;AAE5C,QAAM,UAAU,KAAK,QAAQ,uBAAuB,MAAM;AAC1D,QAAM,QAAQ,SAAS,OAAO,MAAM,IAAI,OAAO,WAAW,OAAO,UAAU,CAAC;AAE5E,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,MAAM,CAAC;AAErB,SAAO,SAAS,OAAO,mBAAmB,KAAK,IAAI;AACrD;;;ACXO,IAAM,yBAAyB;;;AFkB/B,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,GAA2B;AACzB,QAAM,UAAU,eAAe;AAE/B,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AAEd,UAAM,aAAa,cAAc,YAAY;AAC7C,QAAI,OAAO,mBAAmB,eAAe,eAAe,QAAQ,UAAU,GAAG;AAC/E;AAAA,IACF;AAEA,UAAM,wBAAwB,qBAAqB,OAAO,YAAY;AACtE,UAAM,gBAAgB,UAAU,qBAAqB;AACrD,UAAM,YAAY,UAAU,iBAAiB;AAE7C,QAAI,CAAC,iBAAiB,CAAC,UAAW;AAElC,YAAQ,gBAAgB,EAAE,cAAc,eAAe,UAAU,CAAC;AAElE,mBAAe,QAAQ,YAAY,GAAG;AAAA,EACxC,GAAG,CAAC,SAAS,cAAc,mBAAmB,iBAAiB,CAAC;AAEhE,SAAO;AACT;;;AG3CA,SAAS,mBAAmB;AAarB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA,oBAAoB;AACtB,GAA8C;AAC5C,QAAM,UAAU,eAAe;AAE/B,SAAO;AAAA,IACL,CAAC,EAAE,QAAQ,UAAU,MAA8C;AACjE,UAAI,CAAC,QAAS;AAEd,YAAM,aAAa,qBAAqB,OAAO,YAAY;AAC3D,YAAM,gBAAgB,UAAU,UAAU;AAC1C,YAAM,YAAY,UAAU,iBAAiB;AAE7C,UAAI,CAAC,iBAAiB,CAAC,UAAW;AAElC,cAAQ,gBAAgB;AAAA,QACtB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,SAAS,cAAc,mBAAmB,iBAAiB;AAAA,EAC9D;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiryl.pekarski/payload-plugin-ab",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "A/B testing plugin for Payload CMS",
5
5
  "keywords": [
6
6
  "payload-cms",