@mono-labs/dev 0.1.255 → 0.1.257

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 ADDED
@@ -0,0 +1,294 @@
1
+ # @mono-labs/dev
2
+
3
+ Local development server and WebSocket adapter for mono-labs. Maps Lambda handlers to Express routes, emulates API Gateway WebSocket connections, and provides a Redis caching abstraction.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ yarn add @mono-labs/dev
9
+ ```
10
+
11
+ ### Optional Peer Dependencies
12
+
13
+ ```bash
14
+ # For Redis-backed channel store and CacheRelay
15
+ yarn add ioredis
16
+
17
+ # For API Gateway WebSocket mode (SocketGatewayClient)
18
+ yarn add @aws-sdk/client-apigatewaymanagementapi
19
+ ```
20
+
21
+ ## API Reference
22
+
23
+ ### LocalServer
24
+
25
+ Express-based HTTP server that maps Lambda handlers to local routes.
26
+
27
+ ```typescript
28
+ import { LocalServer } from '@mono-labs/dev'
29
+
30
+ const server = new LocalServer({ debug: true })
31
+ ```
32
+
33
+ - **`constructor(config?)`** -- Creates a new server. `LocalServerConfig` options: `debug?: boolean`, `useRedis?: boolean`, `redis?: RedisConfig`.
34
+ - **`.app`** -- The underlying `express.Express` instance for custom middleware.
35
+
36
+ #### `.lambda(path, handler, options?)`
37
+
38
+ Registers a Lambda handler at the given HTTP path. Supports two event types:
39
+
40
+ ```typescript
41
+ // API Gateway V2 (default)
42
+ server.lambda('/api/*', myApiGatewayHandler)
43
+ server.lambda('/api/*', myApiGatewayHandler, { eventType: 'api-gateway' })
44
+
45
+ // Application Load Balancer
46
+ server.lambda('/alb/*', myALBHandler, { eventType: 'alb' })
47
+ ```
48
+
49
+ #### `.attachSocket(adapterFn, config?)`
50
+
51
+ Attaches the WebSocket adapter to the server's HTTP instance:
52
+
53
+ ```typescript
54
+ import { attachSocketAdapter } from '@mono-labs/dev'
55
+
56
+ const socket = server.attachSocket(attachSocketAdapter, {
57
+ debug: true,
58
+ connectHandler: async (connectionId, { token }) => ({
59
+ response: { statusCode: 200 },
60
+ userContext: { userId: '123', organizationId: 'org-1' }
61
+ }),
62
+ routes: {
63
+ ping: async (body, ctx) => ({ statusCode: 200, body: 'pong' })
64
+ }
65
+ })
66
+ ```
67
+
68
+ Returns the same object as `attachSocketAdapter()` (see below).
69
+
70
+ #### `.listen(port, hostname?)`
71
+
72
+ Starts the HTTP server:
73
+
74
+ ```typescript
75
+ server.listen(3000)
76
+ ```
77
+
78
+ ---
79
+
80
+ ### WebSocket System
81
+
82
+ #### `attachSocketAdapter(wss, config?)`
83
+
84
+ Wires a `WebSocketServer` instance with connection tracking, action routing, and event synthesis:
85
+
86
+ ```typescript
87
+ import { WebSocketServer } from 'ws'
88
+ import { attachSocketAdapter } from '@mono-labs/dev'
89
+
90
+ const wss = new WebSocketServer({ noServer: true })
91
+ const {
92
+ postToConnection,
93
+ connectionRegistry,
94
+ actionRouter,
95
+ channelStore,
96
+ socketEmitter,
97
+ getConnectionId,
98
+ } = attachSocketAdapter(wss, { debug: true })
99
+ ```
100
+
101
+ **`SocketAdapterConfig`** options:
102
+ - `domainName?: string` -- Domain for synthesized events (default: `'localhost'`)
103
+ - `stage?: string` -- Stage for synthesized events (default: `'local'`)
104
+ - `debug?: boolean` -- Enable debug logging
105
+ - `connectHandler?: ConnectHandlerFn` -- Custom $connect handler
106
+ - `disconnectHandler?: DisconnectHandlerFn` -- Custom $disconnect handler
107
+ - `routes?: Record<string, ActionHandler>` -- Action routes
108
+ - `defaultHandler?: ActionHandler` -- Fallback for unmatched actions
109
+ - `channelStore?: ChannelStore` -- Custom channel store implementation
110
+ - `useRedis?: boolean` -- Use Redis-backed channel store
111
+ - `redis?: RedisConfig` -- Redis connection options
112
+
113
+ #### `ConnectionRegistry`
114
+
115
+ Tracks WebSocket connections and their user contexts:
116
+
117
+ ```typescript
118
+ registry.register(ws): ConnectionId
119
+ registry.unregister(connectionId): void
120
+ registry.get(connectionId): WebSocket | undefined
121
+ registry.getAll(): ConnectionId[]
122
+ registry.setUserContext(connectionId, ctx): void
123
+ registry.getUserContext(connectionId): WebSocketUserContext | undefined
124
+ registry.getConnectionsByUserId(userId): ConnectionId[]
125
+ registry.getConnectionsByOrgId(orgId): ConnectionId[]
126
+ ```
127
+
128
+ #### `ActionRouter`
129
+
130
+ Routes incoming WebSocket messages to handlers based on the `action` field:
131
+
132
+ ```typescript
133
+ router.addRoute('chat:send', async (body, ctx) => {
134
+ return { statusCode: 200, body: 'ok' }
135
+ })
136
+ router.setDefaultHandler(async (body, ctx) => {
137
+ return { statusCode: 400, body: 'Unknown action' }
138
+ })
139
+ ```
140
+
141
+ **`ActionHandlerContext`**: `{ connectionId, requestContext, postToConnection, userContext }`
142
+
143
+ #### `SocketGatewayClient`
144
+
145
+ Dual-mode client for posting messages to WebSocket connections. Accepts either a `ConnectionRegistry` for local mode or a URL string for AWS API Gateway mode:
146
+
147
+ ```typescript
148
+ import { SocketGatewayClient } from '@mono-labs/dev'
149
+
150
+ // Local mode (uses ConnectionRegistry to find WebSocket instances)
151
+ const localClient = new SocketGatewayClient(connectionRegistry)
152
+
153
+ // API Gateway mode (uses @aws-sdk/client-apigatewaymanagementapi)
154
+ const awsClient = new SocketGatewayClient('https://abc123.execute-api.us-east-1.amazonaws.com/prod')
155
+
156
+ await client.postToConnection(connectionId, { message: 'hello' })
157
+
158
+ // Get a bound function for dependency injection
159
+ const postFn = client.asFunction()
160
+ ```
161
+
162
+ #### `SocketEmitter`
163
+
164
+ High-level emit API targeting users, orgs, connections, channels, or broadcast:
165
+
166
+ ```typescript
167
+ import type { EmitTarget } from '@mono-labs/dev'
168
+
169
+ await socketEmitter.emit({ userId: 'user-1' }, { event: 'update' })
170
+ await socketEmitter.emit({ orgId: 'org-1' }, { event: 'notify' })
171
+ await socketEmitter.emit({ connectionId: 'conn-1' }, data)
172
+ await socketEmitter.emit({ channel: 'room-1' }, data)
173
+ await socketEmitter.emit('broadcast', data)
174
+ ```
175
+
176
+ #### `ChannelStore`
177
+
178
+ Manages pub/sub channel subscriptions. Two implementations:
179
+
180
+ - **`InMemoryChannelStore`** -- Default. In-memory Maps, no dependencies.
181
+ - **`RedisChannelStore`** -- Redis-backed. Requires `ioredis` peer dependency.
182
+
183
+ ```typescript
184
+ interface ChannelStore {
185
+ subscribe(connectionId, channel): Promise<void>
186
+ unsubscribe(connectionId, channel): Promise<void>
187
+ getSubscribers(channel): Promise<ConnectionId[]>
188
+ removeAll(connectionId): Promise<void>
189
+ }
190
+ ```
191
+
192
+ ---
193
+
194
+ ### CacheRelay
195
+
196
+ Redis abstraction with namespaced operations. Requires `ioredis` peer dependency.
197
+
198
+ ```typescript
199
+ import { initCacheRelay, getCacheRelay } from '@mono-labs/dev'
200
+
201
+ // Initialize (defaults to localhost:6379)
202
+ initCacheRelay()
203
+
204
+ // Or with a connection string (bare hostnames auto-normalized to redis://)
205
+ initCacheRelay('my-redis-host:6379')
206
+
207
+ // Get the singleton instance
208
+ const cache = getCacheRelay()
209
+ ```
210
+
211
+ **Top-level convenience methods:**
212
+
213
+ ```typescript
214
+ await cache.set('key', { foo: 'bar' }, { ttlSeconds: 300 })
215
+ const value = await cache.get('key') // string | null
216
+ const parsed = await cache.gett<MyType>('key') // T | null
217
+ await cache.del('key1', 'key2')
218
+ ```
219
+
220
+ **Namespaced operations:**
221
+
222
+ | Namespace | Operations |
223
+ |-----------|-----------|
224
+ | `cache.strings` | `get`, `set`, `mget`, `mset`, `incr`, `incrby`, `decr`, `decrby`, `append`, `strlen` |
225
+ | `cache.hashes` | `get`, `set`, `getAll`, `del`, `exists`, `keys`, `vals`, `len`, `mset`, `mget`, `incrby` |
226
+ | `cache.lists` | `push`, `lpush`, `pop`, `lpop`, `range`, `len`, `trim`, `index`, `set`, `rem` |
227
+ | `cache.sets` | `add`, `rem`, `members`, `isMember`, `card`, `union`, `inter`, `diff` |
228
+ | `cache.sortedSets` | `add`, `rem`, `range`, `rangeWithScores`, `rangeByScore`, `revRange`, `score`, `rank`, `card`, `incrby`, `remRangeByRank`, `remRangeByScore` |
229
+ | `cache.keys` | `exists`, `expire`, `ttl`, `pttl`, `persist`, `rename`, `type`, `scan` |
230
+ | `cache.pubsub` | `publish`, `subscribe`, `unsubscribe` |
231
+ | `cache.transactions` | `multi`, `exec` |
232
+ | `cache.scripts` | `eval`, `evalsha` |
233
+ | `cache.geo` | `add`, `pos`, `dist`, `radius` |
234
+ | `cache.hyperloglog` | `add`, `count`, `merge` |
235
+ | `cache.bitmaps` | `setbit`, `getbit`, `count`, `op` |
236
+ | `cache.streams` | `add`, `read`, `len`, `range`, `trim` |
237
+
238
+ Access the raw `ioredis` client via `cache.raw`.
239
+
240
+ ---
241
+
242
+ ## Types
243
+
244
+ All exported types from `@mono-labs/dev`:
245
+
246
+ ```typescript
247
+ // LocalServer
248
+ type ApiGatewayHandler
249
+ type ALBHandler
250
+ interface LocalServerConfig
251
+
252
+ // WebSocket
253
+ type ConnectionId
254
+ type PostToConnectionFn
255
+ interface SocketAdapterConfig
256
+ interface RedisConfig
257
+ type ConnectHandlerFn
258
+ type DisconnectHandlerFn
259
+ type ActionHandler
260
+ interface ActionHandlerContext
261
+ interface ActionHandlerResult
262
+ interface LocalRequestContext
263
+ interface WebSocketUserContext
264
+ interface ChannelStore
265
+ type EmitTarget
266
+
267
+ // CacheRelay
268
+ interface CacheRelay
269
+ interface StringOps
270
+ interface HashOps
271
+ interface ListOps
272
+ interface SetOps
273
+ interface SortedSetOps
274
+ interface KeyOps
275
+ interface PubSubOps
276
+ interface TransactionOps
277
+ interface ScriptOps
278
+ interface GeoOps
279
+ interface HyperLogLogOps
280
+ interface BitmapOps
281
+ interface StreamOps
282
+ ```
283
+
284
+ ## Development
285
+
286
+ Build the dev package:
287
+
288
+ ```bash
289
+ yarn build:dev
290
+ ```
291
+
292
+ This package has no internal `@mono-labs` dependencies -- it is independent in the dependency graph.
293
+
294
+ See the [Contributing guide](../../CONTRIBUTING.md) for full development setup.
@@ -1 +1 @@
1
- {"version":3,"file":"cache-relay.d.ts","sourceRoot":"","sources":["../src/cache-relay.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache-relay.d.ts","sourceRoot":"","sources":["../src/cache-relay.ts"],"names":[],"mappings":"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"}
@@ -269,7 +269,9 @@ function buildCacheRelay(redis) {
269
269
  * Requires `ioredis` as a peer dependency — throws a clear error if missing.
270
270
  */
271
271
  function initCacheRelay(connectionString) {
272
- const connStr = connectionString ?? 'localhost:6379';
272
+ const raw = connectionString ?? 'localhost:6379';
273
+ // Normalize: bare hostname (no port) → hostname:6379
274
+ const connStr = raw.includes(':') ? raw : `${raw}:6379`;
273
275
  // Reuse existing instance when the connection string hasn't changed
274
276
  if (_cacheRelay && _currentConnectionString === connStr)
275
277
  return _cacheRelay;
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export type { ApiGatewayHandler, ALBHandler, LocalServerConfig } from './local-s
3
3
  export { attachSocketAdapter } from './websocket';
4
4
  export { ConnectionRegistry } from './websocket/connection-registry';
5
5
  export { ActionRouter } from './websocket/action-router';
6
- export { LocalGatewayClient } from './websocket/local-gateway-client';
6
+ export { SocketGatewayClient } from './websocket/socket-gateway-client';
7
7
  export { InMemoryChannelStore, RedisChannelStore } from './websocket/channel-store';
8
8
  export { SocketEmitter } from './websocket/socket-emitter';
9
9
  export type { ConnectionId, PostToConnectionFn, SocketAdapterConfig, RedisConfig, ConnectHandlerFn, DisconnectHandlerFn, ActionHandler, ActionHandlerContext, ActionHandlerResult, LocalRequestContext, WebSocketUserContext, } from './websocket/types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAG5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AACrE,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAG5D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7D,YAAY,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,OAAO,EACP,MAAM,EACN,YAAY,EACZ,MAAM,EACN,SAAS,EACT,cAAc,EACd,SAAS,EACT,MAAM,EACN,cAAc,EACd,SAAS,EACT,SAAS,GACT,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAG5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AACvE,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,YAAY,EACX,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,YAAY,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAG5D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7D,YAAY,EACX,UAAU,EACV,SAAS,EACT,OAAO,EACP,OAAO,EACP,MAAM,EACN,YAAY,EACZ,MAAM,EACN,SAAS,EACT,cAAc,EACd,SAAS,EACT,MAAM,EACN,cAAc,EACd,SAAS,EACT,SAAS,GACT,MAAM,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCacheRelay = exports.initCacheRelay = exports.SocketEmitter = exports.RedisChannelStore = exports.InMemoryChannelStore = exports.LocalGatewayClient = exports.ActionRouter = exports.ConnectionRegistry = exports.attachSocketAdapter = exports.LocalServer = void 0;
3
+ exports.getCacheRelay = exports.initCacheRelay = exports.SocketEmitter = exports.RedisChannelStore = exports.InMemoryChannelStore = exports.SocketGatewayClient = exports.ActionRouter = exports.ConnectionRegistry = exports.attachSocketAdapter = exports.LocalServer = void 0;
4
4
  // Core
5
5
  var local_server_1 = require("./local-server");
6
6
  Object.defineProperty(exports, "LocalServer", { enumerable: true, get: function () { return local_server_1.LocalServer; } });
@@ -11,8 +11,8 @@ var connection_registry_1 = require("./websocket/connection-registry");
11
11
  Object.defineProperty(exports, "ConnectionRegistry", { enumerable: true, get: function () { return connection_registry_1.ConnectionRegistry; } });
12
12
  var action_router_1 = require("./websocket/action-router");
13
13
  Object.defineProperty(exports, "ActionRouter", { enumerable: true, get: function () { return action_router_1.ActionRouter; } });
14
- var local_gateway_client_1 = require("./websocket/local-gateway-client");
15
- Object.defineProperty(exports, "LocalGatewayClient", { enumerable: true, get: function () { return local_gateway_client_1.LocalGatewayClient; } });
14
+ var socket_gateway_client_1 = require("./websocket/socket-gateway-client");
15
+ Object.defineProperty(exports, "SocketGatewayClient", { enumerable: true, get: function () { return socket_gateway_client_1.SocketGatewayClient; } });
16
16
  var channel_store_1 = require("./websocket/channel-store");
17
17
  Object.defineProperty(exports, "InMemoryChannelStore", { enumerable: true, get: function () { return channel_store_1.InMemoryChannelStore; } });
18
18
  Object.defineProperty(exports, "RedisChannelStore", { enumerable: true, get: function () { return channel_store_1.RedisChannelStore; } });
@@ -5,7 +5,7 @@ import { SocketEmitter } from './socket-emitter';
5
5
  import type { SocketAdapterConfig } from './types';
6
6
  export type { ConnectionId, PostToConnectionFn, SocketAdapterConfig, RedisConfig } from './types';
7
7
  export { ConnectionRegistry } from './connection-registry';
8
- export { LocalGatewayClient } from './local-gateway-client';
8
+ export { SocketGatewayClient } from './socket-gateway-client';
9
9
  export { ActionRouter } from './action-router';
10
10
  export { InMemoryChannelStore, RedisChannelStore } from './channel-store';
11
11
  export type { ChannelStore } from './channel-store';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAI1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,KAAK,EAAgB,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAEhE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,mBAAmB;;;;;;0BAgJ9D,SAAS;EAEhC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/websocket/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAEpD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAI1D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAEhD,OAAO,KAAK,EAAgB,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAEhE,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,mBAAmB;;;;;;0BAgJ9D,SAAS;EAEhC"}
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SocketEmitter = exports.RedisChannelStore = exports.InMemoryChannelStore = exports.ActionRouter = exports.LocalGatewayClient = exports.ConnectionRegistry = void 0;
3
+ exports.SocketEmitter = exports.RedisChannelStore = exports.InMemoryChannelStore = exports.ActionRouter = exports.SocketGatewayClient = exports.ConnectionRegistry = void 0;
4
4
  exports.attachSocketAdapter = attachSocketAdapter;
5
5
  const action_router_1 = require("./action-router");
6
6
  const connection_registry_1 = require("./connection-registry");
7
7
  const event_synthesizer_1 = require("./event-synthesizer");
8
- const local_gateway_client_1 = require("./local-gateway-client");
8
+ const socket_gateway_client_1 = require("./socket-gateway-client");
9
9
  const channel_store_1 = require("./channel-store");
10
10
  const socket_emitter_1 = require("./socket-emitter");
11
11
  const cache_relay_1 = require("../cache-relay");
12
12
  var connection_registry_2 = require("./connection-registry");
13
13
  Object.defineProperty(exports, "ConnectionRegistry", { enumerable: true, get: function () { return connection_registry_2.ConnectionRegistry; } });
14
- var local_gateway_client_2 = require("./local-gateway-client");
15
- Object.defineProperty(exports, "LocalGatewayClient", { enumerable: true, get: function () { return local_gateway_client_2.LocalGatewayClient; } });
14
+ var socket_gateway_client_2 = require("./socket-gateway-client");
15
+ Object.defineProperty(exports, "SocketGatewayClient", { enumerable: true, get: function () { return socket_gateway_client_2.SocketGatewayClient; } });
16
16
  var action_router_2 = require("./action-router");
17
17
  Object.defineProperty(exports, "ActionRouter", { enumerable: true, get: function () { return action_router_2.ActionRouter; } });
18
18
  var channel_store_2 = require("./channel-store");
@@ -30,7 +30,7 @@ function attachSocketAdapter(wss, config) {
30
30
  const domainName = config?.domainName ?? 'localhost';
31
31
  const stage = config?.stage ?? 'local';
32
32
  const connectionRegistry = new connection_registry_1.ConnectionRegistry();
33
- const gatewayClient = new local_gateway_client_1.LocalGatewayClient(connectionRegistry);
33
+ const gatewayClient = new socket_gateway_client_1.SocketGatewayClient(connectionRegistry);
34
34
  const postToConnection = gatewayClient.asFunction();
35
35
  const actionRouter = new action_router_1.ActionRouter();
36
36
  // Create channel store
@@ -0,0 +1,20 @@
1
+ import type { ConnectionId, PostToConnectionFn } from './types';
2
+ import type { ConnectionRegistry } from './connection-registry';
3
+ /**
4
+ * Unified gateway client that auto-detects local vs production mode.
5
+ *
6
+ * - Pass a `ConnectionRegistry` → local mode (sends via in-memory WebSocket)
7
+ * - Pass a URL string → API Gateway mode (sends via AWS SDK PostToConnectionCommand)
8
+ */
9
+ export declare class SocketGatewayClient {
10
+ private mode;
11
+ private registry?;
12
+ private endpoint?;
13
+ constructor(backend: ConnectionRegistry | string);
14
+ postToConnection(connectionId: ConnectionId, data: unknown): Promise<void>;
15
+ private postLocal;
16
+ private postApiGateway;
17
+ /** Returns a bound PostToConnectionFn for dependency injection */
18
+ asFunction(): PostToConnectionFn;
19
+ }
20
+ //# sourceMappingURL=socket-gateway-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket-gateway-client.d.ts","sourceRoot":"","sources":["../../src/websocket/socket-gateway-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAE/D;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,QAAQ,CAAC,CAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAQ;gBAEb,OAAO,EAAE,kBAAkB,GAAG,MAAM;IAU1C,gBAAgB,CAAC,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAOlE,SAAS;YAeT,cAAc;IAgC5B,kEAAkE;IAClE,UAAU,IAAI,kBAAkB;CAGhC"}
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SocketGatewayClient = void 0;
4
+ /**
5
+ * Unified gateway client that auto-detects local vs production mode.
6
+ *
7
+ * - Pass a `ConnectionRegistry` → local mode (sends via in-memory WebSocket)
8
+ * - Pass a URL string → API Gateway mode (sends via AWS SDK PostToConnectionCommand)
9
+ */
10
+ class SocketGatewayClient {
11
+ mode;
12
+ registry;
13
+ endpoint;
14
+ constructor(backend) {
15
+ if (typeof backend === 'string') {
16
+ this.mode = 'apigateway';
17
+ this.endpoint = backend;
18
+ }
19
+ else {
20
+ this.mode = 'local';
21
+ this.registry = backend;
22
+ }
23
+ }
24
+ async postToConnection(connectionId, data) {
25
+ if (this.mode === 'local') {
26
+ return this.postLocal(connectionId, data);
27
+ }
28
+ return this.postApiGateway(connectionId, data);
29
+ }
30
+ async postLocal(connectionId, data) {
31
+ const { WebSocket } = require('ws');
32
+ const ws = this.registry.get(connectionId);
33
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
34
+ const error = new Error(`GoneException: Connection ${connectionId} is no longer available`);
35
+ error.statusCode = 410;
36
+ error.name = 'GoneException';
37
+ throw error;
38
+ }
39
+ const payload = typeof data === 'string' ? data : JSON.stringify(data);
40
+ ws.send(payload);
41
+ }
42
+ async postApiGateway(connectionId, data) {
43
+ let ApiGatewayManagementApiClient, PostToConnectionCommand;
44
+ try {
45
+ const mod = require('@aws-sdk/client-apigatewaymanagementapi');
46
+ ApiGatewayManagementApiClient = mod.ApiGatewayManagementApiClient;
47
+ PostToConnectionCommand = mod.PostToConnectionCommand;
48
+ }
49
+ catch {
50
+ throw new Error('API Gateway mode requires "@aws-sdk/client-apigatewaymanagementapi". '
51
+ + 'Install it with: npm install @aws-sdk/client-apigatewaymanagementapi');
52
+ }
53
+ const client = new ApiGatewayManagementApiClient({ endpoint: this.endpoint });
54
+ const payload = typeof data === 'string' ? data : JSON.stringify(data);
55
+ try {
56
+ await client.send(new PostToConnectionCommand({
57
+ ConnectionId: connectionId,
58
+ Data: new TextEncoder().encode(payload),
59
+ }));
60
+ }
61
+ catch (err) {
62
+ if (err.name === 'GoneException' || err.$metadata?.httpStatusCode === 410) {
63
+ const error = new Error(`GoneException: Connection ${connectionId} is no longer available`);
64
+ error.statusCode = 410;
65
+ error.name = 'GoneException';
66
+ throw error;
67
+ }
68
+ throw err;
69
+ }
70
+ }
71
+ /** Returns a bound PostToConnectionFn for dependency injection */
72
+ asFunction() {
73
+ return this.postToConnection.bind(this);
74
+ }
75
+ }
76
+ exports.SocketGatewayClient = SocketGatewayClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mono-labs/dev",
3
- "version": "0.1.255",
3
+ "version": "0.1.257",
4
4
  "type": "commonjs",
5
5
  "description": "Local development server and WebSocket adapter for mono-labs",
6
6
  "main": "dist/index.js",
@@ -27,11 +27,15 @@
27
27
  "ws": "^8.18.0"
28
28
  },
29
29
  "peerDependencies": {
30
- "ioredis": ">=5.0.0"
30
+ "ioredis": ">=5.0.0",
31
+ "@aws-sdk/client-apigatewaymanagementapi": ">=3.0.0"
31
32
  },
32
33
  "peerDependenciesMeta": {
33
34
  "ioredis": {
34
35
  "optional": true
36
+ },
37
+ "@aws-sdk/client-apigatewaymanagementapi": {
38
+ "optional": true
35
39
  }
36
40
  },
37
41
  "devDependencies": {
@@ -452,7 +452,10 @@ function buildCacheRelay(redis: RedisClient): CacheRelay {
452
452
  * Requires `ioredis` as a peer dependency — throws a clear error if missing.
453
453
  */
454
454
  export function initCacheRelay(connectionString?: string): CacheRelay {
455
- const connStr = connectionString ?? 'localhost:6379'
455
+ const raw = connectionString ?? 'localhost:6379'
456
+
457
+ // Normalize: bare hostname (no port) → hostname:6379
458
+ const connStr = raw.includes(':') ? raw : `${raw}:6379`
456
459
 
457
460
  // Reuse existing instance when the connection string hasn't changed
458
461
  if (_cacheRelay && _currentConnectionString === connStr) return _cacheRelay
package/src/index.ts CHANGED
@@ -6,7 +6,7 @@ export type { ApiGatewayHandler, ALBHandler, LocalServerConfig } from './local-s
6
6
  export { attachSocketAdapter } from './websocket'
7
7
  export { ConnectionRegistry } from './websocket/connection-registry'
8
8
  export { ActionRouter } from './websocket/action-router'
9
- export { LocalGatewayClient } from './websocket/local-gateway-client'
9
+ export { SocketGatewayClient } from './websocket/socket-gateway-client'
10
10
  export { InMemoryChannelStore, RedisChannelStore } from './websocket/channel-store'
11
11
  export { SocketEmitter } from './websocket/socket-emitter'
12
12
  export type {
@@ -3,7 +3,7 @@ import type { WebSocket, WebSocketServer } from 'ws'
3
3
  import { ActionRouter } from './action-router'
4
4
  import { ConnectionRegistry } from './connection-registry'
5
5
  import { buildRequestContext } from './event-synthesizer'
6
- import { LocalGatewayClient } from './local-gateway-client'
6
+ import { SocketGatewayClient } from './socket-gateway-client'
7
7
  import { InMemoryChannelStore, RedisChannelStore } from './channel-store'
8
8
  import { SocketEmitter } from './socket-emitter'
9
9
  import { initCacheRelay } from '../cache-relay'
@@ -11,7 +11,7 @@ import type { ConnectionId, SocketAdapterConfig } from './types'
11
11
 
12
12
  export type { ConnectionId, PostToConnectionFn, SocketAdapterConfig, RedisConfig } from './types'
13
13
  export { ConnectionRegistry } from './connection-registry'
14
- export { LocalGatewayClient } from './local-gateway-client'
14
+ export { SocketGatewayClient } from './socket-gateway-client'
15
15
  export { ActionRouter } from './action-router'
16
16
  export { InMemoryChannelStore, RedisChannelStore } from './channel-store'
17
17
  export type { ChannelStore } from './channel-store'
@@ -29,7 +29,7 @@ export function attachSocketAdapter(wss: WebSocketServer, config?: SocketAdapter
29
29
  const stage = config?.stage ?? 'local'
30
30
 
31
31
  const connectionRegistry = new ConnectionRegistry()
32
- const gatewayClient = new LocalGatewayClient(connectionRegistry)
32
+ const gatewayClient = new SocketGatewayClient(connectionRegistry)
33
33
  const postToConnection = gatewayClient.asFunction()
34
34
  const actionRouter = new ActionRouter()
35
35
 
@@ -0,0 +1,83 @@
1
+ import type { ConnectionId, PostToConnectionFn } from './types'
2
+ import type { ConnectionRegistry } from './connection-registry'
3
+
4
+ /**
5
+ * Unified gateway client that auto-detects local vs production mode.
6
+ *
7
+ * - Pass a `ConnectionRegistry` → local mode (sends via in-memory WebSocket)
8
+ * - Pass a URL string → API Gateway mode (sends via AWS SDK PostToConnectionCommand)
9
+ */
10
+ export class SocketGatewayClient {
11
+ private mode: 'local' | 'apigateway'
12
+ private registry?: ConnectionRegistry
13
+ private endpoint?: string
14
+
15
+ constructor(backend: ConnectionRegistry | string) {
16
+ if (typeof backend === 'string') {
17
+ this.mode = 'apigateway'
18
+ this.endpoint = backend
19
+ } else {
20
+ this.mode = 'local'
21
+ this.registry = backend
22
+ }
23
+ }
24
+
25
+ async postToConnection(connectionId: ConnectionId, data: unknown): Promise<void> {
26
+ if (this.mode === 'local') {
27
+ return this.postLocal(connectionId, data)
28
+ }
29
+ return this.postApiGateway(connectionId, data)
30
+ }
31
+
32
+ private async postLocal(connectionId: ConnectionId, data: unknown): Promise<void> {
33
+ const { WebSocket } = require('ws') as typeof import('ws')
34
+ const ws = this.registry!.get(connectionId)
35
+
36
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
37
+ const error = new Error(`GoneException: Connection ${connectionId} is no longer available`)
38
+ ;(error as any).statusCode = 410
39
+ ;(error as any).name = 'GoneException'
40
+ throw error
41
+ }
42
+
43
+ const payload = typeof data === 'string' ? data : JSON.stringify(data)
44
+ ws.send(payload)
45
+ }
46
+
47
+ private async postApiGateway(connectionId: ConnectionId, data: unknown): Promise<void> {
48
+ let ApiGatewayManagementApiClient: any, PostToConnectionCommand: any
49
+ try {
50
+ const mod = require('@aws-sdk/client-apigatewaymanagementapi')
51
+ ApiGatewayManagementApiClient = mod.ApiGatewayManagementApiClient
52
+ PostToConnectionCommand = mod.PostToConnectionCommand
53
+ } catch {
54
+ throw new Error(
55
+ 'API Gateway mode requires "@aws-sdk/client-apigatewaymanagementapi". '
56
+ + 'Install it with: npm install @aws-sdk/client-apigatewaymanagementapi'
57
+ )
58
+ }
59
+
60
+ const client = new ApiGatewayManagementApiClient({ endpoint: this.endpoint })
61
+ const payload = typeof data === 'string' ? data : JSON.stringify(data)
62
+
63
+ try {
64
+ await client.send(new PostToConnectionCommand({
65
+ ConnectionId: connectionId,
66
+ Data: new TextEncoder().encode(payload),
67
+ }))
68
+ } catch (err: any) {
69
+ if (err.name === 'GoneException' || err.$metadata?.httpStatusCode === 410) {
70
+ const error = new Error(`GoneException: Connection ${connectionId} is no longer available`)
71
+ ;(error as any).statusCode = 410
72
+ ;(error as any).name = 'GoneException'
73
+ throw error
74
+ }
75
+ throw err
76
+ }
77
+ }
78
+
79
+ /** Returns a bound PostToConnectionFn for dependency injection */
80
+ asFunction(): PostToConnectionFn {
81
+ return this.postToConnection.bind(this)
82
+ }
83
+ }
@@ -1,31 +0,0 @@
1
- import { WebSocket } from 'ws'
2
- import type { ConnectionRegistry } from './connection-registry'
3
- import type { ConnectionId, PostToConnectionFn } from './types'
4
-
5
- /**
6
- * Local replacement for @aws-sdk/client-apigatewaymanagementapi.
7
- * Looks up the WebSocket in ConnectionRegistry and sends data directly.
8
- */
9
- export class LocalGatewayClient {
10
- constructor(private registry: ConnectionRegistry) {}
11
-
12
- /** Send data to a specific connection. Throws GoneException (410) if not found. */
13
- async postToConnection(connectionId: ConnectionId, data: unknown): Promise<void> {
14
- const ws = this.registry.get(connectionId)
15
-
16
- if (!ws || ws.readyState !== WebSocket.OPEN) {
17
- const error = new Error(`GoneException: Connection ${connectionId} is no longer available`)
18
- ;(error as any).statusCode = 410
19
- ;(error as any).name = 'GoneException'
20
- throw error
21
- }
22
-
23
- const payload = typeof data === 'string' ? data : JSON.stringify(data)
24
- ws.send(payload)
25
- }
26
-
27
- /** Returns a bound PostToConnectionFn for dependency injection */
28
- asFunction(): PostToConnectionFn {
29
- return this.postToConnection.bind(this)
30
- }
31
- }