@c9up/ream 0.2.6 → 0.2.7

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.
Files changed (38) hide show
  1. package/dist/Ignitor.d.ts.map +1 -1
  2. package/dist/Ignitor.js +17 -0
  3. package/dist/Ignitor.js.map +1 -1
  4. package/dist/bootstrap/hyper-server.js.map +1 -1
  5. package/dist/helpers/is.d.ts.map +1 -1
  6. package/dist/helpers/is.js +1 -4
  7. package/dist/helpers/is.js.map +1 -1
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.js +1 -1
  10. package/dist/scheduler/Scheduler.d.ts.map +1 -1
  11. package/dist/scheduler/Scheduler.js +12 -4
  12. package/dist/scheduler/Scheduler.js.map +1 -1
  13. package/dist/services/logger.d.ts +29 -0
  14. package/dist/services/logger.d.ts.map +1 -0
  15. package/dist/services/logger.js +40 -0
  16. package/dist/services/logger.js.map +1 -0
  17. package/dist/session/Session.js.map +1 -1
  18. package/dist/testing/TestClient.d.ts +18 -3
  19. package/dist/testing/TestClient.d.ts.map +1 -1
  20. package/dist/testing/TestClient.js +45 -4
  21. package/dist/testing/TestClient.js.map +1 -1
  22. package/dist/testing/testUtils.d.ts +62 -0
  23. package/dist/testing/testUtils.d.ts.map +1 -0
  24. package/dist/testing/testUtils.js +77 -0
  25. package/dist/testing/testUtils.js.map +1 -0
  26. package/events.win32-x64-msvc.node +0 -0
  27. package/index.win32-x64-msvc.node +0 -0
  28. package/package.json +9 -1
  29. package/scheduler.win32-x64-msvc.node +0 -0
  30. package/src/Ignitor.ts +17 -1
  31. package/src/bootstrap/hyper-server.ts +1 -1
  32. package/src/helpers/is.ts +1 -6
  33. package/src/index.ts +1 -1
  34. package/src/scheduler/Scheduler.ts +10 -4
  35. package/src/services/logger.ts +49 -0
  36. package/src/session/Session.ts +2 -2
  37. package/src/testing/TestClient.ts +47 -5
  38. package/src/testing/testUtils.ts +90 -0
@@ -34,23 +34,59 @@ export class TestClient {
34
34
  this.#sessionSeeder = options.sessionSeeder ?? null;
35
35
  }
36
36
  #server = null;
37
- /** Boot the application on a random port. */
37
+ /**
38
+ * In flight or settled, so concurrent callers share one boot.
39
+ *
40
+ * Also what makes `boot()` optional: the first request awaits this, starting
41
+ * it if nobody has. A test file that never issues a request never starts a
42
+ * server — which is the difference between a unit file paying for one and
43
+ * not, and at ~400ms a file that is most of a campaign's time.
44
+ */
45
+ #booting = null;
46
+ /**
47
+ * Boot the application on a random port. Idempotent: a second call awaits the
48
+ * first rather than starting a second server.
49
+ *
50
+ * Optional — a request boots on its own. Call it when you need `port` before
51
+ * issuing one (an SSE or WebSocket connection opened with `fetch`).
52
+ */
38
53
  async boot() {
54
+ this.#booting ??= this.#startServer();
55
+ return this.#booting;
56
+ }
57
+ async #startServer() {
39
58
  this.#server = await this.#bootFn(0);
40
59
  this.#port = this.#server.port;
41
60
  }
