@pikku/core 0.7.7 → 0.8.0

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 (151) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/errors/error-handler.d.ts +2 -0
  3. package/dist/errors/errors.js +2 -0
  4. package/dist/{channel → events/channel}/channel-handler.d.ts +1 -1
  5. package/dist/{channel → events/channel}/channel-handler.js +2 -2
  6. package/dist/{channel → events/channel}/channel-runner.d.ts +1 -1
  7. package/dist/{channel → events/channel}/channel-runner.js +8 -8
  8. package/dist/{channel → events/channel}/channel-store.d.ts +1 -1
  9. package/dist/{channel → events/channel}/channel.types.d.ts +5 -9
  10. package/dist/{channel → events/channel}/local/local-channel-runner.js +10 -10
  11. package/dist/{channel → events/channel}/log-channels.d.ts +1 -1
  12. package/dist/{channel → events/channel}/log-channels.js +1 -1
  13. package/dist/{channel → events/channel}/serverless/serverless-channel-runner.js +11 -11
  14. package/dist/{http → events/http}/http-runner.d.ts +2 -2
  15. package/dist/{http → events/http}/http-runner.js +30 -19
  16. package/dist/{http → events/http}/http.types.d.ts +4 -3
  17. package/dist/{http → events/http}/index.d.ts +0 -1
  18. package/dist/{http → events/http}/index.js +0 -1
  19. package/dist/{http → events/http}/log-http-routes.d.ts +1 -1
  20. package/dist/{http → events/http}/log-http-routes.js +1 -1
  21. package/dist/{http → events/http}/pikku-fetch-http-request.js +1 -1
  22. package/dist/events/mcp/index.d.ts +2 -0
  23. package/dist/events/mcp/index.js +2 -0
  24. package/dist/events/mcp/mcp-runner.d.ts +30 -0
  25. package/dist/events/mcp/mcp-runner.js +192 -0
  26. package/dist/events/mcp/mcp.types.d.ts +117 -0
  27. package/dist/events/queue/index.d.ts +6 -0
  28. package/dist/events/queue/index.js +6 -0
  29. package/dist/events/queue/queue-runner.d.ts +24 -0
  30. package/dist/events/queue/queue-runner.js +83 -0
  31. package/dist/events/queue/queue.types.d.ts +154 -0
  32. package/dist/events/queue/register-queue-helper.d.ts +17 -0
  33. package/dist/events/queue/register-queue-helper.js +34 -0
  34. package/dist/events/queue/validate-worker-config.d.ts +41 -0
  35. package/dist/events/queue/validate-worker-config.js +50 -0
  36. package/dist/events/rpc/index.d.ts +2 -0
  37. package/dist/events/rpc/rpc-runner.d.ts +28 -0
  38. package/dist/{rpc → events/rpc}/rpc-runner.js +2 -2
  39. package/dist/events/scheduler/index.d.ts +3 -0
  40. package/dist/events/scheduler/index.js +3 -0
  41. package/dist/{scheduler → events/scheduler}/log-schedulers.d.ts +1 -1
  42. package/dist/{scheduler → events/scheduler}/log-schedulers.js +1 -1
  43. package/dist/{scheduler → events/scheduler}/scheduler-runner.d.ts +4 -3
  44. package/dist/{scheduler → events/scheduler}/scheduler-runner.js +7 -4
  45. package/dist/{scheduler → events/scheduler}/scheduler.types.d.ts +3 -4
  46. package/dist/function/function-runner.js +8 -0
  47. package/dist/function/functions.types.d.ts +3 -2
  48. package/dist/handle-error.d.ts +2 -2
  49. package/dist/handle-error.js +1 -1
  50. package/dist/index.d.ts +10 -6
  51. package/dist/index.js +10 -6
  52. package/dist/middleware-runner.d.ts +4 -4
  53. package/dist/middleware-runner.js +4 -2
  54. package/dist/pikku-state.d.ts +18 -4
  55. package/dist/pikku-state.js +12 -0
  56. package/dist/services/user-session-service.d.ts +1 -1
  57. package/dist/types/core.types.d.ts +22 -4
  58. package/dist/types/core.types.js +9 -1
  59. package/lcov.info +3557 -3476
  60. package/package.json +8 -7
  61. package/src/errors/error-handler.ts +2 -1
  62. package/src/errors/errors.ts +2 -0
  63. package/src/{channel → events/channel}/channel-handler.ts +3 -3
  64. package/src/{channel → events/channel}/channel-runner.ts +9 -9
  65. package/src/{channel → events/channel}/channel-store.ts +1 -1
  66. package/src/{channel → events/channel}/channel.types.ts +5 -9
  67. package/src/{channel → events/channel}/local/local-channel-runner.test.ts +1 -1
  68. package/src/{channel → events/channel}/local/local-channel-runner.ts +11 -11
  69. package/src/{channel → events/channel}/local/local-eventhub-service.test.ts +1 -1
  70. package/src/{channel → events/channel}/log-channels.ts +2 -2
  71. package/src/{channel → events/channel}/serverless/serverless-channel-runner.ts +12 -12
  72. package/src/{http → events/http}/http-runner.test.ts +4 -4
  73. package/src/{http → events/http}/http-runner.ts +39 -20
  74. package/src/{http → events/http}/http.types.ts +4 -3
  75. package/src/{http → events/http}/index.ts +0 -1
  76. package/src/{http → events/http}/log-http-routes.ts +2 -2
  77. package/src/{http → events/http}/pikku-fetch-http-request.ts +1 -1
  78. package/src/events/mcp/index.ts +2 -0
  79. package/src/events/mcp/mcp-runner.ts +321 -0
  80. package/src/events/mcp/mcp.types.ts +150 -0
  81. package/src/events/queue/index.ts +18 -0
  82. package/src/events/queue/queue-runner.ts +125 -0
  83. package/src/events/queue/queue.types.ts +176 -0
  84. package/src/events/queue/register-queue-helper.ts +62 -0
  85. package/src/events/queue/validate-worker-config.ts +113 -0
  86. package/src/events/rpc/index.ts +2 -0
  87. package/src/{rpc → events/rpc}/rpc-runner.ts +3 -3
  88. package/src/events/scheduler/index.ts +9 -0
  89. package/src/{scheduler → events/scheduler}/log-schedulers.ts +2 -2
  90. package/src/{scheduler → events/scheduler}/scheduler-runner.ts +11 -10
  91. package/src/{scheduler → events/scheduler}/scheduler.types.ts +2 -4
  92. package/src/function/function-runner.ts +19 -1
  93. package/src/function/functions.types.ts +3 -1
  94. package/src/handle-error.ts +2 -2
  95. package/src/index.ts +23 -6
  96. package/src/middleware-runner.ts +14 -7
  97. package/src/pikku-state.ts +40 -4
  98. package/src/services/user-session-service.ts +1 -1
  99. package/src/types/core.types.ts +31 -4
  100. package/tsconfig.json +3 -2
  101. package/tsconfig.tsbuildinfo +1 -1
  102. package/dist/rpc/index.d.ts +0 -2
  103. package/dist/rpc/rpc-runner.d.ts +0 -27
  104. package/dist/scheduler/index.d.ts +0 -3
  105. package/dist/scheduler/index.js +0 -3
  106. package/src/http/incomingmessage-to-request-convertor.ts +0 -0
  107. package/src/rpc/index.ts +0 -2
  108. package/src/scheduler/index.ts +0 -5
  109. /package/dist/{channel → events/channel}/channel-store.js +0 -0
  110. /package/dist/{channel → events/channel}/channel.types.js +0 -0
  111. /package/dist/{channel → events/channel}/eventhub-service.d.ts +0 -0
  112. /package/dist/{channel → events/channel}/eventhub-service.js +0 -0
  113. /package/dist/{channel → events/channel}/eventhub-store.d.ts +0 -0
  114. /package/dist/{channel → events/channel}/eventhub-store.js +0 -0
  115. /package/dist/{channel → events/channel}/index.d.ts +0 -0
  116. /package/dist/{channel → events/channel}/index.js +0 -0
  117. /package/dist/{channel → events/channel}/local/index.d.ts +0 -0
  118. /package/dist/{channel → events/channel}/local/index.js +0 -0
  119. /package/dist/{channel → events/channel}/local/local-channel-handler.d.ts +0 -0
  120. /package/dist/{channel → events/channel}/local/local-channel-handler.js +0 -0
  121. /package/dist/{channel → events/channel}/local/local-channel-runner.d.ts +0 -0
  122. /package/dist/{channel → events/channel}/local/local-eventhub-service.d.ts +0 -0
  123. /package/dist/{channel → events/channel}/local/local-eventhub-service.js +0 -0
  124. /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.d.ts +0 -0
  125. /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.js +0 -0
  126. /package/dist/{channel → events/channel}/serverless/index.d.ts +0 -0
  127. /package/dist/{channel → events/channel}/serverless/index.js +0 -0
  128. /package/dist/{channel → events/channel}/serverless/serverless-channel-runner.d.ts +0 -0
  129. /package/dist/{http → events/http}/http.types.js +0 -0
  130. /package/dist/{http → events/http}/pikku-fetch-http-request.d.ts +0 -0
  131. /package/dist/{http → events/http}/pikku-fetch-http-response.d.ts +0 -0
  132. /package/dist/{http → events/http}/pikku-fetch-http-response.js +0 -0
  133. /package/dist/{http/incomingmessage-to-request-convertor.d.ts → events/mcp/mcp.types.js} +0 -0
  134. /package/dist/{http/incomingmessage-to-request-convertor.js → events/queue/queue.types.js} +0 -0
  135. /package/dist/{rpc → events/rpc}/index.js +0 -0
  136. /package/dist/{rpc → events/rpc}/rpc-types.d.ts +0 -0
  137. /package/dist/{rpc → events/rpc}/rpc-types.js +0 -0
  138. /package/dist/{scheduler → events/scheduler}/scheduler.types.js +0 -0
  139. /package/src/{channel → events/channel}/eventhub-service.ts +0 -0
  140. /package/src/{channel → events/channel}/eventhub-store.ts +0 -0
  141. /package/src/{channel → events/channel}/index.ts +0 -0
  142. /package/src/{channel → events/channel}/local/index.ts +0 -0
  143. /package/src/{channel → events/channel}/local/local-channel-handler.ts +0 -0
  144. /package/src/{channel → events/channel}/local/local-eventhub-service.ts +0 -0
  145. /package/src/{channel → events/channel}/pikku-abstract-channel-handler.test.ts +0 -0
  146. /package/src/{channel → events/channel}/pikku-abstract-channel-handler.ts +0 -0
  147. /package/src/{channel → events/channel}/serverless/index.ts +0 -0
  148. /package/src/{http → events/http}/pikku-fetch-http-request.test.ts +0 -0
  149. /package/src/{http → events/http}/pikku-fetch-http-response.test.ts +0 -0
  150. /package/src/{http → events/http}/pikku-fetch-http-response.ts +0 -0
  151. /package/src/{rpc → events/rpc}/rpc-types.ts +0 -0
