@archbase/ssr 3.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 +411 -0
- package/dist/archbase-ssr-3.0.0.tgz +0 -0
- package/dist/datasource/ArchbaseSSRDataSource.d.ts +122 -0
- package/dist/hooks/useArchbaseSSRDataSource.d.ts +94 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +655 -0
- package/dist/providers/ArchbaseSSRProvider.d.ts +52 -0
- package/dist/tanstack/ArchbaseTanStackIntegration.d.ts +67 -0
- package/dist/utils/ArchbaseSSRUtils.d.ts +81 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# @archbase/ssr
|
|
2
|
+
|
|
3
|
+
Server-Side Rendering utilities for Archbase React components with TanStack Start support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @archbase/ssr
|
|
9
|
+
# or
|
|
10
|
+
yarn add @archbase/ssr
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @archbase/ssr
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Peer Dependencies
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install react react-dom @mantine/core @mantine/hooks @tanstack/react-query @tanstack/start
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
### 🚀 **TanStack Start Integration**
|
|
24
|
+
- Full SSR support for TanStack Start applications
|
|
25
|
+
- Seamless server/client data synchronization
|
|
26
|
+
- Optimized hydration strategies
|
|
27
|
+
|
|
28
|
+
### 📊 **DataSource SSR Support**
|
|
29
|
+
- SSR-compatible DataSource implementations
|
|
30
|
+
- State serialization/deserialization
|
|
31
|
+
- Automatic hydration from server data
|
|
32
|
+
|
|
33
|
+
### 🎯 **SSR-Safe Components**
|
|
34
|
+
- Hydration-safe providers and hooks
|
|
35
|
+
- Client-only and server-only components
|
|
36
|
+
- Media query hooks that work with SSR
|
|
37
|
+
|
|
38
|
+
### âš¡ **Performance Optimized**
|
|
39
|
+
- Minimal payload serialization
|
|
40
|
+
- Streaming-compatible
|
|
41
|
+
- Lazy hydration support
|
|
42
|
+
|
|
43
|
+
## Basic Setup
|
|
44
|
+
|
|
45
|
+
### 1. Wrap your app with ArchbaseSSRProvider
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// app.tsx (TanStack Start)
|
|
49
|
+
import { ArchbaseSSRProvider, ArchbaseTanStackProvider } from '@archbase/ssr';
|
|
50
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
51
|
+
|
|
52
|
+
function App() {
|
|
53
|
+
const queryClient = new QueryClient();
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<ArchbaseSSRProvider>
|
|
57
|
+
<ArchbaseTanStackProvider queryClient={queryClient}>
|
|
58
|
+
<YourAppContent />
|
|
59
|
+
</ArchbaseTanStackProvider>
|
|
60
|
+
</ArchbaseSSRProvider>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 2. Use SSR-compatible DataSources
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { useArchbaseSSRDataSource } from '@archbase/ssr';
|
|
69
|
+
|
|
70
|
+
function UsersList() {
|
|
71
|
+
const {
|
|
72
|
+
dataSource,
|
|
73
|
+
isLoading,
|
|
74
|
+
error,
|
|
75
|
+
isHydrated
|
|
76
|
+
} = useArchbaseSSRDataSource('users', {
|
|
77
|
+
initialRecords: [], // Server-side initial data
|
|
78
|
+
autoHydrate: true,
|
|
79
|
+
fallbackRecords: []
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (!isHydrated) {
|
|
83
|
+
return <div>Loading...</div>; // SSR placeholder
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<div>
|
|
88
|
+
{dataSource.getRecords().map(user => (
|
|
89
|
+
<div key={user.id}>{user.name}</div>
|
|
90
|
+
))}
|
|
91
|
+
</div>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Advanced Usage
|
|
97
|
+
|
|
98
|
+
### Server-Side Data Fetching with TanStack Start
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
// routes/users.tsx
|
|
102
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
103
|
+
import { useArchbaseQuery, prepareServerQueries } from '@archbase/ssr';
|
|
104
|
+
|
|
105
|
+
export const Route = createFileRoute('/users')({
|
|
106
|
+
component: UsersPage,
|
|
107
|
+
loader: async ({ context }) => {
|
|
108
|
+
// Prepare queries for SSR
|
|
109
|
+
const queryClient = context.queryClient;
|
|
110
|
+
|
|
111
|
+
await prepareServerQueries(queryClient, [
|
|
112
|
+
{
|
|
113
|
+
key: ['users'],
|
|
114
|
+
fetchFn: () => fetch('/api/users').then(res => res.json())
|
|
115
|
+
}
|
|
116
|
+
]);
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
dehydratedState: queryClient.getQueryData(['users'])
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
function UsersPage() {
|
|
125
|
+
const { dataSource } = useArchbaseSSRDataSource('users');
|
|
126
|
+
|
|
127
|
+
const { data, isLoading } = useArchbaseQuery(
|
|
128
|
+
['users'],
|
|
129
|
+
() => fetch('/api/users').then(res => res.json()),
|
|
130
|
+
{
|
|
131
|
+
dataSource,
|
|
132
|
+
syncWithDataSource: true,
|
|
133
|
+
ssr: true
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<div>
|
|
139
|
+
<h1>Users</h1>
|
|
140
|
+
{/* Your user list component */}
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### SSR-Safe Utilities
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import {
|
|
150
|
+
canUseDOM,
|
|
151
|
+
safeLocalStorage,
|
|
152
|
+
withSSRFallback,
|
|
153
|
+
ClientOnly,
|
|
154
|
+
ServerOnly
|
|
155
|
+
} from '@archbase/ssr';
|
|
156
|
+
|
|
157
|
+
function MyComponent() {
|
|
158
|
+
// Safe localStorage access
|
|
159
|
+
const savedData = safeLocalStorage.getItem('userData');
|
|
160
|
+
|
|
161
|
+
// Safe operation with fallback
|
|
162
|
+
const windowWidth = withSSRFallback(
|
|
163
|
+
() => window.innerWidth,
|
|
164
|
+
1024 // fallback for SSR
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<div>
|
|
169
|
+
<ServerOnly>
|
|
170
|
+
<div>This only renders on server</div>
|
|
171
|
+
</ServerOnly>
|
|
172
|
+
|
|
173
|
+
<ClientOnly fallback={<div>Loading...</div>}>
|
|
174
|
+
<div>This only renders on client after hydration</div>
|
|
175
|
+
</ClientOnly>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Hydration-Safe State Management
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { useHydrationSafeState, useSSRSafeMediaQuery } from '@archbase/ssr';
|
|
185
|
+
|
|
186
|
+
function ResponsiveComponent() {
|
|
187
|
+
// Media query that works with SSR
|
|
188
|
+
const isMobile = useSSRSafeMediaQuery('(max-width: 768px)', false);
|
|
189
|
+
|
|
190
|
+
// State that's safe during hydration
|
|
191
|
+
const theme = useHydrationSafeState(
|
|
192
|
+
'light', // SSR value
|
|
193
|
+
() => localStorage.getItem('theme') || 'light' // Client value
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<div className={`theme-${theme} ${isMobile ? 'mobile' : 'desktop'}`}>
|
|
198
|
+
Content
|
|
199
|
+
</div>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Advanced DataSource Serialization
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { ArchbaseSSRDataSource } from '@archbase/ssr';
|
|
208
|
+
|
|
209
|
+
// Create SSR-compatible DataSource
|
|
210
|
+
const userDataSource = new ArchbaseSSRDataSource('users');
|
|
211
|
+
|
|
212
|
+
// On server - serialize state
|
|
213
|
+
const serializedState = userDataSource.serializeState();
|
|
214
|
+
|
|
215
|
+
// Send to client and deserialize
|
|
216
|
+
userDataSource.deserializeState(serializedState);
|
|
217
|
+
|
|
218
|
+
// Or use minimal serialization for performance
|
|
219
|
+
const minimalState = userDataSource.serializeMinimalState();
|
|
220
|
+
|
|
221
|
+
// Create from server data
|
|
222
|
+
const hydratedDataSource = ArchbaseSSRDataSource.fromServerData(
|
|
223
|
+
'users',
|
|
224
|
+
serverData,
|
|
225
|
+
{ /* options */ }
|
|
226
|
+
);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Multiple DataSources Management
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { useArchbaseSSRDataSources } from '@archbase/ssr';
|
|
233
|
+
|
|
234
|
+
function Dashboard() {
|
|
235
|
+
const {
|
|
236
|
+
sources,
|
|
237
|
+
getDataSource,
|
|
238
|
+
serializeAll,
|
|
239
|
+
isAnyLoading,
|
|
240
|
+
errors
|
|
241
|
+
} = useArchbaseSSRDataSources([
|
|
242
|
+
{ name: 'users', options: { initialRecords: [] } },
|
|
243
|
+
{ name: 'products', options: { initialRecords: [] } },
|
|
244
|
+
{ name: 'orders', options: { initialRecords: [] } }
|
|
245
|
+
]);
|
|
246
|
+
|
|
247
|
+
const userDataSource = getDataSource('users');
|
|
248
|
+
const productDataSource = getDataSource('products');
|
|
249
|
+
|
|
250
|
+
if (isAnyLoading) {
|
|
251
|
+
return <div>Loading dashboard...</div>;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<div>
|
|
256
|
+
<UsersList dataSource={userDataSource?.dataSource} />
|
|
257
|
+
<ProductsList dataSource={productDataSource?.dataSource} />
|
|
258
|
+
</div>
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## TanStack Start Route Example
|
|
264
|
+
|
|
265
|
+
Complete example of a TanStack Start route with Archbase SSR:
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
268
|
+
// routes/products/$productId.tsx
|
|
269
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
270
|
+
import {
|
|
271
|
+
ArchbaseSSRProvider,
|
|
272
|
+
useArchbaseSSRDataSource,
|
|
273
|
+
prepareServerQueries
|
|
274
|
+
} from '@archbase/ssr';
|
|
275
|
+
|
|
276
|
+
export const Route = createFileRoute('/products/$productId')({
|
|
277
|
+
component: ProductPage,
|
|
278
|
+
loader: async ({ params, context }) => {
|
|
279
|
+
const { productId } = params;
|
|
280
|
+
const queryClient = context.queryClient;
|
|
281
|
+
|
|
282
|
+
// Prefetch product data on server
|
|
283
|
+
await prepareServerQueries(queryClient, [
|
|
284
|
+
{
|
|
285
|
+
key: ['product', productId],
|
|
286
|
+
fetchFn: () => fetchProduct(productId)
|
|
287
|
+
}
|
|
288
|
+
]);
|
|
289
|
+
|
|
290
|
+
const productData = queryClient.getQueryData(['product', productId]);
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
productData,
|
|
294
|
+
dehydratedState: queryClient.getQueryData(['product', productId])
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
function ProductPage() {
|
|
300
|
+
const { productId } = Route.useParams();
|
|
301
|
+
const { productData } = Route.useLoaderData();
|
|
302
|
+
|
|
303
|
+
const { dataSource, isHydrated } = useArchbaseSSRDataSource('product', {
|
|
304
|
+
initialRecords: productData ? [productData] : [],
|
|
305
|
+
autoHydrate: true
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
if (!isHydrated) {
|
|
309
|
+
// SSR/hydration loading state
|
|
310
|
+
return <ProductSkeleton />;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const product = dataSource.getCurrentRecord();
|
|
314
|
+
|
|
315
|
+
return (
|
|
316
|
+
<div>
|
|
317
|
+
<h1>{product?.name}</h1>
|
|
318
|
+
<p>{product?.description}</p>
|
|
319
|
+
<ProductForm dataSource={dataSource} />
|
|
320
|
+
</div>
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
async function fetchProduct(id: string) {
|
|
325
|
+
const response = await fetch(`/api/products/${id}`);
|
|
326
|
+
return response.json();
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Best Practices
|
|
331
|
+
|
|
332
|
+
### 1. **Minimize Serialized Data**
|
|
333
|
+
```typescript
|
|
334
|
+
// Good: Only serialize essential data
|
|
335
|
+
const minimalState = dataSource.serializeMinimalState();
|
|
336
|
+
|
|
337
|
+
// Avoid: Serializing large datasets
|
|
338
|
+
const fullState = dataSource.serializeState(); // Use sparingly
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 2. **Graceful Fallbacks**
|
|
342
|
+
```typescript
|
|
343
|
+
const { dataSource, error } = useArchbaseSSRDataSource('users', {
|
|
344
|
+
fallbackRecords: [], // Always provide fallbacks
|
|
345
|
+
autoHydrate: true
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
if (error) {
|
|
349
|
+
return <ErrorBoundary error={error} />;
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### 3. **Conditional Client Features**
|
|
354
|
+
```typescript
|
|
355
|
+
import { ClientOnly, canUseDOM } from '@archbase/ssr';
|
|
356
|
+
|
|
357
|
+
function AdvancedFeatures() {
|
|
358
|
+
return (
|
|
359
|
+
<ClientOnly fallback={<BasicView />}>
|
|
360
|
+
{canUseDOM() && <InteractiveChart />}
|
|
361
|
+
</ClientOnly>
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 4. **Performance Optimization**
|
|
367
|
+
```typescript
|
|
368
|
+
// Lazy load heavy components
|
|
369
|
+
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
|
|
370
|
+
|
|
371
|
+
function App() {
|
|
372
|
+
return (
|
|
373
|
+
<ClientOnly>
|
|
374
|
+
<React.Suspense fallback={<Loading />}>
|
|
375
|
+
<HeavyComponent />
|
|
376
|
+
</React.Suspense>
|
|
377
|
+
</ClientOnly>
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## Migration from Client-Only Archbase
|
|
383
|
+
|
|
384
|
+
1. **Wrap your app with SSR providers**
|
|
385
|
+
2. **Replace DataSource with useArchbaseSSRDataSource**
|
|
386
|
+
3. **Add SSR-safe utilities where needed**
|
|
387
|
+
4. **Update server routes for data prefetching**
|
|
388
|
+
|
|
389
|
+
## TypeScript Support
|
|
390
|
+
|
|
391
|
+
All components and hooks are fully typed with TypeScript. The package includes complete type definitions for optimal development experience.
|
|
392
|
+
|
|
393
|
+
## Browser Compatibility
|
|
394
|
+
|
|
395
|
+
- **Server**: Node.js 18+
|
|
396
|
+
- **Client**: Modern browsers with ES2020 support
|
|
397
|
+
- **SSR**: Full support for all server-side environments
|
|
398
|
+
|
|
399
|
+
## Performance
|
|
400
|
+
|
|
401
|
+
- **Bundle Size**: ~15KB gzipped
|
|
402
|
+
- **Runtime Overhead**: Minimal (hydration detection only)
|
|
403
|
+
- **Memory Usage**: Optimized serialization reduces memory footprint
|
|
404
|
+
|
|
405
|
+
## Contributing
|
|
406
|
+
|
|
407
|
+
This package is part of the Archbase React ecosystem. See the main repository for contribution guidelines.
|
|
408
|
+
|
|
409
|
+
## License
|
|
410
|
+
|
|
411
|
+
MIT License
|
|
Binary file
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ArchbaseDataSource } from '@archbase/data';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for serializable DataSource state
|
|
4
|
+
*/
|
|
5
|
+
interface SerializableDataSourceState<T, ID> {
|
|
6
|
+
records: T[];
|
|
7
|
+
currentRecord: T | undefined;
|
|
8
|
+
recordIndex: number;
|
|
9
|
+
state: string;
|
|
10
|
+
hasChanges: boolean;
|
|
11
|
+
filter?: any;
|
|
12
|
+
sort?: any;
|
|
13
|
+
metadata?: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Extended DataSource with SSR capabilities
|
|
17
|
+
*/
|
|
18
|
+
export declare class ArchbaseSSRDataSource<T extends Record<string, any>, ID> extends ArchbaseDataSource<T, ID> {
|
|
19
|
+
private _ssrData?;
|
|
20
|
+
private _isHydrating;
|
|
21
|
+
constructor(name: string, options?: any);
|
|
22
|
+
/**
|
|
23
|
+
* Serialize DataSource state for SSR
|
|
24
|
+
*/
|
|
25
|
+
serializeState(): string;
|
|
26
|
+
/**
|
|
27
|
+
* Restore DataSource state from serialized data
|
|
28
|
+
*/
|
|
29
|
+
deserializeState(serializedState: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Check if DataSource is currently hydrating from SSR
|
|
32
|
+
*/
|
|
33
|
+
isHydrating(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Get SSR data if available
|
|
36
|
+
*/
|
|
37
|
+
getSSRData(): SerializableDataSourceState<T, ID> | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Create a minimal state object for SSR
|
|
40
|
+
* Only includes essential data to reduce payload size
|
|
41
|
+
*/
|
|
42
|
+
serializeMinimalState(): string;
|
|
43
|
+
/**
|
|
44
|
+
* Create a DataSource instance from server data
|
|
45
|
+
*/
|
|
46
|
+
static fromServerData<T extends Record<string, any>, ID>(name: string, serverData: any, options?: any): ArchbaseSSRDataSource<T, ID>;
|
|
47
|
+
/**
|
|
48
|
+
* Enhanced method to handle SSR-safe operations
|
|
49
|
+
*/
|
|
50
|
+
ssrSafeOperation<R>(operation: () => R, fallback: R): R;
|
|
51
|
+
/**
|
|
52
|
+
* Override to handle SSR-safe filtering
|
|
53
|
+
*/
|
|
54
|
+
applyFilter(filter: any): void;
|
|
55
|
+
/**
|
|
56
|
+
* Override to handle SSR-safe sorting
|
|
57
|
+
*/
|
|
58
|
+
applySort(sort: any): void;
|
|
59
|
+
/**
|
|
60
|
+
* Get records with SSR safety
|
|
61
|
+
*/
|
|
62
|
+
getRecords(): T[];
|
|
63
|
+
/**
|
|
64
|
+
* Get current record with SSR safety
|
|
65
|
+
*/
|
|
66
|
+
getCurrentRecord(): T | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Check if we have data available for rendering
|
|
69
|
+
*/
|
|
70
|
+
hasData(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Create a snapshot that can be safely transmitted between server/client
|
|
73
|
+
*/
|
|
74
|
+
createSnapshot(): {
|
|
75
|
+
records: T[];
|
|
76
|
+
currentIndex: number;
|
|
77
|
+
metadata: Record<string, any>;
|
|
78
|
+
timestamp: number;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Restore from a snapshot
|
|
82
|
+
*/
|
|
83
|
+
restoreFromSnapshot(snapshot: {
|
|
84
|
+
records: T[];
|
|
85
|
+
currentIndex: number;
|
|
86
|
+
metadata: Record<string, any>;
|
|
87
|
+
timestamp: number;
|
|
88
|
+
}): void;
|
|
89
|
+
/**
|
|
90
|
+
* Helper method to get all metadata
|
|
91
|
+
*/
|
|
92
|
+
private getAllMetadata;
|
|
93
|
+
/**
|
|
94
|
+
* Get all records from the data source
|
|
95
|
+
*/
|
|
96
|
+
getAllRecords(): T[];
|
|
97
|
+
/**
|
|
98
|
+
* Get current record index
|
|
99
|
+
*/
|
|
100
|
+
getRecordIndex(): number;
|
|
101
|
+
/**
|
|
102
|
+
* Check if data source has changes
|
|
103
|
+
*/
|
|
104
|
+
isChanged(): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Get current filter
|
|
107
|
+
*/
|
|
108
|
+
getFilter(): any;
|
|
109
|
+
/**
|
|
110
|
+
* Get current sort
|
|
111
|
+
*/
|
|
112
|
+
getSort(): any;
|
|
113
|
+
/**
|
|
114
|
+
* Get record count
|
|
115
|
+
*/
|
|
116
|
+
getRecordCount(): number;
|
|
117
|
+
/**
|
|
118
|
+
* Set records with proper DataSource options
|
|
119
|
+
*/
|
|
120
|
+
private setRecords;
|
|
121
|
+
}
|
|
122
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { ArchbaseSSRDataSource } from '../datasource/ArchbaseSSRDataSource';
|
|
2
|
+
interface UseArchbaseSSRDataSourceOptions<T, ID> {
|
|
3
|
+
/** Initial records for SSR */
|
|
4
|
+
initialRecords?: T[];
|
|
5
|
+
/** Server data key in SSR context */
|
|
6
|
+
serverDataKey?: string;
|
|
7
|
+
/** Auto-hydrate from server data */
|
|
8
|
+
autoHydrate?: boolean;
|
|
9
|
+
/** Fallback records if server data fails */
|
|
10
|
+
fallbackRecords?: T[];
|
|
11
|
+
/** Custom serialization/deserialization */
|
|
12
|
+
serializer?: {
|
|
13
|
+
serialize: (data: any) => string;
|
|
14
|
+
deserialize: (data: string) => any;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* SSR-compatible hook for DataSource management
|
|
19
|
+
*/
|
|
20
|
+
export declare function useArchbaseSSRDataSource<T extends Record<string, any>, ID>(name: string, options?: UseArchbaseSSRDataSourceOptions<T, ID>): {
|
|
21
|
+
dataSource: ArchbaseSSRDataSource<T, ID>;
|
|
22
|
+
isLoading: boolean;
|
|
23
|
+
error: Error | null;
|
|
24
|
+
isHydrated: boolean;
|
|
25
|
+
serializeState: () => string;
|
|
26
|
+
deserializeState: (serializedState: string) => void;
|
|
27
|
+
getMinimalState: () => {
|
|
28
|
+
recordCount: number;
|
|
29
|
+
currentIndex: number;
|
|
30
|
+
hasData: boolean;
|
|
31
|
+
isActive: boolean;
|
|
32
|
+
};
|
|
33
|
+
refresh: (newRecords?: T[]) => Promise<void>;
|
|
34
|
+
records: T[];
|
|
35
|
+
currentRecord: T | undefined;
|
|
36
|
+
recordCount: number;
|
|
37
|
+
hasData: boolean;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Hook for managing multiple DataSources with SSR
|
|
41
|
+
*/
|
|
42
|
+
export declare function useArchbaseSSRDataSources<T extends Record<string, any>, ID>(dataSources: Array<{
|
|
43
|
+
name: string;
|
|
44
|
+
options?: UseArchbaseSSRDataSourceOptions<T, ID>;
|
|
45
|
+
}>): {
|
|
46
|
+
sources: {
|
|
47
|
+
dataSource: ArchbaseSSRDataSource<T, ID>;
|
|
48
|
+
isLoading: boolean;
|
|
49
|
+
error: Error | null;
|
|
50
|
+
isHydrated: boolean;
|
|
51
|
+
serializeState: () => string;
|
|
52
|
+
deserializeState: (serializedState: string) => void;
|
|
53
|
+
getMinimalState: () => {
|
|
54
|
+
recordCount: number;
|
|
55
|
+
currentIndex: number;
|
|
56
|
+
hasData: boolean;
|
|
57
|
+
isActive: boolean;
|
|
58
|
+
};
|
|
59
|
+
refresh: (newRecords?: T[] | undefined) => Promise<void>;
|
|
60
|
+
records: T[];
|
|
61
|
+
currentRecord: T | undefined;
|
|
62
|
+
recordCount: number;
|
|
63
|
+
hasData: boolean;
|
|
64
|
+
name: string;
|
|
65
|
+
}[];
|
|
66
|
+
getDataSource: (name: string) => {
|
|
67
|
+
dataSource: ArchbaseSSRDataSource<T, ID>;
|
|
68
|
+
isLoading: boolean;
|
|
69
|
+
error: Error | null;
|
|
70
|
+
isHydrated: boolean;
|
|
71
|
+
serializeState: () => string;
|
|
72
|
+
deserializeState: (serializedState: string) => void;
|
|
73
|
+
getMinimalState: () => {
|
|
74
|
+
recordCount: number;
|
|
75
|
+
currentIndex: number;
|
|
76
|
+
hasData: boolean;
|
|
77
|
+
isActive: boolean;
|
|
78
|
+
};
|
|
79
|
+
refresh: (newRecords?: T[] | undefined) => Promise<void>;
|
|
80
|
+
records: T[];
|
|
81
|
+
currentRecord: T | undefined;
|
|
82
|
+
recordCount: number;
|
|
83
|
+
hasData: boolean;
|
|
84
|
+
name: string;
|
|
85
|
+
} | undefined;
|
|
86
|
+
serializeAll: () => Record<string, string>;
|
|
87
|
+
isAnyLoading: boolean;
|
|
88
|
+
errors: {
|
|
89
|
+
name: string;
|
|
90
|
+
error: Error | null;
|
|
91
|
+
}[];
|
|
92
|
+
isHydrated: boolean;
|
|
93
|
+
};
|
|
94
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { isServer, isClient, canUseDOM, safeLocalStorage, safeSessionStorage, serializeForSSR, deserializeFromSSR, createSSRId, resetSSRIdCounter, getWindow, getDocument, hasFeature, withSSRFallback, clientOnly, serverOnly, createHydrationSafeValue, getMediaQuery, type MediaQueryResult } from './utils/ArchbaseSSRUtils';
|
|
2
|
+
export { ArchbaseSSRProvider, useArchbaseSSR, useHydrationSafeState, ClientOnly, ServerOnly, useClientEffect, useSSRSafeMediaQuery } from './providers/ArchbaseSSRProvider';
|
|
3
|
+
export { ArchbaseSSRDataSource } from './datasource/ArchbaseSSRDataSource';
|
|
4
|
+
export { useArchbaseSSRDataSource, useArchbaseSSRDataSources } from './hooks/useArchbaseSSRDataSource';
|
|
5
|
+
export { ArchbaseTanStackProvider, useArchbaseQuery, serializeQueryClientState, prepareServerQueries, withArchbaseTanStack } from './tanstack/ArchbaseTanStackIntegration';
|
|
6
|
+
export declare const ArchbaseSSRVersion = "3.0.0";
|