lamix 4.2.17 → 4.2.19

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/README.md CHANGED
@@ -117,15 +117,9 @@ const User = require('./models/User');
117
117
  const user = await User.create({ name: 'Alice', email: 'alice@example.com', password: 'secret' });
118
118
 
119
119
  # Fill & save (update)
120
- name = 'Alice Smith';
121
- user.fill({ name })
120
+ user.name = 'Alice Smith'; // you can also use user.fill({ name: 'Alice Smith' })
122
121
  await user.save();
123
122
 
124
- # Method 2 (update)
125
- const user = await User.findOrFail(param.id);
126
- const payload = req.body;
127
- await user.update({ payload });
128
-
129
123
  # Find by primary key
130
124
  const user1 = await User.find(1);
131
125
  const user2 = await User.findOrFail(param.id);
@@ -170,7 +164,7 @@ const qb = User.query();
170
164
  const names = await User.query().select('id', 'name').get();
171
165
 
172
166
  # Aggregates
173
- const cnt = await User.query().count(); # count(*)
167
+ const cnt = await User.query().count(); // count(*)
174
168
  const sumId = await User.query().sum('id');
175
169
  const avgId = await User.query().avg('id');
176
170
  const minId = await User.query().min('id');
@@ -187,12 +181,12 @@ const Pluckemails = await User.query().pluck('email');
187
181
 
188
182
  # Pagination
189
183
  const page1 = await User.query().paginate(1, 10);
190
- #page1 = { total, perPage, page, lastPage, data: [users...] }
184
+ // page1 = { total, perPage, page, lastPage, data: [users...] }
191
185
 
192
186
  # Where In
193
187
  const usersIn = await User.query().whereIn('id', [1, 2, 3]).get();
194
188
 
195
- # Where Null / Not Null
189
+ // Where Null / Not Null
196
190
  const withNull = await User.query().whereNull('deleted_at').get();
197
191
  const notNull = await User.query().whereNotNull('deleted_at').get();
198
192
 
@@ -225,7 +219,7 @@ const cached = await DB.cached('SELECT * FROM users WHERE id = ?', [5], 60000);
225
219
  #You can use relations:
226
220
 
227
221
  const user = await User.find(1);
228
- const posts = await user.posts().get(); # all posts for the user
222
+ const posts = await user.posts().get(); // all posts for the user
229
223
 
230
224
  # Eager load in a query with Relations:
231
225
  const usersWithPosts = await User.query().with('posts').get();
package/lib/index.d.ts CHANGED
@@ -294,15 +294,8 @@ export class QueryBuilder {
294
294
  _pushWhere(w: any): this;
295
295
  then(resolve: any, reject: any): Promise<Collection>;
296
296
  where(columnOrObject: any, operator: any, value: any, ...args: any[]): this;
297
+ andWhere(...args: any[]): this;
297
298
  orWhere(columnOrObject: any, operatorOrValue: any, value: any, ...args: any[]): this;
298
- toSQL(): string;
299
- /**************************************************************************
300
- * TO SQL
301
- **************************************************************************/
302
- toSQL(): {
303
- sql: string;
304
- bindings: any[];
305
- };
306
299
  whereRaw(sql: any, bindings?: any[]): this;
307
300
  orWhereRaw(sql: any, bindings?: any[]): this;
308
301
  whereColumn(a: any, op: any, b: any, ...args: any[]): this;
@@ -433,6 +426,13 @@ export class QueryBuilder {
433
426
  }[];
434
427
  fromRaw: any;
435
428
  };
