@bereasoftware/nexa 1.7.0 → 1.8.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.
@@ -0,0 +1 @@
1
+ export declare function isDevelopmentEnv(): boolean;
@@ -0,0 +1,3 @@
1
+ export declare function escapeHtml(value: string): string;
2
+ export declare function truncateUrl(url: string, max?: number): string;
3
+ export declare function formatJson(data: unknown): string;
@@ -31,8 +31,6 @@ export declare class DevOverlayUI {
31
31
  private exportHistory;
32
32
  private copyAsFetch;
33
33
  private showNotification;
34
- private truncateUrl;
35
- private formatJson;
36
34
  private canUseDOM;
37
35
  private createFloatingIcon;
38
36
  private showFloatingIcon;
@@ -0,0 +1,6 @@
1
+ import type { TrackedRequest, DevMetrics } from './types';
2
+ export type FilterType = 'all' | 'xhr' | 'fetch' | 'err' | 'slow';
3
+ export declare function filterRequests(requests: TrackedRequest[], filterType: FilterType, searchQuery: string): TrackedRequest[];
4
+ export declare function renderRequestListHtml(requests: TrackedRequest[], searchQuery: string): string;
5
+ export declare function renderMetricsHtml(m: DevMetrics): string;
6
+ export declare function renderDetailHtml(request: TrackedRequest): string;
@@ -0,0 +1,40 @@
1
+ export declare const ICONS: {
2
+ gear: string;
3
+ close: string;
4
+ chevron: string;
5
+ back: string;
6
+ retry: string;
7
+ clear: string;
8
+ search: string;
9
+ clock: string;
10
+ zap: string;
11
+ download: string;
12
+ copy: string;
13
+ };
14
+ export declare const COLORS: {
15
+ bg: string;
16
+ bgElevated: string;
17
+ bgSurface: string;
18
+ border: string;
19
+ borderFocus: string;
20
+ text: string;
21
+ textMuted: string;
22
+ textDim: string;
23
+ accent: string;
24
+ accentHover: string;
25
+ accentSoft: string;
26
+ success: string;
27
+ successBg: string;
28
+ error: string;
29
+ errorBg: string;
30
+ warning: string;
31
+ warningBg: string;
32
+ info: string;
33
+ infoBg: string;
34
+ get: string;
35
+ post: string;
36
+ put: string;
37
+ patch: string;
38
+ delete: string;
39
+ };
40
+ export declare const STYLES: string;
@@ -1,18 +1,24 @@
1
1
  import type { TrackedRequest, DevMetrics, DevOverlayConfig } from './types';
2
2
  export declare function loadPersistedConfig(): Partial<DevOverlayConfig>;
3
3
  export declare class RequestTracker {
4
- private history;
4
+ /** Fixed-size ring buffer; `buffer[writeIndex]` is the next slot to overwrite. */
5
+ private buffer;
6
+ private writeIndex;
7
+ private count;
5
8
  private maxHistory;
6
9
  private listeners;
7
10
  private startTime;
8
11
  private config;
9
12
  constructor(config?: DevOverlayConfig);
10
13
  track(request: Omit<TrackedRequest, 'id' | 'timestamp'>): TrackedRequest;
14
+ /** Returns a fresh array, newest first. O(n) — safe to call on every render. */
11
15
  getHistory(): TrackedRequest[];
12
16
  getMetrics(): DevMetrics;
13
17
  clear(): void;
14
18
  onChange(listener: (request: TrackedRequest) => void): () => void;
15
19
  getConfig(): Required<DevOverlayConfig>;
16
20
  updateConfig(partial: Partial<DevOverlayConfig>): Required<DevOverlayConfig>;
21
+ /** Rebuilds the ring buffer at a new capacity, keeping the most recent entries. */
22
+ private resizeHistory;
17
23
  private generateId;
18
24
  }
@@ -58,6 +58,12 @@ export declare class HttpClient implements IHttpClient {
58
58
  post<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
59
59
  put<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
60
60
  patch<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
61
+ /**
62
+ * Safe, idempotent request carrying a JSON body (IETF-draft HTTP QUERY
63
+ * method). Use it for complex search/filter payloads that don't fit in a
64
+ * URL. Cacheable like GET when `config.cache` is enabled.
65
+ */
66
+ query<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
61
67
  delete<T = unknown>(url: string, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
62
68
  head(url: string, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<void>, HttpErrorDetails>>;
63
69
  options(url: string, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<void>, HttpErrorDetails>>;
@@ -120,6 +126,7 @@ export declare class HttpClient implements IHttpClient {
120
126
  poll<T = unknown>(url: string, options: PollOptions<T>, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
121
127
  private buildRequest;
122
128
  private buildUrl;
129
+ private isCacheableMethod;
123
130
  private getCacheKey;
124
131
  private fetchWithTimeout;
125
132
  /**
@@ -2,6 +2,6 @@
2
2
  * HTTP Client Plugin - Main Exports
3
3
  */
4
4
  export { createHttpClient, HttpClient, HttpError, isHttpError, } from './http-client.js';
5
- export type { IHttpClient, HttpRequest, HttpRequestConfig, HttpResponse, HttpErrorDetails, RequestInterceptor, ResponseInterceptor, RetryStrategy, CacheStrategy, Validator, Transformer, HttpClientConfig, ResponseType, RequestHooks, ProgressEvent, PaginateOptions, PollOptions, Disposer, Result, } from '../types/index.js';
5
+ export type { IHttpClient, HttpRequest, HttpRequestConfig, HttpResponse, HttpErrorDetails, RequestInterceptor, ResponseInterceptor, RetryStrategy, CacheStrategy, Validator, Transformer, HttpClientConfig, ResponseType, RequestHooks, ProgressEvent, PaginateOptions, PollOptions, Disposer, Result, QueryParams, QueryParamValue, } from '../types/index.js';
6
6
  export { Ok, Err } from '../types/index.js';
7
7
  export { withTimeout, retry, createSchemaValidator, createRequiredFieldsValidator, validatorIsArray, validatorIsObject, transformSnakeToCamel, transformCamelToSnake, transformFlatten, createProjectionTransformer, createWrapperTransformer, AggressiveRetry, ConservativeRetry, CircuitBreakerRetry, CacheStore, createCacheMiddleware, cacheMiddleware, RequestDeduplicator, createDedupeMiddleware, dedupeMiddleware, MiddlewarePipeline, createPipeline, type Middleware, type HttpContext, createTypedResponse, createTypedRequest, createTypedApiClient, createTypeGuard, createUrl, createApiUrl, TypedObservable, Defer, type TypedResponse, type ApiEndpoint, type ApiSchema, type Url, type ApiUrl, type FileUrl, type UnionToIntersection, type ResultOf, handleStream, streamToFile, createStreamingMiddleware, streamingMiddleware, type StreamOptions, PluginManager, LoggerPlugin, MetricsPlugin, CachePlugin, DedupePlugin, type Plugin, } from '../utils';
@@ -3,7 +3,7 @@
3
3
  * Provides unified API for real-time communication with automatic reconnection,
4
4
  * heartbeat, and plugin support.
5
5
  */
6
- export type { WebSocketOptions, SSEOptions, RealtimeMessageEvent, IRealtimeClient, IWebSocketClient, ISSEClient, } from '../types/index.js';
6
+ export type { WebSocketOptions, SSEOptions, RealtimeMessageEvent, IRealtimeClient, IWebSocketClient, ISSEClient, RealtimeSendError, } from '../types/index.js';
7
7
  export { createWebSocketClient } from './websocket-client.js';
8
8
  export { createSSEClient } from './sse-client.js';
9
9
  export { createRealtimePlugin } from './plugin.js';
@@ -15,12 +15,24 @@ export type Result<T, E = Error> = {
15
15
  };
16
16
  export declare const Ok: <T>(value: T) => Result<T>;
17
17
  export declare const Err: <E>(error: E) => Result<never, E>;
18
+ /**
19
+ * A single query-string value. Arrays are serialized as repeated keys
20
+ * (`?tag=a&tag=b`); nested plain objects use one level of bracket notation
21
+ * (`?filter[status]=active`). `null`/`undefined` values are omitted.
22
+ */
23
+ export type QueryParamValue = string | number | boolean | null | undefined | Array<string | number | boolean> | Record<string, string | number | boolean | null | undefined>;
24
+ export type QueryParams = Record<string, QueryParamValue>;
18
25
  export interface HttpRequest {
19
26
  url: string;
20
- method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
27
+ /**
28
+ * 'QUERY' is the IETF-draft safe/idempotent/cacheable HTTP method that
29
+ * carries a JSON body — use it for complex search/filter payloads that
30
+ * don't fit cleanly in a URL. See `IHttpClient.query()`.
31
+ */
32
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'QUERY';
21
33
  headers?: Record<string, string>;
22
34
  body?: unknown;
23
- query?: Record<string, string | number | boolean>;
35
+ query?: QueryParams;
24
36
  params?: Record<string, string | number>;
25
37
  timeout?: HttpTimeout;
26
38
  signal?: AbortSignal;
@@ -247,6 +259,12 @@ export interface IHttpClient {
247
259
  post<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
248
260
  put<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
249
261
  patch<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
262
+ /**
263
+ * Safe, idempotent request carrying a JSON body — for complex search/filter
264
+ * payloads that don't fit in a URL. Cacheable like GET when `config.cache`
265
+ * is enabled (the body is included in the cache key).
266
+ */
267
+ query<T = unknown>(url: string, body?: unknown, config?: Omit<HttpRequestConfig, 'url' | 'method' | 'body'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
250
268
  delete<T = unknown>(url: string, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<T>, HttpErrorDetails>>;
251
269
  head(url: string, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<void>, HttpErrorDetails>>;
252
270
  options(url: string, config?: Omit<HttpRequestConfig, 'url' | 'method'>): Promise<Result<HttpResponse<void>, HttpErrorDetails>>;
@@ -419,6 +437,13 @@ export interface RealtimeMessageEvent<T = unknown> {
419
437
  /** Timestamp when message was received */
420
438
  timestamp: number;
421
439
  }
440
+ /**
441
+ * Error returned by a failed IRealtimeClient.send()/sendJson() call.
442
+ */
443
+ export interface RealtimeSendError {
444
+ message: string;
445
+ code: 'NOT_CONNECTED' | 'UNSUPPORTED' | 'SEND_FAILED';
446
+ }
422
447
  /**
423
448
  * Real-time client interface
424
449
  */
@@ -427,8 +452,8 @@ export interface IRealtimeClient {
427
452
  connect(): Promise<void>;
428
453
  /** Disconnect from the server */
429
454
  disconnect(): void;
430
- /** Send a message */
431
- send(data: string | ArrayBuffer | Blob): void;
455
+ /** Send a message. Returns a Result instead of throwing on failure. */
456
+ send(data: string | ArrayBuffer | Blob): Result<void, RealtimeSendError>;
432
457
  /** Subscribe to messages */
433
458
  onMessage<T = unknown>(callback: (event: RealtimeMessageEvent<T>) => void): () => void;
434
459
  /** Subscribe to connection open events */
@@ -453,8 +478,8 @@ export interface IRealtimeClient {
453
478
  export interface IWebSocketClient extends IRealtimeClient {
454
479
  /** WebSocket instance */
455
480
  readonly socket: WebSocket | null;
456
- /** Send JSON data (automatically serialized) */
457
- sendJson(data: unknown): void;
481
+ /** Send JSON data (automatically serialized). Returns a Result instead of throwing. */
482
+ sendJson(data: unknown): Result<void, RealtimeSendError>;
458
483
  /** Subscribe to specific message types */
459
484
  onMessageType<T = unknown>(type: string, callback: (data: T) => void): () => void;
460
485
  }
@@ -189,7 +189,7 @@ export declare function createTypedResponse<T, U = unknown>(status: number, data
189
189
  * API Endpoint definition with typed request/response
190
190
  */
191
191
  export interface ApiEndpoint<TRequest = unknown, TResponse = unknown> {
192
- method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
192
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'QUERY';
193
193
  path: string;
194
194
  request?: TRequest;
195
195
  response: TResponse;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bereasoftware/nexa",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "type": "module",
5
5
  "main": "./dist/nexa.cjs.js",
6
6
  "module": "./dist/nexa.es.js",
@@ -25,7 +25,7 @@
25
25
  "registry": "https://registry.npmjs.org/",
26
26
  "access": "public"
27
27
  },
28
- "packageManager": "pnpm@10.21.0",
28
+ "packageManager": "pnpm@11.9.0",
29
29
  "keywords": [
30
30
  "http",
31
31
  "client",
@@ -90,21 +90,21 @@
90
90
  "devDependencies": {
91
91
  "@semantic-release/changelog": "^6.0.3",
92
92
  "@semantic-release/git": "^10.0.1",
93
- "@semantic-release/github": "^12.0.6",
93
+ "@semantic-release/github": "^12.0.8",
94
94
  "@semantic-release/npm": "^13.1.5",
95
- "@types/node": "^25.5.0",
96
- "@typescript-eslint/eslint-plugin": "^8.0.0",
97
- "@typescript-eslint/parser": "^8.0.0",
98
- "@vitest/coverage-v8": "^4.1.2",
99
- "@vitest/ui": "^4.1.2",
100
- "eslint": "^9.0.0",
101
- "husky": "^9.0.0",
102
- "lint-staged": "^15.0.0",
103
- "prettier": "^3.0.0",
104
- "semantic-release": "^25.0.3",
105
- "typescript": "~6.0.2",
106
- "vite": "^8.0.3",
107
- "vitest": "^4.1.2"
95
+ "@types/node": "^26.1.0",
96
+ "@typescript-eslint/eslint-plugin": "^8.62.1",
97
+ "@typescript-eslint/parser": "^8.62.1",
98
+ "@vitest/coverage-v8": "^4.1.9",
99
+ "@vitest/ui": "^4.1.9",
100
+ "eslint": "^10.6.0",
101
+ "husky": "^9.1.7",
102
+ "lint-staged": "^17.0.8",
103
+ "prettier": "^3.9.4",
104
+ "semantic-release": "^25.0.5",
105
+ "typescript": "~6.0.3",
106
+ "vite": "^8.1.2",
107
+ "vitest": "^4.1.9"
108
108
  },
109
109
  "lint-staged": {
110
110
  "*.ts": [
Binary file