@pikku/core 0.8.2 → 0.9.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/dist/function/functions.types.d.ts +9 -9
  3. package/dist/handle-error.d.ts +1 -1
  4. package/dist/index.d.ts +11 -10
  5. package/dist/index.js +11 -10
  6. package/dist/pikku-state.d.ts +9 -9
  7. package/dist/services/user-session-service.d.ts +1 -1
  8. package/dist/types/core.types.d.ts +5 -5
  9. package/dist/types/core.types.js +9 -9
  10. package/dist/wirings/channel/channel-handler.d.ts +3 -0
  11. package/dist/{events → wirings}/channel/channel-handler.js +3 -3
  12. package/dist/wirings/channel/channel-runner.d.ts +14 -0
  13. package/dist/{events → wirings}/channel/channel-runner.js +13 -13
  14. package/dist/{events → wirings}/channel/channel.types.d.ts +7 -7
  15. package/dist/{events → wirings}/channel/eventhub-service.d.ts +4 -4
  16. package/dist/wirings/channel/eventhub-store.d.ts +5 -0
  17. package/dist/wirings/channel/local/local-channel-runner.d.ts +3 -0
  18. package/dist/{events → wirings}/channel/local/local-eventhub-service.d.ts +4 -4
  19. package/dist/{events → wirings}/channel/local/local-eventhub-service.js +1 -1
  20. package/dist/{events → wirings}/channel/serverless/serverless-channel-runner.d.ts +2 -2
  21. package/dist/{events → wirings}/http/http-runner.d.ts +12 -12
  22. package/dist/{events → wirings}/http/http-runner.js +15 -15
  23. package/dist/{events → wirings}/http/http.types.d.ts +32 -27
  24. package/dist/{events → wirings}/http/index.d.ts +1 -1
  25. package/dist/{events → wirings}/http/index.js +1 -1
  26. package/dist/{events → wirings}/mcp/mcp-runner.d.ts +4 -4
  27. package/dist/{events → wirings}/mcp/mcp-runner.js +3 -3
  28. package/dist/{events → wirings}/mcp/mcp.types.d.ts +7 -7
  29. package/dist/{events → wirings}/queue/index.d.ts +1 -1
  30. package/dist/{events → wirings}/queue/index.js +1 -1
  31. package/dist/{events → wirings}/queue/queue-runner.d.ts +2 -2
  32. package/dist/{events → wirings}/queue/queue-runner.js +1 -1
  33. package/dist/{events → wirings}/queue/queue.types.d.ts +3 -3
  34. package/dist/wirings/scheduler/index.d.ts +3 -0
  35. package/dist/wirings/scheduler/index.js +3 -0
  36. package/dist/{events → wirings}/scheduler/scheduler-runner.d.ts +2 -2
  37. package/dist/{events → wirings}/scheduler/scheduler-runner.js +1 -1
  38. package/dist/{events → wirings}/scheduler/scheduler.types.d.ts +3 -3
  39. package/package.json +9 -9
  40. package/src/function/functions.types.ts +13 -13
  41. package/src/handle-error.ts +1 -1
  42. package/src/index.ts +14 -13
  43. package/src/pikku-state.ts +11 -11
  44. package/src/services/user-session-service.ts +1 -1
  45. package/src/types/core.types.ts +5 -5
  46. package/src/{events → wirings}/channel/channel-handler.ts +5 -5
  47. package/src/{events → wirings}/channel/channel-runner.ts +18 -18
  48. package/src/{events → wirings}/channel/channel.types.ts +16 -16
  49. package/src/{events → wirings}/channel/eventhub-service.ts +12 -8
  50. package/src/wirings/channel/eventhub-store.ts +13 -0
  51. package/src/{events → wirings}/channel/local/local-channel-runner.test.ts +2 -2
  52. package/src/{events → wirings}/channel/local/local-channel-runner.ts +2 -2
  53. package/src/{events → wirings}/channel/local/local-eventhub-service.ts +16 -10
  54. package/src/{events → wirings}/channel/serverless/serverless-channel-runner.ts +2 -2
  55. package/src/{events → wirings}/http/http-runner.test.ts +4 -4
  56. package/src/{events → wirings}/http/http-runner.ts +32 -31
  57. package/src/{events → wirings}/http/http.types.ts +40 -35
  58. package/src/{events → wirings}/http/index.ts +1 -1
  59. package/src/{events → wirings}/mcp/mcp-runner.ts +10 -10
  60. package/src/{events → wirings}/mcp/mcp.types.ts +9 -7
  61. package/src/{events → wirings}/queue/index.ts +1 -1
  62. package/src/{events → wirings}/queue/queue-runner.ts +5 -5
  63. package/src/{events → wirings}/queue/queue.types.ts +3 -3
  64. package/src/{events → wirings}/scheduler/index.ts +1 -1
  65. package/src/{events → wirings}/scheduler/scheduler-runner.ts +4 -4
  66. package/src/{events → wirings}/scheduler/scheduler.types.ts +3 -3
  67. package/tsconfig.tsbuildinfo +1 -1
  68. package/dist/events/channel/channel-handler.d.ts +0 -3
  69. package/dist/events/channel/channel-runner.d.ts +0 -14
  70. package/dist/events/channel/eventhub-store.d.ts +0 -5
  71. package/dist/events/channel/local/local-channel-runner.d.ts +0 -3
  72. package/dist/events/scheduler/index.d.ts +0 -3
  73. package/dist/events/scheduler/index.js +0 -3
  74. package/src/events/channel/eventhub-store.ts +0 -8
  75. /package/dist/{events → wirings}/channel/channel-store.d.ts +0 -0
  76. /package/dist/{events → wirings}/channel/channel-store.js +0 -0
  77. /package/dist/{events → wirings}/channel/channel.types.js +0 -0
  78. /package/dist/{events → wirings}/channel/eventhub-service.js +0 -0
  79. /package/dist/{events → wirings}/channel/eventhub-store.js +0 -0
  80. /package/dist/{events → wirings}/channel/index.d.ts +0 -0
  81. /package/dist/{events → wirings}/channel/index.js +0 -0
  82. /package/dist/{events → wirings}/channel/local/index.d.ts +0 -0
  83. /package/dist/{events → wirings}/channel/local/index.js +0 -0
  84. /package/dist/{events → wirings}/channel/local/local-channel-handler.d.ts +0 -0
  85. /package/dist/{events → wirings}/channel/local/local-channel-handler.js +0 -0
  86. /package/dist/{events → wirings}/channel/local/local-channel-runner.js +0 -0
  87. /package/dist/{events → wirings}/channel/log-channels.d.ts +0 -0
  88. /package/dist/{events → wirings}/channel/log-channels.js +0 -0
  89. /package/dist/{events → wirings}/channel/pikku-abstract-channel-handler.d.ts +0 -0
  90. /package/dist/{events → wirings}/channel/pikku-abstract-channel-handler.js +0 -0
  91. /package/dist/{events → wirings}/channel/serverless/index.d.ts +0 -0
  92. /package/dist/{events → wirings}/channel/serverless/index.js +0 -0
  93. /package/dist/{events → wirings}/channel/serverless/serverless-channel-runner.js +0 -0
  94. /package/dist/{events → wirings}/http/http.types.js +0 -0
  95. /package/dist/{events → wirings}/http/log-http-routes.d.ts +0 -0
  96. /package/dist/{events → wirings}/http/log-http-routes.js +0 -0
  97. /package/dist/{events → wirings}/http/pikku-fetch-http-request.d.ts +0 -0
  98. /package/dist/{events → wirings}/http/pikku-fetch-http-request.js +0 -0
  99. /package/dist/{events → wirings}/http/pikku-fetch-http-response.d.ts +0 -0
  100. /package/dist/{events → wirings}/http/pikku-fetch-http-response.js +0 -0
  101. /package/dist/{events → wirings}/mcp/index.d.ts +0 -0
  102. /package/dist/{events → wirings}/mcp/index.js +0 -0
  103. /package/dist/{events → wirings}/mcp/mcp-endpoint-registry.d.ts +0 -0
  104. /package/dist/{events → wirings}/mcp/mcp-endpoint-registry.js +0 -0
  105. /package/dist/{events → wirings}/mcp/mcp.types.js +0 -0
  106. /package/dist/{events → wirings}/queue/queue.types.js +0 -0
  107. /package/dist/{events → wirings}/queue/register-queue-helper.d.ts +0 -0
  108. /package/dist/{events → wirings}/queue/register-queue-helper.js +0 -0
  109. /package/dist/{events → wirings}/queue/validate-worker-config.d.ts +0 -0
  110. /package/dist/{events → wirings}/queue/validate-worker-config.js +0 -0
  111. /package/dist/{events → wirings}/rpc/index.d.ts +0 -0
  112. /package/dist/{events → wirings}/rpc/index.js +0 -0
  113. /package/dist/{events → wirings}/rpc/rpc-runner.d.ts +0 -0
  114. /package/dist/{events → wirings}/rpc/rpc-runner.js +0 -0
  115. /package/dist/{events → wirings}/rpc/rpc-types.d.ts +0 -0
  116. /package/dist/{events → wirings}/rpc/rpc-types.js +0 -0
  117. /package/dist/{events → wirings}/scheduler/log-schedulers.d.ts +0 -0
  118. /package/dist/{events → wirings}/scheduler/log-schedulers.js +0 -0
  119. /package/dist/{events → wirings}/scheduler/scheduler.types.js +0 -0
  120. /package/src/{events → wirings}/channel/channel-store.ts +0 -0
  121. /package/src/{events → wirings}/channel/index.ts +0 -0
  122. /package/src/{events → wirings}/channel/local/index.ts +0 -0
  123. /package/src/{events → wirings}/channel/local/local-channel-handler.ts +0 -0
  124. /package/src/{events → wirings}/channel/local/local-eventhub-service.test.ts +0 -0
  125. /package/src/{events → wirings}/channel/log-channels.ts +0 -0
  126. /package/src/{events → wirings}/channel/pikku-abstract-channel-handler.test.ts +0 -0
  127. /package/src/{events → wirings}/channel/pikku-abstract-channel-handler.ts +0 -0
  128. /package/src/{events → wirings}/channel/serverless/index.ts +0 -0
  129. /package/src/{events → wirings}/http/log-http-routes.ts +0 -0
  130. /package/src/{events → wirings}/http/pikku-fetch-http-request.test.ts +0 -0
  131. /package/src/{events → wirings}/http/pikku-fetch-http-request.ts +0 -0
  132. /package/src/{events → wirings}/http/pikku-fetch-http-response.test.ts +0 -0
  133. /package/src/{events → wirings}/http/pikku-fetch-http-response.ts +0 -0
  134. /package/src/{events → wirings}/mcp/index.ts +0 -0
  135. /package/src/{events → wirings}/mcp/mcp-endpoint-registry.test.d.ts +0 -0
  136. /package/src/{events → wirings}/mcp/mcp-endpoint-registry.test.ts +0 -0
  137. /package/src/{events → wirings}/mcp/mcp-endpoint-registry.ts +0 -0
  138. /package/src/{events → wirings}/queue/register-queue-helper.ts +0 -0
  139. /package/src/{events → wirings}/queue/validate-worker-config.ts +0 -0
  140. /package/src/{events → wirings}/rpc/index.ts +0 -0
  141. /package/src/{events → wirings}/rpc/rpc-runner.ts +0 -0
  142. /package/src/{events → wirings}/rpc/rpc-types.ts +0 -0
  143. /package/src/{events → wirings}/scheduler/log-schedulers.ts +0 -0
