Skip to content

Commit a68d125

Browse files
committed
Add support for passing custom callbacks to ActionCableLink
1 parent fcbfa86 commit a68d125

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

javascript_client/src/subscriptions/ActionCableLink.ts

+15-2
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,28 @@ import { print } from "graphql"
44

55
type RequestResult = FetchResult<{ [key: string]: any; }, Record<string, any>, Record<string, any>>
66
type ConnectionParams = object | ((operation: Operation) => object)
7+
type SubscriptionCallbacks = {
8+
connected?: (args?: { reconnected: boolean }) => void;
9+
disconnected?: () => void;
10+
received?: (payload: any) => void;
11+
};
712

813
class ActionCableLink extends ApolloLink {
914
cable: Consumer
1015
channelName: string
1116
actionName: string
1217
connectionParams: ConnectionParams
18+
callbacks: SubscriptionCallbacks
1319

1420
constructor(options: {
15-
cable: Consumer, channelName?: string, actionName?: string, connectionParams?: ConnectionParams
21+
cable: Consumer, channelName?: string, actionName?: string, connectionParams?: ConnectionParams, callbacks?: SubscriptionCallbacks
1622
}) {
1723
super()
1824
this.cable = options.cable
1925
this.channelName = options.channelName || "GraphqlChannel"
2026
this.actionName = options.actionName || "execute"
2127
this.connectionParams = options.connectionParams || {}
28+
this.callbacks = options.callbacks || {}
2229
}
2330

2431
// Interestingly, this link does _not_ call through to `next` because
@@ -29,11 +36,12 @@ class ActionCableLink extends ApolloLink {
2936
var actionName = this.actionName
3037
var connectionParams = (typeof this.connectionParams === "function") ?
3138
this.connectionParams(operation) : this.connectionParams
39+
var callbacks = this.callbacks
3240
var channel = this.cable.subscriptions.create(Object.assign({},{
3341
channel: this.channelName,
3442
channelId: channelId
3543
}, connectionParams), {
36-
connected: function() {
44+
connected: function(args?: any) {
3745
this.perform(
3846
actionName,
3947
{
@@ -44,6 +52,7 @@ class ActionCableLink extends ApolloLink {
4452
operationName: operation.operationName
4553
}
4654
)
55+
callbacks.connected?.(args)
4756
},
4857
received: function(payload) {
4958
if (payload?.result?.data || payload?.result?.errors) {
@@ -53,6 +62,10 @@ class ActionCableLink extends ApolloLink {
5362
if (!payload.more) {
5463
observer.complete()
5564
}
65+
callbacks.received?.(payload)
66+
},
67+
disconnected: function() {
68+
callbacks.disconnected?.()
5669
}
5770
})
5871
// Make the ActionCable subscription behave like an Apollo subscription

javascript_client/src/subscriptions/__tests__/ActionCableLinkTest.ts

+22
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,26 @@ describe("ActionCableLink", () => {
171171

172172
expect(subscription.params["test"]).toEqual(1)
173173
})
174+
175+
it('allows passing custom callbacks', () => {
176+
var connected = jest.fn()
177+
var received = jest.fn()
178+
var disconnected = jest.fn()
179+
180+
var observable = new ActionCableLink(
181+
Object.assign(options, { callbacks: { connected, received, disconnected } })
182+
).request(operation, null as any)
183+
184+
// unpack the underlying subscription
185+
var subscription: any = (observable.subscribe(() => null) as any)._cleanup
186+
187+
subscription.received({ result: { data: "data 1" }, more: true })
188+
subscription.received({ result: { data: "data 2" }, more: false })
189+
subscription.disconnected()
190+
191+
expect(connected).toHaveBeenCalledTimes(1)
192+
expect(received).toHaveBeenCalledWith({ result: { data: "data 1" }, more: true })
193+
expect(received).toHaveBeenCalledWith({ result: { data: "data 2" }, more: false })
194+
expect(disconnected).toHaveBeenCalledTimes(1)
195+
})
174196
})

0 commit comments

Comments
 (0)