@proteinjs/server 3.5.3 → 3.7.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.7.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.6.0...@proteinjs/server@3.7.0) (2026-09-12)
7
+
8
+
9
+ ### Features
10
+
11
+ * **server:** the react app page boots in one round — the server-rendered scripts render concurrently (emitted in registration order), the bundles are deferred and preloaded from the head, and the dev page renders the compile's own entrypoint files (DevClientBuild.assets) stamped ?v=<hash> instead of a hard-coded app.js + vendor.js pair ([206412a](https://github.com/proteinjs/server/commit/206412a0f4176d0052d3ed95b24c4ce5c08c5e06))
12
+
13
+
14
+
15
+
16
+
17
+ # [3.6.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.5.3...@proteinjs/server@3.6.0) (2026-09-10)
18
+
19
+
20
+ ### Features
21
+
22
+ * **server:** GracefulShutdown holds — the SIGTERM drain waits for work no connection represents (a detached chat turn), bounded by shutdown.turnDrainMs ([b534d68](https://github.com/proteinjs/server/commit/b534d68ab14f925a686cb338466ebabd4b40ef75))
23
+
24
+
25
+
26
+
27
+
6
28
  ## [3.5.3](https://github.com/proteinjs/server/compare/@proteinjs/server@3.5.2...@proteinjs/server@3.5.3) (2026-09-01)
7
29
 
8
30
 
@@ -33,7 +33,7 @@ require("react-helmet");
33
33
  require("socket.io");
34
34
  require("typescript");
35
35
  /** Generate Source Graph */
36
- var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeGlobalDataStorage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/NodeGlobalDataStorage.ts\",\"qualifiedName\":\"@proteinjs/server/NodeGlobalDataStorage\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"HOOK_INITIALIZED\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"GLOBAL_DATA\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"{ [id: string]: GlobalData }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/{ [id: string]: GlobalData }\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"environment\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"setData\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"data\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalData\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getData\",\"returnType\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalData\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"initHook\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalDataStorage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalDataStorage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/server-api/GlobalDataStorage\"},{\"v\":\"@proteinjs/server/NodeSessionDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeSessionDataStorage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/NodeSessionDataStorage.ts\",\"qualifiedName\":\"@proteinjs/server/NodeSessionDataStorage\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"HOOK_INITIALIZED\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"SESSION_DATA\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"{ [id: string]: SessionData }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/{ [id: string]: SessionData }\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"environment\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"setData\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"data\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionData\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getData\",\"returnType\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionData\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"clearData\",\"returnType\":{\"packageName\":\"\",\"name\":\"void\",\"filePath\":null,\"qualifiedName\":\"/void\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"initHook\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionDataStorage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionDataStorage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/server-api/SessionDataStorage\"},{\"v\":\"@proteinjs/server/ExtendedIncomingMessage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedIncomingMessage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts\",\"qualifiedName\":\"@proteinjs/server/ExtendedIncomingMessage\",\"properties\":[{\"name\":\"sessionID\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"user\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"http\",\"name\":\"IncomingMessage\",\"filePath\":null,\"qualifiedName\":\"http/IncomingMessage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"http/IncomingMessage\"},{\"v\":\"@proteinjs/server/ExtendedSocket\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedSocket\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts\",\"qualifiedName\":\"@proteinjs/server/ExtendedSocket\",\"properties\":[{\"name\":\"request\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedIncomingMessage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/ExtendedIncomingMessage\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"socket.io\",\"name\":\"Socket\",\"filePath\":null,\"qualifiedName\":\"socket.io/Socket\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"socket.io/Socket\"},{\"v\":\"@proteinjs/server/environmentCache\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"environmentCache\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/envCache.ts\",\"qualifiedName\":\"@proteinjs/server/environmentCache\",\"type\":{\"packageName\":\"\",\"name\":\"GlobalDataCache<Env>\",\"filePath\":null,\"qualifiedName\":\"/GlobalDataCache<Env>\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalDataCache\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalDataCache\",\"typeParameters\":[\"@proteinjs/server-api/Env\"],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/GlobalDataCache\"},{\"v\":\"@proteinjs/server/healthCheck\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"healthCheck\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/routes/healthCheck.ts\",\"qualifiedName\":\"@proteinjs/server/healthCheck\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/Route\"}],\"edges\":[{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"w\":\"@proteinjs/server-api/GlobalDataStorage\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/server/NodeSessionDataStorage\",\"w\":\"@proteinjs/server-api/SessionDataStorage\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/server/ExtendedIncomingMessage\",\"w\":\"http/IncomingMessage\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/server/ExtendedSocket\",\"w\":\"socket.io/Socket\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/server/environmentCache\",\"w\":\"@proteinjs/server-api/GlobalDataCache\",\"value\":\"has type\"},{\"v\":\"@proteinjs/server/healthCheck\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"}]}";
36
+ var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"/() => void\"},{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeGlobalDataStorage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/NodeGlobalDataStorage.ts\",\"qualifiedName\":\"@proteinjs/server/NodeGlobalDataStorage\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"HOOK_INITIALIZED\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"GLOBAL_DATA\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"{ [id: string]: GlobalData }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/{ [id: string]: GlobalData }\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"environment\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"setData\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"data\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalData\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getData\",\"returnType\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalData\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"initHook\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalDataStorage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalDataStorage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/server-api/GlobalDataStorage\"},{\"v\":\"@proteinjs/server/NodeSessionDataStorage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"NodeSessionDataStorage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/NodeSessionDataStorage.ts\",\"qualifiedName\":\"@proteinjs/server/NodeSessionDataStorage\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"HOOK_INITIALIZED\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"SESSION_DATA\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"{ [id: string]: SessionData }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/{ [id: string]: SessionData }\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"environment\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"setData\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"data\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionData\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"getData\",\"returnType\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionData\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionData\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"clearData\",\"returnType\":{\"packageName\":\"\",\"name\":\"void\",\"filePath\":null,\"qualifiedName\":\"/void\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"initHook\",\"returnType\":null,\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionDataStorage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionDataStorage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/server-api/SessionDataStorage\"},{\"v\":\"@proteinjs/server/ExtendedIncomingMessage\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedIncomingMessage\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts\",\"qualifiedName\":\"@proteinjs/server/ExtendedIncomingMessage\",\"properties\":[{\"name\":\"sessionID\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"user\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":true,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"http\",\"name\":\"IncomingMessage\",\"filePath\":null,\"qualifiedName\":\"http/IncomingMessage\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"http/IncomingMessage\"},{\"v\":\"@proteinjs/server/ExtendedSocket\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedSocket\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/SocketIOServerRepo.ts\",\"qualifiedName\":\"@proteinjs/server/ExtendedSocket\",\"properties\":[{\"name\":\"request\",\"type\":{\"packageName\":\"@proteinjs/server\",\"name\":\"ExtendedIncomingMessage\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server/ExtendedIncomingMessage\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"socket.io\",\"name\":\"Socket\",\"filePath\":null,\"qualifiedName\":\"socket.io/Socket\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"socket.io/Socket\"},{\"v\":\"@proteinjs/server/environmentCache\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"environmentCache\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/envCache.ts\",\"qualifiedName\":\"@proteinjs/server/environmentCache\",\"type\":{\"packageName\":\"\",\"name\":\"GlobalDataCache<Env>\",\"filePath\":null,\"qualifiedName\":\"/GlobalDataCache<Env>\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"GlobalDataCache\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/GlobalDataCache\",\"typeParameters\":[\"@proteinjs/server-api/Env\"],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/GlobalDataCache\"},{\"v\":\"@proteinjs/server/healthCheck\",\"value\":{\"packageName\":\"@proteinjs/server\",\"name\":\"healthCheck\",\"filePath\":\"/home/runner/work/server/server/packages/server/src/routes/healthCheck.ts\",\"qualifiedName\":\"@proteinjs/server/healthCheck\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/Route\"}],\"edges\":[{\"v\":\"@proteinjs/server/NodeGlobalDataStorage\",\"w\":\"@proteinjs/server-api/GlobalDataStorage\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/server/NodeSessionDataStorage\",\"w\":\"@proteinjs/server-api/SessionDataStorage\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/server/ExtendedIncomingMessage\",\"w\":\"http/IncomingMessage\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/server/ExtendedSocket\",\"w\":\"socket.io/Socket\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/server/environmentCache\",\"w\":\"@proteinjs/server-api/GlobalDataCache\",\"value\":\"has type\"},{\"v\":\"@proteinjs/server/healthCheck\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"}]}";
37
37
  /** Generate Source Links */
