@c9up/eon 0.2.9 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"EonProvider.d.ts","sourceRoot":"","sources":["../src/EonProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAa,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EACN,KAAK,iBAAiB,EAEtB,KAAK,UAAU,EACf,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE;QACV,SAAS,CACR,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,GACpB,IAAI,CAAC;QACR;;;;WAIG;QACH,OAAO,CAAC,CACP,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,GAC1D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC9B,CAAC;IACF,MAAM,EAAE;QAAE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;IACzD;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,iBAAiB,CAAC;CAC/D;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAC1B,MAAM,EAAE,mBAAmB,KACvB,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,qBAAa,WAAW;;gBAQX,GAAG,EAAE,aAAa,EAAE,OAAO,GAAE,YAA2B;IAKpE,QAAQ,IAAI,IAAI;IAOV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6IrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAgF/B;AAID,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"EonProvider.d.ts","sourceRoot":"","sources":["../src/EonProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAa,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,EACN,KAAK,iBAAiB,EAEtB,KAAK,UAAU,EACf,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE;QACV,SAAS,CACR,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,EAC5D,OAAO,EAAE,MAAM,OAAO,GACpB,IAAI,CAAC;QACR;;;;WAIG;QACH,OAAO,CAAC,CACP,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,GAC1D,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC9B,CAAC;IACF,MAAM,EAAE;QAAE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;IACzD;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,iBAAiB,CAAC;CAC/D;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,CAC1B,MAAM,EAAE,mBAAmB,KACvB,OAAO,CAAC,aAAa,CAAC,CAAC;AAE5B,qBAAa,WAAW;;gBAUX,GAAG,EAAE,aAAa,EAAE,OAAO,GAAE,YAA2B;IAKpE,QAAQ,IAAI,IAAI;IAgFV,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuNrB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAkF/B;AAID,eAAe,WAAW,CAAC"}
@@ -22,11 +22,72 @@ export class EonProvider {
22
22
  #connections = new Map();
23
23
  /** Set once a full boot opened connections — guards against a leaking re-boot. */
24
24
  #booted = false;
25
+ /** What the `eon` / `eon.connection` tokens resolve to, once boot opened it. */
26
+ #defaultConnection;
25
27
  constructor(app, connect = connectWsEon) {
26
28
  this.#app = app;
27
29
  this.#connect = connect;
28
30
  }
29
- register() { }
31
+ register() {
32
+ // Bindings belong here, not in boot(). Upstream registers in `register`
33
+ // precisely so another provider can count on them during its own boot;
34
+ // bound in boot, the container had a different surface depending on
35
+ // which provider ran first, and `eon.compiler` was simply unavailable to
36
+ // anything booting earlier.
37
+ //
38
+ // It is also pure — a compile is a call into the native compiler, no
39
+ // socket, no database — so there is nothing here an inspection must
40
+ // avoid.
41
+ const service = {
42
+ compile: (spec, dialect) => compileStatementNative(spec, dialect),
43
+ };
44
+ this.#app.container.singleton("eon.compiler", () => service);
45
+ // The connection tokens are registered here too, so the surface does not
46
+ // change between warmup and run. What they RESOLVE to still depends on
47
+ // boot having opened something — a lazy factory cannot await — so
48
+ // reading one too early says what to do instead of answering undefined.
49
+ this.#app.container.singleton("eon", () => this.#requireDefault("eon"));
50
+ this.#app.container.singleton("eon.connection", () => this.#requireDefault("eon.connection"));
51
+ // The NAMED tokens too. Their names come from the config, which is
52
+ // readable here — nothing about `eon:primary` needs a socket to exist.
53
+ // Bound in boot they appeared only on the run path, so the container had
54
+ // a different surface in an inspection, and a boot that failed late left
55
+ // factories behind pointing at connections it had just closed.
56
+ const config = this.#app.config.get("timeseries") ??
57
+ this.#app.config.get("eon");
58
+ if (!config)
59
+ return;
60
+ for (const name of Object.keys(this.#resolveConnections(config).connections)) {
61
+ this.#app.container.singleton(`eon:${name}`, () => this.#requireNamed(name));
62
+ }
63
+ }
64
+ /**
65
+ * A named connection, or a message saying what is missing.
66
+ *
67
+ * Same reasoning as {@link #requireDefault}: resolving to `undefined` sent
68
+ * the caller into a TypeError several frames from the cause.
69
+ */
70
+ #requireNamed(name) {
71
+ const connection = this.#connections.get(name);
72
+ if (connection === undefined) {
73
+ throw new Error(`EonProvider: connection '${name}' was resolved before it was opened. Connections open in boot(); check that config.timeseries.connections defines '${name}' and that EonProvider is listed before whatever resolved this.`);
74
+ }
75
+ return connection;
76
+ }
77
+ /**
78
+ * The default connection, or a message naming what is missing.
79
+ *
80
+ * Resolving to `undefined` sent the caller into a `TypeError` several
81
+ * frames away from the cause — a provider that resolved eon during its own
82
+ * boot, or an application with no `config/timeseries.ts` at all.
83
+ */
84
+ #requireDefault(token) {
85
+ const connection = this.#defaultConnection;
86
+ if (connection === undefined) {
87
+ throw new Error(`EonProvider: '${token}' was resolved before any connection was opened. Connections open in boot(); check that config.timeseries defines one and that EonProvider is listed before whatever resolved this.`);
88
+ }
89
+ return connection;
90
+ }
30
91
  /** True when the application was assembled to be inspected rather than run. */
31
92
  #isInspecting() {
32
93
  return this.#app.getMode?.() === "warmup";
@@ -39,12 +100,7 @@ export class EonProvider {
39
100
  if (this.#booted) {
40
101
  throw new Error("EonProvider: boot() has already opened connections; a second boot would overwrite and leak them. Call shutdown() first, or construct a new provider.");
41
102
  }
42
- // The compiler is transport-independent register it unconditionally.
43
- const service = {
44
- compile: (spec, dialect) => compileStatementNative(spec, dialect),
45
- };
46
- this.#app.container.singleton("eon.compiler", () => service);
47
- // Everything past here opens a socket or creates a database, so an
103
+ // Everything here opens a socket or creates a database, so an
48
104
  // inspection stops at the compiler. `warmUp()` runs boot, so a route
49
105
  // listing reached TDengine — and could CREATE a database there — while
50
106
  // `shutdown()` never fires on that path, leaving the sockets open.
@@ -97,22 +153,63 @@ export class EonProvider {
97
153
  this.#connections.clear();
98
154
  throw new Error(`EonProvider: default connection '${defaultName}' is not defined in config.timeseries.connections`);
99
155
  }
100
- // Register the container singletons only AFTER validation succeeds. The
101
- // throw path above registers none, so a failed boot never leaves an
102
- // `eon:<name>` factory resolving to a now-closed connection.
103
- for (const { name, conn } of successes) {
104
- this.#app.container.singleton(`eon:${name}`, () => conn);
105
- }
106
- this.#app.container.singleton("eon", () => defaultConn);
107
- this.#app.container.singleton("eon.connection", () => defaultConn);
108
- // Populate the `@c9up/eon/services/connection` singleton so apps can
109
- // `import connection from '@c9up/eon/services/connection'` anywhere. Lazy
110
- // import so a type-only discovery scan does not pull the module at
111
- // construction time.
112
- const { setConnection } = await import("./services/connection.js");
113
- setConnection(defaultConn);
114
- await this.#registerMigrationSource(defaultConn, config);
115
- this.#booted = true;
156
+ // Everything past this point runs with the sockets ALREADY OPEN, and any
157
+ // of it can fail: importing the services module, registering the
158
+ // migration source. Without this the failure left the connections open,
159
+ // possibly the module singleton published, and `#booted` false so the
160
+ // next attempt opened another set on top of the ones nobody could reach.
161
+ try {
162
+ // The tokens were all bound in `register()`; this is what they
163
+ // resolve to. Filling the map is what makes them answer.
164
+ this.#defaultConnection = defaultConn;
165
+ // Populate the `@c9up/eon/services/connection` singleton so apps can
166
+ // `import connection from '@c9up/eon/services/connection'` anywhere.
167
+ // Lazy import so a type-only discovery scan does not pull the module
168
+ // at construction time.
169
+ const { setConnection } = await import("./services/connection.js");
170
+ setConnection(defaultConn);
171
+ await this.#registerMigrationSource(defaultConn, config);
172
+ this.#booted = true;
173
+ }
174
+ catch (error) {
175
+ await this.#rollbackBoot(defaultConn);
176
+ throw error;
177
+ }
178
+ }
179
+ /**
180
+ * Undo a boot that opened its connections and then failed.
181
+ *
182
+ * Everything this releases was created by THIS attempt, so a retry starts
183
+ * from nothing rather than from a half-assembled state. The module
184
+ * singleton is released only while it is still the one we published — two
185
+ * applications can share a process, and the survivor's connection must
186
+ * stay.
187
+ */
188
+ async #rollbackBoot(published) {
189
+ await this.#releaseMigrationSource();
190
+ // The connector keeps PROCESS-GLOBAL handles, so closing the individual
191
+ // connections is not enough to let Node exit — shutdown() says so and
192
+ // destroys them; a failed boot left them behind and the process hung.
193
+ const hadWebsocket = [...this.#connections.values()].some((conn) => conn.transport === "websocket");
194
+ try {
195
+ const { clearConnection } = await import("./services/connection.js");
196
+ clearConnection(published);
197
+ }
198
+ catch {
199
+ // The module could not be loaded, so nothing was published from it.
200
+ }
201
+ this.#defaultConnection = undefined;
202
+ await Promise.allSettled([...this.#connections.values()].map((conn) => conn.close()));
203
+ this.#connections.clear();
204
+ if (hadWebsocket) {
205
+ try {
206
+ const { destroyEonConnector } = await import("./connection/websocket.js");
207
+ await destroyEonConnector();
208
+ }
209
+ catch {
210
+ // A fake-only boot never pulled the connector in.
211
+ }
212
+ }
116
213
  }
117
214
  /**
118
215
  * Hand eon's migration runner to the framework's `migrations` registry, so
@@ -142,20 +239,52 @@ export class EonProvider {
142
239
  }
143
240
  const { EonMigrationRunner } = await import("./schema/EonMigrationRunner.js");
144
241
  const migrationsDir = config.migrationsDir ?? "database/eon-migrations";
145
- registry.register({
242
+ const source = {
146
243
  name: "eon",
147
244
  directory: migrationsDir,
148
245
  runner: new EonMigrationRunner(conn, { migrationsDir }),
149
- });
246
+ };
247
+ registry.register(source);
248
+ // Kept so shutdown can hand the name back. Registering refuses a
249
+ // duplicate, so a provider that stops without releasing its name leaves
250
+ // a second boot in the same process failing on "already registered" —
251
+ // and the CLI driving a runner that holds a closed connection.
252
+ this.#migrationSource = source;
253
+ }
254
+ /** What this provider registered with the host's migration registry. */
255
+ #migrationSource;
256
+ /** Give the migration name back, while it is still ours. */
257
+ async #releaseMigrationSource() {
258
+ const source = this.#migrationSource;
259
+ if (source === undefined)
260
+ return;
261
+ this.#migrationSource = undefined;
262
+ const resolve = this.#app.container.resolve;
263
+ if (typeof resolve !== "function")
264
+ return;
265
+ try {
266
+ const registry = await resolve.call(this.#app.container, "migrations");
267
+ if (typeof registry === "object" &&
268
+ registry !== null &&
269
+ typeof Reflect.get(registry, "unregister") === "function") {
270
+ registry.unregister("eon", source);
271
+ }
272
+ }
273
+ catch {
274
+ // No registry, or an older host without `unregister`: nothing to give
275
+ // back, and a shutdown must not fail over it.
276
+ }
150
277
  }
151
278
  async shutdown() {
152
279
  // Close every connection in parallel. `allSettled` (fail-open) so a single
153
280
  // stuck close doesn't block the rest, but failures are aggregated and
154
281
  // rethrown so supervisors see a non-zero shutdown signal. The map + module
155
282
  // singleton are cleared unconditionally (never hand out closed handles).
283
+ await this.#releaseMigrationSource();
156
284
  const named = [...this.#connections.entries()];
157
285
  const results = await Promise.allSettled(named.map(([, c]) => c.close()));
158
286
  this.#connections.clear();
287
+ this.#defaultConnection = undefined;
159
288
  this.#booted = false; // allow a fresh boot() after a clean shutdown
160
289
  const { clearConnection } = await import("./services/connection.js");
161
290
  for (const [, conn] of named)
@@ -1 +1 @@
1
- {"version":3,"file":"EonProvider.js","sourceRoot":"","sources":["../src/EonProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EonProvider.js","sourceRoot":"","sources":["../src/EonProvider.ts"],"names":[],"mappings":"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"}
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/eon",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "Eon — time-series data layer for the Ream framework (TDengine-backed)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -80,13 +80,88 @@ export class EonProvider {
80
80
  readonly #connections = new Map<string, EonConnection>();
81
81
  /** Set once a full boot opened connections — guards against a leaking re-boot. */
82
82
  #booted = false;
83
+ /** What the `eon` / `eon.connection` tokens resolve to, once boot opened it. */
84
+ #defaultConnection?: EonConnection;
83
85
 
84
86
  constructor(app: EonAppContext, connect: EonConnector = connectWsEon) {
85
87
  this.#app = app;
86
88
  this.#connect = connect;
87
89
  }
88
90
 
89
- register(): void {}
91
+ register(): void {
92
+ // Bindings belong here, not in boot(). Upstream registers in `register`
93
+ // precisely so another provider can count on them during its own boot;
94
+ // bound in boot, the container had a different surface depending on
95
+ // which provider ran first, and `eon.compiler` was simply unavailable to
96
+ // anything booting earlier.
97
+ //
98
+ // It is also pure — a compile is a call into the native compiler, no
99
+ // socket, no database — so there is nothing here an inspection must
100
+ // avoid.
101
+ const service: EonService = {
102
+ compile: (spec, dialect) => compileStatementNative(spec, dialect),
103
+ };
104
+ this.#app.container.singleton("eon.compiler", () => service);
105
+
106
+ // The connection tokens are registered here too, so the surface does not
107
+ // change between warmup and run. What they RESOLVE to still depends on
108
+ // boot having opened something — a lazy factory cannot await — so
109
+ // reading one too early says what to do instead of answering undefined.
110
+ this.#app.container.singleton("eon", () => this.#requireDefault("eon"));
111
+ this.#app.container.singleton("eon.connection", () =>
112
+ this.#requireDefault("eon.connection"),
113
+ );
114
+
115
+ // The NAMED tokens too. Their names come from the config, which is
116
+ // readable here — nothing about `eon:primary` needs a socket to exist.
117
+ // Bound in boot they appeared only on the run path, so the container had
118
+ // a different surface in an inspection, and a boot that failed late left
119
+ // factories behind pointing at connections it had just closed.
120
+ const config =
121
+ this.#app.config.get<EonConfig>("timeseries") ??
122
+ this.#app.config.get<EonConfig>("eon");
123
+ if (!config) return;
124
+ for (const name of Object.keys(
125
+ this.#resolveConnections(config).connections,
126
+ )) {
127
+ this.#app.container.singleton(`eon:${name}`, () =>
128
+ this.#requireNamed(name),
129
+ );
130
+ }
131
+ }
132
+
133
+ /**
134
+ * A named connection, or a message saying what is missing.
135
+ *
136
+ * Same reasoning as {@link #requireDefault}: resolving to `undefined` sent
137
+ * the caller into a TypeError several frames from the cause.
138
+ */
139
+ #requireNamed(name: string): EonConnection {
140
+ const connection = this.#connections.get(name);
141
+ if (connection === undefined) {
142
+ throw new Error(
143
+ `EonProvider: connection '${name}' was resolved before it was opened. Connections open in boot(); check that config.timeseries.connections defines '${name}' and that EonProvider is listed before whatever resolved this.`,
144
+ );
145
+ }
146
+ return connection;
147
+ }
148
+
149
+ /**
150
+ * The default connection, or a message naming what is missing.
151
+ *
152
+ * Resolving to `undefined` sent the caller into a `TypeError` several
153
+ * frames away from the cause — a provider that resolved eon during its own
154
+ * boot, or an application with no `config/timeseries.ts` at all.
155
+ */
156
+ #requireDefault(token: string): EonConnection {
157
+ const connection = this.#defaultConnection;
158
+ if (connection === undefined) {
159
+ throw new Error(
160
+ `EonProvider: '${token}' was resolved before any connection was opened. Connections open in boot(); check that config.timeseries defines one and that EonProvider is listed before whatever resolved this.`,
161
+ );
162
+ }
163
+ return connection;
164
+ }
90
165
 
91
166
  /** True when the application was assembled to be inspected rather than run. */
92
167
  #isInspecting(): boolean {
@@ -103,13 +178,7 @@ export class EonProvider {
103
178
  "EonProvider: boot() has already opened connections; a second boot would overwrite and leak them. Call shutdown() first, or construct a new provider.",
104
179
  );
105
180
  }
106
- // The compiler is transport-independent register it unconditionally.
107
- const service: EonService = {
108
- compile: (spec, dialect) => compileStatementNative(spec, dialect),
109
- };
110
- this.#app.container.singleton("eon.compiler", () => service);
111
-
112
- // Everything past here opens a socket or creates a database, so an
181
+ // Everything here opens a socket or creates a database, so an
113
182
  // inspection stops at the compiler. `warmUp()` runs boot, so a route
114
183
  // listing reached TDengine — and could CREATE a database there — while
115
184
  // `shutdown()` never fires on that path, leaving the sockets open.
@@ -172,24 +241,69 @@ export class EonProvider {
172
241
  `EonProvider: default connection '${defaultName}' is not defined in config.timeseries.connections`,
173
242
  );
174
243
  }
175
- // Register the container singletons only AFTER validation succeeds. The
176
- // throw path above registers none, so a failed boot never leaves an
177
- // `eon:<name>` factory resolving to a now-closed connection.
178
- for (const { name, conn } of successes) {
179
- this.#app.container.singleton(`eon:${name}`, () => conn);
244
+ // Everything past this point runs with the sockets ALREADY OPEN, and any
245
+ // of it can fail: importing the services module, registering the
246
+ // migration source. Without this the failure left the connections open,
247
+ // possibly the module singleton published, and `#booted` false so the
248
+ // next attempt opened another set on top of the ones nobody could reach.
249
+ try {
250
+ // The tokens were all bound in `register()`; this is what they
251
+ // resolve to. Filling the map is what makes them answer.
252
+ this.#defaultConnection = defaultConn;
253
+
254
+ // Populate the `@c9up/eon/services/connection` singleton so apps can
255
+ // `import connection from '@c9up/eon/services/connection'` anywhere.
256
+ // Lazy import so a type-only discovery scan does not pull the module
257
+ // at construction time.
258
+ const { setConnection } = await import("./services/connection.js");
259
+ setConnection(defaultConn);
260
+
261
+ await this.#registerMigrationSource(defaultConn, config);
262
+ this.#booted = true;
263
+ } catch (error) {
264
+ await this.#rollbackBoot(defaultConn);
265
+ throw error;
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Undo a boot that opened its connections and then failed.
271
+ *
272
+ * Everything this releases was created by THIS attempt, so a retry starts
273
+ * from nothing rather than from a half-assembled state. The module
274
+ * singleton is released only while it is still the one we published — two
275
+ * applications can share a process, and the survivor's connection must
276
+ * stay.
277
+ */
278
+ async #rollbackBoot(published: EonConnection): Promise<void> {
279
+ await this.#releaseMigrationSource();
280
+ // The connector keeps PROCESS-GLOBAL handles, so closing the individual
281
+ // connections is not enough to let Node exit — shutdown() says so and
282
+ // destroys them; a failed boot left them behind and the process hung.
283
+ const hadWebsocket = [...this.#connections.values()].some(
284
+ (conn) => conn.transport === "websocket",
285
+ );
286
+ try {
287
+ const { clearConnection } = await import("./services/connection.js");
288
+ clearConnection(published);
289
+ } catch {
290
+ // The module could not be loaded, so nothing was published from it.
291
+ }
292
+ this.#defaultConnection = undefined;
293
+ await Promise.allSettled(
294
+ [...this.#connections.values()].map((conn) => conn.close()),
295
+ );
296
+ this.#connections.clear();
297
+ if (hadWebsocket) {
298
+ try {
299
+ const { destroyEonConnector } = await import(
300
+ "./connection/websocket.js"
301
+ );
302
+ await destroyEonConnector();
303
+ } catch {
304
+ // A fake-only boot never pulled the connector in.
305
+ }
180
306
  }
181
- this.#app.container.singleton("eon", () => defaultConn);
182
- this.#app.container.singleton("eon.connection", () => defaultConn);
183
-
184
- // Populate the `@c9up/eon/services/connection` singleton so apps can
185
- // `import connection from '@c9up/eon/services/connection'` anywhere. Lazy
186
- // import so a type-only discovery scan does not pull the module at
187
- // construction time.
188
- const { setConnection } = await import("./services/connection.js");
189
- setConnection(defaultConn);
190
-
191
- await this.#registerMigrationSource(defaultConn, config);
192
- this.#booted = true;
193
307
  }
194
308
 
195
309
  /**
@@ -227,11 +341,46 @@ export class EonProvider {
227
341
  "./schema/EonMigrationRunner.js"
228
342
  );
229
343
  const migrationsDir = config.migrationsDir ?? "database/eon-migrations";
230
- (registry.register as (source: unknown) => unknown)({
344
+ const source = {
231
345
  name: "eon",
232
346
  directory: migrationsDir,
233
347
  runner: new EonMigrationRunner(conn, { migrationsDir }),
234
- });
348
+ };
349
+ (registry.register as (source: unknown) => unknown)(source);
350
+ // Kept so shutdown can hand the name back. Registering refuses a
351
+ // duplicate, so a provider that stops without releasing its name leaves
352
+ // a second boot in the same process failing on "already registered" —
353
+ // and the CLI driving a runner that holds a closed connection.
354
+ this.#migrationSource = source;
355
+ }
356
+
357
+ /** What this provider registered with the host's migration registry. */
358
+ #migrationSource?: object;
359
+
360
+ /** Give the migration name back, while it is still ours. */
361
+ async #releaseMigrationSource(): Promise<void> {
362
+ const source = this.#migrationSource;
363
+ if (source === undefined) return;
364
+ this.#migrationSource = undefined;
365
+ const resolve = this.#app.container.resolve;
366
+ if (typeof resolve !== "function") return;
367
+ try {
368
+ const registry = await resolve.call(this.#app.container, "migrations");
369
+ if (
370
+ typeof registry === "object" &&
371
+ registry !== null &&
372
+ typeof Reflect.get(registry, "unregister") === "function"
373
+ ) {
374
+ (
375
+ registry as {
376
+ unregister: (name: string, source?: unknown) => unknown;
377
+ }
378
+ ).unregister("eon", source);
379
+ }
380
+ } catch {
381
+ // No registry, or an older host without `unregister`: nothing to give
382
+ // back, and a shutdown must not fail over it.
383
+ }
235
384
  }
236
385
 
237
386
  async shutdown(): Promise<void> {
@@ -239,9 +388,11 @@ export class EonProvider {
239
388
  // stuck close doesn't block the rest, but failures are aggregated and
240
389
  // rethrown so supervisors see a non-zero shutdown signal. The map + module
241
390
  // singleton are cleared unconditionally (never hand out closed handles).
391
+ await this.#releaseMigrationSource();
242
392
  const named = [...this.#connections.entries()];
243
393
  const results = await Promise.allSettled(named.map(([, c]) => c.close()));
244
394
  this.#connections.clear();
395
+ this.#defaultConnection = undefined;
245
396
  this.#booted = false; // allow a fresh boot() after a clean shutdown
246
397
 
247
398
  const { clearConnection } = await import("./services/connection.js");