@tiendanube/live-state 1.0.0-beta.8 → 1.0.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.
Files changed (50) hide show
  1. package/README.md +112 -0
  2. package/dist/LiveStateProvider-BEiLZeen.js +1457 -0
  3. package/dist/LiveStateProvider-BEiLZeen.js.map +1 -0
  4. package/dist/LiveStateProvider-B_uOhVFY.cjs +2 -0
  5. package/dist/LiveStateProvider-B_uOhVFY.cjs.map +1 -0
  6. package/dist/index.cjs +1 -1
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.js +513 -219
  10. package/dist/index.js.map +1 -1
  11. package/dist/src/components/LiveStateAlert.d.ts +7 -1
  12. package/dist/src/components/LiveStateAlert.d.ts.map +1 -1
  13. package/dist/src/components/LiveStateInfo.d.ts +13 -1
  14. package/dist/src/components/LiveStateInfo.d.ts.map +1 -1
  15. package/dist/src/components/LiveStateRenderer.d.ts +1 -1
  16. package/dist/src/components/LiveStateRenderer.d.ts.map +1 -1
  17. package/dist/src/components/RichText.d.ts +19 -0
  18. package/dist/src/components/RichText.d.ts.map +1 -0
  19. package/dist/src/hooks/useClosable.d.ts.map +1 -1
  20. package/dist/src/hooks/useLiveState.d.ts +13 -4
  21. package/dist/src/hooks/useLiveState.d.ts.map +1 -1
  22. package/dist/src/hooks/useTrackEvent.d.ts.map +1 -1
  23. package/dist/src/index.d.ts +5 -1
  24. package/dist/src/index.d.ts.map +1 -1
  25. package/dist/src/providers/LiveStateProvider.d.ts +11 -9
  26. package/dist/src/providers/LiveStateProvider.d.ts.map +1 -1
  27. package/dist/src/query-client.d.ts +15 -0
  28. package/dist/src/query-client.d.ts.map +1 -0
  29. package/dist/src/testing/index.d.ts +58 -0
  30. package/dist/src/testing/index.d.ts.map +1 -0
  31. package/dist/src/types/index.d.ts +206 -9
  32. package/dist/src/types/index.d.ts.map +1 -1
  33. package/dist/src/utils/analytics.d.ts +19 -19
  34. package/dist/src/utils/analytics.d.ts.map +1 -1
  35. package/dist/src/utils/closable-storage.d.ts +1 -0
  36. package/dist/src/utils/closable-storage.d.ts.map +1 -1
  37. package/dist/src/utils/cta.d.ts +3 -1
  38. package/dist/src/utils/cta.d.ts.map +1 -1
  39. package/dist/src/utils/logger.d.ts +17 -0
  40. package/dist/src/utils/logger.d.ts.map +1 -0
  41. package/dist/src/utils/query.d.ts +38 -0
  42. package/dist/src/utils/query.d.ts.map +1 -0
  43. package/dist/src/utils/sanitize.d.ts +25 -0
  44. package/dist/src/utils/sanitize.d.ts.map +1 -0
  45. package/dist/testing.cjs +2 -0
  46. package/dist/testing.cjs.map +1 -0
  47. package/dist/testing.d.ts +1 -0
  48. package/dist/testing.js +62 -0
  49. package/dist/testing.js.map +1 -0
  50. package/package.json +23 -12
package/README.md CHANGED
@@ -88,6 +88,118 @@ That's it. The library handles rendering, tracking, and CTA behavior automatical
88
88
 
89
89
  ---
90
90
 
