@nexushub/client 0.9.0 → 1.1.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 +36 -1078
- package/dist/chunk-OP3LNZPC.cjs +116 -0
- package/dist/chunk-PB3YCBFH.js +116 -0
- package/dist/cli.cjs +259 -428
- package/dist/content/local-cache-server.cjs +36 -15
- package/dist/content/local-cache-server.d.cts +2 -5
- package/dist/content/local-cache-server.d.ts +2 -5
- package/dist/content/local-cache-server.js +36 -15
- package/dist/index.cjs +662 -341
- package/dist/index.d.cts +221 -32
- package/dist/index.d.ts +221 -32
- package/dist/index.js +652 -341
- package/dist/{local-cache-server-KUGMBMJP.cjs → local-cache-server-EKRKNL6N.cjs} +16 -8
- package/dist/{local-cache-server-RM7T456Z.js → local-cache-server-POO2S6OU.js} +15 -7
- package/dist/react.cjs +971 -374
- package/dist/react.d.cts +193 -76
- package/dist/react.d.ts +193 -76
- package/dist/react.js +1013 -416
- package/package.json +34 -28
- package/dist/chunk-3TDCUTZR.cjs +0 -53
- package/dist/chunk-VQ6IEN4I.js +0 -53
package/dist/index.d.cts
CHANGED
|
@@ -8,12 +8,33 @@ interface MinimalNexusConfig {
|
|
|
8
8
|
}
|
|
9
9
|
declare const DEFAULT_API_URL = "https://api.gnapex.com";
|
|
10
10
|
declare const DEFAULT_ANALYTICS_URL = "https://sentry.gnapex.com";
|
|
11
|
+
declare const SDK_VERSION = "1.1.0";
|
|
11
12
|
declare const LOCAL_NEST_URL = "https://api.gnapex.com";
|
|
12
13
|
declare const LOCAL_RUST_URL = "https://sentry.gnapex.com";
|
|
14
|
+
/**
|
|
15
|
+
* Automatically discovers runtime configuration across:
|
|
16
|
+
* 1. Window Global (__GNAPEX__ or __NEXUS__)
|
|
17
|
+
* 2. HTML Meta Tags (<meta name="gnapex-project"> / <meta name="nexus-project">)
|
|
18
|
+
* 3. Next.js Public Environment Variables (NEXT_PUBLIC_GNAPEX_* / NEXT_PUBLIC_NEXUS_*)
|
|
19
|
+
* 4. Node.js Standard Process Variables (GNAPEX_* / NEXUS_*)
|
|
20
|
+
*/
|
|
13
21
|
declare const getEnvConfig: () => MinimalNexusConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Merges discovered configuration with manual constructor overrides
|
|
24
|
+
*/
|
|
14
25
|
declare const mergeConfigs: (base: MinimalNexusConfig, override: Partial<MinimalNexusConfig>) => MinimalNexusConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Returns complete resolved configuration snapshot
|
|
28
|
+
*/
|
|
15
29
|
declare const getFullConfig: (partialConfig?: Partial<MinimalNexusConfig>) => MinimalNexusConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Validates configuration integrity
|
|
32
|
+
*/
|
|
16
33
|
declare const validateConfig: (config: MinimalNexusConfig) => string[];
|
|
34
|
+
/**
|
|
35
|
+
* Helper to check if required keys exist
|
|
36
|
+
*/
|
|
37
|
+
declare const hasRequiredConfig: (config: MinimalNexusConfig) => boolean;
|
|
17
38
|
|
|
18
39
|
interface NexusConfig extends MinimalNexusConfig {
|
|
19
40
|
debug?: boolean;
|
|
@@ -21,6 +42,18 @@ interface NexusConfig extends MinimalNexusConfig {
|
|
|
21
42
|
revalidateTime?: number | false;
|
|
22
43
|
timeout?: number;
|
|
23
44
|
retries?: number;
|
|
45
|
+
/** Internal/runtime version; populated automatically. */
|
|
46
|
+
sdkVersion?: string;
|
|
47
|
+
/** GN-Apex owns cache invalidation. Forever is intentional by default. */
|
|
48
|
+
cacheInvalidation?: "platform" | "manual";
|
|
49
|
+
environment?: "development" | "staging" | "production";
|
|
50
|
+
privacy?: {
|
|
51
|
+
analytics?: boolean;
|
|
52
|
+
fingerprinting?: boolean;
|
|
53
|
+
redact?: boolean;
|
|
54
|
+
};
|
|
55
|
+
autoTracking?: boolean;
|
|
56
|
+
publicKeyOnly?: boolean;
|
|
24
57
|
}
|
|
25
58
|
interface NexusConfig {
|
|
26
59
|
projectId: string;
|
|
@@ -92,6 +125,8 @@ declare class ContentEngine {
|
|
|
92
125
|
private abortController?;
|
|
93
126
|
private isServer;
|
|
94
127
|
constructor(config: NexusConfig);
|
|
128
|
+
/** Update runtime configuration without exposing internal mutation. */
|
|
129
|
+
updateConfig(config: NexusConfig): void;
|
|
95
130
|
/**
|
|
96
131
|
* Fetch a Single Page with full strategy pipeline
|
|
97
132
|
*/
|
|
@@ -113,7 +148,7 @@ declare class ContentEngine {
|
|
|
113
148
|
}): Promise<CollectionResponse<T>>;
|
|
114
149
|
private _getCollection;
|
|
115
150
|
/**
|
|
116
|
-
* Fetch Global Settings
|
|
151
|
+
* Fetch Global Settings
|
|
117
152
|
*/
|
|
118
153
|
getGlobals<T = any>(options?: {
|
|
119
154
|
include?: string[];
|
|
@@ -142,31 +177,11 @@ declare class ContentEngine {
|
|
|
142
177
|
total: number;
|
|
143
178
|
}>;
|
|
144
179
|
/**
|
|
145
|
-
* Prefetch content
|
|
180
|
+
* Prefetch content
|
|
146
181
|
*/
|
|
147
182
|
prefetch(urls: string[]): Promise<void>;
|
|
148
183
|
/**
|
|
149
184
|
* Robust Real-time Subscriptions (SSE) with Auto-Reconnect
|
|
150
|
-
*
|
|
151
|
-
* ⚠️ SCOPE — READ BEFORE RELYING ON THIS FOR "instant" UPDATES:
|
|
152
|
-
* This connects from the BROWSER TAB it's called in, and on message it
|
|
153
|
-
* only clears THIS SDK INSTANCE's in-memory `memoryCache` (via
|
|
154
|
-
* invalidateCache below) in THAT browser tab's JS heap. In a typical
|
|
155
|
-
* Next.js deployment — and Cloudflare specifically, which is stateless
|
|
156
|
-
* per-request at the edge — that is a different process/isolate than the
|
|
157
|
-
* one that will render the NEXT server request for this content. So:
|
|
158
|
-
* - ✅ Useful for: a client component that reads from `nexus.content`
|
|
159
|
-
* directly in the browser and re-renders in place without a page
|
|
160
|
-
* navigation (e.g. a live-updating dashboard widget).
|
|
161
|
-
* - ❌ NOT sufficient for: "user A edits content in the CMS, user B's
|
|
162
|
-
* already-loaded page updates" via a server-rendered page. That
|
|
163
|
-
* requires the backend's /api/revalidate webhook (see
|
|
164
|
-
* content.service.ts `pingNextRevalidateWebhook`) to have actually
|
|
165
|
-
* cleared the *server's* Data Cache, so the NEXT navigation or
|
|
166
|
-
* server request picks up fresh data. This SSE channel does not
|
|
167
|
-
* replace that — it's a complementary, browser-local optimization.
|
|
168
|
-
* If your symptom was "stale content after editing," fix the webhook
|
|
169
|
-
* wiring first; treat this method as an enhancement layered on top.
|
|
170
185
|
*/
|
|
171
186
|
subscribeToUpdates(callback: (data: any) => void): () => void;
|
|
172
187
|
private checkCaches;
|
|
@@ -193,9 +208,13 @@ declare class ContentEngine {
|
|
|
193
208
|
private fetchWithTimeout;
|
|
194
209
|
private getHeaders;
|
|
195
210
|
private isCacheValid;
|
|
211
|
+
/**
|
|
212
|
+
* 🛡️ FIX: Normalizes timeout errors (AbortError, 408, or Timeout messages)
|
|
213
|
+
* into clean, standardized "Request timeout" errors.
|
|
214
|
+
*/
|
|
196
215
|
private normalizeError;
|
|
197
216
|
cancelRequests(): void;
|
|
198
|
-
|
|
217
|
+
cleanup(): void;
|
|
199
218
|
}
|
|
200
219
|
|
|
201
220
|
declare class AnalyticsEngine {
|
|
@@ -243,28 +262,184 @@ declare class AnalyticsEngine {
|
|
|
243
262
|
stop(isFinalShutdown?: boolean): void;
|
|
244
263
|
}
|
|
245
264
|
|
|
265
|
+
type NexusEventMap = {
|
|
266
|
+
"request:start": {
|
|
267
|
+
requestId: string;
|
|
268
|
+
url: string;
|
|
269
|
+
method: string;
|
|
270
|
+
};
|
|
271
|
+
"request:end": {
|
|
272
|
+
requestId: string;
|
|
273
|
+
url: string;
|
|
274
|
+
status: number;
|
|
275
|
+
duration: number;
|
|
276
|
+
};
|
|
277
|
+
"cache:hit": {
|
|
278
|
+
key: string;
|
|
279
|
+
stale?: boolean;
|
|
280
|
+
};
|
|
281
|
+
"cache:miss": {
|
|
282
|
+
key: string;
|
|
283
|
+
};
|
|
284
|
+
"analytics:queued": {
|
|
285
|
+
count: number;
|
|
286
|
+
};
|
|
287
|
+
"analytics:flushed": {
|
|
288
|
+
sent: number;
|
|
289
|
+
remaining: number;
|
|
290
|
+
};
|
|
291
|
+
"content:updated": {
|
|
292
|
+
type: string;
|
|
293
|
+
slug?: string;
|
|
294
|
+
collectionId?: string;
|
|
295
|
+
id?: string;
|
|
296
|
+
};
|
|
297
|
+
"error": {
|
|
298
|
+
error: unknown;
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
type Listener<T> = (payload: T) => void;
|
|
302
|
+
declare class NexusEventBus<M extends Record<string, any> = NexusEventMap> {
|
|
303
|
+
private listeners;
|
|
304
|
+
on<K extends keyof M>(event: K, listener: Listener<M[K]>): () => void;
|
|
305
|
+
emit<K extends keyof M>(event: K, payload: M[K]): void;
|
|
306
|
+
clear(): void;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
interface NexusRequestOptions extends RequestInit {
|
|
310
|
+
timeout?: number;
|
|
311
|
+
retries?: number;
|
|
312
|
+
next?: {
|
|
313
|
+
tags?: string[];
|
|
314
|
+
revalidate?: number | false;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
declare class NexusHttpClient {
|
|
318
|
+
private config;
|
|
319
|
+
private events;
|
|
320
|
+
private readonly limiter;
|
|
321
|
+
private readonly breaker;
|
|
322
|
+
private readonly backoff;
|
|
323
|
+
constructor(config: NexusConfig, events?: NexusEventBus<NexusEventMap>);
|
|
324
|
+
updateConfig(config: NexusConfig): void;
|
|
325
|
+
request(input: string, options?: NexusRequestOptions): Promise<Response>;
|
|
326
|
+
getStats(): {
|
|
327
|
+
rateLimit: {
|
|
328
|
+
currentRequests: number;
|
|
329
|
+
limit: number;
|
|
330
|
+
};
|
|
331
|
+
circuit: string;
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
declare class FeatureFlags {
|
|
336
|
+
private values;
|
|
337
|
+
constructor(initial?: Record<string, any>);
|
|
338
|
+
set(values: Record<string, any>): void;
|
|
339
|
+
isEnabled(key: string, fallback?: boolean): boolean;
|
|
340
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
341
|
+
all(): {
|
|
342
|
+
[x: string]: any;
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
declare class RemoteConfig {
|
|
346
|
+
private values;
|
|
347
|
+
set(values: Record<string, any>): void;
|
|
348
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
349
|
+
all(): {
|
|
350
|
+
[x: string]: any;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* GN-Apex client: intentionally zero-config for GN-Apex generated sites.
|
|
356
|
+
* Platform configuration is discovered automatically; explicit overrides are
|
|
357
|
+
* an escape hatch for SDK consumers, not a requirement for site developers.
|
|
358
|
+
* Cache revalidation is FALSE by default on purpose: GN-Apex/Cloudflare owns
|
|
359
|
+
* invalidation and purge, so immutable content can stay cached indefinitely.
|
|
360
|
+
*/
|
|
246
361
|
declare class NexusClient {
|
|
247
362
|
private config;
|
|
248
363
|
content: ContentEngine;
|
|
249
364
|
analytics?: AnalyticsEngine;
|
|
365
|
+
readonly events: NexusEventBus;
|
|
366
|
+
readonly http: NexusHttpClient;
|
|
367
|
+
readonly flags: FeatureFlags;
|
|
368
|
+
readonly remoteConfig: RemoteConfig;
|
|
250
369
|
constructor(config?: Partial<NexusConfig>);
|
|
251
370
|
/**
|
|
252
|
-
* Helper alias for cleaner content fetching.
|
|
371
|
+
* Helper alias for cleaner page content fetching.
|
|
253
372
|
*/
|
|
254
373
|
getPage<T = any>(slug: string, options?: any): Promise<T>;
|
|
255
374
|
/**
|
|
256
|
-
* Returns a readonly snapshot of the
|
|
375
|
+
* Returns a readonly snapshot of the active configuration.
|
|
257
376
|
*/
|
|
258
377
|
getConfig(): Readonly<NexusConfig>;
|
|
259
378
|
/**
|
|
260
|
-
* Updates
|
|
261
|
-
* Replaces the previous pattern of `(nexus as any).config.projectId = x`
|
|
262
|
-
* which bypassed TypeScript and mutated internal state unsafely.
|
|
379
|
+
* Updates runtime configuration dynamically without breaking active listeners.
|
|
263
380
|
*/
|
|
264
381
|
updateConfig(updates: Partial<NexusConfig>): void;
|
|
382
|
+
/**
|
|
383
|
+
* Returns deep system diagnostics including HTTP and cache performance.
|
|
384
|
+
*/
|
|
385
|
+
diagnostics(): {
|
|
386
|
+
cache: {
|
|
387
|
+
memory: {
|
|
388
|
+
size: number;
|
|
389
|
+
hits: number;
|
|
390
|
+
misses: number;
|
|
391
|
+
hitRate: number;
|
|
392
|
+
};
|
|
393
|
+
browser: {
|
|
394
|
+
size: number;
|
|
395
|
+
} | null;
|
|
396
|
+
local: {
|
|
397
|
+
loaded: boolean;
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
http: {
|
|
401
|
+
rateLimit: {
|
|
402
|
+
currentRequests: number;
|
|
403
|
+
limit: number;
|
|
404
|
+
};
|
|
405
|
+
circuit: string;
|
|
406
|
+
};
|
|
407
|
+
analyticsQueue: number | undefined;
|
|
408
|
+
version: string;
|
|
409
|
+
environment: string;
|
|
410
|
+
online: boolean;
|
|
411
|
+
userAgent?: string;
|
|
412
|
+
memory?: number;
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
* Gracefully terminates background tasks and cleans up listeners.
|
|
416
|
+
*/
|
|
417
|
+
destroy(): void;
|
|
265
418
|
}
|
|
266
419
|
declare const nexus: NexusClient;
|
|
267
|
-
declare const createNexusClient: (config
|
|
420
|
+
declare const createNexusClient: (config?: Partial<NexusConfig>) => NexusClient;
|
|
421
|
+
|
|
422
|
+
type NexusErrorCode = "CONFIGURATION_ERROR" | "NETWORK_ERROR" | "TIMEOUT" | "ABORTED" | "HTTP_ERROR" | "RATE_LIMITED" | "CIRCUIT_OPEN" | "NOT_FOUND" | "VALIDATION_ERROR" | "STORAGE_ERROR" | "UNKNOWN";
|
|
423
|
+
declare class NexusError extends Error {
|
|
424
|
+
readonly code: NexusErrorCode;
|
|
425
|
+
readonly status?: number | undefined;
|
|
426
|
+
readonly requestId?: string | undefined;
|
|
427
|
+
readonly details?: unknown | undefined;
|
|
428
|
+
readonly retryable: boolean;
|
|
429
|
+
readonly cause?: unknown | undefined;
|
|
430
|
+
readonly name = "NexusError";
|
|
431
|
+
constructor(message: string, code?: NexusErrorCode, status?: number | undefined, requestId?: string | undefined, details?: unknown | undefined, retryable?: boolean, cause?: unknown | undefined);
|
|
432
|
+
}
|
|
433
|
+
declare const isNexusError: (e: unknown) => e is NexusError;
|
|
434
|
+
|
|
435
|
+
interface NexusDiagnostics {
|
|
436
|
+
version: string;
|
|
437
|
+
environment: string;
|
|
438
|
+
online: boolean;
|
|
439
|
+
userAgent?: string;
|
|
440
|
+
memory?: number;
|
|
441
|
+
}
|
|
442
|
+
declare const getDiagnostics: (version: string, environment: string) => NexusDiagnostics;
|
|
268
443
|
|
|
269
444
|
interface SiteUser {
|
|
270
445
|
id: string;
|
|
@@ -319,8 +494,9 @@ interface AuthContextType extends AuthState {
|
|
|
319
494
|
interface CacheOptions {
|
|
320
495
|
maxSize?: number;
|
|
321
496
|
ttl?: number;
|
|
497
|
+
/** false means platform-controlled immutable cache. */
|
|
498
|
+
revalidate?: number | false;
|
|
322
499
|
tags?: string[];
|
|
323
|
-
revalidate?: number;
|
|
324
500
|
}
|
|
325
501
|
interface CacheStats {
|
|
326
502
|
size: number;
|
|
@@ -385,6 +561,19 @@ declare class LocalCacheProxy implements ILocalCache {
|
|
|
385
561
|
getAllData(): Promise<any>;
|
|
386
562
|
}
|
|
387
563
|
|
|
388
|
-
declare
|
|
564
|
+
declare class NexusPushClient {
|
|
565
|
+
private config;
|
|
566
|
+
constructor(config: NexusConfig);
|
|
567
|
+
/**
|
|
568
|
+
* Helper to convert Base64 VAPID key to Uint8Array for WebPush security
|
|
569
|
+
*/
|
|
570
|
+
private urlBase64ToUint8Array;
|
|
571
|
+
/**
|
|
572
|
+
* Requests browser notification permissions and registers the WebPush subscription
|
|
573
|
+
*/
|
|
574
|
+
requestSubscription(serviceWorkerPath?: string): Promise<boolean>;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
declare const VERSION = "1.1.0";
|
|
389
578
|
|
|
390
|
-
export { AnalyticsEngine, type AuthContextType, type AuthError, type AuthState, BrowserCache, type CacheEntry, type CacheMetadata, CacheTags, type CollectionQuery, type CollectionResponse, ContentEngine, type ContentResponse, DEFAULT_ANALYTICS_URL, DEFAULT_API_URL, type ErrorResponse, LOCAL_NEST_URL, LOCAL_RUST_URL, LocalCacheProxy as LocalCache, type LoginCredentials, MemoryCache, type MinimalNexusConfig, NexusClient, type NexusConfig, type RegisterCredentials, type SiteUser, VERSION, createNexusClient, getEnvConfig, getFullConfig, mergeConfigs, nexus, validateConfig };
|
|
579
|
+
export { AnalyticsEngine, type AuthContextType, type AuthError, type AuthState, BrowserCache, type CacheEntry, type CacheMetadata, CacheTags, type CollectionQuery, type CollectionResponse, ContentEngine, type ContentResponse, DEFAULT_ANALYTICS_URL, DEFAULT_API_URL, type ErrorResponse, FeatureFlags, LOCAL_NEST_URL, LOCAL_RUST_URL, LocalCacheProxy as LocalCache, type LoginCredentials, MemoryCache, type MinimalNexusConfig, NexusClient, type NexusConfig, type NexusDiagnostics, NexusError, type NexusErrorCode, NexusEventBus, type NexusEventMap, NexusHttpClient, NexusPushClient, type NexusRequestOptions, type RegisterCredentials, RemoteConfig, SDK_VERSION, type SiteUser, VERSION, createNexusClient, getDiagnostics, getEnvConfig, getFullConfig, hasRequiredConfig, isNexusError, mergeConfigs, nexus, validateConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,12 +8,33 @@ interface MinimalNexusConfig {
|
|
|
8
8
|
}
|
|
9
9
|
declare const DEFAULT_API_URL = "https://api.gnapex.com";
|
|
10
10
|
declare const DEFAULT_ANALYTICS_URL = "https://sentry.gnapex.com";
|
|
11
|
+
declare const SDK_VERSION = "1.1.0";
|
|
11
12
|
declare const LOCAL_NEST_URL = "https://api.gnapex.com";
|
|
12
13
|
declare const LOCAL_RUST_URL = "https://sentry.gnapex.com";
|
|
14
|
+
/**
|
|
15
|
+
* Automatically discovers runtime configuration across:
|
|
16
|
+
* 1. Window Global (__GNAPEX__ or __NEXUS__)
|
|
17
|
+
* 2. HTML Meta Tags (<meta name="gnapex-project"> / <meta name="nexus-project">)
|
|
18
|
+
* 3. Next.js Public Environment Variables (NEXT_PUBLIC_GNAPEX_* / NEXT_PUBLIC_NEXUS_*)
|
|
19
|
+
* 4. Node.js Standard Process Variables (GNAPEX_* / NEXUS_*)
|
|
20
|
+
*/
|
|
13
21
|
declare const getEnvConfig: () => MinimalNexusConfig;
|
|
22
|
+
/**
|
|
23
|
+
* Merges discovered configuration with manual constructor overrides
|
|
24
|
+
*/
|
|
14
25
|
declare const mergeConfigs: (base: MinimalNexusConfig, override: Partial<MinimalNexusConfig>) => MinimalNexusConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Returns complete resolved configuration snapshot
|
|
28
|
+
*/
|
|
15
29
|
declare const getFullConfig: (partialConfig?: Partial<MinimalNexusConfig>) => MinimalNexusConfig;
|
|
30
|
+
/**
|
|
31
|
+
* Validates configuration integrity
|
|
32
|
+
*/
|
|
16
33
|
declare const validateConfig: (config: MinimalNexusConfig) => string[];
|
|
34
|
+
/**
|
|
35
|
+
* Helper to check if required keys exist
|
|
36
|
+
*/
|
|
37
|
+
declare const hasRequiredConfig: (config: MinimalNexusConfig) => boolean;
|
|
17
38
|
|
|
18
39
|
interface NexusConfig extends MinimalNexusConfig {
|
|
19
40
|
debug?: boolean;
|
|
@@ -21,6 +42,18 @@ interface NexusConfig extends MinimalNexusConfig {
|
|
|
21
42
|
revalidateTime?: number | false;
|
|
22
43
|
timeout?: number;
|
|
23
44
|
retries?: number;
|
|
45
|
+
/** Internal/runtime version; populated automatically. */
|
|
46
|
+
sdkVersion?: string;
|
|
47
|
+
/** GN-Apex owns cache invalidation. Forever is intentional by default. */
|
|
48
|
+
cacheInvalidation?: "platform" | "manual";
|
|
49
|
+
environment?: "development" | "staging" | "production";
|
|
50
|
+
privacy?: {
|
|
51
|
+
analytics?: boolean;
|
|
52
|
+
fingerprinting?: boolean;
|
|
53
|
+
redact?: boolean;
|
|
54
|
+
};
|
|
55
|
+
autoTracking?: boolean;
|
|
56
|
+
publicKeyOnly?: boolean;
|
|
24
57
|
}
|
|
25
58
|
interface NexusConfig {
|
|
26
59
|
projectId: string;
|
|
@@ -92,6 +125,8 @@ declare class ContentEngine {
|
|
|
92
125
|
private abortController?;
|
|
93
126
|
private isServer;
|
|
94
127
|
constructor(config: NexusConfig);
|
|
128
|
+
/** Update runtime configuration without exposing internal mutation. */
|
|
129
|
+
updateConfig(config: NexusConfig): void;
|
|
95
130
|
/**
|
|
96
131
|
* Fetch a Single Page with full strategy pipeline
|
|
97
132
|
*/
|
|
@@ -113,7 +148,7 @@ declare class ContentEngine {
|
|
|
113
148
|
}): Promise<CollectionResponse<T>>;
|
|
114
149
|
private _getCollection;
|
|
115
150
|
/**
|
|
116
|
-
* Fetch Global Settings
|
|
151
|
+
* Fetch Global Settings
|
|
117
152
|
*/
|
|
118
153
|
getGlobals<T = any>(options?: {
|
|
119
154
|
include?: string[];
|
|
@@ -142,31 +177,11 @@ declare class ContentEngine {
|
|
|
142
177
|
total: number;
|
|
143
178
|
}>;
|
|
144
179
|
/**
|
|
145
|
-
* Prefetch content
|
|
180
|
+
* Prefetch content
|
|
146
181
|
*/
|
|
147
182
|
prefetch(urls: string[]): Promise<void>;
|
|
148
183
|
/**
|
|
149
184
|
* Robust Real-time Subscriptions (SSE) with Auto-Reconnect
|
|
150
|
-
*
|
|
151
|
-
* ⚠️ SCOPE — READ BEFORE RELYING ON THIS FOR "instant" UPDATES:
|
|
152
|
-
* This connects from the BROWSER TAB it's called in, and on message it
|
|
153
|
-
* only clears THIS SDK INSTANCE's in-memory `memoryCache` (via
|
|
154
|
-
* invalidateCache below) in THAT browser tab's JS heap. In a typical
|
|
155
|
-
* Next.js deployment — and Cloudflare specifically, which is stateless
|
|
156
|
-
* per-request at the edge — that is a different process/isolate than the
|
|
157
|
-
* one that will render the NEXT server request for this content. So:
|
|
158
|
-
* - ✅ Useful for: a client component that reads from `nexus.content`
|
|
159
|
-
* directly in the browser and re-renders in place without a page
|
|
160
|
-
* navigation (e.g. a live-updating dashboard widget).
|
|
161
|
-
* - ❌ NOT sufficient for: "user A edits content in the CMS, user B's
|
|
162
|
-
* already-loaded page updates" via a server-rendered page. That
|
|
163
|
-
* requires the backend's /api/revalidate webhook (see
|
|
164
|
-
* content.service.ts `pingNextRevalidateWebhook`) to have actually
|
|
165
|
-
* cleared the *server's* Data Cache, so the NEXT navigation or
|
|
166
|
-
* server request picks up fresh data. This SSE channel does not
|
|
167
|
-
* replace that — it's a complementary, browser-local optimization.
|
|
168
|
-
* If your symptom was "stale content after editing," fix the webhook
|
|
169
|
-
* wiring first; treat this method as an enhancement layered on top.
|
|
170
185
|
*/
|
|
171
186
|
subscribeToUpdates(callback: (data: any) => void): () => void;
|
|
172
187
|
private checkCaches;
|
|
@@ -193,9 +208,13 @@ declare class ContentEngine {
|
|
|
193
208
|
private fetchWithTimeout;
|
|
194
209
|
private getHeaders;
|
|
195
210
|
private isCacheValid;
|
|
211
|
+
/**
|
|
212
|
+
* 🛡️ FIX: Normalizes timeout errors (AbortError, 408, or Timeout messages)
|
|
213
|
+
* into clean, standardized "Request timeout" errors.
|
|
214
|
+
*/
|
|
196
215
|
private normalizeError;
|
|
197
216
|
cancelRequests(): void;
|
|
198
|
-
|
|
217
|
+
cleanup(): void;
|
|
199
218
|
}
|
|
200
219
|
|
|
201
220
|
declare class AnalyticsEngine {
|
|
@@ -243,28 +262,184 @@ declare class AnalyticsEngine {
|
|
|
243
262
|
stop(isFinalShutdown?: boolean): void;
|
|
244
263
|
}
|
|
245
264
|
|
|
265
|
+
type NexusEventMap = {
|
|
266
|
+
"request:start": {
|
|
267
|
+
requestId: string;
|
|
268
|
+
url: string;
|
|
269
|
+
method: string;
|
|
270
|
+
};
|
|
271
|
+
"request:end": {
|
|
272
|
+
requestId: string;
|
|
273
|
+
url: string;
|
|
274
|
+
status: number;
|
|
275
|
+
duration: number;
|
|
276
|
+
};
|
|
277
|
+
"cache:hit": {
|
|
278
|
+
key: string;
|
|
279
|
+
stale?: boolean;
|
|
280
|
+
};
|
|
281
|
+
"cache:miss": {
|
|
282
|
+
key: string;
|
|
283
|
+
};
|
|
284
|
+
"analytics:queued": {
|
|
285
|
+
count: number;
|
|
286
|
+
};
|
|
287
|
+
"analytics:flushed": {
|
|
288
|
+
sent: number;
|
|
289
|
+
remaining: number;
|
|
290
|
+
};
|
|
291
|
+
"content:updated": {
|
|
292
|
+
type: string;
|
|
293
|
+
slug?: string;
|
|
294
|
+
collectionId?: string;
|
|
295
|
+
id?: string;
|
|
296
|
+
};
|
|
297
|
+
"error": {
|
|
298
|
+
error: unknown;
|
|
299
|
+
};
|
|
300
|
+
};
|
|
301
|
+
type Listener<T> = (payload: T) => void;
|
|
302
|
+
declare class NexusEventBus<M extends Record<string, any> = NexusEventMap> {
|
|
303
|
+
private listeners;
|
|
304
|
+
on<K extends keyof M>(event: K, listener: Listener<M[K]>): () => void;
|
|
305
|
+
emit<K extends keyof M>(event: K, payload: M[K]): void;
|
|
306
|
+
clear(): void;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
interface NexusRequestOptions extends RequestInit {
|
|
310
|
+
timeout?: number;
|
|
311
|
+
retries?: number;
|
|
312
|
+
next?: {
|
|
313
|
+
tags?: string[];
|
|
314
|
+
revalidate?: number | false;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
declare class NexusHttpClient {
|
|
318
|
+
private config;
|
|
319
|
+
private events;
|
|
320
|
+
private readonly limiter;
|
|
321
|
+
private readonly breaker;
|
|
322
|
+
private readonly backoff;
|
|
323
|
+
constructor(config: NexusConfig, events?: NexusEventBus<NexusEventMap>);
|
|
324
|
+
updateConfig(config: NexusConfig): void;
|
|
325
|
+
request(input: string, options?: NexusRequestOptions): Promise<Response>;
|
|
326
|
+
getStats(): {
|
|
327
|
+
rateLimit: {
|
|
328
|
+
currentRequests: number;
|
|
329
|
+
limit: number;
|
|
330
|
+
};
|
|
331
|
+
circuit: string;
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
declare class FeatureFlags {
|
|
336
|
+
private values;
|
|
337
|
+
constructor(initial?: Record<string, any>);
|
|
338
|
+
set(values: Record<string, any>): void;
|
|
339
|
+
isEnabled(key: string, fallback?: boolean): boolean;
|
|
340
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
341
|
+
all(): {
|
|
342
|
+
[x: string]: any;
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
declare class RemoteConfig {
|
|
346
|
+
private values;
|
|
347
|
+
set(values: Record<string, any>): void;
|
|
348
|
+
get<T = any>(key: string, fallback?: T): T;
|
|
349
|
+
all(): {
|
|
350
|
+
[x: string]: any;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* GN-Apex client: intentionally zero-config for GN-Apex generated sites.
|
|
356
|
+
* Platform configuration is discovered automatically; explicit overrides are
|
|
357
|
+
* an escape hatch for SDK consumers, not a requirement for site developers.
|
|
358
|
+
* Cache revalidation is FALSE by default on purpose: GN-Apex/Cloudflare owns
|
|
359
|
+
* invalidation and purge, so immutable content can stay cached indefinitely.
|
|
360
|
+
*/
|
|
246
361
|
declare class NexusClient {
|
|
247
362
|
private config;
|
|
248
363
|
content: ContentEngine;
|
|
249
364
|
analytics?: AnalyticsEngine;
|
|
365
|
+
readonly events: NexusEventBus;
|
|
366
|
+
readonly http: NexusHttpClient;
|
|
367
|
+
readonly flags: FeatureFlags;
|
|
368
|
+
readonly remoteConfig: RemoteConfig;
|
|
250
369
|
constructor(config?: Partial<NexusConfig>);
|
|
251
370
|
/**
|
|
252
|
-
* Helper alias for cleaner content fetching.
|
|
371
|
+
* Helper alias for cleaner page content fetching.
|
|
253
372
|
*/
|
|
254
373
|
getPage<T = any>(slug: string, options?: any): Promise<T>;
|
|
255
374
|
/**
|
|
256
|
-
* Returns a readonly snapshot of the
|
|
375
|
+
* Returns a readonly snapshot of the active configuration.
|
|
257
376
|
*/
|
|
258
377
|
getConfig(): Readonly<NexusConfig>;
|
|
259
378
|
/**
|
|
260
|
-
* Updates
|
|
261
|
-
* Replaces the previous pattern of `(nexus as any).config.projectId = x`
|
|
262
|
-
* which bypassed TypeScript and mutated internal state unsafely.
|
|
379
|
+
* Updates runtime configuration dynamically without breaking active listeners.
|
|
263
380
|
*/
|
|
264
381
|
updateConfig(updates: Partial<NexusConfig>): void;
|
|
382
|
+
/**
|
|
383
|
+
* Returns deep system diagnostics including HTTP and cache performance.
|
|
384
|
+
*/
|
|
385
|
+
diagnostics(): {
|
|
386
|
+
cache: {
|
|
387
|
+
memory: {
|
|
388
|
+
size: number;
|
|
389
|
+
hits: number;
|
|
390
|
+
misses: number;
|
|
391
|
+
hitRate: number;
|
|
392
|
+
};
|
|
393
|
+
browser: {
|
|
394
|
+
size: number;
|
|
395
|
+
} | null;
|
|
396
|
+
local: {
|
|
397
|
+
loaded: boolean;
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
http: {
|
|
401
|
+
rateLimit: {
|
|
402
|
+
currentRequests: number;
|
|
403
|
+
limit: number;
|
|
404
|
+
};
|
|
405
|
+
circuit: string;
|
|
406
|
+
};
|
|
407
|
+
analyticsQueue: number | undefined;
|
|
408
|
+
version: string;
|
|
409
|
+
environment: string;
|
|
410
|
+
online: boolean;
|
|
411
|
+
userAgent?: string;
|
|
412
|
+
memory?: number;
|
|
413
|
+
};
|
|
414
|
+
/**
|
|
415
|
+
* Gracefully terminates background tasks and cleans up listeners.
|
|
416
|
+
*/
|
|
417
|
+
destroy(): void;
|
|
265
418
|
}
|
|
266
419
|
declare const nexus: NexusClient;
|
|
267
|
-
declare const createNexusClient: (config
|
|
420
|
+
declare const createNexusClient: (config?: Partial<NexusConfig>) => NexusClient;
|
|
421
|
+
|
|
422
|
+
type NexusErrorCode = "CONFIGURATION_ERROR" | "NETWORK_ERROR" | "TIMEOUT" | "ABORTED" | "HTTP_ERROR" | "RATE_LIMITED" | "CIRCUIT_OPEN" | "NOT_FOUND" | "VALIDATION_ERROR" | "STORAGE_ERROR" | "UNKNOWN";
|
|
423
|
+
declare class NexusError extends Error {
|
|
424
|
+
readonly code: NexusErrorCode;
|
|
425
|
+
readonly status?: number | undefined;
|
|
426
|
+
readonly requestId?: string | undefined;
|
|
427
|
+
readonly details?: unknown | undefined;
|
|
428
|
+
readonly retryable: boolean;
|
|
429
|
+
readonly cause?: unknown | undefined;
|
|
430
|
+
readonly name = "NexusError";
|
|
431
|
+
constructor(message: string, code?: NexusErrorCode, status?: number | undefined, requestId?: string | undefined, details?: unknown | undefined, retryable?: boolean, cause?: unknown | undefined);
|
|
432
|
+
}
|
|
433
|
+
declare const isNexusError: (e: unknown) => e is NexusError;
|
|
434
|
+
|
|
435
|
+
interface NexusDiagnostics {
|
|
436
|
+
version: string;
|
|
437
|
+
environment: string;
|
|
438
|
+
online: boolean;
|
|
439
|
+
userAgent?: string;
|
|
440
|
+
memory?: number;
|
|
441
|
+
}
|
|
442
|
+
declare const getDiagnostics: (version: string, environment: string) => NexusDiagnostics;
|
|
268
443
|
|
|
269
444
|
interface SiteUser {
|
|
270
445
|
id: string;
|
|
@@ -319,8 +494,9 @@ interface AuthContextType extends AuthState {
|
|
|
319
494
|
interface CacheOptions {
|
|
320
495
|
maxSize?: number;
|
|
321
496
|
ttl?: number;
|
|
497
|
+
/** false means platform-controlled immutable cache. */
|
|
498
|
+
revalidate?: number | false;
|
|
322
499
|
tags?: string[];
|
|
323
|
-
revalidate?: number;
|
|
324
500
|
}
|
|
325
501
|
interface CacheStats {
|
|
326
502
|
size: number;
|
|
@@ -385,6 +561,19 @@ declare class LocalCacheProxy implements ILocalCache {
|
|
|
385
561
|
getAllData(): Promise<any>;
|
|
386
562
|
}
|
|
387
563
|
|
|
388
|
-
declare
|
|
564
|
+
declare class NexusPushClient {
|
|
565
|
+
private config;
|
|
566
|
+
constructor(config: NexusConfig);
|
|
567
|
+
/**
|
|
568
|
+
* Helper to convert Base64 VAPID key to Uint8Array for WebPush security
|
|
569
|
+
*/
|
|
570
|
+
private urlBase64ToUint8Array;
|
|
571
|
+
/**
|
|
572
|
+
* Requests browser notification permissions and registers the WebPush subscription
|
|
573
|
+
*/
|
|
574
|
+
requestSubscription(serviceWorkerPath?: string): Promise<boolean>;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
declare const VERSION = "1.1.0";
|
|
389
578
|
|
|
390
|
-
export { AnalyticsEngine, type AuthContextType, type AuthError, type AuthState, BrowserCache, type CacheEntry, type CacheMetadata, CacheTags, type CollectionQuery, type CollectionResponse, ContentEngine, type ContentResponse, DEFAULT_ANALYTICS_URL, DEFAULT_API_URL, type ErrorResponse, LOCAL_NEST_URL, LOCAL_RUST_URL, LocalCacheProxy as LocalCache, type LoginCredentials, MemoryCache, type MinimalNexusConfig, NexusClient, type NexusConfig, type RegisterCredentials, type SiteUser, VERSION, createNexusClient, getEnvConfig, getFullConfig, mergeConfigs, nexus, validateConfig };
|
|
579
|
+
export { AnalyticsEngine, type AuthContextType, type AuthError, type AuthState, BrowserCache, type CacheEntry, type CacheMetadata, CacheTags, type CollectionQuery, type CollectionResponse, ContentEngine, type ContentResponse, DEFAULT_ANALYTICS_URL, DEFAULT_API_URL, type ErrorResponse, FeatureFlags, LOCAL_NEST_URL, LOCAL_RUST_URL, LocalCacheProxy as LocalCache, type LoginCredentials, MemoryCache, type MinimalNexusConfig, NexusClient, type NexusConfig, type NexusDiagnostics, NexusError, type NexusErrorCode, NexusEventBus, type NexusEventMap, NexusHttpClient, NexusPushClient, type NexusRequestOptions, type RegisterCredentials, RemoteConfig, SDK_VERSION, type SiteUser, VERSION, createNexusClient, getDiagnostics, getEnvConfig, getFullConfig, hasRequiredConfig, isNexusError, mergeConfigs, nexus, validateConfig };
|