38
38
  var NodeGlobalDataStorage_1 = require("../src/NodeGlobalDataStorage");
39
39
  var NodeSessionDataStorage_1 = require("../src/NodeSessionDataStorage");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,4BAA0B;AAC1B,6BAA2B;AAC3B,iCAA+B;AAC/B,iCAA+B;AAC/B,gCAA8B;AAC9B,uBAAqB;AACrB,yBAAuB;AACvB,kBAAgB;AAChB,mBAAiB;AACjB,2BAAyB;AACzB,oBAAkB;AAClB,0BAAwB;AACxB,mBAAiB;AACjB,iBAAe;AACf,wBAAsB;AACtB,qBAAmB;AACnB,sBAAoB;AAGpB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,y8RAAy8R,CAAC;AAG99R,4BAA4B;AAE5B,sEAAqE;AACrE,wEAAuE;AACvE,4CAAmD;AACnD,yDAAwD;AAExD,IAAM,WAAW,GAAG;IACnB,yCAAyC,EAAE,6CAAqB;IAChE,0CAA0C,EAAE,+CAAsB;IAClE,oCAAoC,EAAE,2BAAgB;IACtD,+BAA+B,EAAE,yBAAW;CAC5C,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,4BAA0B;AAC1B,6BAA2B;AAC3B,iCAA+B;AAC/B,iCAA+B;AAC/B,gCAA8B;AAC9B,uBAAqB;AACrB,yBAAuB;AACvB,kBAAgB;AAChB,mBAAiB;AACjB,2BAAyB;AACzB,oBAAkB;AAClB,0BAAwB;AACxB,mBAAiB;AACjB,iBAAe;AACf,wBAAsB;AACtB,qBAAmB;AACnB,sBAAoB;AAGpB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,i+RAAi+R,CAAC;AAGt/R,4BAA4B;AAE5B,sEAAqE;AACrE,wEAAuE;AACvE,4CAAmD;AACnD,yDAAwD;AAExD,IAAM,WAAW,GAAG;IACnB,yCAAyC,EAAE,6CAAqB;IAChE,0CAA0C,EAAE,+CAAsB;IAClE,oCAAoC,EAAE,2BAAgB;IACtD,+BAA+B,EAAE,yBAAW;CAC5C,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
