@3sixty/engine-server 0.20.0-next.3 → 0.20.0-next.4

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.
@@ -172,13 +172,14 @@ export class EngineServer {
172
172
  }
173
173
  /**
174
174
  * Start the engine server.
175
+ * @param engineReady Called once the engine has started and the routes are built, before the web server accepts requests.
175
176
  * @returns A promise that resolves when the server has started and is ready to accept requests.
176
177
  */
177
- async start() {
178
+ async start(engineReady) {
178
179
  await this._engineCore.start();
179
180
  try {
180
181
  await ContextIdStore.run(this._engineCore.getContextIds() ?? {}, async () => {
181
- await this.startWebServer();
182
+ await this.startWebServer(engineReady);
182
183
  });
183
184
  }
184
185
  catch (err) {
@@ -211,10 +212,11 @@ export class EngineServer {
211
212
  }
212
213
  /**
213
214
  * Starts the web server.
215
+ * @param engineReady Called after the web server is built and before it starts listening.
214
216
  * @returns A promise that resolves when the web server is built and listening.
215
217
  * @internal
216
218
  */
217
- async startWebServer() {
219
+ async startWebServer(engineReady) {
218
220
  this._restRoutes = await this.buildRestRoutes();
219
221
  this._socketRoutes = await this.buildSocketRoutes();
220
222
  const restRouteProcessors = RestRouteProcessorFactory.names().map(n => RestRouteProcessorFactory.get(n));
@@ -264,6 +266,11 @@ export class EngineServer {
264
266
  }
265
267
  await this._engineCore.addRegisteredComponent("webServer", this._webServer);
266
268
  await this._webServer.build(restRouteProcessors, this._restRoutes, socketRouteProcessors, this._socketRoutes, coreConfig.web);
269
+ // Work which must complete before any request is served, such as seeding the
270
+ // authorization model the route processors check requests against.
271
+ if (Is.function(engineReady)) {
272
+ await engineReady();
273
+ }
267
274
  await this._webServer.start();
268
275
  }
269
276
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"engineServer.js","sources":["../../src/engineServer.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,mCAAmC;AACnC,uCAAuC;AACvC,OAAO,EACN,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAI3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAgC,MAAM,4BAA4B,CAAC;AAC5F,OAAO,EAAE,aAAa,EAA6B,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,eAAe,EAA+B,MAAM,2BAA2B,CAAC;AACzF,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,EACN,sBAAsB,EACtB,wBAAwB,EACxB,aAAa,EAEb,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,yBAAyB,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACpG,OAAO,2BAA2B,MAAM,yCAAyC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxG,OAAO,sBAAsB,MAAM,oCAAoC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAE9F;;GAEG;AACH,MAAM,OAAO,YAAY;IAGxB;;OAEG;IACI,MAAM,CAAU,UAAU,GAAW,cAAc,CAAC;IAE3D;;;OAGG;IACc,WAAW,CAAiB;IAE7C;;;OAGG;IACc,oBAAoB,CAIjC;IAEJ;;;OAGG;IACc,sBAAsB,CAInC;IAEJ;;;OAGG;IACK,UAAU,CAAuB;IAEzC;;;OAGG;IACK,WAAW,CAAe;IAElC;;;OAGG;IACK,aAAa,CAAiB;IAEtC;;;;OAIG;IACH,YAAY,OAAuC;QAClD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,oBAAoB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;QAEjF,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,oBAAoB,GAAG,EAAE,CAAC;QAC/B,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QAExB,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAEhD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACzD,UAAU,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC;YAEzC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;gBACxB,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC;oBACxC,IAAI,EAAE,sBAAsB,CAAC,OAAO;oBACpC,OAAO,EAAE;wBACR,MAAM,EAAE;4BACP,WAAW,EAAE,UAAU,CAAC,KAAK;yBAC7B;qBACD;iBACD,CAAC,CAAC;YACJ,CAAC;YACD,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC;gBACxC,IAAI,EAAE,sBAAsB,CAAC,SAAS;gBACtC,OAAO,EAAE;oBACR,MAAM,EAAE;wBACP,iBAAiB,EAAE,UAAU,CAAC,KAAK;qBACnC;iBACD;aACD,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC3D,UAAU,CAAC,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC;YAE3C,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;gBACxB,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC;oBAC1C,IAAI,EAAE,wBAAwB,CAAC,OAAO;oBACtC,OAAO,EAAE;wBACR,MAAM,EAAE;4BACP,WAAW,EAAE,UAAU,CAAC,KAAK;yBAC7B;qBACD;iBACD,CAAC,CAAC;YACJ,CAAC;YACD,UAAU,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC;gBAC1C,IAAI,EAAE,wBAAwB,CAAC,WAAW;gBAC1C,OAAO,EAAE;oBACR,MAAM,EAAE;wBACP,iBAAiB,EAAE,UAAU,CAAC,KAAK;qBACnC;iBACD;aACD,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,IAAI,CAAC,4BAA4B,EAAE,CAAC;QACpC,IAAI,CAAC,8BAA8B,EAAE,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACI,qBAAqB,CAAC,IAAY,EAAE,MAAc,EAAE,MAAc;QACxE,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE9D,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAC/E,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;YACxD,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;QACzD,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;gBAC9B,IAAI;gBACJ,MAAM;gBACN,MAAM;aACN,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACI,uBAAuB,CAAC,IAAY,EAAE,MAAc,EAAE,MAAc;QAC1E,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE9D,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QACjF,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;YAC1D,IAAI,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC;QAC3D,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC;gBAChC,IAAI;gBACJ,MAAM;gBACN,MAAM;aACN,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,aAAa;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC;IACzB,CAAC;IAED;;;OAGG;IACI,eAAe;QACrB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,KAAK;QACjB,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAE/B,IAAI,CAAC;YACJ,MAAM,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;gBAC3E,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,8EAA8E;YAC9E,kFAAkF;YAClF,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC5B,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,GAAG,CAAC;QACX,CAAC;IACF,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,IAAI;QAChB,IAAI,CAAC;YACJ,MAAM,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;gBAC3E,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;oBACrB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;oBAClC,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;oBAC5B,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;gBACxB,CAAC;YACF,CAAC,CAAC,CAAC;QACJ,CAAC;gBAAS,CAAC;YACV,mFAAmF;YACnF,wCAAwC;YACxC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;IACF,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,cAAc;QAC3B,IAAI,CAAC,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAChD,IAAI,CAAC,aAAa,GAAG,MAAM,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACpD,MAAM,mBAAmB,GAAG,yBAAyB,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACrE,yBAAyB,CAAC,GAAG,CAAC,CAAC,CAAC,CAChC,CAAC;QACF,MAAM,qBAAqB,GAAG,2BAA2B,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACzE,2BAA2B,CAAC,GAAG,CAAC,CAAC,CAAC,CAClC,CAAC;QACF,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CACnE,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,CAC/B,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;QAChD,MAAM,aAAa,GAAG,UAAU,CAAC,aAAa,IAAI,aAAa,CAAC,OAAO,CAAC;QACxE,MAAM,CAAC,UAAU,CAChB,YAAY,CAAC,UAAU,EACvB,0BAA0B,EAC1B,aAAa,EACb,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAC5B,CAAC;QAEF,IAAI,aAAa,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,UAAU,GAAG,IAAI,aAAa,CAAC;gBACnC,oBAAoB,EAAE,UAAU,CAAC,MAAM;oBACtC,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,SAAS,EAAE,eAAe,CAAC;gBACzE,kBAAkB;gBAClB,MAAM,EAAE;oBACP,iBAAiB,EAAE,UAAU,CAAC,KAAK;oBACnC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,eAA8C;oBACnE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,kBAAoD;iBAC5E;aACD,CAAC,CAAC;QACJ,CAAC;aAAM,IAAI,aAAa,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;YACnD,IAAI,CAAC,UAAU,GAAG,IAAI,eAAe,CAAC;gBACrC,oBAAoB,EAAE,UAAU,CAAC,MAAM;oBACtC,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,SAAS,EAAE,iBAAiB,CAAC;gBAC3E,kBAAkB;gBAClB,MAAM,EAAE;oBACP,iBAAiB,EAAE,UAAU,CAAC,KAAK;oBACnC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,eAAgD;oBACrE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,kBAAsD;iBAC9E;aACD,CAAC,CAAC;QACJ,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,UAAU,GAAG,IAAI,gBAAgB,CAAC;gBACtC,oBAAoB,EAAE,UAAU,CAAC,MAAM;oBACtC,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,SAAS,EAAE,kBAAkB,CAAC;gBAC5E,kBAAkB;gBAClB,MAAM,EAAE;oBACP,iBAAiB,EAAE,UAAU,CAAC,KAAK;oBACnC,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,eAAiD;oBACtE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,kBAAuD;iBAC/E;aACD,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,CAAC,WAAW,CAAC,sBAAsB,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAE5E,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAC1B,mBAAmB,EACnB,IAAI,CAAC,WAAW,EAChB,qBAAqB,EACrB,IAAI,CAAC,aAAa,EAClB,UAAU,CAAC,GAAG,CACd,CAAC;QACF,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,eAAe;QAC5B,MAAM,MAAM,GAAiB,EAAE,CAAC;QAEhC,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAClE,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,iBAAiB;QAC9B,MAAM,MAAM,GAAmB,EAAE,CAAC;QAElC,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YACpE,MAAM,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,uBAAuB,CACpC,MAAoB,EACpB,OAAe,EACf,MAAc,EACd,MAAc;QAEd,MAAM,UAAU,GAAwC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAEhG,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,cAAc,GAAG,MAAM,YAAY,CAAC,cAAc,CAEtD,MAAM,EAAE,MAAM,CAAC,CAAC;YAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACxC,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;gBAE9C,IAAI,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzB,MAAM,WAAW,GAChB,UAAU,CAAC,CAAC,CAAC,CAAC,oBAAoB;wBAClC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;oBACrD,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;wBACjC,MAAM,eAAe,GAAG,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;wBAC3E,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;4BACrC,mDAAmD;4BACnD,IAAI,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACzD,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BAC3D,CAAC;wBACF,CAAC;wBACD,MAAM,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;oBACjC,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;;OAQG;IACK,KAAK,CAAC,yBAAyB,CACtC,MAAsB,EACtB,OAAe,EACf,MAAc,EACd,MAAc;QAEd,MAAM,UAAU,GAAwC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAEhG,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,cAAc,GAAG,MAAM,YAAY,CAAC,cAAc,CAEtD,MAAM,EAAE,MAAM,CAAC,CAAC;YAElB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5C,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;gBAC5C,MAAM,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;gBAClD,IAAI,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC3B,MAAM,WAAW,GAChB,UAAU,CAAC,CAAC,CAAC,CAAC,oBAAoB;wBAClC,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;oBACrD,IAAI,EAAE,CAAC,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;wBACjC,MAAM,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;oBACxE,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;OAGG;IACK,yBAAyB;QAChC,KAAK,MAAM,WAAW,IAAI,sBAAsB,EAAE,CAAC;YAClD,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/F,CAAC;IACF,CAAC;IAED;;;OAGG;IACK,4BAA4B;QACnC,KAAK,MAAM,SAAS,IAAI,yBAAyB,EAAE,CAAC;YACnD,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAChF,CAAC;IACF,CAAC;IAED;;;OAGG;IACK,8BAA8B;QACrC,KAAK,MAAM,SAAS,IAAI,2BAA2B,EAAE,CAAC;YACrD,IAAI,CAAC,uBAAuB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAClF,CAAC;IACF,CAAC;CACD","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// Copyright 2026 3Sixty Trade Ltd.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tMimeTypeProcessorFactory,\n\tRestRouteProcessorFactory,\n\tSocketRouteProcessorFactory,\n\ttype IRestRoute,\n\ttype ISocketRoute,\n\ttype IWebServer\n} from \"@3sixty/api-models\";\nimport { FastifyWebServer, type IFastifyWebServerConfig } from \"@3sixty/api-server-fastify\";\nimport { HonoWebServer, type IHonoWebServerConfig } from \"@3sixty/api-server-hono\";\nimport { NativeWebServer, type INativeWebServerConfig } from \"@3sixty/api-server-native\";\nimport { ContextIdStore } from \"@3sixty/context\";\nimport { Guards, Is, StringHelper } from \"@3sixty/core\";\nimport type { IEngineCore, IEngineCoreTypeConfig, IEngineServer } from \"@3sixty/engine-models\";\nimport {\n\tRestRouteProcessorType,\n\tSocketRouteProcessorType,\n\tWebServerType,\n\ttype IEngineServerConfig\n} from \"@3sixty/engine-server-types\";\nimport { ModuleHelper } from \"@3sixty/modules\";\n\nimport serverRestRouteGenerators from \"./data/serverRestRouteGenerators.json\" with { type: \"json\" };\nimport serverSocketRouteGenerators from \"./data/serverSocketRouteGenerators.json\" with { type: \"json\" };\nimport serverTypeInitialisers from \"./data/serverTypeInitialisers.json\" with { type: \"json\" };\n\n/**\n * Server for the engine.\n */\nexport class EngineServer<\n\tT extends IEngineServerConfig = IEngineServerConfig\n> implements IEngineServer {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = \"EngineServer\";\n\n\t/**\n\t * The engine.\n\t * @internal\n\t */\n\tprivate readonly _engineCore: IEngineCore<T>;\n\n\t/**\n\t * The REST route generators.\n\t * @internal\n\t */\n\tprivate readonly _restRouteGenerators: {\n\t\ttype: string;\n\t\tmodule: string;\n\t\tmethod: string;\n\t}[];\n\n\t/**\n\t * The socket route generators.\n\t * @internal\n\t */\n\tprivate readonly _socketRouteGenerators: {\n\t\ttype: string;\n\t\tmodule: string;\n\t\tmethod: string;\n\t}[];\n\n\t/**\n\t * The web server.\n\t * @internal\n\t */\n\tprivate _webServer?: IWebServer<unknown>;\n\n\t/**\n\t * The REST routes for the application.\n\t * @internal\n\t */\n\tprivate _restRoutes: IRestRoute[];\n\n\t/**\n\t * The Socket routes for the application.\n\t * @internal\n\t */\n\tprivate _socketRoutes: ISocketRoute[];\n\n\t/**\n\t * Create a new instance of EngineServer.\n\t * @param options The options for the engine.\n\t * @param options.engineCore The engine core to serve from.\n\t */\n\tconstructor(options: { engineCore: IEngineCore<T> }) {\n\t\tGuards.object(EngineServer.CLASS_NAME, \"options\", options);\n\t\tGuards.object(EngineServer.CLASS_NAME, \"options.engineCore\", options.engineCore);\n\n\t\tthis._engineCore = options.engineCore;\n\t\tthis._restRouteGenerators = [];\n\t\tthis._socketRouteGenerators = [];\n\t\tthis._restRoutes = [];\n\t\tthis._socketRoutes = [];\n\n\t\tconst coreConfig = this._engineCore.getConfig();\n\n\t\tif (!Is.arrayValue(coreConfig.types.restRouteProcessor)) {\n\t\t\tcoreConfig.types.restRouteProcessor = [];\n\n\t\t\tif (!coreConfig.silent) {\n\t\t\t\tcoreConfig.types.restRouteProcessor.push({\n\t\t\t\t\ttype: RestRouteProcessorType.Logging,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tincludeBody: coreConfig.debug\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tcoreConfig.types.restRouteProcessor.push({\n\t\t\t\ttype: RestRouteProcessorType.RestRoute,\n\t\t\t\toptions: {\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tincludeErrorStack: coreConfig.debug\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (!Is.arrayValue(coreConfig.types.socketRouteProcessor)) {\n\t\t\tcoreConfig.types.socketRouteProcessor = [];\n\n\t\t\tif (!coreConfig.silent) {\n\t\t\t\tcoreConfig.types.socketRouteProcessor.push({\n\t\t\t\t\ttype: SocketRouteProcessorType.Logging,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tincludeBody: coreConfig.debug\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tcoreConfig.types.socketRouteProcessor.push({\n\t\t\t\ttype: SocketRouteProcessorType.SocketRoute,\n\t\t\t\toptions: {\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tincludeErrorStack: coreConfig.debug\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.addServerTypeInitialisers();\n\t\tthis.addServerRestRouteGenerators();\n\t\tthis.addServerSocketRouteGenerators();\n\t}\n\n\t/**\n\t * Add a REST route generator.\n\t * @param type The type to add the generator for.\n\t * @param module The module containing the generator.\n\t * @param method The method to call on the module.\n\t */\n\tpublic addRestRouteGenerator(type: string, module: string, method: string): void {\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"type\", type);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"module\", module);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"method\", method);\n\n\t\tconst currentIndex = this._restRouteGenerators.findIndex(r => r.type === type);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis._restRouteGenerators[currentIndex].module = module;\n\t\t\tthis._restRouteGenerators[currentIndex].method = method;\n\t\t} else {\n\t\t\tthis._restRouteGenerators.push({\n\t\t\t\ttype,\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Add a socket route generator.\n\t * @param type The type to add the generator for.\n\t * @param module The module containing the generator.\n\t * @param method The method to call on the module.\n\t */\n\tpublic addSocketRouteGenerator(type: string, module: string, method: string): void {\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"type\", type);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"module\", module);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"method\", method);\n\n\t\tconst currentIndex = this._socketRouteGenerators.findIndex(s => s.type === type);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis._socketRouteGenerators[currentIndex].module = module;\n\t\t\tthis._socketRouteGenerators[currentIndex].method = method;\n\t\t} else {\n\t\t\tthis._socketRouteGenerators.push({\n\t\t\t\ttype,\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get the built REST routes.\n\t * @returns The REST routes.\n\t */\n\tpublic getRestRoutes(): IRestRoute[] {\n\t\treturn this._restRoutes;\n\t}\n\n\t/**\n\t * Get the built socket routes.\n\t * @returns The socket routes.\n\t */\n\tpublic getSocketRoutes(): ISocketRoute[] {\n\t\treturn this._socketRoutes;\n\t}\n\n\t/**\n\t * Start the engine server.\n\t * @returns A promise that resolves when the server has started and is ready to accept requests.\n\t */\n\tpublic async start(): Promise<void> {\n\t\tawait this._engineCore.start();\n\n\t\ttry {\n\t\t\tawait ContextIdStore.run(this._engineCore.getContextIds() ?? {}, async () => {\n\t\t\t\tawait this.startWebServer();\n\t\t\t});\n\t\t} catch (err) {\n\t\t\t// The engine components are already running, so they must be stopped when the\n\t\t\t// web server fails to start, the web server itself never started so is discarded.\n\t\t\tthis._webServer = undefined;\n\t\t\tawait this._engineCore.stop();\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Stop the engine server.\n\t * @returns A promise that resolves when the server has stopped and all connections are closed.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\ttry {\n\t\t\tawait ContextIdStore.run(this._engineCore.getContextIds() ?? {}, async () => {\n\t\t\t\tif (this._webServer) {\n\t\t\t\t\tconst webServer = this._webServer;\n\t\t\t\t\tthis._webServer = undefined;\n\t\t\t\t\tawait webServer.stop();\n\t\t\t\t}\n\t\t\t});\n\t\t} finally {\n\t\t\t// The engine is always stopped so its components are shut down and state is saved,\n\t\t\t// even if the web server fails to stop.\n\t\t\tawait this._engineCore.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Starts the web server.\n\t * @returns A promise that resolves when the web server is built and listening.\n\t * @internal\n\t */\n\tprivate async startWebServer(): Promise<void> {\n\t\tthis._restRoutes = await this.buildRestRoutes();\n\t\tthis._socketRoutes = await this.buildSocketRoutes();\n\t\tconst restRouteProcessors = RestRouteProcessorFactory.names().map(n =>\n\t\t\tRestRouteProcessorFactory.get(n)\n\t\t);\n\t\tconst socketRouteProcessors = SocketRouteProcessorFactory.names().map(n =>\n\t\t\tSocketRouteProcessorFactory.get(n)\n\t\t);\n\t\tconst mimeTypeProcessors = MimeTypeProcessorFactory.names().map(n =>\n\t\t\tMimeTypeProcessorFactory.get(n)\n\t\t);\n\n\t\tconst coreConfig = this._engineCore.getConfig();\n\t\tconst webServerType = coreConfig.webServerType ?? WebServerType.Fastify;\n\t\tGuards.arrayOneOf<WebServerType>(\n\t\t\tEngineServer.CLASS_NAME,\n\t\t\t\"coreConfig.webServerType\",\n\t\t\twebServerType,\n\t\t\tObject.values(WebServerType)\n\t\t);\n\n\t\tif (webServerType === WebServerType.Hono) {\n\t\t\tthis._webServer = new HonoWebServer({\n\t\t\t\tloggingComponentType: coreConfig.silent\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this._engineCore.getRegisteredSilencedType(\"logging\", \"HonoWebServer\"),\n\t\t\t\tmimeTypeProcessors,\n\t\t\t\tconfig: {\n\t\t\t\t\tincludeErrorStack: coreConfig.debug,\n\t\t\t\t\tweb: coreConfig.web?.customWebConfig as IHonoWebServerConfig[\"web\"],\n\t\t\t\t\tsocket: coreConfig.web?.customSocketConfig as IHonoWebServerConfig[\"socket\"]\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (webServerType === WebServerType.Native) {\n\t\t\tthis._webServer = new NativeWebServer({\n\t\t\t\tloggingComponentType: coreConfig.silent\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this._engineCore.getRegisteredSilencedType(\"logging\", \"NativeWebServer\"),\n\t\t\t\tmimeTypeProcessors,\n\t\t\t\tconfig: {\n\t\t\t\t\tincludeErrorStack: coreConfig.debug,\n\t\t\t\t\tweb: coreConfig.web?.customWebConfig as INativeWebServerConfig[\"web\"],\n\t\t\t\t\tsocket: coreConfig.web?.customSocketConfig as INativeWebServerConfig[\"socket\"]\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis._webServer = new FastifyWebServer({\n\t\t\t\tloggingComponentType: coreConfig.silent\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this._engineCore.getRegisteredSilencedType(\"logging\", \"FastifyWebServer\"),\n\t\t\t\tmimeTypeProcessors,\n\t\t\t\tconfig: {\n\t\t\t\t\tincludeErrorStack: coreConfig.debug,\n\t\t\t\t\tweb: coreConfig.web?.customWebConfig as IFastifyWebServerConfig[\"web\"],\n\t\t\t\t\tsocket: coreConfig.web?.customSocketConfig as IFastifyWebServerConfig[\"socket\"]\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tawait this._engineCore.addRegisteredComponent(\"webServer\", this._webServer);\n\n\t\tawait this._webServer.build(\n\t\t\trestRouteProcessors,\n\t\t\tthis._restRoutes,\n\t\t\tsocketRouteProcessors,\n\t\t\tthis._socketRoutes,\n\t\t\tcoreConfig.web\n\t\t);\n\t\tawait this._webServer.start();\n\t}\n\n\t/**\n\t * The REST routes for the application.\n\t * @returns The REST routes for the application.\n\t * @internal\n\t */\n\tprivate async buildRestRoutes(): Promise<IRestRoute[]> {\n\t\tconst routes: IRestRoute[] = [];\n\n\t\tfor (const { type, module, method } of this._restRouteGenerators) {\n\t\t\tawait this.initialiseRestTypeRoute(routes, type, module, method);\n\t\t}\n\n\t\treturn routes;\n\t}\n\n\t/**\n\t * The socket routes for the application.\n\t * @returns The socket routes for the application.\n\t * @internal\n\t */\n\tprivate async buildSocketRoutes(): Promise<ISocketRoute[]> {\n\t\tconst routes: ISocketRoute[] = [];\n\n\t\tfor (const { type, module, method } of this._socketRouteGenerators) {\n\t\t\tawait this.initialiseSocketTypeRoute(routes, type, module, method);\n\t\t}\n\n\t\treturn routes;\n\t}\n\n\t/**\n\t * Initialise the rest routes from connector.\n\t * @param routes The routes to add to.\n\t * @param typeKey The key for the default types.\n\t * @param module The module containing the route generator.\n\t * @param method The method to generate the routes.\n\t * @returns A promise that resolves when all REST routes for the type have been added.\n\t * @internal\n\t */\n\tprivate async initialiseRestTypeRoute(\n\t\troutes: IRestRoute[],\n\t\ttypeKey: string,\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<void> {\n\t\tconst typeConfig: IEngineCoreTypeConfig[] | undefined = this._engineCore.getTypeConfig(typeKey);\n\n\t\tif (Is.arrayValue(typeConfig)) {\n\t\t\tconst generateRoutes = await ModuleHelper.getModuleEntry<\n\t\t\t\t(baseRouteName: string, componentName: string, options?: unknown) => IRestRoute[]\n\t\t\t>(module, method);\n\n\t\t\tfor (let i = 0; i < typeConfig.length; i++) {\n\t\t\t\tconst restPath = typeConfig[i].restPath;\n\t\t\t\tconst restOptions = typeConfig[i].restOptions;\n\n\t\t\t\tif (Is.string(restPath)) {\n\t\t\t\t\tconst serviceType =\n\t\t\t\t\t\ttypeConfig[i].overrideInstanceType ??\n\t\t\t\t\t\tthis._engineCore.getRegisteredInstanceType(typeKey);\n\t\t\t\t\tif (Is.stringValue(serviceType)) {\n\t\t\t\t\t\tconst generatedRoutes = generateRoutes(restPath, serviceType, restOptions);\n\t\t\t\t\t\tfor (const route of generatedRoutes) {\n\t\t\t\t\t\t\t// Don't strip trailing slashes from the root path.\n\t\t\t\t\t\t\tif (Is.stringValue(route.path) && route.path.length > 1) {\n\t\t\t\t\t\t\t\troute.path = StringHelper.trimTrailingSlashes(route.path);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\troutes.push(...generatedRoutes);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Initialise the socket routes from connector.\n\t * @param routes The routes to add to.\n\t * @param typeKey The key for the default types.\n\t * @param module The module containing the generator.\n\t * @param method The method to call on the module.\n\t * @returns A promise that resolves when all socket routes for the type have been added.\n\t * @internal\n\t */\n\tprivate async initialiseSocketTypeRoute(\n\t\troutes: ISocketRoute[],\n\t\ttypeKey: string,\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<void> {\n\t\tconst typeConfig: IEngineCoreTypeConfig[] | undefined = this._engineCore.getTypeConfig(typeKey);\n\n\t\tif (Is.arrayValue(typeConfig)) {\n\t\t\tconst generateRoutes = await ModuleHelper.getModuleEntry<\n\t\t\t\t(baseRouteName: string, componentName: string, options?: unknown) => ISocketRoute[]\n\t\t\t>(module, method);\n\n\t\t\tfor (let i = 0; i < typeConfig.length; i++) {\n\t\t\t\tconst socketPath = typeConfig[i].socketPath;\n\t\t\t\tconst socketOptions = typeConfig[i].socketOptions;\n\t\t\t\tif (Is.string(socketPath)) {\n\t\t\t\t\tconst serviceType =\n\t\t\t\t\t\ttypeConfig[i].overrideInstanceType ??\n\t\t\t\t\t\tthis._engineCore.getRegisteredInstanceType(typeKey);\n\t\t\t\t\tif (Is.stringValue(serviceType)) {\n\t\t\t\t\t\troutes.push(...generateRoutes(socketPath, serviceType, socketOptions));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Add the server type initializers.\n\t * @internal\n\t */\n\tprivate addServerTypeInitialisers(): void {\n\t\tfor (const initializer of serverTypeInitialisers) {\n\t\t\tthis._engineCore.addTypeInitialiser(initializer.type, initializer.module, initializer.method);\n\t\t}\n\t}\n\n\t/**\n\t * Add the server REST route generators.\n\t * @internal\n\t */\n\tprivate addServerRestRouteGenerators(): void {\n\t\tfor (const generator of serverRestRouteGenerators) {\n\t\t\tthis.addRestRouteGenerator(generator.type, generator.module, generator.method);\n\t\t}\n\t}\n\n\t/**\n\t * Add the server socket route generators.\n\t * @internal\n\t */\n\tprivate addServerSocketRouteGenerators(): void {\n\t\tfor (const generator of serverSocketRouteGenerators) {\n\t\t\tthis.addSocketRouteGenerator(generator.type, generator.module, generator.method);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"engineServer.js","sources":["../../src/engineServer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// Copyright 2026 3Sixty Trade Ltd.\n// SPDX-License-Identifier: Apache-2.0.\nimport {\n\tMimeTypeProcessorFactory,\n\tRestRouteProcessorFactory,\n\tSocketRouteProcessorFactory,\n\ttype IRestRoute,\n\ttype ISocketRoute,\n\ttype IWebServer\n} from \"@3sixty/api-models\";\nimport { FastifyWebServer, type IFastifyWebServerConfig } from \"@3sixty/api-server-fastify\";\nimport { HonoWebServer, type IHonoWebServerConfig } from \"@3sixty/api-server-hono\";\nimport { NativeWebServer, type INativeWebServerConfig } from \"@3sixty/api-server-native\";\nimport { ContextIdStore } from \"@3sixty/context\";\nimport { Guards, Is, StringHelper } from \"@3sixty/core\";\nimport type { IEngineCore, IEngineCoreTypeConfig, IEngineServer } from \"@3sixty/engine-models\";\nimport {\n\tRestRouteProcessorType,\n\tSocketRouteProcessorType,\n\tWebServerType,\n\ttype IEngineServerConfig\n} from \"@3sixty/engine-server-types\";\nimport { ModuleHelper } from \"@3sixty/modules\";\n\nimport serverRestRouteGenerators from \"./data/serverRestRouteGenerators.json\" with { type: \"json\" };\nimport serverSocketRouteGenerators from \"./data/serverSocketRouteGenerators.json\" with { type: \"json\" };\nimport serverTypeInitialisers from \"./data/serverTypeInitialisers.json\" with { type: \"json\" };\n\n/**\n * Server for the engine.\n */\nexport class EngineServer<\n\tT extends IEngineServerConfig = IEngineServerConfig\n> implements IEngineServer {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = \"EngineServer\";\n\n\t/**\n\t * The engine.\n\t * @internal\n\t */\n\tprivate readonly _engineCore: IEngineCore<T>;\n\n\t/**\n\t * The REST route generators.\n\t * @internal\n\t */\n\tprivate readonly _restRouteGenerators: {\n\t\ttype: string;\n\t\tmodule: string;\n\t\tmethod: string;\n\t}[];\n\n\t/**\n\t * The socket route generators.\n\t * @internal\n\t */\n\tprivate readonly _socketRouteGenerators: {\n\t\ttype: string;\n\t\tmodule: string;\n\t\tmethod: string;\n\t}[];\n\n\t/**\n\t * The web server.\n\t * @internal\n\t */\n\tprivate _webServer?: IWebServer<unknown>;\n\n\t/**\n\t * The REST routes for the application.\n\t * @internal\n\t */\n\tprivate _restRoutes: IRestRoute[];\n\n\t/**\n\t * The Socket routes for the application.\n\t * @internal\n\t */\n\tprivate _socketRoutes: ISocketRoute[];\n\n\t/**\n\t * Create a new instance of EngineServer.\n\t * @param options The options for the engine.\n\t * @param options.engineCore The engine core to serve from.\n\t */\n\tconstructor(options: { engineCore: IEngineCore<T> }) {\n\t\tGuards.object(EngineServer.CLASS_NAME, \"options\", options);\n\t\tGuards.object(EngineServer.CLASS_NAME, \"options.engineCore\", options.engineCore);\n\n\t\tthis._engineCore = options.engineCore;\n\t\tthis._restRouteGenerators = [];\n\t\tthis._socketRouteGenerators = [];\n\t\tthis._restRoutes = [];\n\t\tthis._socketRoutes = [];\n\n\t\tconst coreConfig = this._engineCore.getConfig();\n\n\t\tif (!Is.arrayValue(coreConfig.types.restRouteProcessor)) {\n\t\t\tcoreConfig.types.restRouteProcessor = [];\n\n\t\t\tif (!coreConfig.silent) {\n\t\t\t\tcoreConfig.types.restRouteProcessor.push({\n\t\t\t\t\ttype: RestRouteProcessorType.Logging,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tincludeBody: coreConfig.debug\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tcoreConfig.types.restRouteProcessor.push({\n\t\t\t\ttype: RestRouteProcessorType.RestRoute,\n\t\t\t\toptions: {\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tincludeErrorStack: coreConfig.debug\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (!Is.arrayValue(coreConfig.types.socketRouteProcessor)) {\n\t\t\tcoreConfig.types.socketRouteProcessor = [];\n\n\t\t\tif (!coreConfig.silent) {\n\t\t\t\tcoreConfig.types.socketRouteProcessor.push({\n\t\t\t\t\ttype: SocketRouteProcessorType.Logging,\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tconfig: {\n\t\t\t\t\t\t\tincludeBody: coreConfig.debug\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\tcoreConfig.types.socketRouteProcessor.push({\n\t\t\t\ttype: SocketRouteProcessorType.SocketRoute,\n\t\t\t\toptions: {\n\t\t\t\t\tconfig: {\n\t\t\t\t\t\tincludeErrorStack: coreConfig.debug\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.addServerTypeInitialisers();\n\t\tthis.addServerRestRouteGenerators();\n\t\tthis.addServerSocketRouteGenerators();\n\t}\n\n\t/**\n\t * Add a REST route generator.\n\t * @param type The type to add the generator for.\n\t * @param module The module containing the generator.\n\t * @param method The method to call on the module.\n\t */\n\tpublic addRestRouteGenerator(type: string, module: string, method: string): void {\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"type\", type);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"module\", module);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"method\", method);\n\n\t\tconst currentIndex = this._restRouteGenerators.findIndex(r => r.type === type);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis._restRouteGenerators[currentIndex].module = module;\n\t\t\tthis._restRouteGenerators[currentIndex].method = method;\n\t\t} else {\n\t\t\tthis._restRouteGenerators.push({\n\t\t\t\ttype,\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Add a socket route generator.\n\t * @param type The type to add the generator for.\n\t * @param module The module containing the generator.\n\t * @param method The method to call on the module.\n\t */\n\tpublic addSocketRouteGenerator(type: string, module: string, method: string): void {\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"type\", type);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"module\", module);\n\t\tGuards.stringValue(EngineServer.CLASS_NAME, \"method\", method);\n\n\t\tconst currentIndex = this._socketRouteGenerators.findIndex(s => s.type === type);\n\t\tif (currentIndex >= 0) {\n\t\t\tthis._socketRouteGenerators[currentIndex].module = module;\n\t\t\tthis._socketRouteGenerators[currentIndex].method = method;\n\t\t} else {\n\t\t\tthis._socketRouteGenerators.push({\n\t\t\t\ttype,\n\t\t\t\tmodule,\n\t\t\t\tmethod\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Get the built REST routes.\n\t * @returns The REST routes.\n\t */\n\tpublic getRestRoutes(): IRestRoute[] {\n\t\treturn this._restRoutes;\n\t}\n\n\t/**\n\t * Get the built socket routes.\n\t * @returns The socket routes.\n\t */\n\tpublic getSocketRoutes(): ISocketRoute[] {\n\t\treturn this._socketRoutes;\n\t}\n\n\t/**\n\t * Start the engine server.\n\t * @param engineReady Called once the engine has started and the routes are built, before the web server accepts requests.\n\t * @returns A promise that resolves when the server has started and is ready to accept requests.\n\t */\n\tpublic async start(engineReady?: () => Promise<void>): Promise<void> {\n\t\tawait this._engineCore.start();\n\n\t\ttry {\n\t\t\tawait ContextIdStore.run(this._engineCore.getContextIds() ?? {}, async () => {\n\t\t\t\tawait this.startWebServer(engineReady);\n\t\t\t});\n\t\t} catch (err) {\n\t\t\t// The engine components are already running, so they must be stopped when the\n\t\t\t// web server fails to start, the web server itself never started so is discarded.\n\t\t\tthis._webServer = undefined;\n\t\t\tawait this._engineCore.stop();\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * Stop the engine server.\n\t * @returns A promise that resolves when the server has stopped and all connections are closed.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\ttry {\n\t\t\tawait ContextIdStore.run(this._engineCore.getContextIds() ?? {}, async () => {\n\t\t\t\tif (this._webServer) {\n\t\t\t\t\tconst webServer = this._webServer;\n\t\t\t\t\tthis._webServer = undefined;\n\t\t\t\t\tawait webServer.stop();\n\t\t\t\t}\n\t\t\t});\n\t\t} finally {\n\t\t\t// The engine is always stopped so its components are shut down and state is saved,\n\t\t\t// even if the web server fails to stop.\n\t\t\tawait this._engineCore.stop();\n\t\t}\n\t}\n\n\t/**\n\t * Starts the web server.\n\t * @param engineReady Called after the web server is built and before it starts listening.\n\t * @returns A promise that resolves when the web server is built and listening.\n\t * @internal\n\t */\n\tprivate async startWebServer(engineReady?: () => Promise<void>): Promise<void> {\n\t\tthis._restRoutes = await this.buildRestRoutes();\n\t\tthis._socketRoutes = await this.buildSocketRoutes();\n\t\tconst restRouteProcessors = RestRouteProcessorFactory.names().map(n =>\n\t\t\tRestRouteProcessorFactory.get(n)\n\t\t);\n\t\tconst socketRouteProcessors = SocketRouteProcessorFactory.names().map(n =>\n\t\t\tSocketRouteProcessorFactory.get(n)\n\t\t);\n\t\tconst mimeTypeProcessors = MimeTypeProcessorFactory.names().map(n =>\n\t\t\tMimeTypeProcessorFactory.get(n)\n\t\t);\n\n\t\tconst coreConfig = this._engineCore.getConfig();\n\t\tconst webServerType = coreConfig.webServerType ?? WebServerType.Fastify;\n\t\tGuards.arrayOneOf<WebServerType>(\n\t\t\tEngineServer.CLASS_NAME,\n\t\t\t\"coreConfig.webServerType\",\n\t\t\twebServerType,\n\t\t\tObject.values(WebServerType)\n\t\t);\n\n\t\tif (webServerType === WebServerType.Hono) {\n\t\t\tthis._webServer = new HonoWebServer({\n\t\t\t\tloggingComponentType: coreConfig.silent\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this._engineCore.getRegisteredSilencedType(\"logging\", \"HonoWebServer\"),\n\t\t\t\tmimeTypeProcessors,\n\t\t\t\tconfig: {\n\t\t\t\t\tincludeErrorStack: coreConfig.debug,\n\t\t\t\t\tweb: coreConfig.web?.customWebConfig as IHonoWebServerConfig[\"web\"],\n\t\t\t\t\tsocket: coreConfig.web?.customSocketConfig as IHonoWebServerConfig[\"socket\"]\n\t\t\t\t}\n\t\t\t});\n\t\t} else if (webServerType === WebServerType.Native) {\n\t\t\tthis._webServer = new NativeWebServer({\n\t\t\t\tloggingComponentType: coreConfig.silent\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this._engineCore.getRegisteredSilencedType(\"logging\", \"NativeWebServer\"),\n\t\t\t\tmimeTypeProcessors,\n\t\t\t\tconfig: {\n\t\t\t\t\tincludeErrorStack: coreConfig.debug,\n\t\t\t\t\tweb: coreConfig.web?.customWebConfig as INativeWebServerConfig[\"web\"],\n\t\t\t\t\tsocket: coreConfig.web?.customSocketConfig as INativeWebServerConfig[\"socket\"]\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis._webServer = new FastifyWebServer({\n\t\t\t\tloggingComponentType: coreConfig.silent\n\t\t\t\t\t? undefined\n\t\t\t\t\t: this._engineCore.getRegisteredSilencedType(\"logging\", \"FastifyWebServer\"),\n\t\t\t\tmimeTypeProcessors,\n\t\t\t\tconfig: {\n\t\t\t\t\tincludeErrorStack: coreConfig.debug,\n\t\t\t\t\tweb: coreConfig.web?.customWebConfig as IFastifyWebServerConfig[\"web\"],\n\t\t\t\t\tsocket: coreConfig.web?.customSocketConfig as IFastifyWebServerConfig[\"socket\"]\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tawait this._engineCore.addRegisteredComponent(\"webServer\", this._webServer);\n\n\t\tawait this._webServer.build(\n\t\t\trestRouteProcessors,\n\t\t\tthis._restRoutes,\n\t\t\tsocketRouteProcessors,\n\t\t\tthis._socketRoutes,\n\t\t\tcoreConfig.web\n\t\t);\n\n\t\t// Work which must complete before any request is served, such as seeding the\n\t\t// authorization model the route processors check requests against.\n\t\tif (Is.function(engineReady)) {\n\t\t\tawait engineReady();\n\t\t}\n\n\t\tawait this._webServer.start();\n\t}\n\n\t/**\n\t * The REST routes for the application.\n\t * @returns The REST routes for the application.\n\t * @internal\n\t */\n\tprivate async buildRestRoutes(): Promise<IRestRoute[]> {\n\t\tconst routes: IRestRoute[] = [];\n\n\t\tfor (const { type, module, method } of this._restRouteGenerators) {\n\t\t\tawait this.initialiseRestTypeRoute(routes, type, module, method);\n\t\t}\n\n\t\treturn routes;\n\t}\n\n\t/**\n\t * The socket routes for the application.\n\t * @returns The socket routes for the application.\n\t * @internal\n\t */\n\tprivate async buildSocketRoutes(): Promise<ISocketRoute[]> {\n\t\tconst routes: ISocketRoute[] = [];\n\n\t\tfor (const { type, module, method } of this._socketRouteGenerators) {\n\t\t\tawait this.initialiseSocketTypeRoute(routes, type, module, method);\n\t\t}\n\n\t\treturn routes;\n\t}\n\n\t/**\n\t * Initialise the rest routes from connector.\n\t * @param routes The routes to add to.\n\t * @param typeKey The key for the default types.\n\t * @param module The module containing the route generator.\n\t * @param method The method to generate the routes.\n\t * @returns A promise that resolves when all REST routes for the type have been added.\n\t * @internal\n\t */\n\tprivate async initialiseRestTypeRoute(\n\t\troutes: IRestRoute[],\n\t\ttypeKey: string,\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<void> {\n\t\tconst typeConfig: IEngineCoreTypeConfig[] | undefined = this._engineCore.getTypeConfig(typeKey);\n\n\t\tif (Is.arrayValue(typeConfig)) {\n\t\t\tconst generateRoutes = await ModuleHelper.getModuleEntry<\n\t\t\t\t(baseRouteName: string, componentName: string, options?: unknown) => IRestRoute[]\n\t\t\t>(module, method);\n\n\t\t\tfor (let i = 0; i < typeConfig.length; i++) {\n\t\t\t\tconst restPath = typeConfig[i].restPath;\n\t\t\t\tconst restOptions = typeConfig[i].restOptions;\n\n\t\t\t\tif (Is.string(restPath)) {\n\t\t\t\t\tconst serviceType =\n\t\t\t\t\t\ttypeConfig[i].overrideInstanceType ??\n\t\t\t\t\t\tthis._engineCore.getRegisteredInstanceType(typeKey);\n\t\t\t\t\tif (Is.stringValue(serviceType)) {\n\t\t\t\t\t\tconst generatedRoutes = generateRoutes(restPath, serviceType, restOptions);\n\t\t\t\t\t\tfor (const route of generatedRoutes) {\n\t\t\t\t\t\t\t// Don't strip trailing slashes from the root path.\n\t\t\t\t\t\t\tif (Is.stringValue(route.path) && route.path.length > 1) {\n\t\t\t\t\t\t\t\troute.path = StringHelper.trimTrailingSlashes(route.path);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\troutes.push(...generatedRoutes);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Initialise the socket routes from connector.\n\t * @param routes The routes to add to.\n\t * @param typeKey The key for the default types.\n\t * @param module The module containing the generator.\n\t * @param method The method to call on the module.\n\t * @returns A promise that resolves when all socket routes for the type have been added.\n\t * @internal\n\t */\n\tprivate async initialiseSocketTypeRoute(\n\t\troutes: ISocketRoute[],\n\t\ttypeKey: string,\n\t\tmodule: string,\n\t\tmethod: string\n\t): Promise<void> {\n\t\tconst typeConfig: IEngineCoreTypeConfig[] | undefined = this._engineCore.getTypeConfig(typeKey);\n\n\t\tif (Is.arrayValue(typeConfig)) {\n\t\t\tconst generateRoutes = await ModuleHelper.getModuleEntry<\n\t\t\t\t(baseRouteName: string, componentName: string, options?: unknown) => ISocketRoute[]\n\t\t\t>(module, method);\n\n\t\t\tfor (let i = 0; i < typeConfig.length; i++) {\n\t\t\t\tconst socketPath = typeConfig[i].socketPath;\n\t\t\t\tconst socketOptions = typeConfig[i].socketOptions;\n\t\t\t\tif (Is.string(socketPath)) {\n\t\t\t\t\tconst serviceType =\n\t\t\t\t\t\ttypeConfig[i].overrideInstanceType ??\n\t\t\t\t\t\tthis._engineCore.getRegisteredInstanceType(typeKey);\n\t\t\t\t\tif (Is.stringValue(serviceType)) {\n\t\t\t\t\t\troutes.push(...generateRoutes(socketPath, serviceType, socketOptions));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Add the server type initializers.\n\t * @internal\n\t */\n\tprivate addServerTypeInitialisers(): void {\n\t\tfor (const initializer of serverTypeInitialisers) {\n\t\t\tthis._engineCore.addTypeInitialiser(initializer.type, initializer.module, initializer.method);\n\t\t}\n\t}\n\n\t/**\n\t * Add the server REST route generators.\n\t * @internal\n\t */\n\tprivate addServerRestRouteGenerators(): void {\n\t\tfor (const generator of serverRestRouteGenerators) {\n\t\t\tthis.addRestRouteGenerator(generator.type, generator.module, generator.method);\n\t\t}\n\t}\n\n\t/**\n\t * Add the server socket route generators.\n\t * @internal\n\t */\n\tprivate addServerSocketRouteGenerators(): void {\n\t\tfor (const generator of serverSocketRouteGenerators) {\n\t\t\tthis.addSocketRouteGenerator(generator.type, generator.module, generator.method);\n\t\t}\n\t}\n}\n"]}
@@ -43,9 +43,10 @@ export declare class EngineServer<T extends IEngineServerConfig = IEngineServerC
43
43
  getSocketRoutes(): ISocketRoute[];
44
44
  /**
45
45
  * Start the engine server.
46
+ * @param engineReady Called once the engine has started and the routes are built, before the web server accepts requests.
46
47
  * @returns A promise that resolves when the server has started and is ready to accept requests.
47
48
  */
48
- start(): Promise<void>;
49
+ start(engineReady?: () => Promise<void>): Promise<void>;
49
50
  /**
50
51
  * Stop the engine server.
51
52
  * @returns A promise that resolves when the server has stopped and all connections are closed.
package/docs/changelog.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.20.0-next.4](https://github.com/3sixtyglobal/engine/compare/engine-server-v0.20.0-next.3...engine-server-v0.20.0-next.4) (2026-10-26)
4
+
5
+
6
+ ### Features
7
+
8
+ * release to next [skip ci] ([#30](https://github.com/3sixtyglobal/engine/issues/30)) ([dca87a6](https://github.com/3sixtyglobal/engine/commit/dca87a61dffb102de116a31fd58b31a149057159))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * run engineReady before the web server listens ([#28](https://github.com/3sixtyglobal/engine/issues/28)) ([7b90952](https://github.com/3sixtyglobal/engine/commit/7b909521054ae2368874e7f74bb461bcbff2663e))
14
+
15
+
16
+ ### Dependencies
17
+
18
+ * The following workspace dependencies were updated
19
+ * dependencies
20
+ * @3sixty/engine-models bumped from 0.20.0-next.3 to 0.20.0-next.4
21
+ * @3sixty/engine-server-types bumped from 0.20.0-next.3 to 0.20.0-next.4
22
+ * devDependencies
23
+ * @3sixty/engine bumped from 0.20.0-next.3 to 0.20.0-next.4
24
+ * @3sixty/engine-core bumped from 0.20.0-next.3 to 0.20.0-next.4
25
+ * @3sixty/engine-types bumped from 0.20.0-next.3 to 0.20.0-next.4
26
+
3
27
  ## [0.20.0-next.3](https://github.com/3sixtyglobal/engine/compare/engine-server-v0.20.0-next.2...engine-server-v0.20.0-next.3) (2026-10-26)
4
28
 
5
29
 
package/docs/examples.md CHANGED
@@ -72,6 +72,15 @@ await server.start();
72
72
  await server.stop();
73
73
  ```
74
74
 
75
+ Pass `engineReady` to `start` for work which must complete before the first request is served. It runs once the engine has started and the routes are built, before the web server listens:
76
+
77
+ ```typescript
78
+ await server.start(async () => {
79
+ const routes = server.getRestRoutes();
80
+ // e.g. seed data the route processors depend on
81
+ });
82
+ ```
83
+
75
84
  ## addDefaultRestPaths and addDefaultSocketPaths
76
85
 
77
86
  ```typescript
@@ -156,10 +156,18 @@ The socket routes.
156
156
 
157
157
  ### start() {#start}
158
158
 
159
- > **start**(): `Promise`\<`void`\>
159
+ > **start**(`engineReady?`): `Promise`\<`void`\>
160
160
 
161
161
  Start the engine server.
162
162
 
163
+ #### Parameters
164
+
165
+ ##### engineReady?
166
+
167
+ () => `Promise`\<`void`\>
168
+
169
+ Called once the engine has started and the routes are built, before the web server accepts requests.
170
+
163
171
  #### Returns
164
172
 
165
173
  `Promise`\<`void`\>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@3sixty/engine-server",
3
- "version": "0.20.0-next.3",
3
+ "version": "0.20.0-next.4",
4
4
  "description": "Server runtime that exposes engine components through REST and socket routes.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,8 +21,8 @@
21
21
  "@3sixty/api-server-native": "next",
22
22
  "@3sixty/context": "next",
23
23
  "@3sixty/core": "next",
24
- "@3sixty/engine-models": "0.20.0-next.3",
25
- "@3sixty/engine-server-types": "0.20.0-next.3",
24
+ "@3sixty/engine-models": "0.20.0-next.4",
25
+ "@3sixty/engine-server-types": "0.20.0-next.4",
26
26
  "@3sixty/modules": "next",
27
27
  "@3sixty/nameof": "next"
28
28
  },