@morojs/moro 1.8.16 → 1.8.17

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.
@@ -193,6 +193,11 @@ export declare class MoroEngineServer {
193
193
  /** @internal */ _wsSend: (wsId: number, data: any, isBinary: boolean) => boolean;
194
194
  /** @internal */ _wsClose: (wsId: number, code?: number, reason?: string) => void;
195
195
  /** @internal */ _upgradeToWebSocket: (reqId: number) => number;
196
+ private _setWsAutoUpgrade?;
197
+ private _wsGetHeaders?;
198
+ private _wsGetQuery?;
199
+ private _wsGetRemoteAddress?;
200
+ private _wsAutoOn;
196
201
  /** @internal */ _prepareResponse?: (serverId: number, status: number, headers: string[] | null) => number;
197
202
  /** @internal */ _respondPrepared?: (reqId: number, tplId: number, body: any) => void;
198
203
  /** @internal */ _respondPreparedEmpty?: (reqId: number, tplId: number) => void;
@@ -308,6 +313,17 @@ export declare class MoroEngineServer {
308
313
  onMessage(wsId: number, data: any, isBinary: boolean): void;
309
314
  onClose(wsId: number, code: number): void;
310
315
  }): void;
316
+ /**
317
+ * The handshake of a WebSocket the engine upgraded itself: the peer's
318
+ * address, the request headers as the engine's flat list and the raw query
319
+ * string. undefined without the capability, or once the socket is gone
320
+ * (the engine keeps it for the socket's lifetime, through onWsClose).
321
+ */
322
+ wsHandshake(wsId: number): {
323
+ ip: string;
324
+ flat: string[] | undefined;
325
+ query: string;
326
+ } | undefined;
311
327
  /** Send a frame on a WebSocket. Returns false on backpressure. */
312
328
  wsSend(wsId: number, data: string | ArrayBuffer | Buffer, isBinary: boolean): boolean;
313
329
  /** Close a WebSocket (RFC 6455 close frame). */
@@ -1485,6 +1485,17 @@ export class MoroEngineServer {
1485
1485
  /** @internal */ _wsSend;
1486
1486
  /** @internal */ _wsClose;
1487
1487
  /** @internal */ _upgradeToWebSocket;
1488
+ // Engine-side upgrades (engine >= 1.1.15, capabilities.wsAutoUpgrade): a
1489
+ // valid handshake is answered inside the engine and onWsOpen fires without
1490
+ // the request ever reaching onRequest - no header materialisation, no
1491
+ // native round trips, no request/response objects per upgrade. The
1492
+ // handshake is read from the socket on first access (wsHandshake). Assigned
1493
+ // only when the flag AND every function are present, like the templates.
1494
+ _setWsAutoUpgrade;
1495
+ _wsGetHeaders;
1496
+ _wsGetQuery;
1497
+ _wsGetRemoteAddress;
1498
+ _wsAutoOn = false;
1488
1499
  // Prepared response templates (engine >= 1.1.6): assigned only when the
1489
1500
  // engine advertises capabilities.responseTemplates AND the functions exist,
1490
1501
  // so a flag/binary mismatch can never put `undefined` into a hot call site.
@@ -1641,6 +1652,16 @@ export class MoroEngineServer {
1641
1652
  this._setParamRoute = surface.setParamRoute;
1642
1653
  this._paramOn = true;
1643
1654
  }
1655
+ if (this._capabilities?.wsAutoUpgrade === true &&
1656
+ typeof surface.setWsAutoUpgrade === 'function' &&
1657
+ typeof surface.wsGetHeaders === 'function' &&
1658
+ typeof surface.wsGetQuery === 'function' &&
1659
+ typeof surface.wsGetRemoteAddress === 'function') {
1660
+ this._setWsAutoUpgrade = surface.setWsAutoUpgrade;
1661
+ this._wsGetHeaders = surface.wsGetHeaders;
1662
+ this._wsGetQuery = surface.wsGetQuery;
1663
+ this._wsGetRemoteAddress = surface.wsGetRemoteAddress;
1664
+ }
1644
1665
  if (this._capabilities?.batchDispatch === true &&
1645
1666
  typeof surface.getBatchBuffers === 'function' &&
1646
1667
  typeof surface.getPath === 'function') {
@@ -1940,6 +1961,27 @@ export class MoroEngineServer {
1940
1961
  /** Register the engine WebSocket bridge; upgrade requests then route natively. */
1941
1962
  enableWebSocket(bridge) {
1942
1963
  this._wsBridge = bridge;
1964
+ // With the capability the engine answers valid handshakes itself; the
1965
+ // onRequest branch below stays for an invalid one (surfaced as a plain
1966
+ // request, answered 400 by the router) and for older engines.
1967
+ if (this._setWsAutoUpgrade) {
1968
+ this._setWsAutoUpgrade(this.serverId, true);
1969
+ this._wsAutoOn = true;
1970
+ }
1971
+ }
1972
+ /**
1973
+ * The handshake of a WebSocket the engine upgraded itself: the peer's
1974
+ * address, the request headers as the engine's flat list and the raw query
1975
+ * string. undefined without the capability, or once the socket is gone
1976
+ * (the engine keeps it for the socket's lifetime, through onWsClose).
1977
+ */
1978
+ wsHandshake(wsId) {
1979
+ if (!this._wsGetHeaders || !this._wsGetQuery || !this._wsGetRemoteAddress)
1980
+ return undefined;
1981
+ const flat = this._wsGetHeaders(wsId);
1982
+ if (flat === undefined)
1983
+ return undefined;
1984
+ return { ip: this._wsGetRemoteAddress(wsId) || '', flat, query: this._wsGetQuery(wsId) || '' };
1943
1985
  }
1944
1986
  /** Send a frame on a WebSocket. Returns false on backpressure. */
1945
1987
  wsSend(wsId, data, isBinary) {
@@ -2603,6 +2645,8 @@ export class MoroEngineServer {
2603
2645
  this.serverId = this.registerWithEngine();
2604
2646
  this._resetTemplates();
2605
2647
  this._reapplyStaticRoutes();
2648
+ if (this._wsAutoOn && this._setWsAutoUpgrade)
2649
+ this._setWsAutoUpgrade(this.serverId, true);
2606
2650
  this.closed = false;
2607
2651
  }
2608
2652
  // Synchronous bind; throws on bind errors, returns the actual port