@@ -13,6 +13,12 @@ export type DevClientBuildInfo = {
13
13
  builtAt: string;
14
14
  durationMs?: number;
15
15
  errorCount: number;
16
+ /**
17
+ * The entrypoint's script files (`app.js`, `vendor.js`, …) in the compile's own load order —
18
+ * the dev page's bundle tags are rendered from THIS list (reactApp.ts), so the page follows the
19
+ * chunk graph the webpack config declares instead of a hard-coded pair of names.
20
+ */
21
+ assets: string[];
16
22
  };
17
23
  export declare class DevClientBuild {
18
24
  private static current;
@@ -1 +1 @@
1
- {"version":3,"file":"DevClientBuild.d.ts","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAiC;IAEvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAI7C,MAAM,CAAC,GAAG,IAAI,kBAAkB,GAAG,SAAS;CAG7C"}
1
+ {"version":3,"file":"DevClientBuild.d.ts","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAiC;IAEvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAI7C,MAAM,CAAC,GAAG,IAAI,kBAAkB,GAAG,SAAS;CAG7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"DevClientBuild.js","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":";;;AAiBA;IAAA;IAUA,CAAC;IAPQ,qBAAM,GAAb,UAAc,IAAwB;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEM,kBAAG,GAAV;QACE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACH,qBAAC;AAAD,CAAC,AAVD,IAUC;AAVY,wCAAc"}
1
+ {"version":3,"file":"DevClientBuild.js","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":";;;AAuBA;IAAA;IAUA,CAAC;IAPQ,qBAAM,GAAb,UAAc,IAAwB;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEM,kBAAG,GAAV;QACE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACH,qBAAC;AAAD,CAAC,AAVD,IAUC;AAVY,wCAAc"}
@@ -1,6 +1,21 @@
1
1
  /// <reference types="node" />
2
2
  import { Server as HttpServer } from 'http';
3
3
  import { ServerConfig } from '@proteinjs/server-api';
4
+ /** Releases a hold taken with {@link GracefulShutdown.hold}. Idempotent. */
5
+ export type HoldRelease = () => void;
6
+ /** A hold outstanding on the process: its label plus whatever the holder attached for the logs. */
7
+ export type Hold = {
8
+ label: string;
9
+ context?: Record<string, unknown>;
10
+ };
11
+ /**
12
+ * Follows the process's holds as they come and go — the dev supervisor's lease projection
13
+ * (@n3xah/util-server's ServePackageHold) is the one consumer; it never decides anything here.
14
+ */
15
+ export type HoldObserver = {
16
+ acquired?: (label: string) => void;
17
+ released?: (label: string) => void;
18
+ };
4
19
  /**
5
20
  * The one owner of the server's shutdown state. Installed by `startServer` before the listener
6
21
  * opens; the `/health-check` route reads `isShuttingDown()` — no other flag system exists.
@@ -15,25 +30,48 @@ import { ServerConfig } from '@proteinjs/server-api';
15
30
  * 2. The listener closes (socket.io clients are disconnected, and `io.close()` closes the
16
31
  * http server it is attached to), idle keep-alive connections are closed, and in-flight
17
32
  * requests run to completion.
18
- * 3. The drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining connections are
19
- * force-closed. Either way the exit code is 0 a drained shutdown is not a crash.
33
+ * 3. The process WAITS for its HOLDS (`hold(label)` below) to release, bounded by
34
+ * `shutdown.turnDrainMs`: work that must not die with the process and that no HTTP
35
+ * connection represents — the canonical holder is a chat turn whose client has gone
36
+ * (the response detached, the model still writing, nothing persisted yet). Past the
37
+ * bound every hold still outstanding is logged by label and abandoned.
38
+ * 4. The connection drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining
39
+ * connections are force-closed. Either way the exit code is 0 — a drained shutdown is
40
+ * not a crash.
20
41
  * SIGINT → exit 0 immediately (dev ctrl-C: fast and quiet; nothing needs flushing).
21
42
  * exit 86 → NOT this class's concern: `process.exit(86)` is the ServePackageSupervisor
22
43
  * restart-request contract (a liveness monitor giving up on a dependency); it is not
23
44
  * signal-driven and is untouched by these handlers.
24
45
  *
46
+ * Holds are a process-wide static seam so a holder never needs the server instance (a turn
47
+ * registry, a suite with no listener): `hold(label, context)` returns the release; the same
48
+ * label held twice is one hold (the release is shared — the turn registry's idempotence);
49
+ * `holds()` lists what is outstanding, in acquisition order; `observeHolds` lets the dev
50
+ * supervisor's lease follow the same set, so a holder declares itself ONCE and both the
51
+ * pre-signal restart deferral (dev) and the post-SIGTERM drain (prod) honor it.
52
+ *
53
+ * Why holds and not connections: the 2026-09-05 prod kill — a phone locked mid-turn, the route
54
+ * detached the dead response and the turn ran on to persist, GKE's autoscaler evicted the pod,
55
+ * and this drain saw NO connection in flight, so `process.exit(0)` ran 5 s after SIGTERM with the
56
+ * model call 32 s in. Nothing persisted, nothing logged (plans/FREE_AGENT.md §M.14).
57
+ *
25
58
  * A SIGTERM before the listener is open (mid-boot kill) exits 0 immediately — nothing is
26
59
  * registered anywhere and nothing is in flight.
27
60
  *
28
61
  * Supervisor compatibility (dev): ServePackageSupervisor SIGTERMs the child's process group and
29
62
  * escalates to SIGKILL after its grace period (default 10s); its exit handler ignores exit codes
30
63
  * for kills it initiated, so the drain-then-exit-0 shape cannot be misread. DEVELOPMENT defaults
31
- * `drainDelayMs` to 0 so supervised restarts stay fast.
64
+ * `drainDelayMs` to 0 so supervised restarts stay fast; a turn in flight under the supervisor is
65
+ * covered BEFORE the signal by its lease (the hold projection), not by this drain.
32
66
  */
33
67
  export declare class GracefulShutdown {
34
68
  private server;
35
69
  private config;
36
70
  private static instance?;
71
+ private static holds;
72
+ private static holdObservers;
73
+ private static holdWaiters;
74
+ private static staticLogger;
37
75
  private shuttingDown;
38
76
  private logger;
39
77
  private constructor();
@@ -41,10 +79,25 @@ export declare class GracefulShutdown {
41
79
  static install(server: HttpServer, config: ServerConfig): void;
42
80
  /** The readiness seam: `/health-check` reports 503 whenever this is true. */
43
81
  static isShuttingDown(): boolean;
82
+ /**
83
+ * Keep the process alive through a SIGTERM drain until the returned release is called (bounded
84
+ * by `shutdown.turnDrainMs`). `label` names the work in the drain's logs (`chat-turn:<id>`);
85
+ * `context` rides beside it (chat id, user id). Holding a label already held returns the
86
+ * existing release — one hold per label.
87
+ */
88
+ static hold(label: string, context?: Record<string, unknown>): HoldRelease;
89
+ /** Every hold outstanding right now, in acquisition order. */
90
+ static outstandingHolds(): Hold[];
91
+ /** Follow holds as they are acquired and released. Returns the unsubscribe. */
92
+ static observeHolds(observer: HoldObserver): () => void;
44
93
  private drainAndExit;
94
+ private drainHolds;
45
95
  private exitNow;
46
96
  private drainDelayMs;
47
97
  private drainTimeoutMs;
98
+ private turnDrainMs;
99
+ private static whenNoHolds;
100
+ private static notify;
48
101
  /** Await a promise with a deadline; true if it settled in time. */
49
102
  private settled;
50
103
  private sleep;
@@ -1 +1 @@
1
- {"version":3,"file":"GracefulShutdown.d.ts","sourceRoot":"","sources":["../../src/GracefulShutdown.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAmB;IAC3C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAA4C;IAE1D,OAAO;IAKP,iFAAiF;IACjF,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IAU9D,6EAA6E;IAC7E,MAAM,CAAC,cAAc,IAAI,OAAO;YAIlB,YAAY;IAwC1B,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;IAItB,mEAAmE;YACrD,OAAO;IAUrB,OAAO,CAAC,KAAK;CAGd"}
1
+ {"version":3,"file":"GracefulShutdown.d.ts","sourceRoot":"","sources":["../../src/GracefulShutdown.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAIrD,4EAA4E;AAC5E,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,mGAAmG;AACnG,MAAM,MAAM,IAAI,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAExE;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAEtG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,qBAAa,gBAAgB;IAUzB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IAVhB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAmB;IAC3C,OAAO,CAAC,MAAM,CAAC,KAAK,CAA2D;IAC/E,OAAO,CAAC,MAAM,CAAC,aAAa,CAA2B;IACvD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAyB;IACnD,OAAO,CAAC,MAAM,CAAC,YAAY,CAA4C;IACvE,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAA4C;IAE1D,OAAO;IAKP,iFAAiF;IACjF,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IAU9D,6EAA6E;IAC7E,MAAM,CAAC,cAAc,IAAI,OAAO;IAIhC;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW;IAuB1E,8DAA8D;IAC9D,MAAM,CAAC,gBAAgB,IAAI,IAAI,EAAE;IAIjC,+EAA+E;IAC/E,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,IAAI;YAOzC,YAAY;YA6CZ,UAAU;IAqBxB,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,MAAM,CAAC,WAAW;IAO1B,OAAO,CAAC,MAAM,CAAC,MAAM;IAcrB,mEAAmE;YACrD,OAAO;IAUrB,OAAO,CAAC,KAAK;CAGd"}
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
14
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
15
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -53,20 +64,39 @@ var SocketIOServerRepo_1 = require("./SocketIOServerRepo");
53
64
  * 2. The listener closes (socket.io clients are disconnected, and `io.close()` closes the
54
65
  * http server it is attached to), idle keep-alive connections are closed, and in-flight
55
66
  * requests run to completion.
56
- * 3. The drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining connections are
57
- * force-closed. Either way the exit code is 0 a drained shutdown is not a crash.
67
+ * 3. The process WAITS for its HOLDS (`hold(label)` below) to release, bounded by
68
+ * `shutdown.turnDrainMs`: work that must not die with the process and that no HTTP
69
+ * connection represents — the canonical holder is a chat turn whose client has gone
70
+ * (the response detached, the model still writing, nothing persisted yet). Past the
71
+ * bound every hold still outstanding is logged by label and abandoned.
72
+ * 4. The connection drain is BOUNDED by `shutdown.drainTimeoutMs`: past it, remaining
73
+ * connections are force-closed. Either way the exit code is 0 — a drained shutdown is
74
+ * not a crash.
58
75
  * SIGINT → exit 0 immediately (dev ctrl-C: fast and quiet; nothing needs flushing).
59
76
  * exit 86 → NOT this class's concern: `process.exit(86)` is the ServePackageSupervisor
60
77
  * restart-request contract (a liveness monitor giving up on a dependency); it is not
61
78
  * signal-driven and is untouched by these handlers.
62
79
  *
80
+ * Holds are a process-wide static seam so a holder never needs the server instance (a turn
81
+ * registry, a suite with no listener): `hold(label, context)` returns the release; the same
82
+ * label held twice is one hold (the release is shared — the turn registry's idempotence);
83
+ * `holds()` lists what is outstanding, in acquisition order; `observeHolds` lets the dev
84
+ * supervisor's lease follow the same set, so a holder declares itself ONCE and both the
85
+ * pre-signal restart deferral (dev) and the post-SIGTERM drain (prod) honor it.
86
+ *
87
+ * Why holds and not connections: the 2026-09-05 prod kill — a phone locked mid-turn, the route
88
+ * detached the dead response and the turn ran on to persist, GKE's autoscaler evicted the pod,
89
+ * and this drain saw NO connection in flight, so `process.exit(0)` ran 5 s after SIGTERM with the
90
+ * model call 32 s in. Nothing persisted, nothing logged (plans/FREE_AGENT.md §M.14).
91
+ *
63
92
  * A SIGTERM before the listener is open (mid-boot kill) exits 0 immediately — nothing is
64
93
  * registered anywhere and nothing is in flight.
65
94
  *
66
95
  * Supervisor compatibility (dev): ServePackageSupervisor SIGTERMs the child's process group and
67
96
  * escalates to SIGKILL after its grace period (default 10s); its exit handler ignores exit codes
68
97
  * for kills it initiated, so the drain-then-exit-0 shape cannot be misread. DEVELOPMENT defaults
69
- * `drainDelayMs` to 0 so supervised restarts stay fast.
98
+ * `drainDelayMs` to 0 so supervised restarts stay fast; a turn in flight under the supervisor is
99
+ * covered BEFORE the signal by its lease (the hold projection), not by this drain.
70
100
  */
71
101
  var GracefulShutdown = /** @class */ (function () {
72
102
  function GracefulShutdown(server, config) {
@@ -90,9 +120,50 @@ var GracefulShutdown = /** @class */ (function () {
90
120
  var _a, _b;
91
121
  return (_b = (_a = GracefulShutdown.instance) === null || _a === void 0 ? void 0 : _a.shuttingDown) !== null && _b !== void 0 ? _b : false;
92
122
  };
123
+ /**
124
+ * Keep the process alive through a SIGTERM drain until the returned release is called (bounded
125
+ * by `shutdown.turnDrainMs`). `label` names the work in the drain's logs (`chat-turn:<id>`);
126
+ * `context` rides beside it (chat id, user id). Holding a label already held returns the
127
+ * existing release — one hold per label.
128
+ */
129
+ GracefulShutdown.hold = function (label, context) {
130
+ var existing = GracefulShutdown.holds.get(label);
131
+ if (existing) {
132
+ return existing.release;
133
+ }
134
+ var release = function () {
135
+ var _a;
136
+ if (((_a = GracefulShutdown.holds.get(label)) === null || _a === void 0 ? void 0 : _a.release) !== release) {
137
+ return; // already released (or the label re-held since — that hold has its own release)
138
+ }
139
+ GracefulShutdown.holds.delete(label);
140
+ GracefulShutdown.notify('released', label);
141
+ if (GracefulShutdown.holds.size === 0) {
142
+ var waiters = GracefulShutdown.holdWaiters.splice(0, GracefulShutdown.holdWaiters.length);
143
+ for (var _i = 0, waiters_1 = waiters; _i < waiters_1.length; _i++) {
144
+ var resolve = waiters_1[_i];
145
+ resolve();
146
+ }
147
+ }
148
+ };
149
+ GracefulShutdown.holds.set(label, { hold: context ? { label: label, context: context } : { label: label }, release: release });
150
+ GracefulShutdown.notify('acquired', label);
151
+ return release;
152
+ };
153
+ /** Every hold outstanding right now, in acquisition order. */
154
+ GracefulShutdown.outstandingHolds = function () {
155
+ return Array.from(GracefulShutdown.holds.values()).map(function (entry) { return (__assign({}, entry.hold)); });
156
+ };
157
+ /** Follow holds as they are acquired and released. Returns the unsubscribe. */
158
+ GracefulShutdown.observeHolds = function (observer) {
159
+ GracefulShutdown.holdObservers.add(observer);
160
+ return function () {
161
+ GracefulShutdown.holdObservers.delete(observer);
162
+ };
163
+ };
93
164
  GracefulShutdown.prototype.drainAndExit = function () {
94
165
  return __awaiter(this, void 0, void 0, function () {
95
- var drainDelayMs, drainTimeoutMs, drained, io;
166
+ var drainDelayMs, drainTimeoutMs, turnDrainMs, drained, io;
96
167
  var _this = this;
97
168
  return __generator(this, function (_a) {
98
169
  switch (_a.label) {
@@ -107,8 +178,10 @@ var GracefulShutdown = /** @class */ (function () {
107
178
  }
108
179
  drainDelayMs = this.drainDelayMs();
109
180
  drainTimeoutMs = this.drainTimeoutMs();
181
+ turnDrainMs = this.turnDrainMs();
110
182
  this.logger.info({
111
- message: "Received SIGTERM \u2014 /health-check now reports 503; accepting connections for another ".concat(drainDelayMs, "ms, then draining in-flight requests (bound: ").concat(drainTimeoutMs, "ms)"),
183
+ message: "Received SIGTERM \u2014 /health-check now reports 503; accepting connections for another ".concat(drainDelayMs, "ms, then draining in-flight requests (bound: ").concat(drainTimeoutMs, "ms) and ").concat(GracefulShutdown.holds.size, " hold(s) (bound: ").concat(turnDrainMs, "ms)"),
184
+ obj: { holds: GracefulShutdown.outstandingHolds() },
112
185
  });
113
186
  // 1. Readiness-propagation window: the LB observes the 503 while we still serve normally.
114
187
  return [4 /*yield*/, this.sleep(drainDelayMs)];
@@ -124,9 +197,16 @@ var GracefulShutdown = /** @class */ (function () {
124
197
  this.server.close();
125
198
  }
126
199
  this.server.closeIdleConnections();
127
- return [4 /*yield*/, this.settled(drained, drainTimeoutMs)];
200
+ // 3. Holds: work no connection represents (a detached chat turn). In-flight requests keep
201
+ // running meanwhile — the listener is closed, existing connections are not. Bounded.
202
+ return [4 /*yield*/, this.drainHolds(turnDrainMs)];
128
203
  case 2:
129
- // 3. Bounded: past the drain timeout, force-close what remains. Exit 0 either way.
204
+ // 3. Holds: work no connection represents (a detached chat turn). In-flight requests keep
205
+ // running meanwhile — the listener is closed, existing connections are not. Bounded.
206
+ _a.sent();
207
+ return [4 /*yield*/, this.settled(drained, drainTimeoutMs)];
208
+ case 3:
209
+ // 4. Bounded: past the drain timeout, force-close what remains. Exit 0 either way.
130
210
  if (!(_a.sent())) {
131
211
  this.logger.warn({
132
212
  message: "Drain exceeded its ".concat(drainTimeoutMs, "ms bound \u2014 force-closing the remaining connections"),
@@ -140,6 +220,37 @@ var GracefulShutdown = /** @class */ (function () {
140
220
  });
141
221
  });
142
222
  };
223
+ GracefulShutdown.prototype.drainHolds = function (turnDrainMs) {
224
+ return __awaiter(this, void 0, void 0, function () {
225
+ var abandoned;
226
+ return __generator(this, function (_a) {
227
+ switch (_a.label) {
228
+ case 0:
229
+ if (GracefulShutdown.holds.size === 0) {
230
+ return [2 /*return*/];
231
+ }
232
+ this.logger.info({
233
+ message: "Listener closed \u2014 waiting for ".concat(GracefulShutdown.holds.size, " hold(s) to release (bound: ").concat(turnDrainMs, "ms)"),
234
+ obj: { holds: GracefulShutdown.outstandingHolds() },
235
+ });
236
+ return [4 /*yield*/, this.settled(GracefulShutdown.whenNoHolds(), turnDrainMs)];
237
+ case 1:
238
+ if (_a.sent()) {
239
+ this.logger.info({ message: "Every hold released \u2014 continuing the drain" });
240
+ return [2 /*return*/];
241
+ }
242
+ abandoned = GracefulShutdown.outstandingHolds();
243
+ this.logger.warn({
244
+ message: "Hold drain exceeded its ".concat(turnDrainMs, "ms bound \u2014 abandoning ").concat(abandoned.length, " hold(s): ").concat(abandoned
245
+ .map(function (hold) { return hold.label; })
246
+ .join(', ')),
247
+ obj: { holds: abandoned },
248
+ });
249
+ return [2 /*return*/];
250
+ }
251
+ });
252
+ });
253
+ };
143
254
  GracefulShutdown.prototype.exitNow = function () {
144
255
  this.shuttingDown = true;
145
256
  this.logger.info({ message: "Received SIGINT \u2014 exiting immediately" });
@@ -156,6 +267,32 @@ var GracefulShutdown = /** @class */ (function () {
156
267
  var _a, _b;
157
268
  return (_b = (_a = this.config.shutdown) === null || _a === void 0 ? void 0 : _a.drainTimeoutMs) !== null && _b !== void 0 ? _b : 30000;
158
269
  };
270
+ GracefulShutdown.prototype.turnDrainMs = function () {
271
+ var _a, _b;
272
+ return (_b = (_a = this.config.shutdown) === null || _a === void 0 ? void 0 : _a.turnDrainMs) !== null && _b !== void 0 ? _b : 240000;
273
+ };
274
+ GracefulShutdown.whenNoHolds = function () {
275
+ if (GracefulShutdown.holds.size === 0) {
276
+ return Promise.resolve();
277
+ }
278
+ return new Promise(function (resolve) { return GracefulShutdown.holdWaiters.push(resolve); });
279
+ };
280
+ GracefulShutdown.notify = function (event, label) {
281
+ var _a;
282
+ for (var _i = 0, _b = Array.from(GracefulShutdown.holdObservers); _i < _b.length; _i++) {
283
+ var observer = _b[_i];
284
+ try {
285
+ (_a = observer[event]) === null || _a === void 0 ? void 0 : _a.call(observer, label);
286
+ }
287
+ catch (error) {
288
+ // An observer follows the holds; its failure never touches the hold itself.
289
+ GracefulShutdown.staticLogger.warn({
290
+ message: "A hold observer threw on ".concat(event),
291
+ obj: { label: label, error: error === null || error === void 0 ? void 0 : error.message },
292
+ });
293
+ }
294
+ }
295
+ };
159
296
  /** Await a promise with a deadline; true if it settled in time. */
160
297
  GracefulShutdown.prototype.settled = function (promise, ms) {
161
298
  return __awaiter(this, void 0, void 0, function () {
@@ -178,6 +315,10 @@ var GracefulShutdown = /** @class */ (function () {
178
315
  GracefulShutdown.prototype.sleep = function (ms) {
179
316
  return new Promise(function (resolve) { return setTimeout(resolve, ms); });
180
317
  };
318
+ GracefulShutdown.holds = new Map();
319
+ GracefulShutdown.holdObservers = new Set();
320
+ GracefulShutdown.holdWaiters = [];
321
+ GracefulShutdown.staticLogger = new logger_1.Logger({ name: 'GracefulShutdown' });
181
322
  return GracefulShutdown;
182
323
  }());
183
324
  exports.GracefulShutdown = GracefulShutdown;
@@ -1 +1 @@
1
- {"version":3,"file":"GracefulShutdown.js","sourceRoot":"","sources":["../../src/GracefulShutdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GracefulShutdown.js","sourceRoot":"","sources":["../../src/GracefulShutdown.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactApp.d.ts","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAA4B,MAAM,uBAAuB,CAAC;AAU/E,eAAO,MAAM,cAAc,iBAAkB,YAAY;;;yBAI1B,GAAG,YAAY,GAAG,KAAG,QAAQ,IAAI,CAAC;CAsChE,CAAC"}
1
+ {"version":3,"file":"reactApp.d.ts","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAA4B,MAAM,uBAAuB,CAAC;AAU/E,eAAO,MAAM,cAAc,iBAAkB,YAAY;;;yBAI1B,GAAG,YAAY,GAAG,KAAG,QAAQ,IAAI,CAAC;CA+ChE,CAAC"}