@pikku/core 0.11.0 → 0.11.2

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 (184) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/dist/errors/error-handler.js +3 -3
  3. package/dist/errors/errors.d.ts +1 -1
  4. package/dist/errors/errors.js +3 -3
  5. package/dist/function/function-runner.d.ts +8 -8
  6. package/dist/function/function-runner.js +88 -23
  7. package/dist/function/functions.types.d.ts +104 -33
  8. package/dist/function/functions.types.js +50 -7
  9. package/dist/handle-error.d.ts +1 -1
  10. package/dist/handle-error.js +1 -1
  11. package/dist/index.d.ts +6 -2
  12. package/dist/index.js +5 -2
  13. package/dist/middleware/auth-apikey.d.ts +1 -1
  14. package/dist/middleware/auth-apikey.js +3 -3
  15. package/dist/middleware/auth-bearer.d.ts +1 -1
  16. package/dist/middleware/auth-bearer.js +3 -3
  17. package/dist/middleware/auth-cookie.d.ts +1 -1
  18. package/dist/middleware/auth-cookie.js +5 -5
  19. package/dist/middleware/timeout.d.ts +1 -1
  20. package/dist/middleware/timeout.js +3 -2
  21. package/dist/middleware-runner.d.ts +6 -20
  22. package/dist/middleware-runner.js +19 -20
  23. package/dist/permissions.d.ts +6 -89
  24. package/dist/permissions.js +24 -81
  25. package/dist/pikku-state.d.ts +32 -104
  26. package/dist/pikku-state.js +140 -66
  27. package/dist/schema.d.ts +8 -6
  28. package/dist/schema.js +25 -13
  29. package/dist/services/user-session-service.d.ts +7 -3
  30. package/dist/services/user-session-service.js +8 -1
  31. package/dist/services/workflow-service.d.ts +38 -0
  32. package/dist/services/workflow-service.js +1 -0
  33. package/dist/types/core.types.d.ts +40 -41
  34. package/dist/types/core.types.js +4 -15
  35. package/dist/types/state.types.d.ts +135 -0
  36. package/dist/types/state.types.js +1 -0
  37. package/dist/utils.d.ts +9 -1
  38. package/dist/utils.js +48 -3
  39. package/dist/wirings/channel/channel-common.js +2 -3
  40. package/dist/wirings/channel/channel-handler.d.ts +3 -2
  41. package/dist/wirings/channel/channel-handler.js +7 -10
  42. package/dist/wirings/channel/channel-runner.d.ts +2 -2
  43. package/dist/wirings/channel/channel-runner.js +5 -5
  44. package/dist/wirings/channel/channel.types.d.ts +10 -5
  45. package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
  46. package/dist/wirings/channel/local/local-channel-runner.js +19 -26
  47. package/dist/wirings/channel/log-channels.js +1 -1
  48. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
  49. package/dist/wirings/channel/serverless/serverless-channel-runner.js +43 -48
  50. package/dist/wirings/cli/channel/cli-channel-runner.js +3 -2
  51. package/dist/wirings/cli/cli-runner.d.ts +5 -5
  52. package/dist/wirings/cli/cli-runner.js +20 -38
  53. package/dist/wirings/cli/cli.types.d.ts +16 -11
  54. package/dist/wirings/forge-node/forge-node.types.d.ts +120 -0
  55. package/dist/wirings/forge-node/forge-node.types.js +38 -0
  56. package/dist/wirings/forge-node/index.d.ts +1 -0
  57. package/dist/wirings/forge-node/index.js +1 -0
  58. package/dist/wirings/http/http-runner.d.ts +8 -8
  59. package/dist/wirings/http/http-runner.js +46 -51
  60. package/dist/wirings/http/http.types.d.ts +19 -11
  61. package/dist/wirings/http/log-http-routes.js +1 -1
  62. package/dist/wirings/http/routers/path-to-regex.js +2 -2
  63. package/dist/wirings/mcp/mcp-runner.d.ts +2 -2
  64. package/dist/wirings/mcp/mcp-runner.js +33 -40
  65. package/dist/wirings/mcp/mcp.types.d.ts +6 -0
  66. package/dist/wirings/queue/queue-runner.d.ts +3 -3
  67. package/dist/wirings/queue/queue-runner.js +13 -23
  68. package/dist/wirings/queue/queue.types.d.ts +4 -11
  69. package/dist/wirings/rpc/index.d.ts +1 -1
  70. package/dist/wirings/rpc/index.js +1 -1
  71. package/dist/wirings/rpc/rpc-runner.d.ts +17 -16
  72. package/dist/wirings/rpc/rpc-runner.js +98 -61
  73. package/dist/wirings/rpc/rpc-types.d.ts +7 -0
  74. package/dist/wirings/scheduler/log-schedulers.js +1 -1
  75. package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -3
  76. package/dist/wirings/scheduler/scheduler-runner.js +18 -29
  77. package/dist/wirings/scheduler/scheduler.types.d.ts +3 -8
  78. package/dist/wirings/trigger/index.d.ts +2 -0
  79. package/dist/wirings/trigger/index.js +2 -0
  80. package/dist/wirings/trigger/trigger-runner.d.ts +29 -0
  81. package/dist/wirings/trigger/trigger-runner.js +57 -0
  82. package/dist/wirings/trigger/trigger.types.d.ts +42 -0
  83. package/dist/wirings/trigger/trigger.types.js +1 -0
  84. package/dist/wirings/workflow/dsl/index.d.ts +5 -0
  85. package/dist/wirings/workflow/dsl/index.js +4 -0
  86. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +286 -0
  87. package/dist/wirings/workflow/dsl/workflow-dsl.types.js +5 -0
  88. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +5 -0
  89. package/dist/wirings/workflow/dsl/workflow-runner.js +22 -0
  90. package/dist/wirings/workflow/graph/graph-node.d.ts +122 -0
  91. package/dist/wirings/workflow/graph/graph-node.js +58 -0
  92. package/dist/wirings/workflow/graph/graph-runner.d.ts +35 -0
  93. package/dist/wirings/workflow/graph/graph-runner.js +452 -0
  94. package/dist/wirings/workflow/graph/index.d.ts +3 -0
  95. package/dist/wirings/workflow/graph/index.js +3 -0
  96. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +95 -0
  97. package/dist/wirings/workflow/graph/workflow-graph.types.js +15 -0
  98. package/dist/wirings/workflow/index.d.ts +7 -3
  99. package/dist/wirings/workflow/index.js +6 -3
  100. package/dist/wirings/workflow/pikku-workflow-service.d.ts +108 -10
  101. package/dist/wirings/workflow/pikku-workflow-service.js +274 -165
  102. package/dist/wirings/workflow/wire-workflow.d.ts +42 -0
  103. package/dist/wirings/workflow/wire-workflow.js +53 -0
  104. package/dist/wirings/workflow/workflow-utils.d.ts +23 -0
  105. package/dist/wirings/workflow/workflow-utils.js +66 -0
  106. package/dist/wirings/workflow/workflow.types.d.ts +135 -128
  107. package/package.json +11 -2
  108. package/src/errors/error-handler.ts +3 -3
  109. package/src/errors/errors.ts +3 -3
  110. package/src/factory-functions.test.ts +9 -36
  111. package/src/function/function-runner.test.ts +58 -69
  112. package/src/function/function-runner.ts +130 -37
  113. package/src/function/functions.types.ts +193 -54
  114. package/src/handle-error.ts +1 -1
  115. package/src/index.ts +10 -5
  116. package/src/middleware/auth-apikey.test.ts +360 -0
  117. package/src/middleware/auth-apikey.ts +3 -7
  118. package/src/middleware/auth-bearer.test.ts +447 -0
  119. package/src/middleware/auth-bearer.ts +27 -33
  120. package/src/middleware/auth-cookie.test.ts +525 -0
  121. package/src/middleware/auth-cookie.ts +6 -6
  122. package/src/middleware/timeout.ts +4 -2
  123. package/src/middleware-runner.test.ts +58 -127
  124. package/src/middleware-runner.ts +29 -25
  125. package/src/permissions.test.ts +68 -130
  126. package/src/permissions.ts +41 -100
  127. package/src/pikku-state.ts +156 -201
  128. package/src/schema.ts +42 -13
  129. package/src/services/user-session-service.ts +14 -4
  130. package/src/services/workflow-service.ts +74 -0
  131. package/src/types/core.types.ts +79 -58
  132. package/src/types/state.types.ts +195 -0
  133. package/src/utils.ts +59 -4
  134. package/src/wirings/channel/channel-common.ts +4 -7
  135. package/src/wirings/channel/channel-handler.ts +17 -23
  136. package/src/wirings/channel/channel-runner.ts +7 -7
  137. package/src/wirings/channel/channel.types.ts +14 -11
  138. package/src/wirings/channel/local/local-channel-runner.test.ts +8 -4
  139. package/src/wirings/channel/local/local-channel-runner.ts +23 -38
  140. package/src/wirings/channel/log-channels.ts +1 -1
  141. package/src/wirings/channel/serverless/serverless-channel-runner.ts +53 -79
  142. package/src/wirings/cli/channel/cli-channel-runner.ts +4 -3
  143. package/src/wirings/cli/cli-runner.test.ts +26 -26
  144. package/src/wirings/cli/cli-runner.ts +34 -71
  145. package/src/wirings/cli/cli.types.ts +23 -16
  146. package/src/wirings/forge-node/forge-node.types.ts +135 -0
  147. package/src/wirings/forge-node/index.ts +1 -0
  148. package/src/wirings/http/http-runner.test.ts +10 -10
  149. package/src/wirings/http/http-runner.ts +56 -66
  150. package/src/wirings/http/http.types.ts +19 -14
  151. package/src/wirings/http/log-http-routes.ts +1 -1
  152. package/src/wirings/http/routers/path-to-regex.test.ts +30 -19
  153. package/src/wirings/http/routers/path-to-regex.ts +2 -2
  154. package/src/wirings/mcp/mcp-runner.ts +44 -69
  155. package/src/wirings/mcp/mcp.types.ts +6 -0
  156. package/src/wirings/queue/queue-runner.test.ts +641 -0
  157. package/src/wirings/queue/queue-runner.ts +16 -38
  158. package/src/wirings/queue/queue.types.ts +4 -11
  159. package/src/wirings/rpc/index.ts +1 -1
  160. package/src/wirings/rpc/rpc-runner.ts +129 -77
  161. package/src/wirings/rpc/rpc-types.ts +8 -0
  162. package/src/wirings/scheduler/log-schedulers.ts +1 -1
  163. package/src/wirings/scheduler/scheduler-runner.test.ts +627 -0
  164. package/src/wirings/scheduler/scheduler-runner.ts +29 -55
  165. package/src/wirings/scheduler/scheduler.types.ts +3 -9
  166. package/src/wirings/trigger/index.ts +2 -0
  167. package/src/wirings/trigger/trigger-runner.ts +96 -0
  168. package/src/wirings/trigger/trigger.types.ts +56 -0
  169. package/src/wirings/workflow/dsl/index.ts +30 -0
  170. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +312 -0
  171. package/src/wirings/workflow/dsl/workflow-runner.ts +27 -0
  172. package/src/wirings/workflow/graph/graph-node.ts +227 -0
  173. package/src/wirings/workflow/graph/graph-runner.ts +694 -0
  174. package/src/wirings/workflow/graph/index.ts +3 -0
  175. package/src/wirings/workflow/graph/workflow-graph.types.ts +126 -0
  176. package/src/wirings/workflow/index.ts +60 -12
  177. package/src/wirings/workflow/pikku-workflow-service.ts +401 -195
  178. package/src/wirings/workflow/wire-workflow.ts +94 -0
  179. package/src/wirings/workflow/workflow-utils.ts +120 -0
  180. package/src/wirings/workflow/workflow.types.ts +167 -188
  181. package/tsconfig.tsbuildinfo +1 -1
  182. package/dist/wirings/workflow/workflow-runner.d.ts +0 -35
  183. package/dist/wirings/workflow/workflow-runner.js +0 -68
  184. package/src/wirings/workflow/workflow-runner.ts +0 -85