@@ -0,0 +1,176 @@
1
+ import { APIDocs } from '../../types/core.types.js'
2
+ import { CoreAPIFunctionSessionless } from '../../function/functions.types.js'
3
+ import { QueueConfigMapping } from './validate-worker-config.js'
4
+
5
+ /**
6
+ * Configuration for queue workers - how jobs are processed
7
+ */
8
+ /**
9
+ * Configuration for queue workers - how jobs are processed
10
+ */
11
+ export interface PikkuWorkerConfig {
12
+ /** Optional worker name for identification and monitoring */
13
+ name?: string
14
+ /** Number of messages to process in batch / in parallel */
15
+ batchSize?: number
16
+ /** Number of messages to prefetch for efficiency */
17
+ prefetch?: number
18
+ /** Polling interval for pull-based queues in ms */
19
+ pollInterval?: number
20
+ /** Message visibility timeout in seconds */
21
+ visibilityTimeout?: number
22
+ /** Duration of job lock in milliseconds */
23
+ lockDuration?: number
24
+ /** Number of seconds to wait when queue is empty before polling again */
25
+ drainDelay?: number
26
+ /** Keep N completed jobs for inspection */
27
+ removeOnComplete?: number
28
+ /** Keep N failed jobs for inspection */
29
+ removeOnFail?: number
30
+ /** Maximum number of times a job can be recovered from stalled state */
31
+ maxStalledCount?: number
32
+ /** Condition to start processor at instance creation */
33
+ autorun?: boolean
34
+ }
35
+
36
+ /**
37
+ * Configuration for individual jobs - how jobs behave
38
+ */
39
+ export interface PikkuJobConfig {
40
+ /** Maximum retry attempts for failed jobs */
41
+ retryAttempts?: number
42
+ /** Initial retry delay in milliseconds */
43
+ retryDelay?: number
44
+ /** Retry backoff strategy */
45
+ retryBackoff?: 'linear' | 'exponential' | 'fixed'
46
+ /** Queue for failed messages after max retries */
47
+ deadLetterQueue?: string
48
+ /** How long to retain completed jobs in seconds */
49
+ messageRetention?: number
50
+ /** Job priority (higher numbers = higher priority) */
51
+ priority?: number
52
+ /** Enable FIFO ordering where supported */
53
+ fifo?: boolean
54
+ /** Job timeout in milliseconds */
55
+ timeout?: number
56
+ /** Delay before job execution in milliseconds */
57
+ delay?: number
58
+ }
59
+
60
+ /**
61
+ * Configuration validation result with warnings and fallbacks
62
+ */
63
+ export interface ConfigValidationResult {
64
+ applied: Partial<PikkuWorkerConfig>
65
+ ignored: Partial<PikkuWorkerConfig>
66
+ warnings: string[]
67
+ fallbacks: { [key: string]: any }
68
+ }
69
+
70
+ /**
71
+ * Queue job representation
72
+ */
73
+ export type QueueJobStatus =
74
+ | 'waiting'
75
+ | 'active'
76
+ | 'completed'
77
+ | 'failed'
78
+ | 'delayed'
79
+
80
+ export type QueueJobMetadata = {
81
+ progress?: number | string | object | undefined | boolean
82
+ attemptsMade?: number
83
+ maxAttempts?: number
84
+ processedAt?: Date
85
+ completedAt?: Date
86
+ failedAt?: Date
87
+ error?: string
88
+ createdAt: Date
89
+ }
90
+
91
+ export interface QueueJob<T = any, R = any> {
92
+ id: string
93
+ queueName: string
94
+ status: () => Promise<QueueJobStatus> | QueueJobStatus
95
+ data: T
96
+ result?: R
97
+ waitForCompletion?: (ttl?: number) => Promise<R>
98
+ metadata?: () => Promise<QueueJobMetadata> | QueueJobMetadata
99
+ }
100
+
101
+ /**
102
+ * Job options for queue operations
103
+ */
104
+ export interface JobOptions {
105
+ priority?: number
106
+ delay?: number
107
+ attempts?: number
108
+ backoff?: string | { type: string; delay?: number }
109
+ removeOnComplete?: number
110
+ removeOnFail?: number
111
+ jobId?: string
112
+ }
113
+
114
+ /**
115
+ * Queue provider interface for job publishing operations
116
+ */
117
+ export interface QueueService {
118
+ /** Whether this queue provider supports job results */
119
+ readonly supportsResults: boolean
120
+
121
+ /** Add a job to the queue with type safety */
122
+ add<T>(queueName: string, data: T, options?: JobOptions): Promise<string>
123
+
124
+ /** Get job status and result */
125
+ getJob<T, R>(queueName: string, jobId: string): Promise<QueueJob<T, R> | null>
126
+ }
127
+
128
+ /**
129
+ * Queue service interface that queue adapters implement
130
+ */
131
+ export interface QueueWorkers {
132
+ /** Service name identifier */
133
+ name: string
134
+
135
+ /** Whether this queue service supports job results */
136
+ supportsResults: boolean
137
+
138
+ /** Configuration mapping for validation */
139
+ configMappings: QueueConfigMapping
140
+
141
+ /** Scan state and register all compatible processors */
142
+ registerQueues(): Promise<Record<string, ConfigValidationResult[]>>
143
+
144
+ /** Close all queues and connections */
145
+ close(): Promise<void>
146
+ }
147
+
148
+ /**
149
+ * Queue processor metadata
150
+ */
151
+ export type queueWorkersMeta = Record<
152
+ string,
153
+ {
154
+ pikkuFuncName: string
155
+ schemaName?: string
156
+ queueName: string
157
+ session?: undefined
158
+ docs?: APIDocs
159
+ tags?: string[]
160
+ config?: PikkuWorkerConfig
161
+ }
162
+ >
163
+
164
+ /**
165
+ * Core queue processor definition
166
+ */
167
+ export type CoreQueueWorker<
168
+ APIFunction = CoreAPIFunctionSessionless<any, any>,
169
+ > = {
170
+ queueName: string
171
+ func: APIFunction
172
+ config?: PikkuWorkerConfig
173
+ docs?: APIDocs
174
+ session?: undefined
175
+ tags?: string[]
176
+ }
@@ -0,0 +1,62 @@
1
+ import type { ConfigValidationResult, CoreQueueWorker } from './queue.types.js'
2
+ import { getQueueWorkers } from './queue-runner.js'
3
+ import {
4
+ QueueConfigMapping,
5
+ validateWorkerConfig,
6
+ } from './validate-worker-config.js'
7
+ import { Logger } from '../../services/logger.js'
8
+
9
+ /**
10
+ * Queue processor registration callback
11
+ */
12
+ export type QueueRegistrationCallback<T = any> = (
13
+ queueName: string,
14
+ processor: CoreQueueWorker
15
+ ) => Promise<T>
16
+
17
+ /**
18
+ * Helper function to register queue processors with validation
19
+ * This centralizes the common logic for looping over processors and validating configs
20
+ *
21
+ * @param configMappings - Configuration mapping for the queue implementation
22
+ * @param registerCallback - Callback to register each individual queue processor
23
+ * @param logger - Optional logger for info/error messages
24
+ * @returns Record of validation results by queue name
25
+ */
26
+ export async function registerqueueWorkers<T = any>(
27
+ configMappings: QueueConfigMapping,
28
+ logger: Logger,
29
+ registerCallback: QueueRegistrationCallback<T>
30
+ ): Promise<Record<string, ConfigValidationResult[]>> {
31
+ const configValidation: Record<string, ConfigValidationResult[]> = {}
32
+ const queueWorkers = getQueueWorkers()
33
+
34
+ for (const [queueName, processor] of queueWorkers) {
35
+ logger?.info(`Registering queue processor: ${queueName}`)
36
+ // Validate the processor configuration
37
+ const validationResult = validateWorkerConfig(
38
+ configMappings,
39
+ processor.config
40
+ )
41
+
42
+ // Store validation results
43
+ configValidation[queueName] = configValidation[queueName] || []
44
+ configValidation[queueName].push(validationResult)
45
+
46
+ if (validationResult.warnings.length > 0) {
47
+ logger?.warn(
48
+ `Configuration warnings for queue ${queueName}:`,
49
+ validationResult.warnings
50
+ )
51
+ }
52
+
53
+ try {
54
+ await registerCallback(queueName, processor)
55
+ logger?.info(`Successfully registered queue processor: ${queueName}`)
56
+ } catch (error) {
57
+ logger?.error(`Failed to register queue processor ${queueName}:`, error)
58
+ }
59
+ }
60
+
61
+ return configValidation
62
+ }
@@ -0,0 +1,113 @@
1
+ import { PikkuWorkerConfig, ConfigValidationResult } from './queue.types.js'
2
+
3
+ /**
4
+ * Configuration mapping structure for queue implementations
5
+ */
6
+ export interface QueueConfigMapping {
7
+ /** Configurations that are directly supported */
8
+ supported: Partial<
9
+ Record<
10
+ keyof PikkuWorkerConfig,
11
+ {
12
+ /** The property name in the underlying queue system */
13
+ queueProperty?: string
14
+ /** Optional transform function for the value */
15
+ transform?: (value: any) => any
16
+ /** Description of what this configuration does */
17
+ description: string
18
+ }
19
+ >
20
+ >
21
+
22
+ /** Configurations that are not supported */
23
+ unsupported: Partial<
24
+ Record<
25
+ keyof PikkuWorkerConfig,
26
+ {
27
+ /** Why this configuration is not supported */
28
+ reason: string
29
+ /** Detailed explanation of what the queue system does instead */
30
+ explanation: string
31
+ }
32
+ >
33
+ >
34
+
35
+ /** Configurations that have partial support or workarounds */
36
+ fallbacks: Partial<
37
+ Record<
38
+ keyof PikkuWorkerConfig,
39
+ {
40
+ /** Why this configuration uses a fallback */
41
+ reason: string
42
+ /** Detailed explanation of the fallback behavior */
43
+ explanation: string
44
+ /** The fallback value or description */
45
+ fallbackValue: string
46
+ }
47
+ >
48
+ >
49
+ }
50
+
51
+ /**
52
+ * Validates worker configuration using a mapping table
53
+ * This provides a flexible, maintainable way to validate configurations
54
+ * across different queue implementations
55
+ *
56
+ * @param config - The worker configuration to validate
57
+ * @param configMapping - The mapping table defining supported/unsupported configurations
58
+ * @returns Validation result with applied, ignored, warnings, and fallbacks
59
+ */
60
+ export function validateWorkerConfig(
61
+ configMapping: QueueConfigMapping,
62
+ config: PikkuWorkerConfig = {}
63
+ ): ConfigValidationResult {
64
+ const applied: Partial<PikkuWorkerConfig> = {}
65
+ const ignored: Partial<PikkuWorkerConfig> = {}
66
+ const warnings: string[] = []
67
+ const fallbacks: { [key: string]: any } = {}
68
+
69
+ // Process each configuration property
70
+ for (const [key, value] of Object.entries(config)) {
71
+ if (value === undefined) continue
72
+
73
+ const configKey = key as keyof PikkuWorkerConfig
74
+
75
+ // Check if it's a supported configuration
76
+ if (configKey in configMapping.supported) {
77
+ applied[configKey] = value
78
+ continue
79
+ }
80
+
81
+ // Check if it's a fallback configuration
82
+ if (configKey in configMapping.fallbacks) {
83
+ const fallbackMapping = configMapping.fallbacks[configKey]!
84
+ applied[configKey] = value
85
+ fallbacks[key] = fallbackMapping.fallbackValue
86
+ warnings.push(
87
+ `${key}: ${fallbackMapping.reason}. ${fallbackMapping.explanation}`
88
+ )
89
+ continue
90
+ }
91
+
92
+ // Check if it's an unsupported configuration
93
+ if (configKey in configMapping.unsupported) {
94
+ ignored[configKey] = value
95
+ const mapping = configMapping.unsupported[configKey]!
96
+ warnings.push(`${key}: ${mapping.reason}. ${mapping.explanation}`)
97
+ continue
98
+ }
99
+
100
+ // Unknown configuration
101
+ ignored[configKey] = value
102
+ warnings.push(
103
+ `${key}: Unknown configuration option for this queue implementation`
104
+ )
105
+ }
106
+
107
+ return {
108
+ applied,
109
+ ignored,
110
+ warnings,
111
+ fallbacks,
112
+ }
113
+ }
@@ -0,0 +1,2 @@
1
+ export { initialize } from './rpc-runner.js'
2
+ export type { PikkuRPC, RPCMeta } from './rpc-types.js'
@@ -1,6 +1,6 @@
1
- import { CoreServices } from '../types/core.types.js'
2
- import { runPikkuFunc } from '../function/function-runner.js'
3
- import { pikkuState } from '../pikku-state.js'
1
+ import { CoreServices } from '../../types/core.types.js'
2
+ import { runPikkuFunc } from '../../function/function-runner.js'
3
+ import { pikkuState } from '../../pikku-state.js'
4
4
  import { RPCMeta } from './rpc-types.js'
