@wireai/activation 0.13.6-next.0 → 0.14.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/AGENTS.md +21 -9
- package/CHANGELOG.md +258 -3
- package/INTEGRATION_PROMPT.md +7 -4
- package/README.md +41 -35
- package/dist/analytics/index.d.mts +9 -2
- package/dist/analytics/index.d.ts +9 -2
- package/dist/analytics/index.js +56 -12
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +56 -12
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/{currentSession-Cs3lweFZ.d.mts → currentSession-CUvTOchb.d.mts} +62 -7
- package/dist/{currentSession-DD6dKB0i.d.ts → currentSession-CW_5Mq4O.d.ts} +62 -7
- package/dist/index.d.mts +26 -6
- package/dist/index.d.ts +26 -6
- package/dist/index.js +635 -544
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +635 -544
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs.map +1 -1
- package/llms.txt +3 -3
- package/package.json +1 -1
- package/src/OnboardingFlow.tsx +23 -5
- package/src/WireOnboarding.tsx +4 -3
- package/src/activation/useWireActivation.ts +14 -1
- package/src/activation/wireActivation.ts +68 -2
- package/src/analytics/analyticsFacade.ts +24 -0
- package/src/analytics/eventQueue.ts +106 -11
- package/src/analytics/reportClientEvent.ts +31 -7
- package/src/analytics/useAnalytics.ts +17 -0
- package/src/context/deviceId.ts +10 -3
- package/src/permissions/permissionMemory.ts +12 -1
- package/src/session/persistedSession.ts +32 -8
- package/src/session-analytics/lifecycle.ts +26 -5
- package/src/session-analytics/reportSessionStart.ts +14 -10
- package/src/session-analytics/useLifecycleEvents.ts +70 -32
- package/src/session-analytics/useSessionStart.ts +57 -15
- package/src/types.ts +43 -8
- package/src/utils/readPlan.ts +26 -10
- package/src/utils/readProgress.ts +5 -0
|
@@ -472,10 +472,11 @@ type OnboardingResult = {
|
|
|
472
472
|
/** The raw message thread, for custom downstream parsing. */
|
|
473
473
|
raw: Message[];
|
|
474
474
|
/**
|
|
475
|
-
* The backend's onboarding plan, when
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* byte-identically what it
|
|
475
|
+
* The backend's onboarding plan, present when the backend sent one — the kit never infers it
|
|
476
|
+
* from which flow ran. Whether a plan arrives is the backend's configuration, not the kit's. Any
|
|
477
|
+
* run the server finished without a plan leaves this `undefined` AND leaves the key off the
|
|
478
|
+
* result object entirely — so a host written before plans existed sees byte-identically what it
|
|
479
|
+
* always saw.
|
|
479
480
|
*
|
|
480
481
|
* ⚠️ The kit does NOT interpret this and does NOT validate it. It checks one structural fact (a
|
|
481
482
|
* plan is an object) and hands the payload straight through, unread, unlogged, and never attached
|
|
@@ -484,6 +485,16 @@ type OnboardingResult = {
|
|
|
484
485
|
* the host's decision, not the kit's.
|
|
485
486
|
*/
|
|
486
487
|
plan?: unknown;
|
|
488
|
+
/**
|
|
489
|
+
* The experiment ARM the backend assigned this session, when it is running one. Absent when
|
|
490
|
+
* the tenant runs no experiment, which is the common case, and absent is NOT an error.
|
|
491
|
+
* The kit does NOT interpret it, does not log it, does not brand it and never attaches it
|
|
492
|
+
* to an analytics event. What an arm key MEANS is the host's decision.
|
|
493
|
+
*
|
|
494
|
+
* Like {@link plan}, the KEY is set only when an arm was actually seen, so a run with no
|
|
495
|
+
* experiment leaves the result byte-identical to what every host already reads.
|
|
496
|
+
*/
|
|
497
|
+
variant?: string;
|
|
487
498
|
};
|
|
488
499
|
/**
|
|
489
500
|
* Lifecycle events emitted as the flow runs, for host-side analytics. The kit owns
|
|
@@ -495,7 +506,11 @@ type OnboardingResult = {
|
|
|
495
506
|
* - `resumed`: a persisted session was restored after an app kill (fires INSTEAD of
|
|
496
507
|
* `started`, so host funnels don't double-count the same session). Also carries
|
|
497
508
|
* `contextId`. Requires the `storage` prop.
|
|
498
|
-
* - `turn`: a new assistant card arrived (`step` = 1-based index of cards seen).
|
|
509
|
+
* - `turn`: a new assistant card arrived (`step` = 1-based index of cards seen). Carries
|
|
510
|
+
* `variant`, the backend's experiment arm for this session, from the first card that
|
|
511
|
+
* declared one onwards — this is how the arm is available DURING the flow rather than
|
|
512
|
+
* only at completion. The key is absent whenever no arm has been seen, which is every
|
|
513
|
+
* turn of every tenant running no experiment.
|
|
499
514
|
* - `error`: the backend errored or the first-card watchdog timed out.
|
|
500
515
|
* - `retry`: a transient failure is being auto-retried (`attempt` = 1-based).
|
|
501
516
|
* - `fallback`: retries are exhausted; the kit degraded to the static `fallbackFlow`
|
|
@@ -516,6 +531,7 @@ type OnboardingEvent = {
|
|
|
516
531
|
type: "turn";
|
|
517
532
|
step: number;
|
|
518
533
|
component?: string;
|
|
534
|
+
variant?: string;
|
|
519
535
|
} | {
|
|
520
536
|
type: "error";
|
|
521
537
|
reason: "backend" | "timeout";
|
|
@@ -654,10 +670,19 @@ type WireOnboardingProps = {
|
|
|
654
670
|
*
|
|
655
671
|
* ```tsx
|
|
656
672
|
* <WireOnboarding userContext={activationJoinContext(deviceKey)} ... />
|
|
657
|
-
* // no device id of your own?
|
|
658
|
-
*
|
|
673
|
+
* // no device id of your own? pass `storage` and leave this prop alone — the kit injects its
|
|
674
|
+
* // own key, and only after it has confirmed the key actually persists (see `autoJoinKey`).
|
|
675
|
+
* <WireOnboarding config={{ ...config, storage }} ... />
|
|
659
676
|
* ```
|
|
660
677
|
*
|
|
678
|
+
* ⛔ Do NOT hand-build the auto key with `activationJoinContext(resolveAutoDeviceKey({...}))`.
|
|
679
|
+
* `resolveAutoDeviceKey` is SYNCHRONOUS by contract: it hands back a freshly minted id and adopts
|
|
680
|
+
* the persisted one a storage read later, and it cannot tell you whether the id survives the
|
|
681
|
+
* launch at all. A key that differs on every launch corrupts `min_sessions` rather than merely
|
|
682
|
+
* leaving the join empty. The auto-join path does the awaited, durability-checked read for you;
|
|
683
|
+
* a host that genuinely wants the value in hand should await `hydrateDeviceIdentity` and refuse a
|
|
684
|
+
* `durable: false` record, which is exactly what the kit does internally.
|
|
685
|
+
*
|
|
661
686
|
* SINCE 0.12.2, leaving it out no longer silently empties the funnel: when you pass `storage` and
|
|
662
687
|
* this prop carries no `device_key`, the kit injects its OWN per-install key — the same one the
|
|
663
688
|
* analytics surfaces mint and persist — so the default wiring joins. Anything you DO pass wins
|
|
@@ -790,6 +815,17 @@ type OnboardingProgress = {
|
|
|
790
815
|
slot_id?: string;
|
|
791
816
|
/** Whether the CURRENT screen may be skipped (backend-marked; default false → no Skip shown). */
|
|
792
817
|
skippable?: boolean;
|
|
818
|
+
/**
|
|
819
|
+
* The EXPERIMENT ARM the backend assigned this session, when the tenant is running one. Rides the
|
|
820
|
+
* render envelope as a sibling of {@link step}/{@link total}/{@link key}/{@link slot_id}, and is
|
|
821
|
+
* OMITTED entirely for a tenant running no experiment — which is the common case, and is not an
|
|
822
|
+
* error. The assignment is sticky for the session, so a later card that omits it does not
|
|
823
|
+
* un-assign it.
|
|
824
|
+
*
|
|
825
|
+
* The kit does NOT interpret this. It is whitelisted, latched and handed to the host exactly as
|
|
826
|
+
* received; what an arm key MEANS is the host's decision. See {@link OnboardingResult.variant}.
|
|
827
|
+
*/
|
|
828
|
+
variant?: string;
|
|
793
829
|
};
|
|
794
830
|
|
|
795
831
|
/**
|
|
@@ -958,6 +994,19 @@ type EventQueue = {
|
|
|
958
994
|
notifyOnline(): void;
|
|
959
995
|
/** Current pending (in-memory) count. */
|
|
960
996
|
size(): number;
|
|
997
|
+
/**
|
|
998
|
+
* Tear this queue down when its owner goes away (a hook's effect cleanup, a host disposing its
|
|
999
|
+
* own instance). Idempotent, never throws, and REQUIRED for any queue that can be re-created:
|
|
1000
|
+
* a remount builds a second queue while the first is still holding the storage claim and a live
|
|
1001
|
+
* backoff timer, and the two then fight over one persisted slot.
|
|
1002
|
+
*
|
|
1003
|
+
* It clears the retry timer, releases the claimed storage key so a replacement gets the SAME slot
|
|
1004
|
+
* instead of a rotated `…#2` nobody reads next launch, and makes the queue inert — `enqueue`,
|
|
1005
|
+
* `flush` and every write become no-ops, so a timer that already fired cannot `removeItem` the
|
|
1006
|
+
* slot the live queue owns. Anything still buffered in memory at that point stays on disk under
|
|
1007
|
+
* the released key, which is exactly where the replacement queue looks for it.
|
|
1008
|
+
*/
|
|
1009
|
+
dispose(): void;
|
|
961
1010
|
};
|
|
962
1011
|
/** Test-only: forget every claimed queue key. A real RELAUNCH is a new process, so a test that
|
|
963
1012
|
* simulates one in-process must call this or its second queue reads as a concurrent sibling.
|
|
@@ -1349,6 +1398,12 @@ declare const resolveAutoDeviceKey: (opts?: ResolveAutoDeviceKeyOptions) => stri
|
|
|
1349
1398
|
*
|
|
1350
1399
|
* Never throws or rejects: a missing, hung, or rejecting adapter resolves to the in-memory id, and
|
|
1351
1400
|
* with no `storage` it resolves immediately (there is nothing to hydrate from).
|
|
1401
|
+
*
|
|
1402
|
+
* ⚠️ IT RETURNS A BARE STRING, so it CANNOT say whether the id survives the launch — a degraded
|
|
1403
|
+
* adapter resolves to the in-memory mint and reads identically to a persisted one. No kit surface
|
|
1404
|
+
* uses it any more (0.14.0 moved the two lifecycle hooks off it): a caller writing a cross-launch
|
|
1405
|
+
* join key wants {@link hydrateDeviceIdentity} and its `durable` flag. Kept as public API for a host
|
|
1406
|
+
* that only wants "the id", never as the way to decide whether to stamp one.
|
|
1352
1407
|
*/
|
|
1353
1408
|
declare const hydrateAutoDeviceKey: (opts?: ResolveAutoDeviceKeyOptions) => Promise<string>;
|
|
1354
1409
|
/**
|
|
@@ -472,10 +472,11 @@ type OnboardingResult = {
|
|
|
472
472
|
/** The raw message thread, for custom downstream parsing. */
|
|
473
473
|
raw: Message[];
|
|
474
474
|
/**
|
|
475
|
-
* The backend's onboarding plan, when
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
* byte-identically what it
|
|
475
|
+
* The backend's onboarding plan, present when the backend sent one — the kit never infers it
|
|
476
|
+
* from which flow ran. Whether a plan arrives is the backend's configuration, not the kit's. Any
|
|
477
|
+
* run the server finished without a plan leaves this `undefined` AND leaves the key off the
|
|
478
|
+
* result object entirely — so a host written before plans existed sees byte-identically what it
|
|
479
|
+
* always saw.
|
|
479
480
|
*
|
|
480
481
|
* ⚠️ The kit does NOT interpret this and does NOT validate it. It checks one structural fact (a
|
|
481
482
|
* plan is an object) and hands the payload straight through, unread, unlogged, and never attached
|
|
@@ -484,6 +485,16 @@ type OnboardingResult = {
|
|
|
484
485
|
* the host's decision, not the kit's.
|
|
485
486
|
*/
|
|
486
487
|
plan?: unknown;
|
|
488
|
+
/**
|
|
489
|
+
* The experiment ARM the backend assigned this session, when it is running one. Absent when
|
|
490
|
+
* the tenant runs no experiment, which is the common case, and absent is NOT an error.
|
|
491
|
+
* The kit does NOT interpret it, does not log it, does not brand it and never attaches it
|
|
492
|
+
* to an analytics event. What an arm key MEANS is the host's decision.
|
|
493
|
+
*
|
|
494
|
+
* Like {@link plan}, the KEY is set only when an arm was actually seen, so a run with no
|
|
495
|
+
* experiment leaves the result byte-identical to what every host already reads.
|
|
496
|
+
*/
|
|
497
|
+
variant?: string;
|
|
487
498
|
};
|
|
488
499
|
/**
|
|
489
500
|
* Lifecycle events emitted as the flow runs, for host-side analytics. The kit owns
|
|
@@ -495,7 +506,11 @@ type OnboardingResult = {
|
|
|
495
506
|
* - `resumed`: a persisted session was restored after an app kill (fires INSTEAD of
|
|
496
507
|
* `started`, so host funnels don't double-count the same session). Also carries
|
|
497
508
|
* `contextId`. Requires the `storage` prop.
|
|
498
|
-
* - `turn`: a new assistant card arrived (`step` = 1-based index of cards seen).
|
|
509
|
+
* - `turn`: a new assistant card arrived (`step` = 1-based index of cards seen). Carries
|
|
510
|
+
* `variant`, the backend's experiment arm for this session, from the first card that
|
|
511
|
+
* declared one onwards — this is how the arm is available DURING the flow rather than
|
|
512
|
+
* only at completion. The key is absent whenever no arm has been seen, which is every
|
|
513
|
+
* turn of every tenant running no experiment.
|
|
499
514
|
* - `error`: the backend errored or the first-card watchdog timed out.
|
|
500
515
|
* - `retry`: a transient failure is being auto-retried (`attempt` = 1-based).
|
|
501
516
|
* - `fallback`: retries are exhausted; the kit degraded to the static `fallbackFlow`
|
|
@@ -516,6 +531,7 @@ type OnboardingEvent = {
|
|
|
516
531
|
type: "turn";
|
|
517
532
|
step: number;
|
|
518
533
|
component?: string;
|
|
534
|
+
variant?: string;
|
|
519
535
|
} | {
|
|
520
536
|
type: "error";
|
|
521
537
|
reason: "backend" | "timeout";
|
|
@@ -654,10 +670,19 @@ type WireOnboardingProps = {
|
|
|
654
670
|
*
|
|
655
671
|
* ```tsx
|
|
656
672
|
* <WireOnboarding userContext={activationJoinContext(deviceKey)} ... />
|
|
657
|
-
* // no device id of your own?
|
|
658
|
-
*
|
|
673
|
+
* // no device id of your own? pass `storage` and leave this prop alone — the kit injects its
|
|
674
|
+
* // own key, and only after it has confirmed the key actually persists (see `autoJoinKey`).
|
|
675
|
+
* <WireOnboarding config={{ ...config, storage }} ... />
|
|
659
676
|
* ```
|
|
660
677
|
*
|
|
678
|
+
* ⛔ Do NOT hand-build the auto key with `activationJoinContext(resolveAutoDeviceKey({...}))`.
|
|
679
|
+
* `resolveAutoDeviceKey` is SYNCHRONOUS by contract: it hands back a freshly minted id and adopts
|
|
680
|
+
* the persisted one a storage read later, and it cannot tell you whether the id survives the
|
|
681
|
+
* launch at all. A key that differs on every launch corrupts `min_sessions` rather than merely
|
|
682
|
+
* leaving the join empty. The auto-join path does the awaited, durability-checked read for you;
|
|
683
|
+
* a host that genuinely wants the value in hand should await `hydrateDeviceIdentity` and refuse a
|
|
684
|
+
* `durable: false` record, which is exactly what the kit does internally.
|
|
685
|
+
*
|
|
661
686
|
* SINCE 0.12.2, leaving it out no longer silently empties the funnel: when you pass `storage` and
|
|
662
687
|
* this prop carries no `device_key`, the kit injects its OWN per-install key — the same one the
|
|
663
688
|
* analytics surfaces mint and persist — so the default wiring joins. Anything you DO pass wins
|
|
@@ -790,6 +815,17 @@ type OnboardingProgress = {
|
|
|
790
815
|
slot_id?: string;
|
|
791
816
|
/** Whether the CURRENT screen may be skipped (backend-marked; default false → no Skip shown). */
|
|
792
817
|
skippable?: boolean;
|
|
818
|
+
/**
|
|
819
|
+
* The EXPERIMENT ARM the backend assigned this session, when the tenant is running one. Rides the
|
|
820
|
+
* render envelope as a sibling of {@link step}/{@link total}/{@link key}/{@link slot_id}, and is
|
|
821
|
+
* OMITTED entirely for a tenant running no experiment — which is the common case, and is not an
|
|
822
|
+
* error. The assignment is sticky for the session, so a later card that omits it does not
|
|
823
|
+
* un-assign it.
|
|
824
|
+
*
|
|
825
|
+
* The kit does NOT interpret this. It is whitelisted, latched and handed to the host exactly as
|
|
826
|
+
* received; what an arm key MEANS is the host's decision. See {@link OnboardingResult.variant}.
|
|
827
|
+
*/
|
|
828
|
+
variant?: string;
|
|
793
829
|
};
|
|
794
830
|
|
|
795
831
|
/**
|
|
@@ -958,6 +994,19 @@ type EventQueue = {
|
|
|
958
994
|
notifyOnline(): void;
|
|
959
995
|
/** Current pending (in-memory) count. */
|
|
960
996
|
size(): number;
|
|
997
|
+
/**
|
|
998
|
+
* Tear this queue down when its owner goes away (a hook's effect cleanup, a host disposing its
|
|
999
|
+
* own instance). Idempotent, never throws, and REQUIRED for any queue that can be re-created:
|
|
1000
|
+
* a remount builds a second queue while the first is still holding the storage claim and a live
|
|
1001
|
+
* backoff timer, and the two then fight over one persisted slot.
|
|
1002
|
+
*
|
|
1003
|
+
* It clears the retry timer, releases the claimed storage key so a replacement gets the SAME slot
|
|
1004
|
+
* instead of a rotated `…#2` nobody reads next launch, and makes the queue inert — `enqueue`,
|
|
1005
|
+
* `flush` and every write become no-ops, so a timer that already fired cannot `removeItem` the
|
|
1006
|
+
* slot the live queue owns. Anything still buffered in memory at that point stays on disk under
|
|
1007
|
+
* the released key, which is exactly where the replacement queue looks for it.
|
|
1008
|
+
*/
|
|
1009
|
+
dispose(): void;
|
|
961
1010
|
};
|
|
962
1011
|
/** Test-only: forget every claimed queue key. A real RELAUNCH is a new process, so a test that
|
|
963
1012
|
* simulates one in-process must call this or its second queue reads as a concurrent sibling.
|
|
@@ -1349,6 +1398,12 @@ declare const resolveAutoDeviceKey: (opts?: ResolveAutoDeviceKeyOptions) => stri
|
|
|
1349
1398
|
*
|
|
1350
1399
|
* Never throws or rejects: a missing, hung, or rejecting adapter resolves to the in-memory id, and
|
|
1351
1400
|
* with no `storage` it resolves immediately (there is nothing to hydrate from).
|
|
1401
|
+
*
|
|
1402
|
+
* ⚠️ IT RETURNS A BARE STRING, so it CANNOT say whether the id survives the launch — a degraded
|
|
1403
|
+
* adapter resolves to the in-memory mint and reads identically to a persisted one. No kit surface
|
|
1404
|
+
* uses it any more (0.14.0 moved the two lifecycle hooks off it): a caller writing a cross-launch
|
|
1405
|
+
* join key wants {@link hydrateDeviceIdentity} and its `durable` flag. Kept as public API for a host
|
|
1406
|
+
* that only wants "the id", never as the way to decide whether to stamp one.
|
|
1352
1407
|
*/
|
|
1353
1408
|
declare const hydrateAutoDeviceKey: (opts?: ResolveAutoDeviceKeyOptions) => Promise<string>;
|
|
1354
1409
|
/**
|
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 { I as WireOnboardingProps, J as WireOnboardingConfig, O as OnboardingResult, K as WirePermissionStatus, P as PermissionStage, L as WirePermissionOutcome, S as StepValidator, M as OnboardingEvent, N as OnboardingCopy, C as ClientEventTarget, Q as DeviceContext, T as PermissionScreenConfig, W as WireUserContext,
|
|
4
|
-
export { A as AUTO_DEVICE_ID_PREFIX, a as AnalyticsEvent, b as ClearUserContextOptions, d as ClientEventType, V as DEFAULT_PERMISSION_COPY, X as DeviceFormFactor, D as DeviceKeyStorage, Y as EXTRA_KEY_PREFIX, Z as GENERIC_PERMISSION_COPY, _ as IdentifyOnboardingBinding, $ as IdentifyOnboardingOptions, a0 as IdentityRecord, a1 as IdentitySource, a2 as IdentitySpace, a3 as NOTIFICATIONS_PERMISSION_COPY, a4 as OnboardingProgress, a5 as PermissionScreenCopy, R as ResolveAutoDeviceKeyOptions, a6 as ResolveUserContextOptions, a7 as ResolvedUserContext, a8 as USER_ID_MAX_LENGTH, i as WIRE_ONBOARDING_EVENTS, a9 as WIRE_PERMISSION_EVENTS, j as WireOnboardingEventName, aa as WirePermissionEventName, ab as WirePermissionKind, ac as activationJoinContext, k as analyticsUserIdStorageKey, m as clearPiiFromContext, n as clearUserContext, ad as collectDeviceContext, p as deviceIdStorageKey, q as ensureCurrentSessionId, r as getCurrentSessionId, ae as hashEmailFnv1a, af as hostIdentity, ag as hydrateAutoDeviceKey, ah as hydrateDeviceIdentity, ai as identifyOnboarding, aj as isWireScalar, s as looksLikeEmail, t as makeSessionId, ak as mintDeviceId, al as namespaceExtra, am as normalizePermissionStatus, an as permissionEventName, ao as permissionEventProps, u as reportClientEvent, v as reportClientEventAwait, w as reportClientEvents, x as reportClientEventsAwait, y as resetAutoDeviceKeys, z as resetCurrentSessionId, ap as resetIdentityProvenance, F as resolveAutoDeviceKey, aq as resolveIdentity, ar as resolvePermissionCopy, as as resolveUserContext, at as sanitizeUserId, G as setCurrentSessionId, H as toAnalyticsEvent } from './currentSession-
|
|
3
|
+
import { I as WireOnboardingProps, J as WireOnboardingConfig, O as OnboardingResult, K as WirePermissionStatus, P as PermissionStage, L as WirePermissionOutcome, S as StepValidator, M as OnboardingEvent, N as OnboardingCopy, C as ClientEventTarget, Q as DeviceContext, T as PermissionScreenConfig, W as WireUserContext, c as ClientEvent, U as PermissionPlacement, g as EnvelopeSource } from './currentSession-CUvTOchb.mjs';
|
|
4
|
+
export { A as AUTO_DEVICE_ID_PREFIX, a as AnalyticsEvent, b as ClearUserContextOptions, d as ClientEventType, V as DEFAULT_PERMISSION_COPY, X as DeviceFormFactor, D as DeviceKeyStorage, Y as EXTRA_KEY_PREFIX, Z as GENERIC_PERMISSION_COPY, _ as IdentifyOnboardingBinding, $ as IdentifyOnboardingOptions, a0 as IdentityRecord, a1 as IdentitySource, a2 as IdentitySpace, a3 as NOTIFICATIONS_PERMISSION_COPY, a4 as OnboardingProgress, a5 as PermissionScreenCopy, R as ResolveAutoDeviceKeyOptions, a6 as ResolveUserContextOptions, a7 as ResolvedUserContext, a8 as USER_ID_MAX_LENGTH, i as WIRE_ONBOARDING_EVENTS, a9 as WIRE_PERMISSION_EVENTS, j as WireOnboardingEventName, aa as WirePermissionEventName, ab as WirePermissionKind, ac as activationJoinContext, k as analyticsUserIdStorageKey, m as clearPiiFromContext, n as clearUserContext, ad as collectDeviceContext, p as deviceIdStorageKey, q as ensureCurrentSessionId, r as getCurrentSessionId, ae as hashEmailFnv1a, af as hostIdentity, ag as hydrateAutoDeviceKey, ah as hydrateDeviceIdentity, ai as identifyOnboarding, aj as isWireScalar, s as looksLikeEmail, t as makeSessionId, ak as mintDeviceId, al as namespaceExtra, am as normalizePermissionStatus, an as permissionEventName, ao as permissionEventProps, u as reportClientEvent, v as reportClientEventAwait, w as reportClientEvents, x as reportClientEventsAwait, y as resetAutoDeviceKeys, z as resetCurrentSessionId, ap as resetIdentityProvenance, F as resolveAutoDeviceKey, aq as resolveIdentity, ar as resolvePermissionCopy, as as resolveUserContext, at as sanitizeUserId, G as setCurrentSessionId, H as toAnalyticsEvent } from './currentSession-CUvTOchb.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';
|
|
@@ -1286,6 +1286,8 @@ type PartialProgress = {
|
|
|
1286
1286
|
/** The stable per-slot identity, when the backend sends one. See `OnboardingProgress.slot_id`. */
|
|
1287
1287
|
slot_id?: string;
|
|
1288
1288
|
skippable?: boolean;
|
|
1289
|
+
/** The experiment arm assigned to this session, when the tenant runs one. See `OnboardingProgress.variant`. */
|
|
1290
|
+
variant?: string;
|
|
1289
1291
|
};
|
|
1290
1292
|
declare const readProgress: (response?: WireAIResponse) => PartialProgress;
|
|
1291
1293
|
|
|
@@ -1570,6 +1572,15 @@ type WireActivationConfig = {
|
|
|
1570
1572
|
appVersion?: string;
|
|
1571
1573
|
/** Host persistence (AsyncStorage-compatible subset) so the auto-minted device key survives launches. */
|
|
1572
1574
|
storage?: WireOnboardingStorage;
|
|
1575
|
+
/**
|
|
1576
|
+
* Where a FAILED `track()` goes instead of being dropped: your existing offline queue's `enqueue`
|
|
1577
|
+
* (the same wiring `useLifecycleEvents` takes). Pass it when you already run one queue for the app
|
|
1578
|
+
* and you want one backlog, one retry schedule, one storage slot.
|
|
1579
|
+
*
|
|
1580
|
+
* Omit it and the instance opens its OWN queue the first time a POST fails — never before, so an
|
|
1581
|
+
* app that is online the whole time allocates nothing. A successful `track()` never touches either.
|
|
1582
|
+
*/
|
|
1583
|
+
sink?: (event: ClientEvent) => void;
|
|
1573
1584
|
};
|
|
1574
1585
|
/** The kit-owned activation surface. `sessionId` is a live getter (reads `getCurrentSessionId()`). */
|
|
1575
1586
|
type WireActivation = {
|
|
@@ -1592,6 +1603,12 @@ type WireActivation = {
|
|
|
1592
1603
|
subscribeRevalidation(listener: () => void): () => void;
|
|
1593
1604
|
/** The current revalidation version — include in a decision-fetch effect's deps to re-fetch on bump. */
|
|
1594
1605
|
getRevalidationVersion(): number;
|
|
1606
|
+
/**
|
|
1607
|
+
* Tear down the durability queue a failed `track()` may have opened (see
|
|
1608
|
+
* {@link EventQueue.dispose}). Idempotent, never throws, and a no-op on an instance that never had
|
|
1609
|
+
* a failure. Call it when you build an instance per mount; `useWireActivation` does it for you.
|
|
1610
|
+
*/
|
|
1611
|
+
dispose(): void;
|
|
1595
1612
|
};
|
|
1596
1613
|
/**
|
|
1597
1614
|
* Create a bound activation instance for a tenant transport. Resolves the device key once (explicit >
|
|
@@ -2031,8 +2048,9 @@ interface SessionStartConfig {
|
|
|
2031
2048
|
appVersion?: string;
|
|
2032
2049
|
/** Tenant/app id — namespaces the auto `device_key` fallback below. */
|
|
2033
2050
|
appId?: string;
|
|
2034
|
-
/** Host storage (AsyncStorage subset). Present → `app.session_started`
|
|
2035
|
-
* persisted auto `device_key` when the host passes none. Absent
|
|
2051
|
+
/** Host storage (AsyncStorage subset). Present AND actually persisting → `app.session_started`
|
|
2052
|
+
* falls back to the kit's persisted auto `device_key` when the host passes none. Absent, or an
|
|
2053
|
+
* adapter that throws / rejects → no fallback (a per-launch key is worse than none, see below). */
|
|
2036
2054
|
storage?: WireOnboardingStorage;
|
|
2037
2055
|
}
|
|
2038
2056
|
/** Per-open identity the host supplies. All optional: a pre-auth open is device-only. */
|
|
@@ -2165,8 +2183,10 @@ interface LifecycleConfig {
|
|
|
2165
2183
|
appVersion?: string;
|
|
2166
2184
|
/** Tenant/app id — namespaces the first-open flag AND the hook's internal queue storage key. */
|
|
2167
2185
|
appId?: string;
|
|
2168
|
-
/** Host storage (AsyncStorage subset). Enables the persisted once-ever first-open flag
|
|
2169
|
-
* offline durability of the hook's internal queue
|
|
2186
|
+
/** Host storage (AsyncStorage subset). Enables the persisted once-ever first-open flag, the
|
|
2187
|
+
* offline durability of the hook's internal queue, AND the auto `device_key` fallback — the last
|
|
2188
|
+
* one only when the adapter actually persists (one that throws or rejects gets no fallback, the
|
|
2189
|
+
* same verdict as no storage at all). Omit it and all three degrade to in-memory. */
|
|
2170
2190
|
storage?: WireOnboardingStorage;
|
|
2171
2191
|
}
|
|
2172
2192
|
/** Per-open identity + wiring the host supplies. All optional: a pre-auth open is device-only. */
|
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 { I as WireOnboardingProps, J as WireOnboardingConfig, O as OnboardingResult, K as WirePermissionStatus, P as PermissionStage, L as WirePermissionOutcome, S as StepValidator, M as OnboardingEvent, N as OnboardingCopy, C as ClientEventTarget, Q as DeviceContext, T as PermissionScreenConfig, W as WireUserContext,
|
|
4
|
-
export { A as AUTO_DEVICE_ID_PREFIX, a as AnalyticsEvent, b as ClearUserContextOptions, d as ClientEventType, V as DEFAULT_PERMISSION_COPY, X as DeviceFormFactor, D as DeviceKeyStorage, Y as EXTRA_KEY_PREFIX, Z as GENERIC_PERMISSION_COPY, _ as IdentifyOnboardingBinding, $ as IdentifyOnboardingOptions, a0 as IdentityRecord, a1 as IdentitySource, a2 as IdentitySpace, a3 as NOTIFICATIONS_PERMISSION_COPY, a4 as OnboardingProgress, a5 as PermissionScreenCopy, R as ResolveAutoDeviceKeyOptions, a6 as ResolveUserContextOptions, a7 as ResolvedUserContext, a8 as USER_ID_MAX_LENGTH, i as WIRE_ONBOARDING_EVENTS, a9 as WIRE_PERMISSION_EVENTS, j as WireOnboardingEventName, aa as WirePermissionEventName, ab as WirePermissionKind, ac as activationJoinContext, k as analyticsUserIdStorageKey, m as clearPiiFromContext, n as clearUserContext, ad as collectDeviceContext, p as deviceIdStorageKey, q as ensureCurrentSessionId, r as getCurrentSessionId, ae as hashEmailFnv1a, af as hostIdentity, ag as hydrateAutoDeviceKey, ah as hydrateDeviceIdentity, ai as identifyOnboarding, aj as isWireScalar, s as looksLikeEmail, t as makeSessionId, ak as mintDeviceId, al as namespaceExtra, am as normalizePermissionStatus, an as permissionEventName, ao as permissionEventProps, u as reportClientEvent, v as reportClientEventAwait, w as reportClientEvents, x as reportClientEventsAwait, y as resetAutoDeviceKeys, z as resetCurrentSessionId, ap as resetIdentityProvenance, F as resolveAutoDeviceKey, aq as resolveIdentity, ar as resolvePermissionCopy, as as resolveUserContext, at as sanitizeUserId, G as setCurrentSessionId, H as toAnalyticsEvent } from './currentSession-
|
|
3
|
+
import { I as WireOnboardingProps, J as WireOnboardingConfig, O as OnboardingResult, K as WirePermissionStatus, P as PermissionStage, L as WirePermissionOutcome, S as StepValidator, M as OnboardingEvent, N as OnboardingCopy, C as ClientEventTarget, Q as DeviceContext, T as PermissionScreenConfig, W as WireUserContext, c as ClientEvent, U as PermissionPlacement, g as EnvelopeSource } from './currentSession-CW_5Mq4O.js';
|
|
4
|
+
export { A as AUTO_DEVICE_ID_PREFIX, a as AnalyticsEvent, b as ClearUserContextOptions, d as ClientEventType, V as DEFAULT_PERMISSION_COPY, X as DeviceFormFactor, D as DeviceKeyStorage, Y as EXTRA_KEY_PREFIX, Z as GENERIC_PERMISSION_COPY, _ as IdentifyOnboardingBinding, $ as IdentifyOnboardingOptions, a0 as IdentityRecord, a1 as IdentitySource, a2 as IdentitySpace, a3 as NOTIFICATIONS_PERMISSION_COPY, a4 as OnboardingProgress, a5 as PermissionScreenCopy, R as ResolveAutoDeviceKeyOptions, a6 as ResolveUserContextOptions, a7 as ResolvedUserContext, a8 as USER_ID_MAX_LENGTH, i as WIRE_ONBOARDING_EVENTS, a9 as WIRE_PERMISSION_EVENTS, j as WireOnboardingEventName, aa as WirePermissionEventName, ab as WirePermissionKind, ac as activationJoinContext, k as analyticsUserIdStorageKey, m as clearPiiFromContext, n as clearUserContext, ad as collectDeviceContext, p as deviceIdStorageKey, q as ensureCurrentSessionId, r as getCurrentSessionId, ae as hashEmailFnv1a, af as hostIdentity, ag as hydrateAutoDeviceKey, ah as hydrateDeviceIdentity, ai as identifyOnboarding, aj as isWireScalar, s as looksLikeEmail, t as makeSessionId, ak as mintDeviceId, al as namespaceExtra, am as normalizePermissionStatus, an as permissionEventName, ao as permissionEventProps, u as reportClientEvent, v as reportClientEventAwait, w as reportClientEvents, x as reportClientEventsAwait, y as resetAutoDeviceKeys, z as resetCurrentSessionId, ap as resetIdentityProvenance, F as resolveAutoDeviceKey, aq as resolveIdentity, ar as resolvePermissionCopy, as as resolveUserContext, at as sanitizeUserId, G as setCurrentSessionId, H as toAnalyticsEvent } from './currentSession-CW_5Mq4O.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';
|
|
@@ -1286,6 +1286,8 @@ type PartialProgress = {
|
|
|
1286
1286
|
/** The stable per-slot identity, when the backend sends one. See `OnboardingProgress.slot_id`. */
|
|
1287
1287
|
slot_id?: string;
|
|
1288
1288
|
skippable?: boolean;
|
|
1289
|
+
/** The experiment arm assigned to this session, when the tenant runs one. See `OnboardingProgress.variant`. */
|
|
1290
|
+
variant?: string;
|
|
1289
1291
|
};
|
|
1290
1292
|
declare const readProgress: (response?: WireAIResponse) => PartialProgress;
|
|
1291
1293
|
|
|
@@ -1570,6 +1572,15 @@ type WireActivationConfig = {
|
|
|
1570
1572
|
appVersion?: string;
|
|
1571
1573
|
/** Host persistence (AsyncStorage-compatible subset) so the auto-minted device key survives launches. */
|
|
1572
1574
|
storage?: WireOnboardingStorage;
|
|
1575
|
+
/**
|
|
1576
|
+
* Where a FAILED `track()` goes instead of being dropped: your existing offline queue's `enqueue`
|
|
1577
|
+
* (the same wiring `useLifecycleEvents` takes). Pass it when you already run one queue for the app
|
|
1578
|
+
* and you want one backlog, one retry schedule, one storage slot.
|
|
1579
|
+
*
|
|
1580
|
+
* Omit it and the instance opens its OWN queue the first time a POST fails — never before, so an
|
|
1581
|
+
* app that is online the whole time allocates nothing. A successful `track()` never touches either.
|
|
1582
|
+
*/
|
|
1583
|
+
sink?: (event: ClientEvent) => void;
|
|
1573
1584
|
};
|
|
1574
1585
|
/** The kit-owned activation surface. `sessionId` is a live getter (reads `getCurrentSessionId()`). */
|
|
1575
1586
|
type WireActivation = {
|
|
@@ -1592,6 +1603,12 @@ type WireActivation = {
|
|
|
1592
1603
|
subscribeRevalidation(listener: () => void): () => void;
|
|
1593
1604
|
/** The current revalidation version — include in a decision-fetch effect's deps to re-fetch on bump. */
|
|
1594
1605
|
getRevalidationVersion(): number;
|
|
1606
|
+
/**
|
|
1607
|
+
* Tear down the durability queue a failed `track()` may have opened (see
|
|
1608
|
+
* {@link EventQueue.dispose}). Idempotent, never throws, and a no-op on an instance that never had
|
|
1609
|
+
* a failure. Call it when you build an instance per mount; `useWireActivation` does it for you.
|
|
1610
|
+
*/
|
|
1611
|
+
dispose(): void;
|
|
1595
1612
|
};
|
|
1596
1613
|
/**
|
|
1597
1614
|
* Create a bound activation instance for a tenant transport. Resolves the device key once (explicit >
|
|
@@ -2031,8 +2048,9 @@ interface SessionStartConfig {
|
|
|
2031
2048
|
appVersion?: string;
|
|
2032
2049
|
/** Tenant/app id — namespaces the auto `device_key` fallback below. */
|
|
2033
2050
|
appId?: string;
|
|
2034
|
-
/** Host storage (AsyncStorage subset). Present → `app.session_started`
|
|
2035
|
-
* persisted auto `device_key` when the host passes none. Absent
|
|
2051
|
+
/** Host storage (AsyncStorage subset). Present AND actually persisting → `app.session_started`
|
|
2052
|
+
* falls back to the kit's persisted auto `device_key` when the host passes none. Absent, or an
|
|
2053
|
+
* adapter that throws / rejects → no fallback (a per-launch key is worse than none, see below). */
|
|
2036
2054
|
storage?: WireOnboardingStorage;
|
|
2037
2055
|
}
|
|
2038
2056
|
/** Per-open identity the host supplies. All optional: a pre-auth open is device-only. */
|
|
@@ -2165,8 +2183,10 @@ interface LifecycleConfig {
|
|
|
2165
2183
|
appVersion?: string;
|
|
2166
2184
|
/** Tenant/app id — namespaces the first-open flag AND the hook's internal queue storage key. */
|
|
2167
2185
|
appId?: string;
|
|
2168
|
-
/** Host storage (AsyncStorage subset). Enables the persisted once-ever first-open flag
|
|
2169
|
-
* offline durability of the hook's internal queue
|
|
2186
|
+
/** Host storage (AsyncStorage subset). Enables the persisted once-ever first-open flag, the
|
|
2187
|
+
* offline durability of the hook's internal queue, AND the auto `device_key` fallback — the last
|
|
2188
|
+
* one only when the adapter actually persists (one that throws or rejects gets no fallback, the
|
|
2189
|
+
* same verdict as no storage at all). Omit it and all three degrade to in-memory. */
|
|
2170
2190
|
storage?: WireOnboardingStorage;
|
|
2171
2191
|
}
|
|
2172
2192
|
/** Per-open identity + wiring the host supplies. All optional: a pre-auth open is device-only. */
|