@nodii/grpc-interceptors 0.5.2 → 0.5.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"cancellation-guard.d.ts","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,kBAAkB,EAGlB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAKlB,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,kBAAuB,GAC9B,gBAAgB,CAgDlB"}
1
+ {"version":3,"file":"cancellation-guard.d.ts","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,kBAAkB,EAGlB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAKlB,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,kBAAuB,GAC9B,gBAAgB,CA8ElB"}
@@ -13,7 +13,18 @@ export function cancellationGuard(config = {}) {
13
13
  return (_methodName, handler) => {
14
14
  return async (call) => {
15
15
  let cancelled = false;
16
- let cancellationPromise = null;
16
+ // `handlerDone` is the in-flight gate. grpc-js 1.14.x fires the server
17
+ // `call.on("cancelled")` event on NORMAL end-of-call teardown — i.e.
18
+ // AFTER the handler has already resolved on the success path. We must
19
+ // only treat the event as a real cancel when it arrives while the
20
+ // handler is still running; once the handler has completed it is a
21
+ // benign teardown signal and must NOT throw `RpcCancelledError`.
22
+ let handlerDone = false;
23
+ // Resolves (never rejects) once the onCancel handlers + grace window
24
+ // settle. Throwing is done explicitly at the await sites so the
25
+ // promise never floats as an unhandled rejection (which happens if a
26
+ // `.then(throw)` chain settles before anything awaits it).
27
+ let gracePromise = null;
17
28
  const onCancelled = () => {
18
29
  cancelled = true;
19
30
  // Fire handlers but cap waits at graceMs.
@@ -26,27 +37,47 @@ export function cancellationGuard(config = {}) {
26
37
  }
27
38
  }));
28
39
  const grace = new Promise((resolve) => setTimeout(resolve, graceMs));
29
- return Promise.race([handlers, grace]).then(() => {
30
- throw new RpcCancelledError();
31
- });
40
+ return Promise.race([handlers, grace]).then(() => undefined);
32
41
  };
33
42
  if (typeof call.on === "function") {
34
43
  call.on("cancelled", () => {
35
- if (!cancellationPromise)
36
- cancellationPromise = onCancelled();
44
+ // Normal end-of-call teardown (grpc-js 1.14.x) fires this AFTER the
45
+ // handler resolved — ignore it so a successful RPC isn't reported
46
+ // as CANCELLED.
47
+ if (handlerDone)
48
+ return;
49
+ if (!gracePromise)
50
+ gracePromise = onCancelled();
37
51
  });
38
52
  }
39
53
  // Fixture path: tests set `call.cancelled = true` before calling.
40
- if (call.cancelled && !cancellationPromise) {
41
- cancellationPromise = onCancelled();
54
+ if (call.cancelled && !gracePromise) {
55
+ gracePromise = onCancelled();
42
56
  }
43
- const handlerPromise = handler(call);
44
- if (cancellationPromise) {
45
- return Promise.race([handlerPromise, cancellationPromise]);
57
+ const handlerPromise = handler(call).then((value) => {
58
+ handlerDone = true;
59
+ return value;
60
+ });
61
+ // Pre-cancel path: cancel was already in-flight before the handler
62
+ // started — race the handler against the grace window, then throw.
63
+ if (gracePromise) {
64
+ const cancelThrow = gracePromise.then(() => {
65
+ throw new RpcCancelledError();
66
+ });
67
+ return Promise.race([handlerPromise, cancelThrow]);
46
68
  }
47
69
  const result = await handlerPromise;
48
- if (cancelled)
70
+ // A cancel that arrived WHILE the handler was still running still throws.
71
+ // `gracePromise` was assigned by `onCancelled()` (runs the onCancel
72
+ // handlers + grace race); await it so those side-effects complete before
73
+ // we surface the error. A cancel arriving AFTER `handlerDone` is gated
74
+ // out in `onCancelled`, so reaching here with `cancelled === true`
75
+ // always means a genuine mid-handler cancel.
76
+ if (cancelled) {
77
+ if (gracePromise)
78
+ await gracePromise;
49
79
  throw new RpcCancelledError();
80
+ }
50
81
  return result;
51
82
  };
52
83
  };