91
+ ## Caching behaviour (SWR)
92
+
93
+ The lib uses [SWR](https://swr.vercel.app/) internally for data fetching, caching, and deduplication. Key implications:
94
+
95
+ - **Single request per session** — all `useLiveState()` calls inside the same `LiveStateProvider` share one cached result. The backend is called once, regardless of how many pages or components use the hook.
96
+ - **Cache key is fixed** — the cache key is the string `'live-state'`, not the fetcher URL. This means changing the `page` prop on `LiveStateRenderer` does **not** trigger a new request — the page is a frontend-only concern for tracking event names.
97
+ - **Fetcher reference stability** — SWR does not re-fetch when the fetcher function reference changes, because the key is fixed. Even so, it is good practice to define the fetcher outside the component (or use `useCallback`/`useMemo`) to avoid unnecessary re-renders.
98
+ - **Revalidation on reconnect** — the lib revalidates automatically when the browser reconnects to the network.
99
+ - **No revalidation on focus** — focus-based revalidation is disabled to avoid extra requests when the user switches tabs.
100
+ - **Manual refresh** — call `refresh()` from `useLiveState()` to force a re-fetch at any time.
101
+
102
+ ```tsx
103
+ // ✅ Define fetcher outside the component — stable reference, no re-renders
104
+ const fetcher: LiveStateFetcher = async () => { ... };
105
+
106
+ function App() {
107
+ return <LiveStateProvider fetcher={fetcher}>...</LiveStateProvider>;
108
+ }
109
+
110
+ // ❌ Avoid defining fetcher inline — new reference on every render
111
+ function App() {
112
+ return (
113
+ <LiveStateProvider fetcher={async () => { ... }}>...</LiveStateProvider>
114
+ );
115
+ }
116
+ ```
117
+
118
+ ---
119
+
120
+ ## Testing utilities
121
+
122
+ Import from `@tiendanube/live-state/testing` in your test files:
123
+
124
+ ```tsx
125
+ import {
126
+ MockLiveStateProvider,
127
+ createMockLiveState,
128
+ mockUseLiveState,
129
+ } from '@tiendanube/live-state/testing';
130
+
131
+ // Render with controlled live state data
132
+ render(
133
+ <MockLiveStateProvider liveState={createMockLiveState({ type: 'alert' })}>
134
+ <MyComponent />
135
+ </MockLiveStateProvider>
136
+ );
137
+
138
+ // Mock the hook directly in unit tests
139
+ vi.mock('@tiendanube/live-state', async (importOriginal) => ({
140
+ ...(await importOriginal()),
141
+ useLiveState: () => mockUseLiveState({ liveState: createMockLiveState() }),
142
+ }));
143
+ ```
144
+
145
+ `MockLiveStateProvider` automatically sets `disabled={true}`, suppressing all analytics SDK calls in tests.
146
+
147
+ ---
148
+
149
+ ## Disabling analytics (dev / test / staging)
150
+
151
+ Pass `disabled={true}` to `LiveStateProvider` to prevent the Amplitude and Clarity SDKs from being initialised. The prop value should come from your app's own environment variable — the library does not define or read any env var itself.
152
+
153
+ ```tsx
154
+ // Vite
155
+ <LiveStateProvider
156
+ fetcher={fetchLiveState}
157
+ disabled={import.meta.env.VITE_APP_ENV !== 'production'}
158
+ >
159
+ ...
160
+ </LiveStateProvider>
161
+
162
+ // Create React App / Next.js
163
+ <LiveStateProvider
164
+ fetcher={fetchLiveState}
165
+ disabled={process.env.NODE_ENV !== 'production'}
166
+ >
167
+ ...
168
+ </LiveStateProvider>
169
+ ```
170
+
171
+ When `disabled` is `true`, `onEvent` callbacks still fire normally so you can observe tracking without hitting the real SDKs.
172
+
173
+ ---
174
+
175
+ ## Fetcher timeouts
176
+
177
+ The library does not impose a timeout on the fetcher — if the endpoint hangs, `isLoading` will remain `true` indefinitely. Because live state notifications are non-critical UI, you should configure a timeout directly in your fetcher so that a slow backend never blocks the page.
178
+
179
+ ```tsx
180
+ // Using axios
181
+ const fetcher: LiveStateFetcher = async () => {
182
+ const { data } = await axios.get('/api/live-state', { timeout: 5000 });
183
+ return data ?? null;
184
+ };
185
+
186
+ // Using native fetch + AbortSignal
187
+ const fetcher: LiveStateFetcher = async () => {
188
+ const controller = new AbortController();
189
+ const id = setTimeout(() => controller.abort(), 5000);
190
+ try {
191
+ const res = await fetch('/api/live-state', { signal: controller.signal });
192
+ return res.ok ? await res.json() : null;
193
+ } catch {
194
+ return null; // timeout or network error — fail silently
195
+ } finally {
196
+ clearTimeout(id);
197
+ }
198
+ };
199
+ ```
200
+
201
+ ---
202
+
91
203
  ## Documentation
92
204
 
93
205
  - [Implementation Guide](./docs/IMPLEMENTATION_GUIDE.md) — full integration guide with usage patterns, API reference, and troubleshooting