@pikku/core 0.12.0 → 0.12.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 (262) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/errors/errors.d.ts +6 -0
  3. package/dist/errors/errors.js +10 -0
  4. package/dist/errors/index.d.ts +1 -0
  5. package/dist/errors/index.js +1 -0
  6. package/dist/function/function-runner.d.ts +3 -3
  7. package/dist/function/function-runner.js +66 -44
  8. package/dist/function/functions.types.d.ts +1 -0
  9. package/dist/handle-error.d.ts +2 -2
  10. package/dist/handle-error.js +2 -2
  11. package/dist/index.d.ts +5 -3
  12. package/dist/index.js +2 -1
  13. package/dist/internal.d.ts +3 -0
  14. package/dist/internal.js +2 -0
  15. package/dist/middleware/auth-bearer.d.ts +1 -1
  16. package/dist/middleware/auth-bearer.js +1 -1
  17. package/dist/middleware/auth-cookie.d.ts +2 -2
  18. package/dist/middleware/auth-cookie.js +1 -1
  19. package/dist/middleware/cors.d.ts +2 -2
  20. package/dist/middleware/cors.js +45 -37
  21. package/dist/middleware-runner.d.ts +1 -1
  22. package/dist/permissions.d.ts +2 -2
  23. package/dist/pikku-state.d.ts +9 -8
  24. package/dist/pikku-state.js +30 -17
  25. package/dist/schema.d.ts +4 -4
  26. package/dist/schema.js +9 -5
  27. package/dist/services/ai-agent-runner-service.d.ts +22 -3
  28. package/dist/services/ai-run-state-service.d.ts +1 -1
  29. package/dist/services/ai-storage-service.d.ts +1 -1
  30. package/dist/services/content-service.d.ts +6 -0
  31. package/dist/services/gopass-secrets.d.ts +1 -1
  32. package/dist/services/gopass-secrets.js +3 -0
  33. package/dist/services/in-memory-ai-run-state-service.d.ts +15 -0
  34. package/dist/services/in-memory-ai-run-state-service.js +44 -0
  35. package/dist/services/in-memory-trigger-service.d.ts +0 -1
  36. package/dist/services/in-memory-trigger-service.js +6 -8
  37. package/dist/services/index.d.ts +3 -2
  38. package/dist/services/index.js +1 -0
  39. package/dist/services/local-content.d.ts +2 -1
  40. package/dist/services/local-content.js +6 -1
  41. package/dist/services/local-secrets.d.ts +2 -2
  42. package/dist/services/local-variables.d.ts +1 -1
  43. package/dist/services/logger-console.d.ts +2 -1
  44. package/dist/services/scheduler-service.d.ts +0 -12
  45. package/dist/services/scheduler-service.js +0 -6
  46. package/dist/services/scoped-secret-service.d.ts +1 -1
  47. package/dist/services/trigger-service.d.ts +0 -7
  48. package/dist/services/user-session-service.d.ts +3 -3
  49. package/dist/services/workflow-service.d.ts +2 -3
  50. package/dist/types/core.types.d.ts +24 -18
  51. package/dist/types/state.types.d.ts +17 -15
  52. package/dist/utils.d.ts +5 -5
  53. package/dist/utils.js +12 -9
  54. package/dist/wirings/ai-agent/ai-agent-assistant-ui.d.ts +5 -0
  55. package/dist/wirings/ai-agent/ai-agent-assistant-ui.js +146 -0
  56. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +28 -0
  57. package/dist/wirings/ai-agent/ai-agent-helpers.js +40 -0
  58. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +4 -5
  59. package/dist/wirings/ai-agent/ai-agent-prepare.js +66 -30
  60. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +1 -1
  61. package/dist/wirings/ai-agent/ai-agent-runner.js +107 -8
  62. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
  63. package/dist/wirings/ai-agent/ai-agent-stream.js +246 -87
  64. package/dist/wirings/ai-agent/ai-agent.types.d.ts +61 -2
  65. package/dist/wirings/ai-agent/index.d.ts +3 -1
  66. package/dist/wirings/ai-agent/index.js +2 -0
  67. package/dist/wirings/channel/channel-common.d.ts +2 -2
  68. package/dist/wirings/channel/channel-handler.d.ts +3 -3
  69. package/dist/wirings/channel/channel-handler.js +4 -4
  70. package/dist/wirings/channel/channel-runner.d.ts +5 -5
  71. package/dist/wirings/channel/channel-runner.js +3 -2
  72. package/dist/wirings/channel/channel-store.d.ts +1 -1
  73. package/dist/wirings/channel/channel.types.d.ts +4 -6
  74. package/dist/wirings/channel/local/local-channel-runner.d.ts +7 -2
  75. package/dist/wirings/channel/local/local-channel-runner.js +4 -3
  76. package/dist/wirings/channel/local/local-eventhub-service.d.ts +2 -2
  77. package/dist/wirings/channel/log-channels.d.ts +1 -1
  78. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +1 -1
  79. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +4 -4
  80. package/dist/wirings/channel/serverless/serverless-channel-runner.js +25 -19
  81. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +1 -1
  82. package/dist/wirings/cli/cli-runner.d.ts +2 -2
  83. package/dist/wirings/cli/cli.types.d.ts +3 -3
  84. package/dist/wirings/cli/command-parser.d.ts +1 -1
  85. package/dist/wirings/http/http-runner.d.ts +9 -9
  86. package/dist/wirings/http/http-runner.js +33 -14
  87. package/dist/wirings/http/http.types.d.ts +2 -6
  88. package/dist/wirings/http/log-http-routes.d.ts +1 -1
  89. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -1
  90. package/dist/wirings/http/pikku-fetch-http-response.d.ts +2 -2
  91. package/dist/wirings/http/pikku-fetch-http-response.js +6 -1
  92. package/dist/wirings/http/routers/http-router.d.ts +1 -1
  93. package/dist/wirings/http/routers/path-to-regex.d.ts +2 -2
  94. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +1 -1
  95. package/dist/wirings/mcp/mcp-runner.d.ts +0 -3
  96. package/dist/wirings/mcp/mcp-runner.js +4 -2
  97. package/dist/wirings/mcp/mcp.types.d.ts +2 -2
  98. package/dist/wirings/oauth2/oauth2-client.d.ts +3 -3
  99. package/dist/wirings/oauth2/wire-oauth2-credential.d.ts +1 -1
  100. package/dist/wirings/queue/index.d.ts +1 -1
  101. package/dist/wirings/queue/index.js +1 -1
  102. package/dist/wirings/queue/queue-runner.d.ts +1 -12
  103. package/dist/wirings/queue/queue-runner.js +4 -12
  104. package/dist/wirings/queue/queue.types.d.ts +3 -9
  105. package/dist/wirings/queue/register-queue-helper.d.ts +2 -2
  106. package/dist/wirings/queue/register-queue-helper.js +1 -1
  107. package/dist/wirings/queue/validate-worker-config.d.ts +1 -1
  108. package/dist/wirings/rpc/index.d.ts +2 -0
  109. package/dist/wirings/rpc/index.js +1 -0
  110. package/dist/wirings/rpc/rpc-runner.d.ts +36 -14
  111. package/dist/wirings/rpc/rpc-runner.js +56 -28
  112. package/dist/wirings/rpc/rpc-types.d.ts +14 -2
  113. package/dist/wirings/rpc/wire-addon.d.ts +10 -0
  114. package/dist/wirings/rpc/wire-addon.js +9 -0
  115. package/dist/wirings/scheduler/index.d.ts +1 -1
  116. package/dist/wirings/scheduler/index.js +1 -1
  117. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -1
  118. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -10
  119. package/dist/wirings/scheduler/scheduler-runner.js +4 -25
  120. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -2
  121. package/dist/wirings/trigger/pikku-trigger-service.d.ts +2 -6
  122. package/dist/wirings/trigger/pikku-trigger-service.js +11 -16
  123. package/dist/wirings/trigger/trigger-runner.d.ts +1 -5
  124. package/dist/wirings/trigger/trigger-runner.js +4 -3
  125. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -6
  126. package/dist/wirings/workflow/pikku-workflow-service.js +20 -29
  127. package/dist/wirings/workflow/workflow.types.d.ts +2 -2
  128. package/package.json +2 -1
  129. package/src/crypto-utils.test.ts +116 -0
  130. package/src/errors/error.test.ts +143 -2
  131. package/src/errors/errors.ts +10 -0
  132. package/src/errors/index.ts +1 -0
  133. package/src/function/function-runner.test.ts +2 -2
  134. package/src/function/function-runner.ts +72 -49
  135. package/src/function/functions.types.ts +1 -0
  136. package/src/handle-error.test.ts +361 -0
  137. package/src/handle-error.ts +4 -4
  138. package/src/index.ts +3 -10
  139. package/src/internal.ts +6 -0
  140. package/src/middleware/auth-apikey.test.ts +1 -1
  141. package/src/middleware/auth-bearer.test.ts +1 -1
  142. package/src/middleware/auth-bearer.ts +2 -5
  143. package/src/middleware/auth-cookie.test.ts +1 -1
  144. package/src/middleware/auth-cookie.ts +3 -5
  145. package/src/middleware/cors.test.ts +424 -0
  146. package/src/middleware/cors.ts +14 -6
  147. package/src/middleware/remote-auth.test.ts +488 -0
  148. package/src/middleware-runner.test.ts +1 -1
  149. package/src/middleware-runner.ts +1 -1
  150. package/src/permissions.test.ts +2 -2
  151. package/src/permissions.ts +2 -2
  152. package/src/pikku-state.test.ts +224 -0
  153. package/src/pikku-state.ts +40 -28
  154. package/src/schema.test.ts +198 -6
  155. package/src/schema.ts +11 -7
  156. package/src/services/ai-agent-runner-service.ts +15 -3
  157. package/src/services/ai-run-state-service.ts +1 -1
  158. package/src/services/ai-storage-service.ts +1 -1
  159. package/src/services/content-service.ts +7 -0
  160. package/src/services/gopass-secrets.ts +4 -1
  161. package/src/services/in-memory-ai-run-state-service.ts +73 -0
  162. package/src/services/in-memory-trigger-service.ts +6 -10
  163. package/src/services/in-memory-workflow-service.test.ts +351 -0
  164. package/src/services/index.ts +2 -1
  165. package/src/services/local-content.ts +9 -3
  166. package/src/services/local-secrets.test.ts +80 -0
  167. package/src/services/local-secrets.ts +2 -2
  168. package/src/services/local-variables.test.ts +61 -0
  169. package/src/services/local-variables.ts +1 -1
  170. package/src/services/logger-console.test.ts +118 -0
  171. package/src/services/logger-console.ts +2 -1
  172. package/src/services/scheduler-service.ts +0 -18
  173. package/src/services/scoped-secret-service.test.ts +74 -0
  174. package/src/services/scoped-secret-service.ts +1 -1
  175. package/src/services/trigger-service.ts +0 -21
  176. package/src/services/typed-secret-service.test.ts +93 -0
  177. package/src/services/typed-variables-service.test.ts +73 -0
  178. package/src/services/user-session-service.test.ts +113 -0
  179. package/src/services/user-session-service.ts +3 -3
  180. package/src/services/workflow-service.ts +2 -12
  181. package/src/time-utils.test.ts +1 -1
  182. package/src/types/core.types.ts +25 -19
  183. package/src/types/state.types.ts +24 -15
  184. package/src/utils.test.ts +350 -0
  185. package/src/utils.ts +14 -13
  186. package/src/wirings/ai-agent/ai-agent-assistant-ui.test.ts +363 -0
  187. package/src/wirings/ai-agent/ai-agent-assistant-ui.ts +214 -0
  188. package/src/wirings/ai-agent/ai-agent-helpers.test.ts +152 -0
  189. package/src/wirings/ai-agent/ai-agent-helpers.ts +76 -0
  190. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +115 -0
  191. package/src/wirings/ai-agent/ai-agent-prepare.ts +79 -45
  192. package/src/wirings/ai-agent/ai-agent-registry.ts +1 -1
  193. package/src/wirings/ai-agent/ai-agent-runner.test.ts +245 -3
  194. package/src/wirings/ai-agent/ai-agent-runner.ts +121 -7
  195. package/src/wirings/ai-agent/ai-agent-stream.test.ts +430 -24
  196. package/src/wirings/ai-agent/ai-agent-stream.ts +377 -102
  197. package/src/wirings/ai-agent/ai-agent.types.ts +57 -2
  198. package/src/wirings/ai-agent/index.ts +11 -0
  199. package/src/wirings/channel/channel-common.ts +2 -2
  200. package/src/wirings/channel/channel-handler.ts +13 -9
  201. package/src/wirings/channel/channel-runner.ts +6 -6
  202. package/src/wirings/channel/channel-store.ts +1 -1
  203. package/src/wirings/channel/channel.types.ts +4 -8
  204. package/src/wirings/channel/local/local-channel-runner.test.ts +19 -12
  205. package/src/wirings/channel/local/local-channel-runner.ts +18 -13
  206. package/src/wirings/channel/local/local-eventhub-service.test.ts +2 -2
  207. package/src/wirings/channel/local/local-eventhub-service.ts +2 -2
  208. package/src/wirings/channel/log-channels.ts +1 -1
  209. package/src/wirings/channel/pikku-abstract-channel-handler.ts +1 -1
  210. package/src/wirings/channel/serverless/serverless-channel-runner.ts +37 -32
  211. package/src/wirings/cli/channel/cli-channel-runner.ts +1 -1
  212. package/src/wirings/cli/cli-runner.test.ts +1 -1
  213. package/src/wirings/cli/cli-runner.ts +11 -4
  214. package/src/wirings/cli/cli.types.ts +3 -3
  215. package/src/wirings/cli/command-parser.test.ts +1 -1
  216. package/src/wirings/cli/command-parser.ts +1 -1
  217. package/src/wirings/http/http-routes.test.ts +1 -1
  218. package/src/wirings/http/http-runner.test.ts +9 -17
  219. package/src/wirings/http/http-runner.ts +43 -27
  220. package/src/wirings/http/http.types.ts +1 -14
  221. package/src/wirings/http/log-http-routes.ts +1 -1
  222. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  223. package/src/wirings/http/pikku-fetch-http-response.ts +12 -5
  224. package/src/wirings/http/routers/http-router.ts +1 -1
  225. package/src/wirings/http/routers/path-to-regex.test.ts +1 -1
  226. package/src/wirings/http/routers/path-to-regex.ts +4 -3
  227. package/src/wirings/mcp/mcp-endpoint-registry.ts +5 -1
  228. package/src/wirings/mcp/mcp-runner.ts +9 -15
  229. package/src/wirings/mcp/mcp.types.ts +2 -2
  230. package/src/wirings/oauth2/oauth2-client.ts +3 -3
  231. package/src/wirings/oauth2/wire-oauth2-credential.ts +1 -1
  232. package/src/wirings/queue/index.ts +0 -1
  233. package/src/wirings/queue/queue-runner.test.ts +52 -25
  234. package/src/wirings/queue/queue-runner.ts +8 -30
  235. package/src/wirings/queue/queue.types.ts +3 -13
  236. package/src/wirings/queue/register-queue-helper.ts +3 -5
  237. package/src/wirings/queue/validate-worker-config.test.ts +108 -0
  238. package/src/wirings/queue/validate-worker-config.ts +4 -1
  239. package/src/wirings/rpc/index.ts +2 -0
  240. package/src/wirings/rpc/rpc-runner.ts +92 -49
  241. package/src/wirings/rpc/rpc-types.ts +17 -2
  242. package/src/wirings/rpc/wire-addon.ts +20 -0
  243. package/src/wirings/scheduler/index.ts +0 -1
  244. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  245. package/src/wirings/scheduler/scheduler-runner.test.ts +49 -60
  246. package/src/wirings/scheduler/scheduler-runner.ts +9 -56
  247. package/src/wirings/scheduler/scheduler.types.ts +2 -2
  248. package/src/wirings/secret/validate-secret-definitions.test.ts +140 -0
  249. package/src/wirings/trigger/pikku-trigger-service.ts +17 -39
  250. package/src/wirings/trigger/trigger-runner.test.ts +79 -0
  251. package/src/wirings/trigger/trigger-runner.ts +8 -11
  252. package/src/wirings/variable/validate-variable-definitions.test.ts +91 -0
  253. package/src/wirings/workflow/graph/graph-runner.test.ts +14 -22
  254. package/src/wirings/workflow/graph/template.test.ts +49 -0
  255. package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -27
  256. package/src/wirings/workflow/pikku-workflow-service.ts +29 -45
  257. package/src/wirings/workflow/workflow-helpers.test.ts +129 -0
  258. package/src/wirings/workflow/workflow.types.ts +2 -2
  259. package/tsconfig.tsbuildinfo +1 -1
  260. package/dist/wirings/workflow/workflow-utils.d.ts +0 -1
  261. package/dist/wirings/workflow/workflow-utils.js +0 -1
  262. package/src/wirings/workflow/workflow-utils.ts +0 -0
