@wireai/activation 0.9.1 → 0.9.2

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.
@@ -391,6 +391,22 @@ type WireOnboardingProps = {
391
391
  * accounts mid-flow. Only meaningful with `storage`.
392
392
  */
393
393
  persistKey?: string;
394
+ /**
395
+ * OPT-IN: keep the persisted session seed alive ACROSS completion, so a multi-stage or
396
+ * replay-after-complete re-entry WITHIN one signup (typically a `key=` remount) resumes the
397
+ * SAME session instead of minting a fresh `metadata.sessionId` — which the backend would adopt
398
+ * as a second `contextId`, double-counting a `session_started` on the funnel.
399
+ *
400
+ * Default (omitted / `false`): a completion CLEARS the seed, so the next onboarding on this
401
+ * device starts fresh — the legacy single-stage behavior. Leave it unset and NOTHING changes.
402
+ *
403
+ * When `true`: the seed survives completion, and freshness for a genuinely new run is governed
404
+ * by the TTL (past `sessionTtlMs` → a fresh seed is minted) and an explicit new-run signal
405
+ * (scope a new `persistKey`, e.g. a per-signup id, to force a fresh seed within the TTL).
406
+ *
407
+ * Only meaningful with `storage`. Dropped/degraded sessions are unaffected (they never clear).
408
+ */
409
+ retainSessionOnComplete?: boolean;
394
410
  };
395
411
  /** Backend-supplied progress, read off `response.props.progress` when present. */