5
5
 
6
6
  // Type for the RPC service configuration
@@ -0,0 +1,9 @@
1
+ export * from './scheduler.types.js'
2
+
3
+ export {
4
+ runScheduledTask,
5
+ addScheduledTask,
6
+ getScheduledTasks,
7
+ } from './scheduler-runner.js'
8
+
9
+ export * from './log-schedulers.js'
@@ -1,5 +1,5 @@
1
- import { pikkuState } from '../pikku-state.js'
2
- import { Logger } from '../services/index.js'
1
+ import { pikkuState } from '../../pikku-state.js'
2
+ import { Logger } from '../../services/index.js'
3
3
 
4
4
  /**
5
5
  * Logs all the loaded scheduled tasks.
@@ -3,13 +3,13 @@ import type {
3
3
  CoreSingletonServices,
4
4
  CoreUserSession,
5
5
  CreateSessionServices,
6
- } from '../types/core.types.js'
6
+ } from '../../types/core.types.js'
7
7
  import type { CoreScheduledTask } from './scheduler.types.js'
8
- import type { CoreAPIFunctionSessionless } from '../function/functions.types.js'
9
- import { getErrorResponse } from '../errors/error-handler.js'
10
- import { closeSessionServices } from '../utils.js'
11
- import { pikkuState } from '../pikku-state.js'
12
- import { addFunction, runPikkuFunc } from '../function/function-runner.js'
8
+ import type { CoreAPIFunctionSessionless } from '../../function/functions.types.js'
9
+ import { getErrorResponse } from '../../errors/error-handler.js'
10
+ import { closeSessionServices } from '../../utils.js'
11
+ import { pikkuState } from '../../pikku-state.js'
12
+ import { addFunction, runPikkuFunc } from '../../function/function-runner.js'
13
13
  import { rpcService } from '../rpc/rpc-runner.js'
14
14
 
15
15
  export type RunScheduledTasksParams = {
@@ -50,10 +50,7 @@ class ScheduledTaskNotFoundError extends Error {
50
50
  }
51
51
  }
52
52
 
53
- export async function runScheduledTask<
54
- SingletonServices extends CoreSingletonServices = CoreSingletonServices,
55
- UserSession extends CoreUserSession = CoreUserSession,
56
- >({
53
+ export async function runScheduledTask({
57
54
  name,
58
55
  session,
59
56
  singletonServices,
@@ -108,3 +105,7 @@ export async function runScheduledTask<
108
105
  }
109
106
  }
110
107
  }
108
+
109
+ export const getScheduledTasks = () => {
110
+ return pikkuState('scheduler', 'tasks')
111
+ }
@@ -1,5 +1,5 @@
1
- import { APIDocs, CoreUserSession } from '../types/core.types.js'
2
- import { CoreAPIFunctionSessionless } from '../function/functions.types.js'
1
+ import { APIDocs, CoreUserSession } from '../../types/core.types.js'
2
+ import { CoreAPIFunctionSessionless } from '../../function/functions.types.js'
3
3
 
4
4
  /**
5
5
  * Represents metadata for scheduled tasks, including title, schedule, and documentation.
@@ -22,12 +22,10 @@ export type ScheduledTasksMeta<UserSession extends CoreUserSession = any> =
22
22
  */
