tina4-nodejs 3.13.23 → 3.13.25

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/CLAUDE.md CHANGED
@@ -1,10 +1,10 @@
1
- # CLAUDE.md — AI Developer Guide for tina4-nodejs (v3.13.23)
1
+ # CLAUDE.md — AI Developer Guide for tina4-nodejs (v3.13.25)
2
2
 
3
3
  > This file helps AI assistants (Claude, Copilot, Cursor, etc.) understand and work on this codebase effectively.
4
4
 
5
5
  ## What This Project Is
6
6
 
7
- Tina4 for Node.js/TypeScript v3.13.23 — The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
7
+ Tina4 for Node.js/TypeScript v3.13.25 — The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
8
8
 
9
9
  The philosophy: zero ceremony, batteries included, file system as source of truth.
10
10
 
@@ -591,10 +591,15 @@ db.getNextId(table, pkColumn?, generatorName?): number
591
591
 
592
592
  // DB query cache — request-scoped auto cache is ON by default (TINA4_AUTO_CACHING=true,
593
593
  // TTL TINA4_AUTO_CACHING_TTL=5s): dedupes identical db.fetch()/ORM reads within a request,
594
- // flushed on any write. Persistent cross-request cache opt-in via TINA4_DB_CACHE=true
595
- // (TTL TINA4_DB_CACHE_TTL=30s). cacheStats()/cacheClear() are now real (the DB query cache
596
- // is wired previously db.cacheStats() hardcoded size:0 and db.cacheClear() was a no-op).
597
- db.cacheStats(): { enabled, size, ttl, mode } // mode: "request" | "persistent" | "off"
594
+ // flushed on any write (always in-process, fastest). Persistent cross-request cache opt-in
595
+ // via TINA4_DB_CACHE=true (TTL TINA4_DB_CACHE_TTL=30s), configured via TINA4_DB_CACHE_BACKEND
596
+ // + TINA4_DB_CACHE_URL. The persistent layer routes through the SAME unified async backend
597
+ // set (memory default = in-process; redis/valkey/memcached/mongodb/database distribute), so
598
+ // multiple instances share one cache with global write-invalidation — full parity with
599
+ // Python/PHP/Ruby. (Node's read path — db.fetch → fetchAsync — is async, so the backend's
600
+ // async get/set work directly; the KV/middleware API is async, await it.) cacheStats() reports
601
+ // mode + backend; cacheClear() is real.
602
+ db.cacheStats(): { enabled, size, ttl, mode, backend } // mode: "request" | "persistent" | "off"
598
603
  db.cacheClear(): void
599
604
 
600
605
  // Connection pool access (null when pooling disabled)
@@ -883,7 +888,7 @@ container.reset(); // clear all registrations + cached instances
883
888
 
884
889
  ## Module: Response Cache (`packages/core/src/cache.ts`)
885
890
 
886
- Multi-backend cache. Used as middleware to cache GET responses, or directly via `cacheGet`/`cacheSet` for arbitrary key/value caching. Backends: memory (default), redis/valkey, file.
891
+ Unified multi-backend cache. Used as middleware to cache GET responses, or directly via the **async** KV API (`cacheGet`/`cacheSet`/…) for arbitrary key/value caching. Seven backends, selected by `TINA4_CACHE_BACKEND`: `memory` (default), `file`, `redis`, `valkey`, `memcached`, `mongodb`, `database`.
887
892
 
888
893
  ```typescript
889
894
  import {
@@ -893,21 +898,27 @@ import {
893
898
  // Middleware on a route
894
899
  get("/api/products", listProducts).middleware(responseCache({ ttl: 60 }));
895
900
 
896
- // Direct key/value usage (same shape across all four frameworks)
897
- cacheSet("user:1", { name: "Alice" }, 120);
898
- const u = cacheGet("user:1");
899
- cacheDelete("user:1");
900
- cacheClear();
901
+ // Direct key/value usage Node's KV API is ASYNC (await), matching Node's
902
+ // async-everywhere idiom. All 7 backends use native async clients (no child processes).
903
+ await cacheSet("user:1", { name: "Alice" }, 120);
904
+ const u = await cacheGet("user:1");
905
+ await cacheDelete("user:1");
906
+ await cacheClear();
901
907
 
902
- cacheStats(); // { hits, misses, size, backend } — now reflects the real KV backend
903
- // (previously it wrongly read the response-cache middleware store)
908
+ await cacheStats(); // { hits, misses, size, backend } — reflects the real KV backend
904
909
  ```
905
910
 
911
+ **Async everywhere (full parity):** the KV API, the `responseCache` middleware, and the persistent DB query cache all route through the same unified async backend set with native async clients (no child processes). The `responseCache` middleware and persistent DB cache distribute cross-instance when a network backend (redis/valkey/memcached/mongodb/database) is selected — exactly like Python/PHP/Ruby. The default `memory` backend keeps both in-process (fastest), so default behaviour is unchanged. Because the KV/middleware API is async, **`await` it** (`await cacheGet`/`await cacheSet`/`await clearCache`; the middleware runner and `db.fetch` are async). Request-scoped DB caching (`TINA4_AUTO_CACHING`) always stays in-process.
912
+
913
+ **Graceful fallback**: if a configured backend's driver is missing or the service/credentials are unreachable or wrong, the cache logs a warning and falls back to the **file** backend — a real persistent cache, never a silent no-op.
914
+
906
915
  Environment:
