@envive-ai/react-hooks 0.3.63 → 0.3.65
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/application/models/featureGates.cjs +2 -2
- package/dist/application/models/featureGates.d.cts +2 -2
- package/dist/application/models/featureGates.d.ts +2 -2
- package/dist/application/models/featureGates.js +2 -2
- package/dist/application/utils/elementObserver.d.cts +2 -2
- package/dist/atoms/app/index.d.cts +7 -7
- package/dist/atoms/app/index.d.ts +1 -1
- package/dist/atoms/app/variant.d.ts +6 -6
- package/dist/atoms/chat/chatState.d.cts +19 -19
- package/dist/atoms/chat/chatState.d.ts +19 -19
- package/dist/atoms/chat/form.d.cts +2 -2
- package/dist/atoms/chat/form.d.ts +3 -3
- package/dist/atoms/chat/index.d.ts +3 -3
- package/dist/atoms/chat/lastMessage.d.cts +2 -2
- package/dist/atoms/chat/lastMessage.d.ts +2 -2
- package/dist/atoms/chat/messageQueue.d.ts +7 -7
- package/dist/atoms/chat/performanceMetrics.d.cts +6 -6
- package/dist/atoms/chat/performanceMetrics.d.ts +6 -6
- package/dist/atoms/chat/renderedWidgetRefs.d.cts +2 -2
- package/dist/atoms/chat/renderedWidgetRefs.d.ts +3 -3
- package/dist/atoms/chat/replies.d.cts +3 -3
- package/dist/atoms/chat/suggestions.d.ts +3 -3
- package/dist/atoms/envive/enviveConfig.d.cts +14 -14
- package/dist/atoms/globalSearch/globalSearch.d.cts +5 -5
- package/dist/atoms/org/customerService.d.cts +6 -6
- package/dist/atoms/org/customerService.d.ts +6 -6
- package/dist/atoms/org/graphqlConfig.d.cts +4 -4
- package/dist/atoms/org/graphqlConfig.d.ts +4 -4
- package/dist/atoms/org/newOrgConfigAtom.d.cts +2 -2
- package/dist/atoms/org/newOrgConfigAtom.d.ts +2 -2
- package/dist/atoms/org/orgAnalyticsConfig.d.cts +4 -4
- package/dist/atoms/org/orgAnalyticsConfig.d.ts +4 -4
- package/dist/atoms/search/types.d.cts +1 -1
- package/dist/atoms/search/utils.d.cts +1 -1
- package/dist/atoms/widget/chatPreviewLoading.d.cts +2 -2
- package/dist/atoms/widget/chatPreviewLoading.d.ts +2 -2
- package/dist/contexts/pageContext/pageContext.cjs +12 -24
- package/dist/contexts/pageContext/pageContext.js +12 -24
- package/dist/contexts/systemSettingsContext/systemSettingsContext.d.cts +2 -2
- package/dist/contexts/types.d.cts +1 -1
- package/dist/contexts/types.d.ts +1 -1
- package/dist/contexts/typesV3.cjs +8 -1
- package/dist/contexts/typesV3.d.cts +23 -6
- package/dist/contexts/typesV3.d.ts +23 -6
- package/dist/contexts/typesV3.js +8 -2
- package/dist/hooks/Intersection/useIntersection.cjs +9 -2
- package/dist/hooks/Intersection/useIntersection.d.cts +2 -2
- package/dist/hooks/Intersection/useIntersection.d.ts +2 -2
- package/dist/hooks/Intersection/useIntersection.js +9 -2
- package/dist/hooks/SystemSettingsContext/useSystemSettingsContext.d.cts +2 -2
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.cjs +12 -3
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.d.cts +2 -1
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.d.ts +2 -1
- package/dist/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.js +13 -4
- package/dist/hooks/WidgetLoadDiagnostics/index.cjs +4 -0
- package/dist/hooks/WidgetLoadDiagnostics/index.d.cts +2 -0
- package/dist/hooks/WidgetLoadDiagnostics/index.d.ts +2 -0
- package/dist/hooks/WidgetLoadDiagnostics/index.js +3 -0
- package/dist/hooks/WidgetLoadDiagnostics/useWidgetLoadDiagnostics.cjs +122 -0
- package/dist/hooks/WidgetLoadDiagnostics/useWidgetLoadDiagnostics.d.cts +48 -0
- package/dist/hooks/WidgetLoadDiagnostics/useWidgetLoadDiagnostics.d.ts +48 -0
- package/dist/hooks/WidgetLoadDiagnostics/useWidgetLoadDiagnostics.js +120 -0
- package/dist/hooks/utils.d.cts +1 -1
- package/dist/hooks/utils.d.ts +1 -1
- package/dist/services/amplitudeService/eventNames.cjs +2 -1
- package/dist/services/amplitudeService/eventNames.d.cts +2 -1
- package/dist/services/amplitudeService/eventNames.d.ts +2 -1
- package/dist/services/amplitudeService/eventNames.js +2 -1
- package/dist/services/enviveConfigService/enviveConfigService.cjs +21 -35
- package/dist/services/enviveConfigService/enviveConfigService.d.cts +1 -2
- package/dist/services/enviveConfigService/enviveConfigService.d.ts +1 -2
- package/dist/services/enviveConfigService/enviveConfigService.js +21 -35
- package/dist/services/enviveConfigService/fetchBootstrapConfig.cjs +15 -16
- package/dist/services/enviveConfigService/fetchBootstrapConfig.js +15 -16
- package/dist/services/enviveConfigService/fetchGraphQLConfig.cjs +1 -69
- package/dist/services/enviveConfigService/fetchGraphQLConfig.js +2 -69
- package/dist/services/featureFlagService/index.cjs +7 -5
- package/dist/services/featureFlagService/index.d.cts +2 -1
- package/dist/services/featureFlagService/index.d.ts +2 -1
- package/dist/services/featureFlagService/index.js +7 -5
- package/dist/services/ga4ProjectionService/ga4EventSchema.cjs +3 -2
- package/dist/services/ga4ProjectionService/ga4EventSchema.js +3 -2
- package/dist/services/hardcopyService/hardcopyService.cjs +12 -3
- package/dist/services/hardcopyService/hardcopyService.d.cts +3 -1
- package/dist/services/hardcopyService/hardcopyService.d.ts +3 -1
- package/dist/services/hardcopyService/hardcopyService.js +12 -3
- package/package.json +5 -1
- package/src/application/models/featureGates.ts +11 -8
- package/src/contexts/pageContext/__tests__/pageContext.test.tsx +4 -59
- package/src/contexts/pageContext/pageContext.tsx +20 -41
- package/src/contexts/typesV3.ts +22 -4
- package/src/hooks/Intersection/useIntersection.ts +11 -0
- package/src/hooks/TrackComponentVisibleEvent/__tests__/useTrackComponentVisibleEvent.test.tsx +64 -0
- package/src/hooks/TrackComponentVisibleEvent/useTrackComponentVisibleEvent.ts +23 -4
- package/src/hooks/WidgetLoadDiagnostics/__tests__/useWidgetLoadDiagnostics.test.ts +161 -0
- package/src/hooks/WidgetLoadDiagnostics/index.ts +5 -0
- package/src/hooks/WidgetLoadDiagnostics/useWidgetLoadDiagnostics.ts +178 -0
- package/src/services/amplitudeService/eventNames.ts +4 -0
- package/src/services/enviveConfigService/__tests__/enviveConfigService.test.ts +72 -158
- package/src/services/enviveConfigService/__tests__/fetchBootstrapConfig.test.ts +111 -13
- package/src/services/enviveConfigService/__tests__/fetchGraphQLConfig.test.ts +161 -490
- package/src/services/enviveConfigService/enviveConfigService.ts +51 -87
- package/src/services/enviveConfigService/fetchBootstrapConfig.ts +74 -66
- package/src/services/enviveConfigService/fetchGraphQLConfig.ts +0 -120
- package/src/services/featureFlagService/__tests__/getFeatureFlagOverrides.test.ts +54 -0
- package/src/services/featureFlagService/index.ts +19 -6
- package/src/services/ga4ProjectionService/ga4EventSchema.ts +5 -0
- package/src/services/hardcopyService/__tests__/hardcopyService.test.ts +16 -5
- package/src/services/hardcopyService/hardcopyService.ts +10 -2
- package/dist/application/models/graphql/queries/getWidgetConfigQuery.cjs +0 -42
- package/dist/application/models/graphql/queries/getWidgetConfigQuery.js +0 -41
- package/src/application/models/graphql/queries/getWidgetConfigQuery.ts +0 -55
|
@@ -67,9 +67,9 @@ const baseParams: FetchBootstrapConfigParams = {
|
|
|
67
67
|
source: 'app',
|
|
68
68
|
namespace: 'spiffy-react-components',
|
|
69
69
|
gateNames: ['use_unified_config', 'is_client_session_enabled'],
|
|
70
|
+
// url_resolving inputs (org identity is NOT sent — the server fills it from the
|
|
71
|
+
// authenticated org). Absent url ⇒ bootstrap omits the url_resolving branch.
|
|
70
72
|
url: 'https://shop.example.com/products/thing',
|
|
71
|
-
orgId: 'org-1',
|
|
72
|
-
orgShortName: 'test-org',
|
|
73
73
|
contextSource: 'app',
|
|
74
74
|
env: 'prod',
|
|
75
75
|
featureGates: { use_unified_config: true, is_empty_div_plp_enabled: true },
|
|
@@ -180,20 +180,38 @@ describe('fetchBootstrapConfig', () => {
|
|
|
180
180
|
});
|
|
181
181
|
expect(body.url_resolving).toMatchObject({
|
|
182
182
|
url: 'https://shop.example.com/products/thing',
|
|
183
|
-
// Override-
|
|
183
|
+
// Override-only gates forwarded so client overrides reach page-variant resolution.
|
|
184
184
|
feature_gates: { use_unified_config: true, is_empty_div_plp_enabled: true },
|
|
185
185
|
});
|
|
186
|
-
// No org_base_config_version — the version comes only from the URL query param
|
|
187
|
-
// (override_config_version), never from getWidgetConfig's resolution.
|
|
186
|
+
// No org_base_config_version — the version comes only from the URL query param.
|
|
188
187
|
expect(body.url_resolving.org_base_config_version).toBeUndefined();
|
|
188
|
+
// org identity is NOT sent — the server fills org_id/org_short_name from the
|
|
189
|
+
// authenticated org (bootstrap-only has no getWidgetConfig to source them from).
|
|
189
190
|
expect(body.url_resolving.context).toEqual({
|
|
190
191
|
user_id: 'user-1',
|
|
191
|
-
org_id: 'org-1',
|
|
192
|
-
org_short_name: 'test-org',
|
|
193
192
|
chat_id: 'chat-9',
|
|
194
193
|
source: 'app',
|
|
195
194
|
env: 'prod',
|
|
196
195
|
});
|
|
196
|
+
expect(body.url_resolving.context.org_id).toBeUndefined();
|
|
197
|
+
expect(body.url_resolving.context.org_short_name).toBeUndefined();
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('omits the url_resolving branch from the request when no url is supplied', async () => {
|
|
201
|
+
makeBootstrapResponse();
|
|
202
|
+
|
|
203
|
+
// A disabled session (envive_on=false) requests config only — no page to resolve.
|
|
204
|
+
const { url, contextSource, env, featureGates, ...configOnly } = baseParams;
|
|
205
|
+
await fetchBootstrapConfig(configOnly);
|
|
206
|
+
|
|
207
|
+
const body = JSON.parse(mockFetch.mock.calls[0][1].body as string);
|
|
208
|
+
// Config inputs still sent; the whole url_resolving object is absent.
|
|
209
|
+
expect(body).toMatchObject({
|
|
210
|
+
user_id: 'user-1',
|
|
211
|
+
namespace: 'spiffy-react-components',
|
|
212
|
+
include_feature_gates: ['use_unified_config', 'is_client_session_enabled'],
|
|
213
|
+
});
|
|
214
|
+
expect(body.url_resolving).toBeUndefined();
|
|
197
215
|
});
|
|
198
216
|
|
|
199
217
|
it('threads a config-version query param into version + override_config_version', async () => {
|
|
@@ -207,7 +225,67 @@ describe('fetchBootstrapConfig', () => {
|
|
|
207
225
|
expect(body.url_resolving.override_config_version).toBe('9.9.9');
|
|
208
226
|
});
|
|
209
227
|
|
|
210
|
-
it('
|
|
228
|
+
it('degrades a malformed products_config to mock WITHOUT losing org/gates/experiments', async () => {
|
|
229
|
+
// A 2xx with valid org/gates/widget_config but a products_config that throws
|
|
230
|
+
// in transformV3ProductsConfig (invalid floating-button position). With no
|
|
231
|
+
// getWidgetConfig fallback left, this catch is the SOLE thing keeping a bad
|
|
232
|
+
// products config from aborting injection — it must null colors/frontend only
|
|
233
|
+
// and preserve org identity + gates + experiment_assignments + resolution.
|
|
234
|
+
mockFetch.mockResolvedValueOnce({
|
|
235
|
+
ok: true,
|
|
236
|
+
json: () =>
|
|
237
|
+
Promise.resolve({
|
|
238
|
+
org_config: {
|
|
239
|
+
org: { org: { id: 'org-boot', short_name: 'boot-org' } },
|
|
240
|
+
gates: [{ name: 'use_unified_config', value: true, group_name: 'Treatment' }],
|
|
241
|
+
},
|
|
242
|
+
widget_config: {
|
|
243
|
+
products_config: {
|
|
244
|
+
v_three_config: {
|
|
245
|
+
values: {
|
|
246
|
+
colors: { values: { text_primary: '#000000' } },
|
|
247
|
+
ui_configs: {
|
|
248
|
+
floating_button: { position: 'top-center' }, // invalid → transform throws
|
|
249
|
+
look_and_feel: { typography: {} },
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
experiment_assignments: [
|
|
255
|
+
{
|
|
256
|
+
layer_name: 'ml',
|
|
257
|
+
namespace: 'ml',
|
|
258
|
+
allocated_experiment_name: 'exp_a',
|
|
259
|
+
group_name: 'A',
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
resolution: { base_version: '2.0.0', base_version_source: 'merchant_layer' },
|
|
263
|
+
},
|
|
264
|
+
url_resolving: null,
|
|
265
|
+
}),
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const { config } = await fetchBootstrapConfig(baseParams);
|
|
269
|
+
|
|
270
|
+
// org / gates / experiments survived the products-config failure.
|
|
271
|
+
expect(config.org.org.id).toBe('org-boot');
|
|
272
|
+
expect(config.gates).toContainEqual({
|
|
273
|
+
name: 'use_unified_config',
|
|
274
|
+
value: true,
|
|
275
|
+
groupName: 'Treatment',
|
|
276
|
+
});
|
|
277
|
+
expect(config.experiment_assignments).toEqual([
|
|
278
|
+
{ layer_name: 'ml', namespace: 'ml', allocated_experiment_name: 'exp_a', group_name: 'A' },
|
|
279
|
+
]);
|
|
280
|
+
// colors/frontend degraded to undefined, resolution still attached.
|
|
281
|
+
expect(config.orgConfig).toEqual({
|
|
282
|
+
colorsConfig: undefined,
|
|
283
|
+
frontendConfig: undefined,
|
|
284
|
+
resolution: { baseVersion: '2.0.0', baseVersionSource: 'merchant_layer' },
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('throws on a non-ok response so the caller aborts injection (no fallback)', async () => {
|
|
211
289
|
mockFetch.mockResolvedValueOnce({ ok: false, statusText: 'Bad Gateway' });
|
|
212
290
|
|
|
213
291
|
await expect(fetchBootstrapConfig(baseParams)).rejects.toThrow(
|
|
@@ -225,14 +303,13 @@ describe('fetchBootstrapConfig', () => {
|
|
|
225
303
|
'partial org_config (no org.org)',
|
|
226
304
|
{ org_config: { org: {}, gates: okGates }, widget_config: okWidget },
|
|
227
305
|
],
|
|
228
|
-
['absent gates', { org_config: { org: { org: { id: 'o' } } }, widget_config: okWidget }],
|
|
229
306
|
[
|
|
230
|
-
'
|
|
231
|
-
{ org_config: { org: { org: { id: 'o' } }
|
|
307
|
+
'absent gates (not an array)',
|
|
308
|
+
{ org_config: { org: { org: { id: 'o' } } }, widget_config: okWidget },
|
|
232
309
|
],
|
|
233
310
|
['missing widget_config', { org_config: okOrg, widget_config: null }],
|
|
234
311
|
])(
|
|
235
|
-
'throws on a 2xx with %s so the caller
|
|
312
|
+
'throws on a 2xx with %s so the caller aborts injection instead of using empty config',
|
|
236
313
|
async (_label, payload) => {
|
|
237
314
|
mockFetch.mockResolvedValueOnce({ ok: true, json: () => Promise.resolve(payload) });
|
|
238
315
|
|
|
@@ -240,6 +317,27 @@ describe('fetchBootstrapConfig', () => {
|
|
|
240
317
|
},
|
|
241
318
|
);
|
|
242
319
|
|
|
320
|
+
it('accepts an EMPTY (but present) gates array as a valid all-disabled config', async () => {
|
|
321
|
+
// An empty gates array is a legitimate "everything off" response (no user to
|
|
322
|
+
// bucket, or every requested gate off). It must NOT be rejected as malformed:
|
|
323
|
+
// FeatureFlagService resolves every gate to false → the session disables
|
|
324
|
+
// gracefully (with the init event still firing), rather than aborting injection.
|
|
325
|
+
mockFetch.mockResolvedValueOnce({
|
|
326
|
+
ok: true,
|
|
327
|
+
json: () =>
|
|
328
|
+
Promise.resolve({
|
|
329
|
+
org_config: { org: { org: { id: 'org-boot', short_name: 'boot-org' } }, gates: [] },
|
|
330
|
+
widget_config: { products_config: {}, experiment_assignments: [] },
|
|
331
|
+
url_resolving: null,
|
|
332
|
+
}),
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
const { config } = await fetchBootstrapConfig(baseParams);
|
|
336
|
+
|
|
337
|
+
expect(config.org.org.id).toBe('org-boot');
|
|
338
|
+
expect(config.gates).toEqual([]);
|
|
339
|
+
});
|
|
340
|
+
|
|
243
341
|
it('passes an AbortSignal to fetch (timeout wiring)', async () => {
|
|
244
342
|
makeBootstrapResponse();
|
|
245
343
|
|
|
@@ -249,7 +347,7 @@ describe('fetchBootstrapConfig', () => {
|
|
|
249
347
|
expect(options.signal).toBeInstanceOf(AbortSignal);
|
|
250
348
|
});
|
|
251
349
|
|
|
252
|
-
it('aborts and rejects when the request exceeds the timeout
|
|
350
|
+
it('aborts and rejects when the request exceeds the timeout (injection aborts, no fallback)', async () => {
|
|
253
351
|
vi.useFakeTimers();
|
|
254
352
|
// Mimic real fetch: reject with an AbortError once its signal aborts.
|
|
255
353
|
mockFetch.mockImplementationOnce(
|