@pikku/core 0.11.1 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/errors/error-handler.js +3 -3
- package/dist/function/function-runner.d.ts +4 -3
- package/dist/function/function-runner.js +60 -14
- package/dist/function/functions.types.d.ts +84 -5
- package/dist/function/functions.types.js +41 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -2
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/middleware/auth-bearer.d.ts +1 -1
- package/dist/middleware/auth-cookie.d.ts +1 -1
- package/dist/middleware/timeout.d.ts +1 -1
- package/dist/middleware-runner.d.ts +3 -14
- package/dist/middleware-runner.js +8 -8
- package/dist/permissions.d.ts +3 -86
- package/dist/permissions.js +11 -67
- package/dist/pikku-state.d.ts +32 -104
- package/dist/pikku-state.js +140 -66
- package/dist/schema.d.ts +8 -6
- package/dist/schema.js +25 -13
- package/dist/services/workflow-service.d.ts +38 -0
- package/dist/services/workflow-service.js +1 -0
- package/dist/types/core.types.d.ts +12 -4
- package/dist/types/core.types.js +1 -1
- package/dist/types/state.types.d.ts +135 -0
- package/dist/types/state.types.js +1 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +45 -0
- package/dist/wirings/channel/channel-handler.js +1 -1
- package/dist/wirings/channel/channel-runner.js +5 -5
- package/dist/wirings/channel/log-channels.js +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -2
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -2
- package/dist/wirings/cli/cli-runner.js +10 -10
- package/dist/wirings/cli/cli.types.d.ts +1 -0
- package/dist/wirings/forge-node/forge-node.types.d.ts +120 -0
- package/dist/wirings/forge-node/forge-node.types.js +38 -0
- package/dist/wirings/forge-node/index.d.ts +1 -0
- package/dist/wirings/forge-node/index.js +1 -0
- package/dist/wirings/http/http-runner.d.ts +2 -2
- package/dist/wirings/http/http-runner.js +21 -12
- package/dist/wirings/http/http.types.d.ts +14 -1
- package/dist/wirings/http/log-http-routes.js +1 -1
- package/dist/wirings/http/routers/path-to-regex.js +2 -2
- package/dist/wirings/mcp/mcp-runner.js +21 -21
- package/dist/wirings/queue/queue-runner.js +6 -6
- package/dist/wirings/rpc/index.d.ts +1 -1
- package/dist/wirings/rpc/index.js +1 -1
- package/dist/wirings/rpc/rpc-runner.d.ts +7 -8
- package/dist/wirings/rpc/rpc-runner.js +62 -14
- package/dist/wirings/rpc/rpc-types.d.ts +7 -0
- package/dist/wirings/scheduler/log-schedulers.js +1 -1
- package/dist/wirings/scheduler/scheduler-runner.js +5 -5
- package/dist/wirings/trigger/index.d.ts +2 -0
- package/dist/wirings/trigger/index.js +2 -0
- package/dist/wirings/trigger/trigger-runner.d.ts +29 -0
- package/dist/wirings/trigger/trigger-runner.js +57 -0
- package/dist/wirings/trigger/trigger.types.d.ts +42 -0
- package/dist/wirings/trigger/trigger.types.js +1 -0
- package/dist/wirings/workflow/dsl/index.d.ts +5 -0
- package/dist/wirings/workflow/dsl/index.js +4 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +286 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.js +5 -0
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +5 -0
- package/dist/wirings/workflow/dsl/workflow-runner.js +22 -0
- package/dist/wirings/workflow/graph/graph-node.d.ts +122 -0
- package/dist/wirings/workflow/graph/graph-node.js +58 -0
- package/dist/wirings/workflow/graph/graph-runner.d.ts +35 -0
- package/dist/wirings/workflow/graph/graph-runner.js +452 -0
- package/dist/wirings/workflow/graph/index.d.ts +3 -0
- package/dist/wirings/workflow/graph/index.js +3 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +95 -0
- package/dist/wirings/workflow/graph/workflow-graph.types.js +15 -0
- package/dist/wirings/workflow/index.d.ts +7 -12
- package/dist/wirings/workflow/index.js +6 -11
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +96 -6
- package/dist/wirings/workflow/pikku-workflow-service.js +230 -103
- package/dist/wirings/workflow/wire-workflow.d.ts +42 -0
- package/dist/wirings/workflow/wire-workflow.js +53 -0
- package/dist/wirings/workflow/workflow-utils.d.ts +23 -0
- package/dist/wirings/workflow/workflow-utils.js +66 -0
- package/dist/wirings/workflow/workflow.types.d.ts +133 -211
- package/package.json +10 -1
- package/src/errors/error-handler.ts +3 -3
- package/src/function/function-runner.test.ts +1 -1
- package/src/function/function-runner.ts +86 -16
- package/src/function/functions.types.ts +126 -4
- package/src/index.ts +10 -5
- package/src/middleware-runner.ts +16 -9
- package/src/permissions.test.ts +28 -86
- package/src/permissions.ts +21 -80
- package/src/pikku-state.ts +156 -201
- package/src/schema.ts +42 -13
- package/src/services/workflow-service.ts +74 -0
- package/src/types/core.types.ts +12 -3
- package/src/types/state.types.ts +195 -0
- package/src/utils.ts +55 -0
- package/src/wirings/channel/channel-handler.ts +1 -1
- package/src/wirings/channel/channel-runner.ts +5 -5
- package/src/wirings/channel/local/local-channel-runner.test.ts +3 -1
- package/src/wirings/channel/log-channels.ts +1 -1
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -2
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -3
- package/src/wirings/cli/cli-runner.test.ts +19 -19
- package/src/wirings/cli/cli-runner.ts +10 -9
- package/src/wirings/cli/cli.types.ts +1 -0
- package/src/wirings/forge-node/forge-node.types.ts +135 -0
- package/src/wirings/forge-node/index.ts +1 -0
- package/src/wirings/http/http-runner.test.ts +2 -2
- package/src/wirings/http/http-runner.ts +30 -13
- package/src/wirings/http/http.types.ts +14 -0
- package/src/wirings/http/log-http-routes.ts +1 -1
- package/src/wirings/http/routers/path-to-regex.test.ts +30 -19
- package/src/wirings/http/routers/path-to-regex.ts +2 -2
- package/src/wirings/mcp/mcp-runner.ts +21 -21
- package/src/wirings/queue/queue-runner.test.ts +19 -19
- package/src/wirings/queue/queue-runner.ts +6 -6
- package/src/wirings/rpc/index.ts +1 -1
- package/src/wirings/rpc/rpc-runner.ts +88 -22
- package/src/wirings/rpc/rpc-types.ts +8 -0
- package/src/wirings/scheduler/log-schedulers.ts +1 -1
- package/src/wirings/scheduler/scheduler-runner.test.ts +27 -27
- package/src/wirings/scheduler/scheduler-runner.ts +5 -5
- package/src/wirings/trigger/index.ts +2 -0
- package/src/wirings/trigger/trigger-runner.ts +96 -0
- package/src/wirings/trigger/trigger.types.ts +56 -0
- package/src/wirings/workflow/dsl/index.ts +30 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +312 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +27 -0
- package/src/wirings/workflow/graph/graph-node.ts +227 -0
- package/src/wirings/workflow/graph/graph-runner.ts +694 -0
- package/src/wirings/workflow/graph/index.ts +3 -0
- package/src/wirings/workflow/graph/workflow-graph.types.ts +126 -0
- package/src/wirings/workflow/index.ts +53 -26
- package/src/wirings/workflow/pikku-workflow-service.ts +333 -117
- package/src/wirings/workflow/wire-workflow.ts +94 -0
- package/src/wirings/workflow/workflow-utils.ts +120 -0
- package/src/wirings/workflow/workflow.types.ts +166 -277
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/workflow/workflow-runner.d.ts +0 -34
- package/dist/wirings/workflow/workflow-runner.js +0 -65
- package/src/function/function-runner.ts.bak +0 -188
- package/src/wirings/workflow/workflow-runner.ts +0 -72
|
@@ -56,13 +56,13 @@ export const wireMCPResource = <
|
|
|
56
56
|
>(
|
|
57
57
|
mcpResource: CoreMCPResource<PikkuFunctionConfig>
|
|
58
58
|
) => {
|
|
59
|
-
const resourcesMeta = pikkuState('mcp', 'resourcesMeta')
|
|
59
|
+
const resourcesMeta = pikkuState(null, 'mcp', 'resourcesMeta')
|
|
60
60
|
const mcpResourceMeta = resourcesMeta[mcpResource.uri]
|
|
61
61
|
if (!mcpResourceMeta) {
|
|
62
62
|
throw new Error(`MCP resource metadata not found for '${mcpResource.uri}'`)
|
|
63
63
|
}
|
|
64
64
|
addFunction(mcpResourceMeta.pikkuFuncName, mcpResource.func as any)
|
|
65
|
-
const resources = pikkuState('mcp', 'resources')
|
|
65
|
+
const resources = pikkuState(null, 'mcp', 'resources')
|
|
66
66
|
if (resources.has(mcpResource.uri)) {
|
|
67
67
|
throw new Error(`MCP resource already exists: ${mcpResource.uri}`)
|
|
68
68
|
}
|
|
@@ -76,13 +76,13 @@ export const wireMCPTool = <
|
|
|
76
76
|
>(
|
|
77
77
|
mcpTool: CoreMCPTool<PikkuFunctionConfig>
|
|
78
78
|
) => {
|
|
79
|
-
const toolsMeta = pikkuState('mcp', 'toolsMeta')
|
|
79
|
+
const toolsMeta = pikkuState(null, 'mcp', 'toolsMeta')
|
|
80
80
|
const mcpToolMeta = toolsMeta[mcpTool.name]
|
|
81
81
|
if (!mcpToolMeta) {
|
|
82
82
|
throw new Error(`MCP tool metadata not found for '${mcpTool.name}'`)
|
|
83
83
|
}
|
|
84
84
|
addFunction(mcpToolMeta.pikkuFuncName, mcpTool.func as any)
|
|
85
|
-
const tools = pikkuState('mcp', 'tools')
|
|
85
|
+
const tools = pikkuState(null, 'mcp', 'tools')
|
|
86
86
|
if (tools.has(mcpTool.name)) {
|
|
87
87
|
throw new Error(`MCP tool already exists: ${mcpTool.name}`)
|
|
88
88
|
}
|
|
@@ -96,13 +96,13 @@ export const wireMCPPrompt = <
|
|
|
96
96
|
>(
|
|
97
97
|
mcpPrompt: CoreMCPPrompt<PikkuFunctionConfig>
|
|
98
98
|
) => {
|
|
99
|
-
const promptsMeta = pikkuState('mcp', 'promptsMeta')
|
|
99
|
+
const promptsMeta = pikkuState(null, 'mcp', 'promptsMeta')
|
|
100
100
|
const mcpPromptMeta = promptsMeta[mcpPrompt.name]
|
|
101
101
|
if (!mcpPromptMeta) {
|
|
102
102
|
throw new Error(`MCP prompt metadata not found for '${mcpPrompt.name}'`)
|
|
103
103
|
}
|
|
104
104
|
addFunction(mcpPromptMeta.pikkuFuncName, mcpPrompt.func as any)
|
|
105
|
-
const prompts = pikkuState('mcp', 'prompts')
|
|
105
|
+
const prompts = pikkuState(null, 'mcp', 'prompts')
|
|
106
106
|
if (prompts.has(mcpPrompt.name)) {
|
|
107
107
|
throw new Error(`MCP prompt already exists: ${mcpPrompt.name}`)
|
|
108
108
|
}
|
|
@@ -118,8 +118,8 @@ export async function runMCPResource(
|
|
|
118
118
|
let pikkuFuncName: string | undefined
|
|
119
119
|
let extractedParams: Record<string, string> = {}
|
|
120
120
|
|
|
121
|
-
const metas = pikkuState('mcp', 'resourcesMeta')
|
|
122
|
-
const endpoints = pikkuState('mcp', 'resources')
|
|
121
|
+
const metas = pikkuState(null, 'mcp', 'resourcesMeta')
|
|
122
|
+
const endpoints = pikkuState(null, 'mcp', 'resources')
|
|
123
123
|
|
|
124
124
|
if (endpoints.has(uri)) {
|
|
125
125
|
endpoint = endpoints.get(uri)
|
|
@@ -170,8 +170,8 @@ export async function runMCPTool(
|
|
|
170
170
|
params: RunMCPEndpointParams,
|
|
171
171
|
name: string
|
|
172
172
|
) {
|
|
173
|
-
const endpoint = pikkuState('mcp', 'tools').get(name)
|
|
174
|
-
const meta = pikkuState('mcp', 'toolsMeta')[name]
|
|
173
|
+
const endpoint = pikkuState(null, 'mcp', 'tools').get(name)
|
|
174
|
+
const meta = pikkuState(null, 'mcp', 'toolsMeta')[name]
|
|
175
175
|
return await runMCPPikkuFunc(
|
|
176
176
|
request,
|
|
177
177
|
'tool',
|
|
@@ -187,8 +187,8 @@ export async function runMCPPrompt(
|
|
|
187
187
|
params: RunMCPEndpointParams,
|
|
188
188
|
name: string
|
|
189
189
|
) {
|
|
190
|
-
const endpoint = pikkuState('mcp', 'prompts').get(name)
|
|
191
|
-
const meta = pikkuState('mcp', 'promptsMeta')[name]
|
|
190
|
+
const endpoint = pikkuState(null, 'mcp', 'prompts').get(name)
|
|
191
|
+
const meta = pikkuState(null, 'mcp', 'promptsMeta')[name]
|
|
192
192
|
return await runMCPPikkuFunc(
|
|
193
193
|
request,
|
|
194
194
|
'prompt',
|
|
@@ -242,11 +242,11 @@ async function runMCPPikkuFunc(
|
|
|
242
242
|
// Get metadata for the MCP endpoint to access pre-resolved middleware
|
|
243
243
|
let meta: any
|
|
244
244
|
if (type === 'resource') {
|
|
245
|
-
meta = pikkuState('mcp', 'resourcesMeta')[name]
|
|
245
|
+
meta = pikkuState(null, 'mcp', 'resourcesMeta')[name]
|
|
246
246
|
} else if (type === 'tool') {
|
|
247
|
-
meta = pikkuState('mcp', 'toolsMeta')[name]
|
|
247
|
+
meta = pikkuState(null, 'mcp', 'toolsMeta')[name]
|
|
248
248
|
} else if (type === 'prompt') {
|
|
249
|
-
meta = pikkuState('mcp', 'promptsMeta')[name]
|
|
249
|
+
meta = pikkuState(null, 'mcp', 'promptsMeta')[name]
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
const result = await runPikkuFunc('mcp', `${type}:${name}`, pikkuFuncName, {
|
|
@@ -298,25 +298,25 @@ async function runMCPPikkuFunc(
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
export const getMCPTools = () => {
|
|
301
|
-
return pikkuState('mcp', 'tools')
|
|
301
|
+
return pikkuState(null, 'mcp', 'tools')
|
|
302
302
|
}
|
|
303
303
|
|
|
304
304
|
export const getMCPResources = () => {
|
|
305
|
-
return pikkuState('mcp', 'resources')
|
|
305
|
+
return pikkuState(null, 'mcp', 'resources')
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
export const getMCPResourcesMeta = () => {
|
|
309
|
-
return pikkuState('mcp', 'resourcesMeta')
|
|
309
|
+
return pikkuState(null, 'mcp', 'resourcesMeta')
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
export const getMCPToolsMeta = () => {
|
|
313
|
-
return pikkuState('mcp', 'toolsMeta')
|
|
313
|
+
return pikkuState(null, 'mcp', 'toolsMeta')
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
export const getMCPPrompts = () => {
|
|
317
|
-
return pikkuState('mcp', 'prompts')
|
|
317
|
+
return pikkuState(null, 'mcp', 'prompts')
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
export const getMCPPromptsMeta = () => {
|
|
321
|
-
return pikkuState('mcp', 'promptsMeta')
|
|
321
|
+
return pikkuState(null, 'mcp', 'promptsMeta')
|
|
322
322
|
}
|
|
@@ -39,7 +39,7 @@ const createMockJob = (
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
const addTestQueueFunction = (pikkuFuncName: string) => {
|
|
42
|
-
pikkuState('function', 'meta')[pikkuFuncName] = {
|
|
42
|
+
pikkuState(null, 'function', 'meta')[pikkuFuncName] = {
|
|
43
43
|
pikkuFuncName,
|
|
44
44
|
inputSchemaName: null,
|
|
45
45
|
outputSchemaName: null,
|
|
@@ -61,14 +61,14 @@ describe('wireQueueWorker', () => {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// Set up metadata first
|
|
64
|
-
pikkuState('queue', 'meta')['test-queue'] = {
|
|
64
|
+
pikkuState(null, 'queue', 'meta')['test-queue'] = {
|
|
65
65
|
pikkuFuncName: 'queue_test-queue',
|
|
66
66
|
queueName: 'test-queue',
|
|
67
67
|
}
|
|
68
68
|
addTestQueueFunction('queue_test-queue')
|
|
69
69
|
wireQueueWorker(mockWorker)
|
|
70
70
|
|
|
71
|
-
const registrations = pikkuState('queue', 'registrations')
|
|
71
|
+
const registrations = pikkuState(null, 'queue', 'registrations')
|
|
72
72
|
assert.equal(registrations.has('test-queue'), true)
|
|
73
73
|
assert.equal(registrations.get('test-queue'), mockWorker)
|
|
74
74
|
})
|
|
@@ -109,14 +109,14 @@ describe('wireQueueWorker', () => {
|
|
|
109
109
|
tags: ['queue'],
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
pikkuState('queue', 'meta')['worker-with-middleware'] = {
|
|
112
|
+
pikkuState(null, 'queue', 'meta')['worker-with-middleware'] = {
|
|
113
113
|
pikkuFuncName: 'queue_worker-with-middleware',
|
|
114
114
|
queueName: 'worker-with-middleware',
|
|
115
115
|
}
|
|
116
116
|
addTestQueueFunction('queue_worker-with-middleware')
|
|
117
117
|
wireQueueWorker(mockWorker)
|
|
118
118
|
|
|
119
|
-
const registrations = pikkuState('queue', 'registrations')
|
|
119
|
+
const registrations = pikkuState(null, 'queue', 'registrations')
|
|
120
120
|
const worker = registrations.get('worker-with-middleware')
|
|
121
121
|
assert.equal(worker?.middleware?.length, 1)
|
|
122
122
|
assert.deepEqual(worker?.tags, ['queue'])
|
|
@@ -133,7 +133,7 @@ describe('getQueueWorkers', () => {
|
|
|
133
133
|
},
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
pikkuState('queue', 'meta')['test-queue'] = {
|
|
136
|
+
pikkuState(null, 'queue', 'meta')['test-queue'] = {
|
|
137
137
|
pikkuFuncName: 'queue_test-queue',
|
|
138
138
|
queueName: 'test-queue',
|
|
139
139
|
}
|
|
@@ -162,7 +162,7 @@ describe('removeQueueWorker', () => {
|
|
|
162
162
|
},
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
pikkuState('queue', 'meta')['removable-queue'] = {
|
|
165
|
+
pikkuState(null, 'queue', 'meta')['removable-queue'] = {
|
|
166
166
|
pikkuFuncName: 'queue_removable-queue',
|
|
167
167
|
queueName: 'removable-queue',
|
|
168
168
|
}
|
|
@@ -209,7 +209,7 @@ describe('runQueueJob', () => {
|
|
|
209
209
|
},
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
pikkuState('queue', 'meta')['simple-queue'] = {
|
|
212
|
+
pikkuState(null, 'queue', 'meta')['simple-queue'] = {
|
|
213
213
|
pikkuFuncName: 'queue_simple-queue',
|
|
214
214
|
queueName: 'simple-queue',
|
|
215
215
|
}
|
|
@@ -247,7 +247,7 @@ describe('runQueueJob', () => {
|
|
|
247
247
|
},
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
pikkuState('queue', 'meta')['fail-queue'] = {
|
|
250
|
+
pikkuState(null, 'queue', 'meta')['fail-queue'] = {
|
|
251
251
|
pikkuFuncName: 'queue_fail-queue',
|
|
252
252
|
queueName: 'fail-queue',
|
|
253
253
|
}
|
|
@@ -285,7 +285,7 @@ describe('runQueueJob', () => {
|
|
|
285
285
|
},
|
|
286
286
|
}
|
|
287
287
|
|
|
288
|
-
pikkuState('queue', 'meta')['fail-no-reason-queue'] = {
|
|
288
|
+
pikkuState(null, 'queue', 'meta')['fail-no-reason-queue'] = {
|
|
289
289
|
pikkuFuncName: 'queue_fail-no-reason-queue',
|
|
290
290
|
queueName: 'fail-no-reason-queue',
|
|
291
291
|
}
|
|
@@ -321,7 +321,7 @@ describe('runQueueJob', () => {
|
|
|
321
321
|
},
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
pikkuState('queue', 'meta')['discard-queue'] = {
|
|
324
|
+
pikkuState(null, 'queue', 'meta')['discard-queue'] = {
|
|
325
325
|
pikkuFuncName: 'queue_discard-queue',
|
|
326
326
|
queueName: 'discard-queue',
|
|
327
327
|
}
|
|
@@ -364,7 +364,7 @@ describe('runQueueJob', () => {
|
|
|
364
364
|
},
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
pikkuState('queue', 'meta')['progress-queue'] = {
|
|
367
|
+
pikkuState(null, 'queue', 'meta')['progress-queue'] = {
|
|
368
368
|
pikkuFuncName: 'queue_progress-queue',
|
|
369
369
|
queueName: 'progress-queue',
|
|
370
370
|
}
|
|
@@ -397,7 +397,7 @@ describe('runQueueJob', () => {
|
|
|
397
397
|
},
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
-
pikkuState('queue', 'meta')['default-progress-queue'] = {
|
|
400
|
+
pikkuState(null, 'queue', 'meta')['default-progress-queue'] = {
|
|
401
401
|
pikkuFuncName: 'queue_default-progress-queue',
|
|
402
402
|
queueName: 'default-progress-queue',
|
|
403
403
|
}
|
|
@@ -431,7 +431,7 @@ describe('runQueueJob', () => {
|
|
|
431
431
|
},
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
pikkuState('queue', 'meta')['wire-queue'] = {
|
|
434
|
+
pikkuState(null, 'queue', 'meta')['wire-queue'] = {
|
|
435
435
|
pikkuFuncName: 'queue_wire-queue',
|
|
436
436
|
queueName: 'wire-queue',
|
|
437
437
|
}
|
|
@@ -474,7 +474,7 @@ describe('runQueueJob', () => {
|
|
|
474
474
|
|
|
475
475
|
test('should throw error when queue worker registration not found', async () => {
|
|
476
476
|
// Add metadata but not registration
|
|
477
|
-
pikkuState('queue', 'meta')['no-registration-queue'] = {
|
|
477
|
+
pikkuState(null, 'queue', 'meta')['no-registration-queue'] = {
|
|
478
478
|
pikkuFuncName: 'queue_no-registration-queue',
|
|
479
479
|
queueName: 'no-registration-queue',
|
|
480
480
|
}
|
|
@@ -509,7 +509,7 @@ describe('runQueueJob', () => {
|
|
|
509
509
|
},
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
-
pikkuState('queue', 'meta')['session-services-queue'] = {
|
|
512
|
+
pikkuState(null, 'queue', 'meta')['session-services-queue'] = {
|
|
513
513
|
pikkuFuncName: 'queue_session-services-queue',
|
|
514
514
|
queueName: 'session-services-queue',
|
|
515
515
|
}
|
|
@@ -542,7 +542,7 @@ describe('runQueueJob', () => {
|
|
|
542
542
|
},
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
-
pikkuState('queue', 'meta')['error-queue'] = {
|
|
545
|
+
pikkuState(null, 'queue', 'meta')['error-queue'] = {
|
|
546
546
|
pikkuFuncName: 'queue_error-queue',
|
|
547
547
|
queueName: 'error-queue',
|
|
548
548
|
}
|
|
@@ -591,7 +591,7 @@ describe('runQueueJob', () => {
|
|
|
591
591
|
middleware: [middleware],
|
|
592
592
|
}
|
|
593
593
|
|
|
594
|
-
pikkuState('queue', 'meta')['middleware-queue'] = {
|
|
594
|
+
pikkuState(null, 'queue', 'meta')['middleware-queue'] = {
|
|
595
595
|
pikkuFuncName: 'queue_middleware-queue',
|
|
596
596
|
queueName: 'middleware-queue',
|
|
597
597
|
}
|
|
@@ -618,7 +618,7 @@ describe('runQueueJob', () => {
|
|
|
618
618
|
},
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
-
pikkuState('queue', 'meta')['debug-queue'] = {
|
|
621
|
+
pikkuState(null, 'queue', 'meta')['debug-queue'] = {
|
|
622
622
|
pikkuFuncName: 'queue_debug-queue',
|
|
623
623
|
queueName: 'debug-queue',
|
|
624
624
|
}
|
|
@@ -52,7 +52,7 @@ export const wireQueueWorker = <
|
|
|
52
52
|
queueWorker: CoreQueueWorker<PikkuFunctionConfig>
|
|
53
53
|
) => {
|
|
54
54
|
// Get processor metadata
|
|
55
|
-
const meta = pikkuState('queue', 'meta')
|
|
55
|
+
const meta = pikkuState(null, 'queue', 'meta')
|
|
56
56
|
const processorMeta = meta[queueWorker.queueName]
|
|
57
57
|
if (!processorMeta) {
|
|
58
58
|
throw new Error(
|
|
@@ -70,7 +70,7 @@ export const wireQueueWorker = <
|
|
|
70
70
|
})
|
|
71
71
|
|
|
72
72
|
// Store processor definition in state - runtime adapters will pick this up
|
|
73
|
-
const registrations = pikkuState('queue', 'registrations')
|
|
73
|
+
const registrations = pikkuState(null, 'queue', 'registrations')
|
|
74
74
|
registrations.set(queueWorker.queueName, queueWorker)
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -78,14 +78,14 @@ export const wireQueueWorker = <
|
|
|
78
78
|
* Get all registered queue processors
|
|
79
79
|
*/
|
|
80
80
|
export function getQueueWorkers(): Map<string, CoreQueueWorker> {
|
|
81
|
-
return pikkuState('queue', 'registrations')
|
|
81
|
+
return pikkuState(null, 'queue', 'registrations')
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* Stop and remove a queue processor
|
|
86
86
|
*/
|
|
87
87
|
export async function removeQueueWorker(name: string): Promise<void> {
|
|
88
|
-
const registrations = pikkuState('queue', 'registrations')
|
|
88
|
+
const registrations = pikkuState(null, 'queue', 'registrations')
|
|
89
89
|
const registration = registrations.get(name)
|
|
90
90
|
|
|
91
91
|
if (!registration) {
|
|
@@ -111,14 +111,14 @@ export async function runQueueJob({
|
|
|
111
111
|
}): Promise<void> {
|
|
112
112
|
const logger = singletonServices.logger
|
|
113
113
|
|
|
114
|
-
const meta = pikkuState('queue', 'meta')
|
|
114
|
+
const meta = pikkuState(null, 'queue', 'meta')
|
|
115
115
|
const processorMeta = meta[job.queueName]
|
|
116
116
|
if (!processorMeta) {
|
|
117
117
|
throw new Error(`Processor metadata not found for: ${job.queueName}`)
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// Get the queue worker registration to access middleware
|
|
121
|
-
const registrations = pikkuState('queue', 'registrations')
|
|
121
|
+
const registrations = pikkuState(null, 'queue', 'registrations')
|
|
122
122
|
const queueWorker = registrations.get(job.queueName)
|
|
123
123
|
if (!queueWorker) {
|
|
124
124
|
throw new Error(`Queue worker registration not found for: ${job.queueName}`)
|
package/src/wirings/rpc/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { PikkuRPCService, rpcService } from './rpc-runner.js'
|
|
2
2
|
export type { PikkuRPC, RPCMeta } from './rpc-types.js'
|
|
@@ -2,15 +2,37 @@ import { CoreServices, PikkuWire } from '../../types/core.types.js'
|
|
|
2
2
|
import { runPikkuFunc } from '../../function/function-runner.js'
|
|
3
3
|
import { pikkuState } from '../../pikku-state.js'
|
|
4
4
|
import { ForbiddenError } from '../../errors/errors.js'
|
|
5
|
-
import { PikkuRPC } from './rpc-types.js'
|
|
5
|
+
import { PikkuRPC, ResolvedFunction } from './rpc-types.js'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a namespaced function reference to package and function names
|
|
9
|
+
* Uses pikkuState to look up the namespace -> package mapping
|
|
10
|
+
*/
|
|
11
|
+
const resolveNamespace = (
|
|
12
|
+
namespacedFunction: string
|
|
13
|
+
): ResolvedFunction | null => {
|
|
14
|
+
const colonIndex = namespacedFunction.indexOf(':')
|
|
15
|
+
if (colonIndex === -1) {
|
|
16
|
+
return null
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const namespace = namespacedFunction.substring(0, colonIndex)
|
|
20
|
+
const functionName = namespacedFunction.substring(colonIndex + 1)
|
|
21
|
+
|
|
22
|
+
const externalPackages = pikkuState(null, 'rpc', 'externalPackages')
|
|
23
|
+
const packageName = externalPackages.get(namespace)
|
|
24
|
+
if (!packageName) {
|
|
25
|
+
return null
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
package: packageName,
|
|
30
|
+
function: functionName,
|
|
31
|
+
}
|
|
10
32
|
}
|
|
11
33
|
|
|
12
34
|
const getPikkuFunctionName = (rpcName: string): string => {
|
|
13
|
-
const rpc = pikkuState('rpc', 'meta')
|
|
35
|
+
const rpc = pikkuState(null, 'rpc', 'meta')
|
|
14
36
|
const rpcMeta = rpc[rpcName]
|
|
15
37
|
if (!rpcMeta) {
|
|
16
38
|
throw new Error(`RPC function not found: ${rpcName}`)
|
|
@@ -24,13 +46,12 @@ export class ContextAwareRPCService {
|
|
|
24
46
|
private services: CoreServices,
|
|
25
47
|
private wire: PikkuWire,
|
|
26
48
|
private options: {
|
|
27
|
-
coerceDataFromSchema?: boolean
|
|
28
49
|
requiresAuth?: boolean
|
|
29
50
|
}
|
|
30
51
|
) {}
|
|
31
52
|
|
|
32
53
|
public async rpcExposed(funcName: string, data: any): Promise<any> {
|
|
33
|
-
const functionMeta = pikkuState('function', 'meta')[funcName]
|
|
54
|
+
const functionMeta = pikkuState(null, 'function', 'meta')[funcName]
|
|
34
55
|
if (!functionMeta) {
|
|
35
56
|
throw new Error(`Function not found: ${funcName}`)
|
|
36
57
|
}
|
|
@@ -55,6 +76,17 @@ export class ContextAwareRPCService {
|
|
|
55
76
|
}
|
|
56
77
|
: undefined,
|
|
57
78
|
}
|
|
79
|
+
|
|
80
|
+
// Check if it's a namespaced function call (e.g., 'stripe:createCharge')
|
|
81
|
+
if (funcName.includes(':')) {
|
|
82
|
+
return this.invokeExternalPackageFunction<In, Out>(
|
|
83
|
+
funcName,
|
|
84
|
+
data,
|
|
85
|
+
updatedWire
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Main package function
|
|
58
90
|
return runPikkuFunc<In, Out>(
|
|
59
91
|
'rpc',
|
|
60
92
|
funcName,
|
|
@@ -65,12 +97,60 @@ export class ContextAwareRPCService {
|
|
|
65
97
|
// but is valid since we don't want to keep creating new wire services
|
|
66
98
|
singletonServices: this.services,
|
|
67
99
|
data: () => data,
|
|
68
|
-
coerceDataFromSchema: this.options.coerceDataFromSchema,
|
|
69
100
|
wire: updatedWire,
|
|
70
101
|
}
|
|
71
102
|
)
|
|
72
103
|
}
|
|
73
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Invoke a function from an external package
|
|
107
|
+
* External packages register their functions in pikkuState under their package name.
|
|
108
|
+
* The function is executed using the parent services (shared singleton services).
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
private async invokeExternalPackageFunction<In = any, Out = any>(
|
|
112
|
+
namespacedFunction: string,
|
|
113
|
+
data: In,
|
|
114
|
+
wire: PikkuWire
|
|
115
|
+
): Promise<Out> {
|
|
116
|
+
// Resolve namespace to package name
|
|
117
|
+
const resolved = resolveNamespace(namespacedFunction)
|
|
118
|
+
if (!resolved) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`Unknown namespace in function reference: ${namespacedFunction}. ` +
|
|
121
|
+
`Make sure the package is registered in externalPackages config.`
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Get the function meta from the external package
|
|
126
|
+
// External packages use function meta, not RPC meta
|
|
127
|
+
const externalFunctionMeta = pikkuState(
|
|
128
|
+
resolved.package,
|
|
129
|
+
'function',
|
|
130
|
+
'meta'
|
|
131
|
+
)
|
|
132
|
+
const funcMeta = externalFunctionMeta[resolved.function]
|
|
133
|
+
if (!funcMeta) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`Function '${resolved.function}' not found in package '${resolved.package}'. ` +
|
|
136
|
+
`Available functions: ${Object.keys(externalFunctionMeta).join(', ') || '(none)'}`
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
const funcName = funcMeta.pikkuFuncName || resolved.function
|
|
140
|
+
|
|
141
|
+
// Execute the function using runPikkuFunc with the external package's state
|
|
142
|
+
// We use the parent services (this.services) since external packages share services
|
|
143
|
+
// Pass the function's tags so tag-based middleware/permissions are applied
|
|
144
|
+
return runPikkuFunc<In, Out>('rpc', namespacedFunction, funcName, {
|
|
145
|
+
auth: this.options.requiresAuth,
|
|
146
|
+
singletonServices: this.services,
|
|
147
|
+
data: () => data,
|
|
148
|
+
wire,
|
|
149
|
+
packageName: resolved.package,
|
|
150
|
+
tags: funcMeta.tags,
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
74
154
|
public async rpcWithWire<In = any, Out = any>(
|
|
75
155
|
rpcName: string,
|
|
76
156
|
data: In,
|
|
@@ -96,7 +176,6 @@ export class ContextAwareRPCService {
|
|
|
96
176
|
auth: this.options.requiresAuth,
|
|
97
177
|
singletonServices: this.services,
|
|
98
178
|
data: () => data,
|
|
99
|
-
coerceDataFromSchema: this.options.coerceDataFromSchema,
|
|
100
179
|
wire: mergedWire,
|
|
101
180
|
}
|
|
102
181
|
)
|
|
@@ -122,13 +201,6 @@ export class PikkuRPCService<
|
|
|
122
201
|
Services extends CoreServices,
|
|
123
202
|
TypedRPC = PikkuRPC,
|
|
124
203
|
> {
|
|
125
|
-
private config?: RPCServiceConfig
|
|
126
|
-
|
|
127
|
-
// Initialize the RPC service with configuration
|
|
128
|
-
initialize(config: RPCServiceConfig) {
|
|
129
|
-
this.config = config
|
|
130
|
-
}
|
|
131
|
-
|
|
132
204
|
// Convenience function for initializing
|
|
133
205
|
getContextRPCService(
|
|
134
206
|
services: Services,
|
|
@@ -137,7 +209,6 @@ export class PikkuRPCService<
|
|
|
137
209
|
depth: number = 0
|
|
138
210
|
): TypedRPC {
|
|
139
211
|
const serviceRPC = new ContextAwareRPCService(services, wire, {
|
|
140
|
-
coerceDataFromSchema: this.config?.coerceDataFromSchema,
|
|
141
212
|
requiresAuth,
|
|
142
213
|
})
|
|
143
214
|
return {
|
|
@@ -153,8 +224,3 @@ export class PikkuRPCService<
|
|
|
153
224
|
|
|
154
225
|
// Create a singleton instance
|
|
155
226
|
export const rpcService = new PikkuRPCService()
|
|
156
|
-
|
|
157
|
-
// Convenience function for initializing
|
|
158
|
-
export const initialize = (config: RPCServiceConfig) => {
|
|
159
|
-
rpcService.initialize(config)
|
|
160
|
-
}
|
|
@@ -6,7 +6,7 @@ import { Logger } from '../../services/index.js'
|
|
|
6
6
|
* @param logger - A logger for logging information.
|
|
7
7
|
*/
|
|
8
8
|
export const logSchedulers = (logger: Logger) => {
|
|
9
|
-
const scheduledTasks = pikkuState('scheduler', 'tasks')
|
|
9
|
+
const scheduledTasks = pikkuState(null, 'scheduler', 'tasks')
|
|
10
10
|
if (scheduledTasks.size === 0) {
|
|
11
11
|
logger.info('No scheduled tasks added')
|
|
12
12
|
return
|