23
23
  export type CoreScheduledTask<
24
24
  APIFunction = CoreAPIFunctionSessionless<void, void>,
25
- UserSession extends CoreUserSession = CoreUserSession,
26
25
  > = {
27
26
  name: string
28
27
  schedule: string
29
28
  func: APIFunction
30
29
  docs?: APIDocs
31
- session?: UserSession
32
30
  tags?: string[]
33
31
  }
@@ -1,9 +1,14 @@
1
1
  import { ForbiddenError } from '../errors/errors.js'
2
+ import { runMiddleware } from '../middleware-runner.js'
2
3
  import { verifyPermissions } from '../permissions.js'
3
4
  import { pikkuState } from '../pikku-state.js'
4
5
  import { coerceTopLevelDataFromSchema, validateSchema } from '../schema.js'
5
6
  import { Logger } from '../services/logger.js'
6
- import { CoreServices, CoreUserSession } from '../types/core.types.js'
7
+ import {
8
+ CoreServices,
9
+ CoreUserSession,
10
+ PikkuFunctionMiddleware,
11
+ } from '../types/core.types.js'
7
12
  import {
8
13
  CorePermissionGroup,
9
14
  CorePikkuFunctionConfig,
@@ -145,5 +150,18 @@ export const runPikkuFunc = async <In = any, Out = any>(
145
150
  throw new ForbiddenError('Permission denied')
146
151
  }
147
152
 
153
+ if (funcConfig.middleware) {
154
+ return (await runMiddleware<PikkuFunctionMiddleware>(
155
+ allServices,
156
+ {
157
+ http: allServices.http,
158
+ mcp: allServices.mcp,
159
+ rpc: allServices.rpc,
160
+ },
161
+ funcConfig.middleware,
162
+ async () => await funcConfig.func(allServices, data, session!)
163
+ )) as Out
164
+ }
165
+
148
166
  return (await funcConfig.func(allServices, data, session!)) as Out
149
167
  }