907
- - `TINA4_CACHE_BACKEND` — `memory` | `redis` | `file` (default: `memory`)
908
- - `TINA4_CACHE_URL` — `redis://localhost:6379` (redis backend only)
916
+ - `TINA4_CACHE_BACKEND` — `memory` (default) | `file` | `redis` | `valkey` | `memcached` | `mongodb` | `database`
917
+ - `TINA4_CACHE_URL` — connection for redis/valkey/memcached/mongodb (`redis://localhost:6379`, `mongodb://host`), OR a SQL URL for `database` (falls back to `TINA4_DATABASE_URL`)
918
+ - `TINA4_CACHE_USERNAME` / `TINA4_CACHE_PASSWORD` — credentials (mirror `TINA4_DATABASE_USERNAME`/`_PASSWORD`); may also be embedded in `TINA4_CACHE_URL` (`redis://user:pass@host`, `redis://:pass@host`, `mongodb://user:pass@host`). memcached is unauthenticated
909
919
  - `TINA4_CACHE_TTL` — default TTL seconds (default: `60`)
910
920
  - `TINA4_CACHE_MAX_ENTRIES` — max entries (default: `1000`)
921
+ - `TINA4_CACHE_DIR` — directory for the `file` backend (default: `data/cache`)
911
922
 
912
923
  ## Firebird-Specific Rules
913
924
 
@@ -1103,12 +1114,13 @@ When adding new features, add a corresponding `test/<feature>.test.ts` file.
1103
1114
  ## v3 Features Summary
1104
1115
 
1105
1116
  - **45 built-in features**, zero third-party dependencies
1106
- - **3,708 tests** passing across all modules
1117
+ - **3,804 tests** passing across all modules
1107
1118
  - **Race-safe `getNextId()`** with atomic sequence table (`tina4_sequences`) for SQLite/MySQL/MSSQL; PostgreSQL auto-creates sequences
1108
1119
  - **Frond template engine optimizations**: pre-compiled regexes, lazy loop context (copy-on-write), filter chain caching, path split caching, inline common filters (11-15% speedup)
1109
1120
  - **Production server auto-detect**: `npx tina4nodejs serve --production` auto-uses cluster mode
1110
1121
  - **`npx tina4nodejs generate`**: model, route, migration, middleware scaffolding
1111
- - **Database**: 5 engines (SQLite, PostgreSQL, MySQL, MSSQL, Firebird), DB query caching — request-scoped auto cache **on by default** (`TINA4_AUTO_CACHING=true`, TTL `TINA4_AUTO_CACHING_TTL=5`s) dedupes identical `db.fetch()`/ORM reads within a request and flushes on writes; persistent cross-request cache opt-in via `TINA4_DB_CACHE=true` (TTL `TINA4_DB_CACHE_TTL=30`s). `db.cacheStats()`/`db.cacheClear()` are now real (the DB query cache is wired; was dead code)
1122
+ - **Database**: 5 engines (SQLite, PostgreSQL, MySQL, MSSQL, Firebird), DB query caching — request-scoped auto cache **on by default** (`TINA4_AUTO_CACHING=true`, TTL `TINA4_AUTO_CACHING_TTL=5`s) dedupes identical `db.fetch()`/ORM reads within a request and flushes on writes (always in-process); persistent cross-request cache opt-in via `TINA4_DB_CACHE=true` (TTL `TINA4_DB_CACHE_TTL=30`s) routed through the unified async backend set via `TINA4_DB_CACHE_BACKEND` (memory/file/redis/valkey/memcached/mongodb/database) + `TINA4_DB_CACHE_URL`, so instances share one cache with global write-invalidation (full parity with Python/PHP/Ruby). `db.cacheStats()` reports `mode` (request/persistent/off) + `backend`
1123
+ - **Cache**: unified backend set — `memory` (default), `file`, `redis`, `valkey`, `memcached`, `mongodb`, `database` — via `TINA4_CACHE_BACKEND` (+ `TINA4_CACHE_URL`/credentials); file-backend fallback if a backend is unreachable. The KV API, the `responseCache` middleware, and the persistent DB query cache all route through this async backend set (native async clients, no child processes) — a network backend distributes them cross-instance, full parity with Python/PHP/Ruby; `memory` (default) keeps them in-process. `await` the async API (`cacheGet`/`cacheSet`/`clearCache`)
1112
1124
  - **Sessions**: file backend (default). `TINA4_SESSION_SAMESITE` env var (default: Lax)
1113
1125
  - **Queue**: file/RabbitMQ/Kafka/MongoDB backends, configured via env vars
1114
1126
  - **Cache**: memory/Redis/file backends
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
 
5
5
 
6
- "version": "3.13.23",
6
+ "version": "3.13.25",
7
7
 
8
8
  "type": "module",
9
9
  "description": "Tina4 for Node.js/TypeScript \u2014 54 built-in features, zero dependencies",
@@ -66,6 +66,7 @@
66
66
  "devDependencies": {
67
67
  "typescript": "^5.7.0",
68
68
  "tsx": "^4.19.0",
69
- "esbuild": "^0.24.0"
69
+ "esbuild": "^0.24.0",
70
+ "mongodb": "^6.0.0"
70
71
  }
71
72
  }