@wireai/activation 0.13.2 → 0.13.5
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 +6 -3
- package/CHANGELOG.md +291 -4
- package/INTEGRATION_PROMPT.md +7 -1
- package/README.md +68 -2
- package/dist/analytics/index.d.mts +86 -6
- package/dist/analytics/index.d.ts +86 -6
- package/dist/analytics/index.js +271 -472
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +269 -471
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/coachmarks/index.d.mts +15 -2
- package/dist/coachmarks/index.d.ts +15 -2
- package/dist/coachmarks/index.js +58 -14
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs +58 -14
- package/dist/coachmarks/index.mjs.map +1 -1
- package/dist/{currentSession-ClkLjcJ0.d.mts → currentSession-DgJf0fRz.d.mts} +4 -4
- package/dist/{currentSession-DOVZEWJl.d.ts → currentSession-EOHU64QD.d.ts} +4 -4
- package/dist/{decision-Bl_M2y3r.d.mts → decision-Bgo17oH7.d.mts} +1 -1
- package/dist/{decision-Cau5KmP6.d.ts → decision-Bkh_LigV.d.ts} +1 -1
- package/dist/index.d.mts +27 -4
- package/dist/index.d.ts +27 -4
- package/dist/index.js +224 -575
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +221 -572
- package/dist/index.mjs.map +1 -1
- package/dist/questionnaire/index.d.mts +43 -11
- package/dist/questionnaire/index.d.ts +43 -11
- package/dist/questionnaire/index.js +45 -13
- package/dist/questionnaire/index.js.map +1 -1
- package/dist/questionnaire/index.mjs +45 -13
- package/dist/questionnaire/index.mjs.map +1 -1
- package/dist/reviews/index.d.mts +5 -5
- package/dist/reviews/index.d.ts +5 -5
- package/dist/reviews/index.js +31 -9
- package/dist/reviews/index.js.map +1 -1
- package/dist/reviews/index.mjs +31 -9
- package/dist/reviews/index.mjs.map +1 -1
- package/dist/showcase/index.d.mts +1 -1
- package/dist/showcase/index.d.ts +1 -1
- package/dist/showcase/index.js +7 -2
- package/dist/showcase/index.js.map +1 -1
- package/dist/showcase/index.mjs +7 -2
- package/dist/showcase/index.mjs.map +1 -1
- package/dist/{transport-CF_eHwzC.d.mts → transport-B_0SgCBe.d.ts} +44 -5
- package/dist/{transport-DsRe4epC.d.ts → transport-j5gFfJhK.d.mts} +44 -5
- package/dist/{types-CKFhyrMu.d.mts → types-BpwiRpA8.d.mts} +1 -1
- package/dist/{types-CKFhyrMu.d.ts → types-BpwiRpA8.d.ts} +1 -1
- package/dist/{types-CNUqMK0D.d.mts → types-Cju-1_jT.d.mts} +42 -2
- package/dist/{types-Buj9Lw9t.d.ts → types-h2BZvl1t.d.ts} +42 -2
- package/llms.txt +1 -1
- package/package.json +6 -1
- package/src/OnboardingFlow.tsx +44 -15
- package/src/WireOnboarding.tsx +7 -6
- package/src/activation/revalidation.ts +9 -1
- package/src/activation/wireActivation.ts +3 -3
- package/src/analytics/analyticsFacade.ts +2 -2
- package/src/analytics/currentSession.ts +10 -0
- package/src/analytics/eventQueue.ts +88 -20
- package/src/analytics/index.ts +6 -0
- package/src/analytics/reportClientEvent.ts +29 -7
- package/src/analytics/wireDoctor.ts +330 -0
- package/src/cards/CardGridSelectCard.tsx +1 -1
- package/src/cards/ChipSelectCard.tsx +2 -2
- package/src/cards/SelectionCard.tsx +1 -1
- package/src/coachmarks/runtime.ts +72 -3
- package/src/coachmarks/useCoachmarkTour.ts +62 -14
- package/src/context/deviceId.ts +14 -5
- package/src/features/WireFeaturesProvider.tsx +12 -1
- package/src/identity/identityRecord.ts +9 -1
- package/src/identity/userIdentity.ts +1 -1
- package/src/questionnaire/QuestionnaireGate.tsx +90 -10
- package/src/questionnaire/index.ts +9 -1
- package/src/questionnaire/transport.ts +46 -11
- package/src/reviews/ReviewGate.tsx +61 -6
- package/src/reviews/index.ts +10 -1
- package/src/reviews/runtime.ts +11 -1
- package/src/reviews/transport.ts +58 -12
- package/src/session-analytics/useLifecycleEvents.ts +1 -1
- package/src/theme/ThemeContext.tsx +49 -1
- package/src/types.ts +1 -1
- package/src/utils/submitResult.ts +39 -0
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import * as wireai_rn from 'wireai-rn';
|
|
3
3
|
import { Message } from 'wireai-rn';
|
|
4
4
|
import { O as OnboardingTheme } from './types-BKfpdZzX.js';
|
|
5
|
-
import {
|
|
5
|
+
import { W as WireOnboardingStorage } from './types-BpwiRpA8.js';
|
|
6
6
|
import { Platform } from 'react-native';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -767,7 +767,7 @@ type OnboardingProgress = {
|
|
|
767
767
|
* `answers.interests` silently becomes `answers.what_are_you_into_v2`, with no error anywhere. A
|
|
768
768
|
* slot is the question's identity independent of its wording.
|
|
769
769
|
*
|
|
770
|
-
* FULLY ADDITIVE, AND LIVE SINCE 2026-07-28
|
|
770
|
+
* FULLY ADDITIVE, AND LIVE SINCE 2026-07-28. The deployed server sends it on
|
|
771
771
|
* `progress` for every AI-GENERATED question, as `adaptive_<n>` 1-based over adaptive answers, and
|
|
772
772
|
* for a CONFIGURED question only when the tenant set one. Where the tenant set none the field is
|
|
773
773
|
* simply absent. Every fallback is PER-CARD, so a thread that mixes slotted and unslotted cards
|
|
@@ -1342,7 +1342,7 @@ declare const hydrateAutoDeviceKey: (opts?: ResolveAutoDeviceKeyOptions) => Prom
|
|
|
1342
1342
|
* The PROVENANCE-CARRYING sibling of {@link hydrateAutoDeviceKey}: the same awaited read, but it
|
|
1343
1343
|
* answers "is this id one this install will KEEP?" instead of only "what is the id?".
|
|
1344
1344
|
*
|
|
1345
|
-
* WHY IT EXISTS
|
|
1345
|
+
* WHY IT EXISTS. `<WireOnboarding>` gated auto-injection on `Boolean(storage)` — the presence of
|
|
1346
1346
|
* the prop — because a string carries no provenance and there was nothing better to gate on. A
|
|
1347
1347
|
* REJECTING adapter therefore injected a fresh `wdev_*` on every launch: strictly worse than
|
|
1348
1348
|
* injecting nothing, since the server counts `min_sessions` by distinct opens grouped on `device_key`,
|
|
@@ -1385,4 +1385,4 @@ declare const resetCurrentSessionId: () => void;
|
|
|
1385
1385
|
*/
|
|
1386
1386
|
declare const ensureCurrentSessionId: () => string;
|
|
1387
1387
|
|
|
1388
|
-
export { type IdentifyOnboardingOptions as $, AUTO_DEVICE_ID_PREFIX as A, resetEventQueueKeys as B, type
|
|
1388
|
+
export { type IdentifyOnboardingOptions as $, AUTO_DEVICE_ID_PREFIX as A, resetEventQueueKeys as B, type ClientEventTarget as C, type DeviceKeyStorage as D, type EventQueueOptions as E, resolveAutoDeviceKey as F, setCurrentSessionId as G, toAnalyticsEvent as H, type WireOnboardingProps as I, type WireOnboardingConfig as J, type WirePermissionStatus as K, type WirePermissionOutcome as L, type OnboardingEvent as M, type OnboardingCopy as N, type OnboardingResult as O, type PermissionStage as P, type DeviceContext as Q, type ResolveAutoDeviceKeyOptions as R, type StepValidator as S, type PermissionScreenConfig as T, type PermissionPlacement as U, DEFAULT_PERMISSION_COPY as V, type WireUserContext as W, type DeviceFormFactor as X, EXTRA_KEY_PREFIX as Y, GENERIC_PERMISSION_COPY as Z, type IdentifyOnboardingBinding as _, type AnalyticsEvent as a, type IdentityRecord as a0, type IdentitySource as a1, type IdentitySpace as a2, NOTIFICATIONS_PERMISSION_COPY as a3, type OnboardingProgress as a4, type PermissionScreenCopy as a5, type ResolveUserContextOptions as a6, type ResolvedUserContext as a7, USER_ID_MAX_LENGTH as a8, WIRE_PERMISSION_EVENTS as a9, type WirePermissionEventName as aa, type WirePermissionKind as ab, activationJoinContext as ac, collectDeviceContext as ad, hashEmailFnv1a as ae, hostIdentity as af, hydrateAutoDeviceKey as ag, hydrateDeviceIdentity as ah, identifyOnboarding as ai, isWireScalar as aj, mintDeviceId as ak, namespaceExtra as al, normalizePermissionStatus as am, permissionEventName as an, permissionEventProps as ao, resetIdentityProvenance as ap, resolveIdentity as aq, resolvePermissionCopy as ar, resolveUserContext as as, sanitizeUserId as at, type ClearUserContextOptions as b, type ClientEvent as c, type ClientEventType as d, type ContextEnvelope as e, type ContextEnvelopeInput as f, type EnvelopeSource as g, type EventQueue as h, WIRE_ONBOARDING_EVENTS as i, type WireOnboardingEventName as j, analyticsUserIdStorageKey as k, buildContextEnvelope as l, clearPiiFromContext as m, clearUserContext as n, createEventQueue as o, deviceIdStorageKey as p, ensureCurrentSessionId as q, getCurrentSessionId as r, looksLikeEmail as s, makeSessionId as t, reportClientEvent as u, reportClientEventAwait as v, reportClientEvents as w, reportClientEventsAwait as x, resetAutoDeviceKeys as y, resetCurrentSessionId as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as ReviewDecision, j as ReviewSubmission, e as RatingRoute } from './types-
|
|
1
|
+
import { c as ReviewDecision, j as ReviewSubmission, e as RatingRoute } from './types-Cju-1_jT.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* decision.ts — the pure decision logic for the review gate.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as ReviewDecision, j as ReviewSubmission, e as RatingRoute } from './types-
|
|
1
|
+
import { c as ReviewDecision, j as ReviewSubmission, e as RatingRoute } from './types-h2BZvl1t.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* decision.ts — the pure decision logic for the review gate.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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,
|
|
4
|
-
export { A as AUTO_DEVICE_ID_PREFIX, a as AnalyticsEvent,
|
|
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, U as PermissionPlacement, c as ClientEvent, g as EnvelopeSource } from './currentSession-DgJf0fRz.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-DgJf0fRz.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';
|
|
8
8
|
import { WireAIComponent, InjectedProps, Message, WireAIResponse } from 'wireai-rn';
|
|
9
|
-
import {
|
|
10
|
-
export { D as DEFAULT_SESSION_TTL_MS, L as LoadedSession, O as OnboardingMode, c as clearPersistedSession, l as loadPersistedSession, p as peekPersistedSession, s as savePersistedSession, d as sessionStorageKey } from './types-
|
|
9
|
+
import { b as WireFeaturesConfig, a as WireFeatures, W as WireOnboardingStorage } from './types-BpwiRpA8.mjs';
|
|
10
|
+
export { D as DEFAULT_SESSION_TTL_MS, L as LoadedSession, O as OnboardingMode, c as clearPersistedSession, l as loadPersistedSession, p as peekPersistedSession, s as savePersistedSession, d as sessionStorageKey } from './types-BpwiRpA8.mjs';
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import 'react-native';
|
|
13
13
|
|
|
@@ -48,6 +48,29 @@ declare function DemoOnboarding({ config, theme, illustrations, validators, copy
|
|
|
48
48
|
* themed card via `useOnboardingTheme()`. WHY a context rather than prop-drilling:
|
|
49
49
|
* the cards are mounted by the SDK's ComponentRenderer (not by us), so we can't
|
|
50
50
|
* pass them props directly — they must read the theme from context.
|
|
51
|
+
*
|
|
52
|
+
* ── WHY THE CONTEXT LIVES ON A `Symbol.for` SLOT ───────────────────────────────────────────────
|
|
53
|
+
*
|
|
54
|
+
* It was a plain `createContext(...)`, and tsup inlines this module into FIVE dist bundles
|
|
55
|
+
* (`.`, `./reviews`, `./questionnaire`, `./coachmarks`, `./showcase`) — so each one carried its own
|
|
56
|
+
* context instance. `OnboardingThemeProvider` is exported ONLY from the root barrel, so on any
|
|
57
|
+
* `dist` resolution path (plain RN CLI, `unstable_enablePackageExports: false`, node, jest, SSR) a
|
|
58
|
+
* host that wrapped its tree in `<OnboardingThemeProvider>` and rendered `<ReviewGate>` from
|
|
59
|
+
* `@wireai/activation/reviews` was writing one context and reading another. Nothing crashed and
|
|
60
|
+
* nothing warned: `useOnboardingTheme`'s `ctx ?? mergeTheme()` fallback quietly served the NEUTRAL
|
|
61
|
+
* default theme, so the tenant's brand simply did not apply to the gate. On-device this was masked
|
|
62
|
+
* only because Metro's `react-native` export condition collapses every subpath back to this one
|
|
63
|
+
* `src/` file — the same "bundler accident, not a guarantee" the `currentSession` header names, and
|
|
64
|
+
* the same root cause as the optional-peers bug 0.13.3 fixed.
|
|
65
|
+
*
|
|
66
|
+
* The bundler-agnostic fix, exactly as `coachmarks/runtime`, `analytics/currentSession`,
|
|
67
|
+
* `context/deviceId` and `features/WireFeaturesProvider` already do it: park the ONE context on a
|
|
68
|
+
* well-known `globalThis` slot keyed by `Symbol.for(...)`. `Symbol.for` uses the runtime-global
|
|
69
|
+
* symbol registry, so every inlined copy of this module resolves the SAME symbol, finds the slot
|
|
70
|
+
* already filled, and reuses that instance — one context identity however many copies exist.
|
|
71
|
+
* `globalThis` is present and identical in Hermes/React Native, Node and SSR (we never touch
|
|
72
|
+
* `window`), so this is safe on every host. `test/canary/themeContextIdentity.test.tsx` measures it
|
|
73
|
+
* in the BUILT artifact, because the defect is invisible in source.
|
|
51
74
|
*/
|
|
52
75
|
|
|
53
76
|
type OnboardingThemeProviderProps = {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
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,
|
|
4
|
-
export { A as AUTO_DEVICE_ID_PREFIX, a as AnalyticsEvent,
|
|
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, U as PermissionPlacement, c as ClientEvent, g as EnvelopeSource } from './currentSession-EOHU64QD.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-EOHU64QD.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';
|
|
8
8
|
import { WireAIComponent, InjectedProps, Message, WireAIResponse } from 'wireai-rn';
|
|
9
|
-
import {
|
|
10
|
-
export { D as DEFAULT_SESSION_TTL_MS, L as LoadedSession, O as OnboardingMode, c as clearPersistedSession, l as loadPersistedSession, p as peekPersistedSession, s as savePersistedSession, d as sessionStorageKey } from './types-
|
|
9
|
+
import { b as WireFeaturesConfig, a as WireFeatures, W as WireOnboardingStorage } from './types-BpwiRpA8.js';
|
|
10
|
+
export { D as DEFAULT_SESSION_TTL_MS, L as LoadedSession, O as OnboardingMode, c as clearPersistedSession, l as loadPersistedSession, p as peekPersistedSession, s as savePersistedSession, d as sessionStorageKey } from './types-BpwiRpA8.js';
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import 'react-native';
|
|
13
13
|
|
|
@@ -48,6 +48,29 @@ declare function DemoOnboarding({ config, theme, illustrations, validators, copy
|
|
|
48
48
|
* themed card via `useOnboardingTheme()`. WHY a context rather than prop-drilling:
|
|
49
49
|
* the cards are mounted by the SDK's ComponentRenderer (not by us), so we can't
|
|
50
50
|
* pass them props directly — they must read the theme from context.
|
|
51
|
+
*
|
|
52
|
+
* ── WHY THE CONTEXT LIVES ON A `Symbol.for` SLOT ───────────────────────────────────────────────
|
|
53
|
+
*
|
|
54
|
+
* It was a plain `createContext(...)`, and tsup inlines this module into FIVE dist bundles
|
|
55
|
+
* (`.`, `./reviews`, `./questionnaire`, `./coachmarks`, `./showcase`) — so each one carried its own
|
|
56
|
+
* context instance. `OnboardingThemeProvider` is exported ONLY from the root barrel, so on any
|
|
57
|
+
* `dist` resolution path (plain RN CLI, `unstable_enablePackageExports: false`, node, jest, SSR) a
|
|
58
|
+
* host that wrapped its tree in `<OnboardingThemeProvider>` and rendered `<ReviewGate>` from
|
|
59
|
+
* `@wireai/activation/reviews` was writing one context and reading another. Nothing crashed and
|
|
60
|
+
* nothing warned: `useOnboardingTheme`'s `ctx ?? mergeTheme()` fallback quietly served the NEUTRAL
|
|
61
|
+
* default theme, so the tenant's brand simply did not apply to the gate. On-device this was masked
|
|
62
|
+
* only because Metro's `react-native` export condition collapses every subpath back to this one
|
|
63
|
+
* `src/` file — the same "bundler accident, not a guarantee" the `currentSession` header names, and
|
|
64
|
+
* the same root cause as the optional-peers bug 0.13.3 fixed.
|
|
65
|
+
*
|
|
66
|
+
* The bundler-agnostic fix, exactly as `coachmarks/runtime`, `analytics/currentSession`,
|
|
67
|
+
* `context/deviceId` and `features/WireFeaturesProvider` already do it: park the ONE context on a
|
|
68
|
+
* well-known `globalThis` slot keyed by `Symbol.for(...)`. `Symbol.for` uses the runtime-global
|
|
69
|
+
* symbol registry, so every inlined copy of this module resolves the SAME symbol, finds the slot
|
|
70
|
+
* already filled, and reuses that instance — one context identity however many copies exist.
|
|
71
|
+
* `globalThis` is present and identical in Hermes/React Native, Node and SSR (we never touch
|
|
72
|
+
* `window`), so this is safe on every host. `test/canary/themeContextIdentity.test.tsx` measures it
|
|
73
|
+
* in the BUILT artifact, because the defect is invisible in source.
|
|
51
74
|
*/
|
|
52
75
|
|
|
53
76
|
type OnboardingThemeProviderProps = {
|