42
- /** Close the server. */
61
+ /** Whether a server is currently running for this client. */
62
+ get booted() {
63
+ return this.#server !== null;
64
+ }
65
+ /**
66
+ * Close the server. A no-op when nothing was ever started, so a teardown can
67
+ * call it unconditionally against a client whose file issued no request.
68
+ */
43
69
  async close() {
70
+ // Awaited first: closing while a boot is in flight would otherwise leave
71
+ // the server that boot is about to assign running with nobody holding it.
72
+ if (this.#booting)
73
+ await this.#booting.catch(() => { });
74
+ this.#booting = null;
44
75
  if (this.#server) {
45
76
  await this.#server.close();
46
77
  this.#server = null;
78
+ this.#port = 0;
47
79
  }
48
80
  }
49
81
  /**
50
82
  * Ephemeral port the booted server bound to. Useful for long-lived
51
83
  * connections (SSE / WebSocket) that the fluent buffered request
52
84
  * surface can't model — open them with `fetch` against
53
- * `http://127.0.0.1:${client.port}/...`. Returns 0 before `boot()`.
85
+ * `http://127.0.0.1:${client.port}/...`.
86
+ *
87
+ * Returns 0 while no server is running. Requests boot on their own, so a
88
+ * client that has only been constructed has not bound a port yet — `await
89
+ * client.boot()` first when you need this before issuing one.
54
90
  */
55
91
  get port() {
56
92
  return this.#port;
@@ -102,7 +138,12 @@ export class TestClient {
102
138
  * `form()`. The lower-level `request()` (below) stays for raw control.
103
139
  */
104
140
  fluent(method, path) {
105
- const sender = (m, p, init) => sendRequest(this.#port, m, p, { ...this.#headers, ...init.headers }, init.body.toString('utf8'), init.timeoutMs);
141
+ const sender = async (m, p, init) => {
142
+ // Boots on the first request and no earlier. `#port` is read here rather
143
+ // than captured, so it is the port this boot bound to.
144
+ await this.boot();
145
+ return sendRequest(this.#port, m, p, { ...this.#headers, ...init.headers }, init.body.toString('utf8'), init.timeoutMs);
146
+ };
106
147
  return new RequestBuilder(sender, method, path, this.#auth, this.#sessionSeeder);
107
148
  }
108
149
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TestClient.js","sourceRoot":"","sources":["../../src/testing/TestClient.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Test utilities, in the shape AdonisJS gives them: `testUtils.httpServer()`
3
+ * starts the application's HTTP server for a test run and hands back the
4
+ * function that closes it.
5
+ *
6
+ * // tests/bootstrap.ts
7
+ * configureSuite(suite) {
8
+ * if (['functional', 'e2e'].includes(suite.name)) {
9
+ * return suite.setup(() => testUtils.httpServer().start())
10
+ * }
11
+ * }
12
+ *
13
+ * The point of the shape is WHERE the server starts. A suite that does not
14
+ * declare the hook never starts one, so a unit suite pays nothing — which is
15
+ * the same saving a lazily-booted client buys, obtained by scoping instead of
16
+ * by deferring, and obtained per SUITE rather than per file.
17
+ *
18
+ * `start()` returning its own teardown is what makes it a one-liner in a hook:
19
+ * a setup hook may return its undo, so there is no matching `teardown` to
20
+ * write and no way to forget it.
21
+ */
22
+ import { TestClient } from './TestClient.js';
23
+ /** Boots the app on `port` and reports the port it bound plus how to stop it. */
24
+ export type BootServer = (port: number) => Promise<{
25
+ port: number;
26
+ close: () => Promise<void> | void;
27
+ }>;
28
+ /**
29
+ * What `testUtils.httpServer()` returns — AdonisJS `HttpServerUtils`.
30
+ */
31
+ export declare class HttpServerUtils {
32
+ #private;
33
+ constructor(boot: BootServer, onStarted: (client: TestClient) => void);
34
+ /**
35
+ * Start the server. Returns the function that closes it, so a setup hook can
36
+ * return this call directly.
37
+ */
38
+ start(): Promise<() => Promise<void>>;
39
+ }
40
+ /**
41
+ * The utilities themselves — AdonisJS `TestUtils`.
42
+ *
43
+ * Constructed with how to boot the app, because ream has no ambient
44
+ * application to reach for: the app is whatever the test bootstrap hands over.
45
+ * That is the one place this differs from AdonisJS, where `testUtils` is a
46
+ * service resolved from the container and already knows its app.
47
+ */
48
+ export declare class TestUtils {
49
+ #private;
50
+ constructor(boot: BootServer);
51
+ /** Start/stop the HTTP server for a suite. */
52
+ httpServer(): HttpServerUtils;
53
+ /**
54
+ * The client for the server this run started, or `undefined` before
55
+ * `httpServer().start()`. A plugin reads it to put a client on the test
56
+ * context without booting a second server.
57
+ */
58
+ client(): TestClient | undefined;
59
+ }
60
+ /** Build the utilities for an app booted by `boot`. */
61
+ export declare function createTestUtils(boot: BootServer): TestUtils;
62
+ //# sourceMappingURL=testUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../../src/testing/testUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,iFAAiF;AACjF,MAAM,MAAM,UAAU,GAAG,CACvB,IAAI,EAAE,MAAM,KACT,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAAE,CAAC,CAAA;AAEjE;;GAEG;AACH,qBAAa,eAAe;;gBAId,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI;IAKrE;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAM5C;AAED;;;;;;;GAOG;AACH,qBAAa,SAAS;;gBAIR,IAAI,EAAE,UAAU;IAI5B,8CAA8C;IAC9C,UAAU,IAAI,eAAe;IAM7B;;;;OAIG;IACH,MAAM,IAAI,UAAU,GAAG,SAAS;CAGjC;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAE3D"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Test utilities, in the shape AdonisJS gives them: `testUtils.httpServer()`
3
+ * starts the application's HTTP server for a test run and hands back the
4
+ * function that closes it.
5
+ *
6
+ * // tests/bootstrap.ts
7
+ * configureSuite(suite) {
8
+ * if (['functional', 'e2e'].includes(suite.name)) {
9
+ * return suite.setup(() => testUtils.httpServer().start())
10
+ * }
11
+ * }
12
+ *
13
+ * The point of the shape is WHERE the server starts. A suite that does not
14
+ * declare the hook never starts one, so a unit suite pays nothing — which is
15
+ * the same saving a lazily-booted client buys, obtained by scoping instead of
16
+ * by deferring, and obtained per SUITE rather than per file.
17
+ *
18
+ * `start()` returning its own teardown is what makes it a one-liner in a hook:
19
+ * a setup hook may return its undo, so there is no matching `teardown` to
20
+ * write and no way to forget it.
21
+ */
22
+ import { TestClient } from './TestClient.js';
23
+ /**
24
+ * What `testUtils.httpServer()` returns — AdonisJS `HttpServerUtils`.
25
+ */
26
+ export class HttpServerUtils {
27
+ #boot;
28
+ #onStarted;
29
+ constructor(boot, onStarted) {
30
+ this.#boot = boot;
31
+ this.#onStarted = onStarted;
32
+ }
33
+ /**
34
+ * Start the server. Returns the function that closes it, so a setup hook can
35
+ * return this call directly.
36
+ */
37
+ async start() {
38
+ const client = new TestClient(this.#boot);
39
+ await client.boot();
40
+ this.#onStarted(client);
41
+ return () => client.close();
42
+ }
43
+ }
44
+ /**
45
+ * The utilities themselves — AdonisJS `TestUtils`.
46
+ *
47
+ * Constructed with how to boot the app, because ream has no ambient
48
+ * application to reach for: the app is whatever the test bootstrap hands over.
49
+ * That is the one place this differs from AdonisJS, where `testUtils` is a
50
+ * service resolved from the container and already knows its app.
51
+ */
52
+ export class TestUtils {
53
+ #boot;
54
+ #client;
55
+ constructor(boot) {
56
+ this.#boot = boot;
57
+ }
58
+ /** Start/stop the HTTP server for a suite. */
59
+ httpServer() {
60
+ return new HttpServerUtils(this.#boot, (client) => {
61
+ this.#client = client;
62
+ });
63
+ }
64
+ /**
65
+ * The client for the server this run started, or `undefined` before
66
+ * `httpServer().start()`. A plugin reads it to put a client on the test
67
+ * context without booting a second server.
68
+ */
69
+ client() {
70
+ return this.#client;
71
+ }
72
+ }
73
+ /** Build the utilities for an app booted by `boot`. */
74
+ export function createTestUtils(boot) {
75
+ return new TestUtils(boot);
76
+ }
77
+ //# sourceMappingURL=testUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testUtils.js","sourceRoot":"","sources":["../../src/testing/testUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAO5C;;GAEG;AACH,MAAM,OAAO,eAAe;IACjB,KAAK,CAAY;IACjB,UAAU,CAA8B;IAEjD,YAAY,IAAgB,EAAE,SAAuC;QACnE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;IAC7B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACzC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAA;QACnB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAA;QACvB,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IAC7B,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,SAAS;IACX,KAAK,CAAY;IAC1B,OAAO,CAAwB;IAE/B,YAAY,IAAgB;QAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,8CAA8C;IAC9C,UAAU;QACR,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YAChD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACvB,CAAC,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,UAAU,eAAe,CAAC,IAAgB;IAC9C,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC"}
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/ream",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Ream — Rust-powered Node.js application framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -43,6 +43,10 @@
43
43
  "types": "./dist/services/encryption.d.ts",
44
44
  "import": "./dist/services/encryption.js"
45
45
  },
46
+ "./services/logger": {
47
+ "types": "./dist/services/logger.d.ts",
48
+ "import": "./dist/services/logger.js"
49
+ },
46
50
  "./services/urlBuilder": {
47
51
  "types": "./dist/services/urlBuilder.d.ts",
48
52
  "import": "./dist/services/urlBuilder.js"
@@ -91,6 +95,10 @@
91
95
  "types": "./dist/testing/TestClient.d.ts",
92
96
  "import": "./dist/testing/TestClient.js"
93
97
  },
98
+ "./testing/utils": {
99
+ "types": "./dist/testing/testUtils.d.ts",
100
+ "import": "./dist/testing/testUtils.js"
101
+ },
94
102
  "./bootstrap": {
95
103
  "types": "./dist/bootstrap/hyper-server.d.ts",
96
104
  "import": "./dist/bootstrap/hyper-server.js"
Binary file
package/src/Ignitor.ts CHANGED
@@ -30,7 +30,7 @@ import { startHotReload } from './HotReload.js'
30
30
  import type { HttpKernelRequest, HttpKernelResponse } from './HttpKernel.js'
31
31
  import { createHttpKernel } from './HttpKernel.js'
32
32
  import { ExceptionHandler } from './http/Exception.js'
33
- import { HttpContext } from './http/HttpContext.js'
33
+ import { type ChildLoggerSource, HttpContext } from './http/HttpContext.js'
34
34
  import type { MiddlewareFunction } from './middleware/Pipeline.js'
35
35
  import { MiddlewareRegistry } from './middleware/Pipeline.js'
36
36
  import { MigrationRegistry } from './migrations/MigrationRegistry.js'
@@ -42,6 +42,7 @@ import { SignedUrl } from './security/SignedUrl.js'
42
42
  import { Server } from './server/Server.js'
43
43
  import { clearApp, setApp } from './services/app.js'
44
44
  import { clearEncryption, setEncryption } from './services/encryption.js'
45
+ import { clearLogger, setLogger } from './services/logger.js'
45
46
  import { clearRouter, setRouter } from './services/router.js'
46
47
  import { clearServer, setServer } from './services/server.js'
47
48
  import { registerSessionTemplateTags } from './session/templateTags.js'
@@ -250,6 +251,11 @@ export class Ignitor {
250
251
  * — an unguarded clear would tear down a newer Ignitor's binding.
251
252
  */
252
253
  #signer?: CookieSigner
254
+ /**
255
+ * The bound logger, when a provider supplied one. Held so `stop()` releases
256
+ * the locator against the exact instance it installed.
257
+ */
258
+ #logger?: ChildLoggerSource
253
259
  #_httpServer?: HyperServerLike
254
260
  #config: IgnitorConfig
255
261
  #appRoot?: URL
@@ -557,6 +563,15 @@ export class Ignitor {
557
563
 
558
564
  async #phaseBoot(): Promise<void> {
559
565
  await this.#app.boot()
566
+ // A provider is what binds `'logger'` — ream declares the contract and
567
+ // implements none — so the locator can only be filled once they have all
568
+ // booted. Absent is a normal state: `ctx.logger` falls back to console and
569
+ // `services/logger` says which package to install.
570
+ const container = this.#app.container
571
+ if (container.has('logger')) {
572
+ this.#logger = await container.resolve<ChildLoggerSource>('logger')
573
+ setLogger(this.#logger)
574
+ }
560
575
  this.#phase = 'booted'
561
576
  }
562
577
 
@@ -885,6 +900,7 @@ export class Ignitor {
885
900
  // `services/encryption` is the same object, so releasing it here keeps the
886
901
  // locator from outliving the app that built it.
887
902
  if (this.#signer) clearEncryption(this.#signer)
903
+ if (this.#logger) clearLogger(this.#logger)
888
904
 
889
905
  this.#phase = 'shutdown'
890
906
  if (errors.length === 1) throw errors[0]
@@ -38,7 +38,7 @@ function isHyperServerNapi(value: unknown): value is HyperServerNapiModule {
38
38
  typeof value === 'object' &&
39
39
  value !== null &&
40
40
  'HyperServer' in value &&
41
- typeof (value as { HyperServer: unknown }).HyperServer === 'function'
41
+ typeof value.HyperServer === 'function'
42
42
  )
43
43
  }
44
44
 
package/src/helpers/is.ts CHANGED
@@ -62,12 +62,7 @@ export function isArray<T = unknown>(v: unknown): v is T[] {
62
62
  * @example isPromise(Promise.resolve()) // true
63
63
  */
64
64
  export function isPromise<T = unknown>(v: unknown): v is Promise<T> {
65
- return (
66
- v !== null &&
67
- typeof v === 'object' &&
68
- 'then' in v &&
69
- typeof (v as Record<string, unknown>).then === 'function'
70
- )
65
+ return v !== null && typeof v === 'object' && 'then' in v && typeof v.then === 'function'
71
66
  }
72
67
 
73
68
  /**
package/src/index.ts CHANGED
@@ -371,4 +371,4 @@ export {
371
371
  StatsTracker,
372
372
  } from './scheduler/index.js'
373
373
 
374
- export const VERSION = '0.2.6'
374
+ export const VERSION = '0.2.7'
@@ -252,9 +252,12 @@ export class Scheduler {
252
252
  // `.then`-based detection + `Promise.resolve` wrap so non-native
253
253
  // thenables (e.g. RxJS-style) are handled uniformly.
254
254
  if (
255
+ // Object OR function: a thenable function is exotic but legal, and the
256
+ // guard this replaced accepted one. `in` narrows either.
257
+ (typeof result === 'object' || typeof result === 'function') &&
255
258
  result !== null &&
256
- result !== undefined &&
257
- typeof (result as { then?: unknown }).then === 'function'
259
+ 'then' in result &&
260
+ typeof result.then === 'function'
258
261
  ) {
259
262
  Promise.resolve(result).catch(() => {})
260
263
  }
@@ -334,9 +337,12 @@ export class Scheduler {
334
337
  // reporter never crashes the ticker.
335
338
  const result = this.#errorReporter(err, { taskName }) as unknown
336
339
  if (
340
+ // Object OR function: a thenable function is exotic but legal, and the
341
+ // guard this replaced accepted one. `in` narrows either.
342
+ (typeof result === 'object' || typeof result === 'function') &&
337
343
  result !== null &&
338
- result !== undefined &&
339
- typeof (result as { then?: unknown }).then === 'function'
344
+ 'then' in result &&
345
+ typeof result.then === 'function'
340
346
  ) {
341
347
  Promise.resolve(result).catch(() => {})
342
348
  }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Application logger singleton service.
3
+ *
4
+ * Usage:
5
+ * import logger from '@c9up/ream/services/logger'
6
+ * logger.info('user signed in', { userId })
7
+ *
8
+ * ream does not implement the logger — it declares the contract
9
+ * ({@link ContextLogger}) and reads whatever a provider bound as `'logger'`.
10
+ * `@c9up/spectrum` is the implementation in this universe, the way `hash` is
11
+ * sigil's and validation is rune's.
12
+ *
13
+ * `ctx.logger` stays the right thing to use inside a request: it is
14
+ * correlation-scoped. This is for everywhere else — a provider, a scheduled
15
+ * task, a console command — where there is no request to scope to.
16
+ */
17
+
18
+ import type { ChildLoggerSource } from '../http/HttpContext.js'
19
+ import { createServiceProxy } from './createServiceProxy.js'
20
+
21
+ let instance: ChildLoggerSource | undefined
22
+
23
+ /** @internal Set the logger (called by Ignitor once providers have booted). */
24
+ export function setLogger(logger: ChildLoggerSource): void {
25
+ instance = logger
26
+ }
27
+
28
+ /**
29
+ * @internal Unset the locator IF it still points at `logger` (called by
30
+ * Ignitor.stop()). Ownership-guarded — see services/app.ts.
31
+ */
32
+ export function clearLogger(logger: ChildLoggerSource): void {
33
+ if (instance === logger) instance = undefined
34
+ }
35
+
36
+ /** @internal Get the logger directly. */
37
+ export function getLogger(): ChildLoggerSource | undefined {
38
+ return instance
39
+ }
40
+
41
+ const logger: ChildLoggerSource = createServiceProxy<ChildLoggerSource>(
42
+ () => instance,
43
+ 'Logger accessed before initialization. ' +
44
+ 'ream declares the contract but implements no logger — install one (`@c9up/spectrum`) ' +
45
+ "and register its provider, which binds it as 'logger'. Inside a request, prefer " +
46
+ '`ctx.logger`, which is scoped to the correlation id.',
47
+ )
48
+
49
+ export default logger
@@ -56,9 +56,9 @@ export interface SessionDriverWithTagging extends SessionDriver {
56
56
  export function supportsTagging(driver: SessionDriver): driver is SessionDriverWithTagging {
57
57
  return (
58
58
  'tag' in driver &&
59
- typeof (driver as SessionDriverWithTagging).tag === 'function' &&
59
+ typeof driver.tag === 'function' &&
60
60
  'tagged' in driver &&
61
- typeof (driver as SessionDriverWithTagging).tagged === 'function'
61
+ typeof driver.tagged === 'function'
62
62
  )
63
63
  }
64
64
 
@@ -68,17 +68,51 @@ export class TestClient {
68
68
 
69
69
  #server: { port: number; close: () => Promise<void> | void } | null = null
70
70
 
71
- /** Boot the application on a random port. */
71
+ /**
72
+ * In flight or settled, so concurrent callers share one boot.
73
+ *
74
+ * Also what makes `boot()` optional: the first request awaits this, starting
75
+ * it if nobody has. A test file that never issues a request never starts a
76
+ * server — which is the difference between a unit file paying for one and
77
+ * not, and at ~400ms a file that is most of a campaign's time.
78
+ */
79
+ #booting: Promise<void> | null = null
80
+
81
+ /**
82
+ * Boot the application on a random port. Idempotent: a second call awaits the
83
+ * first rather than starting a second server.
84
+ *
85
+ * Optional — a request boots on its own. Call it when you need `port` before
86
+ * issuing one (an SSE or WebSocket connection opened with `fetch`).
87
+ */
72
88
  async boot(): Promise<void> {
89
+ this.#booting ??= this.#startServer()
90
+ return this.#booting
91
+ }
92
+
93
+ async #startServer(): Promise<void> {
73
94
  this.#server = await this.#bootFn(0)
74
95
  this.#port = this.#server.port
75
96
  }
76
97
 
77
- /** Close the server. */
98
+ /** Whether a server is currently running for this client. */
99
+ get booted(): boolean {
100
+ return this.#server !== null
101
+ }
102
+
103
+ /**
104
+ * Close the server. A no-op when nothing was ever started, so a teardown can
105
+ * call it unconditionally against a client whose file issued no request.
106
+ */
78
107
  async close(): Promise<void> {
108
+ // Awaited first: closing while a boot is in flight would otherwise leave
109
+ // the server that boot is about to assign running with nobody holding it.
110
+ if (this.#booting) await this.#booting.catch(() => {})
111
+ this.#booting = null
79
112
  if (this.#server) {
80
113
  await this.#server.close()
81
114
  this.#server = null
115
+ this.#port = 0
82
116
  }
83
117
  }
84
118
 
@@ -86,7 +120,11 @@ export class TestClient {
86
120
  * Ephemeral port the booted server bound to. Useful for long-lived
87
121
  * connections (SSE / WebSocket) that the fluent buffered request
88
122
  * surface can't model — open them with `fetch` against
89
- * `http://127.0.0.1:${client.port}/...`. Returns 0 before `boot()`.
123
+ * `http://127.0.0.1:${client.port}/...`.
124
+ *
125
+ * Returns 0 while no server is running. Requests boot on their own, so a
126
+ * client that has only been constructed has not bound a port yet — `await
127
+ * client.boot()` first when you need this before issuing one.
90
128
  */
91
129
  get port(): number {
92
130
  return this.#port
@@ -148,8 +186,11 @@ export class TestClient {
148
186
  * `form()`. The lower-level `request()` (below) stays for raw control.
149
187
  */
150
188
  fluent(method: HttpMethod, path: string): RequestBuilder {
151
- const sender: HttpSender = (m, p, init) =>
152
- sendRequest(
189
+ const sender: HttpSender = async (m, p, init) => {
190
+ // Boots on the first request and no earlier. `#port` is read here rather
191
+ // than captured, so it is the port this boot bound to.
192
+ await this.boot()
193
+ return sendRequest(
153
194
  this.#port,
154
195
  m,
155
196
  p,
@@ -157,6 +198,7 @@ export class TestClient {
157
198
  init.body.toString('utf8'),
158
199
  init.timeoutMs,
159
200
  )
201
+ }
160
202
  return new RequestBuilder(sender, method, path, this.#auth, this.#sessionSeeder)
161
203
  }
162
204