@@ -1,27 +1,21 @@
1
1
  import type { Logger, LogLevel } from '../services/logger.js';
2
2
  import { VariablesService } from '../services/variables-service.js';
3
+ import { SecretService } from '../services/secret-service.js';
3
4
  import { SchemaService } from '../services/schema-service.js';
4
5
  import { JWTService } from '../services/jwt-service.js';
5
6
  import { PikkuHTTP } from '../wirings/http/http.types.js';
6
- import { UserSessionService } from '../services/user-session-service.js';
7
+ import { SessionService } from '../services/user-session-service.js';
7
8
  import { PikkuChannel } from '../wirings/channel/channel.types.js';
8
9
  import { PikkuRPC } from '../wirings/rpc/rpc-types.js';
9
10
  import { PikkuMCP } from '../wirings/mcp/mcp.types.js';
10
11
  import { PikkuScheduledTask } from '../wirings/scheduler/scheduler.types.js';
11
12
  import { PikkuQueue, QueueService } from '../wirings/queue/queue.types.js';
12
13
  import { PikkuCLI } from '../wirings/cli/cli.types.js';
13
- import { PikkuWorkflowInteraction, WorkflowService, WorkflowServiceConfig, WorkflowStepInteraction } from '../wirings/workflow/workflow.types.js';
14
+ import { PikkuWorkflowWire, WorkflowService, WorkflowServiceConfig, WorkflowStepWire } from '../wirings/workflow/workflow.types.js';
15
+ import type { PikkuGraphWire } from '../wirings/workflow/graph/workflow-graph.types.js';
16
+ import { PikkuTrigger } from '../wirings/trigger/trigger.types.js';
14
17
  import { SchedulerService } from '../services/scheduler-service.js';
