@owlmeans/socket 0.1.18-rc.9 → 0.1.18

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 CHANGED
@@ -12,7 +12,7 @@ Shared WebSocket connection types and message protocol for OwlMeans real-time co
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/socket@^0.1.18-rc.8
15
+ bun add @owlmeans/socket@^0.1.18
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -91,7 +91,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
91
91
  your project's skill store (`.agents/skills/`):
92
92
 
93
93
  ```sh
94
- npx @owlmeans/agent-skills@^0.1.18-rc.12
94
+ npx @owlmeans/agent-skills@^0.1.18
95
95
  ```
96
96
 
97
97
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/socket",
4
- "version": "0.1.18-rc.9",
5
- "generatedAt": "2026-09-04T22:43:25.444Z",
4
+ "version": "0.1.18",
5
+ "generatedAt": "2026-10-28T00:31:34.737Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/socket
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/socket": "^0.1.18-rc.9"` in `dependencies`
11
+ **Install:** `"@owlmeans/socket": "^0.1.18"` in `dependencies`
12
12
 
13
13
  Contracts and one implementation-free connection model. It knows nothing about WebSockets: the
14
14
  browser side is `@owlmeans/client-socket`, the Fastify side `@owlmeans/server-socket`, and each
@@ -24,8 +24,10 @@ that make it concrete. Both halves of an application therefore speak the same fr
24
24
  | `Message<T>` | The frame — `{ type, payload, id?, sender?, recipient?, dt?, rawData? }` |
25
25
  | `CallMessage<T>` / `EventMessage<T>` / `AuthMessage<T>` | The three frames that add a field: `method` + `timeout`, `event`, `stage` |
26
26
  | `MessageType` | `Call` `Result` `Error` `Request` `Response` `Event` `Message` `Auth` `System` |
27
- | `isMessage` / `isEventMessage` / `isCallMessage` / `isAuthMessage` | Type guards — `isMessage(msg, true)` excludes system frames, `isEventMessage(msg, true)` keeps only them |
27
+ | `socketMessageHelper` — `.isMessage` / `.isEventMessage` / `.isCallMessage` / `.isAuthMessage` | Type guards — `socketMessageHelper.isMessage(msg, true)` excludes system frames, `.isEventMessage(msg, true)` keeps only them |
28
28
  | `ConnectionListener` / `CallHendler` / `RequestHandler` / `CallResolver` | The callback shapes |
29
+ | `SocketSystemEvent` | The `event` values a `MessageType.System` frame carries — see below |
30
+ | `SOCKET_HEARTBEAT_TIMEOUT_CODE` | `4000` — the close code `client-socket`'s carrier uses when it force-closes a socket that has gone silent |
29
31
  | `SocketError` and subclasses | `SocketInitializationError`, `SocketConnectionError`, `SocketUnauthorized`, `SocketUnsupported`, `SocketTimeout`, `SocketMessageError`, `SocketMessageMalformed` — all registered with `ResilientError` |
30
32
  | `CALL_TIMEOUT` | 60 000 ms, the fallback when neither the message nor `connection.defaultCallTimeout` says |
31
33
 
