@ultimat3/cli 25.0.0 → 25.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/cli",
3
- "version": "25.0.0",
3
+ "version": "25.1.0",
4
4
  "description": "The `x` binary: new, dev, build, verify, generate, db, mcp, doctor, deploy",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -39,33 +39,33 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@babel/core": "^8.0.1",
42
- "@ultimat3/action": "25.0.0",
43
- "@ultimat3/admin": "25.0.0",
44
- "@ultimat3/ai": "25.0.0",
45
- "@ultimat3/auth": "25.0.0",
46
- "@ultimat3/cache": "25.0.0",
47
- "@ultimat3/core": "25.0.0",
48
- "@ultimat3/db": "25.0.0",
49
- "@ultimat3/entity": "25.0.0",
50
- "@ultimat3/flags": "25.0.0",
51
- "@ultimat3/http": "25.0.0",
52
- "@ultimat3/i18n": "25.0.0",
53
- "@ultimat3/jobs": "25.0.0",
54
- "@ultimat3/mail": "25.0.0",
55
- "@ultimat3/manifest": "25.0.0",
56
- "@ultimat3/mcp": "25.0.0",
57
- "@ultimat3/money": "25.0.0",
58
- "@ultimat3/notify": "25.0.0",
59
- "@ultimat3/policy": "25.0.0",
60
- "@ultimat3/pwa": "25.0.0",
61
- "@ultimat3/query": "25.0.0",
62
- "@ultimat3/realtime": "25.0.0",
63
- "@ultimat3/render": "25.0.0",
64
- "@ultimat3/schema": "25.0.0",
65
- "@ultimat3/seo": "25.0.0",
66
- "@ultimat3/storage": "25.0.0",
67
- "@ultimat3/testing": "25.0.0",
68
- "@ultimat3/time": "25.0.0",
42
+ "@ultimat3/action": "25.1.0",
43
+ "@ultimat3/admin": "25.1.0",
44
+ "@ultimat3/ai": "25.1.0",
45
+ "@ultimat3/auth": "25.1.0",
46
+ "@ultimat3/cache": "25.1.0",
47
+ "@ultimat3/core": "25.1.0",
48
+ "@ultimat3/db": "25.1.0",
49
+ "@ultimat3/entity": "25.1.0",
50
+ "@ultimat3/flags": "25.1.0",
51
+ "@ultimat3/http": "25.1.0",
52
+ "@ultimat3/i18n": "25.1.0",
53
+ "@ultimat3/jobs": "25.1.0",
54
+ "@ultimat3/mail": "25.1.0",
55
+ "@ultimat3/manifest": "25.1.0",
56
+ "@ultimat3/mcp": "25.1.0",
57
+ "@ultimat3/money": "25.1.0",
58
+ "@ultimat3/notify": "25.1.0",
59
+ "@ultimat3/policy": "25.1.0",
60
+ "@ultimat3/pwa": "25.1.0",
61
+ "@ultimat3/query": "25.1.0",
62
+ "@ultimat3/realtime": "25.1.0",
63
+ "@ultimat3/render": "25.1.0",
64
+ "@ultimat3/schema": "25.1.0",
65
+ "@ultimat3/seo": "25.1.0",
66
+ "@ultimat3/storage": "25.1.0",
67
+ "@ultimat3/testing": "25.1.0",
68
+ "@ultimat3/time": "25.1.0",
69
69
  "babel-preset-solid": "^1.9.15"
70
70
  }
71
71
  }
package/src/role-start.ts CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  import type { Role } from '@ultimat3/core';
10
10
  import { ctxOf, isRole, logger, markReady, ROLES } from '@ultimat3/core';
11
+ import { dbExecutor } from '@ultimat3/db';
11
12
  import type { RateLimitStore, Route, ServerHandle, WebSocketMount } from '@ultimat3/http';
