@mstuercke/api-utils 6.0.3 → 6.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mstuercke/api-utils",
3
- "version": "6.0.3",
3
+ "version": "6.1.1",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "files": [
@@ -55,7 +55,7 @@
55
55
  "@types/aws-lambda": "^8.10.138"
56
56
  },
57
57
  "devDependencies": {
58
- "@mstuercke/bun-utils": "6.1.0",
58
+ "@mstuercke/bun-utils": "6.2.20",
59
59
  "@trpc/server": "^11.0.0-rc.390",
60
60
  "@types/aws-lambda": "^8.10.138",
61
61
  "@types/bun": "^1.1.3",
@@ -19,110 +19,116 @@ export const awsLambdaTrpcSubscriptionRequestHandler = <Router extends AnyTRPCRo
19
19
 
20
20
  if (!event.body || event.body === '[]') return {statusCode: 200, body: '{}'}
21
21
 
22
- const request = JSON.parse(event.body) as TrpcSubscriptionRequest
23
-
24
- const sendMessage = async (response: TrpcSubscriptionResponse) => {
25
- await getApiGatewayManagementApiClient(connection.endpoint).send(
26
- new PostToConnectionCommand({
27
- ConnectionId: connection.connectionId,
28
- Data: JSON.stringify(response),
29
- }),
30
- )
31
- }
32
- const isConnected = async (): Promise<boolean> => {
33
- return getApiGatewayManagementApiClient(connection.endpoint)
34
- .send(new GetConnectionCommand({ConnectionId: connection.connectionId}))
35
- .then(() => true)
36
- .catch(() => false)
37
- }
38
- const stopConnection = async (): Promise<void> => {
39
- await sendMessage({
40
- id: request.id,
41
- result: {type: 'stopped'},
42
- })
43
- }
44
-
45
- try {
46
- const messageQueue: TrpcSubscriptionResponse[] = []
47
-
48
- if (request.method === 'subscription.stop') {
49
- await stopConnection()
50
- }
51
-
52
- if (request.method === 'subscription') {
53
- messageQueue.push({
54
- id: request.id,
55
- result: {type: 'started'},
56
- })
57
-
58
- const procedure = await callTRPCProcedure({
59
- procedures: router._def.procedures,
60
- path: request.params.path,
61
- type: 'subscription',
62
- ctx: (await createContext?.(event)) || {},
63
- getRawInput: async () => request.params.input,
64
- })
65
-
66
- if (!isObservable(procedure)) {
67
- console.error(`observable`, procedure)
68
- throw `Procedure is not an observable!`
22
+ const requestOrRequests = JSON.parse(event.body) as TrpcSubscriptionRequest | TrpcSubscriptionRequest[]
23
+
24
+ const requests = Array.isArray(requestOrRequests) ? requestOrRequests : [requestOrRequests]
25
+
26
+ await Promise.all(
27
+ requests.map(async (request) => {
28
+ const sendMessage = async (response: TrpcSubscriptionResponse) => {
29
+ await getApiGatewayManagementApiClient(connection.endpoint).send(
30
+ new PostToConnectionCommand({
31
+ ConnectionId: connection.connectionId,
32
+ Data: JSON.stringify(response),
33
+ }),
34
+ )
69
35
  }
36
+ const isConnected = async (): Promise<boolean> => {
37
+ return getApiGatewayManagementApiClient(connection.endpoint)
38
+ .send(new GetConnectionCommand({ConnectionId: connection.connectionId}))
39
+ .then(() => true)
40
+ .catch(() => false)
41
+ }
42
+ const stopConnection = async (): Promise<void> => {
43
+ await sendMessage({
44
+ id: request.id,
45
+ result: {type: 'stopped'},
46
+ })
47
+ }
48
+
49
+ try {
50
+ const messageQueue: TrpcSubscriptionResponse[] = []
70
51
 
71
- procedure.subscribe({
72
- next: (data: unknown) => {
52
+ if (request.method === 'subscription.stop') {
53
+ await stopConnection()
54
+ }
55
+
56
+ if (request.method === 'subscription') {
73
57
  messageQueue.push({
74
58
  id: request.id,
75
- result: {
76
- type: 'data',
77
- data: data,
78
- },
59
+ result: {type: 'started'},
79
60
  })
80
- },
81
- error: (err) => {
82
- console.error(err)
83
- messageQueue.push({
84
- id: request.id,
85
- result: {type: 'stopped'},
61
+
62
+ const procedure = await callTRPCProcedure({
63
+ procedures: router._def.procedures,
64
+ path: request.params.path,
65
+ type: 'subscription',
66
+ ctx: (await createContext?.(event)) || {},
67
+ getRawInput: async () => request.params.input,
86
68
  })
87
- },
88
- complete: () => {
89
- messageQueue.push({
90
- id: request.id,
91
- result: {type: 'stopped'},
69
+
70
+ if (!isObservable(procedure)) {
71
+ console.error(`observable`, procedure)
72
+ throw `Procedure is not an observable!`
73
+ }
74
+
75
+ procedure.subscribe({
76
+ next: (data: unknown) => {
77
+ messageQueue.push({
78
+ id: request.id,
79
+ result: {
80
+ type: 'data',
81
+ data: data,
82
+ },
83
+ })
84
+ },
85
+ error: (err) => {
86
+ console.error(err)
87
+ messageQueue.push({
88
+ id: request.id,
89
+ result: {type: 'stopped'},
90
+ })
91
+ },
92
+ complete: () => {
93
+ messageQueue.push({
94
+ id: request.id,
95
+ result: {type: 'stopped'},
96
+ })
97
+ },
92
98
  })
93
- },
94
- })
95
-
96
- const pingIntervalMs = 5_000
97
- let lastPing = Date.now()
98
- let stopped = false
99
- while (!stopped) {
100
- if (messageQueue.length === 0) await new Promise((resolve) => setTimeout(resolve, 10))
101
- const message = messageQueue.shift()
102
- if (!message) continue
103
-
104
- await sendMessage(message)
105
-
106
- stopped = message.result.type === 'stopped'
107
-
108
- if (Date.now() > lastPing + pingIntervalMs) {
109
- const connected = await isConnected()
110
- if (!connected) {
111
- console.info('Ping: Connection closed by client')
112
- stopped = true
99
+
100
+ const pingIntervalMs = 5_000
101
+ let lastPing = Date.now()
102
+ let stopped = false
103
+ while (!stopped) {
104
+ if (messageQueue.length === 0) await new Promise((resolve) => setTimeout(resolve, 10))
105
+ const message = messageQueue.shift()
106
+ if (!message) continue
107
+
108
+ await sendMessage(message)
109
+
110
+ stopped = message.result.type === 'stopped'
111
+
112
+ if (Date.now() > lastPing + pingIntervalMs) {
113
+ const connected = await isConnected()
114
+ if (!connected) {
115
+ console.info('Ping: Connection closed by client')
116
+ stopped = true
117
+ }
118
+ lastPing = Date.now()
119
+ }
113
120
  }
114
- lastPing = Date.now()
121
+ }
122
+ } catch (err) {
123
+ if (err instanceof GoneException) {
124
+ console.info('Error: Connection closed by client', err.message)
125
+ } else {
126
+ console.error(err)
127
+ await stopConnection()
115
128
  }
116
129
  }
117
- }
118
- } catch (err) {
119
- if (err instanceof GoneException) {
120
- console.info('Error: Connection closed by client', err.message)
121
- } else {
122
- console.error(err)
123
- await stopConnection()
124
- }
125
- }
130
+ }),
131
+ )
126
132
 
127
133
  return {
128
134
  statusCode: 200,