@tumbaland/backend-core 1.46.0 → 1.48.0

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.
@@ -19,9 +19,9 @@ export interface RegisterShutdownOptions {
19
19
  }
20
20
  /**
21
21
  * Registers `SIGINT` and `SIGTERM` handlers that drain the service before the
22
- * process exits: run the optional cleanup hook, stop accepting new HTTP
23
- * connections, then close the MongoDB connection. `SIGTERM` matters most —
24
- * it's the signal Docker/Kubernetes send on stop and rollout, and without a
22
+ * process exits: end any open event streams, run the optional cleanup hook,
23
+ * stop accepting new HTTP connections, then close the MongoDB connection.
24
+ * `SIGTERM` matters most — it's the signal Docker/Kubernetes send on stop and rollout, and without a
25
25
  * handler the process is force-killed with its DB connection still open.
26
26
  *
27
27
  * The handler is idempotent (a second signal while shutting down is ignored)
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/app/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,MAAM,WAAW,uBAAuB;IACtC,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAI,2EAM9B,uBAAuB,KAAG,IAyC5B,CAAC"}
1
+ {"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../../src/app/shutdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAKnC,MAAM,WAAW,uBAAuB;IACtC,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAAI,2EAM9B,uBAAuB,KAAG,IA2C5B,CAAC"}
@@ -6,11 +6,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.registerShutdown = void 0;
7
7
  const logger_1 = __importDefault(require("../logging/logger"));
8
8
  const connection_1 = require("../database/connection");
9
+ const sseStream_1 = require("../sse/sseStream");
9
10
  /**
10
11
  * Registers `SIGINT` and `SIGTERM` handlers that drain the service before the
11
- * process exits: run the optional cleanup hook, stop accepting new HTTP
12
- * connections, then close the MongoDB connection. `SIGTERM` matters most —
13
- * it's the signal Docker/Kubernetes send on stop and rollout, and without a
12
+ * process exits: end any open event streams, run the optional cleanup hook,
13
+ * stop accepting new HTTP connections, then close the MongoDB connection.
14
+ * `SIGTERM` matters most — it's the signal Docker/Kubernetes send on stop and rollout, and without a
14
15
  * handler the process is force-killed with its DB connection still open.
15
16
  *
16
17
  * The handler is idempotent (a second signal while shutting down is ignored)
@@ -30,6 +31,8 @@ const registerShutdown = ({ serviceName, server, disconnectDatabase = true, onSh
30
31
  // Don't let the timer itself keep the event loop alive.
31
32
  forceExit.unref?.();
32
33
  try {
34
+ // An event stream never finishes by itself, and server.close() waits for it.
35
+ (0, sseStream_1.closeAllSseStreams)();
33
36
  if (onShutdown)
34
37
  await onShutdown();
35
38
  if (server) {
@@ -1 +1 @@
1
- {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/app/shutdown.ts"],"names":[],"mappings":";;;;;;AACA,+DAAuC;AACvC,uDAAsD;AAqBtD;;;;;;;;;GASG;AACI,MAAM,gBAAgB,GAAG,CAAC,EAC/B,WAAW,EACX,MAAM,EACN,kBAAkB,GAAG,IAAI,EACzB,UAAU,EACV,gBAAgB,GAAG,MAAM,EACD,EAAQ,EAAE;IAClC,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QAEpB,gBAAM,CAAC,IAAI,CAAC,8CAA8C,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QAE9F,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,gBAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACrB,wDAAwD;QACxD,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;QAEpB,IAAI,CAAC;YACH,IAAI,UAAU;gBAAE,MAAM,UAAU,EAAE,CAAC;YAEnC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACzD,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,kBAAkB;gBAAE,MAAM,IAAA,yBAAY,EAAC,WAAW,CAAC,CAAC;YAExD,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,gBAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE;gBAC7C,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAG,KAAe,EAAE,OAAO;aACjC,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AA/CW,QAAA,gBAAgB,oBA+C3B"}
1
+ {"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../../src/app/shutdown.ts"],"names":[],"mappings":";;;;;;AACA,+DAAuC;AACvC,uDAAsD;AACtD,gDAAsD;AAqBtD;;;;;;;;;GASG;AACI,MAAM,gBAAgB,GAAG,CAAC,EAC/B,WAAW,EACX,MAAM,EACN,kBAAkB,GAAG,IAAI,EACzB,UAAU,EACV,gBAAgB,GAAG,MAAM,EACD,EAAQ,EAAE;IAClC,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAiB,EAAE;QACvD,IAAI,YAAY;YAAE,OAAO;QACzB,YAAY,GAAG,IAAI,CAAC;QAEpB,gBAAM,CAAC,IAAI,CAAC,8CAA8C,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QAE9F,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,gBAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;YACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACrB,wDAAwD;QACxD,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;QAEpB,IAAI,CAAC;YACH,6EAA6E;YAC7E,IAAA,8BAAkB,GAAE,CAAC;YACrB,IAAI,UAAU;gBAAE,MAAM,UAAU,EAAE,CAAC;YAEnC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACzD,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,kBAAkB;gBAAE,MAAM,IAAA,yBAAY,EAAC,WAAW,CAAC,CAAC;YAExD,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,YAAY,CAAC,SAAS,CAAC,CAAC;YACxB,gBAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE;gBAC7C,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAG,KAAe,EAAE,OAAO;aACjC,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpD,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAjDW,QAAA,gBAAgB,oBAiD3B"}
package/dist/index.d.ts CHANGED
@@ -16,6 +16,7 @@ export * from './apiKeys';
16
16
  export * from './fileService';
17
17
  export * from './oauth';
18
18
  export * from './audit';
19
+ export * from './sse';
19
20
  export { authenticateToken, optionalAuth } from './middleware/authMiddleware';
20
21
  export { USER_SESSIONS_COLLECTION, isCurrentSession, isLegacySessionlessToken } from './auth/session';
21
22
  export { requireInternalServiceToken, internalServiceTokenBypass, allowUserOrInternalService, verifyInternalToken, INTERNAL_TOKEN_HEADER, SERVICE_ID_HEADER } from './middleware/internalServiceAuth';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC7K,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGjE,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,eAAe,CAAC;AAG9B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACtG,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC1G,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACnH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACT,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,UAAU,EACV,aAAa,EACb,kBAAkB,EACnB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC7K,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGjE,cAAc,gBAAgB,CAAC;AAG/B,cAAc,UAAU,CAAC;AAGzB,cAAc,WAAW,CAAC;AAG1B,cAAc,eAAe,CAAC;AAG9B,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AAGxB,cAAc,OAAO,CAAC;AAGtB,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACtG,OAAO,EACL,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC1G,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACnH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,QAAQ,EACT,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,UAAU,EACV,aAAa,EACb,kBAAkB,EACnB,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -63,6 +63,8 @@ __exportStar(require("./fileService"), exports);
63
63
  // OAuth 2.1 authorization server, for assistants connecting over MCP
64
64
  __exportStar(require("./oauth"), exports);
65
65
  __exportStar(require("./audit"), exports);
66
+ // Server-Sent Events streams (headers, heartbeat, lifetime, shutdown)
67
+ __exportStar(require("./sse"), exports);
66
68
  // Middleware
67
69
  var authMiddleware_1 = require("./middleware/authMiddleware");
68
70
  Object.defineProperty(exports, "authenticateToken", { enumerable: true, get: function () { return authMiddleware_1.authenticateToken; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,qFAAqF;;;;;;;;;;;;;;;;;;;;;AAErF,gBAAgB;AAChB,qDAAoD;AAA3C,8GAAA,aAAa,OAAA;AAEtB,2CAAkD;AAAzC,4GAAA,gBAAgB,OAAA;AAGzB,UAAU;AACV,2CAAqD;AAA5C,iHAAA,OAAO,OAAU;AAE1B,gBAAgB;AAChB,8DAAoF;AAA3E,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,kHAAA,cAAc,OAAA;AAChD,gEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAG1B,WAAW;AACX,oDAAgE;AAAvD,uGAAA,SAAS,OAAA;AAAE,0GAAA,YAAY,OAAA;AAEhC,SAAS;AACT,oCAA0C;AAAjC,iGAAA,UAAU,OAAA;AAEnB,SAAS;AACT,gDAA6K;AAApK,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,2GAAA,cAAc,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAGhJ,wDAAwD;AACxD,iDAA+B;AAE/B,0DAA0D;AAC1D,2CAAyB;AAEzB,+DAA+D;AAC/D,4CAA0B;AAE1B,+EAA+E;AAC/E,gDAA8B;AAE9B,qEAAqE;AACrE,0CAAwB;AACxB,0CAAwB;AAExB,aAAa;AACb,8DAA8E;AAArE,mHAAA,iBAAiB,OAAA;AAAE,8GAAA,YAAY,OAAA;AACxC,0CAAsG;AAA7F,mHAAA,wBAAwB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,mHAAA,wBAAwB,OAAA;AAC7E,wEAO0C;AANxC,kIAAA,2BAA2B,OAAA;AAC3B,iIAAA,0BAA0B,OAAA;AAC1B,iIAAA,0BAA0B,OAAA;AAC1B,0HAAA,mBAAmB,OAAA;AACnB,4HAAA,qBAAqB,OAAA;AACrB,wHAAA,iBAAiB,OAAA;AAEnB,8DAAmE;AAA1D,sHAAA,oBAAoB,OAAA;AAC7B,0DAAyD;AAAhD,4GAAA,YAAY,OAAA;AACrB,4DAA0G;AAAjG,8GAAA,aAAa,OAAA;AAAE,yHAAA,wBAAwB,OAAA;AAAE,oHAAA,mBAAmB,OAAA;AACrE,kDAAmH;AAA1G,2GAAA,eAAe,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AAAE,+GAAA,mBAAmB,OAAA;AAAE,6GAAA,iBAAiB,OAAA;AACnF,kDAAiD;AAAxC,oGAAA,QAAQ,OAAA;AAKjB,QAAQ;AACR,mDAAmF;AAA1E,oHAAA,qBAAqB,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AACrD,6CAA6E;AAApE,6GAAA,iBAAiB,OAAA;AAAE,uGAAA,WAAW,OAAA;AAAE,qGAAA,SAAS,OAAA;AAElD,2DAA8E;AAArE,mHAAA,gBAAgB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAC5C,mDAAkD;AAAzC,0GAAA,WAAW,OAAA;AAEpB,UAAU;AACV,qCAQmB;AAPjB,4GAAA,iBAAiB,OAAA;AACjB,8GAAA,mBAAmB,OAAA;AACnB,4GAAA,iBAAiB,OAAA;AACjB,gHAAA,qBAAqB,OAAA;AACrB,+GAAA,oBAAoB,OAAA;AACpB,0GAAA,eAAe,OAAA;AACf,mGAAA,QAAQ,OAAA;AAGV,UAAU;AACV,qCAUmB;AATjB,qGAAA,UAAU,OAAA;AACV,oGAAA,SAAS,OAAA;AACT,oGAAA,SAAS,OAAA;AACT,4GAAA,iBAAiB,OAAA;AACjB,0GAAA,eAAe,OAAA;AACf,oGAAA,SAAS,OAAA;AACT,qGAAA,UAAU,OAAA;AACV,wGAAA,aAAa,OAAA;AACb,6GAAA,kBAAkB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { SSE_HEARTBEAT_MS, SSE_MAX_STREAM_AGE_MS, formatSseFrame, openSseStream, openSseStreamCount, closeAllSseStreams } from './sseStream';
2
+ export type { SseStream, OpenSseStreamOptions } from './sseStream';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sse/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.closeAllSseStreams = exports.openSseStreamCount = exports.openSseStream = exports.formatSseFrame = exports.SSE_MAX_STREAM_AGE_MS = exports.SSE_HEARTBEAT_MS = void 0;
4
+ var sseStream_1 = require("./sseStream");
5
+ Object.defineProperty(exports, "SSE_HEARTBEAT_MS", { enumerable: true, get: function () { return sseStream_1.SSE_HEARTBEAT_MS; } });
6
+ Object.defineProperty(exports, "SSE_MAX_STREAM_AGE_MS", { enumerable: true, get: function () { return sseStream_1.SSE_MAX_STREAM_AGE_MS; } });
7
+ Object.defineProperty(exports, "formatSseFrame", { enumerable: true, get: function () { return sseStream_1.formatSseFrame; } });
8
+ Object.defineProperty(exports, "openSseStream", { enumerable: true, get: function () { return sseStream_1.openSseStream; } });
9
+ Object.defineProperty(exports, "openSseStreamCount", { enumerable: true, get: function () { return sseStream_1.openSseStreamCount; } });
10
+ Object.defineProperty(exports, "closeAllSseStreams", { enumerable: true, get: function () { return sseStream_1.closeAllSseStreams; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sse/index.ts"],"names":[],"mappings":";;;AAAA,yCAOqB;AANnB,6GAAA,gBAAgB,OAAA;AAChB,kHAAA,qBAAqB,OAAA;AACrB,2GAAA,cAAc,OAAA;AACd,0GAAA,aAAa,OAAA;AACb,+GAAA,kBAAkB,OAAA;AAClB,+GAAA,kBAAkB,OAAA"}
@@ -0,0 +1,57 @@
1
+ import type { Response } from 'express';
2
+ /**
3
+ * The plumbing of a Server-Sent Events response: headers, heartbeat, a bounded
4
+ * lifetime, cleanup when the client goes, and closing everything at shutdown.
5
+ * What goes down the stream, and to whom, stays with the service.
6
+ *
7
+ * Three things here are not optional:
8
+ *
9
+ * - `X-Accel-Buffering: no` plus `flushHeaders()`. Without them nginx holds the
10
+ * response in its buffer and the client sees an open connection that never
11
+ * delivers anything, which looks exactly like a broken server.
12
+ * - The heartbeat. The proxy closes an idle connection at `proxy_read_timeout`,
13
+ * and a client reconnecting every time looks like a reconnect loop.
14
+ * - The lifetime. Access is checked when a stream opens, and a stream carries
15
+ * that answer for as long as it runs. Recycling it bounds how long someone
16
+ * taken out of a group could keep receiving; EventSource reconnects on its
17
+ * own, re-authenticates, and the client sees nothing.
18
+ */
19
+ /**
20
+ * Heartbeat interval. A named event rather than a comment line: comments are
21
+ * invisible to browser JavaScript, and the client's watchdog needs to see it.
22
+ * iOS suspends a backgrounded EventSource without closing it, so a client that
23
+ * waits for an error event waits forever.
24
+ */
25
+ export declare const SSE_HEARTBEAT_MS = 25000;
26
+ /** How long one stream runs before the server closes it and the client reconnects. */
27
+ export declare const SSE_MAX_STREAM_AGE_MS: number;
28
+ export interface SseStream {
29
+ /** Writes a frame. False once the stream is closed, or if the write failed (which closes it). */
30
+ send(frame: string): boolean;
31
+ /** Ends the response, after one last frame if given. */
32
+ end(lastFrame?: string): void;
33
+ /** Runs once when the stream closes, for whatever reason. At once if it already has. */
34
+ onClose(handler: () => void): void;
35
+ readonly closed: boolean;
36
+ }
37
+ export interface OpenSseStreamOptions {
38
+ heartbeatMs?: number;
39
+ maxAgeMs?: number;
40
+ }
41
+ /** Serialises one event in the SSE wire format. */
42
+ export declare function formatSseFrame(event: string, data: unknown, id?: string | number): string;
43
+ /**
44
+ * Turns a response into an event stream. Check access before calling it: once
45
+ * the headers are out, an error can no longer be a status code, only a frame.
46
+ */
47
+ export declare function openSseStream(res: Response, options?: OpenSseStreamOptions): SseStream;
48
+ /** Open stream count, for `/metrics` and tests. */
49
+ export declare function openSseStreamCount(): number;
50
+ /**
51
+ * Ends every open stream, for shutdown. `server.close()` waits for in-flight
52
+ * responses and an event stream never finishes by itself, so without this a
53
+ * rollout times out and force-exits. The browsers reconnect to the new
54
+ * container on their own. `registerShutdown` calls it.
55
+ */
56
+ export declare function closeAllSseStreams(): void;
57
+ //# sourceMappingURL=sseStream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sseStream.d.ts","sourceRoot":"","sources":["../../src/sse/sseStream.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGxC;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,QAAiB,CAAC;AAIpD,MAAM,WAAW,SAAS;IACxB,iGAAiG;IACjG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,wDAAwD;IACxD,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,wFAAwF;IACxF,OAAO,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,mDAAmD;AACnD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAGzF;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,CA+E1F;AAED,mDAAmD;AACnD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SSE_MAX_STREAM_AGE_MS = exports.SSE_HEARTBEAT_MS = void 0;
7
+ exports.formatSseFrame = formatSseFrame;
8
+ exports.openSseStream = openSseStream;
9
+ exports.openSseStreamCount = openSseStreamCount;
10
+ exports.closeAllSseStreams = closeAllSseStreams;
11
+ const logger_1 = __importDefault(require("../logging/logger"));
12
+ /**
13
+ * The plumbing of a Server-Sent Events response: headers, heartbeat, a bounded
14
+ * lifetime, cleanup when the client goes, and closing everything at shutdown.
15
+ * What goes down the stream, and to whom, stays with the service.
16
+ *
17
+ * Three things here are not optional:
18
+ *
19
+ * - `X-Accel-Buffering: no` plus `flushHeaders()`. Without them nginx holds the
20
+ * response in its buffer and the client sees an open connection that never
21
+ * delivers anything, which looks exactly like a broken server.
22
+ * - The heartbeat. The proxy closes an idle connection at `proxy_read_timeout`,
23
+ * and a client reconnecting every time looks like a reconnect loop.
24
+ * - The lifetime. Access is checked when a stream opens, and a stream carries
25
+ * that answer for as long as it runs. Recycling it bounds how long someone
26
+ * taken out of a group could keep receiving; EventSource reconnects on its
27
+ * own, re-authenticates, and the client sees nothing.
28
+ */
29
+ /**
30
+ * Heartbeat interval. A named event rather than a comment line: comments are
31
+ * invisible to browser JavaScript, and the client's watchdog needs to see it.
32
+ * iOS suspends a backgrounded EventSource without closing it, so a client that
33
+ * waits for an error event waits forever.
34
+ */
35
+ exports.SSE_HEARTBEAT_MS = 25_000;
36
+ /** How long one stream runs before the server closes it and the client reconnects. */
37
+ exports.SSE_MAX_STREAM_AGE_MS = 30 * 60 * 1000;
38
+ const HEARTBEAT_FRAME = 'event: heartbeat\ndata: {}\n\n';
39
+ /** Serialises one event in the SSE wire format. */
40
+ function formatSseFrame(event, data, id) {
41
+ const idLine = id === undefined ? '' : `id: ${id}\n`;
42
+ return `${idLine}event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
43
+ }
44
+ const open = new Set();
45
+ /**
46
+ * Turns a response into an event stream. Check access before calling it: once
47
+ * the headers are out, an error can no longer be a status code, only a frame.
48
+ */
49
+ function openSseStream(res, options = {}) {
50
+ const { heartbeatMs = exports.SSE_HEARTBEAT_MS, maxAgeMs = exports.SSE_MAX_STREAM_AGE_MS } = options;
51
+ res.writeHead(200, {
52
+ 'Content-Type': 'text/event-stream; charset=utf-8',
53
+ 'Cache-Control': 'no-cache, no-transform',
54
+ Connection: 'keep-alive',
55
+ 'X-Accel-Buffering': 'no'
56
+ });
57
+ res.flushHeaders?.();
58
+ let closed = false;
59
+ const handlers = [];
60
+ const runHandler = (handler) => {
61
+ try {
62
+ handler();
63
+ }
64
+ catch (error) {
65
+ // One failing cleanup must not skip the others.
66
+ logger_1.default.warn('SSE close handler failed', { error: error.message });
67
+ }
68
+ };
69
+ const close = () => {
70
+ if (closed)
71
+ return;
72
+ closed = true;
73
+ clearInterval(heartbeat);
74
+ clearTimeout(recycle);
75
+ open.delete(stream);
76
+ for (const handler of handlers.splice(0))
77
+ runHandler(handler);
78
+ };
79
+ const send = (frame) => {
80
+ if (closed)
81
+ return false;
82
+ try {
83
+ res.write(frame);
84
+ return true;
85
+ }
86
+ catch (error) {
87
+ // A half-closed socket throws rather than returning an error.
88
+ logger_1.default.warn('Closing SSE stream after a failed write', { error: error.message });
89
+ close();
90
+ return false;
91
+ }
92
+ };
93
+ const end = (lastFrame) => {
94
+ if (closed)
95
+ return;
96
+ if (lastFrame)
97
+ send(lastFrame);
98
+ try {
99
+ res.end();
100
+ }
101
+ catch {
102
+ // Already gone.
103
+ }
104
+ close();
105
+ };
106
+ const heartbeat = setInterval(() => send(HEARTBEAT_FRAME), heartbeatMs);
107
+ // `retry:` tells the browser how soon to reconnect.
108
+ const recycle = setTimeout(() => end('retry: 1000\n\n'), maxAgeMs);
109
+ const stream = {
110
+ send,
111
+ end,
112
+ onClose(handler) {
113
+ if (closed)
114
+ runHandler(handler);
115
+ else
116
+ handlers.push(handler);
117
+ },
118
+ get closed() {
119
+ return closed;
120
+ }
121
+ };
122
+ open.add(stream);
123
+ // The response, not the request: a GET's request side can report closed as
124
+ // soon as its empty body has been read.
125
+ res.on('close', close);
126
+ res.on('error', close);
127
+ return stream;
128
+ }
129
+ /** Open stream count, for `/metrics` and tests. */
130
+ function openSseStreamCount() {
131
+ return open.size;
132
+ }
133
+ /**
134
+ * Ends every open stream, for shutdown. `server.close()` waits for in-flight
135
+ * responses and an event stream never finishes by itself, so without this a
136
+ * rollout times out and force-exits. The browsers reconnect to the new
137
+ * container on their own. `registerShutdown` calls it.
138
+ */
139
+ function closeAllSseStreams() {
140
+ for (const stream of [...open])
141
+ stream.end('retry: 2000\n\n');
142
+ }
143
+ //# sourceMappingURL=sseStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sseStream.js","sourceRoot":"","sources":["../../src/sse/sseStream.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tumbaland/backend-core",
3
- "version": "1.46.0",
3
+ "version": "1.48.0",
4
4
  "description": "Core shared functionality for Tumbaland backend services",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "release:beta": "commit-and-tag-version --prerelease beta && npm run build && npm publish --access public --tag beta",
18
18
  "test": "jest",
19
19
  "test:coverage": "jest --coverage",
20
- "lint": "eslint .",
20
+ "lint": "vp lint .",
21
21
  "typecheck": "tsc --noEmit"
22
22
  },
23
23
  "keywords": [