15
- export declare enum PikkuWiringTypes {
16
- http = "http",
17
- scheduler = "scheduler",
18
- channel = "channel",
19
- rpc = "rpc",
20
- queue = "queue",
21
- mcp = "mcp",
22
- cli = "cli",
23
- workflow = "workflow"
24
- }
18
+ export type PikkuWiringTypes = 'http' | 'scheduler' | 'channel' | 'rpc' | 'queue' | 'mcp' | 'cli' | 'workflow';
25
19
  export interface FunctionServicesMeta {
26
20
  optimized: boolean;
27
21
  services: string[];
@@ -70,14 +64,13 @@ export type FunctionRuntimeMeta = {
70
64
  export type FunctionMeta = FunctionRuntimeMeta & Partial<{
71
65
  name: string;
72
66
  services: FunctionServicesMeta;
67
+ usedWires: string[];
73
68
  inputs: string[] | null;
74
69
  outputs: string[] | null;
75
- tags: string[];
76
- docs: PikkuDocs;
77
- isDirectFunction: boolean;
78
70
  middleware: MiddlewareMetadata[];
79
71
  permissions: PermissionMetadata[];
80
- }>;
72
+ isDirectFunction: boolean;
73
+ } & CommonWireMeta>;
81
74
  export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>;
82
75
  export type FunctionsMeta = Record<string, FunctionMeta>;
83
76
  export type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
@@ -134,6 +127,8 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
134
127
  logger: Logger;
135
128
  /** The variable service to be used */
136
129
  variables: VariablesService;
130
+ /** The secrets service to retrieve secrets */
131
+ secrets: SecretService;
137
132
  /** The workflow orchestrator service */
138
133
  workflowService?: WorkflowService;
139
134
  /** The queue service */
@@ -142,25 +137,27 @@ export interface CoreSingletonServices<Config extends CoreConfig = CoreConfig> {
142
137
  schedulerService?: SchedulerService;
143
138
  }
144
139
  /**
145
- * Represents different forms of interaction within Pikku and the outside world.
140
+ * Represents different forms of wire within Pikku and the outside world.
146
141
  */
147
- export type PikkuInteraction<In = unknown, Out = unknown> = Partial<{
142
+ export type PikkuWire<In = unknown, Out = unknown, HasInitialSession extends boolean = false, UserSession extends CoreUserSession = CoreUserSession, TypedRPC extends PikkuRPC = PikkuRPC, IsChannel extends true | null = null, MCPTools extends string | never = never, TypedWorkflow extends PikkuWorkflowWire | never = PikkuWorkflowWire, TriggerOutput = unknown> = Partial<{
148
143
  http: PikkuHTTP<In>;
149
- mcp: PikkuMCP;
150
- rpc: PikkuRPC;
151
- channel: PikkuChannel<unknown, Out>;
144
+ mcp: PikkuMCP<MCPTools>;
145
+ rpc: TypedRPC;
146
+ channel: [IsChannel] extends [null] ? PikkuChannel<unknown, Out> : PikkuChannel<unknown, Out> | undefined;
152
147
  scheduledTask: PikkuScheduledTask;
153
148
  queue: PikkuQueue;
154
149
  cli: PikkuCLI;
155
- workflow: PikkuWorkflowInteraction;
156
- workflowStep: WorkflowStepInteraction;
150
+ workflow: TypedWorkflow;
151
+ workflowStep: WorkflowStepWire;
152
+ graph: PikkuGraphWire;
153
+ trigger: PikkuTrigger<TriggerOutput>;
154
+ initialSession: HasInitialSession extends true ? UserSession : UserSession | undefined;
155
+ session: SessionService<UserSession>;
157
156
  }>;
158
157
  /**
159
- * A function that can wrap an interaction and be called before or after
158
+ * A function that can wrap an wire and be called before or after
160
159
  */
161
- export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices & {
162
- userSession: UserSessionService<UserSession>;
163
- }, interactions: PikkuInteraction, next: () => Promise<void>) => Promise<void>;
160
+ export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wires: PikkuWire<unknown, unknown, false, UserSession>, next: () => Promise<void>) => Promise<void>;
164
161
  /**
165
162
  * Configuration object for creating middleware with metadata
166
163
  *
@@ -170,8 +167,8 @@ export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices
170
167
  export type CorePikkuMiddlewareConfig<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = {
171
168
  /** The middleware function */
