@virex-tech/paywallo-sdk 2.5.3 → 2.6.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.mjs CHANGED
@@ -648,9 +648,12 @@ var init_IdentityManager = __esm({
648
648
  dateOfBirth: this.dateOfBirth ?? void 0,
649
649
  gender: this.gender ?? void 0
650
650
  });
651
+ if (this.debug) console.log("[Paywallo] identify confirmed", this.anonId.slice(0, 8));
651
652
  } catch (err) {
652
- if (this.debug) console.log("[Paywallo] identify dispatch error", err);
653
+ if (this.debug) console.log("[Paywallo] identify failed:", err);
653
654
  }
655
+ } else {
656
+ if (this.debug) console.log("[Paywallo] identify skipped \u2014 anonId not ready");
654
657
  }
655
658
  }
656
659
  getDistinctId() {
@@ -2285,18 +2288,15 @@ var init_constants = __esm({
2285
2288
  });
2286
2289
 
2287
2290
  // src/domains/notifications/config.ts
2288
- function resolveApiBaseUrl(config) {
2289
- if (config.apiBaseUrl) return config.apiBaseUrl;
2290
- if (config.environment === "sandbox") return SANDBOX_API_BASE_URL;
2291
+ function resolveApiBaseUrl() {
2291
2292
  return DEFAULT_API_BASE_URL;
2292
2293
  }
2293
- var DEFAULT_API_BASE_URL, SANDBOX_API_BASE_URL;
2294
+ var DEFAULT_API_BASE_URL;
2294
2295
  var init_config = __esm({
2295
2296
  "src/domains/notifications/config.ts"() {
2296
2297
  "use strict";
2297
2298
  init_constants();
2298
2299
  DEFAULT_API_BASE_URL = DEFAULT_API_URL;
2299
- SANDBOX_API_BASE_URL = DEFAULT_API_URL;
2300
2300
  }
2301
2301
  });
2302
2302
 
@@ -2611,8 +2611,8 @@ var init_NotificationHandlerSetup = __esm({
2611
2611
  // src/core/version.ts
2612
2612
  function resolveVersion() {
2613
2613
  try {
2614
- if ("2.5.3") {
2615
- return "2.5.3";
2614
+ if ("2.6.0") {
2615
+ return "2.6.0";
2616
2616
  }
2617
2617
  } catch {
2618
2618
  }
@@ -3066,10 +3066,7 @@ var init_NotificationsManager = __esm({
3066
3066
  }
3067
3067
  applyConfig(config) {
3068
3068
  this.appKey = config.appKey;
3069
- this.apiBaseUrl = resolveApiBaseUrl({
3070
- apiBaseUrl: config.apiBaseUrl,
3071
- environment: config.environment
3072
- });
3069
+ this.apiBaseUrl = resolveApiBaseUrl();
3073
3070
  this.debug = config.debug ?? false;
3074
3071
  this.permissionManager.setDebug(this.debug);
3075
3072
  }
@@ -3245,7 +3242,8 @@ var init_OnboardingError = __esm({
3245
3242
  };
3246
3243
  ONBOARDING_ERROR_CODES = {
3247
3244
  NOT_INITIALIZED: "ONBOARDING_NOT_INITIALIZED",
3248
- INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME"
3245
+ INVALID_STEP_NAME: "ONBOARDING_INVALID_STEP_NAME",
3246
+ INVALID_ORDER: "ONBOARDING_INVALID_ORDER"
3249
3247
  };
3250
3248
  }
3251
3249
  });
@@ -3275,16 +3273,20 @@ var init_OnboardingManager = __esm({
3275
3273
  * Saves the step name internally for implicit drop detection on the backend.
3276
3274
  *
3277
3275
  * @param stepName - Unique name for this onboarding step.
3278
- * @param order - Optional explicit display order (accepts decimals, e.g. 2.1 for A/B variants).
3276
+ * @param order - Ordem de exibição do step. Obrigatório. Aceita decimais (ex: 2.1 para variantes A/B).
3277
+ * Deve ser um número finito e não-negativo. O servidor faz o floor — não arredondar aqui.
3279
3278
  */
3280
- async step(stepName, order) {
3279
+ async step(stepName, order, options) {
3281
3280
  this.assertConfig();
3282
3281
  this.validateStepName(stepName, "step");
3282
+ this.validateOrder(order);
3283
3283
  this.lastStep = stepName;
3284
- const stepPayload = { step_name: stepName };
3285
- if (order !== void 0 && Number.isFinite(order) && order >= 0) {
3286
- stepPayload.order = order;
3287
- }
3284
+ const stepPayload = {
3285
+ step_name: stepName,
3286
+ order,
3287
+ ...options?.variantKey !== void 0 ? { variant_key: options.variantKey } : {},
3288
+ ...options?.timeOnPrevS !== void 0 ? { time_on_prev_s: options.timeOnPrevS } : {}
3289
+ };
3288
3290
  const payload = {
3289
3291
  family: "onboarding",
3290
3292
  type: "step",
@@ -3296,33 +3298,21 @@ var init_OnboardingManager = __esm({
3296
3298
  * Tracks successful completion of the onboarding flow.
3297
3299
  * Marks the flow as finished.
3298
3300
  */
3299
- async complete() {
3300
- this.assertConfig();
3301
- this.finished = true;
3302
- return this.emit("onboarding", { family: "onboarding", type: "complete" }, "complete");
3303
- }
3304
- /**
3305
- * Tracks an explicit drop (abandonment) at the given step.
3306
- * Marks the flow as finished.
3307
- *
3308
- * @param stepName - The step name where the user dropped off.
3309
- */
3310
- async drop(stepName) {
3301
+ async complete(options) {
3311
3302
  this.assertConfig();
3312
- this.validateStepName(stepName, "drop");
3313
3303
  this.finished = true;
3314
3304
  const payload = {
3315
3305
  family: "onboarding",
3316
- type: "drop",
3317
- ...{ step_name: stepName }
3306
+ type: "complete",
3307
+ ...options?.variantKey !== void 0 ? { variant_key: options.variantKey } : {}
3318
3308
  };
3319
- return this.emit("onboarding", payload, "drop");
3309
+ return this.emit("onboarding", payload, "complete");
3320
3310
  }
3321
3311
  /** Returns the last step name seen, or null if no step was tracked yet. */
3322
3312
  getLastStep() {
3323
3313
  return this.lastStep;
3324
3314
  }
3325
- /** Returns whether the flow has been marked as finished (complete or drop). */
3315
+ /** Returns whether the flow has been marked as finished (complete). */
3326
3316
  isFinished() {
3327
3317
  return this.finished;
3328
3318
  }
@@ -3354,6 +3344,14 @@ var init_OnboardingManager = __esm({
3354
3344
  );
3355
3345
  }
3356
3346
  }
3347
+ validateOrder(order) {
3348
+ if (order === void 0 || order === null || !Number.isFinite(order) || order < 0) {
3349
+ throw new OnboardingError(
3350
+ ONBOARDING_ERROR_CODES.INVALID_ORDER,
3351
+ "OnboardingManager.step(): order deve ser um n\xFAmero finito e n\xE3o-negativo."
3352
+ );
3353
+ }
3354
+ }
3357
3355
  };
3358
3356
  onboardingManager = new OnboardingManager();
3359
3357
  }
@@ -5221,7 +5219,7 @@ var init_QueueProcessor = __esm({
5221
5219
  for (const item of batch) {
5222
5220
  retryIds.add(item.id);
5223
5221
  }
5224
- console.error("[Paywallo:QUEUE] event batch network error \u2014 items will retry", { size: batch.length, error: error instanceof Error ? error.message : String(error) });
5222
+ if (this.config.debug) console.log("[Paywallo:QUEUE] event batch network error \u2014 items will retry", { size: batch.length, error: error instanceof Error ? error.message : String(error) });
5225
5223
  this.log("Event batch threw network error - will retry", {
5226
5224
  size: batch.length,
5227
5225
  error: error instanceof Error ? error.message : String(error)
@@ -5234,7 +5232,7 @@ var init_QueueProcessor = __esm({
5234
5232
  processed++;
5235
5233
  }
5236
5234
  this.log("Event batch processed successfully", { size: batch.length });
5237
- } else if (response.status >= 400 && response.status < 500) {
5235
+ } else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
5238
5236
  for (const item of batch) {
5239
5237
  await offlineQueue.removeItem(item.id);
5240
5238
  failed++;
@@ -5246,7 +5244,7 @@ var init_QueueProcessor = __esm({
5246
5244
  console.log("[Paywallo:QUEUE] event batch deduplicated by server \u2014 items dropped (benign)", { status: response.status, size: batch.length, error: responseError });
5247
5245
  }
5248
5246
  } else {
5249
- console.error("[Paywallo:QUEUE] event batch failed PERMANENTLY (4xx) \u2014 items dropped", { status: response.status, size: batch.length, responseBody: typeof response.data === "string" ? response.data.slice(0, 1e3) : JSON.stringify(response.data).slice(0, 1e3), firstItemBody: typeof batch[0].body === "string" ? batch[0].body.slice(0, 1e3) : JSON.stringify(batch[0].body).slice(0, 1e3) });
5247
+ if (this.config.debug) console.log("[Paywallo:QUEUE] event batch failed PERMANENTLY (4xx) \u2014 items dropped", { status: response.status, size: batch.length, responseBody: typeof response.data === "string" ? response.data.slice(0, 1e3) : JSON.stringify(response.data).slice(0, 1e3), firstItemBody: typeof batch[0].body === "string" ? batch[0].body.slice(0, 1e3) : JSON.stringify(batch[0].body).slice(0, 1e3) });
5250
5248
  }
5251
5249
  this.log("Event batch failed permanently (4xx) - removing from queue", {
5252
5250
  status: response.status,
@@ -5257,7 +5255,7 @@ var init_QueueProcessor = __esm({
5257
5255
  for (const item of batch) {
5258
5256
  retryIds.add(item.id);
5259
5257
  }
5260
- console.error("[Paywallo:QUEUE] event batch server error (5xx) \u2014 will retry", { status: response.status, size: batch.length });
5258
+ if (this.config.debug) console.log("[Paywallo:QUEUE] event batch server error (5xx) \u2014 will retry", { status: response.status, size: batch.length });
5261
5259
  this.log("Event batch failed with server error - will retry", {
5262
5260
  status: response.status,
5263
5261
  size: batch.length
@@ -5287,7 +5285,7 @@ var init_QueueProcessor = __esm({
5287
5285
  skipRetry: false
5288
5286
  });
5289
5287
  } catch (error) {
5290
- console.error("[Paywallo:QUEUE] individual item network error \u2014 will retry", { id: item.id, url: item.url, error: error instanceof Error ? error.message : String(error) });
5288
+ if (this.config.debug) console.log("[Paywallo:QUEUE] individual item network error \u2014 will retry", { id: item.id, url: item.url, error: error instanceof Error ? error.message : String(error) });
5291
5289
  this.log("Request threw network error - will retry", {
5292
5290
  id: item.id,
5293
5291
  error: error instanceof Error ? error.message : String(error)
@@ -5298,7 +5296,7 @@ var init_QueueProcessor = __esm({
5298
5296
  this.log("Queue item processed successfully", { id: item.id });
5299
5297
  return { success: true, permanent: false };
5300
5298
  }
5301
- if (response.status >= 400 && response.status < 500) {
5299
+ if (response.status >= 400 && response.status < 500 && response.status !== 429) {
5302
5300
  this.log("Request failed with permanent client error - removing from queue", {
5303
5301
  id: item.id,
5304
5302
  url: item.url,
@@ -6821,8 +6819,9 @@ var init_schemas = __esm({
6821
6819
  path: ["transaction_id"]
6822
6820
  });
6823
6821
  onboardingEventSchema = z.object({
6824
- type: z.enum(["step", "complete", "drop"]),
6825
- step_index: z.number().int().nonnegative().optional(),
6822
+ type: z.enum(["step", "complete"]),
6823
+ family: z.literal("onboarding").optional(),
6824
+ order: z.number().nonnegative().optional(),
6826
6825
  step_name: z.string().optional(),
6827
6826
  variant_key: z.string().optional(),
6828
6827
  time_on_prev_s: z.number().nonnegative().optional()
@@ -6919,7 +6918,7 @@ function isValidEventName(name) {
6919
6918
  async function trackEvent(apiClient, state, eventName, options) {
6920
6919
  const distinctId = identityManager.getDistinctId();
6921
6920
  if (!distinctId) {
6922
- console.error("[Paywallo:DROP] event dropped \u2014 no distinctId available yet", { eventName });
6921
+ if (state.config?.debug) console.log("[Paywallo:DROP] event dropped \u2014 no distinctId available yet", { eventName });
6923
6922
  return;
6924
6923
  }
6925
6924
  if (!isValidEventName(eventName)) {
@@ -7654,6 +7653,11 @@ function isServerError(res) {
7654
7653
  const r = res;
7655
7654
  return r.ok === false && typeof r.status === "number" && r.status >= 500;
7656
7655
  }
7656
+ function isRateLimitError(res) {
7657
+ if (typeof res !== "object" || res === null) return false;
7658
+ const r = res;
7659
+ return r.ok === false && r.status === 429;
7660
+ }
7657
7661
  async function postWithQueue(deps, url, payload, label, priority) {
7658
7662
  const enqueue = async () => {
7659
7663
  await offlineQueue.enqueue(
@@ -7675,6 +7679,9 @@ async function postWithQueue(deps, url, payload, label, priority) {
7675
7679
  if (isServerError(res) && deps.isOfflineQueueEnabled()) {
7676
7680
  if (deps.isDebug()) console.log("[Paywallo:ApiClient] Server error, queued for retry:", label, priority ?? "normal");
7677
7681
  await enqueue();
7682
+ } else if (isRateLimitError(res) && deps.isOfflineQueueEnabled()) {
7683
+ if (deps.isDebug()) console.log("[Paywallo:ApiClient] Rate limited (429), queued for retry:", label, priority ?? "normal");
7684
+ await enqueue();
7678
7685
  }
7679
7686
  } catch (error) {
7680
7687
  if (deps.isDebug()) console.log("[Paywallo:ApiClient] Request failed:", label, error);
@@ -7971,7 +7978,7 @@ var init_EventBatcher = __esm({
7971
7978
  try {
7972
7979
  await this.postBatch([event], `event_critical:${event.eventName}`, "critical");
7973
7980
  } catch (err) {
7974
- console.error("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
7981
+ if (this.debug) console.log("[Paywallo:CRITICAL] critical event post failed", { eventName: event.eventName, error: err instanceof Error ? err.message : String(err) });
7975
7982
  }
7976
7983
  }
7977
7984
  }
@@ -7985,7 +7992,7 @@ var init_EventBatcher = __esm({
7985
7992
  try {
7986
7993
  await this.postBatch(batch, `event_batch:${batch.length}`);
7987
7994
  } catch (err) {
7988
- console.error("[Paywallo:NORMAL] batch post failed \u2014 relying on OfflineQueue", { batchSize: batch.length, error: err instanceof Error ? err.message : String(err) });
7995
+ if (this.debug) console.log("[Paywallo:NORMAL] batch post failed \u2014 relying on OfflineQueue", { batchSize: batch.length, error: err instanceof Error ? err.message : String(err) });
7989
7996
  }
7990
7997
  }
7991
7998
  async postBatch(events, label, priority = "normal") {
@@ -8000,7 +8007,7 @@ var init_EventBatcher = __esm({
8000
8007
  const parsed = v2EnvelopeSchema.safeParse(envelope);
8001
8008
  if (!parsed.success) {
8002
8009
  if (this.debug) console.log("[Paywallo EVENTS] V2 envelope schema validation failed:", parsed.error.issues);
8003
- console.error("[Paywallo:CRITICAL] V2 envelope schema validation failed", { issues: parsed.error.issues, eventCount: events.length, firstEventName: events[0]?.eventName, context: providerContext });
8010
+ if (this.debug) console.log("[Paywallo:CRITICAL] V2 envelope schema validation failed", { issues: parsed.error.issues, eventCount: events.length, firstEventName: events[0]?.eventName, context: providerContext });
8004
8011
  throw parsed.error;
8005
8012
  }
8006
8013
  await this.post(V2_BATCH_ENDPOINT, parsed.data, label, priority);
@@ -8618,7 +8625,6 @@ function setupNotifications(apiClient, config, environment, eventPipeline) {
8618
8625
  notificationsManager.setupHandlers({ eventBatcher: eventPipeline });
8619
8626
  notificationsManager.initialize({
8620
8627
  appKey: config.appKey,
8621
- apiBaseUrl: DEFAULT_API_URL,
8622
8628
  debug: config.debug,
8623
8629
  environment: environment === "Sandbox" ? "sandbox" : "production"
8624
8630
  }).catch((err) => {
@@ -8660,7 +8666,6 @@ var init_PaywalloInitHelpers = __esm({
8660
8666
  init_identity();
8661
8667
  init_notifications();
8662
8668
  init_NativePushBridge();
8663
- init_constants();
8664
8669
  init_SecureStorage();
8665
8670
  }
8666
8671
  });
@@ -8751,7 +8756,7 @@ function reportInitFailure(state, config, error, reason) {
8751
8756
  error: error instanceof Error ? error.message : String(error)
8752
8757
  });
8753
8758
  } catch (err) {
8754
- console.error("[Paywallo] reportInitFailure error", err);
8759
+ if (config.debug) console.log("[Paywallo] reportInitFailure error", err);
8755
8760
  }
8756
8761
  }
8757
8762
  function reportInitSuccess(state, config, attempts) {
@@ -8760,7 +8765,7 @@ function reportInitSuccess(state, config, attempts) {
8760
8765
  void state.apiClient.reportError("INIT_RECOVERED", `Succeeded after ${attempts} retries`, { attempts });
8761
8766
  }
8762
8767
  } catch (err) {
8763
- console.error("[Paywallo] reportInitSuccess error", err);
8768
+ if (config.debug) console.log("[Paywallo] reportInitSuccess error", err);
8764
8769
  }
8765
8770
  }
8766
8771
  async function resolveSessionFlags(state, keys, apiClient, distinctId) {
@@ -8914,12 +8919,15 @@ async function doInit(state, config) {
8914
8919
  setupNotifications(apiClient, config, environment, eventPipeline);
8915
8920
  if (config.autoStartSession !== false) {
8916
8921
  sessionManager.startSession().catch((err) => {
8917
- console.error("[Paywallo INIT] autoStart session error", err);
8922
+ if (config.debug) console.log("[Paywallo INIT] autoStart session error", err);
8918
8923
  });
8919
8924
  }
8920
8925
  new InstallTracker(config.debug, {
8921
8926
  distinctIdProvider: () => identityManager.getDistinctId()
8922
- }).trackIfNeeded(apiClient, config.requestATT === true).catch(() => {
8927
+ }).trackIfNeeded(apiClient, config.requestATT === true).then(() => {
8928
+ if (config.debug) console.log("[Paywallo INSTALL] $app_installed sent");
8929
+ }).catch(() => {
8930
+ if (config.debug) console.log("[Paywallo INSTALL] $app_installed failed \u2014 will retry on next launch");
8923
8931
  });
8924
8932
  if (config.sessionFlags && config.sessionFlags.length > 0) {
8925
8933
  await resolveSessionFlags(state, config.sessionFlags, apiClient, distinctId);
@@ -9154,6 +9162,7 @@ var init_PaywalloClient = __esm({
9154
9162
  }
9155
9163
  if (this.state.config?.debug) console.log("[Paywallo IDENTIFY]", options ? { hasEmail: "email" in options && !!options.email, hasProperties: "properties" in options } : void 0);
9156
9164
  await identityManager.identify(options);
9165
+ if (this.state.config?.debug) console.log("[Paywallo IDENTIFY] done");
9157
9166
  }
9158
9167
  async track(eventName, options) {
9159
9168
  return trackEvent(this.getApiClientOrThrow(), this.state, eventName, options);
@@ -9635,18 +9644,14 @@ init_onboarding();
9635
9644
  import { useCallback as useCallback9 } from "react";
9636
9645
  function useOnboarding() {
9637
9646
  const step = useCallback9(
9638
- (stepName, order) => onboardingManager.step(stepName, order),
9647
+ (stepName, order, options) => onboardingManager.step(stepName, order, options),
9639
9648
  []
9640
9649
  );
9641
9650
  const complete = useCallback9(
9642
- () => onboardingManager.complete(),
9643
- []
9644
- );
9645
- const drop = useCallback9(
9646
- (stepName) => onboardingManager.drop(stepName),
9651
+ (options) => onboardingManager.complete(options),
9647
9652
  []
9648
9653
  );
9649
- return { step, complete, drop };
9654
+ return { step, complete };
9650
9655
  }
9651
9656
 
9652
9657
  // src/hooks/usePaywallo.ts
@@ -10960,6 +10965,7 @@ function PaywalloProvider({ children, config }) {
10960
10965
  void pushAttributionToSuperwall(configRef.current.debug);
10961
10966
  setDistinctId(PaywalloClient.getDistinctId());
10962
10967
  setIsInitialized(true);
10968
+ if (configRef.current.debug) console.log("[Paywallo] SDK ready", PaywalloClient.getDistinctId()?.slice(0, 8));
10963
10969
  if (!autoPreloadTriggeredRef.current) {
10964
10970
  autoPreloadTriggeredRef.current = true;
10965
10971
  const placement = await PaywalloClient.waitForAutoPreloadedPlacement();