@@ -1,8 +1,9 @@
1
- import { PikkuChannel } from '../channel/channel.types.js'
1
+ import { PikkuChannel } from '../events/channel/channel.types.js'
2
2
  import type {
3
3
  CoreServices,
4
4
  CoreSingletonServices,
5
5
  CoreUserSession,
6
+ PikkuFunctionMiddleware,
6
7
  } from '../types/core.types.js'
7
8
 
8
9
  /**
@@ -85,4 +86,5 @@ export type CorePikkuFunctionConfig<
85
86
  func: APIFunction
86
87
  auth?: boolean
87
88
  permissions?: CorePermissionGroup<APIPermission>
89
+ middleware?: PikkuFunctionMiddleware[]
88
90
  }
@@ -1,7 +1,7 @@
1
1
  import { getErrorResponse } from './errors/error-handler.js'
2
2
  import { NotFoundError } from './errors/errors.js'
3
3
  import { Logger } from './services/logger.js'
4
- import { PikkuHTTP } from './http/http.types.js'
4
+ import { PikkuHTTP } from './events/http/http.types.js'
5
5
 
6
6
  /**
7
7
  * Handle errors that occur during route processing
@@ -14,7 +14,7 @@ import { PikkuHTTP } from './http/http.types.js'
14
14
  * @param {boolean} respondWith404 - Whether to respond with 404 for NotFoundError
15
15
  * @param {boolean} bubbleError - Whether to throw the error after handling
16
16
  */