429
+ /**************************************************************************
430
+ * TO SQL
431
+ **************************************************************************/
432
+ toSQL(): {
433
+ sql: string;
434
+ bindings: any[];
435
+ };
436
436
  toSQLJSON(): {
437
437
  sql: string;
438
438
  bindings: any[];
@@ -494,7 +494,7 @@ export class LamixSessionStore {
494
494
  cleanupInterval: any;
495
495
  logger: any;
496
496
  compress: any;
497
- cache: LRUCache<{}, {}, unknown>;
497
+ cache: any;
498
498
  redisEnabled: boolean;
499
499
  redisRetryAt: number;
500
500
  redisCooldown: any;
@@ -548,11 +548,24 @@ export class BaseModel extends Model {
548
548
  }
549
549
  declare class SimpleCache {
550
550
  constructor(options?: {});
551
- cache: LRUCache<{}, {}, unknown>;
552
- get(k: any): {};
553
- set(k: any, v: any, ttl?: number): void;
554
- del(k: any): void;
551
+ cache: any;
552
+ get(key: any): any;
553
+ set(key: any, value: any, ttl?: any): void;
554
+ has(key: any): any;
555
+ delete(key: any): any;
555
556
  clear(): void;
557
+ /**
558
+ * Get value or compute + store it
559
+ * Supports async functions
560
+ */
561
+ getOrSet(key: any, fetchFn: any, ttl?: any): Promise<any>;
562
+ /**
563
+ * Basic cache stats
564
+ */
565
+ stats(): {
566
+ size: any;
567
+ calculatedSize: any;
568
+ };
556
569
  }
557
570
  import { AsyncLocalStorage } from "node:async_hooks";
558
571
  declare class HasManyThrough extends Relation {
@@ -612,5 +625,4 @@ declare class Relation {
612
625
  deleteBehavior: any;
613
626
  onDelete(behavior: any): this;
614
627
  }
615
- import { LRUCache } from "lru-cache";
616
628
  export {};
package/lib/index.js CHANGED
@@ -3,11 +3,11 @@
3
3
  const util = require('util');
4
4
  const { performance } = require('perf_hooks');
5
5
  const { AsyncLocalStorage } = require('async_hooks');
6
+ require('dotenv').config();
6
7
  const session = require('express-session');
7
8
  const Redis = require('ioredis');
8
- const LRUCache = require('lru-cache');
9
+ const { LRUCache } = require('lru-cache');
9
10
  const zlib = require('zlib');
10
- require('dotenv').config();
11
11
 
12
12
  /* ---------------- Utilities ---------------- */
13
13
 
@@ -29,37 +29,76 @@ class DBError extends Error {
29
29
  }
30
30
 
31
31
  /* ---------------- Cache ---------------- */
32
-
33
32
  class SimpleCache {
34
33
  constructor(options = {}) {
34
+ const {
35
+ max = 1000, // max number of items
36
+ ttl = 0, // default TTL (ms)
37
+ maxSize, // optional size-based eviction
38
+ sizeCalculation, // function(value, key)
39
+ } = options;
40
+
35
41
  this.cache = new LRUCache({
36
- max: options.max || 1000, // max number of items
37
- ttlAutopurge: true, // auto-remove expired entries
42
+ max,
43
+ ttl,
44
+ ttlAutopurge: true,
45
+ maxSize,
46
+ sizeCalculation,
47
+ allowStale: false,
48
+ updateAgeOnGet: false,
38
49
  });
39
50
  }
40
51
 
41
- get(k) {
42
- const v = this.cache.get(k);
43
- return v === undefined ? null : v;
52
+ get(key) {
53
+ const value = this.cache.get(key);
54
+ return value === undefined ? null : value;
44
55
  }
45
56
 
46
- set(k, v, ttl = 0) {
47
- if (ttl > 0) {
48
- this.cache.set(k, v, { ttl });
57
+ set(key, value, ttl = null) {
58
+ if (ttl !== null) {
59
+ this.cache.set(key, value, { ttl });
49
60
  } else {
50
- this.cache.set(k, v);
61
+ this.cache.set(key, value);
51
62
  }
52
63
  }
53
64
 
54
- del(k) {
55
- this.cache.delete(k);
65
+ has(key) {
66
+ return this.cache.has(key);
67
+ }
68
+
69
+ delete(key) {
70
+ return this.cache.delete(key);
56
71
  }
57
72
 
58
73
  clear() {
59
74
  this.cache.clear();
60
75
  }
76
+
77
+ /**
78
+ * Get value or compute + store it
79
+ * Supports async functions
80
+ */
81
+ async getOrSet(key, fetchFn, ttl = null) {
82
+ const existing = this.get(key);
83
+ if (existing !== null) return existing;
84
+
85
+ const value = await fetchFn();
86
+ this.set(key, value, ttl);
87
+ return value;
88
+ }
89
+
90
+ /**
91
+ * Basic cache stats
92
+ */
93
+ stats() {
94
+ return {
95
+ size: this.cache.size,
96
+ calculatedSize: this.cache.calculatedSize,
97
+ };
98
+ }
61
99
  }
62
100
 
101
+
63
102
  /* ---------------- Grammar ---------------- */
64
103
 
65
104
  class Grammar {
@@ -85,7 +124,7 @@ class DB {
85
124
  static config = null;
86
125
  static pool = null;
87
126
 
88
- static cache = new SimpleCache();
127
+ static cache = new SimpleCache({ max: 1000, ttl: 60_000 });
89
128
  static retryAttempts = 1;
90
129
 
91
130
  static eventHandlers = { query: [], error: [], reconnect: [] };
@@ -1308,6 +1347,10 @@ class QueryBuilder {
1308
1347
  });
1309
1348
  }
1310
1349
 
1350
+ andWhere(...args) {
1351
+ return this.where(...args);
1352
+ }
1353
+
1311
1354
  orWhere(columnOrObject, operatorOrValue, value) {
1312
1355
  if (typeof columnOrObject === 'object' && columnOrObject !== null) {
1313
1356
  let query = this;
@@ -1336,15 +1379,14 @@ class QueryBuilder {
1336
1379
  }
1337
1380
 
1338
1381
  // Example method to generate SQL
1339
- toSQL() {
1340
- if (!this.wheres.length) return '';
1341
- const sql = this.wheres.map((w, i) => {
1342
- const prefix = i === 0 ? '' : ` ${w.boolean} `;
1343
- return `${prefix}\`${w.column}\` ${w.operator} ?`;
1344
- }).join('');
1345
- return 'WHERE ' + sql;
1346
- }
1347
-
1382
+ // toSQL() {
1383
+ // if (!this.wheres.length) return '';
1384
+ // const sql = this.wheres.map((w, i) => {
1385
+ // const prefix = i === 0 ? '' : ` ${w.boolean} `;
1386
+ // return `${prefix}\`${w.column}\` ${w.operator} ?`;
1387
+ // }).join('');
1388
+ // return 'WHERE ' + sql;
1389
+ // }
1348
1390
 
1349
1391
  whereRaw(sql, bindings = []) {
1350
1392
  return this._pushWhere({
@@ -3451,7 +3493,9 @@ class Model {
3451
3493
  // INSERT – validation first
3452
3494
  // ──────────────────────────────
3453
3495
  async saveNew(attrs) {
3454
- if (!this._exists && !Object.keys(this._attributes).length) {
3496
+ this._attributes = { ...attrs };
3497
+
3498
+ if (!Object.keys(this._attributes).length) {
3455
3499
  throw new DBError('Cannot save empty model', {
3456
3500
  model: this.constructor.name
3457
3501
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lamix",
3
- "version": "4.2.17",
3
+ "version": "4.2.19",
4
4
  "description": "lamix - ORM for Node-express js",
5
5
  "main": "./lib",
6
6
  "type": "commonjs",
@@ -34,7 +34,7 @@
34
34
  "lru-cache": "^11.2.5",
35
35
  "ioredis": "^5.9.2",
36
36
  "chalk": "^4.1.2",
37
- "dotenv": "^17.2.4"
37
+ "dotenv": "^17.2.4 "
38
38
  },
39
39
  "keywords": [
40
40
  "lamix",