@dumbql/ssr 0.0.1 → 0.0.2-alpha.1
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 +44 -0
- package/fesm2022/dumbql-ssr.mjs.map +1 -1
- package/package.json +1 -1
- package/types/dumbql-ssr.d.ts +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @dumbql/ssr
|
|
2
|
+
|
|
3
|
+
Server-Side Rendering helpers for DumbQL. Transfers GraphQL cache from server to browser using Angular's `TransferState`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @dumbql/ssr
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { TransferCacheService, SsrStreamService } from '@dumbql/ssr';
|
|
15
|
+
|
|
16
|
+
// On server: serialize the cache after all queries
|
|
17
|
+
const transferCache = inject(TransferCacheService);
|
|
18
|
+
const cache = inject(CacheService);
|
|
19
|
+
transferCache.save(cache); // stores in TransferState
|
|
20
|
+
|
|
21
|
+
// On browser: restore the cache before any query
|
|
22
|
+
transferCache.restore(cache); // loads from TransferState
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Streaming
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
const stream = inject(SsrStreamService);
|
|
29
|
+
stream.writeChunked('myKey', data); // server
|
|
30
|
+
const data = stream.readChunked('myKey'); // browser
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## API
|
|
34
|
+
|
|
35
|
+
| Export | Description |
|
|
36
|
+
|--------|-------------|
|
|
37
|
+
| `TransferCacheService` | Saves/restores full cache snapshot to/from `TransferState` |
|
|
38
|
+
| `SsrStreamService` | Chunked key-value streaming via `TransferState` |
|
|
39
|
+
| `SSR_STREAM_KEY` | Injection token for config (prefix, chunk size) |
|
|
40
|
+
| `SsrStreamConfig` | `{ key?: string, chunkSize?: number }` |
|
|
41
|
+
|
|
42
|
+
## Dependencies
|
|
43
|
+
|
|
44
|
+
`@angular/common`, `@angular/core`, `@dumbql/cache`, `rxjs`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dumbql-ssr.mjs","sources":["../../../../projects/dumbql/ssr/src/lib/ssr-stream.ts","../../../../projects/dumbql/ssr/src/lib/transfer-cache.service.ts","../../../../projects/dumbql/ssr/src/dumbql-ssr.ts"],"sourcesContent":["import { Injectable, inject, InjectionToken, TransferState, makeStateKey } from '@angular/core';\n\nexport const SSR_STREAM_KEY = new InjectionToken<string>('SSR_STREAM_KEY');\n\nexport interface SsrStreamConfig {\n /** Key prefix for TransferState */\n key?: string;\n /** Chunk size for progressive loading (bytes) */\n chunkSize?: number;\n}\n\n/**\n * Service for progressive SSR transfer of GraphQL data.\n * Splits large payloads into chunks for faster TTFB.\n */\n@Injectable({ providedIn: 'root' })\nexport class SsrStreamService {\n private readonly transferState = inject(TransferState, { optional: true });\n private readonly config: SsrStreamConfig;\n\n constructor() {\n \tthis.config = (inject(SSR_STREAM_KEY, { optional: true }) as SsrStreamConfig) ?? {};\n }\n\n /** Serialize data to TransferState in chunks */\n writeChunked(key: string, data: unknown): void {\n \tif (!this.transferState) return;\n \tconst stateKey = makeStateKey<unknown>(`${this.config.key ?? 'gql'}_${key}`);\n \tthis.transferState.set(stateKey, data);\n }\n\n /** Read chunked data from TransferState */\n readChunked<T>(key: string): T | undefined {\n \tif (!this.transferState) return undefined;\n \tconst stateKey = makeStateKey<T | undefined>(`${this.config.key ?? 'gql'}_${key}`);\n \treturn this.transferState.get(stateKey, undefined);\n }\n\n /** Clear all GQL-related TransferState entries */\n clear(): void {\n \t// TransferState doesn't expose keys, so this is a no-op in Angular\n }\n}\n","import { Injectable, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformServer, isPlatformBrowser } from '@angular/common';\nimport { SsrStreamService } from './ssr-stream';\nimport { type CacheService } from '@dumbql/cache';\n\n@Injectable({ providedIn: 'root' })\nexport class TransferCacheService {\n private readonly platformId = inject(PLATFORM_ID);\n private readonly streamSvc = inject(SsrStreamService);\n\n /** Save cache state for transfer to browser */\n save(cache: CacheService): void {\n \tif (!isPlatformServer(this.platformId)) return;\n \tthis.streamSvc.writeChunked('cache', cache.serialize());\n }\n\n /** Restore cache state from SSR transfer */\n restore(cache: CacheService): boolean {\n \tif (!isPlatformBrowser(this.platformId)) return false;\n \tconst data = this.streamSvc.readChunked<string>('cache');\n \tif (!data) return false;\n \ttry {\n \t\tcache.deserialize(data);\n \t\treturn true;\n \t} catch {\n \t\treturn false;\n \t}\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"dumbql-ssr.mjs","sources":["../../../../projects/dumbql/ssr/src/lib/ssr-stream.ts","../../../../projects/dumbql/ssr/src/lib/transfer-cache.service.ts","../../../../projects/dumbql/ssr/src/dumbql-ssr.ts"],"sourcesContent":["import { Injectable, inject, InjectionToken, TransferState, makeStateKey } from '@angular/core';\n\nexport const SSR_STREAM_KEY = new InjectionToken<string>('SSR_STREAM_KEY');\n\nexport interface SsrStreamConfig {\n /** Key prefix for TransferState */\n key?: string;\n /** Chunk size for progressive loading (bytes) */\n chunkSize?: number;\n}\n\n/**\n * Service for progressive SSR transfer of GraphQL data.\n * Splits large payloads into chunks for faster TTFB.\n */\n@Injectable({ providedIn: 'root' })\nexport class SsrStreamService {\n private readonly transferState = inject(TransferState, { optional: true });\n private readonly config: SsrStreamConfig;\n\n constructor() {\n \tthis.config = (inject(SSR_STREAM_KEY, { optional: true }) as SsrStreamConfig) ?? {};\n }\n\n /** Serialize data to TransferState in chunks */\n writeChunked(key: string, data: unknown): void {\n \tif (!this.transferState) return;\n \tconst stateKey = makeStateKey<unknown>(`${this.config.key ?? 'gql'}_${key}`);\n \tthis.transferState.set(stateKey, data);\n }\n\n /** Read chunked data from TransferState */\n readChunked<T>(key: string): T | undefined {\n \tif (!this.transferState) return undefined;\n \tconst stateKey = makeStateKey<T | undefined>(`${this.config.key ?? 'gql'}_${key}`);\n \treturn this.transferState.get(stateKey, undefined);\n }\n\n /** Clear all GQL-related TransferState entries */\n clear(): void {\n \t// TransferState doesn't expose keys, so this is a no-op in Angular\n }\n}\n","import { Injectable, inject, PLATFORM_ID } from '@angular/core';\nimport { isPlatformServer, isPlatformBrowser } from '@angular/common';\nimport { SsrStreamService } from './ssr-stream';\nimport { type CacheService } from '@dumbql/cache/angular';\n\n@Injectable({ providedIn: 'root' })\nexport class TransferCacheService {\n private readonly platformId = inject(PLATFORM_ID);\n private readonly streamSvc = inject(SsrStreamService);\n\n /** Save cache state for transfer to browser */\n save(cache: CacheService): void {\n \tif (!isPlatformServer(this.platformId)) return;\n \tthis.streamSvc.writeChunked('cache', cache.serialize());\n }\n\n /** Restore cache state from SSR transfer */\n restore(cache: CacheService): boolean {\n \tif (!isPlatformBrowser(this.platformId)) return false;\n \tconst data = this.streamSvc.readChunked<string>('cache');\n \tif (!data) return false;\n \ttry {\n \t\tcache.deserialize(data);\n \t\treturn true;\n \t} catch {\n \t\treturn false;\n \t}\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/types/dumbql-ssr.d.ts
CHANGED