Skip to content

Commit b2407c6

Browse files
Use CustomEvent for PubSub and TypedEventTarget impl (#1761)
* Use CustomEvent for PubSub and TypedEventTarget impl * :sweaty_face: * chore(dependencies): updated changesets for modified dependencies Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 1857491 commit b2407c6

File tree

11 files changed

+99
-58
lines changed

11 files changed

+99
-58
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@graphql-yoga/redis-event-target": patch
3+
---
4+
5+
dependencies updates:
6+
7+
- Added dependency [`@whatwg-node/[email protected]` ↗︎](https://www.npmjs.com/package/@whatwg-node/events/v/0.0.1) (to `dependencies`)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@graphql-yoga/subscription": patch
3+
---
4+
5+
dependencies updates:
6+
7+
- Added dependency [`@whatwg-node/[email protected]` ↗︎](https://www.npmjs.com/package/@whatwg-node/events/v/0.0.1) (to `dependencies`)

.changeset/sour-apricots-move.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@graphql-yoga/redis-event-target': major
3+
'@graphql-yoga/typed-event-target': major
4+
'@graphql-yoga/subscription': major
5+
---
6+
7+
Breaking changes;
8+
9+
- Drop `TypedEvent` in favor of [`CustomEvent`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent)
10+
- Use `@whatwg-node/events` as a ponyfill instead of `@whatwg-node/fetch`

packages/event-target/redis-event-target/__tests__/redis-event-target.spec.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import type { TypedEvent } from '@graphql-yoga/typed-event-target'
21
import Redis from 'ioredis-mock'
32
import { createRedisEventTarget } from '../src'
4-
import { Event, EventTarget } from '@whatwg-node/fetch'
3+
import { CustomEvent } from '@whatwg-node/events'
54

65
describe('createRedisEventTarget', () => {
76
it('can listen to a simple publish', (done) => {
@@ -10,16 +9,19 @@ describe('createRedisEventTarget', () => {
109
subscribeClient: new Redis({}),
1110
})
1211

13-
eventTarget.addEventListener('a', (event: TypedEvent) => {
12+
eventTarget.addEventListener('a', (event: CustomEvent) => {
1413
expect(event.type).toEqual('a')
15-
expect(event.data).toEqual({
14+
expect(event.detail).toEqual({
1615
hi: 1,
1716
})
1817
done()
1918
})
2019

21-
const event = new Event('a') as TypedEvent
22-
event.data = { hi: 1 }
20+
const event = new CustomEvent('a', {
21+
detail: {
22+
hi: 1,
23+
},
24+
})
2325
eventTarget.dispatchEvent(event)
2426
})
2527

@@ -29,19 +31,22 @@ describe('createRedisEventTarget', () => {
2931
subscribeClient: new Redis({}),
3032
})
3133

32-
eventTarget.addEventListener('a', (_event: TypedEvent) => {
34+
eventTarget.addEventListener('a', (_event: CustomEvent) => {
3335
done(new Error('This should not be invoked'))
3436
})
35-
eventTarget.addEventListener('b', (event: TypedEvent) => {
37+
eventTarget.addEventListener('b', (event: CustomEvent) => {
3638
expect(event.type).toEqual('b')
37-
expect(event.data).toEqual({
39+
expect(event.detail).toEqual({
3840
hi: 1,
3941
})
4042
done()
4143
})
4244

43-
const event = new Event('b') as TypedEvent
44-
event.data = { hi: 1 }
45+
const event = new CustomEvent('b', {
46+
detail: {
47+
hi: 1,
48+
},
49+
})
4550
eventTarget.dispatchEvent(event)
4651
})
4752
it('distributes the event to all event listeners', (done) => {
@@ -51,15 +56,18 @@ describe('createRedisEventTarget', () => {
5156
})
5257

5358
let counter = 0
54-
eventTarget.addEventListener('b', (_event: TypedEvent) => {
59+
eventTarget.addEventListener('b', (_event: CustomEvent) => {
5560
counter++
5661
})
57-
eventTarget.addEventListener('b', (_event: TypedEvent) => {
62+
eventTarget.addEventListener('b', (_event: CustomEvent) => {
5863
counter++
5964
})
6065

61-
const event = new Event('b') as TypedEvent
62-
event.data = { hi: 1 }
66+
const event = new CustomEvent('b', {
67+
detail: {
68+
hi: 1,
69+
},
70+
})
6371
eventTarget.dispatchEvent(event)
6472

6573
setImmediate(() => {

packages/event-target/redis-event-target/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
"author": "Laurin Quast <[email protected]>",
2020
"license": "MIT",
2121
"dependencies": {
22+
"@whatwg-node/events": "0.0.1",
2223
"@graphql-yoga/typed-event-target": "^0.1.1"
2324
},
2425
"peerDependencies": {
2526
"ioredis": "^5.0.6"
2627
},
2728
"devDependencies": {
2829
"@types/ioredis-mock": "5.6.0",
29-
"event-target-polyfill": "0.0.3",
3030
"ioredis": "5.2.3",
3131
"ioredis-mock": "8.2.2"
3232
},

packages/event-target/redis-event-target/src/index.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import type { TypedEventTarget } from '@graphql-yoga/typed-event-target'
2-
import { Event } from '@whatwg-node/fetch'
2+
import { CustomEvent } from '@whatwg-node/events'
33
import type { Redis, Cluster } from 'ioredis'
44

55
export type CreateRedisEventTargetArgs = {
66
publishClient: Redis | Cluster
77
subscribeClient: Redis | Cluster
88
}
99

10-
export function createRedisEventTarget<TEvent extends Event>(
10+
export function createRedisEventTarget<TEvent extends CustomEvent>(
1111
args: CreateRedisEventTargetArgs,
1212
): TypedEventTarget<TEvent> {
1313
const { publishClient, subscribeClient } = args
@@ -19,10 +19,10 @@ export function createRedisEventTarget<TEvent extends Event>(
1919
if (callbacks === undefined) {
2020
return
2121
}
22-
const event = new Event(channel) as TEvent & {
23-
data: unknown
24-
}
25-
event.data = message === '' ? undefined : JSON.parse(message)
22+
23+
const event = new CustomEvent(channel, {
24+
detail: message === '' ? undefined : JSON.parse(message),
25+
}) as TEvent
2626
for (const callback of callbacks) {
2727
callback(event)
2828
}
@@ -56,27 +56,29 @@ export function createRedisEventTarget<TEvent extends Event>(
5656

5757
return {
5858
addEventListener(topic, callbackOrOptions) {
59-
const callback =
60-
'handleEvent' in callbackOrOptions
61-
? callbackOrOptions.handleEvent
62-
: callbackOrOptions
63-
addCallback(topic, callback)
59+
if (callbackOrOptions != null) {
60+
const callback =
61+
'handleEvent' in callbackOrOptions
62+
? callbackOrOptions.handleEvent
63+
: callbackOrOptions
64+
addCallback(topic, callback)
65+
}
6466
},
6567
dispatchEvent(event: TEvent) {
6668
publishClient.publish(
6769
event.type,
68-
(event as any).data === undefined
69-
? ''
70-
: JSON.stringify((event as any).data),
70+
event.detail === undefined ? '' : JSON.stringify(event.detail),
7171
)
7272
return true
7373
},
7474
removeEventListener(topic, callbackOrOptions) {
75-
const callback =
76-
'handleEvent' in callbackOrOptions
77-
? callbackOrOptions.handleEvent
78-
: callbackOrOptions
79-
removeCallback(topic, callback)
75+
if (callbackOrOptions != null) {
76+
const callback =
77+
'handleEvent' in callbackOrOptions
78+
? callbackOrOptions.handleEvent
79+
: callbackOrOptions
80+
removeCallback(topic, callback)
81+
}
8082
},
8183
}
8284
}
Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,26 @@
1-
export type TypedEvent = Event & {
2-
data?: unknown
3-
}
4-
5-
export interface TypedEventListener<TEvent extends TypedEvent>
6-
extends EventListener {
1+
export interface TypedEventListener<TEvent extends CustomEvent> {
72
(evt: TEvent): void
83
}
94

10-
export interface TypedEventListenerObject<TEvent extends TypedEvent>
11-
extends EventListener {
5+
export interface TypedEventListenerObject<TEvent extends CustomEvent> {
126
handleEvent(object: TEvent): void
137
}
148

15-
export type TypedEventListenerOrEventListenerObject<TEvent extends TypedEvent> =
16-
TypedEventListener<TEvent> | TypedEventListenerObject<TEvent>
9+
export type TypedEventListenerOrEventListenerObject<
10+
TEvent extends CustomEvent,
11+
> = TypedEventListener<TEvent> | TypedEventListenerObject<TEvent>
1712

18-
export interface TypedEventTarget<TEvent extends TypedEvent>
13+
export interface TypedEventTarget<TEvent extends CustomEvent>
1914
extends EventTarget {
2015
addEventListener(
2116
type: string,
22-
callback: TypedEventListenerOrEventListenerObject<TEvent>,
17+
callback: TypedEventListenerOrEventListenerObject<TEvent> | null,
2318
options?: AddEventListenerOptions | boolean,
2419
): void
2520
dispatchEvent(event: TEvent): boolean
2621
removeEventListener(
2722
type: string,
28-
callback: TypedEventListenerOrEventListenerObject<TEvent>,
23+
callback: TypedEventListenerOrEventListenerObject<TEvent> | null,
2924
options?: EventListenerOptions | boolean,
3025
): void
3126
}

packages/subscription/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
},
6262
"dependencies": {
6363
"@graphql-yoga/typed-event-target": "^0.1.1",
64+
"@whatwg-node/events": "0.0.1",
6465
"@repeaterjs/repeater": "^3.0.4",
6566
"tslib": "^2.3.1"
6667
},

packages/subscription/src/createPubSub.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Repeater } from '@repeaterjs/repeater'
22
import type { TypedEventTarget } from '@graphql-yoga/typed-event-target'
3-
import { Event, EventTarget } from '@whatwg-node/fetch'
3+
import { CustomEvent, EventTarget } from '@whatwg-node/events'
44

55
type PubSubPublishArgsByKey = {
66
[key: string]: [] | [any] | [number | string, any]
@@ -9,11 +9,11 @@ type PubSubPublishArgsByKey = {
99
export type PubSubEvent<
1010
TPubSubPublishArgsByKey extends PubSubPublishArgsByKey,
1111
TKey extends Extract<keyof TPubSubPublishArgsByKey, string>,
12-
> = Event & {
13-
data?: TPubSubPublishArgsByKey[TKey][1] extends undefined
12+
> = CustomEvent<
13+
TPubSubPublishArgsByKey[TKey][1] extends undefined
1414
? TPubSubPublishArgsByKey[TKey][0]
1515
: TPubSubPublishArgsByKey[TKey][1]
16-
}
16+
>
1717

1818
export type PubSubEventTarget<
1919
TPubSubPublishArgsByKey extends PubSubPublishArgsByKey,
@@ -66,7 +66,9 @@ export const createPubSub = <
6666
>(
6767
config?: ChannelPubSubConfig<TPubSubPublishArgsByKey>,
6868
): PubSub<TPubSubPublishArgsByKey> => {
69-
const target = config?.eventTarget ?? new EventTarget()
69+
const target =
70+
config?.eventTarget ??
71+
(new EventTarget() as PubSubEventTarget<TPubSubPublishArgsByKey>)
7072

7173
return {
7274
publish<TKey extends Extract<keyof TPubSubPublishArgsByKey, string>>(
@@ -79,8 +81,12 @@ export const createPubSub = <
7981
? routingKey
8082
: `${routingKey}:${args[0] as number}`
8183

82-
const event: PubSubEvent<TPubSubPublishArgsByKey, TKey> = new Event(topic)
83-
event.data = payload
84+
const event: PubSubEvent<TPubSubPublishArgsByKey, TKey> = new CustomEvent(
85+
topic,
86+
{
87+
detail: payload,
88+
},
89+
)
8490
target.dispatchEvent(event)
8591
},
8692
subscribe<TKey extends Extract<keyof TPubSubPublishArgsByKey, string>>(
@@ -105,7 +111,7 @@ export const createPubSub = <
105111
function pubsubEventListener(
106112
event: PubSubEvent<TPubSubPublishArgsByKey, TKey>,
107113
) {
108-
next(event.data)
114+
next(event.detail)
109115
}
110116
})
111117
},

website/src/pages/v3/features/subscriptions.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ The `createPubSub` function allows you to specify a custom [`EventTarget`](https
405405

406406
The minimal `EventTarget` implementation is described by the [`TypedEventTarget` interface](https://github.com/dotansimha/graphql-yoga/blob/master/packages/event-target/typed-event-target/src/typed-event-target.ts).
407407

408-
Yoga comes with an `EventTarget` implementation for [Redis Pub/Sub](https://redis.io/docs/manual/pubsub/).import { PackageCmd } from '@theguild/components';
408+
Yoga comes with an `EventTarget` implementation for [Redis Pub/Sub](https://redis.io/docs/manual/pubsub/).
409409

410410
<PackageCmd packages={['@graphql-yoga/redis-event-target ioredis']} />
411411

0 commit comments

Comments
 (0)