@pikku/core 0.12.15 → 0.12.16
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 +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.js +1 -0
- package/dist/middleware/telemetry.d.ts +47 -0
- package/dist/middleware/telemetry.js +106 -0
- package/dist/middleware-runner.js +31 -4
- package/dist/types/core.types.d.ts +13 -0
- package/dist/types/core.types.js +7 -1
- package/dist/wirings/cli/cli-runner.js +2 -1
- package/dist/wirings/http/http.types.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +3 -0
- package/dist/wirings/mcp/mcp.types.d.ts +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/middleware/index.ts +1 -0
- package/src/middleware/telemetry.ts +110 -0
- package/src/middleware-runner.test.ts +149 -1
- package/src/middleware-runner.ts +48 -4
- package/src/types/core.types.ts +28 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +5 -1
- package/src/wirings/cli/cli-runner.ts +2 -1
- package/src/wirings/http/http.types.ts +1 -0
- package/src/wirings/http/pikku-fetch-http-response.ts +4 -0
- package/src/wirings/mcp/mcp.types.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
package/src/middleware-runner.ts
CHANGED
|
@@ -5,10 +5,34 @@ import type {
|
|
|
5
5
|
CorePikkuMiddlewareGroup,
|
|
6
6
|
PikkuWiringTypes,
|
|
7
7
|
MiddlewareMetadata,
|
|
8
|
+
MiddlewarePriority,
|
|
8
9
|
} from './types/core.types.js'
|
|
9
10
|
import { pikkuState } from './pikku-state.js'
|
|
10
11
|
import { freezeDedupe, getTagGroups } from './utils.js'
|
|
11
12
|
|
|
13
|
+
const PRIORITY_ORDER: Record<MiddlewarePriority, number> = {
|
|
14
|
+
highest: 0,
|
|
15
|
+
high: 1,
|
|
16
|
+
medium: 2,
|
|
17
|
+
low: 3,
|
|
18
|
+
lowest: 4,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const getMiddlewarePriority = (fn: CorePikkuMiddleware): number => {
|
|
22
|
+
const priority = (
|
|
23
|
+
fn as CorePikkuMiddleware & { __priority?: MiddlewarePriority }
|
|
24
|
+
).__priority
|
|
25
|
+
return PRIORITY_ORDER[priority ?? 'medium']
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const sortByPriority = (
|
|
29
|
+
middlewares: CorePikkuMiddleware[]
|
|
30
|
+
): CorePikkuMiddleware[] => {
|
|
31
|
+
return middlewares.sort(
|
|
32
|
+
(a, b) => getMiddlewarePriority(a) - getMiddlewarePriority(b)
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
12
36
|
/**
|
|
13
37
|
* Runs a chain of middleware functions in sequence before executing the main function.
|
|
14
38
|
*
|
|
@@ -32,11 +56,16 @@ export const runMiddleware = async <Middleware extends CorePikkuMiddleware>(
|
|
|
32
56
|
middlewares: readonly Middleware[],
|
|
33
57
|
main?: () => Promise<unknown>
|
|
34
58
|
): Promise<unknown> => {
|
|
35
|
-
//
|
|
59
|
+
// Sort by priority if not already sorted (cached middleware is pre-sorted)
|
|
60
|
+
const sorted = isSortedByPriority(middlewares)
|
|
61
|
+
? middlewares
|
|
62
|
+
: ([...middlewares].sort(
|
|
63
|
+
(a, b) => getMiddlewarePriority(a) - getMiddlewarePriority(b)
|
|
64
|
+
) as readonly Middleware[])
|
|
36
65
|
let result: any
|
|
37
66
|
const dispatch = async (index: number): Promise<any> => {
|
|
38
|
-
if (
|
|
39
|
-
return await
|
|
67
|
+
if (sorted && index < sorted.length) {
|
|
68
|
+
return await sorted[index]!(services as any, wire, () =>
|
|
40
69
|
dispatch(index + 1)
|
|
41
70
|
)
|
|
42
71
|
} else if (main) {
|
|
@@ -47,6 +76,20 @@ export const runMiddleware = async <Middleware extends CorePikkuMiddleware>(
|
|
|
47
76
|
return result
|
|
48
77
|
}
|
|
49
78
|
|
|
79
|
+
const isSortedByPriority = (
|
|
80
|
+
middlewares: readonly CorePikkuMiddleware[]
|
|
81
|
+
): boolean => {
|
|
82
|
+
for (let i = 1; i < middlewares.length; i++) {
|
|
83
|
+
if (
|
|
84
|
+
getMiddlewarePriority(middlewares[i]) <
|
|
85
|
+
getMiddlewarePriority(middlewares[i - 1])
|
|
86
|
+
) {
|
|
87
|
+
return false
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return true
|
|
91
|
+
}
|
|
92
|
+
|
|
50
93
|
/**
|
|
51
94
|
* Registers global middleware for a specific tag.
|
|
52
95
|
*
|
|
@@ -231,7 +274,8 @@ export const combineMiddleware = (
|
|
|
231
274
|
resolved.push(...funcMiddleware)
|
|
232
275
|
}
|
|
233
276
|
|
|
234
|
-
//
|
|
277
|
+
// Sort by priority, deduplicate, and freeze
|
|
278
|
+
sortByPriority(resolved)
|
|
235
279
|
middlewareCache[wireType][uid] = freezeDedupe(
|
|
236
280
|
resolved
|
|
237
281
|
) as readonly CorePikkuMiddleware[]
|
package/src/types/core.types.ts
CHANGED
|
@@ -305,6 +305,23 @@ export type CorePikkuMiddleware<
|
|
|
305
305
|
next: () => Promise<void>
|
|
306
306
|
) => Promise<void>
|
|
307
307
|
|
|
308
|
+
/**
|
|
309
|
+
* Priority levels for middleware execution order.
|
|
310
|
+
* Lower priority runs first (outermost in the onion model).
|
|
311
|
+
*
|
|
312
|
+
* - `highest` — Runs first (outermost). Use for telemetry, request tracing.
|
|
313
|
+
* - `high` — Runs early. Use for CORS, rate limiting.
|
|
314
|
+
* - `medium` — Default. Use for auth, most user middleware.
|
|
315
|
+
* - `low` — Runs late. Use for post-auth processing.
|
|
316
|
+
* - `lowest` — Runs last (innermost, closest to function). Use for inner telemetry.
|
|
317
|
+
*/
|
|
318
|
+
export type MiddlewarePriority =
|
|
319
|
+
| 'highest'
|
|
320
|
+
| 'high'
|
|
321
|
+
| 'medium'
|
|
322
|
+
| 'low'
|
|
323
|
+
| 'lowest'
|
|
324
|
+
|
|
308
325
|
/**
|
|
309
326
|
* Configuration object for creating middleware with metadata
|
|
310
327
|
*
|
|
@@ -321,6 +338,8 @@ export type CorePikkuMiddlewareConfig<
|
|
|
321
338
|
name?: string
|
|
322
339
|
/** Optional description of what the middleware does */
|
|
323
340
|
description?: string
|
|
341
|
+
/** Execution priority. Lower runs first (outermost). Defaults to 'medium'. */
|
|
342
|
+
priority?: MiddlewarePriority
|
|
324
343
|
}
|
|
325
344
|
|
|
326
345
|
/**
|
|
@@ -378,7 +397,15 @@ export const pikkuMiddleware = <
|
|
|
378
397
|
| CorePikkuMiddleware<SingletonServices, UserSession>
|
|
379
398
|
| CorePikkuMiddlewareConfig<SingletonServices, UserSession>
|
|
380
399
|
): CorePikkuMiddleware<SingletonServices, UserSession> => {
|
|
381
|
-
|
|
400
|
+
if (typeof middleware === 'function') return middleware
|
|
401
|
+
const func = middleware.func as CorePikkuMiddleware<
|
|
402
|
+
SingletonServices,
|
|
403
|
+
UserSession
|
|
404
|
+
> & { __priority?: MiddlewarePriority }
|
|
405
|
+
if (middleware.priority) {
|
|
406
|
+
func.__priority = middleware.priority
|
|
407
|
+
}
|
|
408
|
+
return func
|
|
382
409
|
}
|
|
383
410
|
|
|
384
411
|
/**
|
|
@@ -70,7 +70,11 @@ export class PikkuMockRequest implements PikkuHTTPRequest {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export class PikkuMockResponse implements PikkuHTTPResponse {
|
|
73
|
-
public _status: number
|
|
73
|
+
public _status: number = 200
|
|
74
|
+
|
|
75
|
+
public get statusCode(): number {
|
|
76
|
+
return this._status
|
|
77
|
+
}
|
|
74
78
|
|
|
75
79
|
status(code: number): this {
|
|
76
80
|
this._status = code
|
|
@@ -500,8 +500,9 @@ export async function executeCLI({
|
|
|
500
500
|
? await createConfig(new LocalVariablesService(), data)
|
|
501
501
|
: ({} as any)
|
|
502
502
|
|
|
503
|
-
// Create services with config
|
|
503
|
+
// Create services with config and register in global state
|
|
504
504
|
const singletonServices = await createSingletonServices(config)
|
|
505
|
+
pikkuState(null, 'package', 'singletonServices', singletonServices)
|
|
505
506
|
|
|
506
507
|
// Execute the command
|
|
507
508
|
await runCLICommand({
|
|
@@ -271,6 +271,7 @@ export interface PikkuHTTPRequest<In = unknown> {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
export interface PikkuHTTPResponse<Out = unknown> {
|
|
274
|
+
readonly statusCode: number
|
|
274
275
|
status(code: number): this
|
|
275
276
|
cookie(name: string, value: string | null, options: SerializeOptions): this
|
|
276
277
|
header(name: string, value: string | string[]): this
|