@pikku/core 0.7.8 → 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 +10 -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 +4 -4
  8. package/dist/{channel → events/channel}/channel-store.d.ts +1 -1
  9. package/dist/{channel → events/channel}/channel.types.d.ts +3 -3
  10. package/dist/{channel → events/channel}/local/local-channel-runner.js +6 -6
  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 +7 -7
  14. package/dist/{http → events/http}/http-runner.d.ts +1 -1
  15. package/dist/{http → events/http}/http-runner.js +8 -8
  16. package/dist/{http → events/http}/http.types.d.ts +3 -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 +3 -1
  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 +17 -5
  58. package/dist/types/core.types.js +2 -0
  59. package/lcov.info +3191 -3123
  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 +5 -5
  65. package/src/{channel → events/channel}/channel-store.ts +1 -1
  66. package/src/{channel → events/channel}/channel.types.ts +3 -3
  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 +7 -7
  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 +8 -8
  72. package/src/{http → events/http}/http-runner.test.ts +4 -4
  73. package/src/{http → events/http}/http-runner.ts +9 -9
  74. package/src/{http → events/http}/http.types.ts +3 -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 +24 -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,24 @@
1
+ import type { CoreServices } from '../../types/core.types.js';
2
+ import type { CoreQueueWorker, QueueJob } from './queue.types.js';
3
+ import type { CoreAPIFunctionSessionless } from '../../function/functions.types.js';
4
+ import { CreateSessionServices } from '../../types/core.types.js';
5
+ /**
6
+ * Add a queue processor to the system
7
+ */
8
+ export declare const addQueueWorker: <InputData = any, OutputData = any, APIFunction extends CoreAPIFunctionSessionless<InputData, OutputData> = CoreAPIFunctionSessionless<InputData, OutputData>>(queueWorker: CoreQueueWorker<APIFunction>) => void;
9
+ /**
10
+ * Get all registered queue processors
11
+ */
12
+ export declare function getQueueWorkers(): Map<string, CoreQueueWorker>;
13
+ /**
14
+ * Stop and remove a queue processor
15
+ */
16
+ export declare function removeQueueWorker(name: string): Promise<void>;
17
+ /**
18
+ * Process a single queue job - this function is called by queue consumers
19
+ */
20
+ export declare function runQueueJob({ singletonServices, createSessionServices, job, }: {
21
+ singletonServices: CoreServices;
22
+ createSessionServices?: CreateSessionServices;
23
+ job: QueueJob;
24
+ }): Promise<void>;
@@ -0,0 +1,83 @@
1
+ import { getErrorResponse } from '../../errors/error-handler.js';
2
+ import { pikkuState } from '../../pikku-state.js';
3
+ import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
4
+ /**
5
+ * Error class for queue processor not found
6
+ */
7
+ class QueueWorkerNotFoundError extends Error {
8
+ constructor(name) {
9
+ super(`Queue processor not found: ${name}`);
10
+ }
11
+ }
12
+ /**
13
+ * Add a queue processor to the system
14
+ */
15
+ export const addQueueWorker = (queueWorker) => {
16
+ // Get processor metadata
17
+ const meta = pikkuState('queue', 'meta');
18
+ const processorMeta = meta[queueWorker.queueName];
19
+ if (!processorMeta) {
20
+ throw new Error(`Queue processor metadata not found for '${queueWorker.queueName}'. Make sure to run the CLI to generate metadata.`);
21
+ }
22
+ // Register the function with pikku
23
+ addFunction(processorMeta.pikkuFuncName, {
24
+ func: queueWorker.func,
25
+ });
26
+ // Store processor definition in state - runtime adapters will pick this up
27
+ const registrations = pikkuState('queue', 'registrations');
28
+ registrations.set(queueWorker.queueName, queueWorker);
29
+ };
30
+ /**
31
+ * Get all registered queue processors
32
+ */
33
+ export function getQueueWorkers() {
34
+ return pikkuState('queue', 'registrations');
35
+ }
36
+ /**
37
+ * Stop and remove a queue processor
38
+ */
39
+ export async function removeQueueWorker(name) {
40
+ const registrations = pikkuState('queue', 'registrations');
41
+ const registration = registrations.get(name);
42
+ if (!registration) {
43
+ throw new QueueWorkerNotFoundError(name);
44
+ }
45
+ registrations.delete(name);
46
+ }
47
+ /**
48
+ * Process a single queue job - this function is called by queue consumers
49
+ */
50
+ export async function runQueueJob({ singletonServices, createSessionServices, job, }) {
51
+ const logger = singletonServices.logger;
52
+ const meta = pikkuState('queue', 'meta');
53
+ const processorMeta = meta[job.queueName];
54
+ if (!processorMeta) {
55
+ throw new Error(`Processor metadata not found for: ${job.queueName}`);
56
+ }
57
+ try {
58
+ logger.info(`Processing job ${job.id} in queue ${job.queueName}`);
59
+ // Use provided singleton services
60
+ const getAllServices = () => ({
61
+ ...singletonServices,
62
+ ...(createSessionServices
63
+ ? createSessionServices(singletonServices, {}, undefined)
64
+ : {}),
65
+ });
66
+ // Execute the pikku function with the job data
67
+ const result = await runPikkuFunc(processorMeta.pikkuFuncName, {
68
+ getAllServices,
69
+ data: job.data,
70
+ });
71
+ logger.debug(`Successfully processed job ${job.id} in queue ${job.queueName}`);
72
+ return result;
73
+ }
74
+ catch (error) {
75
+ logger.error(`Error processing job ${job.id} in queue ${job.queueName}:`, error);
76
+ const errorResponse = getErrorResponse(error);
77
+ if (errorResponse != null) {
78
+ logger.error('Processed error response:', errorResponse);
79
+ }
80
+ // Re-throw the error so the queue service can handle retries/DLQ
81
+ throw error;
82
+ }
83
+ }
@@ -0,0 +1,154 @@
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
+ * Configuration for queue workers - how jobs are processed
6
+ */
7
+ /**
8
+ * Configuration for queue workers - how jobs are processed
9
+ */
10
+ export interface PikkuWorkerConfig {
11
+ /** Optional worker name for identification and monitoring */
12
+ name?: string;
13
+ /** Number of messages to process in batch / in parallel */
14
+ batchSize?: number;
15
+ /** Number of messages to prefetch for efficiency */
16
+ prefetch?: number;
17
+ /** Polling interval for pull-based queues in ms */
18
+ pollInterval?: number;
19
+ /** Message visibility timeout in seconds */
20
+ visibilityTimeout?: number;
21
+ /** Duration of job lock in milliseconds */
22
+ lockDuration?: number;
23
+ /** Number of seconds to wait when queue is empty before polling again */
24
+ drainDelay?: number;
25
+ /** Keep N completed jobs for inspection */
26
+ removeOnComplete?: number;
27
+ /** Keep N failed jobs for inspection */
28
+ removeOnFail?: number;
29
+ /** Maximum number of times a job can be recovered from stalled state */
30
+ maxStalledCount?: number;
31
+ /** Condition to start processor at instance creation */
32
+ autorun?: boolean;
33
+ }
34
+ /**
35
+ * Configuration for individual jobs - how jobs behave
36
+ */
37
+ export interface PikkuJobConfig {
38
+ /** Maximum retry attempts for failed jobs */
39
+ retryAttempts?: number;
40
+ /** Initial retry delay in milliseconds */
41
+ retryDelay?: number;
42
+ /** Retry backoff strategy */
43
+ retryBackoff?: 'linear' | 'exponential' | 'fixed';
44
+ /** Queue for failed messages after max retries */
45
+ deadLetterQueue?: string;
46
+ /** How long to retain completed jobs in seconds */
47
+ messageRetention?: number;
48
+ /** Job priority (higher numbers = higher priority) */
49
+ priority?: number;
50
+ /** Enable FIFO ordering where supported */
51
+ fifo?: boolean;
52
+ /** Job timeout in milliseconds */
53
+ timeout?: number;
54
+ /** Delay before job execution in milliseconds */
55
+ delay?: number;
56
+ }
57
+ /**
58
+ * Configuration validation result with warnings and fallbacks
59
+ */
60
+ export interface ConfigValidationResult {
61
+ applied: Partial<PikkuWorkerConfig>;
62
+ ignored: Partial<PikkuWorkerConfig>;
63
+ warnings: string[];
64
+ fallbacks: {
65
+ [key: string]: any;
66
+ };
67
+ }
68
+ /**
69
+ * Queue job representation
70
+ */
71
+ export type QueueJobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed';
72
+ export type QueueJobMetadata = {
73
+ progress?: number | string | object | undefined | boolean;
74
+ attemptsMade?: number;
75
+ maxAttempts?: number;
76
+ processedAt?: Date;
77
+ completedAt?: Date;
78
+ failedAt?: Date;
79
+ error?: string;
80
+ createdAt: Date;
81
+ };
82
+ export interface QueueJob<T = any, R = any> {
83
+ id: string;
84
+ queueName: string;
85
+ status: () => Promise<QueueJobStatus> | QueueJobStatus;
86
+ data: T;
87
+ result?: R;
88
+ waitForCompletion?: (ttl?: number) => Promise<R>;
89
+ metadata?: () => Promise<QueueJobMetadata> | QueueJobMetadata;
90
+ }
91
+ /**
92
+ * Job options for queue operations
93
+ */
94
+ export interface JobOptions {
95
+ priority?: number;
96
+ delay?: number;
97
+ attempts?: number;
98
+ backoff?: string | {
99
+ type: string;
100
+ delay?: number;
101
+ };
102
+ removeOnComplete?: number;
103
+ removeOnFail?: number;
104
+ jobId?: string;
105
+ }
106
+ /**
107
+ * Queue provider interface for job publishing operations
108
+ */
109
+ export interface QueueService {
110
+ /** Whether this queue provider supports job results */
111
+ readonly supportsResults: boolean;
112
+ /** Add a job to the queue with type safety */
113
+ add<T>(queueName: string, data: T, options?: JobOptions): Promise<string>;
114
+ /** Get job status and result */
115
+ getJob<T, R>(queueName: string, jobId: string): Promise<QueueJob<T, R> | null>;
116
+ }
117
+ /**
118
+ * Queue service interface that queue adapters implement
119
+ */
120
+ export interface QueueWorkers {
121
+ /** Service name identifier */
122
+ name: string;
123
+ /** Whether this queue service supports job results */
124
+ supportsResults: boolean;
125
+ /** Configuration mapping for validation */
126
+ configMappings: QueueConfigMapping;
127
+ /** Scan state and register all compatible processors */
128
+ registerQueues(): Promise<Record<string, ConfigValidationResult[]>>;
129
+ /** Close all queues and connections */
130
+ close(): Promise<void>;
131
+ }
132
+ /**
133
+ * Queue processor metadata
134
+ */
135
+ export type queueWorkersMeta = Record<string, {
136
+ pikkuFuncName: string;
137
+ schemaName?: string;
138
+ queueName: string;
139
+ session?: undefined;
140
+ docs?: APIDocs;
141
+ tags?: string[];
142
+ config?: PikkuWorkerConfig;
143
+ }>;
144
+ /**
145
+ * Core queue processor definition
146
+ */
147
+ export type CoreQueueWorker<APIFunction = CoreAPIFunctionSessionless<any, any>> = {
148
+ queueName: string;
149
+ func: APIFunction;
150
+ config?: PikkuWorkerConfig;
151
+ docs?: APIDocs;
152
+ session?: undefined;
153
+ tags?: string[];
154
+ };
@@ -0,0 +1,17 @@
1
+ import type { ConfigValidationResult, CoreQueueWorker } from './queue.types.js';
2
+ import { QueueConfigMapping } from './validate-worker-config.js';
3
+ import { Logger } from '../../services/logger.js';
4
+ /**
5
+ * Queue processor registration callback
6
+ */
7
+ export type QueueRegistrationCallback<T = any> = (queueName: string, processor: CoreQueueWorker) => Promise<T>;
8
+ /**
9
+ * Helper function to register queue processors with validation
10
+ * This centralizes the common logic for looping over processors and validating configs
11
+ *
12
+ * @param configMappings - Configuration mapping for the queue implementation
13
+ * @param registerCallback - Callback to register each individual queue processor
14
+ * @param logger - Optional logger for info/error messages
15
+ * @returns Record of validation results by queue name
16
+ */
17
+ export declare function registerqueueWorkers<T = any>(configMappings: QueueConfigMapping, logger: Logger, registerCallback: QueueRegistrationCallback<T>): Promise<Record<string, ConfigValidationResult[]>>;
@@ -0,0 +1,34 @@
1
+ import { getQueueWorkers } from './queue-runner.js';
2
+ import { validateWorkerConfig, } from './validate-worker-config.js';
3
+ /**
4
+ * Helper function to register queue processors with validation
5
+ * This centralizes the common logic for looping over processors and validating configs
6
+ *
7
+ * @param configMappings - Configuration mapping for the queue implementation
8
+ * @param registerCallback - Callback to register each individual queue processor
9
+ * @param logger - Optional logger for info/error messages
10
+ * @returns Record of validation results by queue name
11
+ */
12
+ export async function registerqueueWorkers(configMappings, logger, registerCallback) {
13
+ const configValidation = {};
14
+ const queueWorkers = getQueueWorkers();
15
+ for (const [queueName, processor] of queueWorkers) {
16
+ logger?.info(`Registering queue processor: ${queueName}`);
17
+ // Validate the processor configuration
18
+ const validationResult = validateWorkerConfig(configMappings, processor.config);
19
+ // Store validation results
20
+ configValidation[queueName] = configValidation[queueName] || [];
21
+ configValidation[queueName].push(validationResult);
22
+ if (validationResult.warnings.length > 0) {
23
+ logger?.warn(`Configuration warnings for queue ${queueName}:`, validationResult.warnings);
24
+ }
25
+ try {
26
+ await registerCallback(queueName, processor);
27
+ logger?.info(`Successfully registered queue processor: ${queueName}`);
28
+ }
29
+ catch (error) {
30
+ logger?.error(`Failed to register queue processor ${queueName}:`, error);
31
+ }
32
+ }
33
+ return configValidation;
34
+ }
@@ -0,0 +1,41 @@
1
+ import { PikkuWorkerConfig, ConfigValidationResult } from './queue.types.js';
2
+ /**
3
+ * Configuration mapping structure for queue implementations
4
+ */
5
+ export interface QueueConfigMapping {
6
+ /** Configurations that are directly supported */
7
+ supported: Partial<Record<keyof PikkuWorkerConfig, {
8
+ /** The property name in the underlying queue system */
9
+ queueProperty?: string;
10
+ /** Optional transform function for the value */
11
+ transform?: (value: any) => any;
12
+ /** Description of what this configuration does */
13
+ description: string;
14
+ }>>;
15
+ /** Configurations that are not supported */
16
+ unsupported: Partial<Record<keyof PikkuWorkerConfig, {
17
+ /** Why this configuration is not supported */
18
+ reason: string;
19
+ /** Detailed explanation of what the queue system does instead */
20
+ explanation: string;
21
+ }>>;
22
+ /** Configurations that have partial support or workarounds */
23
+ fallbacks: Partial<Record<keyof PikkuWorkerConfig, {
24
+ /** Why this configuration uses a fallback */
25
+ reason: string;
26
+ /** Detailed explanation of the fallback behavior */
27
+ explanation: string;
28
+ /** The fallback value or description */
29
+ fallbackValue: string;
30
+ }>>;
31
+ }
32
+ /**
33
+ * Validates worker configuration using a mapping table
34
+ * This provides a flexible, maintainable way to validate configurations
35
+ * across different queue implementations
36
+ *
37
+ * @param config - The worker configuration to validate
38
+ * @param configMapping - The mapping table defining supported/unsupported configurations
39
+ * @returns Validation result with applied, ignored, warnings, and fallbacks
40
+ */
41
+ export declare function validateWorkerConfig(configMapping: QueueConfigMapping, config?: PikkuWorkerConfig): ConfigValidationResult;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Validates worker configuration using a mapping table
3
+ * This provides a flexible, maintainable way to validate configurations
4
+ * across different queue implementations
5
+ *
6
+ * @param config - The worker configuration to validate
7
+ * @param configMapping - The mapping table defining supported/unsupported configurations
8
+ * @returns Validation result with applied, ignored, warnings, and fallbacks
9
+ */
10
+ export function validateWorkerConfig(configMapping, config = {}) {
11
+ const applied = {};
12
+ const ignored = {};
13
+ const warnings = [];
14
+ const fallbacks = {};
15
+ // Process each configuration property
16
+ for (const [key, value] of Object.entries(config)) {
17
+ if (value === undefined)
18
+ continue;
19
+ const configKey = key;
20
+ // Check if it's a supported configuration
21
+ if (configKey in configMapping.supported) {
22
+ applied[configKey] = value;
23
+ continue;
24
+ }
25
+ // Check if it's a fallback configuration
26
+ if (configKey in configMapping.fallbacks) {
27
+ const fallbackMapping = configMapping.fallbacks[configKey];
28
+ applied[configKey] = value;
29
+ fallbacks[key] = fallbackMapping.fallbackValue;
30
+ warnings.push(`${key}: ${fallbackMapping.reason}. ${fallbackMapping.explanation}`);
31
+ continue;
32
+ }
33
+ // Check if it's an unsupported configuration
34
+ if (configKey in configMapping.unsupported) {
35
+ ignored[configKey] = value;
36
+ const mapping = configMapping.unsupported[configKey];
37
+ warnings.push(`${key}: ${mapping.reason}. ${mapping.explanation}`);
38
+ continue;
39
+ }
40
+ // Unknown configuration
41
+ ignored[configKey] = value;
42
+ warnings.push(`${key}: Unknown configuration option for this queue implementation`);
43
+ }
44
+ return {
45
+ applied,
46
+ ignored,
47
+ warnings,
48
+ fallbacks,
49
+ };
50
+ }
@@ -0,0 +1,2 @@
1
+ export { initialize } from './rpc-runner.js';
2
+ export type { PikkuRPC, RPCMeta } from './rpc-types.js';
@@ -0,0 +1,28 @@
1
+ import { CoreServices } from '../../types/core.types.js';
2
+ type RPCServiceConfig = {
3
+ coerceDataFromSchema: boolean;
4
+ };
5
+ export declare class PikkuRPCService {
6
+ private config?;
7
+ initialize(config: RPCServiceConfig): void;
8
+ injectRPCService(coreServices: CoreServices, depth?: number): {
9
+ jwt?: import("../../index.js").JWTService;
10
+ schema?: import("../../index.js").SchemaService;
11
+ config: {
12
+ logLevel?: import("../../index.js").LogLevel;
13
+ secrets?: {};
14
+ };
15
+ logger: import("../../index.js").Logger;
16
+ variables: import("../../index.js").VariablesService;
17
+ eventHub?: import("../channel/eventhub-service.js").EventHubService<unknown>;
18
+ secrets?: import("../../index.js").SecretService;
19
+ http?: import("../http/http.types.js").PikkuHTTP;
20
+ mcp?: import("../mcp/mcp.types.js").PikkuMCP;
21
+ rpc?: import("./rpc-types.js").PikkuRPC;
22
+ userSession?: import("../../index.js").UserSessionService<import("../../types/core.types.js").CoreUserSession> | undefined;
23
+ channel?: import("../channel/channel.types.js").PikkuChannel<unknown, unknown>;
24
+ };
25
+ }
26
+ export declare const rpcService: PikkuRPCService;
27
+ export declare const initialize: (config: RPCServiceConfig) => void;
28
+ export {};
@@ -1,5 +1,5 @@
1
- import { runPikkuFunc } from '../function/function-runner.js';
2
- import { pikkuState } from '../pikku-state.js';
1
+ import { runPikkuFunc } from '../../function/function-runner.js';
2
+ import { pikkuState } from '../../pikku-state.js';
3
3
  const getRPCMeta = (rpcName) => {
4
4
  const rpc = pikkuState('rpc', 'meta');
5
5
  const rpcMeta = rpc[rpcName];
@@ -0,0 +1,3 @@
1
+ export * from './scheduler.types.js';
2
+ export { runScheduledTask, addScheduledTask, getScheduledTasks, } from './scheduler-runner.js';
3
+ export * from './log-schedulers.js';
@@ -0,0 +1,3 @@
1
+ export * from './scheduler.types.js';
2
+ export { runScheduledTask, addScheduledTask, getScheduledTasks, } from './scheduler-runner.js';
3
+ export * from './log-schedulers.js';
@@ -1,4 +1,4 @@
1
- import { Logger } from '../services/index.js';
1
+ import { Logger } from '../../services/index.js';
2
2
  /**
3
3
  * Logs all the loaded scheduled tasks.
4
4
  * @param logger - A logger for logging information.
@@ -1,4 +1,4 @@
1
- import { pikkuState } from '../pikku-state.js';
1
+ import { pikkuState } from '../../pikku-state.js';
2
2
  /**
3
3
  * Logs all the loaded scheduled tasks.
4
4
  * @param logger - A logger for logging information.
@@ -1,6 +1,6 @@
1
- import type { CoreServices, CoreSingletonServices, CoreUserSession, CreateSessionServices } from '../types/core.types.js';
1
+ import type { CoreServices, CoreSingletonServices, CoreUserSession, CreateSessionServices } from '../../types/core.types.js';
2
2
  import type { CoreScheduledTask } from './scheduler.types.js';
3
- import type { CoreAPIFunctionSessionless } from '../function/functions.types.js';
3
+ import type { CoreAPIFunctionSessionless } from '../../function/functions.types.js';
4
4
  export type RunScheduledTasksParams = {
5
5
  name: string;
6
6
  session?: CoreUserSession;
@@ -8,4 +8,5 @@ export type RunScheduledTasksParams = {
8
8
  createSessionServices?: CreateSessionServices<CoreSingletonServices, CoreServices<CoreSingletonServices>, CoreUserSession>;
9
9
  };
10
10
  export declare const addScheduledTask: <APIFunction extends CoreAPIFunctionSessionless<void, void>>(scheduledTask: CoreScheduledTask<APIFunction>) => void;
11
- export declare function runScheduledTask<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession>({ name, session, singletonServices, createSessionServices, }: RunScheduledTasksParams): Promise<void>;
11
+ export declare function runScheduledTask({ name, session, singletonServices, createSessionServices, }: RunScheduledTasksParams): Promise<void>;
12
+ export declare const getScheduledTasks: () => Map<string, CoreScheduledTask>;
@@ -1,7 +1,7 @@
1
- import { getErrorResponse } from '../errors/error-handler.js';
2
- import { closeSessionServices } from '../utils.js';
3
- import { pikkuState } from '../pikku-state.js';
4
- import { addFunction, runPikkuFunc } from '../function/function-runner.js';
1
+ import { getErrorResponse } from '../../errors/error-handler.js';
2
+ import { closeSessionServices } from '../../utils.js';
3
+ import { pikkuState } from '../../pikku-state.js';
4
+ import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
5
5
  import { rpcService } from '../rpc/rpc-runner.js';
6
6
  export const addScheduledTask = (scheduledTask) => {
7
7
  const meta = pikkuState('scheduler', 'meta');
@@ -64,3 +64,6 @@ export async function runScheduledTask({ name, session, singletonServices, creat
64
64
  }
65
65
  }
66
66
  }
67
+ export const getScheduledTasks = () => {
68
+ return pikkuState('scheduler', 'tasks');
69
+ };
@@ -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
  * Represents metadata for scheduled tasks, including title, schedule, and documentation.
5
5
  */
@@ -14,11 +14,10 @@ export type ScheduledTasksMeta<UserSession extends CoreUserSession = any> = Reco
14
14
  /**
15
15
  * Represents a core scheduled task.
16
16
  */
17
- export type CoreScheduledTask<APIFunction = CoreAPIFunctionSessionless<void, void>, UserSession extends CoreUserSession = CoreUserSession> = {
17
+ export type CoreScheduledTask<APIFunction = CoreAPIFunctionSessionless<void, void>> = {
18
18
  name: string;
19
19
  schedule: string;
20
20
  func: APIFunction;
21
21
  docs?: APIDocs;
22
- session?: UserSession;
23
22
  tags?: string[];
24
23
  };
@@ -1,4 +1,5 @@
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';
@@ -76,5 +77,12 @@ export const runPikkuFunc = async (funcName, { getAllServices, data, session, pe
76
77
  if (permissioned === false) {
77
78
  throw new ForbiddenError('Permission denied');
78
79
  }
80
+ if (funcConfig.middleware) {
81
+ return (await runMiddleware(allServices, {
82
+ http: allServices.http,
83
+ mcp: allServices.mcp,
84
+ rpc: allServices.rpc,
85
+ }, funcConfig.middleware, async () => await funcConfig.func(allServices, data, session)));
86
+ }
79
87
  return (await funcConfig.func(allServices, data, session));
80
88
  };
@@ -1,5 +1,5 @@
1
- import { PikkuChannel } from '../channel/channel.types.js';
2
- import type { CoreServices, CoreSingletonServices, CoreUserSession } from '../types/core.types.js';
1
+ import { PikkuChannel } from '../events/channel/channel.types.js';
2
+ import type { CoreServices, CoreSingletonServices, CoreUserSession, PikkuFunctionMiddleware } from '../types/core.types.js';
3
3
  /**
4
4
  * Represents a core API function that performs an operation using core services and a user session.
5
5
  *
@@ -39,4 +39,5 @@ export type CorePikkuFunctionConfig<APIFunction extends CoreAPIFunction<any, any
39
39
  func: APIFunction;
40
40
  auth?: boolean;
41
41
  permissions?: CorePermissionGroup<APIPermission>;
42
+ middleware?: PikkuFunctionMiddleware[];
42
43
  };
@@ -1,5 +1,5 @@
1
1
  import { Logger } from './services/logger.js';
2
- import { PikkuHTTP } from './http/http.types.js';
2
+ import { PikkuHTTP } from './events/http/http.types.js';
3
3
  /**
4
4
  * Handle errors that occur during route processing
5
5
  *
@@ -11,4 +11,4 @@ import { PikkuHTTP } from './http/http.types.js';
11
11
  * @param {boolean} respondWith404 - Whether to respond with 404 for NotFoundError
12
12
  * @param {boolean} bubbleError - Whether to throw the error after handling
13
13
  */
14
- export declare const handleError: (e: any, http: PikkuHTTP | undefined, trackerId: string | undefined, logger: Logger, logWarningsForStatusCodes: number[], respondWith404: boolean, bubbleError: boolean) => void;
14
+ export declare const handleHTTPError: (e: any, http: PikkuHTTP | undefined, trackerId: string | undefined, logger: Logger, logWarningsForStatusCodes: number[], respondWith404: boolean, bubbleError: boolean) => void;
@@ -11,7 +11,7 @@ import { NotFoundError } from './errors/errors.js';
11
11
  * @param {boolean} respondWith404 - Whether to respond with 404 for NotFoundError
12
12
  * @param {boolean} bubbleError - Whether to throw the error after handling
13
13
  */
14
- export const handleError = (e, http, trackerId, logger, logWarningsForStatusCodes, respondWith404, bubbleError) => {
14
+ export const handleHTTPError = (e, http, trackerId, logger, logWarningsForStatusCodes, respondWith404, bubbleError) => {
15
15
  // Skip 404 handling if configured to do so
16
16
  if (e instanceof NotFoundError && !respondWith404) {
17
17
  return;
package/dist/index.d.ts CHANGED
@@ -6,15 +6,19 @@ 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 { addMCPResource, addMCPTool, addMCPPrompt, runMCPResource, runMCPTool, runMCPPrompt, getMCPTools, getMCPResources, getMCPPrompts, getMCPResourcesMeta, getMCPToolsMeta, getMCPPromptsMeta, } from './events/mcp/mcp-runner.js';
package/dist/index.js CHANGED
@@ -6,15 +6,19 @@ 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 { addMCPResource, addMCPTool, addMCPPrompt, runMCPResource, runMCPTool, runMCPPrompt, getMCPTools, getMCPResources, getMCPPrompts, getMCPResourcesMeta, getMCPToolsMeta, getMCPPromptsMeta, } from './events/mcp/mcp-runner.js';