@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.
- package/CHANGELOG.md +18 -1
- package/dist/errors/error-handler.d.ts +2 -0
- package/dist/errors/errors.js +2 -0
- package/dist/{channel → events/channel}/channel-handler.d.ts +1 -1
- package/dist/{channel → events/channel}/channel-handler.js +2 -2
- package/dist/{channel → events/channel}/channel-runner.d.ts +1 -1
- package/dist/{channel → events/channel}/channel-runner.js +8 -8
- package/dist/{channel → events/channel}/channel-store.d.ts +1 -1
- package/dist/{channel → events/channel}/channel.types.d.ts +5 -9
- package/dist/{channel → events/channel}/local/local-channel-runner.js +10 -10
- package/dist/{channel → events/channel}/log-channels.d.ts +1 -1
- package/dist/{channel → events/channel}/log-channels.js +1 -1
- package/dist/{channel → events/channel}/serverless/serverless-channel-runner.js +11 -11
- package/dist/{http → events/http}/http-runner.d.ts +2 -2
- package/dist/{http → events/http}/http-runner.js +30 -19
- package/dist/{http → events/http}/http.types.d.ts +4 -3
- package/dist/{http → events/http}/index.d.ts +0 -1
- package/dist/{http → events/http}/index.js +0 -1
- package/dist/{http → events/http}/log-http-routes.d.ts +1 -1
- package/dist/{http → events/http}/log-http-routes.js +1 -1
- package/dist/{http → events/http}/pikku-fetch-http-request.js +1 -1
- package/dist/events/mcp/index.d.ts +2 -0
- package/dist/events/mcp/index.js +2 -0
- package/dist/events/mcp/mcp-runner.d.ts +30 -0
- package/dist/events/mcp/mcp-runner.js +192 -0
- package/dist/events/mcp/mcp.types.d.ts +117 -0
- package/dist/events/queue/index.d.ts +6 -0
- package/dist/events/queue/index.js +6 -0
- package/dist/events/queue/queue-runner.d.ts +24 -0
- package/dist/events/queue/queue-runner.js +83 -0
- package/dist/events/queue/queue.types.d.ts +154 -0
- package/dist/events/queue/register-queue-helper.d.ts +17 -0
- package/dist/events/queue/register-queue-helper.js +34 -0
- package/dist/events/queue/validate-worker-config.d.ts +41 -0
- package/dist/events/queue/validate-worker-config.js +50 -0
- package/dist/events/rpc/index.d.ts +2 -0
- package/dist/events/rpc/rpc-runner.d.ts +28 -0
- package/dist/{rpc → events/rpc}/rpc-runner.js +2 -2
- package/dist/events/scheduler/index.d.ts +3 -0
- package/dist/events/scheduler/index.js +3 -0
- package/dist/{scheduler → events/scheduler}/log-schedulers.d.ts +1 -1
- package/dist/{scheduler → events/scheduler}/log-schedulers.js +1 -1
- package/dist/{scheduler → events/scheduler}/scheduler-runner.d.ts +4 -3
- package/dist/{scheduler → events/scheduler}/scheduler-runner.js +7 -4
- package/dist/{scheduler → events/scheduler}/scheduler.types.d.ts +3 -4
- package/dist/function/function-runner.js +8 -0
- package/dist/function/functions.types.d.ts +3 -2
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +1 -1
- package/dist/index.d.ts +10 -6
- package/dist/index.js +10 -6
- package/dist/middleware-runner.d.ts +4 -4
- package/dist/middleware-runner.js +4 -2
- package/dist/pikku-state.d.ts +18 -4
- package/dist/pikku-state.js +12 -0
- package/dist/services/user-session-service.d.ts +1 -1
- package/dist/types/core.types.d.ts +22 -4
- package/dist/types/core.types.js +9 -1
- package/lcov.info +3557 -3476
- package/package.json +8 -7
- package/src/errors/error-handler.ts +2 -1
- package/src/errors/errors.ts +2 -0
- package/src/{channel → events/channel}/channel-handler.ts +3 -3
- package/src/{channel → events/channel}/channel-runner.ts +9 -9
- package/src/{channel → events/channel}/channel-store.ts +1 -1
- package/src/{channel → events/channel}/channel.types.ts +5 -9
- package/src/{channel → events/channel}/local/local-channel-runner.test.ts +1 -1
- package/src/{channel → events/channel}/local/local-channel-runner.ts +11 -11
- package/src/{channel → events/channel}/local/local-eventhub-service.test.ts +1 -1
- package/src/{channel → events/channel}/log-channels.ts +2 -2
- package/src/{channel → events/channel}/serverless/serverless-channel-runner.ts +12 -12
- package/src/{http → events/http}/http-runner.test.ts +4 -4
- package/src/{http → events/http}/http-runner.ts +39 -20
- package/src/{http → events/http}/http.types.ts +4 -3
- package/src/{http → events/http}/index.ts +0 -1
- package/src/{http → events/http}/log-http-routes.ts +2 -2
- package/src/{http → events/http}/pikku-fetch-http-request.ts +1 -1
- package/src/events/mcp/index.ts +2 -0
- package/src/events/mcp/mcp-runner.ts +321 -0
- package/src/events/mcp/mcp.types.ts +150 -0
- package/src/events/queue/index.ts +18 -0
- package/src/events/queue/queue-runner.ts +125 -0
- package/src/events/queue/queue.types.ts +176 -0
- package/src/events/queue/register-queue-helper.ts +62 -0
- package/src/events/queue/validate-worker-config.ts +113 -0
- package/src/events/rpc/index.ts +2 -0
- package/src/{rpc → events/rpc}/rpc-runner.ts +3 -3
- package/src/events/scheduler/index.ts +9 -0
- package/src/{scheduler → events/scheduler}/log-schedulers.ts +2 -2
- package/src/{scheduler → events/scheduler}/scheduler-runner.ts +11 -10
- package/src/{scheduler → events/scheduler}/scheduler.types.ts +2 -4
- package/src/function/function-runner.ts +19 -1
- package/src/function/functions.types.ts +3 -1
- package/src/handle-error.ts +2 -2
- package/src/index.ts +23 -6
- package/src/middleware-runner.ts +14 -7
- package/src/pikku-state.ts +40 -4
- package/src/services/user-session-service.ts +1 -1
- package/src/types/core.types.ts +31 -4
- package/tsconfig.json +3 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/rpc/index.d.ts +0 -2
- package/dist/rpc/rpc-runner.d.ts +0 -27
- package/dist/scheduler/index.d.ts +0 -3
- package/dist/scheduler/index.js +0 -3
- package/src/http/incomingmessage-to-request-convertor.ts +0 -0
- package/src/rpc/index.ts +0 -2
- package/src/scheduler/index.ts +0 -5
- /package/dist/{channel → events/channel}/channel-store.js +0 -0
- /package/dist/{channel → events/channel}/channel.types.js +0 -0
- /package/dist/{channel → events/channel}/eventhub-service.d.ts +0 -0
- /package/dist/{channel → events/channel}/eventhub-service.js +0 -0
- /package/dist/{channel → events/channel}/eventhub-store.d.ts +0 -0
- /package/dist/{channel → events/channel}/eventhub-store.js +0 -0
- /package/dist/{channel → events/channel}/index.d.ts +0 -0
- /package/dist/{channel → events/channel}/index.js +0 -0
- /package/dist/{channel → events/channel}/local/index.d.ts +0 -0
- /package/dist/{channel → events/channel}/local/index.js +0 -0
- /package/dist/{channel → events/channel}/local/local-channel-handler.d.ts +0 -0
- /package/dist/{channel → events/channel}/local/local-channel-handler.js +0 -0
- /package/dist/{channel → events/channel}/local/local-channel-runner.d.ts +0 -0
- /package/dist/{channel → events/channel}/local/local-eventhub-service.d.ts +0 -0
- /package/dist/{channel → events/channel}/local/local-eventhub-service.js +0 -0
- /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.d.ts +0 -0
- /package/dist/{channel → events/channel}/pikku-abstract-channel-handler.js +0 -0
- /package/dist/{channel → events/channel}/serverless/index.d.ts +0 -0
- /package/dist/{channel → events/channel}/serverless/index.js +0 -0
- /package/dist/{channel → events/channel}/serverless/serverless-channel-runner.d.ts +0 -0
- /package/dist/{http → events/http}/http.types.js +0 -0
- /package/dist/{http → events/http}/pikku-fetch-http-request.d.ts +0 -0
- /package/dist/{http → events/http}/pikku-fetch-http-response.d.ts +0 -0
- /package/dist/{http → events/http}/pikku-fetch-http-response.js +0 -0
- /package/dist/{http/incomingmessage-to-request-convertor.d.ts → events/mcp/mcp.types.js} +0 -0
- /package/dist/{http/incomingmessage-to-request-convertor.js → events/queue/queue.types.js} +0 -0
- /package/dist/{rpc → events/rpc}/index.js +0 -0
- /package/dist/{rpc → events/rpc}/rpc-types.d.ts +0 -0
- /package/dist/{rpc → events/rpc}/rpc-types.js +0 -0
- /package/dist/{scheduler → events/scheduler}/scheduler.types.js +0 -0
- /package/src/{channel → events/channel}/eventhub-service.ts +0 -0
- /package/src/{channel → events/channel}/eventhub-store.ts +0 -0
- /package/src/{channel → events/channel}/index.ts +0 -0
- /package/src/{channel → events/channel}/local/index.ts +0 -0
- /package/src/{channel → events/channel}/local/local-channel-handler.ts +0 -0
- /package/src/{channel → events/channel}/local/local-eventhub-service.ts +0 -0
- /package/src/{channel → events/channel}/pikku-abstract-channel-handler.test.ts +0 -0
- /package/src/{channel → events/channel}/pikku-abstract-channel-handler.ts +0 -0
- /package/src/{channel → events/channel}/serverless/index.ts +0 -0
- /package/src/{http → events/http}/pikku-fetch-http-request.test.ts +0 -0
- /package/src/{http → events/http}/pikku-fetch-http-response.test.ts +0 -0
- /package/src/{http → events/http}/pikku-fetch-http-response.ts +0 -0
- /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
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { CoreServices } from '
|
|
2
|
-
import { runPikkuFunc } from '
|
|
3
|
-
import { pikkuState } from '
|
|
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
|
|
@@ -3,13 +3,13 @@ import type {
|
|
|
3
3
|
CoreSingletonServices,
|
|
4
4
|
CoreUserSession,
|
|
5
5
|
CreateSessionServices,
|
|
6
|
-
} from '
|
|
6
|
+
} from '../../types/core.types.js'
|
|
7
7
|
import type { CoreScheduledTask } from './scheduler.types.js'
|
|
8
|
-
import type { CoreAPIFunctionSessionless } from '
|
|
9
|
-
import { getErrorResponse } from '
|
|
10
|
-
import { closeSessionServices } from '
|
|
11
|
-
import { pikkuState } from '
|
|
12
|
-
import { addFunction, runPikkuFunc } from '
|
|
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 '
|
|
2
|
-
import { CoreAPIFunctionSessionless } from '
|
|
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 {
|
|
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
|
}
|
package/src/handle-error.ts
CHANGED
|
@@ -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
|
|
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'
|
package/src/middleware-runner.ts
CHANGED
|
@@ -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
|
|
32
|
+
userSession?: UserSessionService<any>
|
|
28
33
|
},
|
|
29
34
|
interaction: PikkuInteraction,
|
|
30
|
-
middlewares:
|
|
31
|
-
main?: () => Promise<
|
|
32
|
-
): Promise<
|
|
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
|
-
|
|
45
|
+
result = await main()
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
48
|
await dispatch(0)
|
|
49
|
+
return result
|
|
43
50
|
}
|
package/src/pikku-state.ts
CHANGED
|
@@ -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(),
|