@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/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 with nested includes support
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 for better performance
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
- private cleanup;
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 current config.
375
+ * Returns a readonly snapshot of the active configuration.
257
376
  */
258
377
  getConfig(): Readonly<NexusConfig>;
259
378
  /**
260
- * Updates specific config fields at runtime.
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: Partial<NexusConfig>) => NexusClient;
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 const VERSION = "0.0.1";
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 with nested includes support
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 for better performance
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
- private cleanup;
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 current config.
375
+ * Returns a readonly snapshot of the active configuration.
257
376
  */
258
377
  getConfig(): Readonly<NexusConfig>;
259
378
  /**
260
- * Updates specific config fields at runtime.
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: Partial<NexusConfig>) => NexusClient;
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 const VERSION = "0.0.1";
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 };