ocpp-ws-io 2.2.4 → 2.3.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 +3 -3
- package/dist/adapters/redis.d.mts +2 -2
- package/dist/adapters/redis.d.ts +2 -2
- package/dist/adapters/redis.js +1 -1
- package/dist/adapters/redis.mjs +1 -1
- package/dist/browser.js +1 -1
- package/dist/browser.mjs +1 -1
- package/dist/{context-B_y56LLS.d.ts → context-B4-L-O1-.d.ts} +1 -1
- package/dist/{context-BVYqFvfw.d.mts → context-BNELI5Ux.d.mts} +1 -1
- package/dist/express.d.mts +1 -1
- package/dist/express.d.ts +1 -1
- package/dist/fastify.d.mts +2 -2
- package/dist/fastify.d.ts +2 -2
- package/dist/hono.d.mts +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/{index-DrWsObRI.d.ts → index-CEMhGOxh.d.ts} +16 -6
- package/dist/{index-Dr8uXTWu.d.mts → index-Gz98XqQ7.d.mts} +16 -6
- package/dist/index.d.mts +9 -11
- package/dist/index.d.ts +9 -11
- package/dist/index.js +7 -7
- package/dist/index.mjs +7 -7
- package/dist/nestjs.d.mts +1 -1
- package/dist/nestjs.d.ts +1 -1
- package/dist/nestjs.js +8 -8
- package/dist/nestjs.mjs +8 -8
- package/dist/parse-worker.cjs +91 -0
- package/dist/plugins.d.mts +12 -2
- package/dist/plugins.d.ts +12 -2
- package/dist/plugins.js +1 -1
- package/dist/plugins.mjs +1 -1
- package/dist/{types-BsoUgWtt.d.mts → types-tTYOr5Gm.d.mts} +110 -22
- package/dist/{types-BsoUgWtt.d.ts → types-tTYOr5Gm.d.ts} +110 -22
- package/package.json +1 -1
|
@@ -4465,6 +4465,11 @@ declare class OCPPRouter extends OCPPRouter_base {
|
|
|
4465
4465
|
* @internal
|
|
4466
4466
|
*/
|
|
4467
4467
|
_regexPatterns: CompiledRegexPattern[];
|
|
4468
|
+
/**
|
|
4469
|
+
* @internal Set by OCPPServer when the router is registered, so patterns
|
|
4470
|
+
* added after registration still reach the trie / regex list.
|
|
4471
|
+
*/
|
|
4472
|
+
_onPatternAdded?: (pattern: string | RegExp) => void;
|
|
4468
4473
|
constructor(patterns?: Array<string | RegExp>, middlewares?: ConnectionMiddleware[]);
|
|
4469
4474
|
/**
|
|
4470
4475
|
* Appends URL paths or regular expressions to this router's match condition.
|
|
@@ -4573,7 +4578,7 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4573
4578
|
private _pendingResponses;
|
|
4574
4579
|
private _callQueue;
|
|
4575
4580
|
private _pingTimer;
|
|
4576
|
-
|
|
4581
|
+
protected _pongTimer: ReturnType<typeof setTimeout> | null;
|
|
4577
4582
|
private _closePromise;
|
|
4578
4583
|
private _reconnectAttempt;
|
|
4579
4584
|
private _reconnectTimer;
|
|
@@ -4608,6 +4613,11 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4608
4613
|
* The connection endpoint URL.
|
|
4609
4614
|
*/
|
|
4610
4615
|
get endpoint(): string;
|
|
4616
|
+
/**
|
|
4617
|
+
* Bytes currently queued in the underlying WebSocket send buffer
|
|
4618
|
+
* (0 when disconnected). Useful for backpressure monitoring and drain checks.
|
|
4619
|
+
*/
|
|
4620
|
+
get bufferedAmount(): number;
|
|
4611
4621
|
/**
|
|
4612
4622
|
* The current configuration options for this client.
|
|
4613
4623
|
*/
|
|
@@ -4690,6 +4700,11 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4690
4700
|
* Remove a registered handler for a specific version and method.
|
|
4691
4701
|
*/
|
|
4692
4702
|
removeHandler(version: OCPPProtocol, method: string): void;
|
|
4703
|
+
/**
|
|
4704
|
+
* Check whether a handler is registered for a method
|
|
4705
|
+
* (optionally version-scoped, matching the handle() overloads).
|
|
4706
|
+
*/
|
|
4707
|
+
hasHandler(method: string, version?: string): boolean;
|
|
4693
4708
|
/**
|
|
4694
4709
|
* Remove all registered handlers for this client, including the wildcard handler.
|
|
4695
4710
|
*/
|
|
@@ -4715,6 +4730,12 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4715
4730
|
call<M extends AllMethodNames<P>>(method: M, params: OCPPRequestType<P, M>, options?: CallOptions): Promise<OCPPResponseType<P, M>>;
|
|
4716
4731
|
/** Call a known typed method with explicit response type. */
|
|
4717
4732
|
call<TResult = unknown>(method: string, params?: Record<string, unknown>, options?: CallOptions): Promise<TResult>;
|
|
4733
|
+
/**
|
|
4734
|
+
* Execute a call immediately, bypassing the callConcurrency queue.
|
|
4735
|
+
* Used by OCPPServer.sendBatch to pipeline warm-up calls without
|
|
4736
|
+
* mutating the client's configured concurrency (report M9).
|
|
4737
|
+
*/
|
|
4738
|
+
callImmediate<TResult = unknown>(method: string, params?: Record<string, unknown>, options?: CallOptions): Promise<TResult>;
|
|
4718
4739
|
/**
|
|
4719
4740
|
* Version-specific safe call. Returns `undefined` on error instead of throwing.
|
|
4720
4741
|
*/
|
|
@@ -4754,7 +4775,7 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4754
4775
|
* Reject all in-flight calls and clear pending state.
|
|
4755
4776
|
*/
|
|
4756
4777
|
private _rejectPendingCalls;
|
|
4757
|
-
|
|
4778
|
+
protected _onClose(code: number, reason: Buffer): void;
|
|
4758
4779
|
/** Errors that should stop reconnection immediately */
|
|
4759
4780
|
private static readonly _INTOLERABLE_ERRORS;
|
|
4760
4781
|
private _scheduleReconnect;
|
|
@@ -4772,20 +4793,27 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4772
4793
|
private _callWithRetry;
|
|
4773
4794
|
/** Maximum bytes allowed in the ws send buffer before applying backpressure (512KB) */
|
|
4774
4795
|
private static readonly _BACKPRESSURE_THRESHOLD;
|
|
4796
|
+
/** Sends queued while the socket is backpressured (FIFO). */
|
|
4797
|
+
private _backpressureQueue;
|
|
4798
|
+
private _backpressureTimer;
|
|
4775
4799
|
/**
|
|
4776
4800
|
* Protected hook for plugins to intercept outbound messages before serialization.
|
|
4777
4801
|
* Return `false` to suppress the message transmission.
|
|
4778
4802
|
*/
|
|
4779
4803
|
protected _invokeBeforeSend(_message: OCPPMessage): boolean | Promise<boolean>;
|
|
4780
4804
|
/**
|
|
4781
|
-
* Wraps ws.send() with backpressure protection.
|
|
4782
|
-
*
|
|
4783
|
-
*
|
|
4805
|
+
* Wraps ws.send() with backpressure protection. When bufferedAmount
|
|
4806
|
+
* exceeds the threshold, sends are queued and flushed FIFO by a single
|
|
4807
|
+
* shared 50ms drain timer (one per client, not one per send — report M10).
|
|
4808
|
+
* Entries older than 10s are sent regardless, preserving the previous
|
|
4809
|
+
* timeout semantics. Prevents OOM on slow 2G/3G charger connections.
|
|
4784
4810
|
*/
|
|
4785
4811
|
private _safeSend;
|
|
4786
|
-
private
|
|
4812
|
+
private _startBackpressureDrain;
|
|
4813
|
+
private _stopBackpressureDrain;
|
|
4814
|
+
protected _startPing(): void;
|
|
4787
4815
|
private _stopPing;
|
|
4788
|
-
|
|
4816
|
+
protected _recordActivity(): void;
|
|
4789
4817
|
private _setupValidators;
|
|
4790
4818
|
private _validateOutbound;
|
|
4791
4819
|
private _validateInbound;
|
|
@@ -4800,6 +4828,8 @@ interface WorkerPoolOptions {
|
|
|
4800
4828
|
poolSize?: number;
|
|
4801
4829
|
/** Max pending parse jobs before rejecting (default: 10000) */
|
|
4802
4830
|
maxQueueSize?: number;
|
|
4831
|
+
/** Override the worker entry path (used by tests; defaults to parse-worker.cjs next to this file) */
|
|
4832
|
+
workerPath?: string;
|
|
4803
4833
|
}
|
|
4804
4834
|
interface ParseResult {
|
|
4805
4835
|
message: unknown;
|
|
@@ -4867,9 +4897,17 @@ declare class OCPPServerClient extends OCPPClient {
|
|
|
4867
4897
|
private _rateLimits;
|
|
4868
4898
|
private _adaptiveMultiplier;
|
|
4869
4899
|
private _workerPool;
|
|
4900
|
+
/**
|
|
4901
|
+
* Per-connection inbound pipeline. Serializes async pre-processing
|
|
4902
|
+
* (plugin onBeforeReceive, rate-limit parse, worker-pool parse) so
|
|
4903
|
+
* messages are dispatched in wire order — OCPP transaction semantics
|
|
4904
|
+
* depend on it (e.g. StartTransaction before StopTransaction).
|
|
4905
|
+
*/
|
|
4906
|
+
private _inboundChain;
|
|
4870
4907
|
private _checkRateLimit;
|
|
4871
4908
|
protected _invokeBeforeSend(message: OCPPMessage): boolean | Promise<boolean>;
|
|
4872
4909
|
private _attachServerWebsocket;
|
|
4910
|
+
private _processInboundMessage;
|
|
4873
4911
|
private _handleRateLimitExceeded;
|
|
4874
4912
|
/**
|
|
4875
4913
|
* Session data associated with this client connection.
|
|
@@ -4918,6 +4956,10 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
4918
4956
|
private _clients;
|
|
4919
4957
|
private _clientsByIdentity;
|
|
4920
4958
|
private _httpServers;
|
|
4959
|
+
/** HTTP servers created by listen() — we own their lifecycle. */
|
|
4960
|
+
private _ownedHttpServers;
|
|
4961
|
+
/** Listeners we attached per server, for removal on close(). */
|
|
4962
|
+
private _attachedHttpHandlers;
|
|
4921
4963
|
private _wss;
|
|
4922
4964
|
private _state;
|
|
4923
4965
|
private _adapter;
|
|
@@ -4929,7 +4971,12 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
4929
4971
|
private _plugins;
|
|
4930
4972
|
private _workerPool;
|
|
4931
4973
|
private _telemetryInterval;
|
|
4974
|
+
private _presenceInterval;
|
|
4932
4975
|
private readonly _nodeId;
|
|
4976
|
+
/** Pending cross-node RPC calls awaiting a correlated response. */
|
|
4977
|
+
private _pendingRemoteCalls;
|
|
4978
|
+
/** Extra wait on top of the call timeout to absorb cross-node transit. */
|
|
4979
|
+
private static readonly _REMOTE_RESPONSE_GRACE_MS;
|
|
4933
4980
|
private _sessions;
|
|
4934
4981
|
private _gcInterval;
|
|
4935
4982
|
private readonly _sessionTimeoutMs;
|
|
@@ -5073,21 +5120,25 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
5073
5120
|
*/
|
|
5074
5121
|
private _handleUpgrade;
|
|
5075
5122
|
private _updateSessionActivity;
|
|
5123
|
+
/**
|
|
5124
|
+
* Evict per-IP connection buckets that have been idle longer than the
|
|
5125
|
+
* rate-limit window. Recreating a bucket grants a full token allowance,
|
|
5126
|
+
* which is exactly what a full refill after `windowMs` idle would yield —
|
|
5127
|
+
* so eviction is behavior-preserving while bounding memory (report H4).
|
|
5128
|
+
*/
|
|
5129
|
+
private _sweepConnectionBuckets;
|
|
5076
5130
|
close(options?: CloseOptions): Promise<void>;
|
|
5077
5131
|
reconfigure(options: Partial<ServerOptions>): void;
|
|
5078
5132
|
/**
|
|
5079
5133
|
* Send a request to a specific client (local or remote).
|
|
5080
5134
|
*
|
|
5081
|
-
* 1.
|
|
5082
|
-
* 2.
|
|
5083
|
-
*
|
|
5084
|
-
|
|
5085
|
-
/**
|
|
5086
|
-
* Send a request to a specific client (local or remote).
|
|
5135
|
+
* 1. Local clients are called directly.
|
|
5136
|
+
* 2. Otherwise the presence registry routes the call to the owning node,
|
|
5137
|
+
* and the response is correlated back over the adapter (cross-node RPC).
|
|
5138
|
+
* 3. Unknown identity → rejects with "Client <identity> not found".
|
|
5087
5139
|
*
|
|
5088
|
-
*
|
|
5089
|
-
*
|
|
5090
|
-
* 3. Fallback: Error (Client not found).
|
|
5140
|
+
* Backward compatibility: nodes running older versions deliver the call
|
|
5141
|
+
* but never publish a response — such calls reject with TimeoutError.
|
|
5091
5142
|
*/
|
|
5092
5143
|
sendToClient<V extends OCPPProtocol, M extends AllMethodNames<V>>(identity: string, version: V, method: M, params: OCPPRequestType<V, M>, options?: CallOptions): Promise<OCPPResponseType<V, M> | undefined>;
|
|
5093
5144
|
sendToClient<M extends AllMethodNames<any>>(identity: string, method: M, params: OCPPRequestType<any, M>, options?: CallOptions): Promise<OCPPResponseType<any, M> | undefined>;
|
|
@@ -5120,8 +5171,12 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
5120
5171
|
options?: CallOptions;
|
|
5121
5172
|
}>): Promise<Array<unknown | undefined>>;
|
|
5122
5173
|
setAdapter(adapter: EventAdapterInterface): Promise<void>;
|
|
5174
|
+
private _startPresenceRefresh;
|
|
5175
|
+
private _refreshPresence;
|
|
5123
5176
|
private _onBroadcast;
|
|
5124
5177
|
private _onUnicast;
|
|
5178
|
+
/** Publish the result of a remotely requested call back to the origin node. */
|
|
5179
|
+
private _publishRemoteResult;
|
|
5125
5180
|
publish(channel: string, data: unknown): Promise<void>;
|
|
5126
5181
|
broadcast<V extends AllMethodNames<any>>(method: V, params: OCPPRequestType<any, V>): Promise<void>;
|
|
5127
5182
|
/**
|
|
@@ -5179,9 +5234,11 @@ declare class Validator {
|
|
|
5179
5234
|
hasSchema(schemaId: string): boolean;
|
|
5180
5235
|
}
|
|
5181
5236
|
/**
|
|
5182
|
-
* Create
|
|
5183
|
-
*
|
|
5184
|
-
*
|
|
5237
|
+
* Create a validator for a specific subprotocol version.
|
|
5238
|
+
*
|
|
5239
|
+
* Always returns a fresh instance so custom schema sets are never shadowed
|
|
5240
|
+
* by previously created validators for the same subprotocol (report M8).
|
|
5241
|
+
* Standard validators are cached separately by getStandardValidators().
|
|
5185
5242
|
*/
|
|
5186
5243
|
declare function createValidator(subprotocol: string, schemas: ValidatorSchema[]): Validator;
|
|
5187
5244
|
|
|
@@ -5458,7 +5515,11 @@ interface ClientOptions {
|
|
|
5458
5515
|
strictModeMethods?: Array<AllMethodNames<OCPPProtocol>>;
|
|
5459
5516
|
/** Custom validators for strict mode */
|
|
5460
5517
|
strictModeValidators?: Validator[];
|
|
5461
|
-
/**
|
|
5518
|
+
/**
|
|
5519
|
+
* Max number of bad messages before closing.
|
|
5520
|
+
* Default: Infinity (never disconnects on bad messages) — set a finite
|
|
5521
|
+
* value in production.
|
|
5522
|
+
*/
|
|
5462
5523
|
maxBadMessages?: number;
|
|
5463
5524
|
/** Include error details in responses (default: false) */
|
|
5464
5525
|
respondWithDetailedErrors?: boolean;
|
|
@@ -5581,6 +5642,13 @@ interface CORSOptions {
|
|
|
5581
5642
|
allowedOrigins?: string[];
|
|
5582
5643
|
/** Allowed WebSocket protocol schemes */
|
|
5583
5644
|
allowedSchemes?: ("ws" | "wss")[];
|
|
5645
|
+
/**
|
|
5646
|
+
* Honor `X-Forwarded-Proto` from a reverse proxy when evaluating
|
|
5647
|
+
* `allowedSchemes`. Leave false (default) unless the server is only
|
|
5648
|
+
* reachable through a trusted proxy — otherwise clients can spoof the
|
|
5649
|
+
* header to bypass wss-only rules.
|
|
5650
|
+
*/
|
|
5651
|
+
trustProxy?: boolean;
|
|
5584
5652
|
}
|
|
5585
5653
|
interface ServerOptionsBase {
|
|
5586
5654
|
/** OCPP Security Profile (default: NONE) */
|
|
@@ -5601,7 +5669,11 @@ interface ServerOptionsBase {
|
|
|
5601
5669
|
strictModeValidators?: Validator[];
|
|
5602
5670
|
/** Rate Limiting configuration — inherited */
|
|
5603
5671
|
rateLimit?: RateLimitOptions;
|
|
5604
|
-
/**
|
|
5672
|
+
/**
|
|
5673
|
+
* Max bad messages — inherited.
|
|
5674
|
+
* Default: Infinity (never disconnects on bad messages) — set a finite
|
|
5675
|
+
* value in production.
|
|
5676
|
+
*/
|
|
5605
5677
|
maxBadMessages?: number;
|
|
5606
5678
|
/** Include error details in responses — inherited (default: false) */
|
|
5607
5679
|
respondWithDetailedErrors?: boolean;
|
|
@@ -5610,6 +5682,12 @@ interface ServerOptionsBase {
|
|
|
5610
5682
|
* (default: 7200000 / 2 hours)
|
|
5611
5683
|
*/
|
|
5612
5684
|
sessionTtlMs?: number;
|
|
5685
|
+
/**
|
|
5686
|
+
* TTL (seconds) for cluster presence registry entries, and the basis for
|
|
5687
|
+
* the automatic presence heartbeat (refreshed every ttl/2 while clients
|
|
5688
|
+
* are connected). Default: 300.
|
|
5689
|
+
*/
|
|
5690
|
+
presenceTtlSeconds?: number;
|
|
5613
5691
|
/**
|
|
5614
5692
|
* Maximum time (ms) to wait for the auth callback to resolve during
|
|
5615
5693
|
* a WebSocket upgrade handshake. If the callback does not settle within
|
|
@@ -5640,10 +5718,20 @@ interface ServerOptionsBase {
|
|
|
5640
5718
|
* (default: 50000)
|
|
5641
5719
|
*/
|
|
5642
5720
|
maxSessions?: number;
|
|
5721
|
+
/**
|
|
5722
|
+
* Hard cap on concurrent client connections, enforced before the TLS/auth
|
|
5723
|
+
* handshake work is done (the connection-guard plugin only closes after
|
|
5724
|
+
* the fact). Excess upgrades are rejected with HTTP 503.
|
|
5725
|
+
*/
|
|
5726
|
+
maxConnections?: number;
|
|
5643
5727
|
/**
|
|
5644
5728
|
* Enable the built-in HTTP health/metrics endpoint.
|
|
5645
5729
|
* When enabled, non-upgrade HTTP requests to `/health` return a JSON health check,
|
|
5646
5730
|
* and requests to `/metrics` return Prometheus-compatible text metrics.
|
|
5731
|
+
* When attaching to a user-provided server (listen(..., { server })),
|
|
5732
|
+
* only /health and /metrics are handled; all other routes are left to
|
|
5733
|
+
* the application, and close() will not close the external server.
|
|
5734
|
+
* Ensure your app does not also write responses for /health or /metrics.
|
|
5647
5735
|
* (default: false)
|
|
5648
5736
|
*/
|
|
5649
5737
|
healthEndpoint?: boolean;
|
|
@@ -5818,7 +5906,7 @@ interface ClientEvents {
|
|
|
5818
5906
|
*/
|
|
5819
5907
|
interface SecurityEvent {
|
|
5820
5908
|
/** Event type identifier */
|
|
5821
|
-
type: "AUTH_FAILED" | "RATE_LIMIT_EXCEEDED" | "UPGRADE_ABORTED" | "CONNECTION_RATE_LIMIT" | "INVALID_PAYLOAD" | "ANOMALY_RAPID_RECONNECT" | "ANOMALY_AUTH_BRUTE_FORCE" | "ANOMALY_MESSAGE_FUZZING" | "ANOMALY_IDENTITY_COLLISION";
|
|
5909
|
+
type: "AUTH_FAILED" | "RATE_LIMIT_EXCEEDED" | "UPGRADE_ABORTED" | "CONNECTION_RATE_LIMIT" | "CONNECTION_LIMIT" | "INVALID_PAYLOAD" | "ANOMALY_RAPID_RECONNECT" | "ANOMALY_AUTH_BRUTE_FORCE" | "ANOMALY_MESSAGE_FUZZING" | "ANOMALY_IDENTITY_COLLISION";
|
|
5822
5910
|
/** Station identity (if known) */
|
|
5823
5911
|
identity?: string;
|
|
5824
5912
|
/** Remote IP address */
|
|
@@ -4465,6 +4465,11 @@ declare class OCPPRouter extends OCPPRouter_base {
|
|
|
4465
4465
|
* @internal
|
|
4466
4466
|
*/
|
|
4467
4467
|
_regexPatterns: CompiledRegexPattern[];
|
|
4468
|
+
/**
|
|
4469
|
+
* @internal Set by OCPPServer when the router is registered, so patterns
|
|
4470
|
+
* added after registration still reach the trie / regex list.
|
|
4471
|
+
*/
|
|
4472
|
+
_onPatternAdded?: (pattern: string | RegExp) => void;
|
|
4468
4473
|
constructor(patterns?: Array<string | RegExp>, middlewares?: ConnectionMiddleware[]);
|
|
4469
4474
|
/**
|
|
4470
4475
|
* Appends URL paths or regular expressions to this router's match condition.
|
|
@@ -4573,7 +4578,7 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4573
4578
|
private _pendingResponses;
|
|
4574
4579
|
private _callQueue;
|
|
4575
4580
|
private _pingTimer;
|
|
4576
|
-
|
|
4581
|
+
protected _pongTimer: ReturnType<typeof setTimeout> | null;
|
|
4577
4582
|
private _closePromise;
|
|
4578
4583
|
private _reconnectAttempt;
|
|
4579
4584
|
private _reconnectTimer;
|
|
@@ -4608,6 +4613,11 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4608
4613
|
* The connection endpoint URL.
|
|
4609
4614
|
*/
|
|
4610
4615
|
get endpoint(): string;
|
|
4616
|
+
/**
|
|
4617
|
+
* Bytes currently queued in the underlying WebSocket send buffer
|
|
4618
|
+
* (0 when disconnected). Useful for backpressure monitoring and drain checks.
|
|
4619
|
+
*/
|
|
4620
|
+
get bufferedAmount(): number;
|
|
4611
4621
|
/**
|
|
4612
4622
|
* The current configuration options for this client.
|
|
4613
4623
|
*/
|
|
@@ -4690,6 +4700,11 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4690
4700
|
* Remove a registered handler for a specific version and method.
|
|
4691
4701
|
*/
|
|
4692
4702
|
removeHandler(version: OCPPProtocol, method: string): void;
|
|
4703
|
+
/**
|
|
4704
|
+
* Check whether a handler is registered for a method
|
|
4705
|
+
* (optionally version-scoped, matching the handle() overloads).
|
|
4706
|
+
*/
|
|
4707
|
+
hasHandler(method: string, version?: string): boolean;
|
|
4693
4708
|
/**
|
|
4694
4709
|
* Remove all registered handlers for this client, including the wildcard handler.
|
|
4695
4710
|
*/
|
|
@@ -4715,6 +4730,12 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4715
4730
|
call<M extends AllMethodNames<P>>(method: M, params: OCPPRequestType<P, M>, options?: CallOptions): Promise<OCPPResponseType<P, M>>;
|
|
4716
4731
|
/** Call a known typed method with explicit response type. */
|
|
4717
4732
|
call<TResult = unknown>(method: string, params?: Record<string, unknown>, options?: CallOptions): Promise<TResult>;
|
|
4733
|
+
/**
|
|
4734
|
+
* Execute a call immediately, bypassing the callConcurrency queue.
|
|
4735
|
+
* Used by OCPPServer.sendBatch to pipeline warm-up calls without
|
|
4736
|
+
* mutating the client's configured concurrency (report M9).
|
|
4737
|
+
*/
|
|
4738
|
+
callImmediate<TResult = unknown>(method: string, params?: Record<string, unknown>, options?: CallOptions): Promise<TResult>;
|
|
4718
4739
|
/**
|
|
4719
4740
|
* Version-specific safe call. Returns `undefined` on error instead of throwing.
|
|
4720
4741
|
*/
|
|
@@ -4754,7 +4775,7 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4754
4775
|
* Reject all in-flight calls and clear pending state.
|
|
4755
4776
|
*/
|
|
4756
4777
|
private _rejectPendingCalls;
|
|
4757
|
-
|
|
4778
|
+
protected _onClose(code: number, reason: Buffer): void;
|
|
4758
4779
|
/** Errors that should stop reconnection immediately */
|
|
4759
4780
|
private static readonly _INTOLERABLE_ERRORS;
|
|
4760
4781
|
private _scheduleReconnect;
|
|
@@ -4772,20 +4793,27 @@ declare class OCPPClient<P extends OCPPProtocol = OCPPProtocol> extends OCPPClie
|
|
|
4772
4793
|
private _callWithRetry;
|
|
4773
4794
|
/** Maximum bytes allowed in the ws send buffer before applying backpressure (512KB) */
|
|
4774
4795
|
private static readonly _BACKPRESSURE_THRESHOLD;
|
|
4796
|
+
/** Sends queued while the socket is backpressured (FIFO). */
|
|
4797
|
+
private _backpressureQueue;
|
|
4798
|
+
private _backpressureTimer;
|
|
4775
4799
|
/**
|
|
4776
4800
|
* Protected hook for plugins to intercept outbound messages before serialization.
|
|
4777
4801
|
* Return `false` to suppress the message transmission.
|
|
4778
4802
|
*/
|
|
4779
4803
|
protected _invokeBeforeSend(_message: OCPPMessage): boolean | Promise<boolean>;
|
|
4780
4804
|
/**
|
|
4781
|
-
* Wraps ws.send() with backpressure protection.
|
|
4782
|
-
*
|
|
4783
|
-
*
|
|
4805
|
+
* Wraps ws.send() with backpressure protection. When bufferedAmount
|
|
4806
|
+
* exceeds the threshold, sends are queued and flushed FIFO by a single
|
|
4807
|
+
* shared 50ms drain timer (one per client, not one per send — report M10).
|
|
4808
|
+
* Entries older than 10s are sent regardless, preserving the previous
|
|
4809
|
+
* timeout semantics. Prevents OOM on slow 2G/3G charger connections.
|
|
4784
4810
|
*/
|
|
4785
4811
|
private _safeSend;
|
|
4786
|
-
private
|
|
4812
|
+
private _startBackpressureDrain;
|
|
4813
|
+
private _stopBackpressureDrain;
|
|
4814
|
+
protected _startPing(): void;
|
|
4787
4815
|
private _stopPing;
|
|
4788
|
-
|
|
4816
|
+
protected _recordActivity(): void;
|
|
4789
4817
|
private _setupValidators;
|
|
4790
4818
|
private _validateOutbound;
|
|
4791
4819
|
private _validateInbound;
|
|
@@ -4800,6 +4828,8 @@ interface WorkerPoolOptions {
|
|
|
4800
4828
|
poolSize?: number;
|
|
4801
4829
|
/** Max pending parse jobs before rejecting (default: 10000) */
|
|
4802
4830
|
maxQueueSize?: number;
|
|
4831
|
+
/** Override the worker entry path (used by tests; defaults to parse-worker.cjs next to this file) */
|
|
4832
|
+
workerPath?: string;
|
|
4803
4833
|
}
|
|
4804
4834
|
interface ParseResult {
|
|
4805
4835
|
message: unknown;
|
|
@@ -4867,9 +4897,17 @@ declare class OCPPServerClient extends OCPPClient {
|
|
|
4867
4897
|
private _rateLimits;
|
|
4868
4898
|
private _adaptiveMultiplier;
|
|
4869
4899
|
private _workerPool;
|
|
4900
|
+
/**
|
|
4901
|
+
* Per-connection inbound pipeline. Serializes async pre-processing
|
|
4902
|
+
* (plugin onBeforeReceive, rate-limit parse, worker-pool parse) so
|
|
4903
|
+
* messages are dispatched in wire order — OCPP transaction semantics
|
|
4904
|
+
* depend on it (e.g. StartTransaction before StopTransaction).
|
|
4905
|
+
*/
|
|
4906
|
+
private _inboundChain;
|
|
4870
4907
|
private _checkRateLimit;
|
|
4871
4908
|
protected _invokeBeforeSend(message: OCPPMessage): boolean | Promise<boolean>;
|
|
4872
4909
|
private _attachServerWebsocket;
|
|
4910
|
+
private _processInboundMessage;
|
|
4873
4911
|
private _handleRateLimitExceeded;
|
|
4874
4912
|
/**
|
|
4875
4913
|
* Session data associated with this client connection.
|
|
@@ -4918,6 +4956,10 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
4918
4956
|
private _clients;
|
|
4919
4957
|
private _clientsByIdentity;
|
|
4920
4958
|
private _httpServers;
|
|
4959
|
+
/** HTTP servers created by listen() — we own their lifecycle. */
|
|
4960
|
+
private _ownedHttpServers;
|
|
4961
|
+
/** Listeners we attached per server, for removal on close(). */
|
|
4962
|
+
private _attachedHttpHandlers;
|
|
4921
4963
|
private _wss;
|
|
4922
4964
|
private _state;
|
|
4923
4965
|
private _adapter;
|
|
@@ -4929,7 +4971,12 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
4929
4971
|
private _plugins;
|
|
4930
4972
|
private _workerPool;
|
|
4931
4973
|
private _telemetryInterval;
|
|
4974
|
+
private _presenceInterval;
|
|
4932
4975
|
private readonly _nodeId;
|
|
4976
|
+
/** Pending cross-node RPC calls awaiting a correlated response. */
|
|
4977
|
+
private _pendingRemoteCalls;
|
|
4978
|
+
/** Extra wait on top of the call timeout to absorb cross-node transit. */
|
|
4979
|
+
private static readonly _REMOTE_RESPONSE_GRACE_MS;
|
|
4933
4980
|
private _sessions;
|
|
4934
4981
|
private _gcInterval;
|
|
4935
4982
|
private readonly _sessionTimeoutMs;
|
|
@@ -5073,21 +5120,25 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
5073
5120
|
*/
|
|
5074
5121
|
private _handleUpgrade;
|
|
5075
5122
|
private _updateSessionActivity;
|
|
5123
|
+
/**
|
|
5124
|
+
* Evict per-IP connection buckets that have been idle longer than the
|
|
5125
|
+
* rate-limit window. Recreating a bucket grants a full token allowance,
|
|
5126
|
+
* which is exactly what a full refill after `windowMs` idle would yield —
|
|
5127
|
+
* so eviction is behavior-preserving while bounding memory (report H4).
|
|
5128
|
+
*/
|
|
5129
|
+
private _sweepConnectionBuckets;
|
|
5076
5130
|
close(options?: CloseOptions): Promise<void>;
|
|
5077
5131
|
reconfigure(options: Partial<ServerOptions>): void;
|
|
5078
5132
|
/**
|
|
5079
5133
|
* Send a request to a specific client (local or remote).
|
|
5080
5134
|
*
|
|
5081
|
-
* 1.
|
|
5082
|
-
* 2.
|
|
5083
|
-
*
|
|
5084
|
-
|
|
5085
|
-
/**
|
|
5086
|
-
* Send a request to a specific client (local or remote).
|
|
5135
|
+
* 1. Local clients are called directly.
|
|
5136
|
+
* 2. Otherwise the presence registry routes the call to the owning node,
|
|
5137
|
+
* and the response is correlated back over the adapter (cross-node RPC).
|
|
5138
|
+
* 3. Unknown identity → rejects with "Client <identity> not found".
|
|
5087
5139
|
*
|
|
5088
|
-
*
|
|
5089
|
-
*
|
|
5090
|
-
* 3. Fallback: Error (Client not found).
|
|
5140
|
+
* Backward compatibility: nodes running older versions deliver the call
|
|
5141
|
+
* but never publish a response — such calls reject with TimeoutError.
|
|
5091
5142
|
*/
|
|
5092
5143
|
sendToClient<V extends OCPPProtocol, M extends AllMethodNames<V>>(identity: string, version: V, method: M, params: OCPPRequestType<V, M>, options?: CallOptions): Promise<OCPPResponseType<V, M> | undefined>;
|
|
5093
5144
|
sendToClient<M extends AllMethodNames<any>>(identity: string, method: M, params: OCPPRequestType<any, M>, options?: CallOptions): Promise<OCPPResponseType<any, M> | undefined>;
|
|
@@ -5120,8 +5171,12 @@ declare class OCPPServer extends OCPPServer_base {
|
|
|
5120
5171
|
options?: CallOptions;
|
|
5121
5172
|
}>): Promise<Array<unknown | undefined>>;
|
|
5122
5173
|
setAdapter(adapter: EventAdapterInterface): Promise<void>;
|
|
5174
|
+
private _startPresenceRefresh;
|
|
5175
|
+
private _refreshPresence;
|
|
5123
5176
|
private _onBroadcast;
|
|
5124
5177
|
private _onUnicast;
|
|
5178
|
+
/** Publish the result of a remotely requested call back to the origin node. */
|
|
5179
|
+
private _publishRemoteResult;
|
|
5125
5180
|
publish(channel: string, data: unknown): Promise<void>;
|
|
5126
5181
|
broadcast<V extends AllMethodNames<any>>(method: V, params: OCPPRequestType<any, V>): Promise<void>;
|
|
5127
5182
|
/**
|
|
@@ -5179,9 +5234,11 @@ declare class Validator {
|
|
|
5179
5234
|
hasSchema(schemaId: string): boolean;
|
|
5180
5235
|
}
|
|
5181
5236
|
/**
|
|
5182
|
-
* Create
|
|
5183
|
-
*
|
|
5184
|
-
*
|
|
5237
|
+
* Create a validator for a specific subprotocol version.
|
|
5238
|
+
*
|
|
5239
|
+
* Always returns a fresh instance so custom schema sets are never shadowed
|
|
5240
|
+
* by previously created validators for the same subprotocol (report M8).
|
|
5241
|
+
* Standard validators are cached separately by getStandardValidators().
|
|
5185
5242
|
*/
|
|
5186
5243
|
declare function createValidator(subprotocol: string, schemas: ValidatorSchema[]): Validator;
|
|
5187
5244
|
|
|
@@ -5458,7 +5515,11 @@ interface ClientOptions {
|
|
|
5458
5515
|
strictModeMethods?: Array<AllMethodNames<OCPPProtocol>>;
|
|
5459
5516
|
/** Custom validators for strict mode */
|
|
5460
5517
|
strictModeValidators?: Validator[];
|
|
5461
|
-
/**
|
|
5518
|
+
/**
|
|
5519
|
+
* Max number of bad messages before closing.
|
|
5520
|
+
* Default: Infinity (never disconnects on bad messages) — set a finite
|
|
5521
|
+
* value in production.
|
|
5522
|
+
*/
|
|
5462
5523
|
maxBadMessages?: number;
|
|
5463
5524
|
/** Include error details in responses (default: false) */
|
|
5464
5525
|
respondWithDetailedErrors?: boolean;
|
|
@@ -5581,6 +5642,13 @@ interface CORSOptions {
|
|
|
5581
5642
|
allowedOrigins?: string[];
|
|
5582
5643
|
/** Allowed WebSocket protocol schemes */
|
|
5583
5644
|
allowedSchemes?: ("ws" | "wss")[];
|
|
5645
|
+
/**
|
|
5646
|
+
* Honor `X-Forwarded-Proto` from a reverse proxy when evaluating
|
|
5647
|
+
* `allowedSchemes`. Leave false (default) unless the server is only
|
|
5648
|
+
* reachable through a trusted proxy — otherwise clients can spoof the
|
|
5649
|
+
* header to bypass wss-only rules.
|
|
5650
|
+
*/
|
|
5651
|
+
trustProxy?: boolean;
|
|
5584
5652
|
}
|
|
5585
5653
|
interface ServerOptionsBase {
|
|
5586
5654
|
/** OCPP Security Profile (default: NONE) */
|
|
@@ -5601,7 +5669,11 @@ interface ServerOptionsBase {
|
|
|
5601
5669
|
strictModeValidators?: Validator[];
|
|
5602
5670
|
/** Rate Limiting configuration — inherited */
|
|
5603
5671
|
rateLimit?: RateLimitOptions;
|
|
5604
|
-
/**
|
|
5672
|
+
/**
|
|
5673
|
+
* Max bad messages — inherited.
|
|
5674
|
+
* Default: Infinity (never disconnects on bad messages) — set a finite
|
|
5675
|
+
* value in production.
|
|
5676
|
+
*/
|
|
5605
5677
|
maxBadMessages?: number;
|
|
5606
5678
|
/** Include error details in responses — inherited (default: false) */
|
|
5607
5679
|
respondWithDetailedErrors?: boolean;
|
|
@@ -5610,6 +5682,12 @@ interface ServerOptionsBase {
|
|
|
5610
5682
|
* (default: 7200000 / 2 hours)
|
|
5611
5683
|
*/
|
|
5612
5684
|
sessionTtlMs?: number;
|
|
5685
|
+
/**
|
|
5686
|
+
* TTL (seconds) for cluster presence registry entries, and the basis for
|
|
5687
|
+
* the automatic presence heartbeat (refreshed every ttl/2 while clients
|
|
5688
|
+
* are connected). Default: 300.
|
|
5689
|
+
*/
|
|
5690
|
+
presenceTtlSeconds?: number;
|
|
5613
5691
|
/**
|
|
5614
5692
|
* Maximum time (ms) to wait for the auth callback to resolve during
|
|
5615
5693
|
* a WebSocket upgrade handshake. If the callback does not settle within
|
|
@@ -5640,10 +5718,20 @@ interface ServerOptionsBase {
|
|
|
5640
5718
|
* (default: 50000)
|
|
5641
5719
|
*/
|
|
5642
5720
|
maxSessions?: number;
|
|
5721
|
+
/**
|
|
5722
|
+
* Hard cap on concurrent client connections, enforced before the TLS/auth
|
|
5723
|
+
* handshake work is done (the connection-guard plugin only closes after
|
|
5724
|
+
* the fact). Excess upgrades are rejected with HTTP 503.
|
|
5725
|
+
*/
|
|
5726
|
+
maxConnections?: number;
|
|
5643
5727
|
/**
|
|
5644
5728
|
* Enable the built-in HTTP health/metrics endpoint.
|
|
5645
5729
|
* When enabled, non-upgrade HTTP requests to `/health` return a JSON health check,
|
|
5646
5730
|
* and requests to `/metrics` return Prometheus-compatible text metrics.
|
|
5731
|
+
* When attaching to a user-provided server (listen(..., { server })),
|
|
5732
|
+
* only /health and /metrics are handled; all other routes are left to
|
|
5733
|
+
* the application, and close() will not close the external server.
|
|
5734
|
+
* Ensure your app does not also write responses for /health or /metrics.
|
|
5647
5735
|
* (default: false)
|
|
5648
5736
|
*/
|
|
5649
5737
|
healthEndpoint?: boolean;
|
|
@@ -5818,7 +5906,7 @@ interface ClientEvents {
|
|
|
5818
5906
|
*/
|
|
5819
5907
|
interface SecurityEvent {
|
|
5820
5908
|
/** Event type identifier */
|
|
5821
|
-
type: "AUTH_FAILED" | "RATE_LIMIT_EXCEEDED" | "UPGRADE_ABORTED" | "CONNECTION_RATE_LIMIT" | "INVALID_PAYLOAD" | "ANOMALY_RAPID_RECONNECT" | "ANOMALY_AUTH_BRUTE_FORCE" | "ANOMALY_MESSAGE_FUZZING" | "ANOMALY_IDENTITY_COLLISION";
|
|
5909
|
+
type: "AUTH_FAILED" | "RATE_LIMIT_EXCEEDED" | "UPGRADE_ABORTED" | "CONNECTION_RATE_LIMIT" | "CONNECTION_LIMIT" | "INVALID_PAYLOAD" | "ANOMALY_RAPID_RECONNECT" | "ANOMALY_AUTH_BRUTE_FORCE" | "ANOMALY_MESSAGE_FUZZING" | "ANOMALY_IDENTITY_COLLISION";
|
|
5822
5910
|
/** Station identity (if known) */
|
|
5823
5911
|
identity?: string;
|
|
5824
5912
|
/** Remote IP address */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ocpp-ws-io",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "OCPP RPC WebSocket client and server for OCPP 1.6J, 2.0.1, and 2.1. Type-safe TypeScript toolkit for EV charging, CSMS backends, Redis scaling, and protocol validation.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|