@@ -1 +1 @@
1
- {"version":3,"file":"cancellation-guard.js","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,wEAAwE;AACxE,iEAAiE;AACjE,uEAAuE;AACvE,uEAAuE;AACvE,0EAA0E;AAQ1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,UAAU,iBAAiB,CAC/B,SAA6B,EAAE;IAE/B,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,gBAAgB,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEvC,OAAO,CAAC,WAAmB,EAAE,OAAqB,EAAgB,EAAE;QAClE,OAAO,KAAK,EAAE,IAAe,EAAoB,EAAE;YACjD,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,IAAI,mBAAmB,GAA0B,IAAI,CAAC;YAEtD,MAAM,WAAW,GAAG,GAAmB,EAAE;gBACvC,SAAS,GAAG,IAAI,CAAC;gBACjB,0CAA0C;gBAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CACjC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;oBACvB,IAAI,CAAC;wBACH,MAAM,CAAC,EAAE,CAAC;oBACZ,CAAC;oBAAC,MAAM,CAAC;wBACP,aAAa;oBACf,CAAC;gBACH,CAAC,CAAC,CACH,CAAC;gBACF,MAAM,KAAK,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAC1C,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAC7B,CAAC;gBACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;oBAC/C,MAAM,IAAI,iBAAiB,EAAE,CAAC;gBAChC,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;YAEF,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;gBAClC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;oBACxB,IAAI,CAAC,mBAAmB;wBAAE,mBAAmB,GAAG,WAAW,EAAE,CAAC;gBAChE,CAAC,CAAC,CAAC;YACL,CAAC;YACD,kEAAkE;YAClE,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3C,mBAAmB,GAAG,WAAW,EAAE,CAAC;YACtC,CAAC;YAED,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YACrC,IAAI,mBAAmB,EAAE,CAAC;gBACxB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,mBAAmB,CAAC,CAAC,CAAC;YAC7D,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;YACpC,IAAI,SAAS;gBAAE,MAAM,IAAI,iBAAiB,EAAE,CAAC;YAC7C,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cancellation-guard.js","sourceRoot":"","sources":["../../src/interceptors/cancellation-guard.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,EAAE;AACF,wEAAwE;AACxE,iEAAiE;AACjE,uEAAuE;AACvE,uEAAuE;AACvE,0EAA0E;AAQ1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,MAAM,UAAU,iBAAiB,CAC/B,SAA6B,EAAE;IAE/B,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,gBAAgB,CAAC;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEvC,OAAO,CAAC,WAAmB,EAAE,OAAqB,EAAgB,EAAE;QAClE,OAAO,KAAK,EAAE,IAAe,EAAoB,EAAE;YACjD,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,uEAAuE;YACvE,qEAAqE;YACrE,sEAAsE;YACtE,kEAAkE;YAClE,mEAAmE;YACnE,iEAAiE;YACjE,IAAI,WAAW,GAAG,KAAK,CAAC;YACxB,qEAAqE;YACrE,gEAAgE;YAChE,qEAAqE;YACrE,2DAA2D;YAC3D,IAAI,YAAY,GAAyB,IAAI,CAAC;YAE9C,MAAM,WAAW,GAAG,GAAkB,EAAE;gBACtC,SAAS,GAAG,IAAI,CAAC;gBACjB,0CAA0C;gBAC1C,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CACjC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;oBACvB,IAAI,CAAC;wBACH,MAAM,CAAC,EAAE,CAAC;oBACZ,CAAC;oBAAC,MAAM,CAAC;wBACP,aAAa;oBACf,CAAC;gBACH,CAAC,CAAC,CACH,CAAC;gBACF,MAAM,KAAK,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAC1C,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAC7B,CAAC;gBACF,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC/D,CAAC,CAAC;YAEF,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;gBAClC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;oBACxB,oEAAoE;oBACpE,kEAAkE;oBAClE,gBAAgB;oBAChB,IAAI,WAAW;wBAAE,OAAO;oBACxB,IAAI,CAAC,YAAY;wBAAE,YAAY,GAAG,WAAW,EAAE,CAAC;gBAClD,CAAC,CAAC,CAAC;YACL,CAAC;YACD,kEAAkE;YAClE,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpC,YAAY,GAAG,WAAW,EAAE,CAAC;YAC/B,CAAC;YAED,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBAClD,WAAW,GAAG,IAAI,CAAC;gBACnB,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;YACH,mEAAmE;YACnE,mEAAmE;YACnE,IAAI,YAAY,EAAE,CAAC;gBACjB,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,GAAU,EAAE;oBAChD,MAAM,IAAI,iBAAiB,EAAE,CAAC;gBAChC,CAAC,CAAC,CAAC;gBACH,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC;YACpC,0EAA0E;YAC1E,oEAAoE;YACpE,yEAAyE;YACzE,uEAAuE;YACvE,mEAAmE;YACnE,6CAA6C;YAC7C,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,YAAY;oBAAE,MAAM,YAAY,CAAC;gBACrC,MAAM,IAAI,iBAAiB,EAAE,CAAC;YAChC,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodii/grpc-interceptors",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Substrate gRPC interceptor library for the Nodii microservice stack — 8 cross-cutting interceptors (logging, audit, enrichAuthContext, tenantContext, auditContext, deadlineGuard, cancellationGuard, errorMap) + re-export façade over @nodii/grpc-auth/saga/idempotency + locked-order createStandardServerStack factory. Spec: planning hub docKey=grpc-interceptors.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,14 +24,14 @@
24
24
  "test": "bun test"
25
25
  },
26
26
  "devDependencies": {
27
- "@nodii/audit-chain": "0.8.1",
27
+ "@nodii/audit-chain": "0.9.1",
28
28
  "ioredis": "^5.4.0",
29
29
  "postgres": "^3.4.0",
30
30
  "typescript": "^5.9.3",
31
31
  "@nodii/grpc-auth": "0.9.1",
32
32
  "@nodii/idempotency": "0.6.1",
33
- "@nodii/saga": "0.6.0",
34
- "@nodii/telemetry": "0.9.0"
33
+ "@nodii/saga": "0.8.0",
34
+ "@nodii/telemetry": "0.9.1"
35
35
  },
36
36
  "repository": {
37
37
  "type": "git",