172
169
  func: CorePikkuMiddleware<SingletonServices, UserSession>;
173
- /** Optional human-readable name for the middleware */
174
- name?: string;
170
+ /** Optional human-readable title for the middleware */
171
+ title?: string;
175
172
  /** Optional description of what the middleware does */
176
173
  description?: string;
177
174
  };
@@ -193,7 +190,7 @@ export type CorePikkuMiddlewareGroup<SingletonServices extends CoreSingletonServ
193
190
  * ```typescript
194
191
  * // Direct function syntax
195
192
  * export const logMiddleware = pikkuMiddleware(
196
- * async ({ logger }, _interaction, next) => {
193
+ * async ({ logger }, next) => {
197
194
  * logger.info('Request started')
198
195
  * await next()
199
196
  * }
@@ -201,9 +198,9 @@ export type CorePikkuMiddlewareGroup<SingletonServices extends CoreSingletonServ
201
198
  *
202
199
  * // Configuration object syntax with metadata
203
200
  * export const logMiddleware = pikkuMiddleware({
204
- * name: 'Request Logger',
201
+ * title: 'Request Logger',
205
202
  * description: 'Logs request information',
206
- * func: async ({ logger }, _interaction, next) => {
203
+ * func: async ({ logger }, next) => {
207
204
  * logger.info('Request started')
208
205
  * await next()
209
206
  * }
@@ -221,7 +218,7 @@ export declare const pikkuMiddleware: <SingletonServices extends CoreSingletonSe
221
218
  * message,
222
219
  * level = 'info'
223
220
  * }) => {
224
- * return pikkuMiddleware(async ({ logger }, _interaction, next) => {
221
+ * return pikkuMiddleware(async ({ logger }, next) => {
225
222
  * logger[level](message)
226
223
  * await next()
227
224
  * })
@@ -230,12 +227,10 @@ export declare const pikkuMiddleware: <SingletonServices extends CoreSingletonSe
230
227
  */
231
228
  export declare const pikkuMiddlewareFactory: <In = any>(factory: CorePikkuMiddlewareFactory<In>) => CorePikkuMiddlewareFactory<In>;
232
229
  /**
233
- * Represents the core services used by Pikku, including singleton services and the request/response interaction.
230
+ * Represents the core services used by Pikku, including singleton services.
234
231
  */
235
- export type CoreServices<SingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = SingletonServices & PikkuInteraction & {
236
- userSession?: UserSessionService<UserSession>;
237
- };
238
- export type SessionServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services = CoreServices<SingletonServices>> = Omit<Services, keyof SingletonServices | keyof PikkuInteraction | 'session'>;
232
+ export type CoreServices<SingletonServices = CoreSingletonServices> = SingletonServices;
233
+ export type WireServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services = CoreServices<SingletonServices>> = Omit<Services, keyof SingletonServices | 'session'>;
239
234
  /**
240
235
  * Defines a function type for creating singleton services from the given configuration.
241
236
  */
@@ -243,7 +238,7 @@ export type CreateSingletonServices<Config extends CoreConfig, SingletonServices
243
238
  /**
244
239
  * Defines a function type for creating session-specific services.
245
240
  */
246
- export type CreateSessionServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services extends CoreServices<SingletonServices> = CoreServices<SingletonServices>, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, interaction: PikkuInteraction, session: UserSession | undefined) => Promise<SessionServices<Services, SingletonServices>>;
241
+ export type CreateWireServices<SingletonServices extends CoreSingletonServices = CoreSingletonServices, Services extends CoreServices<SingletonServices> = CoreServices<SingletonServices>, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wire: PikkuWire<unknown, unknown, false, UserSession>) => Promise<WireServices<Services, SingletonServices>>;
247
242
  /**
248
243
  * Defines a function type for creating config.
249
244
  */
@@ -251,11 +246,15 @@ export type CreateConfig<Config extends CoreConfig, RemainingArgs extends any[]
251
246
  /**
252
247
  * Represents the documentation for a route, including summary, description, tags, and errors.
253
248
  */
254
- export type PikkuDocs = {
249
+ export type CommonWireMeta = {
250
+ pikkuFuncName: string;
251
+ title?: string;
252
+ tags?: string[];
255
253
  summary?: string;
256
254
  description?: string;
257
- tags?: string[];
258
255
  errors?: string[];
256
+ middleware?: MiddlewareMetadata[];
257
+ permissions?: PermissionMetadata[];
259
258
  };
260
259
  /**
261
260
  * Serialized error for storage
@@ -1,14 +1,3 @@
1
- export var PikkuWiringTypes;
2
- (function (PikkuWiringTypes) {
3
- PikkuWiringTypes["http"] = "http";
4
- PikkuWiringTypes["scheduler"] = "scheduler";
5
- PikkuWiringTypes["channel"] = "channel";
6
- PikkuWiringTypes["rpc"] = "rpc";
7
- PikkuWiringTypes["queue"] = "queue";
8
- PikkuWiringTypes["mcp"] = "mcp";
9
- PikkuWiringTypes["cli"] = "cli";
10
- PikkuWiringTypes["workflow"] = "workflow";
11
- })(PikkuWiringTypes || (PikkuWiringTypes = {}));
12
1
  /**
13
2
  * Factory function for creating middleware with tree-shaking support
14
3
  * Supports both direct function and configuration object syntax
@@ -17,7 +6,7 @@ export var PikkuWiringTypes;
17
6
  * ```typescript
18
7
  * // Direct function syntax
