@zintrust/core 2.4.6 → 2.4.7

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": "@zintrust/core",
3
- "version": "2.4.6",
3
+ "version": "2.4.7",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -6,6 +6,7 @@
6
6
  import type { CacheDriver } from './CacheDriver';
7
7
  type CacheStore = Readonly<{
8
8
  get: <T>(key: string) => Promise<T | null>;
9
+ many: <T>(keys: string[]) => Promise<(T | null)[]>;
9
10
  set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
10
11
  delete: (key: string) => Promise<void>;
11
12
  clear: () => Promise<void>;
@@ -16,6 +17,7 @@ type CacheStore = Readonly<{
16
17
  }>;
17
18
  export declare const Cache: Readonly<{
18
19
  get: <T>(key: string) => Promise<T | null>;
20
+ many: <T>(keys: string[]) => Promise<(T | null)[]>;
19
21
  set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
20
22
  delete: (key: string) => Promise<void>;
21
23
  clear: () => Promise<void>;
@@ -32,6 +34,7 @@ export declare const Cache: Readonly<{
32
34
  */
33
35
  export declare const cache: Readonly<{
34
36
  get: <T>(key: string) => Promise<T | null>;
37
+ many: <T>(keys: string[]) => Promise<(T | null)[]>;
35
38
  set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
36
39
  delete: (key: string) => Promise<void>;
37
40
  clear: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAiOtD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,SAAS,EAAE,MAAM,WAAW,CAAC;CAC9B,CAAC,CAAC;AAsIH,eAAO,MAAM,KAAK;UApQC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAkBlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAkBjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAiBtB,OAAO,CAAC,IAAI,CAAC;eAgBb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAenB,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAapC,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAgB5C,WAAW;iCAwIG,MAAM,KAAG,OAAO;mBAvH9B,MAAM,KAAG,UAAU;iBAmHvB,IAAI;EA2BpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UArRC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAkBlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAkBjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAiBtB,OAAO,CAAC,IAAI,CAAC;eAgBb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAenB,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAapC,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAgB5C,WAAW;iCAwIG,MAAM,KAAG,OAAO;mBAvH9B,MAAM,KAAG,UAAU;iBAmHvB,IAAI;EAgCI,CAAC"}
1
+ {"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2QtD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IACnD,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,SAAS,EAAE,MAAM,WAAW,CAAC;CAC9B,CAAC,CAAC;AA0IH,eAAO,MAAM,KAAK;UAnTC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;WAsDjC,CAAC,QAAQ,MAAM,EAAE,KAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;UAM1C,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAkBjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAiBtB,OAAO,CAAC,IAAI,CAAC;eAgBb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAenB,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAapC,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAgB5C,WAAW;iCA6IG,MAAM,KAAG,OAAO;mBA3H9B,MAAM,KAAG,UAAU;iBAuHvB,IAAI;EA4BpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UArUC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;WAsDjC,CAAC,QAAQ,MAAM,EAAE,KAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;UAM1C,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAkBjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAiBtB,OAAO,CAAC,IAAI,CAAC;eAgBb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAenB,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAapC,MAAM,sBAAe,OAAO,CAAC,MAAM,CAAC;qBAgB5C,WAAW;iCA6IG,MAAM,KAAG,OAAO;mBA3H9B,MAAM,KAAG,UAAU;iBAuHvB,IAAI;EAiCI,CAAC"}
@@ -95,6 +95,33 @@ const get = async (key) => {
95
95
  SystemTraceBridge.emitCache('get', prefixedKey, Date.now() - startedAt, value !== null, value, DEFAULT_STORE_NAME);
96
96
  return value;
97
97
  };
98
+ // Batched read: one round-trip via driver.many() (e.g. Redis MGET) when supported,
99
+ // otherwise individual gets. Results stay aligned to the requested key order.
100
+ const runMany = async (driver, keys, storeName) => {
101
+ if (keys.length === 0)
102
+ return [];
103
+ const prefixedKeys = keys.map((key) => autoPrefixKey(key));
104
+ const startedAt = Date.now();
105
+ const many = driver.many;
106
+ let values;
107
+ const batched = typeof many === 'function';
108
+ if (batched) {
109
+ values = await many(prefixedKeys);
110
+ }
111
+ else {
112
+ values = await Promise.all(prefixedKeys.map(async (prefixedKey) => driver.get(prefixedKey)));
113
+ }
114
+ const elapsed = Date.now() - startedAt;
115
+ const normalized = prefixedKeys.map((_prefixedKey, index) => values[index] ?? null);
116
+ const hitCount = normalized.filter((value) => value !== null).length;
117
+ // One trace record per round-trip: a driver-level `many` (e.g. Redis MGET) is a single
118
+ // network call, so it must not look like N separate gets. Drivers without `many` fall back
119
+ // to N gets, which is reflected with the `gets` label.
120
+ const label = batched ? 'mget' : 'gets';
121
+ SystemTraceBridge.emitCache('get', `${label}(${prefixedKeys.length}/${hitCount} hit) ${prefixedKeys.join(',')}`, elapsed, hitCount > 0, undefined, storeName);
122
+ return normalized;
123
+ };
124
+ const many = async (keys) => runMany(getDriverInstance(), keys, DEFAULT_STORE_NAME);
98
125
  /**
99
126
  * Store an item in the cache
100
127
  */
@@ -169,6 +196,7 @@ const store = (name) => {
169
196
  SystemTraceBridge.emitCache('get', prefixedKey, Date.now() - startedAt, value !== null, value, String(name ?? DEFAULT_STORE_NAME));
170
197
  return value;
171
198
  };
199
+ const manyFromStore = async (keys) => runMany(getDriverInstance(name), keys, String(name ?? DEFAULT_STORE_NAME));
172
200
  const setInStore = async (key, value, ttl) => {
173
201
  const prefixedKey = autoPrefixKey(key);
174
202
  const startedAt = Date.now();
@@ -220,6 +248,7 @@ const store = (name) => {
220
248
  };
221
249
  return Object.freeze({
222
250
  get: getFromStore,
251
+ many: manyFromStore,
223
252
  set: setInStore,
224
253
  delete: delFromStore,
225
254
  clear: clearStore,
@@ -242,6 +271,7 @@ const getRedisClient = (storeName) => {
242
271
  // Sealed namespace with cache functionality
243
272
  export const Cache = Object.freeze({
244
273
  get,
274
+ many,
245
275
  set,
246
276
  delete: del,
247
277
  clear,
@@ -7,6 +7,13 @@ export interface CacheDriver {
7
7
  * Get an item from the cache
8
8
  */
9
9
  get<T>(key: string): Promise<T | null>;
10
+ /**
11
+ * Get many items from the cache in a single round-trip when the driver
12
+ * supports it (e.g. Redis MGET). Results are returned in the same order as
13
+ * the requested keys, with `null` for misses. Optional: callers fall back to
14
+ * issuing individual `get` calls when a driver does not implement it.
15
+ */
16
+ many?<T>(keys: string[]): Promise<(T | null)[]>;
10
17
  /**
11
18
  * Store an item in the cache
12
19
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CacheDriver.d.ts","sourceRoot":"","sources":["../../../src/cache/CacheDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEvC;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEnC;;OAEG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1D;;OAEG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,IAAI,OAAO,CAAC;CAC5B;AAGD,eAAO,MAAM,sBAAsB,gBAAgB,CAAC"}
1
+ {"version":3,"file":"CacheDriver.d.ts","sourceRoot":"","sources":["../../../src/cache/CacheDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEvC;;;;;OAKG;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEnC;;OAEG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1D;;OAEG;IACH,SAAS,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;OAGG;IACH,cAAc,CAAC,IAAI,OAAO,CAAC;CAC5B;AAGD,eAAO,MAAM,sBAAsB,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../../../src/cache/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA+btD;;GAEG;AACH,eAAO,MAAM,WAAW;kBAbL,WAAW;EAe5B,CAAC"}
1
+ {"version":3,"file":"RedisDriver.d.ts","sourceRoot":"","sources":["../../../../src/cache/drivers/RedisDriver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAsdtD;;GAEG;AACH,eAAO,MAAM,WAAW;kBAbL,WAAW;EAe5B,CAAC"}
@@ -69,6 +69,30 @@ const createCacheDriverFromIoredisClient = (client) => ({
69
69
  return null;
70
70
  }
71
71
  },
72
+ async many(keys) {
73
+ if (keys.length === 0)
74
+ return [];
75
+ try {
76
+ const prefixedKeys = keys.map((key) => RedisKeys.createCacheKey(key));
77
+ const values = typeof client.mget === 'function'
78
+ ? await client.mget(...prefixedKeys)
79
+ : await Promise.all(prefixedKeys.map(async (prefixedKey) => client.get(prefixedKey)));
80
+ return values.map((value) => {
81
+ if (value === null || value === undefined)
82
+ return null;
83
+ try {
84
+ return JSON.parse(value);
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ });
90
+ }
91
+ catch (error) {
92
+ Logger.error('Redis MGET failed', error);
93
+ return keys.map(() => null);
94
+ }
95
+ },
72
96
  async set(key, value, ttl) {
73
97
  try {
74
98
  const prefixedKey = RedisKeys.createCacheKey(key);
package/src/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * @zintrust/core v2.4.6
2
+ * @zintrust/core v2.4.7
3
3
  *
4
4
  * ZinTrust Framework - Production-Grade TypeScript Backend
5
5
  * Built for performance, type safety, and exceptional developer experience
6
6
  *
7
7
  * Build Information:
8
- * Built: 2026-06-01T16:53:34.785Z
8
+ * Built: 2026-06-01T22:49:09.622Z
9
9
  * Node: >=20.0.0
10
10
  * License: MIT
11
11
  *
@@ -21,7 +21,7 @@
21
21
  * Available at runtime for debugging and health checks
22
22
  */
23
23
  export const ZINTRUST_VERSION = '0.1.41';
24
- export const ZINTRUST_BUILD_DATE = '2026-06-01T16:53:34.743Z'; // Replaced during build
24
+ export const ZINTRUST_BUILD_DATE = '2026-06-01T22:49:09.586Z'; // Replaced during build
25
25
  export { Application } from './boot/Application.js';
26
26
  export { AwsSigV4 } from './common/index.js';
27
27
  export { SignedRequest } from './security/SignedRequest.js';