tina4-nodejs 3.13.90 → 3.13.91

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.90)
1
+ # CLAUDE.md - AI Developer Guide for tina4-nodejs (v3.13.91)
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.90 - 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.91 - 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
 
@@ -1244,7 +1244,7 @@ When adding new features, add a corresponding `test/<feature>.test.ts` file.
1244
1244
  ## v3 Features Summary
1245
1245
 
1246
1246
  - **98 built-in features**, zero third-party dependencies
1247
- - **5,923 tests** passing across 189 files (build + typecheck green)
1247
+ - **5,932 tests** passing across 190 files (build + typecheck green)
1248
1248
  - **Race-safe `getNextId()`** with atomic sequence table (`tina4_sequences`) for SQLite/MySQL/MSSQL; PostgreSQL auto-creates sequences
1249
1249
  - **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)
1250
1250
  - **Production server auto-detect**: `npx tina4nodejs serve --production` auto-uses cluster mode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tina4-nodejs",
3
- "version": "3.13.90",
3
+ "version": "3.13.91",
4
4
  "type": "module",
5
5
  "description": "Tina4 for Node.js/TypeScript - 54 built-in features, zero dependencies",
6
6
  "keywords": [
@@ -17938,7 +17938,7 @@ function extractFunctions(source, filePath, root = ".") {
17938
17938
  if (funcName !== null && !NON_FUNCTION_WORDS.has(funcName)) {
17939
17939
  const displayName = funcName === "constructor" && currentClass ? `${currentClass}.constructor` : currentClass !== null && !isTopLevelDecl ? `${currentClass}.${funcName}` : funcName;
17940
17940
  const funcBody = extractFunctionBody(lines, i);
17941
- const funcLoc = funcBody.split("\n").length;
17941
+ const funcLoc = Math.max(1, countLines(funcBody).loc);
17942
17942
  const complexity = cycloMaticComplexity(funcBody);
17943
17943
  const args = argsStr.split(",").map((a) => a.trim().split(":")[0].split("=")[0].replace("?", "").trim()).filter((a) => a && a !== "this");
17944
17944
  functions.push({
@@ -17954,6 +17954,24 @@ function extractFunctions(source, filePath, root = ".") {
17954
17954
  currentClass = null;
17955
17955
  }
17956
17956
  }
17957
+ return chargeNestedComplexityToTheNestedFunction(functions);
17958
+ }
17959
+ function chargeNestedComplexityToTheNestedFunction(functions) {
17960
+ if (functions.length < 2) return functions;
17961
+ const lastLine = (f) => f.line + Math.max(1, f.loc) - 1;
17962
+ const contains = (outer, inner) => inner.line > outer.line && lastLine(inner) <= lastLine(outer);
17963
+ const raw = functions.map((f) => f.complexity);
17964
+ functions.forEach((outer, i) => {
17965
+ let subtract = 0;
17966
+ functions.forEach((inner, j) => {
17967
+ if (i === j || !contains(outer, inner)) return;
17968
+ const nestedDeeper = functions.some(
17969
+ (mid, k) => k !== i && k !== j && contains(outer, mid) && contains(mid, inner)
17970
+ );
17971
+ if (!nestedDeeper) subtract += raw[j] - 1;
17972
+ });
17973
+ outer.complexity = Math.max(1, raw[i] - subtract);
17974
+ });
17957
17975
  return functions;
17958
17976
  }
17959
17977
  function extractFunctionBody(lines, startLine) {
@@ -17937,7 +17937,7 @@ function extractFunctions(source, filePath, root = ".") {
17937
17937
  if (funcName !== null && !NON_FUNCTION_WORDS.has(funcName)) {
17938
17938
  const displayName = funcName === "constructor" && currentClass ? `${currentClass}.constructor` : currentClass !== null && !isTopLevelDecl ? `${currentClass}.${funcName}` : funcName;
17939
17939
  const funcBody = extractFunctionBody(lines, i);
17940
- const funcLoc = funcBody.split("\n").length;
17940
+ const funcLoc = Math.max(1, countLines(funcBody).loc);
17941
17941
  const complexity = cycloMaticComplexity(funcBody);
17942
17942
  const args = argsStr.split(",").map((a) => a.trim().split(":")[0].split("=")[0].replace("?", "").trim()).filter((a) => a && a !== "this");
17943
17943
  functions.push({
@@ -17953,6 +17953,24 @@ function extractFunctions(source, filePath, root = ".") {
17953
17953
  currentClass = null;
17954
17954
  }
17955
17955
  }
17956
+ return chargeNestedComplexityToTheNestedFunction(functions);
17957
+ }
17958
+ function chargeNestedComplexityToTheNestedFunction(functions) {
17959
+ if (functions.length < 2) return functions;
17960
+ const lastLine = (f) => f.line + Math.max(1, f.loc) - 1;
17961
+ const contains = (outer, inner) => inner.line > outer.line && lastLine(inner) <= lastLine(outer);
17962
+ const raw = functions.map((f) => f.complexity);
17963
+ functions.forEach((outer, i) => {
17964
+ let subtract = 0;
17965
+ functions.forEach((inner, j) => {
17966
+ if (i === j || !contains(outer, inner)) return;
17967
+ const nestedDeeper = functions.some(
17968
+ (mid, k) => k !== i && k !== j && contains(outer, mid) && contains(mid, inner)
17969
+ );
17970
+ if (!nestedDeeper) subtract += raw[j] - 1;
17971
+ });
17972
+ outer.complexity = Math.max(1, raw[i] - subtract);
17973
+ });
17956
17974
  return functions;
17957
17975
  }
17958
17976
  function extractFunctionBody(lines, startLine) {