@hile/model 2.0.2 → 3.0.1

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/README.md CHANGED
@@ -101,9 +101,26 @@ const model = defineModel({
101
101
 
102
102
  - 通过 `ctx.args` 改写入参
103
103
  - 通过 `ctx.state` 在中间件间传递数据
104
- - 不调 `next()` 可短路,`main` 不会执行
104
+ - `main` 的返回值会写入 `ctx.state.result`,`defineModel().handler()` 最终返回 `ctx.state.result`
105
+ - 不调 `next()` 可短路,`main` 不会执行;只要 middleware 写入 `ctx.state.result`,`handler()` 就会返回这个值
106
+ - `await next()` 后可改写 `ctx.state.result`,用于统一响应包装、缓存、幂等、审计等横切逻辑
105
107
  - 最后一个中间件不应调 `next()`
106
108
 
109
+ 短路示例:
110
+
111
+ ```typescript
112
+ const cacheMiddleware: PipelineMiddleware<{ id: string }> = async (ctx, next) => {
113
+ const cached = await readCachedUser(ctx.args.id)
114
+ if (cached) {
115
+ ctx.state.result = cached
116
+ return
117
+ }
118
+
119
+ await next()
120
+ await writeCachedUser(ctx.args.id, ctx.state.result)
121
+ }
122
+ ```
123
+
107
124
  ### 函数简写
108
125
 
109
126
  无 services 和 pipelines 时可直接传入 `main`:
package/dist/model.js CHANGED
@@ -34,15 +34,14 @@ export function defineModel(optionsOrMain) {
34
34
  if (pipelines !== undefined && pipelines.length > 0) {
35
35
  const ctx = new PipelineContext(input);
36
36
  const chain = new Pipeline();
37
- let result;
38
37
  for (const middleware of pipelines) {
39
38
  chain.use(middleware);
40
39
  }
41
40
  chain.use(async (ctx) => {
42
- result = await invokeMain(ctx.args);
41
+ ctx.state.result = await invokeMain(ctx.args);
43
42
  });
44
43
  await chain.dispatch(ctx);
45
- return result;
44
+ return ctx.state.result;
46
45
  }
47
46
  return invokeMain(input);
48
47
  };
@@ -79,6 +79,52 @@ describe('defineModel', () => {
79
79
  });
80
80
  await expect(m.handler({ id: 1 })).resolves.toBe(99);
81
81
  });
82
+ it('pipeline middleware 可短路并返回 ctx.state.result', async () => {
83
+ let mainCalled = false;
84
+ const m = defineModel({
85
+ pipelines: [
86
+ async (ctx) => {
87
+ ctx.state.result = `cached-${ctx.args.id}`;
88
+ },
89
+ ],
90
+ async main(input) {
91
+ mainCalled = true;
92
+ return input.id;
93
+ },
94
+ });
95
+ await expect(m.handler({ id: 1 })).resolves.toBe('cached-1');
96
+ expect(mainCalled).toBe(false);
97
+ });
98
+ it('pipeline middleware 可在 main 后改写 ctx.state.result', async () => {
99
+ const m = defineModel({
100
+ pipelines: [
101
+ async (ctx, next) => {
102
+ await next();
103
+ ctx.state.result = ctx.state.result * 2;
104
+ },
105
+ ],
106
+ async main(input) {
107
+ return input.id + 1;
108
+ },
109
+ });
110
+ await expect(m.handler({ id: 3 })).resolves.toBe(8);
111
+ });
112
+ it('pipeline middleware 短路但未写 result 时返回 undefined', async () => {
113
+ let mainCalled = false;
114
+ const m = defineModel({
115
+ pipelines: [
116
+ async () => {
117
+ // intentionally short-circuit without result
118
+ },
119
+ ],
120
+ async main(input) {
121
+ mainCalled = true;
122
+ return input.id;
123
+ },
124
+ });
125
+ await expect(m.handler({ id: 1 })).resolves.toBeUndefined();
126
+ expect(mainCalled).toBe(false);
127
+ });
82
128
  it('loadModel 调用 handler', async () => {
83
129
  const m = defineModel({
84
130
  services: [A],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hile/model",
3
- "version": "2.0.2",
3
+ "version": "3.0.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -22,7 +22,7 @@
22
22
  "vitest": "^4.0.18"
23
23
  },
24
24
  "dependencies": {
25
- "@hile/core": "^2.0.1"
25
+ "@hile/core": "^2.1.1"
26
26
  },
27
- "gitHead": "2c8011db01f2815e5ce34de964d5492640396828"
27
+ "gitHead": "ffc9f14ed2591075290c77c1bcc0afc67ecf1794"
28
28
  }