@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.
- package/README.md +112 -0
- package/dist/LiveStateProvider-BEiLZeen.js +1457 -0
- package/dist/LiveStateProvider-BEiLZeen.js.map +1 -0
- package/dist/LiveStateProvider-B_uOhVFY.cjs +2 -0
- package/dist/LiveStateProvider-B_uOhVFY.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +513 -219
- package/dist/index.js.map +1 -1
- package/dist/src/components/LiveStateAlert.d.ts +7 -1
- package/dist/src/components/LiveStateAlert.d.ts.map +1 -1
- package/dist/src/components/LiveStateInfo.d.ts +13 -1
- package/dist/src/components/LiveStateInfo.d.ts.map +1 -1
- package/dist/src/components/LiveStateRenderer.d.ts +1 -1
- package/dist/src/components/LiveStateRenderer.d.ts.map +1 -1
- package/dist/src/components/RichText.d.ts +19 -0
- package/dist/src/components/RichText.d.ts.map +1 -0
- package/dist/src/hooks/useClosable.d.ts.map +1 -1
- package/dist/src/hooks/useLiveState.d.ts +13 -4
- package/dist/src/hooks/useLiveState.d.ts.map +1 -1
- package/dist/src/hooks/useTrackEvent.d.ts.map +1 -1
- package/dist/src/index.d.ts +5 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/providers/LiveStateProvider.d.ts +11 -9
- package/dist/src/providers/LiveStateProvider.d.ts.map +1 -1
- package/dist/src/query-client.d.ts +15 -0
- package/dist/src/query-client.d.ts.map +1 -0
- package/dist/src/testing/index.d.ts +58 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/types/index.d.ts +206 -9
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/utils/analytics.d.ts +19 -19
- package/dist/src/utils/analytics.d.ts.map +1 -1
- package/dist/src/utils/closable-storage.d.ts +1 -0
- package/dist/src/utils/closable-storage.d.ts.map +1 -1
- package/dist/src/utils/cta.d.ts +3 -1
- package/dist/src/utils/cta.d.ts.map +1 -1
- package/dist/src/utils/logger.d.ts +17 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/query.d.ts +38 -0
- package/dist/src/utils/query.d.ts.map +1 -0
- package/dist/src/utils/sanitize.d.ts +25 -0
- package/dist/src/utils/sanitize.d.ts.map +1 -0
- package/dist/testing.cjs +2 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.js +62 -0
- package/dist/testing.js.map +1 -0
- 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
|