@getstrata/core 2.2.10 → 2.2.12

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.
@@ -26,22 +26,6 @@ function createAsyncContextStore(key) {
26
26
  }
27
27
  var init_asyncContextStore = () => {};
28
28
 
29
- // ../../src/core/database/connectionContext.ts
30
- function runWithDatabaseConnection(connection, callback) {
31
- return activeConnection.run(connection, callback);
32
- }
33
- function getActiveDatabaseConnection(fallback) {
34
- return activeConnection.getStore() ?? fallback;
35
- }
36
- function hasActiveDatabaseConnection() {
37
- return activeConnection.getStore() !== undefined;
38
- }
39
- var activeConnection;
40
- var init_connectionContext = __esm(() => {
41
- init_asyncContextStore();
42
- activeConnection = createAsyncContextStore("@getstrata/databaseConnectionContext");
43
- });
44
-
45
29
  // ../../src/core/database/schema/driver.ts
46
30
  function normalizeConnectionName(connection) {
47
31
  const normalized = connection.trim().toLowerCase();
@@ -243,6 +227,22 @@ var init_dialect = __esm(() => {
243
227
  dialectContext = createAsyncContextStore("@getstrata/sqlDialect");
244
228
  });
245
229
 
230
+ // ../../src/core/database/connectionContext.ts
231
+ function runWithDatabaseConnection(connection, callback) {
232
+ return activeConnection.run(connection, callback);
233
+ }
234
+ function getActiveDatabaseConnection(fallback) {
235
+ return activeConnection.getStore() ?? fallback;
236
+ }
237
+ function hasActiveDatabaseConnection() {
238
+ return activeConnection.getStore() !== undefined;
239
+ }
240
+ var activeConnection;
241
+ var init_connectionContext = __esm(() => {
242
+ init_asyncContextStore();
243
+ activeConnection = createAsyncContextStore("@getstrata/databaseConnectionContext");
244
+ });
245
+
246
246
  // ../../src/core/database/boundConnection.ts
247
247
  function boundConnectionState() {
248
248
  const globalRecord = globalThis;
@@ -2192,12 +2192,15 @@ function createAppQueue(driver, redisUrl, failedJobs = createFailedJobService(),
2192
2192
  });
2193
2193
  }
2194
2194
 
2195
- // ../../src/core/database/postgresReadOnlyCollector.ts
2195
+ // ../../src/core/queue/failedJobMetrics.ts
2196
+ init_dialect();
2197
+
2198
+ // ../../src/core/database/readOnlyCollector.ts
2196
2199
  init_connectionContext();
2197
2200
  init_dialect();
2198
2201
  init_repositoryConnection();
2199
2202
  init_transaction();