@@ -5,7 +5,7 @@ import {
5
5
  } from '../../types/core.types.js'
6
6
  import {
7
7
  ChannelMessageMeta,
8
- CoreAPIChannel,
8
+ CoreChannel,
9
9
  PikkuChannelHandler,
10
10
  } from './channel.types.js'
11
11
  import { pikkuState } from '../../pikku-state.js'
@@ -31,7 +31,7 @@ const getRouteMeta = (
31
31
  `Channel ${channelName} requires a router value for ${routingProperty}`
32
32
  )
33
33
  }
34
- const route = channelMeta.messageRoutes[routingProperty]?.[routerValue]
34
+ const route = channelMeta.messageWirings[routingProperty]?.[routerValue]
35
35
  if (!route) {
36
36
  throw new Error(
37
37
  `Channel ${channelName} has no route for ${routingProperty}:${routerValue}`
@@ -61,7 +61,7 @@ const validateAuth = (
61
61
  export const processMessageHandlers = (
62
62
  services: CoreServices,
63
63
  session: CoreUserSession | undefined,
64
- channelConfig: CoreAPIChannel<any, any>,
64
+ channelConfig: CoreChannel<any, any>,
65
65
  channelHandler: PikkuChannelHandler
66
66
  ) => {
67
67
  const logger = services.logger
@@ -115,10 +115,10 @@ export const processMessageHandlers = (
115
115
  let processed = false
116
116
 
117
117
  // Route-specific handling
118
- if (typeof rawData === 'string' && channelConfig.onMessageRoute) {
118
+ if (typeof rawData === 'string' && channelConfig.onMessageWiring) {
119
119
  try {
120
120
  const messageData = JSON.parse(rawData)
121
- const entries = Object.entries(channelConfig.onMessageRoute)
121
+ const entries = Object.entries(channelConfig.onMessageWiring)
122
122
  for (const [routingProperty, routes] of entries) {
123
123
  const routerValue = messageData[routingProperty]
124
124
  if (routerValue && routes[routerValue]) {
@@ -5,7 +5,7 @@ import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js'
5
5
  import { UserSessionService } from '../../services/user-session-service.js'
6
6
  import {
7
7
  ChannelMeta,
8
- CoreAPIChannel,
8
+ CoreChannel,
9
9
  RunChannelOptions,
10
10
  RunChannelParams,
11
11
  } from './channel.types.js'
@@ -15,14 +15,14 @@ import { match } from 'path-to-regexp'
15
15
  * Adds a channel and registers all functions referenced in it using the
16
16
  * function names already stored in the channel metadata
17
17
  */
18
- export const addChannel = <
18
+ export const wireChannel = <
19
19
  In,
20
20
  Channel extends string,
21
21
  ChannelFunction,
22
22
  ChannelFunctionSessionless,
23
- APIPermission,
23
+ PikkuPermission,
24
24
  >(
25
- channel: CoreAPIChannel<In, Channel, ChannelFunction, APIPermission>
25
+ channel: CoreChannel<In, Channel, ChannelFunction, PikkuPermission>
26
26
  ) => {
27
27
  // Get the channel metadata
28
28
  const channelsMeta = pikkuState('channel', 'meta')
@@ -58,20 +58,20 @@ export const addChannel = <
58
58
  })
59
59
  }
60
60
 
61
- // Register functions in onMessageRoute
62
- if (channel.onMessageRoute && channelMeta.messageRoutes) {
63
- // Iterate through each channel in onMessageRoute
64
- Object.entries(channel.onMessageRoute).forEach(([channelKey, routes]) => {
65
- const channelRoutes = channelMeta.messageRoutes[channelKey]
66
- if (!channelRoutes) return
61
+ // Register functions in onMessageWiring
62
+ if (channel.onMessageWiring && channelMeta.messageWirings) {
63
+ // Iterate through each channel in onMessageWiring
64
+ Object.entries(channel.onMessageWiring).forEach(([channelKey, wirings]) => {
65
+ const channelWirings = channelMeta.messageWirings[channelKey]
66
+ if (!channelWirings) return
67
67
 
68
- // Iterate through each route in the channel
69
- Object.entries(routes).forEach(([routeKey, handler]) => {
70
- const routeMeta = channelRoutes[routeKey]
71
- if (!routeMeta) return
68
+ // Iterate through each wiring in the channel
69
+ Object.entries(wirings).forEach(([wiringKey, handler]) => {
70
+ const wiringMeta = channelWirings[wiringKey]
71
+ if (!wiringMeta) return
72
72
 
73
73
  // Extract the function from the handler
74
- const routeFunc =
74
+ const wiringFunc =
75
75
  typeof handler === 'function'
76
76
  ? { func: handler }
77
77
  : {
@@ -81,7 +81,7 @@ export const addChannel = <
81
81
  }
82
82
 
83
83
  // Register the function using the pikku name from metadata
84
- addFunction(routeMeta.pikkuFuncName, routeFunc)
84
+ addFunction(wiringMeta.pikkuFuncName, wiringFunc)
85
85
  })
86
86
  })
87
87
  }
@@ -122,12 +122,12 @@ export const openChannel = async ({
122
122
  singletonServices,
123
123
  coerceDataFromSchema = true,
124
124
  request,
125
- }: Pick<CoreAPIChannel<unknown, string>, 'route'> &
125
+ }: Pick<CoreChannel<unknown, string>, 'route'> &
126
126
  RunChannelParams<unknown> & {
127
127
  userSession: UserSessionService<any>
128
128
  } & RunChannelOptions): Promise<{
129
129
  openingData: unknown
130
- channelConfig: CoreAPIChannel<unknown, any>
130
+ channelConfig: CoreChannel<unknown, any>
131
131
  meta: ChannelMeta
132
132
  }> => {
133
133
  const matchingChannel = getMatchingChannelConfig(route)
@@ -11,9 +11,9 @@ import {
11
11
  PikkuMiddleware,
12
12
  } from '../../types/core.types.js'
13
13
  import {
14
- CoreAPIFunction,
15
- CoreAPIFunctionSessionless,
16
- CoreAPIPermission,
14
+ CorePikkuFunction,
15
+ CorePikkuFunctionSessionless,
16
+ CorePikkuPermission,
17
17
  } from '../../function/functions.types.js'
18
18
 
19
19
  export type RunChannelOptions = Partial<{
@@ -47,26 +47,26 @@ export interface ChannelMeta {
47
47
  connect: ChannelMessageMeta | null
48
48
  disconnect: ChannelMessageMeta | null
49
49
  message: ChannelMessageMeta | null
50
- messageRoutes: Record<string, Record<string, ChannelMessageMeta>>
50
+ messageWirings: Record<string, Record<string, ChannelMessageMeta>>
51
51
  docs?: APIDocs
52
52
  tags?: string[]
53
53
  }
54
54
 
55
55
  export type ChannelsMeta = Record<string, ChannelMeta>
56
56
 
57
- export type CoreAPIChannel<
57
+ export type CoreChannel<
58
58
  ChannelData,
59
59
  Channel extends string,
60
60
  ChannelConnect =
61
- | CoreAPIFunction<void, unknown, ChannelData>
62
- | CoreAPIFunctionSessionless<void, unknown, ChannelData>,
61
+ | CorePikkuFunction<void, unknown, ChannelData>
62
+ | CorePikkuFunctionSessionless<void, unknown, ChannelData>,
63
63
  ChannelDisconnect =
64
- | CoreAPIFunction<void, void, ChannelData>
65
- | CoreAPIFunctionSessionless<void, void, ChannelData>,
64
+ | CorePikkuFunction<void, void, ChannelData>
65
+ | CorePikkuFunctionSessionless<void, void, ChannelData>,
66
66
  ChannelFunctionMessage =
67
- | CoreAPIFunction<unknown, unknown, ChannelData>
68
- | CoreAPIFunctionSessionless<unknown, unknown, ChannelData>,
69
- APIPermission = CoreAPIPermission<ChannelData>,
67
+ | CorePikkuFunction<unknown, unknown, ChannelData>
68
+ | CorePikkuFunctionSessionless<unknown, unknown, ChannelData>,
69
+ PikkuPermission = CorePikkuPermission<ChannelData>,
70
70
  > = {
71
71
  name: string
72
72
  route: Channel
@@ -75,24 +75,24 @@ export type CoreAPIChannel<
75
75
  onMessage?:
76
76
  | {
77
77
  func: ChannelFunctionMessage
78
- permissions?: Record<string, APIPermission[] | APIPermission>
78
+ permissions?: Record<string, PikkuPermission[] | PikkuPermission>
79
79
  auth?: boolean
80
80
  }
81
81
  | ChannelFunctionMessage
82
- onMessageRoute?: Record<
82
+ onMessageWiring?: Record<
83
83
  string,
84
84
  Record<
85
85
  string,
86
86
  | ChannelFunctionMessage
87
87
  | {
88
88
  func: ChannelFunctionMessage
89
- permissions?: Record<string, APIPermission[] | APIPermission>
89
+ permissions?: Record<string, PikkuPermission[] | PikkuPermission>
90
90
  auth?: boolean
91
91
  }
92
92
  >
93
93
  >
94
94
  middleware?: PikkuMiddleware[]
95
- permissions?: Record<string, APIPermission[] | APIPermission>
95
+ permissions?: Record<string, PikkuPermission[] | PikkuPermission>
96
96
  auth?: boolean
97
97
  docs?: Partial<{
98
98
  description: string
@@ -1,30 +1,34 @@
1
1
  /**
2
2
  * Interface defining the methods of a EventHub Service.
3
3
  */
4
- export interface EventHubService<Out = unknown> {
4
+ export interface EventHubService<Topics extends Record<string, any>> {
5
5
  /**
6
6
  * Subscribes a connection to a specific topic.
7
7
  * @param topic - The topic to subscribe to.
8
8
  * @param channelId - The unique ID of the connection to subscribe.
9
9
  */
10
- subscribe(topic: string, channelId: string): Promise<void> | void
11
-
10
+ subscribe<T extends keyof Topics>(
11
+ topic: T,
12
+ channelId: string
13
+ ): Promise<void> | void
12
14
  /**
13
15
  * Unsubscribes a connection from a specific topic.
14
16
  * @param topic - The topic to unsubscribe from.
15
17
  * @param channelId - The unique ID of the connection to unsubscribe.
16
18
  */
17
- unsubscribe(topic: string, channelId: string): Promise<void> | void
18
-
19
+ unsubscribe<T extends keyof Topics>(
20
+ topic: T,
21
+ channelId: string
22
+ ): Promise<void> | void
19
23
  /**
20
24
  * Sends data to all connections subscribed to a topic.
21
25
  * @param topic - The topic to send data to.
22
26
  * @param data - The data to send to the subscribers.
23
27
  */
24
- publish(
25
- topic: string,
28
+ publish<T extends keyof Topics>(
29
+ topic: T,
26
30
  channelId: string | null,
27
- data: Out,
31
+ data: Topics[T],
28
32
  isBinary?: boolean
29
33
  ): Promise<void> | void
30
34
  }
@@ -0,0 +1,13 @@
1
+ export abstract class EventHubStore<
2
+ EventTopics extends Record<string, any> = {},
3
+ > {
4
+ public abstract getChannelIdsForTopic(topic: string): Promise<string[]>
5
+ public abstract subscribe<T extends keyof EventTopics>(
6
+ topic: T,
7
+ channelId: string
8
+ ): Promise<boolean>
9
+ public abstract unsubscribe<T extends keyof EventTopics>(
10
+ topic: T,
11
+ channelId: string
12
+ ): Promise<boolean>
13
+ }
@@ -2,7 +2,7 @@ import { test, beforeEach, afterEach } from 'node:test'
2
2
  import * as assert from 'node:assert/strict'
3
3
  import { runLocalChannel } from './local-channel-runner.js'
4
4
  import { pikkuState, resetPikkuState } from '../../../pikku-state.js'
5
- import { addChannel } from '../channel-runner.js'
5
+ import { wireChannel } from '../channel-runner.js'
6
6
  import {
7
7
  HTTPMethod,
8
8
  PikkuHTTPRequest,
@@ -133,7 +133,7 @@ test('runChannel should return a channel handler if channel matches and no auth
133
133
  route: '/test-channel',
134
134
  },
135
135
  } as any)
136
- addChannel({
136
+ wireChannel({
137
137
  name: 'test',
138
138
  route: '/test-channel',
139
139
  auth: false,
@@ -3,7 +3,7 @@ import { createHTTPInteraction } from '../../http/http-runner.js'
3
3
  import { closeSessionServices } from '../../../utils.js'
4
4
  import { processMessageHandlers } from '../channel-handler.js'
5
5
  import {
6
- CoreAPIChannel,
6
+ CoreChannel,
7
7
  RunChannelOptions,
8
8
  RunChannelParams,
9
9
  } from '../channel.types.js'
@@ -28,7 +28,7 @@ export const runLocalChannel = async ({
28
28
  coerceDataFromSchema = true,
29
29
  logWarningsForStatusCodes = [],
30
30
  bubbleErrors = false,
31
- }: Partial<Pick<CoreAPIChannel<unknown, any>, 'route'>> &
31
+ }: Partial<Pick<CoreChannel<unknown, any>, 'route'>> &
32
32
  RunChannelOptions &
33
33
  RunChannelParams<unknown>): Promise<PikkuLocalChannelHandler | void> => {
34
34
  let sessionServices: SessionServices<typeof singletonServices> | undefined
@@ -5,7 +5,7 @@ import { EventHubService } from '../eventhub-service.js'
5
5
  * Implementation of the SubscriptionService interface.
6
6
  * Manages subscriptions and publishes messages to subscribers.
7
7
  */
8
- export class LocalEventHubService<Data = unknown>
8
+ export class LocalEventHubService<Data extends Record<string, any> = {}>
9
9
  implements EventHubService<Data>
10
10
  {
11
11
  private channels = new Map<string, PikkuChannelHandler>()
@@ -13,7 +13,7 @@ export class LocalEventHubService<Data = unknown>
13
13
  /**
14
14
  * A map storing topics and their associated connection IDs.
15
15
  */
16
- private subscriptions: Map<string, Set<string>> = new Map()
16
+ private subscriptions: Map<keyof Data, Set<string>> = new Map()
17
17
 
18
18
  /**
19
19
  * Subscribes a connection to a specific topic.
@@ -21,7 +21,10 @@ export class LocalEventHubService<Data = unknown>
21
21
  * @param topic - The topic to subscribe to.
22
22
  * @param channelId - The unique ID of the connection to subscribe.
23
23
  */
24
- public subscribe(topic: string, channelId: string): void {
24
+ public subscribe<T extends keyof Data>(
25
+ topic: T,
26
+ channelId: string
27
+ ): void | Promise<void> {
25
28
  if (!this.subscriptions.has(topic)) {
26
29
  this.subscriptions.set(topic, new Set())
27
30
  }
@@ -34,12 +37,15 @@ export class LocalEventHubService<Data = unknown>
34
37
  * @param topic - The topic to unsubscribe from.
35
38
  * @param channelId - The unique ID of the connection to unsubscribe.
36
39
  */
37
- public unsubscribe(topic: string, channelId: string): void {
40
+ public unsubscribe<T extends keyof Data>(
41
+ topic: T,
42
+ channelId: string
43
+ ): void | Promise<void> {
38
44
  const topicSubscriptions = this.subscriptions.get(topic)
39
45
  if (topicSubscriptions) {
40
46
  topicSubscriptions.delete(channelId)
41
47
  if (topicSubscriptions.size === 0) {
42
- this.subscriptions.delete(topic) // Cleanup empty subscriptions
48
+ this.subscriptions.delete(topic)
43
49
  }
44
50
  }
45
51
  }
@@ -49,12 +55,12 @@ export class LocalEventHubService<Data = unknown>
49
55
  * @param topic - The topic to send data to.
50
56
  * @param data - The data to send to the subscribers.
51
57
  */
52
- public publish(
53
- topic: string,
54
- channelId: string,
55
- data: Data,
58
+ public publish<T extends keyof Data>(
59
+ topic: T,
60
+ channelId: string | null,
61
+ data: Data[T],
56
62
  isBinary?: boolean
57
- ): void {
63
+ ): void | Promise<void> {
58
64
  const subscribedChannelIds = this.subscriptions.get(topic)
59
65
  if (!subscribedChannelIds) {
60
66
  return
@@ -3,7 +3,7 @@ import { closeSessionServices } from '../../../utils.js'
3
3
  import { processMessageHandlers } from '../channel-handler.js'
4
4
  import { openChannel } from '../channel-runner.js'
5
5
  import type {
6
- CoreAPIChannel,
6
+ CoreChannel,
7
7
  RunChannelOptions,
8
8
  RunChannelParams,
9
9
  PikkuChannelHandlerFactory,
@@ -73,7 +73,7 @@ export const runChannelConnect = async ({
73
73
  logWarningsForStatusCodes = [],
74
74
  respondWith404 = true,
75
75
  bubbleErrors = false,
76
- }: Pick<CoreAPIChannel<unknown, any>, 'route'> &
76
+ }: Pick<CoreChannel<unknown, any>, 'route'> &
77
77
  RunChannelOptions &
78
78
  RunServerlessChannelParams<unknown>) => {
79
79
  let sessionServices: SessionServices | undefined
@@ -2,7 +2,7 @@ import { test, describe, beforeEach, afterEach } from 'node:test'
2
2
  import * as assert from 'assert'
3
3
  import { NotFoundError } from '../../errors/errors.js'
4
4
  import { JSONValue, PikkuMiddleware } from '../../types/core.types.js'
5
- import { fetch, addHTTPRoute } from './http-runner.js'
5
+ import { fetch, wireHTTP } from './http-runner.js'
6
6
  import { pikkuState, resetPikkuState } from '../../pikku-state.js'
7
7
  import {
8
8
  PikkuMockRequest,
@@ -78,7 +78,7 @@ describe('fetch', () => {
78
78
  const routeFunc = async () => ({ success: true })
79
79
  setHTTPFunctionMap(routeFunc)
80
80
 
81
- addHTTPRoute({
81
+ wireHTTP({
82
82
  route: 'test',
83
83
  method: 'get',
84
84
  func: routeFunc,
@@ -98,7 +98,7 @@ describe('fetch', () => {
98
98
  const routeFunc = async () => ({ success: true })
99
99
  setHTTPFunctionMap(routeFunc)
100
100
 
101
- addHTTPRoute({
101
+ wireHTTP({
102
102
  route: 'test',
103
103
  method: 'get',
104
104
  func: routeFunc,
@@ -120,7 +120,7 @@ describe('fetch', () => {
120
120
  throw error
121
121
  }
122
122
  setHTTPFunctionMap(routeFunc)
123
- addHTTPRoute({
123
+ wireHTTP({
124
124
  route: 'test',
125
125
  method: 'get',
126
126
  func: routeFunc,
@@ -1,11 +1,11 @@
1
1
  import {
2
- CoreHTTPFunctionRoute,
3
- RunRouteOptions,
4
- RunRouteParams,
2
+ CoreHTTPFunctionWiring,
3
+ RunHTTPWiringOptions,
4
+ RunHTTPWiringParams,
5
5
  PikkuHTTP,
6
6
  PikkuHTTPRequest,
7
7
  PikkuHTTPResponse,
8
- HTTPRouteMeta,
8
+ HTTPWiringMeta,
9
9
  HTTPMethod,
10
10
  } from './http.types.js'
11
11
  import {
@@ -87,48 +87,49 @@ export const addMiddleware = <APIMiddleware extends PikkuMiddleware>(
87
87
  * @template In Expected input type.
88
88
  * @template Out Expected output type.
89
89
  * @template Route Route pattern as a string.
90
- * @template APIFunction Type for the route handler function.
91
- * @template APIFunctionSessionless Type for a sessionless handler.
92
- * @template APIPermissionGroup Type representing required permissions.
90
+ * @template PikkuFunction Type for the route handler function.
91
+ * @template PikkuFunctionSessionless Type for a sessionless handler.
92
+ * @template PikkuPermissionGroup Type representing required permissions.
93
93
  * @template APIMiddleware Middleware type to be used with the route.
94
- * @param {CoreHTTPFunctionRoute<In, Out, Route, APIFunction, APIFunctionSessionless, APIPermission, APIMiddleware>} route - The route configuration object.
94
+ * @param {CoreHTTPFunctionWiring<In, Out, Route, PikkuFunction, PikkuFunctionSessionless, PikkuPermission, APIMiddleware>} httpWiring - The HTTP wiring configuration object.
95
95
  */
96
- export const addHTTPRoute = <
96
+ export const wireHTTP = <
97
97
  In,
98
98
  Out,
99
99
  Route extends string,
100
- APIFunction,
101
- APIFunctionSessionless,
102
- APIPermissionGroup,
100
+ PikkuFunction,
101
+ PikkuFunctionSessionless,
102
+ PikkuPermissionGroup,
103
103
  APIMiddleware,
104
104
  >(
105
- httpRoute: CoreHTTPFunctionRoute<
105
+ httpWiring: CoreHTTPFunctionWiring<
106
106
  In,
107
107
  Out,
108
108
  Route,
109
- APIFunction,
110
- APIFunctionSessionless,
111
- APIPermissionGroup,
109
+ PikkuFunction,
110
+ PikkuFunctionSessionless,
111
+ PikkuPermissionGroup,
112
112
  APIMiddleware
113
113
  >
114
114
  ) => {
115
115
  const httpMeta = pikkuState('http', 'meta')
116
116
  const routeMeta = httpMeta.find(
117
- (meta) => meta.route === httpRoute.route && meta.method === httpRoute.method
117
+ (meta) =>
118
+ meta.route === httpWiring.route && meta.method === httpWiring.method
118
119
  )
119
120
  if (!routeMeta) {
120
121
  throw new Error('Route metadata not found')
121
122
  }
122
123
  addFunction(routeMeta.pikkuFuncName, {
123
- func: httpRoute.func,
124
+ func: httpWiring.func,
124
125
  })
125
126
  const routes = pikkuState('http', 'routes')
126
- if (!routes.has(httpRoute.method)) {
127
- routes.set(httpRoute.method, new Map())
127
+ if (!routes.has(httpWiring.method)) {
128
+ routes.set(httpWiring.method, new Map())
128
129
  }
129
130
  pikkuState('http', 'routes')
130
- .get(httpRoute.method)
131
- ?.set(httpRoute.route, httpRoute as any)
131
+ .get(httpWiring.method)
132
+ ?.set(httpWiring.route, httpWiring as any)
132
133
  }
133
134
 
134
135
  /**
@@ -242,9 +243,9 @@ const executeRouteWithMiddleware = async (
242
243
  matchedRoute: {
243
244
  matchedPath: any
244
245
  params: any
245
- route: CoreHTTPFunctionRoute<any, any, any>
246
+ route: CoreHTTPFunctionWiring<any, any, any>
246
247
  middleware: any[]
247
- meta: HTTPRouteMeta
248
+ meta: HTTPWiringMeta
248
249
  },
249
250
  http: PikkuHTTP,
250
251
  options: {
@@ -290,7 +291,7 @@ const executeRouteWithMiddleware = async (
290
291
  throw new MissingSessionError()
291
292
  }
292
293
 
293
- const data = http.request!.data()
294
+ const data = await http.request!.data()
294
295
 
295
296
  const getAllServices = async () => {
296
297
  let channel: PikkuChannel<unknown, unknown> | undefined
@@ -382,12 +383,12 @@ const executeRouteWithMiddleware = async (
382
383
  * @template In Expected input data type.
383
384
  * @template Out Expected output data type.
384
385
  * @param {Request} request - The native Fetch API Request object.
385
- * @param {RunRouteOptions & RunRouteParams} params - Additional options including services and session management.
386
+ * @param {RunHTTPWiringOptions & RunHTTPWiringParams} params - Additional options including services and session management.
386
387
  * @returns {Promise<Response>} A promise that resolves to a Fetch API Response object.
387
388
  */
388
389
  export const fetch = async <In, Out>(
389
390
  request: Request,
390
- params: RunRouteOptions & RunRouteParams
391
+ params: RunHTTPWiringOptions & RunHTTPWiringParams
391
392
  ): Promise<Response> => {
392
393
  const pikkuResponse = new PikkuFetchHTTPResponse()
393
394
  await fetchData<In, Out>(request, pikkuResponse, params)
@@ -403,12 +404,12 @@ export const fetch = async <In, Out>(
403
404
  * @template In Expected input data type.
404
405
  * @template Out Expected output data type.
405
406
  * @param {Request | PikkuHTTPRequest} request - The request object.
406
- * @param {RunRouteOptions & RunRouteParams} params - Execution options including services and session configuration.
407
+ * @param {RunHTTPWiringOptions & RunHTTPWiringParams} params - Execution options including services and session configuration.
407
408
  * @returns {Promise<PikkuFetchHTTPResponse>} A promise that resolves to a PikkuFetchHTTPResponse object.
408
409
  */
409
410
  export const pikkuFetch = async <In, Out>(
410
411
  request: Request | PikkuHTTPRequest,
411
- params: RunRouteOptions & RunRouteParams
412
+ params: RunHTTPWiringOptions & RunHTTPWiringParams
412
413
  ): Promise<PikkuFetchHTTPResponse> => {
413
414
  const pikkuResponse = new PikkuFetchHTTPResponse()
414
415
  await fetchData<In, Out>(request, pikkuResponse, params)
@@ -430,7 +431,7 @@ export const pikkuFetch = async <In, Out>(
430
431
  * @template Out Expected output data type.
431
432
  * @param {Request | PikkuHTTPRequest} request - The incoming HTTP request.
432
433
  * @param {PikkuHTTPResponse} response - The response object to be populated.
433
- * @param {RunRouteOptions & RunRouteParams} options - Options such as singleton services, session handling, and error configuration.
434
+ * @param {RunHTTPWiringOptions & RunHTTPWiringParams} options - Options such as singleton services, session handling, and error configuration.
434
435
  * @returns {Promise<Out | void>} The output from the route handler or void if an error occurred.
435
436
  */
436
437
  export const fetchData = async <In, Out>(
@@ -446,7 +447,7 @@ export const fetchData = async <In, Out>(
446
447
  bubbleErrors = false,
447
448
  generateRequestId,
448
449
  ignoreMiddleware = false,
449
- }: RunRouteOptions & RunRouteParams
450
+ }: RunHTTPWiringOptions & RunHTTPWiringParams
450
451
  ): Promise<Out | void> => {
451
452
  const requestId =
452
453
  (request as any).getHeader?.('x-request-id') ||