Skip to content

Commit fb6175a

Browse files
committed
feat: simplify EventClient types to accept unprefixed event maps
EventClient now accepts event maps with plain event names instead of requiring the pluginId prefix in every key. The prefix is handled purely at runtime. This removes the complex conditional types that were stripping prefixes from emit/on/createEventPayload signatures.
1 parent b75b84d commit fb6175a

10 files changed

Lines changed: 48 additions & 85 deletions

File tree

examples/preact/basic/src/plugin.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { EventClient } from '@tanstack/devtools-event-client'
22

33
interface EventMap {
4-
'query-devtools:test': {
4+
'test': {
55
title: string
66
description: string
77
}
8-
'query-devtools:init': {
8+
'init': {
99
title: string
1010
description: string
1111
}
12-
'query-devtools:query': {
12+
'query': {
1313
title: string
1414
description: string
1515
}

examples/preact/custom-devtools/src/eventClient.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { EventClient } from '@tanstack/devtools-event-client'
22

33
type EventMap = {
4-
// The key of the event map is a combination of {pluginId}:{eventSuffix}
5-
// The value is the expected type of the event payload
6-
'custom-devtools:counter-state': { count: number; history: Array<number> }
4+
'counter-state': { count: number; history: Array<number> }
75
}
86

97
class CustomEventClient extends EventClient<EventMap> {
108
constructor() {
119
super({
12-
// The pluginId must match that of the event map key
1310
pluginId: 'custom-devtools',
1411
debug: true,
1512
})

examples/react/basic/src/plugin.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { EventClient } from '@tanstack/devtools-event-client'
22

33
interface EventMap {
4-
'query-devtools:test': {
4+
'test': {
55
title: string
66
description: string
77
}
8-
'query-devtools:init': {
8+
'init': {
99
title: string
1010
description: string
1111
}
12-
'query-devtools:query': {
12+
'query': {
1313
title: string
1414
description: string
1515
}

examples/react/custom-devtools/src/eventClient.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { EventClient } from '@tanstack/devtools-event-client'
22

33
type EventMap = {
4-
// The key of the event map is a combination of {pluginId}:{eventSuffix}
5-
// The value is the expected type of the event payload
6-
'custom-devtools:counter-state': { count: number; history: Array<number> }
4+
'counter-state': { count: number; history: Array<number> }
75
}
86

97
class CustomEventClient extends EventClient<EventMap> {
108
constructor() {
119
super({
12-
// The pluginId must match that of the event map key
1310
pluginId: 'custom-devtools',
1411
debug: true,
1512
})

examples/react/https/src/plugin.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { EventClient } from '@tanstack/devtools-event-client'
22

33
interface EventMap {
4-
'query-devtools:test': {
4+
'test': {
55
title: string
66
description: string
77
}
8-
'query-devtools:init': {
8+
'init': {
99
title: string
1010
description: string
1111
}
12-
'query-devtools:query': {
12+
'query': {
1313
title: string
1414
description: string
1515
}

examples/react/start/src/devtools/route-navigation-event-client.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,11 @@ export interface RouteNavigationEvent {
99
}
1010

1111
type RouteNavigationEventMap = {
12-
'route-navigation:navigate': RouteNavigationEvent
13-
'route-navigation:clear': undefined
12+
'navigate': RouteNavigationEvent
13+
'clear': undefined
1414
}
1515

16-
class RouteNavigationEventClient extends EventClient<
17-
RouteNavigationEventMap,
18-
'route-navigation'
19-
> {
16+
class RouteNavigationEventClient extends EventClient<RouteNavigationEventMap> {
2017
constructor() {
2118
super({
2219
pluginId: 'route-navigation',

examples/react/time-travel/src/zustand-client.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { EventClient } from '@tanstack/devtools-event-client'
22
import { createStore } from 'zustand'
33

44
interface ZustandEventMap {
5-
'zustand:stateChange': any
6-
'zustand:revertSnapshot': any
5+
'stateChange': any
6+
'revertSnapshot': any
77
}
88
export const eventClient = new EventClient<ZustandEventMap>({
99
pluginId: 'zustand',

packages/devtools-client/src/index.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,37 +53,37 @@ export interface PluginInjection {
5353
}
5454

5555
interface EventMap {
56-
'tanstack-devtools-core:ready': {
56+
'ready': {
5757
packageJson: PackageJson | null
5858
outdatedDeps: OutdatedDeps | null
5959
}
60-
'tanstack-devtools-core:outdated-deps-read': {
60+
'outdated-deps-read': {
6161
outdatedDeps: OutdatedDeps | null
6262
}
63-
'tanstack-devtools-core:package-json-read': {
63+
'package-json-read': {
6464
packageJson: PackageJson | null
6565
}
66-
'tanstack-devtools-core:mounted': void
67-
'tanstack-devtools-core:install-devtools': PluginInjection
68-
'tanstack-devtools-core:devtools-installed': {
66+
'mounted': void
67+
'install-devtools': PluginInjection
68+
'devtools-installed': {
6969
packageName: string
7070
success: boolean
7171
error?: string
7272
}
73-
'tanstack-devtools-core:add-plugin-to-devtools': PluginInjection
74-
'tanstack-devtools-core:plugin-added': {
73+
'add-plugin-to-devtools': PluginInjection
74+
'plugin-added': {
7575
packageName: string
7676
success: boolean
7777
error?: string
7878
}
79-
'tanstack-devtools-core:bump-package-version': PluginInjection & {
79+
'bump-package-version': PluginInjection & {
8080
devtoolsPackage: string
8181
minVersion?: string
8282
}
83-
'tanstack-devtools-core:package-json-updated': {
83+
'package-json-updated': {
8484
packageJson: PackageJson | null
8585
}
86-
'tanstack-devtools-core:trigger-toggled': {
86+
'trigger-toggled': {
8787
isOpen: boolean
8888
}
8989
}

packages/event-bus-client/src/plugin.ts

Lines changed: 17 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,15 @@ declare global {
88
}
99

1010
type AllDevtoolsEvents<TEventMap extends Record<string, any>> = {
11-
[Key in keyof TEventMap]: TanStackDevtoolsEvent<Key & string, TEventMap[Key]>
12-
}[keyof TEventMap]
11+
[Key in keyof TEventMap & string]: TanStackDevtoolsEvent<
12+
Key,
13+
TEventMap[Key]
14+
>
15+
}[keyof TEventMap & string]
1316

14-
export class EventClient<
15-
TEventMap extends Record<string, any>,
16-
TPluginId extends string = TEventMap extends Record<infer P, any>
17-
? P extends `${infer Id}:${string}`
18-
? Id
19-
: never
20-
: never,
21-
> {
17+
export class EventClient<TEventMap extends Record<string, any>> {
2218
#enabled = true
23-
#pluginId: TPluginId
19+
#pluginId: string
2420
#eventTarget: () => EventTarget
2521
#debug: boolean
2622
#queuedEvents: Array<TanStackDevtoolsEvent<string, any>>
@@ -80,7 +76,7 @@ export class EventClient<
8076
enabled = true,
8177
reconnectEveryMs = 300,
8278
}: {
83-
pluginId: TPluginId
79+
pluginId: string
8480
debug?: boolean
8581
reconnectEveryMs?: number
8682
enabled?: boolean
@@ -194,33 +190,19 @@ export class EventClient<
194190
this.dispatchCustomEvent('tanstack-dispatch-event', event)
195191
}
196192

197-
createEventPayload<
198-
TSuffix extends Extract<
199-
keyof TEventMap,
200-
`${TPluginId & string}:${string}`
201-
> extends `${TPluginId & string}:${infer S}`
202-
? S
203-
: never,
204-
>(
205-
eventSuffix: TSuffix,
206-
payload: TEventMap[`${TPluginId & string}:${TSuffix}`],
193+
createEventPayload<TEvent extends keyof TEventMap & string>(
194+
eventSuffix: TEvent,
195+
payload: TEventMap[TEvent],
207196
) {
208197
return {
209198
type: `${this.#pluginId}:${eventSuffix}`,
210199
payload,
211200
pluginId: this.#pluginId,
212201
}
213202
}
214-
emit<
215-
TSuffix extends Extract<
216-
keyof TEventMap,
217-
`${TPluginId & string}:${string}`
218-
> extends `${TPluginId & string}:${infer S}`
219-
? S
220-
: never,
221-
>(
222-
eventSuffix: TSuffix,
223-
payload: TEventMap[`${TPluginId & string}:${TSuffix}`],
203+
emit<TEvent extends keyof TEventMap & string>(
204+
eventSuffix: TEvent,
205+
payload: TEventMap[TEvent],
224206
) {
225207
if (!this.#enabled) {
226208
this.debugLog(
@@ -262,20 +244,10 @@ export class EventClient<
262244
return this.emitEventToBus(this.createEventPayload(eventSuffix, payload))
263245
}
264246

265-
on<
266-
TSuffix extends Extract<
267-
keyof TEventMap,
268-
`${TPluginId & string}:${string}`
269-
> extends `${TPluginId & string}:${infer S}`
270-
? S
271-
: never,
272-
>(
273-
eventSuffix: TSuffix,
247+
on<TEvent extends keyof TEventMap & string>(
248+
eventSuffix: TEvent,
274249
cb: (
275-
event: TanStackDevtoolsEvent<
276-
`${TPluginId & string}:${TSuffix}`,
277-
TEventMap[`${TPluginId & string}:${TSuffix}`]
278-
>,
250+
event: TanStackDevtoolsEvent<TEvent, TEventMap[TEvent]>,
279251
) => void,
280252
options?: {
281253
withEventTarget?: boolean

packages/event-bus-client/tests/index.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ describe('EventClient', () => {
6666
const targetEmitSpy = vi.spyOn(target, 'dispatchEvent')
6767
const targetListenSpy = vi.spyOn(target, 'addEventListener')
6868
const targetRemoveSpy = vi.spyOn(target, 'removeEventListener')
69-
const cleanup = client.on('test:event', () => {})
69+
const cleanup = client.on('event', () => {})
7070
cleanup()
71-
client.emit('test:event', { foo: 'bar' })
71+
client.emit('event', { foo: 'bar' })
7272
expect(targetEmitSpy).toHaveBeenCalledWith(expect.any(Event))
7373
expect(targetListenSpy).toHaveBeenCalledWith(
7474
expect.any(String),
@@ -90,9 +90,9 @@ describe('EventClient', () => {
9090
const targetEmitSpy = vi.spyOn(target, 'dispatchEvent')
9191
const targetListenSpy = vi.spyOn(target, 'addEventListener')
9292
const targetRemoveSpy = vi.spyOn(target, 'removeEventListener')
93-
const cleanup = client.on('test:event', () => {})
93+
const cleanup = client.on('event', () => {})
9494
cleanup()
95-
client.emit('test:event', { foo: 'bar' })
95+
client.emit('event', { foo: 'bar' })
9696
expect(targetEmitSpy).toHaveBeenCalledWith(expect.any(Event))
9797
expect(targetListenSpy).toHaveBeenCalledWith(
9898
expect.any(String),

0 commit comments

Comments
 (0)