@voltro/sql-mysql 0.32.0 → 0.34.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/dist/index.d.ts CHANGED
@@ -143,6 +143,10 @@ declare class CdcDeliveryGate {
143
143
  * and the dialect's `id` field is what discriminates downstream.
144
144
  *
145
145
  * Defaults: port 3306, user `app`, password `app`, database `app`.
146
+ *
147
+ * TLS: an explicit `config.ssl` wins; otherwise the URL's `?sslmode=` / `?ssl=`
148
+ * query decides (see `sslFromUrlQuery`); otherwise unset — plaintext, mysql2's
149
+ * default.
146
150
  */
147
151
  export declare const connectionFromConfig: (config: ConnectionConfig) => MysqlConnection;
148
152
 
@@ -180,6 +184,53 @@ export declare interface MysqlConnection {
180
184
  readonly password: string;
181
185
  readonly database: string;
182
186
  readonly maxConnections?: number;
187
+ /**
188
+ * TLS. `true` = encrypt without certificate verification (`sslmode=require`
189
+ * semantics, matching the postgres dialect and the cross-dialect
190
+ * `ConnectionConfig.ssl`); `false`/unset = plaintext, mysql2's default.
191
+ *
192
+ * **There was no TLS path here at all.** `MysqlConnection` carried no `ssl`
193
+ * field, `connectionFromConfig` read neither `config.ssl` nor the URL query,
194
+ * and `makeMysqlSqlLayer` passed the driver nothing — so
195
+ * `DB_URL=mysql://…?ssl=true` connected in PLAINTEXT with no warning and no
196
+ * error. A TLS request that cannot be honoured now throws
197
+ * (see `sslFromUrlQuery`); it never silently downgrades.
198
+ */
199
+ readonly ssl?: boolean;
200
+ /**
201
+ * Bound on ESTABLISHING a connection (ms) — mysql2's `connectTimeout`.
202
+ * Default {@link DEFAULT_ACQUIRE_TIMEOUT_MS}, `0` = the driver's own.
203
+ *
204
+ * Note precisely what this does NOT cover, because the name promises more on
205
+ * postgres than mysql2 can deliver: mysql2's pool has **no time-based bound
206
+ * on waiting for a busy connection**. `lib/base/pool.js` pushes the waiting
207
+ * callback onto `_connectionQueue` and there is no timer anywhere near it, so
208
+ * the queued half is UNBOUNDED — {@link acquireQueueLimit} is the only bound
209
+ * available and is opt-in. Mapping this value onto the wait would be
210
+ * inventing a guarantee.
211
+ *
212
+ * At the framework default this is a no-op: mysql2 already defaults
213
+ * `connectTimeout` to 10 s (`lib/connection_config.js:115`). It is passed
214
+ * anyway so the value is ONE decision across dialects and an operator who
215
+ * lowers it gets it honoured here too — not so that mysql suddenly gains a
216
+ * bound it had.
217
+ */
218
+ readonly acquireTimeoutMs?: number;
219
+ /**
220
+ * How many callers may be queued waiting for a free pooled connection before
221
+ * the next one fails immediately — mysql2's `queueLimit`. **Unset by
222
+ * default**, i.e. mysql2's own unbounded queue; `0` spells the same thing.
223
+ *
224
+ * Opt-in rather than defaulted, and the reason is a measured wedge rather
225
+ * than caution: past the limit mysql2 rejects the acquire SYNCHRONOUSLY (its
226
+ * queue-limit branch is the one error return in `getConnection` that skips
227
+ * `process.nextTick`), so any caller that retries an acquire failure without
228
+ * a delay spins in-tick forever and the event loop — hence every timer, and
229
+ * hence the drain that would clear the queue — is never reached again.
230
+ * `@effect/cluster`'s per-shard release does exactly that. Full account on
231
+ * `ConnectionConfig.acquireQueueLimit`.
232
+ */
233
+ readonly acquireQueueLimit?: number;
183
234
  }
184
235
 
185
236
  /**
@@ -208,6 +259,10 @@ export declare class MysqlStore implements DataStore {
208
259
  private cdcReplicaId;
209
260
  private cdcStreamName;
210
261
  private readonly cdcGate;
262
+ /** PERF-23 — counts EVERY eager JSON-agg → walker degradation and logs a
263
+ * rate-limited line. Instance-scoped so a second store in one process cannot
264
+ * silence this one's first warning. */
265
+ private readonly reportEagerFallback;
211
266
  constructor(sql: SqlClient.SqlClient, runtime: ManagedRuntime.ManagedRuntime<SqlClient.SqlClient | MysqlClient.MysqlClient, never>, variant: 'mysql' | 'mariadb', changeStrategy?: ChangeStrategy, namespace?: QueryNamespace, sharedEmitter?: EventEmitter, sharedGate?: CdcDeliveryGate);
212
267
  /**
213
268
  * Bind a per-request tenant namespace (a DATABASE on mysql/mariadb),
@@ -284,6 +339,13 @@ export declare class MysqlStore implements DataStore {
284
339
  * the range is [first, first + n - 1]. Re-selects that range ordered by
285
340
  * id (= input order) for the post-images. Same connection-pinning +
286
341
  * retry as the single-row path.
342
+ *
343
+ * Takes the rows ALREADY CHUNKED (`bulkInsertLimits.ts`) and walks the chunks
344
+ * on the one pinned connection, because the contiguous-range guarantee is per
345
+ * STATEMENT: each chunk has its own `LAST_INSERT_ID()` and its own
346
+ * `[first, first + chunkLen - 1]`. Chunking outside this function — issuing
347
+ * the inserts and then asking once — would read one chunk's range and lose
348
+ * the rest, which is worse than the limit error it replaces.
287
349
  */
288
350
  private insertManyRecoverAutoIds;
289
351
  private executePatchJson;
@@ -398,6 +460,18 @@ export declare class MysqlStore implements DataStore {
398
460
  /* Excluded from this release type: getInternalExecuteUpsert */
399
461
  /* Excluded from this release type: getInternalExecuteInsertIgnore */
400
462
  transactional<T>(work: (tx: DataStore) => Promise<T>): Promise<T>;
463
+ /**
464
+ * The DIALECT half of the shared transaction bracket
465
+ * (`runStoreTransaction` in `@voltro/database`).
466
+ *
467
+ * mysql/mariadb own three things: the client's `withTransaction`, the runtime,
468
+ * and `isRetryableMysqlFailure` (deadlock / lock-wait timeout). Retry,
469
+ * commit-defect promotion, attribution threading and exit settling are shared
470
+ * — this store carried its own copy of the last one for a release after
471
+ * postgres was fixed, and a consumer on MariaDB paid for it. See
472
+ * `transactionOutcome.ts`.
473
+ */
474
+ private txnSpec;
401
475
  onChange(listener: (event: ChangeEvent) => void): () => void;
402
476
  /** Cross-instance reactivity seam — emit an externally-sourced event to
403
477
  * local subscribers without re-persisting. The binlog CDC consumer and