12
13
  import {
13
14
  adoptRateLimitStore,
@@ -43,7 +44,6 @@ import { startWorkerWake } from './role-wake';
43
44
  import { devHooks } from './runtime-hooks';
44
45
  import { workerOptionsFor } from './runtime-jobs';
45
46
  import { startLiveFeed } from './runtime-live-feed';
46
- import { pgExecutorFor } from './runtime-queue';
47
47
  import { type RunningServices, releaseOrThrow } from './runtime-services';
48
48
  import { inlineScriptSources } from './script-csp';
49
49
  import { inlineStyleSources } from './style-csp';
@@ -359,7 +359,7 @@ export async function startRoles(options: StartRolesOptions): Promise<RunningRol
359
359
  // SESSION-scoped, and the session ends the moment the connection goes back to the pool, so
360
360
  // every node reads itself as leader anyway. An expiring row is correct on the executor this
361
361
  // package is actually handed.
362
- const executor = pgExecutorFor(options.runtime.db);
362
+ const executor = dbExecutor(() => options.runtime.db);
363
363
  const scheduler = selected.includes('scheduler')
364
364
  ? jobScheduler({
365
365
  driver: options.runtime.jobs,
package/src/role-wake.ts CHANGED
@@ -5,10 +5,9 @@
5
5
 
6
6
  import { gauge } from '@ultimat3/core';
7
7
  import type { DbClient } from '@ultimat3/db';
8
- import { canListen } from '@ultimat3/db';
8
+ import { canListen, dbExecutor } from '@ultimat3/db';
9
9
  import type { QueueWake } from '@ultimat3/jobs';
10
10
  import { startQueueWake } from '@ultimat3/jobs';
11
- import { pgExecutorFor } from './runtime-queue';
12
11
 
13
12
  // The wake the gauge reads. One observer for the life of the process: a gauge redeclared with a
14
13
  // different `observe` is refused, and `x dev` starts the roles again on every restart-in-place.
@@ -32,7 +31,7 @@ export function startWorkerWake(db: DbClient): QueueWake | null {
32
31
  observe: wakeLive,
33
32
  });
34
33
  }
35
- const wake = startQueueWake({ listener: db, executor: pgExecutorFor(db) });
34
+ const wake = startQueueWake({ listener: db, executor: dbExecutor(() => db) });
36
35
  current = wake;
37
36
  return {
38
37
  live: () => wake.live(),
@@ -11,17 +11,18 @@ import {
11
11
  resetIdempotency,
12
12
  setIdempotencyStore,
13
13
  } from '@ultimat3/action';
14
- import type { DbClient, PgliteClient, PostgresClient, SqlFragment } from '@ultimat3/db';
14
+ import type { PgliteClient, PostgresClient } from '@ultimat3/db';
15
15
  import {
16
16
  baseClient,
17
17
  currentTx,
18
+ dbExecutor,
18
19
  pgliteClient,
19
20
  pgliteDataDir,
20
21
  postgresClient,
21
22
  setDbClient,
22
23
  } from '@ultimat3/db';
23
24
  import type { Tx } from '@ultimat3/entity';
24
- import type { EventBus, JobDriver, OutboxStore, PgExecutor } from '@ultimat3/jobs';
25
+ import type { EventBus, JobDriver, OutboxStore } from '@ultimat3/jobs';
25
26
  import {
26
27
  outboxJobsFacade,
27
28
  postgresEventBus,
@@ -109,20 +110,6 @@ export function startDb(services: DevServices, env: ReplicaEnv): StartedDb {
109
110
  return { client, replica: attached.replica };
110
111
  }
111
112
 
112
- /**
113
- * `@ultimat3/jobs` deliberately depends on no database package: Postgres reaches it as an
114
- * injected `PgExecutor`. Boot code is what supplies one, and this is the boot.
115
- *
116
- * The fragment is assembled by hand rather than through `sql`` ` because the driver hands over
117
- * `$1..$n` text it wrote itself plus already-bound values — there is no interpolation to guard.
118
- */
119
- export function pgExecutorFor(client: DbClient): PgExecutor {
120
- return {
121
- query: <R>(text: string, values: readonly unknown[]): Promise<readonly R[]> =>
122
- client.query<R>({ text, values } satisfies SqlFragment),
123
- };
124
- }
125
-
126
113
  /**
127
114
  * Every table this process's framework packages own, applied before anything reads one.
128
115
  *
@@ -183,13 +170,15 @@ async function startJobs(
183
170
  schema: SchemaMode,
184
171
  ): Promise<RunningQueue> {
185
172
  await applySchema(client, schema);
186
- const executor = pgExecutorFor(client);
173
+ // Bound to `client`, never the ambient `db()`: the queue, the event bus and the idempotency
174
+ // reservations stay on the boot's pool whatever transaction is open.
175
+ const executor = dbExecutor(() => client);
187
176
  const driver = overrides?.jobs ?? postgresJobDriver({ executor });
188
177
  setJobDriver(driver);
189
178
  const outbox = postgresOutboxStore({
190
179
  executor,
191
180
  // The open transaction is a client on its own connection; the `Tx` token is not that object.
192
- txExecutor: () => pgExecutorFor(currentTx() ?? client),
181
+ txExecutor: () => dbExecutor(() => currentTx() ?? client),
193
182
  });
194
183
  setJobsFacade(
195
184
  outboxJobsFacade({ store: outbox, driver }, () => currentTx() as unknown as Tx | undefined),
@@ -15,6 +15,7 @@ import {
15
15
  resolveEnvironment,
16
16
  systemClock,
17
17
  } from '@ultimat3/core';
18
+ import { dbExecutor } from '@ultimat3/db';
18
19
  import type { RateLimitStore } from '@ultimat3/http';
19
20
  import { adoptRateLimitStore, postgresRateLimitStore } from '@ultimat3/http';
20
21
  import type { EventBus, JobDriver, OutboxStore } from '@ultimat3/jobs';
@@ -40,7 +41,7 @@ import { inboxRetentionOf } from './runtime-notify-retention';
40
41
  import type { RuntimeOverrides } from './runtime-overrides';
41
42
  import { installRetentionSweep } from './runtime-purge';
42
43
  import type { DevDbClient, SchemaMode } from './runtime-queue';
43
- import { pgExecutorFor, startQueue } from './runtime-queue';
44
+ import { startQueue } from './runtime-queue';
44
45
  import { realtimeConfigOf } from './runtime-realtime';
45
46
 
46
47
  export interface RunningServices {
@@ -351,7 +352,7 @@ export async function startServices(
351
352
  // The same executor the jobs driver, the outbox, the event bus and the idempotency store run
352
353
  // on — one pool, one `Bun.sql` that does NOT satisfy `PgExecutor` (`Bun.sql.query` is
353
354
  // `undefined`), one wrapper.
354
- const executor = pgExecutorFor(db);
355
+ const executor = dbExecutor(() => db);
355
356
  const rateLimitStore = postgresRateLimitStore({ executor });
356
357
  // Boot is a sequence of external resources, and every step after the first can reject — the
357
358
  // queue is already up, so from here an unwind must release it exactly like everything after it.