17
- export const handleError = (
17
+ export const handleHTTPError = (
18
18
  e: any,
19
19
  http: PikkuHTTP | undefined,
20
20
  trackerId: string | undefined,
package/src/index.ts CHANGED
@@ -6,15 +6,32 @@ export * from './function/index.js'
6
6
  export * from './pikku-request.js'
7
7
  export * from './pikku-response.js'
8
8
  export * from './services/index.js'
9
- export * from './http/index.js'
10
- export * from './channel/index.js'
11
- export * from './scheduler/index.js'
9
+ export * from './events/http/index.js'
10
+ export * from './events/channel/index.js'
11
+ export * from './events/scheduler/index.js'
12
+ export * from './events/rpc/index.js'
13
+ export * from './events/queue/index.js'
14
+ export * from './events/mcp/index.js'
12
15
  export * from './errors/index.js'
13
16
  export * from './middleware/index.js'
14
17
  export * from './time-utils.js'
15
18
  export * from './utils.js'
16
19
  export { pikkuState } from './pikku-state.js'
17
20
  export { runMiddleware } from './middleware-runner.js'
18
- export { addHTTPRoute, addMiddleware } from './http/http-runner.js'
19
- export { addChannel } from './channel/channel-runner.js'
20
- export { addScheduledTask } from './scheduler/scheduler-runner.js'
21
+ export { addHTTPRoute, addMiddleware } from './events/http/http-runner.js'
22
+ export { addChannel } from './events/channel/channel-runner.js'
23
+ export { addScheduledTask } from './events/scheduler/scheduler-runner.js'
24
+ export {
25
+ addMCPResource,
26
+ addMCPTool,
27
+ addMCPPrompt,
28
+ runMCPResource,
29
+ runMCPTool,
30
+ runMCPPrompt,
31
+ getMCPTools,
32
+ getMCPResources,
33
+ getMCPPrompts,
34
+ getMCPResourcesMeta,
35
+ getMCPToolsMeta,
36
+ getMCPPromptsMeta,
37
+ } from './events/mcp/mcp-runner.js'
@@ -1,6 +1,7 @@
1
1
  import { UserSessionService } from './services/user-session-service.js'
2
2
  import {
3
3
  CoreSingletonServices,
4
+ PikkuFunctionMiddleware,
4
5
  PikkuInteraction,
5
6
  PikkuMiddleware,
6
7
  } from './types/core.types.js'
@@ -22,22 +23,28 @@ import {
22
23
  * async () => { return await runMain(); }
23
24
  * );
24
25
  */
25
- export const runMiddleware = async (
26
+ export const runMiddleware = async <
27
+ Middleware extends
28
+ | PikkuMiddleware
29
+ | PikkuFunctionMiddleware = PikkuMiddleware,
30
+ >(
26
31
  services: CoreSingletonServices & {
27
- userSession: UserSessionService<any>
32
+ userSession?: UserSessionService<any>
28
33
  },
29
34
  interaction: PikkuInteraction,
30
- middlewares: PikkuMiddleware[],
31
- main?: () => Promise<void>
32
- ): Promise<void> => {
35
+ middlewares: Middleware[],
36
+ main?: () => Promise<unknown>
37
+ ): Promise<unknown> => {
38
+ let result: any
33
39
  const dispatch = async (index: number): Promise<any> => {
34
40
  if (middlewares && index < middlewares.length) {
35
- await middlewares[index]!(services, interaction, () =>
41
+ return await middlewares[index]!(services as any, interaction, () =>
36
42
  dispatch(index + 1)
37
43
  )
38
44
  } else if (main) {
39
- return await main()
45
+ result = await main()
40
46
  }
41
47
  }
42
48
  await dispatch(0)
49
+ return result
43
50
  }
@@ -1,17 +1,29 @@
1
- import { ChannelsMeta, CoreAPIChannel } from './channel/channel.types.js'
1
+ import { ChannelsMeta, CoreAPIChannel } from './events/channel/channel.types.js'
2
2
  import {
3
3
  CoreHTTPFunctionRoute,
4
4
  HTTPMethod,
5
5
  HTTPRoutesMeta,
6
- } from './http/http.types.js'
6
+ } from './events/http/http.types.js'
7
7
  import { FunctionsMeta, PikkuMiddleware } from './types/core.types.js'
8
8
  import {
9
9
  CoreScheduledTask,
10
10
  ScheduledTasksMeta,
11
- } from './scheduler/scheduler.types.js'
11
+ } from './events/scheduler/scheduler.types.js'
12
12
  import { ErrorDetails, PikkuError } from './errors/error-handler.js'
13
13
  import { CorePikkuFunctionConfig } from './function/functions.types.js'
14
- import { RPCMeta } from './rpc/rpc-types.js'
14
+ import { RPCMeta } from './events/rpc/rpc-types.js'
15
+ import {
16
+ queueWorkersMeta,
17
+ CoreQueueWorker,
18
+ } from './events/queue/queue.types.js'
19
+ import {
20
+ CoreMCPResource,
21
+ CoreMCPTool,
22
+ CoreMCPPrompt,
23
+ MCPResourceMeta,
24
+ MCPToolMeta,
25
+ MCPPromptMeta,
26
+ } from './events/mcp/mcp.types.js'
15
27
 
16
28
  interface PikkuState {
17
29
  function: {
@@ -41,6 +53,18 @@ interface PikkuState {
41
53
  tasks: Map<string, CoreScheduledTask>
42
54
  meta: ScheduledTasksMeta
43
55
  }
56
+ queue: {
57
+ registrations: Map<string, CoreQueueWorker>
58
+ meta: queueWorkersMeta
59
+ }
60
+ mcp: {
61
+ resources: Map<string, CoreMCPResource>
62
+ resourcesMeta: MCPResourceMeta
63
+ tools: Map<string, CoreMCPTool>
64
+ toolsMeta: MCPToolMeta
65
+ prompts: Map<string, CoreMCPPrompt>
66
+ promptsMeta: MCPPromptMeta
67
+ }
44
68
  misc: {
45
69
  errors: Map<PikkuError, ErrorDetails>
46
70
  schemas: Map<string, any>
@@ -70,6 +94,18 @@ export const resetPikkuState = () => {
70
94
  tasks: new Map(),
71
95
  meta: [] as unknown as ScheduledTasksMeta,
72
96
  },
97
+ queue: {
98
+ registrations: new Map(),
99
+ meta: {},
100
+ },
101
+ mcp: {
102
+ resources: new Map(),
103
+ resourcesMeta: {} as MCPResourceMeta,
104
+ tools: new Map(),
105
+ toolsMeta: {} as MCPToolMeta,
106
+ prompts: new Map(),
107
+ promptsMeta: {} as MCPPromptMeta,
108
+ },
73
109
  misc: {
74
110
  errors: globalThis.pikkuState?.misc?.errors || new Map(),
75
111
  schemas: globalThis.pikkuState?.misc?.schema || new Map(),
@@ -1,4 +1,4 @@
1
- import { ChannelStore } from '../channel/channel-store.js'
1
+ import { ChannelStore } from '../events/channel/channel-store.js'
2
2
  import { CoreUserSession } from '../types/core.types.js'
3
3
 
4
4
  export interface UserSessionService<UserSession extends CoreUserSession> {