396
412
  type OnboardingProgress = {
@@ -391,6 +391,22 @@ type WireOnboardingProps = {
391
391
  * accounts mid-flow. Only meaningful with `storage`.
392
392
  */
393
393
  persistKey?: string;
394
+ /**
395
+ * OPT-IN: keep the persisted session seed alive ACROSS completion, so a multi-stage or
396
+ * replay-after-complete re-entry WITHIN one signup (typically a `key=` remount) resumes the
397
+ * SAME session instead of minting a fresh `metadata.sessionId` — which the backend would adopt
398
+ * as a second `contextId`, double-counting a `session_started` on the funnel.
399
+ *
400
+ * Default (omitted / `false`): a completion CLEARS the seed, so the next onboarding on this
401
+ * device starts fresh — the legacy single-stage behavior. Leave it unset and NOTHING changes.
402
+ *
403
+ * When `true`: the seed survives completion, and freshness for a genuinely new run is governed
404
+ * by the TTL (past `sessionTtlMs` → a fresh seed is minted) and an explicit new-run signal
405
+ * (scope a new `persistKey`, e.g. a per-signup id, to force a fresh seed within the TTL).
406
+ *
407
+ * Only meaningful with `storage`. Dropped/degraded sessions are unaffected (they never clear).
408
+ */
409
+ retainSessionOnComplete?: boolean;
394
410
  };
395
411
  /** Backend-supplied progress, read off `response.props.progress` when present. */
396
412
  type OnboardingProgress = {
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
- import { o as WireOnboardingProps, p as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, q as OnboardingEvent, u as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './currentSession-Bs2JfTJ8.mjs';
4
- export { A as AnalyticsEvent, b as ClientEventType, v as DeviceFormFactor, w as EXTRA_KEY_PREFIX, x as OnboardingProgress, R as RESERVED_USER_CONTEXT_KEYS, y as ResolveUserContextOptions, z as ResolvedUserContext, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, W as WireUserContext, B as collectDeviceContext, k as getCurrentSessionId, F as hashEmailFnv1a, G as isWireScalar, m as makeSessionId, H as namespaceExtra, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, I as resolveUserContext, s as setCurrentSessionId, t as toAnalyticsEvent } from './currentSession-Bs2JfTJ8.mjs';
3
+ import { o as WireOnboardingProps, p as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, q as OnboardingEvent, u as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './currentSession-CRRQLbAq.mjs';
4
+ export { A as AnalyticsEvent, b as ClientEventType, v as DeviceFormFactor, w as EXTRA_KEY_PREFIX, x as OnboardingProgress, R as RESERVED_USER_CONTEXT_KEYS, y as ResolveUserContextOptions, z as ResolvedUserContext, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, W as WireUserContext, B as collectDeviceContext, k as getCurrentSessionId, F as hashEmailFnv1a, G as isWireScalar, m as makeSessionId, H as namespaceExtra, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, I as resolveUserContext, s as setCurrentSessionId, t as toAnalyticsEvent } from './currentSession-CRRQLbAq.mjs';
5
5
  import { O as OnboardingTheme } from './types-BKfpdZzX.mjs';
6
6
  export { a as OnboardingButtonStyle, b as OnboardingColors, c as OnboardingFonts, d as OnboardingRadius, e as OnboardingSpacing } from './types-BKfpdZzX.mjs';
7
7
  export { C as CenteredModal, a as CenteredModalHandle, b as CenteredModalProps } from './CenteredModal-C3qQBHsA.mjs';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
- import { o as WireOnboardingProps, p as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, q as OnboardingEvent, u as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './currentSession-61dcm3V-.js';
4
- export { A as AnalyticsEvent, b as ClientEventType, v as DeviceFormFactor, w as EXTRA_KEY_PREFIX, x as OnboardingProgress, R as RESERVED_USER_CONTEXT_KEYS, y as ResolveUserContextOptions, z as ResolvedUserContext, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, W as WireUserContext, B as collectDeviceContext, k as getCurrentSessionId, F as hashEmailFnv1a, G as isWireScalar, m as makeSessionId, H as namespaceExtra, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, I as resolveUserContext, s as setCurrentSessionId, t as toAnalyticsEvent } from './currentSession-61dcm3V-.js';
3
+ import { o as WireOnboardingProps, p as WireOnboardingConfig, O as OnboardingResult, S as StepValidator, q as OnboardingEvent, u as OnboardingCopy, a as ClientEventTarget, D as DeviceContext, C as ClientEvent, e as EnvelopeSource } from './currentSession-Dj0cN3Rg.js';
4
+ export { A as AnalyticsEvent, b as ClientEventType, v as DeviceFormFactor, w as EXTRA_KEY_PREFIX, x as OnboardingProgress, R as RESERVED_USER_CONTEXT_KEYS, y as ResolveUserContextOptions, z as ResolvedUserContext, g as WIRE_ONBOARDING_EVENTS, h as WireOnboardingEventName, W as WireUserContext, B as collectDeviceContext, k as getCurrentSessionId, F as hashEmailFnv1a, G as isWireScalar, m as makeSessionId, H as namespaceExtra, r as reportClientEvent, l as reportClientEvents, n as resetCurrentSessionId, I as resolveUserContext, s as setCurrentSessionId, t as toAnalyticsEvent } from './currentSession-Dj0cN3Rg.js';
5
5
  import { O as OnboardingTheme } from './types-BKfpdZzX.js';
6
6
  export { a as OnboardingButtonStyle, b as OnboardingColors, c as OnboardingFonts, d as OnboardingRadius, e as OnboardingSpacing } from './types-BKfpdZzX.js';
7
7
  export { C as CenteredModal, a as CenteredModalHandle, b as CenteredModalProps } from './CenteredModal-Cdgns6--.js';
package/dist/index.js CHANGED
@@ -3351,6 +3351,7 @@ var clearPersistedSession = (storage, key) => {
3351
3351
  } catch {
3352
3352
  }
3353
3353
  };
3354
+ var shouldClearOnComplete = (retainSessionOnComplete) => !retainSessionOnComplete;
3354
3355
 
3355
3356
  // src/identity/userIdentity.ts
3356
3357
  var USER_ID_MAX_LENGTH = 128;
@@ -3400,6 +3401,7 @@ var WireOnboarding = ({
3400
3401
  storage,
3401
3402
  sessionTtlMs = DEFAULT_SESSION_TTL_MS,
3402
3403
  persistKey,
3404
+ retainSessionOnComplete,
3403
3405
  userContext,
3404
3406
  userId
3405
3407
  }) => {
@@ -3434,10 +3436,10 @@ var WireOnboarding = ({
3434
3436
  }, [storage, storageKey, sessionTtlMs, session]);
3435
3437
  const handleComplete = React18.useCallback(
3436
3438
  (result) => {
3437
- if (storage) clearPersistedSession(storage, storageKey);
3439
+ if (storage && shouldClearOnComplete(retainSessionOnComplete)) clearPersistedSession(storage, storageKey);
3438
3440
  onComplete(result);
3439
3441
  },
3440
- [storage, storageKey, onComplete]
3442
+ [storage, storageKey, retainSessionOnComplete, onComplete]
3441
3443
  );
3442
3444
  const sessionId = (_a2 = session == null ? void 0 : session.id) != null ? _a2 : "";
3443
3445
  const startupUserIdRef = React18.useRef(boundUserId);
@@ -4433,8 +4435,9 @@ var createEventQueue = (options) => {
4433
4435
  } catch {
4434
4436
  }
4435
4437
  })();
4438
+ const DROP_STATUSES = /* @__PURE__ */ new Set([400, 404, 413, 422]);
4436
4439
  const postBatch = async (events) => {
4437
- if (!(target == null ? void 0 : target.serverUrl) || events.length === 0) return false;
4440
+ if (!(target == null ? void 0 : target.serverUrl) || events.length === 0) return "retry";
4438
4441
  const controller = typeof AbortController !== "undefined" ? new AbortController() : void 0;
4439
4442
  const timer = setTimeout(() => controller == null ? void 0 : controller.abort(), 15e3);
4440
4443
  try {
@@ -4447,9 +4450,12 @@ var createEventQueue = (options) => {
4447
4450
  body: JSON.stringify({ events }),
4448
4451
  signal: controller == null ? void 0 : controller.signal
4449
4452
  });
4450
- return !!(res && res.ok);
4453
+ if (res && res.ok) return "ok";
4454
+ const status = res == null ? void 0 : res.status;
4455
+ if (typeof status === "number" && DROP_STATUSES.has(status)) return "drop";
4456
+ return "retry";
4451
4457
  } catch {
4452
- return false;
4458
+ return "retry";
4453
4459
  } finally {
4454
4460
  clearTimeout(timer);
4455
4461
  }
@@ -4481,8 +4487,8 @@ var createEventQueue = (options) => {
4481
4487
  try {
4482
4488
  while (pending.length > 0) {
4483
4489
  const batch = pending.slice(0, batchSize);
4484
- const ok = await postBatch(batch.map((item) => item.event));
4485
- if (!ok) {
4490
+ const result = await postBatch(batch.map((item) => item.event));
4491
+ if (result === "retry") {
4486
4492
  scheduleRetry();
4487
4493
  return;
4488
4494
  }