@@ -1,8 +1,8 @@
1
- import {
1
+ import type {
2
2
  CorePermissionGroup,
3
3
  CorePikkuPermission,
4
4
  } from '../../function/functions.types.js'
5
- import {
5
+ import type {
6
6
  CorePikkuMiddleware,
7
7
  MiddlewareMetadata,
8
8
  PermissionMetadata,
@@ -65,6 +65,7 @@ export interface AIAgentToolDef {
65
65
  description: string
66
66
  inputSchema: Record<string, unknown>
67
67
  execute: (input: unknown) => Promise<unknown>
68
+ needsApproval?: boolean
68
69
  }
69
70
 
70
71
  export interface PikkuAIMiddlewareHooks<
@@ -97,6 +98,50 @@ export interface PikkuAIMiddlewareHooks<
97
98
  ) =>
98
99
  | Promise<{ text: string; messages: AIMessage[] }>
99
100
  | { text: string; messages: AIMessage[] }
101
+
102
+ beforeToolCall?: (
103
+ services: Services,
104
+ ctx: {
105
+ toolName: string
106
+ toolCallId: string
107
+ args: Record<string, unknown>
108
+ }
109
+ ) =>
110
+ | Promise<{ args: Record<string, unknown> } | void>
111
+ | { args: Record<string, unknown> }
112
+ | void
113
+
114
+ afterToolCall?: (
115
+ services: Services,
116
+ ctx: {
117
+ toolName: string
118
+ toolCallId: string
119
+ args: Record<string, unknown>
120
+ result: unknown
121
+ durationMs: number
122
+ }
123
+ ) => Promise<{ result: unknown } | void> | { result: unknown } | void
124
+
125
+ afterStep?: (
126
+ services: Services,
127
+ ctx: {
128
+ stepNumber: number
129
+ text: string
130
+ toolCalls: { toolCallId: string; toolName: string; args: unknown }[]
131
+ toolResults: { toolCallId: string; toolName: string; result: unknown }[]
132
+ usage: { inputTokens: number; outputTokens: number }
133
+ finishReason: string
134
+ }
135
+ ) => Promise<void> | void
136
+
137
+ onError?: (
138
+ services: Services,
139
+ ctx: {
140
+ error: Error
141
+ stepNumber: number
142
+ messages: AIMessage[]
143
+ }
144
+ ) => Promise<void> | void
100
145
  }
101
146
 
102
147
  export type AIAgentMemoryConfig = {
@@ -126,6 +171,15 @@ export type CoreAIAgent<
126
171
  input?: unknown
127
172
  output?: unknown
128
173
  tags?: string[]
174
+ protocol?: 'ui-message-stream'
175
+ prepareStep?: (ctx: {
176
+ stepNumber: number
177
+ messages: AIMessage[]
178
+ tools: AIAgentToolDef[]
179
+ toolChoice: 'auto' | 'required' | 'none'
180
+ model: string
181
+ stop: () => void
182
+ }) => void | Promise<void>
129
183
  middleware?: PikkuMiddleware[]
130
184
  channelMiddleware?: CorePikkuChannelMiddleware<any, any>[]
131
185
  aiMiddleware?: PikkuAIMiddlewareHooks<any, any>[]
@@ -133,6 +187,7 @@ export type CoreAIAgent<
133
187
  }
134
188
 
135
189
  export type AIStreamEvent =
190
+ | { type: 'step-start'; stepNumber: number; agent?: string; session?: string }
136
191
  | { type: 'text-delta'; text: string; agent?: string; session?: string }
137
192
  | { type: 'reasoning-delta'; text: string; agent?: string; session?: string }
138
193
  | {
@@ -1,5 +1,15 @@
1
+ export {
2
+ agent,
3
+ agentStream,
4
+ agentResume,
5
+ agentApprove,
6
+ } from './ai-agent-helpers.js'
1
7
  export { runAIAgent } from './ai-agent-runner.js'
2
8
  export { streamAIAgent, resumeAIAgent } from './ai-agent-stream.js'
9
+ export {
10
+ createAssistantUIChannel,
11
+ parseAssistantUIInput,
12
+ } from './ai-agent-assistant-ui.js'
3
13
  export {
4
14
  type RunAIAgentParams,
5
15
  type StreamAIAgentOptions,
@@ -12,6 +22,7 @@ export {
12
22
  getAIAgentsMeta,
13
23
  } from './ai-agent-registry.js'
14
24
  export type {
25
+ AIAgentInput,
15
26
  AIAgentMeta,
16
27
  AIAgentMemoryConfig,
17
28
  AIAgentStep,
@@ -1,10 +1,10 @@
1
- import {
1
+ import type {
2
2
  CoreSingletonServices,
3
3
  CorePikkuMiddleware,
4
4
  PikkuWire,
5
5
  MiddlewareMetadata,
6
6
  } from '../../types/core.types.js'
7
- import { CoreChannel, ChannelMessageMeta } from './channel.types.js'
7
+ import type { CoreChannel, ChannelMessageMeta } from './channel.types.js'
8
8
  import { combineMiddleware, runMiddleware } from '../../middleware-runner.js'
9
9
  import { runPikkuFuncDirectly } from '../../function/function-runner.js'
10
10
  import {
@@ -1,19 +1,17 @@
1
- import {
1
+ import type {
2
2
  CoreServices,
3
3
  JSONValue,
4
4
  CoreUserSession,
5
5
  } from '../../types/core.types.js'
6
- import {
6
+ import type {
7
7
  ChannelMessageMeta,
8
8
  CoreChannel,
9
9
  PikkuChannelHandler,
10
10
  } from './channel.types.js'
11
11
  import { pikkuState } from '../../pikku-state.js'
12
12
  import { runPikkuFunc } from '../../function/function-runner.js'
13
- import {
14
- SessionService,
15
- createMiddlewareSessionWireProps,
16
- } from '../../services/user-session-service.js'
13
+ import type { SessionService } from '../../services/user-session-service.js'
14
+ import { createMiddlewareSessionWireProps } from '../../services/user-session-service.js'
17
15
 
18
16
  const getChannelMeta = (channelName: string) => {
19
17
  return pikkuState(null, 'channel', 'meta')[channelName]
@@ -81,7 +79,13 @@ export const processMessageHandlers = (
81
79
  routingProperty?: string,
82
80
  routerValue?: string
83
81
  ): Promise<unknown> => {
84
- if (!validateAuth(requiresSession, channelHandler, onMessage)) {
82
+ if (
83
+ !validateAuth(
84
+ requiresSession,
85
+ userSession?.get() as CoreUserSession | undefined,
86
+ onMessage
87
+ )
88
+ ) {
85
89
  const routeMessage = routingProperty
86
90
  ? `route '${routingProperty}:${routerValue}'`
87
91
  : 'the default message route'
@@ -159,7 +163,7 @@ export const processMessageHandlers = (
159
163
  let messageData: any
160
164
  try {
161
165
  messageData = JSON.parse(rawData)
162
- } catch (error) {
166
+ } catch {
163
167
  // Most likely a json error.. ignore
164
168
  }
165
169
 
@@ -201,7 +205,7 @@ export const processMessageHandlers = (
201
205
  logger.error(
202
206
  `No handler found for message in channel ${channelConfig.name} for ${JSON.stringify(rawData)}`
203
207
  )
204
- logger.error(`Channel ${JSON.stringify(channelConfig)}`)
208
+ logger.error(`Channel config name: ${channelConfig.name}`)
205
209
  }
206
210
 
207
211
  return result
@@ -1,12 +1,12 @@
1
1
  import { NotFoundError, PikkuMissingMetaError } from '../../errors/errors.js'
2
2
  import { addFunction } from '../../function/function-runner.js'
3
- import { CorePikkuPermission } from '../../function/functions.types.js'
4
- import { pikkuState } from '../../pikku-state.js'
3
+ import type { CorePikkuPermission } from '../../function/functions.types.js'
4
+ import { pikkuState, getSingletonServices } from '../../pikku-state.js'
5
5
  import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js'
6
- import { SessionService } from '../../services/user-session-service.js'
7
- import { CorePikkuMiddleware } from '../../types/core.types.js'
6
+ import type { SessionService } from '../../services/user-session-service.js'
7
+ import type { CorePikkuMiddleware } from '../../types/core.types.js'
8
8
  import { httpRouter } from '../http/routers/http-router.js'
9
- import {
9
+ import type {
10
10
  ChannelMeta,
11
11
  CoreChannel,
12
12
  RunChannelOptions,
@@ -122,7 +122,6 @@ const getMatchingChannelConfig = (path: string) => {
122
122
 
123
123
  export const openChannel = async ({
124
124
  route,
125
- singletonServices,
126
125
  coerceDataFromSchema = true,
127
126
  request,
128
127
  }: Pick<CoreChannel<unknown, string>, 'route'> &
@@ -133,6 +132,7 @@ export const openChannel = async ({
133
132
  channelConfig: CoreChannel<unknown, any>
134
133
  meta: ChannelMeta
135
134
  }> => {
135
+ const singletonServices = getSingletonServices()
136
136
  const matchingChannel = getMatchingChannelConfig(route)
137
137
  if (!matchingChannel) {
138
138
  singletonServices.logger.info(`Channel not found: ${route}`)
@@ -1,4 +1,4 @@
1
- import { CoreUserSession } from '../../types/core.types.js'
1
+ import type { CoreUserSession } from '../../types/core.types.js'
2
2
 
3
3
  export type Channel<ChannelType = unknown, OpeningData = unknown> = {
4
4
  channelId: string
@@ -1,12 +1,10 @@
1
- import { PikkuError } from '../../errors/error-handler.js'
2
- import {
1
+ import type { PikkuError } from '../../errors/error-handler.js'
2
+ import type {
3
3
  HTTPFunctionMetaInputTypes,
4
4
  PikkuHTTPRequest,
5
5
  PikkuHTTPResponse,
6
6
  } from '../http/http.types.js'
7
- import {
8
- CoreSingletonServices,
9
- CreateWireServices,
7
+ import type {
10
8
  CorePikkuMiddleware,
11
9
  MiddlewareMetadata,
12
10
  PermissionMetadata,
@@ -23,7 +21,7 @@ export type CorePikkuChannelMiddlewareFactory<
23
21
  Services = any,
24
22
  Event = unknown,
25
23
  > = (input: In) => CorePikkuChannelMiddleware<Services, Event>
26
- import {
24
+ import type {
27
25
  CorePermissionGroup,
28
26
  CorePikkuFunction,
29
27
  CorePikkuFunctionConfig,
@@ -41,10 +39,8 @@ export type RunChannelOptions = Partial<{
41
39
 
42
40
  export type RunChannelParams<ChannelData> = {
43
41
  channelId: string
44
- singletonServices: CoreSingletonServices
45
42
  request?: PikkuHTTPRequest<ChannelData>
46
43
  response?: PikkuHTTPResponse
47
- createWireServices?: CreateWireServices
48
44
  }
49
45
 
50
46
  export interface ChannelMessageMeta {
@@ -3,13 +3,13 @@ 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
5
  import { wireChannel } from '../channel-runner.js'
6
- import {
6
+ import type {
7
7
  HTTPMethod,
8
8
  PikkuHTTPRequest,
9
9
  PikkuHTTPResponse,
10
10
  PikkuQuery,
11
11
  } from '../../http/http.types.js'
12
- import { SerializeOptions } from 'cookie'
12
+ import type { SerializeOptions } from 'cookie'
13
13
  import { httpRouter } from '../../http/routers/http-router.js'
14
14
 
15
15
  /**
@@ -102,6 +102,10 @@ const mockCreateWireServices = async () => ({
102
102
  beforeEach(() => {
103
103
  resetPikkuState()
104
104
  httpRouter.reset()
105
+ pikkuState(null, 'package', 'singletonServices', mockSingletonServices as any)
106
+ pikkuState(null, 'package', 'factories', {
107
+ createWireServices: mockCreateWireServices,
108
+ } as any)
105
109
  })
106
110
 
107
111
  afterEach(() => {
@@ -113,11 +117,9 @@ test('runChannel should return undefined and 404 if no matching channel is found
113
117
  const mockResponse = new PikkuMockResponse()
114
118
 
115
119
  const result = await runLocalChannel({
116
- singletonServices: mockSingletonServices,
117
120
  channelId: 'test-channel-id',
118
121
  request: new PikkuMockRequest('/non-existent-channel', 'get'),
119
122
  response: mockResponse,
120
- createWireServices: mockCreateWireServices,
121
123
  })
122
124
 
123
125
  assert.equal(
@@ -131,6 +133,10 @@ test('runChannel should return undefined and 404 if no matching channel is found
131
133
 
132
134
  test('runChannel should return a channel handler if channel matches and no auth required', async () => {
133
135
  resetPikkuState()
136
+ pikkuState(null, 'package', 'singletonServices', mockSingletonServices as any)
137
+ pikkuState(null, 'package', 'factories', {
138
+ createWireServices: mockCreateWireServices,
139
+ } as any)
134
140
 
135
141
  pikkuState(null, 'channel', 'meta', {
136
142
  test: {
@@ -148,12 +154,10 @@ test('runChannel should return a channel handler if channel matches and no auth
148
154
  httpRouter.initialize()
149
155
 
150
156
  const result = await runLocalChannel({
151
- singletonServices: mockSingletonServices,
152
157
  channelId: 'test-channel-id',
153
158
  request: new PikkuMockRequest('/test-channel', 'get'),
154
159
  response: new PikkuMockResponse(),
155
160
  route: '/test-channel',
156
- createWireServices: mockCreateWireServices,
157
161
  })
158
162
 
159
163
  assert.ok(result, 'Should return a PikkuChannelHandler instance')
@@ -164,6 +168,7 @@ test('runChannel should return a channel handler if channel matches and no auth
164
168
 
165
169
  test('runChannel should close wire services once when channel closes', async () => {
166
170
  resetPikkuState()
171
+ pikkuState(null, 'package', 'singletonServices', mockSingletonServices as any)
167
172
  let closeCount = 0
168
173
 
169
174
  pikkuState(null, 'channel', 'meta', {
@@ -180,12 +185,7 @@ test('runChannel should close wire services once when channel closes', async ()
180
185
 
181
186
  httpRouter.initialize()
182
187
 
183
- const result = await runLocalChannel({
184
- singletonServices: mockSingletonServices,
185
- channelId: 'test-channel-id',
186
- request: new PikkuMockRequest('/test-channel', 'get'),
187
- response: new PikkuMockResponse(),
188
- route: '/test-channel',
188
+ pikkuState(null, 'package', 'factories', {
189
189
  createWireServices: async () => ({
190
190
  tracked: {
191
191
  close: async () => {
@@ -193,6 +193,13 @@ test('runChannel should close wire services once when channel closes', async ()
193
193
  },
194
194
  },
195
195
  }),
196
+ } as any)
197
+
198
+ const result = await runLocalChannel({
199
+ channelId: 'test-channel-id',
200
+ request: new PikkuMockRequest('/test-channel', 'get'),
201
+ response: new PikkuMockResponse(),
202
+ route: '/test-channel',
196
203
  })
197
204
 
198
205
  assert.ok(result)
@@ -2,36 +2,43 @@ import { openChannel } from '../channel-runner.js'
2
2
  import { createHTTPWire } from '../../http/http-runner.js'
3
3
  import { closeWireServices } from '../../../utils.js'
4
4
  import { processMessageHandlers } from '../channel-handler.js'
5
- import {
6
- CoreChannel,
7
- RunChannelOptions,
8
- RunChannelParams,
9
- } from '../channel.types.js'
5
+ import type { CoreChannel, RunChannelOptions } from '../channel.types.js'
10
6
  import { PikkuLocalChannelHandler } from './local-channel-handler.js'
11
- import { PikkuWire, WireServices } from '../../../types/core.types.js'
7
+ import type { PikkuWire, WireServices } from '../../../types/core.types.js'
12
8
  import { handleHTTPError } from '../../../handle-error.js'
13
9
  import {
14
10
  PikkuSessionService,
15
11
  createMiddlewareSessionWireProps,
16
12
  } from '../../../services/user-session-service.js'
17
- import { PikkuHTTP } from '../../http/http.types.js'
13
+ import type {
14
+ PikkuHTTP,
15
+ PikkuHTTPRequest,
16
+ PikkuHTTPResponse,
17
+ } from '../../http/http.types.js'
18
18
  import { runChannelLifecycleWithMiddleware } from '../channel-common.js'
19
+ import {
20
+ getSingletonServices,
21
+ getCreateWireServices,
22
+ } from '../../../pikku-state.js'
19
23
 
20
24
  export const runLocalChannel = async ({
21
- singletonServices,
22
25
  channelId,
23
26
  request,
24
27
  response,
25
28
  route,
26
- createWireServices,
27
29
  skipUserSession = false,
28
30
  respondWith404 = true,
29
31
  coerceDataFromSchema = true,
30
32
  logWarningsForStatusCodes = [],
31
33
  bubbleErrors = false,
32
34
  }: Partial<Pick<CoreChannel<unknown, any>, 'route'>> &
33
- RunChannelOptions &
34
- RunChannelParams<unknown>): Promise<PikkuLocalChannelHandler | void> => {
35
+ RunChannelOptions & {
36
+ channelId: string
37
+ request?: PikkuHTTPRequest
38
+ response?: PikkuHTTPResponse
39
+ }): Promise<PikkuLocalChannelHandler | void> => {
40
+ const singletonServices = getSingletonServices()
41
+ const createWireServices = getCreateWireServices()
35
42
  let wireServices: WireServices<typeof singletonServices> | undefined
36
43
  let closedWireServices = false
37
44
 
@@ -48,12 +55,10 @@ export const runLocalChannel = async ({
48
55
  try {
49
56
  ;({ openingData, channelConfig, meta } = await openChannel({
50
57
  channelId,
51
- createWireServices,
52
58
  respondWith404,
53
59
  request,
54
60
  response,
55
61
  route,
56
- singletonServices,
57
62
  skipUserSession,
58
63
  coerceDataFromSchema,
59
64
  userSession,
@@ -1,7 +1,7 @@
1
1
  import * as assert from 'assert'
2
2
  import { test } from 'node:test'
3
- import { PikkuChannelHandler } from '../channel.types.js'
4
- import { CoreUserSession } from '../../../types/core.types.js'
3
+ import type { PikkuChannelHandler } from '../channel.types.js'
4
+ import type { CoreUserSession } from '../../../types/core.types.js'
5
5
  import { LocalEventHubService } from './local-eventhub-service.js'
6
6
 
7
7
  class MockChannelHandler implements PikkuChannelHandler {
@@ -1,5 +1,5 @@
1
- import { PikkuChannelHandler } from '../channel.types.js'
2
- import { EventHubService } from '../eventhub-service.js'
1
+ import type { PikkuChannelHandler } from '../channel.types.js'
2
+ import type { EventHubService } from '../eventhub-service.js'
3
3
 
4
4
  /**
5
5
  * Implementation of the SubscriptionService interface.
@@ -1,5 +1,5 @@
1
1
  import { pikkuState } from '../../pikku-state.js'
2
- import { Logger } from '../../services/index.js'
2
+ import type { Logger } from '../../services/index.js'
3
3
 
4
4
  /**
5
5
  * Logs all the loaded channels.
@@ -1,4 +1,4 @@
1
- import { PikkuChannel, PikkuChannelHandler } from './channel.types.js'
1
+ import type { PikkuChannel, PikkuChannelHandler } from './channel.types.js'
2
2
 
3
3
  export abstract class PikkuAbstractChannelHandler<
4
4
  OpeningData = unknown,
@@ -1,4 +1,4 @@
1
- import { PikkuWire, WireServices } from '../../../types/core.types.js'
1
+ import type { PikkuWire, WireServices } from '../../../types/core.types.js'
2
2
  import { closeWireServices } from '../../../utils.js'
3
3
  import { processMessageHandlers } from '../channel-handler.js'
4
4
  import { openChannel } from '../channel-runner.js'
@@ -9,15 +9,19 @@ import type {
9
9
  PikkuChannelHandlerFactory,
10
10
  } from '../channel.types.js'
11
11
  import { createHTTPWire } from '../../http/http-runner.js'
12
- import { ChannelStore } from '../channel-store.js'
12
+ import type { ChannelStore } from '../channel-store.js'
13
13
  import { handleHTTPError } from '../../../handle-error.js'
14
14
  import {
15
15
  PikkuSessionService,
16
16
  createMiddlewareSessionWireProps,
17
17
  } from '../../../services/user-session-service.js'
18
- import { pikkuState } from '../../../pikku-state.js'
18
+ import {
19
+ getSingletonServices,
20
+ getCreateWireServices,
21
+ pikkuState,
22
+ } from '../../../pikku-state.js'
19
23
  import { PikkuFetchHTTPRequest } from '../../http/pikku-fetch-http-request.js'
20
- import { PikkuHTTP } from '../../http/http.types.js'
24
+ import type { PikkuHTTP } from '../../http/http.types.js'
21
25
  import { runChannelLifecycleWithMiddleware } from '../channel-common.js'
22
26
 
23
27
  export interface RunServerlessChannelParams<ChannelData>
@@ -62,13 +66,11 @@ const getVariablesForChannel = ({
62
66
  }
63
67
 
64
68
  export const runChannelConnect = async ({
65
- singletonServices,
66
69
  channelId,
67
70
  channelObject,
68
71
  request,
69
72
  response,
70
73
  route,
71
- createWireServices,
72
74
  channelStore,
73
75
  channelHandlerFactory,
74
76
  coerceDataFromSchema = true,
@@ -78,6 +80,8 @@ export const runChannelConnect = async ({
78
80
  }: Pick<CoreChannel<unknown, any>, 'route'> &
79
81
  RunChannelOptions &
80
82
  RunServerlessChannelParams<unknown>) => {
83
+ const singletonServices = getSingletonServices()
84
+ const createWireServices = getCreateWireServices()
81
85
  let wireServices: WireServices | undefined
82
86
 
83
87
  let http: PikkuHTTP | undefined
@@ -89,10 +93,8 @@ export const runChannelConnect = async ({
89
93
 
90
94
  const { channelConfig, openingData, meta } = await openChannel({
91
95
  channelId,
92
- createWireServices,
93
96
  request,
94
97
  route,
95
- singletonServices,
96
98
  coerceDataFromSchema,
97
99
  userSession,
98
100
  })
@@ -155,9 +157,12 @@ export const runChannelConnect = async ({
155
157
  }
156
158
 
157
159
  export const runChannelDisconnect = async ({
158
- singletonServices,
159
- ...params
160
+ channelId,
161
+ channelStore,
162
+ channelHandlerFactory,
160
163
  }: RunServerlessChannelParams<unknown>): Promise<void> => {
164
+ const singletonServices = getSingletonServices()
165
+ const createWireServices = getCreateWireServices()
161
166
  let wireServices: WireServices | undefined
162
167
 
163
168
  // Try to get channel from store. In serverless environments (especially with
@@ -166,35 +171,31 @@ export const runChannelDisconnect = async ({
166
171
  // there's nothing to disconnect, so we can return early.
167
172
  let channelData
168
173
  try {
169
- channelData = await params.channelStore.getChannelAndSession(
170
- params.channelId
171
- )
172
- } catch (error) {
174
+ channelData = await channelStore.getChannelAndSession(channelId)
175
+ } catch {
173
176
  singletonServices.logger.info(
174
- `Channel ${params.channelId} not found during disconnect - already cleaned up`
177
+ `Channel ${channelId} not found during disconnect - already cleaned up`
175
178
  )
176
179
  return
177
180
  }
178
181
 
179
182
  const { openingData, channelName, session } = channelData
180
183
  const { channel, channelConfig, meta } = getVariablesForChannel({
181
- ...params,
184
+ channelId,
185
+ channelHandlerFactory,
182
186
  openingData,
183
187
  channelName,
184
188
  })
185
189
 
186
- const userSession = new PikkuSessionService(
187
- params.channelStore,
188
- params.channelId
189
- )
190
+ const userSession = new PikkuSessionService(channelStore, channelId)
190
191
  userSession.setInitial(session)
191
192
  const wire: PikkuWire = {
192
193
  channel,
193
194
  ...createMiddlewareSessionWireProps(userSession),
194
195
  }
195
196
 
196
- if (!wireServices && params.createWireServices) {
197
- wireServices = await params.createWireServices(singletonServices, wire)
197
+ if (createWireServices) {
198
+ wireServices = await createWireServices(singletonServices, wire)
198
199
  }
199
200
 
200
201
  const services = {
@@ -219,38 +220,42 @@ export const runChannelDisconnect = async ({
219
220
  )
220
221
  }
221
222
  }
222
- await params.channelStore.removeChannels([channel.channelId])
223
+ await channelStore.removeChannels([channel.channelId])
223
224
  if (wireServices) {
224
225
  await closeWireServices(singletonServices.logger, wireServices)
225
226
  }
226
227
  }
227
228
 
228
229
  export const runChannelMessage = async (
229
- { singletonServices, ...params }: RunServerlessChannelParams<unknown>,
230
+ {
231
+ channelId,
232
+ channelStore,
233
+ channelHandlerFactory,
234
+ }: RunServerlessChannelParams<unknown>,
230
235
  data: unknown
231
236
  ): Promise<unknown> => {
237
+ const singletonServices = getSingletonServices()
238
+ const createWireServices = getCreateWireServices()
232
239
  let wireServices: WireServices | undefined
233
240
  const { openingData, channelName, session } =
234
- await params.channelStore.getChannelAndSession(params.channelId)
241
+ await channelStore.getChannelAndSession(channelId)
235
242
 
236
243
  const { channel, channelHandler, channelConfig } = getVariablesForChannel({
237
- ...params,
244
+ channelId,
245
+ channelHandlerFactory,
238
246
  openingData,
239
247
  channelName,
240
248
  })
241
249
 
242
- const userSession = new PikkuSessionService(
243
- params.channelStore,
244
- params.channelId
245
- )
250
+ const userSession = new PikkuSessionService(channelStore, channelId)
246
251
  userSession.setInitial(session)
247
252
  const wire: PikkuWire = {
248
253
  channel,
249
254
  ...createMiddlewareSessionWireProps(userSession),
250
255
  }
251
256
 
252
- if (params.createWireServices) {
253
- wireServices = await params.createWireServices(singletonServices, wire)
257
+ if (createWireServices) {
258
+ wireServices = await createWireServices(singletonServices, wire)
254
259
  }
255
260
 
256
261
  const services = {
@@ -1,5 +1,5 @@
1
1
  import { pikkuState } from '../../../pikku-state.js'
2
- import { CorePikkuCLIRender, type CLIMeta } from '../cli.types.js'
2
+ import type { CorePikkuCLIRender, CLIMeta } from '../cli.types.js'
3
3
  import { generateCommandHelp, parseCLIArguments } from '../command-parser.js'
4
4
 
5
5
  /**
@@ -1,7 +1,7 @@
1
1
  import { test, describe, beforeEach, afterEach } from 'node:test'
2
2
  import * as assert from 'assert'
3
3
  import { NotFoundError } from '../../errors/errors.js'
4
- import { CorePikkuMiddleware } from '../../types/core.types.js'
4
+ import type { CorePikkuMiddleware } from '../../types/core.types.js'
5
5
  import { wireCLI, runCLICommand, pikkuCLIRender } from './cli-runner.js'
6
6
  import { pikkuState, resetPikkuState } from '../../pikku-state.js'
7
7
  import { addFunction } from '../../function/function-runner.js'