19
8
  * export const logMiddleware = pikkuMiddleware(
20
- * async ({ logger }, _interaction, next) => {
9
+ * async ({ logger }, next) => {
21
10
  * logger.info('Request started')
22
11
  * await next()
23
12
  * }
@@ -25,9 +14,9 @@ export var PikkuWiringTypes;
25
14
  *
26
15
  * // Configuration object syntax with metadata
27
16
  * export const logMiddleware = pikkuMiddleware({
28
- * name: 'Request Logger',
17
+ * title: 'Request Logger',
29
18
  * description: 'Logs request information',
30
- * func: async ({ logger }, _interaction, next) => {
19
+ * func: async ({ logger }, next) => {
31
20
  * logger.info('Request started')
32
21
  * await next()
33
22
  * }
@@ -47,7 +36,7 @@ export const pikkuMiddleware = (middleware) => {
47
36
  * message,
48
37
  * level = 'info'
49
38
  * }) => {
50
- * return pikkuMiddleware(async ({ logger }, _interaction, next) => {
39
+ * return pikkuMiddleware(async ({ logger }, next) => {
51
40
  * logger[level](message)
52
41
  * await next()
53
42
  * })
@@ -0,0 +1,135 @@
1
+ import { PikkuError, ErrorDetails } from '../errors/error-handler.js';
2
+ import { CorePikkuFunctionConfig, CorePermissionGroup, CorePikkuPermission } from '../function/functions.types.js';
3
+ import { CoreChannel, ChannelsMeta } from '../wirings/channel/channel.types.js';
4
+ import { CLIMeta, CLIProgramState } from '../wirings/cli/cli.types.js';
5
+ import { HTTPMethod, CoreHTTPFunctionWiring, HTTPWiringsMeta } from '../wirings/http/http.types.js';
6
+ import { CoreMCPResource, MCPResourceMeta, CoreMCPTool, MCPToolMeta, CoreMCPPrompt, MCPPromptMeta } from '../wirings/mcp/mcp.types.js';
7
+ import { CoreQueueWorker, QueueWorkersMeta } from '../wirings/queue/queue.types.js';
8
+ import { CoreScheduledTask, ScheduledTasksMeta } from '../wirings/scheduler/scheduler.types.js';
9
+ import { CoreWorkflow, WorkflowsRuntimeMeta, WorkflowWires } from '../wirings/workflow/workflow.types.js';
10
+ import type { WorkflowGraphDefinition, GraphNodeConfig } from '../wirings/workflow/graph/workflow-graph.types.js';
11
+ import { CoreTrigger, TriggerMeta } from '../wirings/trigger/trigger.types.js';
12
+ import { FunctionsMeta, CorePikkuMiddleware, CorePikkuMiddlewareGroup, FunctionServicesMeta, CreateConfig, CreateSingletonServices, CreateWireServices, CoreConfig, CoreSingletonServices, CoreServices, CoreUserSession } from './core.types.js';
13
+ /**
14
+ * State structure for an individual package
15
+ */
16
+ export interface PikkuPackageState {
17
+ function: {
18
+ meta: FunctionsMeta;
19
+ functions: Map<string, CorePikkuFunctionConfig<any, any>>;
20
+ };
21
+ rpc: {
22
+ meta: Record<string, string>;
23
+ files: Map<string, {
24
+ exportedName: string;
25
+ path: string;
26
+ }>;
27
+ /** Maps namespace aliases to package names (e.g., 'ext' -> '@pikku/templates-function-external') */
28
+ externalPackages: Map<string, string>;
29
+ };
30
+ http: {
31
+ middleware: Map<string, CorePikkuMiddleware<any, any>[]>;
32
+ permissions: Map<string, CorePermissionGroup | CorePikkuPermission[]>;
33
+ routes: Map<HTTPMethod, Map<string, CoreHTTPFunctionWiring<any, any, any>>>;
34
+ meta: HTTPWiringsMeta;
35
+ };
36
+ channel: {
37
+ channels: Map<string, CoreChannel<any, any>>;
38
+ meta: ChannelsMeta;
39
+ };
40
+ scheduler: {
41
+ tasks: Map<string, CoreScheduledTask>;
42
+ meta: ScheduledTasksMeta;
43
+ };
44
+ queue: {
45
+ registrations: Map<string, CoreQueueWorker>;
46
+ meta: QueueWorkersMeta;
47
+ };
48
+ workflows: {
49
+ registrations: Map<string, CoreWorkflow>;
50
+ graphRegistrations: Map<string, WorkflowGraphDefinition<any>>;
51
+ /** DSL workflow wirings (from wireWorkflow({ func: ... })) */
52
+ wirings: Map<any, {
53
+ wires: WorkflowWires;
54
+ func: any;
55
+ }>;
56
+ /** Graph workflow wirings (from wireWorkflow({ graph: ... })) */
57
+ graphWirings: Map<any, {
58
+ wires: WorkflowWires;
59
+ graph: Record<string, GraphNodeConfig<string>>;
60
+ }>;
61
+ meta: WorkflowsRuntimeMeta;
62
+ };
63
+ trigger: {
64
+ triggers: Map<string, CoreTrigger>;
65
+ meta: TriggerMeta;
66
+ };
67
+ mcp: {
68
+ resources: Map<string, CoreMCPResource>;
69
+ resourcesMeta: MCPResourceMeta;
70
+ tools: Map<string, CoreMCPTool>;
71
+ toolsMeta: MCPToolMeta;
72
+ prompts: Map<string, CoreMCPPrompt>;
73
+ promptsMeta: MCPPromptMeta;
74
+ };
75
+ cli: {
76
+ meta: CLIMeta | Record<string, any>;
77
+ programs: Record<string, CLIProgramState>;
78
+ };
79
+ middleware: {
80
+ tagGroup: Record<string, CorePikkuMiddlewareGroup>;
81
+ httpGroup: Record<string, CorePikkuMiddlewareGroup>;
82
+ tagGroupMeta: Record<string, {
83
+ exportName: string | null;
84
+ sourceFile: string;
85
+ position: number;
86
+ services: FunctionServicesMeta;
87
+ middlewareCount: number;
88
+ isFactory: boolean;
89
+ }>;
90
+ httpGroupMeta: Record<string, {
91
+ exportName: string | null;
92
+ sourceFile: string;
93
+ position: number;
94
+ services: FunctionServicesMeta;
95
+ middlewareCount: number;
96
+ isFactory: boolean;
97
+ }>;
98
+ };
99
+ permissions: {
100
+ tagGroup: Record<string, CorePermissionGroup | CorePikkuPermission[]>;
101
+ httpGroup: Record<string, CorePermissionGroup | CorePikkuPermission[]>;
102
+ tagGroupMeta: Record<string, {
103
+ exportName: string | null;
104
+ sourceFile: string;
105
+ position: number;
106
+ services: FunctionServicesMeta;
107
+ permissionCount: number;
108
+ isFactory: boolean;
109
+ }>;
110
+ httpGroupMeta: Record<string, {
111
+ exportName: string | null;
112
+ sourceFile: string;
113
+ position: number;
114
+ services: FunctionServicesMeta;
115
+ permissionCount: number;
116
+ isFactory: boolean;
117
+ }>;
118
+ };
119
+ misc: {
120
+ errors: Map<PikkuError, ErrorDetails>;
121
+ schemas: Map<string, any>;
122
+ middleware: Record<string, CorePikkuMiddleware[]>;
123
+ permissions: Record<string, CorePermissionGroup | CorePikkuPermission[]>;
124
+ };
125
+ package: {
126
+ /** Service factory functions for external packages */
127
+ factories: {
128
+ createConfig?: CreateConfig<CoreConfig>;
129
+ createSingletonServices?: CreateSingletonServices<CoreConfig, CoreSingletonServices>;
130
+ createWireServices?: CreateWireServices<CoreSingletonServices, CoreServices, CoreUserSession>;
131
+ } | null;
132
+ /** Cached singleton services for this package */
133
+ singletonServices: CoreSingletonServices | null;
134
+ };
135
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,13 @@
1
1
  import { Logger } from './services/logger.js';
2
- export declare const closeSessionServices: (logger: Logger, sessionServices: Record<string, any>) => Promise<void>;
2
+ import { CoreSingletonServices } from './types/core.types.js';
3
+ export declare const closeWireServices: (logger: Logger, wireServices: Record<string, any>) => Promise<void>;
3
4
  export declare const createWeakUID: () => string;
4
5
  export declare const isSerializable: (data: any) => boolean;
5
6
  export declare const freezeDedupe: <T>(arr?: readonly T[] | T[] | undefined) => readonly T[];
7
+ /**
8
+ * Stop all singleton services, including external package services.
9
+ * External package services are stopped first, then the parent services.
10
+ *
11
+ * @param singletonServices - The parent singleton services to stop
12
+ */
13
+ export declare const stopSingletonServices: (singletonServices: CoreSingletonServices) => Promise<void>;
package/dist/utils.js CHANGED
@@ -1,8 +1,8 @@
1
- // TODO: SessionServices probably needs it's own type
1
+ // TODO: WireServices probably needs it's own type
2
2
  // but is an issue for the future and will be tackled
3
3
  // with dependency injection
4
- export const closeSessionServices = async (logger, sessionServices) => {
5
- await Promise.all(Object.values(sessionServices).map(async (service) => {
4
+ export const closeWireServices = async (logger, wireServices) => {
5
+ await Promise.all(Object.values(wireServices).map(async (service) => {
6
6
  if (service?.close) {
7
7
  try {
8
8
  await service.close();
@@ -45,3 +45,48 @@ export const freezeDedupe = (arr) => {
45
45
  }
46
46
  return Object.freeze(out);
47
47
  };
48
+ /**
49
+ * Stop a single service by calling its stop method if it exists
50
+ */
51
+ const stopService = async (logger, name, service) => {
52
+ const stop = service?.stop;
53
+ if (stop) {
54
+ logger.info(`Stopping singleton service: ${name}`);
55
+ try {
56
+ await stop.call(service);
57
+ }
58
+ catch (e) {
59
+ logger.error(`Error stopping service ${name}:`, e);
60
+ }
61
+ }
62
+ };
63
+ /**
64
+ * Stop all singleton services, including external package services.
65
+ * External package services are stopped first, then the parent services.
66
+ *
67
+ * @param singletonServices - The parent singleton services to stop
68
+ */
69
+ export const stopSingletonServices = async (singletonServices) => {
70
+ const logger = singletonServices.logger;
71
+ // First, stop all external package singleton services
72
+ if (globalThis.pikkuState) {
73
+ for (const [packageName, packageState] of globalThis.pikkuState) {
74
+ // Skip main package - we handle it separately
75
+ if (packageName === '__main__')
76
+ continue;
77
+ const packageServices = packageState.package?.singletonServices;
78
+ if (packageServices) {
79
+ logger.info(`Stopping singleton services for package: ${packageName}`);
80
+ for (const [name, service] of Object.entries(packageServices)) {
81
+ await stopService(logger, `${packageName}/${name}`, service);
82
+ }
83
+ // Clear the cached services
84
+ packageState.package.singletonServices = null;
85
+ }
86
+ }
87
+ }
88
+ // Then stop the parent singleton services
89
+ for (const [name, service] of Object.entries(singletonServices)) {
90
+ await stopService(logger, name, service);
91
+ }
92
+ };
@@ -1,4 +1,3 @@
1
- import { PikkuWiringTypes, } from '../../types/core.types.js';
2
1
  import { combineMiddleware, runMiddleware } from '../../middleware-runner.js';
3
2
  import { runPikkuFuncDirectly } from '../../function/function-runner.js';
4
3
  /**
@@ -24,13 +23,13 @@ export const runChannelLifecycleWithMiddleware = async ({ channelConfig, meta, l
24
23
  ? lifecycleConfig.middleware || []
25
24
  : [];
26
25
  // Use combineMiddleware to properly resolve metadata + inline middleware
27
- const allMiddleware = combineMiddleware(PikkuWiringTypes.channel, `${channelConfig.name}:${lifecycleType}`, {
26
+ const allMiddleware = combineMiddleware('channel', `${channelConfig.name}:${lifecycleType}`, {
28
27
  wireInheritedMiddleware: meta.middleware,
29
28
  wireMiddleware: lifecycleMiddleware,
30
29
  });
31
30
  // Run the lifecycle function
32
31
  const runLifecycle = async () => {
33
- return await runPikkuFuncDirectly(meta.pikkuFuncName, { ...services, channel }, data);
32
+ return await runPikkuFuncDirectly(meta.pikkuFuncName, services, { channel }, data);
34
33
  };
35
34
  // Run with middleware if any
36
35
  if (allMiddleware.length > 0) {
@@ -1,3 +1,4 @@
1
- import { CoreServices } from '../../types/core.types.js';
1
+ import { CoreServices, CoreUserSession } from '../../types/core.types.js';
2
2
  import { CoreChannel, PikkuChannelHandler } from './channel.types.js';
3
- export declare const processMessageHandlers: (services: CoreServices, channelConfig: CoreChannel<any, any>, channelHandler: PikkuChannelHandler) => (rawData: any) => Promise<unknown>;
3
+ import { SessionService } from '../../services/user-session-service.js';
4
+ export declare const processMessageHandlers: (services: CoreServices, channelConfig: CoreChannel<any, any>, channelHandler: PikkuChannelHandler, userSession?: SessionService<CoreUserSession>) => (rawData: any) => Promise<unknown>;
@@ -1,8 +1,7 @@
1
- import { PikkuWiringTypes, } from '../../types/core.types.js';
2
1
  import { pikkuState } from '../../pikku-state.js';
3
2
  import { runPikkuFunc } from '../../function/function-runner.js';
4
3
  const getRouteMeta = (channelName, routingProperty, routerValue) => {
5
- const channelMeta = pikkuState('channel', 'meta')[channelName];
4
+ const channelMeta = pikkuState(null, 'channel', 'meta')[channelName];
6
5
  if (!channelMeta) {
7
6
  throw new Error(`Channel ${channelName} not found`);
8
7
  }
@@ -32,7 +31,7 @@ const validateAuth = (requiresSession, session, onMessage) => {
32
31
  }
33
32
  return true;
34
33
  };
35
- export const processMessageHandlers = (services, channelConfig, channelHandler) => {
34
+ export const processMessageHandlers = (services, channelConfig, channelHandler, userSession) => {
36
35
  const logger = services.logger;
37
36
  const requiresSession = channelConfig.auth !== false;
38
37
  const processMessage = async (data, onMessage, routingProperty, routerValue) => {
@@ -69,20 +68,18 @@ export const processMessageHandlers = (services, channelConfig, channelHandler)
69
68
  const cacheKey = routingProperty
70
69
  ? `${channelConfig.name}:${routingProperty}:${routerValue}`
71
70
  : `${channelConfig.name}:default`;
72
- return await runPikkuFunc(PikkuWiringTypes.channel, cacheKey, pikkuFuncName, {
71
+ return await runPikkuFunc('channel', cacheKey, pikkuFuncName, {
73
72
  singletonServices: services,
74
- getAllServices: () => ({
75
- ...services,
76
- channel: channelHandler.getChannel(),
77
- }),
78
73
  data: () => data,
79
- userSession: services.userSession,
80
74
  inheritedMiddleware,
81
75
  wireMiddleware,
82
76
  inheritedPermissions,
83
77
  wirePermissions,
84
78
  tags: channelConfig.tags,
85
- interaction: { channel: channelHandler.getChannel() },
79
+ wire: {
80
+ channel: channelHandler.getChannel(),
81
+ session: userSession,
82
+ },
86
83
  });
87
84
  };
88
85
  return async (rawData) => {
@@ -1,5 +1,5 @@
1
1
  import { CorePikkuPermission } from '../../function/functions.types.js';
2
- import { UserSessionService } from '../../services/user-session-service.js';
2
+ import { SessionService } from '../../services/user-session-service.js';
3
3
  import { CorePikkuMiddleware } from '../../types/core.types.js';
4
4
  import { ChannelMeta, CoreChannel, RunChannelOptions, RunChannelParams } from './channel.types.js';
5
5
  /**
@@ -8,7 +8,7 @@ import { ChannelMeta, CoreChannel, RunChannelOptions, RunChannelParams } from '.
8
8
  */
9
9
  export declare const wireChannel: <In, Channel extends string, PikkuPermission extends CorePikkuPermission<In>, PikkuMiddleware extends CorePikkuMiddleware, ChannelFunction>(channel: CoreChannel<In, Channel, PikkuPermission, PikkuMiddleware, ChannelFunction>) => void;
10
10
  export declare const openChannel: ({ route, singletonServices, coerceDataFromSchema, request, }: Pick<CoreChannel<unknown, string>, "route"> & RunChannelParams<unknown> & {
11
- userSession: UserSessionService<any>;
11
+ userSession: SessionService<any>;
12
12
  } & RunChannelOptions) => Promise<{
13
13
  openingData: unknown;
14
14
  channelConfig: CoreChannel<unknown, any>;
@@ -9,12 +9,12 @@ import { httpRouter } from '../http/routers/http-router.js';
9
9
  */
10
10
  export const wireChannel = (channel) => {
11
11
  // Get the channel metadata
12
- const channelsMeta = pikkuState('channel', 'meta');
12
+ const channelsMeta = pikkuState(null, 'channel', 'meta');
13
13
  const channelMeta = channelsMeta[channel.name];
14
14
  if (!channelMeta) {
15
15
  throw new Error(`Channel metadata not found for channel: ${channel.name}`);
16
16
  }
17
- pikkuState('channel', 'channels').set(channel.name, channel);
17
+ pikkuState(null, 'channel', 'channels').set(channel.name, channel);
18
18
  // Register onConnect function if provided
19
19
  if (channel.onConnect && channelMeta.connect) {
20
20
  addFunction(channelMeta.connect.pikkuFuncName, channel.onConnect);
@@ -50,19 +50,19 @@ export const wireChannel = (channel) => {
50
50
  });
51
51
  }
52
52
  // Store the channel configuration
53
- pikkuState('channel', 'channels').set(channel.name, channel);
53
+ pikkuState(null, 'channel', 'channels').set(channel.name, channel);
54
54
  };
55
55
  const getMatchingChannelConfig = (path) => {
56
56
  const matchedPath = httpRouter.match('get', path);
57
57
  if (!matchedPath) {
58
58
  return null;
59
59
  }
60
- const meta = pikkuState('channel', 'meta');
60
+ const meta = pikkuState(null, 'channel', 'meta');
61
61
  const channelMeta = Object.values(meta).find((channelConfig) => channelConfig.route === matchedPath.route);
62
62
  if (!channelMeta) {
63
63
  return null;
64
64
  }
65
- const channels = pikkuState('channel', 'channels');
65
+ const channels = pikkuState(null, 'channel', 'channels');
66
66
  const channelConfig = channels.get(channelMeta.name);
67
67
  if (!channelConfig) {
68
68
  return null;
@@ -1,6 +1,6 @@
1
1
  import { PikkuError } from '../../errors/error-handler.js';
2
2
  import { HTTPFunctionMetaInputTypes, PikkuHTTPRequest, PikkuHTTPResponse } from '../http/http.types.js';
3
- import { PikkuDocs, CoreSingletonServices, CreateSessionServices, CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
3
+ import { CoreSingletonServices, CreateWireServices, CorePikkuMiddleware, MiddlewareMetadata, PermissionMetadata } from '../../types/core.types.js';
4
4
  import { CorePermissionGroup, CorePikkuFunction, CorePikkuFunctionConfig, CorePikkuFunctionSessionless, CorePikkuPermission } from '../../function/functions.types.js';
5
5
  export type RunChannelOptions = Partial<{
6
6
  skipUserSession: boolean;
@@ -14,11 +14,14 @@ export type RunChannelParams<ChannelData> = {
14
14
  singletonServices: CoreSingletonServices;
15
15
  request?: PikkuHTTPRequest<ChannelData>;
16
16
  response?: PikkuHTTPResponse;
17
- createSessionServices?: CreateSessionServices;
17
+ createWireServices?: CreateWireServices;
18
18
  };
19
19
  export interface ChannelMessageMeta {
20
20
  pikkuFuncName: string;
21
- docs?: PikkuDocs;
21
+ summary?: string;
22
+ description?: string;
23
+ errors?: string[];
24
+ tags?: string[];
22
25
  middleware?: MiddlewareMetadata[];
23
26
  permissions?: PermissionMetadata[];
24
27
  }
@@ -33,13 +36,15 @@ export interface ChannelMeta {
33
36
  disconnect: ChannelMessageMeta | null;
34
37
  message: ChannelMessageMeta | null;
35
38
  messageWirings: Record<string, Record<string, ChannelMessageMeta>>;
36
- docs?: PikkuDocs;
39
+ summary?: string;
40
+ description?: string;
41
+ errors?: string[];
37
42
  tags?: string[];
38
43
  middleware?: MiddlewareMetadata[];
39
44
  permissions?: PermissionMetadata[];
40
45
  }
41
46
  export type ChannelsMeta = Record<string, ChannelMeta>;
42
- export type CoreChannel<ChannelData, Channel extends string, ChannelConnect = CorePikkuFunctionConfig<CorePikkuFunction<void, unknown, ChannelData> | CorePikkuFunctionSessionless<void, unknown, ChannelData>, CorePikkuPermission<void>, CorePikkuMiddleware>, ChannelDisconnect = CorePikkuFunctionConfig<CorePikkuFunction<void, void, ChannelData> | CorePikkuFunctionSessionless<void, void, ChannelData>, CorePikkuPermission<void>, CorePikkuMiddleware>, ChannelFunctionMessage = CorePikkuFunctionConfig<CorePikkuFunction<unknown, unknown, ChannelData> | CorePikkuFunctionSessionless<unknown, unknown, ChannelData>, CorePikkuPermission<unknown>, CorePikkuMiddleware>, PikkuPermission = CorePikkuPermission<ChannelData>, PikkuMiddleware = CorePikkuMiddleware> = {
47
+ export type CoreChannel<ChannelData, Channel extends string, ChannelConnect = CorePikkuFunctionConfig<CorePikkuFunction<void, unknown> | CorePikkuFunctionSessionless<void, unknown>, CorePikkuPermission<void>, CorePikkuMiddleware>, ChannelDisconnect = CorePikkuFunctionConfig<CorePikkuFunction<void, void> | CorePikkuFunctionSessionless<void, void>, CorePikkuPermission<void>, CorePikkuMiddleware>, ChannelFunctionMessage = CorePikkuFunctionConfig<CorePikkuFunction<unknown, unknown> | CorePikkuFunctionSessionless<unknown, unknown>, CorePikkuPermission<unknown>, CorePikkuMiddleware>, PikkuPermission = CorePikkuPermission<ChannelData>, PikkuMiddleware = CorePikkuMiddleware> = {
43
48
  name: string;
44
49
  route: Channel;
45
50
  onConnect?: ChannelConnect | {
@@ -1,3 +1,3 @@
1
1
  import { CoreChannel, RunChannelOptions, RunChannelParams } from '../channel.types.js';
2
2
  import { PikkuLocalChannelHandler } from './local-channel-handler.js';
3
- export declare const runLocalChannel: ({ singletonServices, channelId, request, response, route, createSessionServices, skipUserSession, respondWith404, coerceDataFromSchema, logWarningsForStatusCodes, bubbleErrors, }: Partial<Pick<CoreChannel<unknown, any>, "route">> & RunChannelOptions & RunChannelParams<unknown>) => Promise<PikkuLocalChannelHandler | void>;
3
+ export declare const runLocalChannel: ({ singletonServices, channelId, request, response, route, createWireServices, skipUserSession, respondWith404, coerceDataFromSchema, logWarningsForStatusCodes, bubbleErrors, }: Partial<Pick<CoreChannel<unknown, any>, "route">> & RunChannelOptions & RunChannelParams<unknown>) => Promise<PikkuLocalChannelHandler | void>;