milkio 1.0.0-alpha.90 → 1.0.0-alpha.92
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/execute/execute-id-generator.ts +2 -2
- package/execute/index.ts +1 -1
- package/flow/index.ts +7 -4
- package/listener/index.ts +30 -12
- package/package.json +1 -1
- package/utils/create-id.ts +1 -1
- package/utils/trie.ts +54 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __createId } from '../utils/create-id'
|
|
2
2
|
|
|
3
3
|
export type ExecuteIdGenerator = (request?: Request) => string | Promise<string>
|
|
4
4
|
|
|
5
5
|
export function defineDefaultExecuteIdGenerator() {
|
|
6
|
-
return
|
|
6
|
+
return __createId
|
|
7
7
|
}
|
package/execute/index.ts
CHANGED
|
@@ -86,7 +86,7 @@ export function __initExecuter(generated: GeneratedInit, runtime: any) {
|
|
|
86
86
|
options.createdLogger.request(`headers - ${TSON.stringify(headers.toJSON())}`, `\nparams - ${TSON.stringify(params)}`)
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
const module =
|
|
89
|
+
const module = routeSchema.module
|
|
90
90
|
const meta = (module.default?.meta ? module.default?.meta : {}) as unknown as Readonly<$meta>
|
|
91
91
|
|
|
92
92
|
if (meta.typeSafety === undefined || meta.typeSafety === true) {
|
package/flow/index.ts
CHANGED
|
@@ -14,12 +14,15 @@ export function createFlow<T extends unknown>(): MilkioFlow<T> {
|
|
|
14
14
|
return {
|
|
15
15
|
emit: (flow: T) => {
|
|
16
16
|
if (flows.at(-1)?.blank === true) {
|
|
17
|
-
flows.at(-1)
|
|
17
|
+
const item = flows.at(-1)!;
|
|
18
|
+
item.blank = false;
|
|
19
|
+
item.resolve(flow);
|
|
18
20
|
return;
|
|
21
|
+
} else {
|
|
22
|
+
const resolvers = Promise.withResolvers<T>();
|
|
23
|
+
resolvers.resolve(flow);
|
|
24
|
+
flows.push({ ...resolvers, blank: false });
|
|
19
25
|
}
|
|
20
|
-
const resolvers = Promise.withResolvers<T>();
|
|
21
|
-
resolvers.resolve(flow);
|
|
22
|
-
flows.push({ ...resolvers, blank: false });
|
|
23
26
|
},
|
|
24
27
|
next: async () => {
|
|
25
28
|
if (flows.length === 0) {
|
package/listener/index.ts
CHANGED
|
@@ -2,7 +2,8 @@ import { TSON } from '@southern-aurora/tson'
|
|
|
2
2
|
import { createLogger, exceptionHandler, reject } from '..'
|
|
3
3
|
import type { Mixin, GeneratedInit, $types, ContextHttp, MilkioResponseReject, Results, MilkioResponseSuccess } from '..'
|
|
4
4
|
import type { __initExecuter } from '../execute'
|
|
5
|
-
import {
|
|
5
|
+
import { __createId } from '../utils/create-id'
|
|
6
|
+
import { Trie } from '../utils/trie'
|
|
6
7
|
|
|
7
8
|
export type MilkioHttpRequest = Request
|
|
8
9
|
|
|
@@ -16,7 +17,8 @@ export type MilkioHttpResponse = Mixin<
|
|
|
16
17
|
>
|
|
17
18
|
|
|
18
19
|
export function __initListener(generated: GeneratedInit, runtime: any, executer: ReturnType<typeof __initExecuter>) {
|
|
19
|
-
const port = runtime.port
|
|
20
|
+
const port = runtime.port;
|
|
21
|
+
const trie = new Trie<any>();
|
|
20
22
|
const fetch = async (options: {
|
|
21
23
|
request: MilkioHttpRequest
|
|
22
24
|
envMode?: string
|
|
@@ -50,8 +52,8 @@ export function __initListener(generated: GeneratedInit, runtime: any, executer:
|
|
|
50
52
|
if (runtime.ignorePathLevel !== undefined && runtime.ignorePathLevel !== 0) pathArray = pathArray.slice(runtime.ignorePathLevel)
|
|
51
53
|
const pathString = `/${pathArray.join('/')}`
|
|
52
54
|
|
|
53
|
-
const executeId = runtime?.executeId ? await runtime.executeId(options.request) :
|
|
54
|
-
console.log('executeId', await runtime.executeId(options.request),
|
|
55
|
+
const executeId = runtime?.executeId ? await runtime.executeId(options.request) : __createId()
|
|
56
|
+
console.log('executeId', await runtime.executeId(options.request), __createId())
|
|
55
57
|
|
|
56
58
|
const logger = createLogger(runtime, pathString, executeId)
|
|
57
59
|
runtime.runtime.request.set(executeId, { logger })
|
|
@@ -66,7 +68,7 @@ export function __initListener(generated: GeneratedInit, runtime: any, executer:
|
|
|
66
68
|
'Content-Type': 'application/json',
|
|
67
69
|
},
|
|
68
70
|
}
|
|
69
|
-
|
|
71
|
+
|
|
70
72
|
let finales: Array<() => void | Promise<void>> = []
|
|
71
73
|
|
|
72
74
|
try {
|
|
@@ -96,11 +98,18 @@ export function __initListener(generated: GeneratedInit, runtime: any, executer:
|
|
|
96
98
|
|
|
97
99
|
if (!options.request.headers.get('Accept')?.startsWith('text/event-stream')) {
|
|
98
100
|
// action
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
let routeSchema: any
|
|
102
|
+
routeSchema = trie.get(http.path.string as string)
|
|
103
|
+
if (routeSchema === null) {
|
|
104
|
+
routeSchema = generated.routeSchema?.[http.path.string]
|
|
105
|
+
if (routeSchema === undefined) {
|
|
106
|
+
await runtime.emit('milkio:httpNotFound', { executeId, logger, path: http.path.string as string, http })
|
|
107
|
+
throw reject('NOT_FOUND', { path: http.path.string as string })
|
|
108
|
+
}
|
|
109
|
+
routeSchema.module = await routeSchema.module()
|
|
110
|
+
trie.add(http.path.string as string, routeSchema)
|
|
103
111
|
}
|
|
112
|
+
|
|
104
113
|
if (routeSchema.type !== 'action') throw reject('UNACCEPTABLE', { expected: 'stream', message: `Not acceptable, the Accept in the request header should be "text/event-stream". If you are using the "@milkio/stargate" package, please add \`type: "stream"\` to the execute options.` })
|
|
105
114
|
|
|
106
115
|
const executed = await executer.__execute(routeSchema, {
|
|
@@ -127,7 +136,7 @@ export function __initListener(generated: GeneratedInit, runtime: any, executer:
|
|
|
127
136
|
}
|
|
128
137
|
|
|
129
138
|
await runtime.emit('milkio:httpResponse', { executeId, logger, path: http.path.string as string, http, context: executed.context })
|
|
130
|
-
|
|
139
|
+
|
|
131
140
|
for (const handler of finales) {
|
|
132
141
|
try {
|
|
133
142
|
await handler()
|
|
@@ -141,8 +150,17 @@ export function __initListener(generated: GeneratedInit, runtime: any, executer:
|
|
|
141
150
|
}
|
|
142
151
|
else {
|
|
143
152
|
// stream
|
|
144
|
-
|
|
145
|
-
|
|
153
|
+
let routeSchema: any
|
|
154
|
+
routeSchema = trie.get(http.path.string as string)
|
|
155
|
+
if (routeSchema === null) {
|
|
156
|
+
routeSchema = generated.routeSchema?.[http.path.string]
|
|
157
|
+
if (routeSchema === undefined) {
|
|
158
|
+
await runtime.emit('milkio:httpNotFound', { executeId, logger, path: http.path.string as string, http })
|
|
159
|
+
throw reject('NOT_FOUND', { path: http.path.string as string })
|
|
160
|
+
}
|
|
161
|
+
routeSchema.module = await routeSchema.module()
|
|
162
|
+
trie.add(http.path.string as string, routeSchema)
|
|
163
|
+
}
|
|
146
164
|
if (routeSchema.type !== 'stream') throw reject('UNACCEPTABLE', { expected: 'stream', message: `Not acceptable, the Accept in the request header should be "application/json". If you are using the "@milkio/stargate" package, please remove \`type: "stream"\` to the execute options.` })
|
|
147
165
|
|
|
148
166
|
|
package/package.json
CHANGED
package/utils/create-id.ts
CHANGED
package/utils/trie.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export class Trie<T> {
|
|
2
|
+
private root: TrieNode<T>;
|
|
3
|
+
|
|
4
|
+
constructor() {
|
|
5
|
+
this.root = new TrieNode();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
add(path: string, value: T): void {
|
|
9
|
+
const parts = path.replace(/^\/+|\/+$/g, '').split('/').filter(p => p !== '');
|
|
10
|
+
let currentNode = this.root;
|
|
11
|
+
if (parts.length === 0) {
|
|
12
|
+
currentNode.value = value;
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
for (const part of parts) {
|
|
16
|
+
if (!currentNode.children.has(part)) {
|
|
17
|
+
currentNode.children.set(part, new TrieNode());
|
|
18
|
+
}
|
|
19
|
+
currentNode = currentNode.children.get(part)!;
|
|
20
|
+
}
|
|
21
|
+
currentNode.value = value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get(path: string): T | null {
|
|
25
|
+
const parts = path.replace(/^\/+|\/+$/g, '').split('/').filter(p => p !== '');
|
|
26
|
+
let currentNode = this.root;
|
|
27
|
+
for (const part of parts) {
|
|
28
|
+
if (!currentNode.children.has(part)) return null;
|
|
29
|
+
currentNode = currentNode.children.get(part)!;
|
|
30
|
+
}
|
|
31
|
+
return currentNode.value;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
has(path: string): boolean {
|
|
35
|
+
const parts = path.replace(/^\/+|\/+$/g, '').split('/').filter(p => p !== '');
|
|
36
|
+
let currentNode = this.root;
|
|
37
|
+
if (parts.length === 0) return currentNode.value !== null;
|
|
38
|
+
for (const part of parts) {
|
|
39
|
+
if (!currentNode.children.has(part)) return false;
|
|
40
|
+
else currentNode = currentNode.children.get(part)!;
|
|
41
|
+
}
|
|
42
|
+
return currentNode.value !== null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class TrieNode<T> {
|
|
47
|
+
children: Map<string, TrieNode<T>>;
|
|
48
|
+
value: T | null;
|
|
49
|
+
|
|
50
|
+
constructor() {
|
|
51
|
+
this.children = new Map();
|
|
52
|
+
this.value = null;
|
|
53
|
+
}
|
|
54
|
+
}
|