2200
- function createPostgresReadOnlyCollector(name, timeoutMs, collect) {
2203
+ function createReadOnlyCollector(name, timeoutMs, collect) {
2201
2204
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 5000)
2202
2205
  throw new TypeError(`${name} timeout must be between 1 and 5000 milliseconds.`);
2203
2206
  let active;
@@ -2208,8 +2211,10 @@ function createPostgresReadOnlyCollector(name, timeoutMs, collect) {
2208
2211
  throw new Error(`${name} collector is closed.`);
2209
2212
  if (hasActiveTransaction() || hasActiveDatabaseConnection())
2210
2213
  throw new Error(`${name} require an independent transaction.`);
2211
- if (currentSqlDialect().driver !== "pgsql")
2212
- throw new Error(`${name} currently require Postgres.`);
2214
+ const driver = currentSqlDialect().driver;
2215
+ const pool = resolveRepositoryConnection();
2216
+ if (driver !== "pgsql" && driver !== "sqlite" && driver !== "mysql")
2217
+ throw new Error(`${name} require Postgres or an interruptible SQLite/MySQL adapter.`);
2213
2218
  if (active)
2214
2219
  throw new Error(`${name} collection is still settling.`);
2215
2220
  const deadline = performance.now() + timeoutMs;
@@ -2222,14 +2227,25 @@ function createPostgresReadOnlyCollector(name, timeoutMs, collect) {
2222
2227
  throw new Error(`${name} collection timed out.`);
2223
2228
  return value;
2224
2229
  };
2225
- const work = runInTransaction(async () => {
2226
- await repositoryConnection.unsafe("SELECT set_config('statement_timeout', $1, true)", [`${remaining()}ms`]);
2230
+ const work = driver === "pgsql" ? runInTransaction(async () => {
2231
+ await repositoryConnection.unsafe("SELECT set_config('statement_timeout', $1, true)", [
2232
+ `${remaining()}ms`
2233
+ ]);
2227
2234
  await repositoryConnection.unsafe("SET TRANSACTION READ ONLY");
2228
2235
  remaining();
2229
2236
  const result = await collect(remaining);
2230
2237
  remaining();
2231
2238
  return result;
2232
- }, { acquisitionSignal: acquisition.signal });
2239
+ }, { acquisitionSignal: acquisition.signal }) : (async () => {
2240
+ if (!pool.observeReadOnly)
2241
+ throw new Error(`${name} require Postgres or an interruptible SQLite/MySQL adapter.`);
2242
+ return pool.observeReadOnly(async (connection) => await runWithDatabaseConnection(connection, async () => {
2243
+ remaining();
2244
+ const result = await collect(remaining);
2245
+ remaining();
2246
+ return result;
2247
+ }), { signal: acquisition.signal, timeoutMs: remaining() });
2248
+ })();
2233
2249
  active = work;
2234
2250
  work.finally(() => {
2235
2251
  if (active === work)
@@ -2267,15 +2283,33 @@ var schemaQuery = `SELECT c.relkind = 'r' AND c.relpersistence = 'p' AND NOT c.r
2267
2283
  AND i.indnkeyatts = 1 AND a.attname = 'id' AND NOT a.attisdropped
2268
2284
  AND a.atttypid IN ('int2'::regtype, 'int4'::regtype, 'int8'::regtype)
2269
2285
  ) AS supported FROM pg_class c WHERE c.oid = 'failed_job'::regclass`;
2286
+ var sqliteSchemaQuery = `SELECT 1 AS supported FROM main.sqlite_schema
2287
+ WHERE name='failed_job' AND type='table' AND rootpage > 0
2288
+ AND (SELECT COUNT(*) FROM pragma_table_xinfo('failed_job', 'main') WHERE pk > 0) = 1
2289
+ AND EXISTS (SELECT 1 FROM pragma_table_xinfo('failed_job', 'main')
2290
+ WHERE name='id' AND pk=1 AND upper(type)='INTEGER' AND hidden=0) LIMIT 1`;
2291
+ var mysqlSchemaQuery = `SELECT 1 AS supported FROM information_schema.TABLES t
2292
+ WHERE t.TABLE_SCHEMA=DATABASE() AND t.TABLE_NAME='failed_job' AND t.TABLE_TYPE='BASE TABLE' AND t.ENGINE='InnoDB'
2293
+ AND (SELECT COUNT(*) FROM information_schema.STATISTICS i WHERE i.TABLE_SCHEMA=t.TABLE_SCHEMA
2294
+ AND i.TABLE_NAME=t.TABLE_NAME AND i.INDEX_NAME='PRIMARY')=1
2295
+ AND EXISTS(SELECT 1 FROM information_schema.STATISTICS i JOIN information_schema.COLUMNS c
2296
+ ON c.TABLE_SCHEMA=i.TABLE_SCHEMA AND c.TABLE_NAME=i.TABLE_NAME AND c.COLUMN_NAME=i.COLUMN_NAME
2297
+ WHERE i.TABLE_SCHEMA=t.TABLE_SCHEMA AND i.TABLE_NAME=t.TABLE_NAME AND i.INDEX_NAME='PRIMARY'
2298
+ AND i.SEQ_IN_INDEX=1 AND i.COLUMN_NAME='id' AND c.DATA_TYPE IN ('tinyint','smallint','mediumint','int','bigint')) LIMIT 1`;
2270
2299
  function createFailedJobMetricsCollector(options = {}) {
2271
2300
  const sampleLimit = options.sampleLimit ?? 500;
2272
2301
  if (!Number.isSafeInteger(sampleLimit) || sampleLimit < 1 || sampleLimit > 1000)
2273
2302
  throw new TypeError("Failed-job metrics sample limit must be between 1 and 1000.");
2274
2303
  const repository = new failedJobRepository_default;
2275
- return createPostgresReadOnlyCollector("Failed-job metrics", options.timeoutMs ?? 1000, async (remaining) => {
2276
- await repositoryConnection.unsafe('LOCK TABLE "failed_job" IN ACCESS SHARE MODE');
2277
- const schema = await repositoryConnection.unsafe(schemaQuery);
2278
- if (schema.length !== 1 || schema[0]?.supported !== true)
2304
+ return createReadOnlyCollector("Failed-job metrics", options.timeoutMs ?? 1000, async (remaining) => {
2305
+ const driver = currentSqlDialect().driver;
2306
+ const postgres = driver === "pgsql";
2307
+ if (postgres)
2308
+ await repositoryConnection.unsafe('LOCK TABLE "failed_job" IN ACCESS SHARE MODE');
2309
+ if (driver === "mysql")
2310
+ await repositoryConnection.unsafe("SELECT id FROM failed_job LIMIT 0");
2311
+ const schema = await repositoryConnection.unsafe(postgres ? schemaQuery : driver === "mysql" ? mysqlSchemaQuery : sqliteSchemaQuery);
2312
+ if (schema.length !== 1 || schema[0]?.supported !== (postgres ? true : 1))
2279
2313
  throw new Error("Failed-job metrics require the standard global table with an ID primary key and no RLS.");
2280
2314
  remaining();
2281
2315
  const rows = await repository.query().orderBy({ column: "id", direction: "ASC" }).project(["id"], sampleLimit + 1);
@@ -32,6 +32,8 @@ export { CACHE_TAGS } from "../core/cache/tags.ts";
32
32
  export { ConfigStore, createServiceToken, ServiceContainer, type ServiceToken, } from "../core/contracts/container.ts";
33
33
  export type { ServiceProvider } from "../core/contracts/di.ts";
34
34
  export { resolveService } from "../core/contracts/di.ts";
35
+ export type { FieldEncryptionRotationBatch, FieldEncryptionRotationOptions, } from "../core/crypto/fieldEncryptionRotation";
36
+ export { createFieldEncryptionRotationMigration, runFieldEncryptionRotationBatch, } from "../core/crypto/fieldEncryptionRotation";
35
37
  export type { TransactionAcquisitionMetrics, TransactionAcquisitionSnapshot, } from "../core/database/acquisitionMetrics.ts";
36
38
  export { createTransactionAcquisitionMetrics, renderTransactionAcquisitionMetrics, } from "../core/database/acquisitionMetrics.ts";
37
39
  export type { DatabaseConnection } from "../core/database/baseRepository.ts";