autotel-subscribers 10.0.0 → 11.0.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/dist/index.cjs CHANGED
@@ -15425,6 +15425,35 @@ var EventSubscriber = class {
15425
15425
  payload
15426
15426
  );
15427
15427
  }
15428
+ /**
15429
+ * Filter out undefined and null values from attributes
15430
+ *
15431
+ * This improves DX by allowing callers to pass objects with optional properties
15432
+ * without having to manually filter them first.
15433
+ *
15434
+ * @param attributes - Input attributes (may contain undefined/null)
15435
+ * @returns Filtered attributes with only defined values, or undefined if empty
15436
+ *
15437
+ * @example
15438
+ * ```typescript
15439
+ * const filtered = this.filterAttributes({
15440
+ * userId: user.id,
15441
+ * email: user.email, // might be undefined
15442
+ * plan: null, // will be filtered out
15443
+ * });
15444
+ * // Result: { userId: 'abc', email: 'test@example.com' } or { userId: 'abc' }
15445
+ * ```
15446
+ */
15447
+ filterAttributes(attributes) {
15448
+ if (!attributes) return void 0;
15449
+ const filtered = {};
15450
+ for (const [key, value] of Object.entries(attributes)) {
15451
+ if (value !== void 0 && value !== null) {
15452
+ filtered[key] = value;
15453
+ }
15454
+ }
15455
+ return Object.keys(filtered).length > 0 ? filtered : void 0;
15456
+ }
15428
15457
  /**
15429
15458
  * Track an event
15430
15459
  */
@@ -15482,6 +15511,31 @@ var EventSubscriber = class {
15482
15511
  };
15483
15512
  await this.send(payload);
15484
15513
  }
15514
+ /**
15515
+ * Track funnel progression with custom step names
15516
+ *
15517
+ * Unlike trackFunnelStep which uses FunnelStatus enum values,
15518
+ * this method allows any string as the step name for flexible funnel tracking.
15519
+ *
15520
+ * @param funnelName - Name of the funnel (e.g., "checkout", "onboarding")
15521
+ * @param stepName - Custom step name (e.g., "cart_viewed", "payment_entered")
15522
+ * @param stepNumber - Optional numeric position in the funnel
15523
+ * @param attributes - Optional event attributes
15524
+ */
15525
+ async trackFunnelProgression(funnelName, stepName, stepNumber, attributes) {
15526
+ if (!this.enabled) return;
15527
+ const payload = {
15528
+ type: "funnel",
15529
+ name: `${funnelName}.${stepName}`,
15530
+ funnel: funnelName,
15531
+ step: stepName,
15532
+ stepName,
15533
+ stepNumber,
15534
+ attributes,
15535
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
15536
+ };
15537
+ await this.send(payload);
15538
+ }
15485
15539
  /**
15486
15540
  * Flush pending requests and clean up
15487
15541
  *
@@ -15542,19 +15596,47 @@ var PostHogSubscriber = class extends EventSubscriber {
15542
15596
  posthog = null;
15543
15597
  config;
15544
15598
  initPromise = null;
15599
+ /** True when using browser's window.posthog (different API signature) */
15600
+ isBrowserClient = false;
15545
15601
  constructor(config) {
15546
15602
  super();
15547
- if (!config.apiKey && !config.client) {
15548
- throw new Error("PostHogSubscriber requires either apiKey or client to be provided");
15603
+ if (config.serverless) {
15604
+ config = {
15605
+ flushAt: 1,
15606
+ flushInterval: 0,
15607
+ requestTimeout: 3e3,
15608
+ ...config
15609
+ // User config overrides serverless defaults
15610
+ };
15611
+ }
15612
+ if (!config.apiKey && !config.client && !config.useGlobalClient) {
15613
+ throw new Error(
15614
+ "PostHogSubscriber requires either apiKey, client, or useGlobalClient to be provided"
15615
+ );
15549
15616
  }
15550
15617
  this.enabled = config.enabled ?? true;
15551
- this.config = config;
15618
+ this.config = {
15619
+ filterUndefinedValues: true,
15620
+ ...config
15621
+ };
15552
15622
  if (this.enabled) {
15553
15623
  this.initPromise = this.initialize();
15554
15624
  }
15555
15625
  }
15556
15626
  async initialize() {
15557
15627
  try {
15628
+ if (this.config.useGlobalClient) {
15629
+ const globalWindow = typeof globalThis === "undefined" ? void 0 : globalThis;
15630
+ if (globalWindow?.posthog) {
15631
+ this.posthog = globalWindow.posthog;
15632
+ this.isBrowserClient = true;
15633
+ this.setupErrorHandling();
15634
+ return;
15635
+ }
15636
+ throw new Error(
15637
+ "useGlobalClient enabled but window.posthog not found. Ensure PostHog script is loaded before initializing the subscriber."
15638
+ );
15639
+ }
15558
15640
  if (this.config.client) {
15559
15641
  this.posthog = this.config.client;
15560
15642
  this.setupErrorHandling();
@@ -15601,19 +15683,31 @@ var PostHogSubscriber = class extends EventSubscriber {
15601
15683
  */
15602
15684
  async sendToDestination(payload) {
15603
15685
  await this.ensureInitialized();
15604
- let properties = payload.attributes;
15686
+ const filteredAttributes = this.config.filterUndefinedValues === false ? payload.attributes : this.filterAttributes(payload.attributes);
15687
+ const properties = { ...filteredAttributes };
15605
15688
  if (payload.value !== void 0) {
15606
- properties = { ...payload.attributes, value: payload.value };
15689
+ properties.value = payload.value;
15607
15690
  }
15608
- const capturePayload = {
15609
- distinctId: this.extractDistinctId(payload.attributes),
15610
- event: payload.name,
15611
- properties
15612
- };
15613
- if (payload.attributes?.groups) {
15614
- capturePayload.groups = payload.attributes.groups;
15691
+ if (payload.stepNumber !== void 0) {
15692
+ properties.step_number = payload.stepNumber;
15693
+ }
15694
+ if (payload.stepName !== void 0) {
15695
+ properties.step_name = payload.stepName;
15696
+ }
15697
+ const distinctId = this.extractDistinctId(filteredAttributes);
15698
+ if (this.isBrowserClient) {
15699
+ this.posthog?.capture(payload.name, properties);
15700
+ } else {
15701
+ const capturePayload = {
15702
+ distinctId,
15703
+ event: payload.name,
15704
+ properties
15705
+ };
15706
+ if (filteredAttributes?.groups) {
15707
+ capturePayload.groups = filteredAttributes.groups;
15708
+ }
15709
+ this.posthog?.capture(capturePayload);
15615
15710
  }
15616
- this.posthog?.capture(capturePayload);
15617
15711
  }
15618
15712
  // Feature Flag Methods
15619
15713
  /**
@@ -15835,6 +15929,15 @@ var PostHogSubscriber = class extends EventSubscriber {
15835
15929
  */
15836
15930
  handleError(error, payload) {
15837
15931
  this.config.onError?.(error);
15932
+ if (this.config.onErrorWithContext) {
15933
+ this.config.onErrorWithContext({
15934
+ error,
15935
+ eventName: payload.name,
15936
+ eventType: payload.type,
15937
+ attributes: payload.attributes,
15938
+ subscriberName: this.name
15939
+ });
15940
+ }
15838
15941
  super.handleError(error, payload);
15839
15942
  }
15840
15943
  };