@@ -77,8 +79,24 @@ connection.listen(async message => {
77
79
  ```
78
80
 
79
81
  Both carriers emit exactly that frame — `MessageType.System`, `event: 'close'`, payload
80
- `{ code }` — when the socket closes. Nothing else reports a disconnect, so any subscription a
81
- handler opened is released there.
82
+ `{ code }` — when the socket closes for good. Nothing else reports a TERMINAL disconnect, so any
83
+ subscription a handler opened is released there.
84
+
85
+ **`SocketSystemEvent`** is the full vocabulary a `MessageType.System` frame's `event` can carry —
86
+ `client-socket`'s reconnecting carrier is what emits the other four:
87
+
88
+ | Event | Meaning |
89
+ |---|---|
90
+ | `close` | The connection is gone for good — see above |
91
+ | `disconnected` | The socket dropped and a retry IS scheduled (client-socket only) — `{ code }` |
92
+ | `reconnecting` | Before each retry attempt (client-socket only) — `{ attempt, delay }` |
93
+ | `reconnected` | A retry succeeded, same `Connection` model (client-socket only) — `{ attempts }` |
94
+ | `lost` | The retry budget elapsed with no success (client-socket only). NOT followed by `close`: the connection stays revivable until its owner closes it |
95
+
96
+ `close` is the only one of the five a plain carrier with no retry logic (like `server-socket`, or
97
+ `client-socket` itself with `reconnect: false`) will ever emit. A listener that must react to a
98
+ reconnecting carrier giving up listens for `lost` — a `close` there comes only from its owner's
99
+ own `close()` or a terminal server code.
82
100
 
83
101
  ## What the model expects of a carrier
84
102
 
@@ -103,13 +121,18 @@ null stage and is rebuilt by the initiator. `connection.stage` holds the current
103
121
  `AuthenticationStage` throughout. Only the server carrier implements a real sequence; see the
104
122
  `server-socket` skill.
105
123
 
124
+ Raw inbound data is parsed and structurally checked before dispatch. A server connection may accept
125
+ only authentication frames until its carrier marks it authenticated; an unknown call returns a
126
+ typed socket error, and listener failures are isolated and logged so an EventEmitter never receives
127
+ an unhandled rejected promise. Keep sensitive actions behind the carrier's authentication stage.
128
+
106
129
  ## Depends On
107
130
 
108
131
  - `@owlmeans/error` — `ResilientError`, which every socket error registers with
109
132
  - `@owlmeans/auth` — `AuthenticationStage`, the vocabulary the auth frames carry
110
- - `@owlmeans/basic-ids` — `uuid` for call and request ids
133
+ - `@owlmeans/basic-ids` — `idHelper.uuid` for call and request ids
111
134
 
112
135
  ## Related
113
136
 
114
137
  - `client-socket` — the browser carrier and `useWs`
115
- - `server-socket` — the Fastify carrier, guard enforcement and `handleConnection`
138
+ - `server-socket` — the Fastify carrier, guard enforcement and `connection(protocol, callback)`
package/build/consts.d.ts CHANGED
@@ -10,4 +10,25 @@ export declare enum MessageType {
10
10
  System = "system"
11
11
  }
12
12
  export declare const CALL_TIMEOUT = 60000;
13
+ /**
14
+ * System frames a carrier synthesises around the lifecycle of the underlying transport.
15
+ *
16
+ * `Close` means the connection is gone for good — a client-initiated close, or a terminal server
17
+ * code. A drop the carrier intends to retry is reported as `Disconnected`, and an exhausted retry
18
+ * budget as `Lost` alone: a lost connection can still be revived, so it is not closed.
19
+ */
20
+ export declare enum SocketSystemEvent {
21
+ Close = "close",
22
+ Disconnected = "disconnected",
23
+ Reconnecting = "reconnecting",
24
+ Reconnected = "reconnected",
25
+ Lost = "lost"
26
+ }
27
+ /**
28
+ * The close code a carrier uses when it drops a socket itself — a missed heartbeat pong within
29
+ * `pongTimeout`, catching a half-open TCP connection long before the OS would notice one.
30
+ * Reserved in the 4000–4999 private-use range so it is never confused with a code either
31
+ * endpoint's own WebSocket stack could produce.
32
+ */
33
+ export declare const SOCKET_HEARTBEAT_TIMEOUT_CODE = 4000;
13
34
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,eAAO,MAAM,YAAY,QAAQ,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,WAAW;IACrB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;CAClB;AAED,eAAO,MAAM,YAAY,QAAQ,CAAA;AAEjC;;;;;;GAMG;AACH,oBAAY,iBAAiB;IAC3B,KAAK,UAAU;IACf,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,WAAW,gBAAgB;IAC3B,IAAI,SAAS;CACd;AAED;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAA"}
package/build/consts.js CHANGED
@@ -11,4 +11,26 @@ export var MessageType;
11
11
  MessageType["System"] = "system";
12
12
  })(MessageType || (MessageType = {}));
13
13
  export const CALL_TIMEOUT = 60000;
14
+ /**
15
+ * System frames a carrier synthesises around the lifecycle of the underlying transport.
16
+ *
17
+ * `Close` means the connection is gone for good — a client-initiated close, or a terminal server
18
+ * code. A drop the carrier intends to retry is reported as `Disconnected`, and an exhausted retry
19
+ * budget as `Lost` alone: a lost connection can still be revived, so it is not closed.
20
+ */
21
+ export var SocketSystemEvent;
22
+ (function (SocketSystemEvent) {
23
+ SocketSystemEvent["Close"] = "close";
24
+ SocketSystemEvent["Disconnected"] = "disconnected";
25
+ SocketSystemEvent["Reconnecting"] = "reconnecting";
26
+ SocketSystemEvent["Reconnected"] = "reconnected";
27
+ SocketSystemEvent["Lost"] = "lost";
28
+ })(SocketSystemEvent || (SocketSystemEvent = {}));
29
+ /**
30
+ * The close code a carrier uses when it drops a socket itself — a missed heartbeat pong within
31
+ * `pongTimeout`, catching a half-open TCP connection long before the OS would notice one.
32
+ * Reserved in the 4000–4999 private-use range so it is never confused with a code either
33
+ * endpoint's own WebSocket stack could produce.
34
+ */
35
+ export const SOCKET_HEARTBEAT_TIMEOUT_CODE = 4000;
14
36
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,WAUX;AAVD,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,gCAAiB,CAAA;IACjB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,oCAAqB,CAAA;IACrB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,4BAAa,CAAA;IACb,gCAAiB,CAAA;AACnB,CAAC,EAVW,WAAW,KAAX,WAAW,QAUtB;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,WAUX;AAVD,WAAY,WAAW;IACrB,4BAAa,CAAA;IACb,gCAAiB,CAAA;IACjB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,oCAAqB,CAAA;IACrB,8BAAe,CAAA;IACf,kCAAmB,CAAA;IACnB,4BAAa,CAAA;IACb,gCAAiB,CAAA;AACnB,CAAC,EAVW,WAAW,KAAX,WAAW,QAUtB;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAA;AAEjC;;;;;;GAMG;AACH,MAAM,CAAN,IAAY,iBAMX;AAND,WAAY,iBAAiB;IAC3B,oCAAe,CAAA;IACf,kDAA6B,CAAA;IAC7B,kDAA6B,CAAA;IAC7B,gDAA2B,CAAA;IAC3B,kCAAa,CAAA;AACf,CAAC,EANW,iBAAiB,KAAjB,iBAAiB,QAM5B;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAA"}
@@ -0,0 +1,13 @@
1
+ import type { AuthMessage, CallMessage, EventMessage, Message } from '../types.js';
2
+ /** Recognizes the kinds of socket message. */
3
+ export interface SocketMessageHelper {
4
+ /** Whether a received value is a message; `nonSystem` also requires it (not) to be a system one. */
5
+ isMessage: <P, T extends Message<P>>(msg: string | T, nonSystem?: boolean) => msg is T;
6
+ /** Whether a message is an event (system events included); `system` also requires it (not) to be a system one. */
7
+ isEventMessage: <P>(msg: string | Message<P>, system?: boolean) => msg is EventMessage<P>;
8
+ /** Whether a message is a call. */
9
+ isCallMessage: <P extends any[]>(msg: string | Message<unknown>) => msg is CallMessage<P>;
10
+ /** Whether a message is an authentication one. */
11
+ isAuthMessage: <P>(msg: string | Message<P>) => msg is AuthMessage<P>;
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/helper/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAElF,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,oGAAoG;IACpG,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,KAAK,GAAG,IAAI,CAAC,CAAA;IACtF,kHAAkH;IAClH,cAAc,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAA;IACzF,mCAAmC;IACnC,aAAa,EAAE,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;IACzF,kDAAkD;IAClD,aAAa,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;CACtE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/helper/types.ts"],"names":[],"mappings":""}
package/build/helper.d.ts CHANGED
@@ -1,6 +1,9 @@
1
- import type { CallMessage, EventMessage, Message, AuthMessage } from './types.js';
1
+ import type { EventMessage, Message } from './types.js';
2
+ import type { SocketMessageHelper } from './helper/types.js';
3
+ export declare const createSocketMessageHelper: () => SocketMessageHelper;
4
+ export declare const socketMessageHelper: SocketMessageHelper;
5
+ /** @deprecated compat:factory-refactor — use `socketMessageHelper.isMessage(…)` */
2
6
  export declare const isMessage: <P, T extends Message<P>>(msg: string | T, nonSystem?: boolean) => msg is T;
7
+ /** @deprecated compat:factory-refactor — use `socketMessageHelper.isEventMessage(…)` */
3
8
  export declare const isEventMessage: <P>(msg: string | Message<P>, system?: boolean) => msg is EventMessage<P>;
4
- export declare const isCallMessage: <P extends any[]>(msg: string | Message<unknown>) => msg is CallMessage<P>;
5
- export declare const isAuthMessage: <P>(msg: string | Message<P>) => msg is AuthMessage<P>;
6
9
  //# sourceMappingURL=helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAEjF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,GAAG,CAAC,cAAc,OAAO,KAAG,GAAG,IAAI,CAEhB,CAAA;AAEjF,eAAO,MAAM,cAAc,GAAI,CAAC,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,KAAG,GAAG,IAAI,YAAY,CAAC,CAAC,CAEzB,CAAA;AAE3E,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,GAAG,EAAE,OAAO,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,KAAG,GAAG,IAAI,WAAW,CAAC,CAAC,CACnD,CAAA;AAEjD,eAAO,MAAM,aAAa,GAAI,CAAC,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,KAAG,GAAG,IAAI,WAAW,CAAC,CAAC,CAC/B,CAAA"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,YAAY,EAAE,OAAO,EAAe,MAAM,YAAY,CAAA;AACjF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAwB5D,eAAO,MAAM,yBAAyB,QAAO,mBAgB5C,CAAA;AAED,eAAO,MAAM,mBAAmB,qBAA8B,CAAA;AAE9D,mFAAmF;AACnF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,GAAG,CAAC,cAAc,OAAO,KAAG,GAAG,IAAI,CAAwD,CAAA;AAEzJ,wFAAwF;AACxF,eAAO,MAAM,cAAc,GAAI,CAAC,OAAO,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,KAAG,GAAG,IAAI,YAAY,CAAC,CAAC,CAAuD,CAAA"}
package/build/helper.js CHANGED
@@ -1,10 +1,4 @@
1
1
  import { MessageType } from './consts.js';
2
- export const isMessage = (msg, nonSystem) => typeof msg === 'object' && 'type' in msg && 'payload' in msg
3
- && (nonSystem === undefined || nonSystem === (msg.type !== MessageType.System));
4
- export const isEventMessage = (msg, system) => isMessage(msg) && [MessageType.Event, MessageType.System].includes(msg.type)
5
- && (system === undefined || system === (msg.type === MessageType.System));
6
- export const isCallMessage = (msg) => isMessage(msg) && msg.type === MessageType.Call;
7
- export const isAuthMessage = (msg) => isMessage(msg) && msg.type === MessageType.Auth;
8
2
  // export const prepareLongCalls = (connection: Connection, longTimeout = CALL_TIMEOUT * 10) => {
9
3
  // const _connection = connection as WithLongCalls
10
4
  // if (_connection[long_calls] == null) {
@@ -23,4 +17,18 @@ export const isAuthMessage = (msg) => isMessage(msg) && msg.type === MessageType
23
17
  // interface WithLongCalls extends Connection {
24
18
  // [long_calls]: boolean
25
19
  // }
20
+ export const createSocketMessageHelper = () => {
21
+ const isMessage = (msg, nonSystem) => typeof msg === 'object' && 'type' in msg && 'payload' in msg
22
+ && (nonSystem === undefined || nonSystem === (msg.type !== MessageType.System));
23
+ const isEventMessage = (msg, system) => isMessage(msg) && [MessageType.Event, MessageType.System].includes(msg.type)
24
+ && (system === undefined || system === (msg.type === MessageType.System));
25
+ const isCallMessage = (msg) => isMessage(msg) && msg.type === MessageType.Call;
26
+ const isAuthMessage = (msg) => isMessage(msg) && msg.type === MessageType.Auth;
27
+ return { isMessage, isEventMessage, isCallMessage, isAuthMessage };
28
+ };
29
+ export const socketMessageHelper = createSocketMessageHelper();
30
+ /** @deprecated compat:factory-refactor — use `socketMessageHelper.isMessage(…)` */
31
+ export const isMessage = (msg, nonSystem) => socketMessageHelper.isMessage(msg, nonSystem);
32
+ /** @deprecated compat:factory-refactor — use `socketMessageHelper.isEventMessage(…)` */
33
+ export const isEventMessage = (msg, system) => socketMessageHelper.isEventMessage(msg, system);
26
34
  //# sourceMappingURL=helper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGzC,MAAM,CAAC,MAAM,SAAS,GAAG,CAA0B,GAAe,EAAE,SAAmB,EAAY,EAAE,CACnG,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG;OACzD,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;AAEjF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAI,GAAwB,EAAE,MAAgB,EAA0B,EAAE,CACtG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;OACzE,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;AAE3E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAkB,GAA8B,EAAyB,EAAE,CACtG,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAA;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAI,GAAwB,EAAyB,EAAE,CAClF,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAA;AAGjD,iGAAiG;AACjG,oDAAoD;AACpD,2CAA2C;AAC3C,yCAAyC;AACzC,qDAAqD;AACrD,oDAAoD;AACpD,wCAAwC;AACxC,UAAU;AAEV,wDAAwD;AACxD,QAAQ;AACR,qCAAqC;AACrC,MAAM;AAEN,sBAAsB;AACtB,IAAI;AAEJ,yDAAyD;AACzD,+CAA+C;AAC/C,0BAA0B;AAC1B,IAAI"}
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAIzC,iGAAiG;AACjG,oDAAoD;AACpD,2CAA2C;AAC3C,yCAAyC;AACzC,qDAAqD;AACrD,oDAAoD;AACpD,wCAAwC;AACxC,UAAU;AAEV,wDAAwD;AACxD,QAAQ;AACR,qCAAqC;AACrC,MAAM;AAEN,sBAAsB;AACtB,IAAI;AAEJ,yDAAyD;AACzD,+CAA+C;AAC/C,0BAA0B;AAC1B,IAAI;AAEJ,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAwB,EAAE;IACjE,MAAM,SAAS,GAAG,CAA0B,GAAe,EAAE,SAAmB,EAAY,EAAE,CAC5F,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG;WACzD,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;IAEjF,MAAM,cAAc,GAAG,CAAI,GAAwB,EAAE,MAAgB,EAA0B,EAAE,CAC/F,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;WACzE,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;IAE3E,MAAM,aAAa,GAAG,CAAkB,GAA8B,EAAyB,EAAE,CAC/F,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAA;IAEjD,MAAM,aAAa,GAAG,CAAI,GAAwB,EAAyB,EAAE,CAC3E,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,CAAA;IAEjD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,CAAA;AACpE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,yBAAyB,EAAE,CAAA;AAE9D,mFAAmF;AACnF,MAAM,CAAC,MAAM,SAAS,GAAG,CAA0B,GAAe,EAAE,SAAmB,EAAY,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAO,GAAG,EAAE,SAAS,CAAC,CAAA;AAEzJ,wFAAwF;AACxF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAI,GAAwB,EAAE,MAAgB,EAA0B,EAAE,CAAC,mBAAmB,CAAC,cAAc,CAAI,GAAG,EAAE,MAAM,CAAC,CAAA"}
package/build/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export type * from './types.js';
2
+ export type * from './helper/types.js';
2
3
  export * from './consts.js';
3
4
  export * from './model.js';
4
5
  export * from './errors.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,mBAAmB,CAAA;AACtC,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAC2C,UAAU,EAEhE,MAAM,YAAY,CAAA;AAInB,eAAO,MAAM,qBAAqB,QAAO,UA+VxC,CAAA"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAC2C,UAAU,EAEhE,MAAM,YAAY,CAAA;AAOnB,eAAO,MAAM,qBAAqB,QAAO,UA+XxC,CAAA"}
package/build/model.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { ResilientError } from '@owlmeans/error';
2
2
  import { CALL_TIMEOUT, MessageType } from './consts.js';
3
- import { SocketMessageMalformed, SocketTimeout } from './errors.js';
4
- import { uuid } from '@owlmeans/basic-ids';
3
+ import { SocketMessageMalformed, SocketTimeout, SocketUnauthorized, SocketUnsupported } from './errors.js';
5
4
  import { AuthenticationStage, AuthError } from '@owlmeans/auth';
5
+ import { logger } from '@owlmeans/log';
6
+ import { idHelper } from '@owlmeans/basic-ids';
7
+ const log = logger('socket');
6
8
  export const createBasicConnection = () => {
7
9
  const listeners = [];
8
10
  const callPerformers = {};
@@ -41,7 +43,7 @@ export const createBasicConnection = () => {
41
43
  },
42
44
  call: async (method, ...payload) => {
43
45
  const msg = {
44
- method, payload, type: MessageType.Call, id: uuid()
46
+ method, payload, type: MessageType.Call, id: idHelper.uuid()
45
47
  };
46
48
  conn.prepare?.(msg);
47
49
  return new Promise(async (resolve, reject) => {
@@ -73,7 +75,7 @@ export const createBasicConnection = () => {
73
75
  },
74
76
  request: async (payload, observer) => {
75
77
  const msg = {
76
- type: MessageType.Request, payload, id: uuid()
78
+ type: MessageType.Request, payload, id: idHelper.uuid()
77
79
  };
78
80
  if (observer != null) {
79
81
  observers[msg.id] = observer;
@@ -149,122 +151,145 @@ export const createBasicConnection = () => {
149
151
  return [msg.payload, msg.id, queue.length];
150
152
  },
151
153
  receive: async (message) => {
152
- if (message.startsWith('{') || message.startsWith('[')) {
153
- let msg = message;
154
- try {
155
- msg = JSON.parse(message);
156
- }
157
- catch {
158
- }
159
- if (typeof msg === 'object') {
160
- if (msg.payload == null) {
161
- msg.payload = msg;
162
- }
163
- if (msg.type == null) {
164
- msg.type = MessageType.Message;
165
- }
166
- msg.rawData = message;
167
- if (conn.prepare != null) {
168
- conn.prepare(msg, true);
169
- }
170
- try {
171
- switch (msg.type) {
172
- case MessageType.Call: {
173
- await conn._receiveCall(msg);
174
- break;
175
- }
176
- case MessageType.Result: {
177
- await conn._receiveResult(msg);
178
- break;
179
- }
180
- case MessageType.Error: {
181
- await conn._receiveError(msg);
182
- break;
183
- }
184
- case MessageType.Request: {
185
- await conn._receiveRequest(msg);
186
- break;
154
+ if (!message.startsWith('{') && !message.startsWith('[')) {
155
+ return;
156
+ }
157
+ let parsed;
158
+ try {
159
+ parsed = JSON.parse(message);
160
+ }
161
+ catch {
162
+ throw new SocketMessageMalformed('json');
163
+ }
164
+ if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
165
+ throw new SocketMessageMalformed('shape');
166
+ }
167
+ const msg = parsed;
168
+ if (msg.payload == null) {
169
+ msg.payload = parsed;
170
+ }
171
+ if (msg.type == null) {
172
+ msg.type = MessageType.Message;
173
+ }
174
+ if (!Object.values(MessageType).includes(msg.type)) {
175
+ throw new SocketMessageMalformed('type');
176
+ }
177
+ // System frames belong to the carrier lifecycle and are never accepted from the wire.
178
+ if (msg.type === MessageType.System) {
179
+ throw new SocketMessageMalformed('system');
180
+ }
181
+ if (conn.requiresAuthentication === true
182
+ && conn.stage !== AuthenticationStage.Authenticated
183
+ && msg.type !== MessageType.Auth) {
184
+ throw new SocketUnauthorized('stage');
185
+ }
186
+ msg.rawData = message;
187
+ conn.prepare?.(msg, true);
188
+ try {
189
+ switch (msg.type) {
190
+ case MessageType.Call:
191
+ await conn._receiveCall(msg);
192
+ break;
193
+ case MessageType.Result:
194
+ await conn._receiveResult(msg);
195
+ break;
196
+ case MessageType.Error:
197
+ await conn._receiveError(msg);
198
+ break;
199
+ case MessageType.Request:
200
+ await conn._receiveRequest(msg);
201
+ break;
202
+ case MessageType.Response:
203
+ await conn._receiveResponse(msg);
204
+ break;
205
+ case MessageType.Event:
206
+ await conn._receiveEvent(msg);
207
+ break;
208
+ case MessageType.Message:
209
+ await conn._receiveMessage(msg);
210
+ break;
211
+ case MessageType.Auth: {
212
+ const authMessage = msg;
213
+ if (conn._authSequence != null) {
214
+ if (authMessage.stage == null) {
215
+ conn._authSequence.reject(ResilientError.ensure(authMessage.payload ?? new AuthError('socket:unknown')));
187
216
  }
188
- case MessageType.Response: {
189
- await conn._receiveResponse(msg);
190
- break;
217
+ else {
218
+ conn.stage = authMessage.stage;
219
+ conn._authSequence.resolve(authMessage.payload);
191
220
  }
192
- case MessageType.Event: {
193
- await conn._receiveEvent(msg);
194
- break;
221
+ conn._authSequence = undefined;
222
+ }
223
+ else {
224
+ try {
225
+ const [stage, response] = await conn.authenticate(authMessage.stage, authMessage.payload);
226
+ if (stage != null) {
227
+ void conn.auth(stage, response).catch(error => {
228
+ log.warn('Socket authentication response not sent', { error });
229
+ });
230
+ }
195
231
  }
196
- case MessageType.Message: {
197
- await conn._receiveMessage(msg);
198
- break;
232
+ catch (error) {
233
+ void conn.auth(null, ResilientError.marshal(ResilientError.ensure(error))).catch(sendError => {
234
+ log.warn('Socket authentication error not sent', { error: sendError });
235
+ });
199
236
  }
200
- case MessageType.Auth: {
201
- const _msg = msg;
202
- if (conn._authSequence != null) {
203
- if (_msg.stage == null) {
204
- conn._authSequence.reject(ResilientError.ensure(_msg.payload ?? new AuthError('socket:unknown')));
205
- }
206
- else {
207
- conn.stage = _msg.stage;
208
- conn._authSequence.resolve(_msg.payload);
209
- }
210
- conn._authSequence = undefined;
211
- }
212
- else {
213
- try {
214
- const [stage, response] = await conn.authenticate(_msg.stage, _msg.payload);
215
- if (stage != null) {
216
- conn.auth(stage, response).finally(() => void 0);
217
- }
218
- }
219
- catch (e) {
220
- conn.auth(null, ResilientError.marshal(ResilientError.ensure(e))).finally(() => void 0);
221
- }
222
- finally {
223
- conn._authSequence = undefined;
224
- }
225
- }
226
- break;
237
+ finally {
238
+ conn._authSequence = undefined;
227
239
  }
228
240
  }
229
- }
230
- catch (e) {
231
- console.error('Error on message processing:', e);
232
- throw ResilientError.ensure(e);
241
+ break;
233
242
  }
234
243
  }
235
- await Promise.all(listeners.map(async (listener) => listener(msg)));
236
244
  }
245
+ catch (error) {
246
+ throw ResilientError.ensure(error);
247
+ }
248
+ // A consumer listener is an observation hook, not part of dispatch. One rejecting listener
249
+ // must neither skip its peers nor reject the transport event callback.
250
+ await Promise.all(listeners.map(async (listener) => {
251
+ try {
252
+ await listener(msg);
253
+ }
254
+ catch (error) {
255
+ log.error('Socket listener failed', { error });
256
+ }
257
+ }));
237
258
  },
238
259
  _receiveCall: async (msg) => {
260
+ if (msg.id == null) {
261
+ throw new SocketMessageMalformed('call:id');
262
+ }
263
+ if (typeof msg.method !== 'string' || msg.method.length === 0 || !Array.isArray(msg.payload)) {
264
+ throw new SocketMessageMalformed('call');
265
+ }
239
266
  let cancel = false;
240
- callPerformers[msg.method](...msg.payload)
241
- .then(async (result) => {
242
- if (cancel) {
243
- return;
244
- }
245
- clearTimeout(timeout);
246
- const resultMsg = {
247
- id: msg.id,
248
- type: MessageType.Result,
249
- payload: result
250
- };
251
- await conn.send(resultMsg);
252
- }).catch(async (error) => {
253
- console.error('Error during the call:', error);
254
- if (cancel) {
255
- return;
256
- }
257
- clearTimeout(timeout);
258
- const response = {
259
- id: msg.id,
260
- type: MessageType.Error,
261
- payload: ResilientError.ensure(error).marshal().message
262
- };
263
- await conn.send(response);
264
- });
265
267
  msg.timeout = msg.timeout ?? conn.defaultCallTimeout ?? CALL_TIMEOUT;
266
268
  const timeout = setTimeout(() => { if (msg.timeout !== 0)
267
269
  cancel = true; }, msg.timeout);
270
+ try {
271
+ const performer = callPerformers[msg.method];
272
+ if (performer == null) {
273
+ throw new SocketUnsupported(`call:${msg.method}`);
274
+ }
275
+ const result = await performer(...msg.payload);
276
+ if (!cancel) {
277
+ await conn.send({ id: msg.id, type: MessageType.Result, payload: result });
278
+ }
279
+ }
280
+ catch (error) {
281
+ if (!cancel) {
282
+ const resilient = ResilientError.ensure(error);
283
+ await conn.send({
284
+ id: msg.id,
285
+ type: MessageType.Error,
286
+ payload: resilient.marshal().message
287
+ });
288
+ }
289
+ }
290
+ finally {
291
+ clearTimeout(timeout);
292
+ }
268
293
  },
269
294
  _receiveResult: async (msg) => {
270
295
  if (msg.id == null) {
@@ -1 +1 @@
1
- {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAKnE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAC1C,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/D,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAe,EAAE;IACpD,MAAM,SAAS,GAAyB,EAAE,CAAA;IAE1C,MAAM,cAAc,GAAkD,EAAE,CAAA;IACxE,MAAM,KAAK,GAAwC,EAAE,CAAA;IACrD,MAAM,oBAAoB,GAA0B,EAAE,CAAA;IACtD,MAAM,SAAS,GAAyD,EAAE,CAAA;IAC1E,MAAM,iBAAiB,GAA2C,EAAE,CAAA;IACpE,MAAM,cAAc,GAAyE,EAAE,CAAA;IAC/F,MAAM,KAAK,GAAmB,EAAE,CAAA;IAEhC,MAAM,IAAI,GAAe;QACvB,KAAK,EAAE,mBAAmB,CAAC,IAAI;QAE/B,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,IAAI,WAAW,CAAC,2CAA2C,CAAC,CAAA;QACpE,CAAC;QACD,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,IAAI,WAAW,CAAC,4CAA4C,CAAC,CAAA;QACrE,CAAC;QACD,YAAY,EAAE,KAAK,IAAI,EAAE;YACvB,MAAM,IAAI,WAAW,CAAC,mDAAmD,CAAC,CAAA;QAC5E,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC/B,MAAM,GAAG,GAAsB;gBAC7B,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,KAAK;aACxC,CAAA;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtB,CAAC;QAED,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1B,cAAc,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;YACnD,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnC,OAAO,GAAG,EAAE;gBACV,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBACpD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACjB,cAAc,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBACxC,CAAC;YACH,CAAC,CAAA;QACH,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE;YACjC,MAAM,GAAG,GAAqB;gBAC5B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE;aACpD,CAAA;YACD,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;YACnB,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,kBAAkB,IAAI,YAAY,CAAA;gBACpE,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;gBACrG,KAAK,CAAC,GAAG,CAAC,EAAG,CAAC,GAAG;oBACf,OAAO,EAAE,KAAK,CAAC,EAAE;wBACf,YAAY,CAAC,OAAO,CAAC,CAAA;wBACrB,OAAO,KAAK,CAAC,GAAG,CAAC,EAAG,CAAC,CAAA;wBACrB,OAAO,CAAC,KAAK,CAAC,CAAA;oBAChB,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;wBACjB,YAAY,CAAC,OAAO,CAAC,CAAA;wBACrB,OAAO,KAAK,CAAC,GAAG,CAAC,EAAG,CAAC,CAAA;wBACrB,MAAM,CAAC,KAAK,CAAC,CAAA;oBACf,CAAC;iBACF,CAAA;gBAED,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACtB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,YAAY,CAAC,OAAO,CAAC,CAAA;oBACrB,OAAO,KAAK,CAAC,GAAG,CAAC,EAAG,CAAC,CAAA;oBACrB,MAAM,CAAC,CAAC,CAAC,CAAA;gBACX,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YACjC,cAAc,CAAC,MAAM,CAAC,GAAG,OAAO,CAAA;QAClC,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;YACnC,MAAM,GAAG,GAAiB;gBACxB,IAAI,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE;aAC/C,CAAA;YACD,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;gBACrB,SAAS,CAAC,GAAG,CAAC,EAAG,CAAC,GAAG,QAAQ,CAAA;YAC/B,CAAC;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAEpB,OAAO,GAAG,EAAE;gBACV,IAAI,SAAS,CAAC,GAAG,CAAC,EAAG,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC/B,OAAO,SAAS,CAAC,GAAG,CAAC,EAAG,CAAC,CAAA;gBAC3B,CAAC;YACH,CAAC,CAAA;QACH,CAAC;QAED,eAAe,EAAE,KAAK,EAAC,QAAQ,EAAC,EAAE;YAChC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAChC,OAAO,GAAG,EAAE;gBACV,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;gBACjD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACjB,iBAAiB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBACpC,CAAC;YACH,CAAC,CAAA;QACH,CAAC;QAED,WAAW,EAAE,OAAO,CAAC,EAAE;YACrB,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAElC,OAAO,GAAG,EAAE;gBACV,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;gBACnD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACjB,oBAAoB,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC,CAAA;QACH,CAAC;QAED,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAiB;gBACxB,IAAI,EAAE,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;aACxC,CAAA;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtB,CAAC;QAED,MAAM,EAAE,QAAQ,CAAC,EAAE;YACjB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACxB,OAAO,GAAG,EAAE;gBACV,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;gBACzC,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;oBACjB,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;gBAC5B,CAAC;YACH,CAAC,CAAA;QACH,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAC7B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;YAClB,MAAM,GAAG,GAAqB,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;YAExE,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;gBACxC,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACtB,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE;YAC7B,MAAM,GAAG,GAAiB;gBACxB,IAAI,EAAE,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;aACvC,CAAA;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACtB,CAAC;QAED,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM;QAE5B,OAAO,EAAE,MAAM,CAAC,EAAE;YAChB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAA;YACb,CAAC;YACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;gBACzB,OAAO,CAAC,GAAG,EAAE,OAAO,IAAI,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;YACtD,CAAC;YACD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;YACzD,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;YACnC,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;YAEpC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAC5C,CAAC;QAED,OAAO,EAAE,KAAK,EAAC,OAAO,EAAC,EAAE;YACvB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvD,IAAI,GAAG,GAA0B,OAAO,CAAA;gBACxC,IAAI,CAAC;oBACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBAC3B,CAAC;gBAAC,MAAM,CAAC;gBACT,CAAC;gBACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC5B,IAAI,GAAG,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;wBACxB,GAAG,CAAC,OAAO,GAAG,GAAG,CAAA;oBACnB,CAAC;oBACD,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;wBACrB,GAAG,CAAC,IAAI,GAAG,WAAW,CAAC,OAAO,CAAA;oBAChC,CAAC;oBACD,GAAG,CAAC,OAAO,GAAG,OAAO,CAAA;oBACrB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;wBACzB,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;oBACzB,CAAC;oBACD,IAAI,CAAC;wBACH,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;4BACjB,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;gCACtB,MAAM,IAAI,CAAC,YAAY,CAAC,GAAuB,CAAC,CAAA;gCAChD,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;gCACxB,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;gCAC9B,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,KAAK,EAAE,CAAC;gCACvB,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAA;gCAC7B,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gCACzB,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;gCAC/B,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,QAAQ,EAAE,CAAC;gCAC1B,MAAM,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAA;gCAChC,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,KAAK,EAAE,CAAC;gCACvB,MAAM,IAAI,CAAC,aAAa,CAAC,GAAwB,CAAC,CAAA;gCAClD,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,OAAO,EAAE,CAAC;gCACzB,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;gCAC/B,MAAK;4BACP,CAAC;4BACD,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;gCACtB,MAAM,IAAI,GAAqB,GAAuB,CAAA;gCACtD,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;oCAC/B,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;wCACvB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;oCACnG,CAAC;yCAAM,CAAC;wCACN,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;wCACvB,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;oCAC1C,CAAC;oCACD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;gCAChC,CAAC;qCAAM,CAAC;oCACN,IAAI,CAAC;wCACH,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;wCAC3E,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;4CAClB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;wCAClD,CAAC;oCACH,CAAC;oCAAC,OAAO,CAAC,EAAE,CAAC;wCACX,IAAI,CAAC,IAAI,CAAC,IAAW,EAAE,cAAc,CAAC,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC,CAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;oCACzG,CAAC;4CAAS,CAAC;wCACT,IAAI,CAAC,aAAa,GAAG,SAAS,CAAA;oCAChC,CAAC;gCACH,CAAC;gCACD,MAAK;4BACP,CAAC;wBACH,CAAC;oBACH,CAAC;oBAAC,OAAO,CAAC,EAAE,CAAC;wBACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAA;wBAChD,MAAM,cAAc,CAAC,MAAM,CAAC,CAAU,CAAC,CAAA;oBACzC,CAAC;gBACH,CAAC;gBACD,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAC,QAAQ,EAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YACnE,CAAC;QACH,CAAC;QAED,YAAY,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YACxB,IAAI,MAAM,GAAG,KAAK,CAAA;YAClB,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC;iBACvC,IAAI,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE;gBACnB,IAAI,MAAM,EAAE,CAAC;oBACX,OAAM;gBACR,CAAC;gBACD,YAAY,CAAC,OAAO,CAAC,CAAA;gBACrB,MAAM,SAAS,GAAiB;oBAC9B,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,IAAI,EAAE,WAAW,CAAC,MAAM;oBACxB,OAAO,EAAE,MAAM;iBAChB,CAAA;gBACD,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC5B,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;gBACrB,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAA;gBAC9C,IAAI,MAAM,EAAE,CAAC;oBACX,OAAM;gBACR,CAAC;gBACD,YAAY,CAAC,OAAO,CAAC,CAAA;gBACrB,MAAM,QAAQ,GAAiB;oBAC7B,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,IAAI,EAAE,WAAW,CAAC,KAAK;oBACvB,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO;iBACxD,CAAA;gBACD,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC3B,CAAC,CAAC,CAAA;YACJ,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,kBAAkB,IAAI,YAAY,CAAA;YACpE,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC;gBAAE,MAAM,GAAG,IAAI,CAAA,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QACzF,CAAC;QAED,cAAc,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YAC1B,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAsB,CAAC,WAAW,CAAC,CAAA;YAC/C,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAA;YACnC,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAClC,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACtB,CAAC;QAED,aAAa,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YACzB,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAsB,CAAC,WAAW,CAAC,CAAA;YAC/C,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC1B,MAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAA;YACnC,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;YACxD,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACtB,CAAC;QAED,eAAe,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YAC3B,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAsB,CAAC,YAAY,CAAC,CAAA;YAChD,CAAC;YACD,MAAM,oBAAoB,CAAC,MAAM,CAC/B,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE;gBAClC,IAAI,MAAM,WAAW,EAAE,CAAC;oBACtB,OAAO,WAAW,CAAA;gBACpB,CAAC;gBACD,OAAO,YAAY,CAAC,GAAG,CAAC,EAAY,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;YACpD,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAC1B,CAAA;QACH,CAAC;QAED,gBAAgB,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YAC5B,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAM,IAAI,sBAAsB,CAAC,aAAa,CAAC,CAAA;YACjD,CAAC;YACD,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;gBAC9B,MAAM,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;gBACpC,OAAO,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC1B,CAAC;YACD,MAAM,iBAAiB,CAAC,MAAM,CAC5B,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;gBAC3B,IAAI,MAAM,QAAQ,EAAE,CAAC;oBACnB,OAAO,QAAQ,CAAA;gBACjB,CAAC;gBACD,OAAO,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAC9B,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAC1B,CAAA;QACH,CAAC;QAED,aAAa,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YACzB,IAAI,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;gBACtB,MAAM,IAAI,sBAAsB,CAAC,OAAO,CAAC,CAAA;YAC3C,CAAC;YACD,IAAI,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;gBACtC,OAAM;YACR,CAAC;YACD,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,EAAC,QAAQ,EAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACnF,CAAC;QAED,eAAe,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjB,CAAC;QAED,YAAY,EAAE,GAAG,EAAE,CAAC,SAAS;KAC9B,CAAA;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA"}
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/build/types.d.ts CHANGED
@@ -5,6 +5,11 @@ export interface Connection {
5
5
  defaultCallTimeout?: number;
6
6
  _authSequence?: CallResolver<any>;
7
7
  stage: AuthenticationStage;
8
+ /**
9
+ * When enabled by a server carrier, only authentication frames are accepted until the
10
+ * connection reaches `AuthenticationStage.Authenticated`.
11
+ */
12
+ requiresAuthentication?: boolean;
8
13
  notify: <T>(event: string, payload: T) => Promise<void>;
9
14
  observe: <T>(event: string, handler: (event: EventMessage<T>) => Promise<void>) => () => void;
10
15
  call: <R, T extends any[]>(method: string, ...payload: T) => Promise<R>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/socket",
3
- "version": "0.1.18-rc.9",
3
+ "version": "0.1.18",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -21,12 +21,13 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@owlmeans/auth": "^0.1.18-rc.9",
25
- "@owlmeans/basic-ids": "^0.1.18-rc.9",
26
- "@owlmeans/error": "^0.1.18-rc.8"
24
+ "@owlmeans/auth": "^0.1.18",
25
+ "@owlmeans/basic-ids": "^0.1.18",
26
+ "@owlmeans/error": "^0.1.18",
27
+ "@owlmeans/log": "^0.1.18"
27
28
  },
28
29
  "devDependencies": {
29
- "@owlmeans/dep-config": "workspace:*",
30
+ "@owlmeans/dep-config": "^0.1.18",
30
31
  "nodemon": "^3.1.14",
31
32
  "typescript": "^7.0.2"
32
33
  },
package/src/consts.ts CHANGED
@@ -12,3 +12,26 @@ export enum MessageType {
12
12
  }
13
13
 
14
14
  export const CALL_TIMEOUT = 60000
15
+
16
+ /**
17
+ * System frames a carrier synthesises around the lifecycle of the underlying transport.
18
+ *
19
+ * `Close` means the connection is gone for good — a client-initiated close, or a terminal server
20
+ * code. A drop the carrier intends to retry is reported as `Disconnected`, and an exhausted retry
21
+ * budget as `Lost` alone: a lost connection can still be revived, so it is not closed.
22
+ */
23
+ export enum SocketSystemEvent {
24
+ Close = 'close',
25
+ Disconnected = 'disconnected',
26
+ Reconnecting = 'reconnecting',
27
+ Reconnected = 'reconnected',
28
+ Lost = 'lost'
29
+ }
30
+
31
+ /**
32
+ * The close code a carrier uses when it drops a socket itself — a missed heartbeat pong within
33
+ * `pongTimeout`, catching a half-open TCP connection long before the OS would notice one.
34
+ * Reserved in the 4000–4999 private-use range so it is never confused with a code either
35
+ * endpoint's own WebSocket stack could produce.
36
+ */
37
+ export const SOCKET_HEARTBEAT_TIMEOUT_CODE = 4000
@@ -0,0 +1,13 @@
1
+ import type { AuthMessage, CallMessage, EventMessage, Message } from '../types.js'
2
+
3
+ /** Recognizes the kinds of socket message. */
4
+ export interface SocketMessageHelper {
5
+ /** Whether a received value is a message; `nonSystem` also requires it (not) to be a system one. */
6
+ isMessage: <P, T extends Message<P>>(msg: string | T, nonSystem?: boolean) => msg is T
7
+ /** Whether a message is an event (system events included); `system` also requires it (not) to be a system one. */
8
+ isEventMessage: <P>(msg: string | Message<P>, system?: boolean) => msg is EventMessage<P>
9
+ /** Whether a message is a call. */
10
+ isCallMessage: <P extends any[]>(msg: string | Message<unknown>) => msg is CallMessage<P>
11
+ /** Whether a message is an authentication one. */
12
+ isAuthMessage: <P>(msg: string | Message<P>) => msg is AuthMessage<P>
13
+ }
package/src/helper.ts CHANGED
@@ -1,20 +1,6 @@
1
1
  import { MessageType } from './consts.js'
2
2
  import type { CallMessage, EventMessage, Message, AuthMessage } from './types.js'
3
-
4
- export const isMessage = <P, T extends Message<P>>(msg: string | T, nonSystem?: boolean): msg is T =>
5
- typeof msg === 'object' && 'type' in msg && 'payload' in msg
6
- && (nonSystem === undefined || nonSystem === (msg.type !== MessageType.System))
7
-
8
- export const isEventMessage = <P>(msg: string | Message<P>, system?: boolean): msg is EventMessage<P> =>
9
- isMessage(msg) && [MessageType.Event, MessageType.System].includes(msg.type)
10
- && (system === undefined || system === (msg.type === MessageType.System))
11
-
12
- export const isCallMessage = <P extends any[]>(msg: string | Message<unknown>): msg is CallMessage<P> =>
13
- isMessage(msg) && msg.type === MessageType.Call
14
-
15
- export const isAuthMessage = <P>(msg: string | Message<P>): msg is AuthMessage<P> =>
16
- isMessage(msg) && msg.type === MessageType.Auth
17
-
3
+ import type { SocketMessageHelper } from './helper/types.js'
18
4
 
19
5
  // export const prepareLongCalls = (connection: Connection, longTimeout = CALL_TIMEOUT * 10) => {
20
6
  // const _connection = connection as WithLongCalls
@@ -37,3 +23,29 @@ export const isAuthMessage = <P>(msg: string | Message<P>): msg is AuthMessage<P
37
23
  // interface WithLongCalls extends Connection {
38
24
  // [long_calls]: boolean
39
25
  // }
26
+
27
+ export const createSocketMessageHelper = (): SocketMessageHelper => {
28
+ const isMessage = <P, T extends Message<P>>(msg: string | T, nonSystem?: boolean): msg is T =>
29
+ typeof msg === 'object' && 'type' in msg && 'payload' in msg
30
+ && (nonSystem === undefined || nonSystem === (msg.type !== MessageType.System))
31
+
32
+ const isEventMessage = <P>(msg: string | Message<P>, system?: boolean): msg is EventMessage<P> =>
33
+ isMessage(msg) && [MessageType.Event, MessageType.System].includes(msg.type)
34
+ && (system === undefined || system === (msg.type === MessageType.System))
35
+
36
+ const isCallMessage = <P extends any[]>(msg: string | Message<unknown>): msg is CallMessage<P> =>
37
+ isMessage(msg) && msg.type === MessageType.Call
38
+
39
+ const isAuthMessage = <P>(msg: string | Message<P>): msg is AuthMessage<P> =>
40
+ isMessage(msg) && msg.type === MessageType.Auth
41
+
42
+ return { isMessage, isEventMessage, isCallMessage, isAuthMessage }
43
+ }
44
+
45
+ export const socketMessageHelper = createSocketMessageHelper()
46
+
47
+ /** @deprecated compat:factory-refactor — use `socketMessageHelper.isMessage(…)` */
48
+ export const isMessage = <P, T extends Message<P>>(msg: string | T, nonSystem?: boolean): msg is T => socketMessageHelper.isMessage<P, T>(msg, nonSystem)
49
+
50
+ /** @deprecated compat:factory-refactor — use `socketMessageHelper.isEventMessage(…)` */
51
+ export const isEventMessage = <P>(msg: string | Message<P>, system?: boolean): msg is EventMessage<P> => socketMessageHelper.isEventMessage<P>(msg, system)
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
2
  export type * from './types.js'
3
+ export type * from './helper/types.js'
3
4
  export * from './consts.js'
4
5
  export * from './model.js'
5
6
  export * from './errors.js'
package/src/model.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  import { ResilientError } from '@owlmeans/error'
2
2
  import { CALL_TIMEOUT, MessageType } from './consts.js'
3
- import { SocketMessageMalformed, SocketTimeout } from './errors.js'
3
+ import { SocketMessageMalformed, SocketTimeout, SocketUnauthorized, SocketUnsupported } from './errors.js'
4
4
  import type {
5
5
  AuthMessage, CallHendler, CallMessage, CallResolver, Connection, ConnectionListener,
6
6
  EventMessage, Message, RequestHandler
7
7
  } from './types.js'
8
- import { uuid } from '@owlmeans/basic-ids'
9
8
  import { AuthenticationStage, AuthError } from '@owlmeans/auth'
9
+ import { logger } from '@owlmeans/log'
10
+ import { idHelper } from '@owlmeans/basic-ids'
11
+
12
+ const log = logger('socket')
10
13
 
11
14
  export const createBasicConnection = (): Connection => {
12
15
  const listeners: ConnectionListener[] = []
@@ -52,7 +55,7 @@ export const createBasicConnection = (): Connection => {
52
55
 
53
56
  call: async (method, ...payload) => {
54
57
  const msg: CallMessage<any> = {
55
- method, payload, type: MessageType.Call, id: uuid()
58
+ method, payload, type: MessageType.Call, id: idHelper.uuid()
56
59
  }
57
60
  conn.prepare?.(msg)
58
61
  return new Promise(async (resolve, reject) => {
@@ -86,7 +89,7 @@ export const createBasicConnection = (): Connection => {
86
89
 
87
90
  request: async (payload, observer) => {
88
91
  const msg: Message<any> = {
89
- type: MessageType.Request, payload, id: uuid()
92
+ type: MessageType.Request, payload, id: idHelper.uuid()
90
93
  }
91
94
  if (observer != null) {
92
95
  observers[msg.id!] = observer
@@ -175,116 +178,148 @@ export const createBasicConnection = (): Connection => {
175
178
  },
176
179
 
177
180
  receive: async message => {
178
- if (message.startsWith('{') || message.startsWith('[')) {
179
- let msg: Message<any> | string = message
180
- try {
181
- msg = JSON.parse(message)
182
- } catch {
183
- }
184
- if (typeof msg === 'object') {
185
- if (msg.payload == null) {
186
- msg.payload = msg
187
- }
188
- if (msg.type == null) {
189
- msg.type = MessageType.Message
190
- }
191
- msg.rawData = message
192
- if (conn.prepare != null) {
193
- conn.prepare(msg, true)
194
- }
195
- try {
196
- switch (msg.type) {
197
- case MessageType.Call: {
198
- await conn._receiveCall(msg as CallMessage<any>)
199
- break
200
- }
201
- case MessageType.Result: {
202
- await conn._receiveResult(msg)
203
- break
204
- }
205
- case MessageType.Error: {
206
- await conn._receiveError(msg)
207
- break
208
- }
209
- case MessageType.Request: {
210
- await conn._receiveRequest(msg)
211
- break
212
- }
213
- case MessageType.Response: {
214
- await conn._receiveResponse(msg)
215
- break
216
- }
217
- case MessageType.Event: {
218
- await conn._receiveEvent(msg as EventMessage<any>)
219
- break
220
- }
221
- case MessageType.Message: {
222
- await conn._receiveMessage(msg)
223
- break
181
+ if (!message.startsWith('{') && !message.startsWith('[')) {
182
+ return
183
+ }
184
+
185
+ let parsed: unknown
186
+ try {
187
+ parsed = JSON.parse(message)
188
+ } catch {
189
+ throw new SocketMessageMalformed('json')
190
+ }
191
+ if (parsed == null || typeof parsed !== 'object' || Array.isArray(parsed)) {
192
+ throw new SocketMessageMalformed('shape')
193
+ }
194
+
195
+ const msg = parsed as Message<any>
196
+ if (msg.payload == null) {
197
+ msg.payload = parsed
198
+ }
199
+ if (msg.type == null) {
200
+ msg.type = MessageType.Message
201
+ }
202
+ if (!Object.values(MessageType).includes(msg.type)) {
203
+ throw new SocketMessageMalformed('type')
204
+ }
205
+ // System frames belong to the carrier lifecycle and are never accepted from the wire.
206
+ if (msg.type === MessageType.System) {
207
+ throw new SocketMessageMalformed('system')
208
+ }
209
+ if (conn.requiresAuthentication === true
210
+ && conn.stage !== AuthenticationStage.Authenticated
211
+ && msg.type !== MessageType.Auth) {
212
+ throw new SocketUnauthorized('stage')
213
+ }
214
+
215
+ msg.rawData = message
216
+ conn.prepare?.(msg, true)
217
+
218
+ try {
219
+ switch (msg.type) {
220
+ case MessageType.Call:
221
+ await conn._receiveCall(msg as CallMessage<any>)
222
+ break
223
+ case MessageType.Result:
224
+ await conn._receiveResult(msg)
225
+ break
226
+ case MessageType.Error:
227
+ await conn._receiveError(msg)
228
+ break
229
+ case MessageType.Request:
230
+ await conn._receiveRequest(msg)
231
+ break
232
+ case MessageType.Response:
233
+ await conn._receiveResponse(msg)
234
+ break
235
+ case MessageType.Event:
236
+ await conn._receiveEvent(msg as EventMessage<any>)
237
+ break
238
+ case MessageType.Message:
239
+ await conn._receiveMessage(msg)
240
+ break
241
+ case MessageType.Auth: {
242
+ const authMessage = msg as AuthMessage<any>
243
+ if (conn._authSequence != null) {
244
+ if (authMessage.stage == null) {
245
+ conn._authSequence.reject(ResilientError.ensure(
246
+ authMessage.payload ?? new AuthError('socket:unknown')
247
+ ))
248
+ } else {
249
+ conn.stage = authMessage.stage
250
+ conn._authSequence.resolve(authMessage.payload)
224
251
  }
225
- case MessageType.Auth: {
226
- const _msg: AuthMessage<any> = msg as AuthMessage<any>
227
- if (conn._authSequence != null) {
228
- if (_msg.stage == null) {
229
- conn._authSequence.reject(ResilientError.ensure(_msg.payload ?? new AuthError('socket:unknown')))
230
- } else {
231
- conn.stage = _msg.stage
232
- conn._authSequence.resolve(_msg.payload)
233
- }
234
- conn._authSequence = undefined
235
- } else {
236
- try {
237
- const [stage, response] = await conn.authenticate(_msg.stage, _msg.payload)
238
- if (stage != null) {
239
- conn.auth(stage, response).finally(() => void 0)
240
- }
241
- } catch (e) {
242
- conn.auth(null as any, ResilientError.marshal(ResilientError.ensure(e as Error))).finally(() => void 0)
243
- } finally {
244
- conn._authSequence = undefined
245
- }
252
+ conn._authSequence = undefined
253
+ } else {
254
+ try {
255
+ const [stage, response] = await conn.authenticate(authMessage.stage, authMessage.payload)
256
+ if (stage != null) {
257
+ void conn.auth(stage, response).catch(error => {
258
+ log.warn('Socket authentication response not sent', { error })
259
+ })
246
260
  }
247
- break
261
+ } catch (error) {
262
+ void conn.auth(
263
+ null as any,
264
+ ResilientError.marshal(ResilientError.ensure(error as Error))
265
+ ).catch(sendError => {
266
+ log.warn('Socket authentication error not sent', { error: sendError })
267
+ })
268
+ } finally {
269
+ conn._authSequence = undefined
248
270
  }
249
271
  }
250
- } catch (e) {
251
- console.error('Error on message processing:', e)
252
- throw ResilientError.ensure(e as Error)
272
+ break
253
273
  }
254
274
  }
255
- await Promise.all(listeners.map(async listener => listener(msg)))
275
+ } catch (error) {
276
+ throw ResilientError.ensure(error as Error)
256
277
  }
278
+
279
+ // A consumer listener is an observation hook, not part of dispatch. One rejecting listener
280
+ // must neither skip its peers nor reject the transport event callback.
281
+ await Promise.all(listeners.map(async listener => {
282
+ try {
283
+ await listener(msg)
284
+ } catch (error) {
285
+ log.error('Socket listener failed', { error })
286
+ }
287
+ }))
257
288
  },
258
289
 
259
290
  _receiveCall: async msg => {
291
+ if (msg.id == null) {
292
+ throw new SocketMessageMalformed('call:id')
293
+ }
294
+ if (typeof msg.method !== 'string' || msg.method.length === 0 || !Array.isArray(msg.payload)) {
295
+ throw new SocketMessageMalformed('call')
296
+ }
297
+
260
298
  let cancel = false
261
- callPerformers[msg.method](...msg.payload)
262
- .then(async result => {
263
- if (cancel) {
264
- return
265
- }
266
- clearTimeout(timeout)
267
- const resultMsg: Message<any> = {
268
- id: msg.id,
269
- type: MessageType.Result,
270
- payload: result
271
- }
272
- await conn.send(resultMsg)
273
- }).catch(async error => {
274
- console.error('Error during the call:', error)
275
- if (cancel) {
276
- return
277
- }
278
- clearTimeout(timeout)
279
- const response: Message<any> = {
280
- id: msg.id,
281
- type: MessageType.Error,
282
- payload: ResilientError.ensure(error).marshal().message
283
- }
284
- await conn.send(response)
285
- })
286
299
  msg.timeout = msg.timeout ?? conn.defaultCallTimeout ?? CALL_TIMEOUT
287
300
  const timeout = setTimeout(() => { if (msg.timeout !== 0) cancel = true }, msg.timeout)
301
+
302
+ try {
303
+ const performer = callPerformers[msg.method]
304
+ if (performer == null) {
305
+ throw new SocketUnsupported(`call:${msg.method}`)
306
+ }
307
+ const result = await performer(...msg.payload)
308
+ if (!cancel) {
309
+ await conn.send({ id: msg.id, type: MessageType.Result, payload: result })
310
+ }
311
+ } catch (error) {
312
+ if (!cancel) {
313
+ const resilient = ResilientError.ensure(error as Error)
314
+ await conn.send({
315
+ id: msg.id,
316
+ type: MessageType.Error,
317
+ payload: resilient.marshal().message
318
+ })
319
+ }
320
+ } finally {
321
+ clearTimeout(timeout)
322
+ }
288
323
  },
289
324
 
290
325
  _receiveResult: async msg => {
package/src/types.ts CHANGED
@@ -9,6 +9,12 @@ export interface Connection {
9
9
 
10
10
  stage: AuthenticationStage
11
11
 
12
+ /**
13
+ * When enabled by a server carrier, only authentication frames are accepted until the
14
+ * connection reaches `AuthenticationStage.Authenticated`.
15
+ */
16
+ requiresAuthentication?: boolean
17
+
12
18
  notify: <T>(event: string, payload: T) => Promise<void>
13
19
  observe: <T>(event: string, handler: (event: EventMessage<T>) => Promise<void>) => () => void
14
20
 
@@ -0,0 +1,59 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { AuthenticationStage } from '@owlmeans/auth'
3
+ import { ResilientError } from '@owlmeans/error'
4
+ import {
5
+ createBasicConnection, MessageType, SocketMessageMalformed, SocketUnauthorized, SocketUnsupported
6
+ } from '../src/index.js'
7
+ import type { Message } from '../src/index.js'
8
+
9
+ describe('@owlmeans/socket — inbound frame boundary', () => {
10
+ test('rejects malformed JSON, non-object frames, and wire System frames', async () => {
11
+ const connection = createBasicConnection()
12
+
13
+ await expect(connection.receive('{')).rejects.toBeInstanceOf(SocketMessageMalformed)
14
+ await expect(connection.receive('[]')).rejects.toBeInstanceOf(SocketMessageMalformed)
15
+ await expect(connection.receive(JSON.stringify({
16
+ type: MessageType.System, event: 'close', payload: {}
17
+ }))).rejects.toBeInstanceOf(SocketMessageMalformed)
18
+ })
19
+
20
+ test('permits only authentication frames before a server carrier authenticates the connection', async () => {
21
+ const connection = createBasicConnection()
22
+ connection.requiresAuthentication = true
23
+
24
+ await expect(connection.receive(JSON.stringify({
25
+ type: MessageType.Message, payload: 'before-auth'
26
+ }))).rejects.toBeInstanceOf(SocketUnauthorized)
27
+
28
+ connection.stage = AuthenticationStage.Authenticated
29
+ await connection.receive(JSON.stringify({ type: MessageType.Message, payload: 'after-auth' }))
30
+ expect(connection.consume()).toEqual(['after-auth', undefined, 0])
31
+ })
32
+
33
+ test('answers an unknown call with a typed error instead of rejecting dispatch', async () => {
34
+ const connection = createBasicConnection()
35
+ const sent: Message<unknown>[] = []
36
+ connection.send = async message => {
37
+ if (typeof message !== 'string') sent.push(message)
38
+ }
39
+
40
+ await connection.receive(JSON.stringify({
41
+ type: MessageType.Call, id: 'call-1', method: 'missing', payload: []
42
+ }))
43
+
44
+ expect(sent).toHaveLength(1)
45
+ expect(sent[0]?.type).toBe(MessageType.Error)
46
+ expect(ResilientError.ensure(sent[0]?.payload as string)).toBeInstanceOf(SocketUnsupported)
47
+ })
48
+
49
+ test('isolates rejecting listeners and still runs their peers', async () => {
50
+ const connection = createBasicConnection()
51
+ let observed = false
52
+ connection.listen(async () => { throw new Error('listener failed') })
53
+ connection.listen(async () => { observed = true })
54
+
55
+ await connection.receive(JSON.stringify({ type: MessageType.Message, payload: 'event' }))
56
+
57
+ expect(observed).toBe(true)
58
+ })
59
+ })
package/tsconfig.json CHANGED
@@ -7,5 +7,5 @@
7
7
  "rootDir": "./src/",
8
8
  "outDir": "./build/"
9
9
  },
10
- "exclude": ["./dist/**/*", "./build/**/*", "./*.ts"]
10
+ "exclude": ["./dist/**/*", "./build/**/*", "./tests/**/*", "./*.ts"]
11
11
  }