@spytecgps/nova-orm 1.4.241 → 1.4.242

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.
@@ -6,7 +6,15 @@ export interface LruQueryResultCacheConfig {
6
6
  }
7
7
  export declare class LruQueryResultCache implements QueryResultCache {
8
8
  private readonly cache;
9
+ private readonly maxSize;
9
10
  constructor(config?: LruQueryResultCacheConfig);
11
+ /**
12
+ * Emit `nova.cache.lru.size` and `nova.cache.lru.max` as observable gauges so
13
+ * dashboards can tell "is the LRU full?" directly instead of inferring from
14
+ * hit-rate decay. Filter by `ServiceName` to disambiguate when multiple
15
+ * DataSources share a process.
16
+ */
17
+ private registerSizeGauges;
10
18
  connect(): Promise<void>;
11
19
  disconnect(): Promise<void>;
12
20
  synchronize(): Promise<void>;
@@ -1 +1 @@
1
- "use strict";var e=require("lru-cache");exports.LruQueryResultCache=class LruQueryResultCache{cache;constructor(c={}){this.cache=new e.LRUCache({max:c.max??1e3,ttl:c.maxTtlMs})}async connect(){}async disconnect(){this.cache.clear()}async synchronize(){}async getFromCache(e){const c=this.keyFor(e);if(c)return this.cache.get(c)}async storeInCache(e){const c=this.keyFor(e);if(!c)return;const t={...e,time:e.time??Date.now()};this.cache.set(c,t)}isExpired(e){const c=e.time??0;return Date.now()-c>=e.duration}async remove(e){for(const c of e)this.cache.delete(c)}async clear(){this.cache.clear()}keyFor(e){return e.identifier??e.query}};
1
+ "use strict";var e=require("@opentelemetry/api"),c=require("lru-cache");exports.LruQueryResultCache=class LruQueryResultCache{cache;maxSize;constructor(e={}){this.maxSize=e.max??1e3,this.cache=new c.LRUCache({max:this.maxSize,ttl:e.maxTtlMs}),this.registerSizeGauges()}registerSizeGauges(){const c=e.metrics.getMeter("@spytecgps/nova-orm");c.createObservableGauge("nova.cache.lru.size",{description:"Current entry count in the in-process LRU query result cache"}).addCallback((e=>{e.observe(this.cache.size)})),c.createObservableGauge("nova.cache.lru.max",{description:"Configured max entry count for the in-process LRU query result cache"}).addCallback((e=>{e.observe(this.maxSize)}))}async connect(){}async disconnect(){this.cache.clear()}async synchronize(){}async getFromCache(e){const c=this.keyFor(e);if(c)return this.cache.get(c)}async storeInCache(e){const c=this.keyFor(e);if(!c)return;const t={...e,time:e.time??Date.now()};this.cache.set(c,t)}isExpired(e){const c=e.time??0;return Date.now()-c>=e.duration}async remove(e){for(const c of e)this.cache.delete(c)}async clear(){this.cache.clear()}keyFor(e){return e.identifier??e.query}};
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Build the TypeORM `cache:` config object from REDIS_* env vars so consumers
3
+ * don't have to embed mode-switching logic in every service. SSM-driven
4
+ * `/${stage}/cache/<name>/redis/{host,port,tls,mode}` keys map 1:1 to the env
5
+ * vars and this helper returns the right TypeORM shape.
6
+ *
7
+ * Returns undefined if REDIS_HOST is absent, so it's safe to spread into a
8
+ * DataSource config that may or may not have a cache configured.
9
+ *
10
+ * Supported modes:
11
+ * - "standalone" (default): uses TypeORM's built-in RedisQueryResultCache
12
+ * with the `ioredis` client type. One node, no cluster topology.
13
+ * - "cluster": custom client passed through TypeORM's `client` field; uses
14
+ * `ioredis` Cluster mode with the ElastiCache-cluster-mode safety
15
+ * defaults baked in (enableOfflineQueue:false, checkServerIdentity bypass
16
+ * for TLS — see project_elasticache_cluster_ioredis_tls).
17
+ */
18
+ export type CacheMode = 'standalone' | 'cluster';
19
+ export interface CacheFromEnvOptions {
20
+ /** Env var name for host. Default: REDIS_HOST. Override to support multiple caches in one process. */
21
+ hostEnv?: string;
22
+ portEnv?: string;
23
+ tlsEnv?: string;
24
+ modeEnv?: string;
25
+ }
26
+ export interface BuiltCacheConfig {
27
+ type?: 'ioredis';
28
+ options?: Record<string, unknown>;
29
+ client?: unknown;
30
+ ignoreErrors?: boolean;
31
+ }
32
+ export declare function buildCacheFromEnv(options?: CacheFromEnvOptions): BuiltCacheConfig | undefined;
@@ -0,0 +1 @@
1
+ "use strict";let e;exports.buildCacheFromEnv=function(r={}){const t=r.hostEnv??"REDIS_HOST",n=r.portEnv??"REDIS_PORT",o=r.tlsEnv??"REDIS_TLS",s=r.modeEnv??"REDIS_MODE",i=process.env[t];if(!i)return;const u=Number(process.env[n]??"6379"),c="true"===process.env[o];if("cluster"===(process.env[s]??"standalone")){const r=function(){if(void 0!==e)return e;try{e=require("ioredis")}catch{e=null}return e}();if(!r)throw new Error("buildCacheFromEnv: REDIS_MODE=cluster requires `ioredis` to be installed");return{client:new r.Cluster([{host:i,port:u}],{redisOptions:c?{tls:{checkServerIdentity:()=>{}}}:{},enableOfflineQueue:!1}),ignoreErrors:!0}}return{type:"ioredis",options:{host:i,port:u,tls:c?{}:void 0},ignoreErrors:!0}};
@@ -1,3 +1,4 @@
1
1
  export { attachIoredisErrorHandler, RedisQueryResultCacheLike } from './attachIoredisErrorHandler';
2
+ export { buildCacheFromEnv, BuiltCacheConfig, CacheFromEnvOptions, CacheMode, } from './buildCacheFromEnv';
2
3
  export { CacheKind, InstrumentedQueryResultCache, InstrumentedQueryResultCacheOptions, } from './InstrumentedQueryResultCache';
3
4
  export { LruQueryResultCache, LruQueryResultCacheConfig } from './LruQueryResultCache';
@@ -1 +1 @@
1
- "use strict";var e=require("./attachIoredisErrorHandler.js"),r=require("./InstrumentedQueryResultCache.js"),t=require("./LruQueryResultCache.js");exports.attachIoredisErrorHandler=e.attachIoredisErrorHandler,exports.InstrumentedQueryResultCache=r.InstrumentedQueryResultCache,exports.LruQueryResultCache=t.LruQueryResultCache;
1
+ "use strict";var e=require("./attachIoredisErrorHandler.js"),r=require("./buildCacheFromEnv.js"),u=require("./InstrumentedQueryResultCache.js"),t=require("./LruQueryResultCache.js");exports.attachIoredisErrorHandler=e.attachIoredisErrorHandler,exports.buildCacheFromEnv=r.buildCacheFromEnv,exports.InstrumentedQueryResultCache=u.InstrumentedQueryResultCache,exports.LruQueryResultCache=t.LruQueryResultCache;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spytecgps/nova-orm",
3
- "version": "1.4.241",
3
+ "version": "1.4.242",
4
4
  "description": "ORM with PlanetScale",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/schema.sql CHANGED
@@ -1,6 +1,6 @@
1
- -- nova-orm-schema-checksum: 6c149c8020575fbb21298a8ec3655fcd
1
+ -- nova-orm-schema-checksum: bdf84e9724e3cf6c308f89f1c1871778
2
2
  -- Nova ORM Schema Dump
3
- -- Generated at: 2026-05-24T13:19:09.208Z
3
+ -- Generated at: 2026-05-24T15:55:45.644Z
4
4
 
5
5
  SET FOREIGN_KEY_CHECKS = 0;
6
6