@arcaelas/dynamite 1.0.9 → 1.0.13

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.
Files changed (88) hide show
  1. package/LICENSE.txt +32 -0
  2. package/README.txt +206 -0
  3. package/package.json +5 -4
  4. package/src/@types/index.d.ts +96 -0
  5. package/src/@types/index.js +9 -0
  6. package/src/core/client.d.ts +69 -0
  7. package/src/core/client.js +164 -0
  8. package/src/core/table.d.ts +98 -0
  9. package/src/core/table.js +459 -0
  10. package/src/core/wrapper.d.ts +17 -0
  11. package/src/core/wrapper.js +46 -0
  12. package/src/decorators/belongs_to.d.ts +1 -0
  13. package/src/decorators/belongs_to.js +24 -0
  14. package/src/decorators/created_at.d.ts +1 -0
  15. package/{build → src}/decorators/created_at.js +0 -11
  16. package/src/decorators/default.d.ts +1 -0
  17. package/{build → src}/decorators/default.js +7 -12
  18. package/src/decorators/has_many.d.ts +1 -0
  19. package/src/decorators/has_many.js +24 -0
  20. package/src/decorators/index.d.ts +11 -0
  21. package/src/decorators/index.js +36 -0
  22. package/src/decorators/index_sort.d.ts +12 -0
  23. package/src/decorators/index_sort.js +43 -0
  24. package/{build → src}/decorators/mutate.js +12 -14
  25. package/{build → src}/decorators/name.js +1 -14
  26. package/src/decorators/not_null.d.ts +1 -0
  27. package/src/decorators/not_null.js +13 -0
  28. package/src/decorators/primary_key.d.ts +6 -0
  29. package/src/decorators/primary_key.js +30 -0
  30. package/src/decorators/updated_at.d.ts +12 -0
  31. package/src/decorators/updated_at.js +26 -0
  32. package/{build → src}/decorators/validate.js +12 -13
  33. package/src/index.d.ts +22 -0
  34. package/{build → src}/index.js +22 -6
  35. package/src/utils/batch-relations.d.ts +14 -0
  36. package/src/utils/batch-relations.js +131 -0
  37. package/src/utils/circular-detector.d.ts +82 -0
  38. package/src/utils/circular-detector.js +209 -0
  39. package/src/utils/memory-manager.d.ts +42 -0
  40. package/src/utils/memory-manager.js +108 -0
  41. package/src/utils/naming.d.ts +8 -0
  42. package/src/utils/naming.js +18 -0
  43. package/src/utils/projection.d.ts +12 -0
  44. package/src/utils/projection.js +51 -0
  45. package/src/utils/relations.d.ts +17 -0
  46. package/src/utils/relations.js +166 -0
  47. package/src/utils/security-validator.d.ts +49 -0
  48. package/src/utils/security-validator.js +152 -0
  49. package/src/utils/throttle-manager.d.ts +78 -0
  50. package/src/utils/throttle-manager.js +196 -0
  51. package/src/utils/transaction-manager.d.ts +88 -0
  52. package/src/utils/transaction-manager.js +298 -0
  53. package/build/core/table.d.ts +0 -138
  54. package/build/core/table.js +0 -400
  55. package/build/core/table.js.map +0 -1
  56. package/build/core/wrapper.d.ts +0 -44
  57. package/build/core/wrapper.js +0 -26
  58. package/build/core/wrapper.js.map +0 -1
  59. package/build/decorators/created_at.d.ts +0 -4
  60. package/build/decorators/created_at.js.map +0 -1
  61. package/build/decorators/default.d.ts +0 -2
  62. package/build/decorators/default.js.map +0 -1
  63. package/build/decorators/index.d.ts +0 -1
  64. package/build/decorators/index.js +0 -24
  65. package/build/decorators/index.js.map +0 -1
  66. package/build/decorators/index_sort.d.ts +0 -1
  67. package/build/decorators/index_sort.js +0 -27
  68. package/build/decorators/index_sort.js.map +0 -1
  69. package/build/decorators/mutate.js.map +0 -1
  70. package/build/decorators/name.js.map +0 -1
  71. package/build/decorators/not_null.d.ts +0 -4
  72. package/build/decorators/not_null.js +0 -28
  73. package/build/decorators/not_null.js.map +0 -1
  74. package/build/decorators/primary_key.d.ts +0 -7
  75. package/build/decorators/primary_key.js +0 -30
  76. package/build/decorators/primary_key.js.map +0 -1
  77. package/build/decorators/updated_at.d.ts +0 -4
  78. package/build/decorators/updated_at.js +0 -23
  79. package/build/decorators/updated_at.js.map +0 -1
  80. package/build/decorators/validate.js.map +0 -1
  81. package/build/index.d.ts +0 -11
  82. package/build/index.js.map +0 -1
  83. package/build/utils/naming.d.ts +0 -1
  84. package/build/utils/naming.js +0 -18
  85. package/build/utils/naming.js.map +0 -1
  86. /package/{build → src}/decorators/mutate.d.ts +0 -0
  87. /package/{build → src}/decorators/name.d.ts +0 -0
  88. /package/{build → src}/decorators/validate.d.ts +0 -0
@@ -1,10 +1,4 @@
1
1
  "use strict";
2
- /*
3
- * Dinamite ORM — @Default
4
- * -----------------------
5
- * Registra un valor por defecto y crea (si falta) el
6
- * getter/setter virtual de la propiedad.
7
- */
8
2
  Object.defineProperty(exports, "__esModule", { value: true });
9
3
  exports.default = Default;
10
4
  const wrapper_1 = require("../core/wrapper");
@@ -17,12 +11,10 @@ function Default(factory) {
17
11
  if (column.default)
18
12
  throw new Error(`@Default duplicado en '${String(prop)}'`);
19
13
  column.default = typeof factory === "function" ? factory : () => factory;
20
- if (!Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set) {
14
+ !Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set &&
21
15
  defineVirtual(ctor.prototype, column, prop);
22
- }
23
16
  };
24
17
  }
25
- /* ------------------------------------------------------------------ */
26
18
  function defineVirtual(proto, col, prop) {
27
19
  Object.defineProperty(proto, prop, {
28
20
  get() {
@@ -30,9 +22,12 @@ function defineVirtual(proto, col, prop) {
30
22
  },
31
23
  set(val) {
32
24
  const buf = (this[wrapper_1.STORE] ??= {});
33
- if (val === undefined && col.default !== undefined) {
34
- val = typeof col.default === "function" ? col.default() : col.default;
35
- }
25
+ val =
26
+ val === undefined && col.default !== undefined
27
+ ? typeof col.default === "function"
28
+ ? col.default()
29
+ : col.default
30
+ : val;
36
31
  if (col.mutate)
37
32
  for (const m of col.mutate)
38
33
  val = m(val);
@@ -0,0 +1 @@
1
+ export default function HasMany(targetModel: () => any, foreignKey: string, localKey?: string): PropertyDecorator;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = HasMany;
4
+ const wrapper_1 = require("../core/wrapper");
5
+ function HasMany(targetModel, foreignKey, localKey) {
6
+ return (target, prop) => {
7
+ const entry = (0, wrapper_1.ensureConfig)(target.constructor, target.constructor.name);
8
+ entry.relations.set(prop, {
9
+ type: "hasMany",
10
+ targetModel,
11
+ foreignKey,
12
+ localKey: localKey || "id",
13
+ });
14
+ // Crear getter dinámico para la relación
15
+ Object.defineProperty(target, prop, {
16
+ get() {
17
+ return this[`_${prop.toString()}`] || [];
18
+ },
19
+ enumerable: true,
20
+ configurable: true,
21
+ });
22
+ };
23
+ }
24
+ //# sourceMappingURL=has_many.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @file index.ts
3
+ * @descripcion Decorador @Index para Partition Key
4
+ * @autor Miguel Alejandro
5
+ * @fecha 2025-01-27
6
+ */
7
+ /**
8
+ * Decorador para marcar propiedad como Partition Key.
9
+ * Configura la propiedad como índice principal para consultas.
10
+ */
11
+ export default function Index(): PropertyDecorator;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * @file index.ts
4
+ * @descripcion Decorador @Index para Partition Key
5
+ * @autor Miguel Alejandro
6
+ * @fecha 2025-01-27
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.default = Index;
10
+ const wrapper_1 = require("../core/wrapper");
11
+ const naming_1 = require("../utils/naming");
12
+ /**
13
+ * Decorador para marcar propiedad como Partition Key.
14
+ * Configura la propiedad como índice principal para consultas.
15
+ */
16
+ function Index() {
17
+ return (target, prop) => {
18
+ const ctor = target.constructor;
19
+ const tableName = (0, naming_1.toSnakePlural)(ctor.name);
20
+ const entry = (0, wrapper_1.ensureConfig)(ctor, tableName);
21
+ // Verificar si ya existe un índice primario
22
+ const existingIndex = [...entry.columns.values()].find((col) => col.index === true);
23
+ if (existingIndex && existingIndex.name !== String(prop)) {
24
+ throw new Error(`La tabla ${tableName} ya tiene definida una PartitionKey (${existingIndex.name}). ` +
25
+ `No se puede definir otra PartitionKey en '${String(prop)}'`);
26
+ }
27
+ // Obtener o crear la columna y marcar como índice
28
+ const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
29
+ column.index = true;
30
+ // Asegurar que la columna no sea nula por defecto
31
+ if (column.nullable === undefined) {
32
+ column.nullable = false;
33
+ }
34
+ };
35
+ }
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @file index_sort.ts
3
+ * @descripcion Decorador @IndexSort para Sort Key
4
+ * @autor Miguel Alejandro
5
+ * @fecha 2025-01-27
6
+ */
7
+ /**
8
+ * Decorador para marcar propiedad como Sort Key.
9
+ * Configura la propiedad como clave de ordenación para consultas.
10
+ * Requiere que exista una PartitionKey (@Index) definida previamente.
11
+ */
12
+ export default function IndexSort(): PropertyDecorator;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /**
3
+ * @file index_sort.ts
4
+ * @descripcion Decorador @IndexSort para Sort Key
5
+ * @autor Miguel Alejandro
6
+ * @fecha 2025-01-27
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.default = IndexSort;
10
+ const wrapper_1 = require("../core/wrapper");
11
+ const naming_1 = require("../utils/naming");
12
+ /**
13
+ * Decorador para marcar propiedad como Sort Key.
14
+ * Configura la propiedad como clave de ordenación para consultas.
15
+ * Requiere que exista una PartitionKey (@Index) definida previamente.
16
+ */
17
+ function IndexSort() {
18
+ return (target, prop) => {
19
+ const ctor = target.constructor;
20
+ const tableName = (0, naming_1.toSnakePlural)(ctor.name);
21
+ const entry = (0, wrapper_1.ensureConfig)(ctor, tableName);
22
+ // Verificar que exista una PartitionKey definida
23
+ const hasPartitionKey = [...entry.columns.values()].some((col) => col.index === true);
24
+ if (!hasPartitionKey) {
25
+ throw new Error(`No se puede definir una SortKey en '${String(prop)}' sin una PartitionKey. ` +
26
+ `Asegúrate de marcar una propiedad con @Index primero.`);
27
+ }
28
+ // Verificar si ya existe una SortKey
29
+ const existingSortKey = [...entry.columns.values()].find((col) => col.indexSort === true);
30
+ if (existingSortKey && existingSortKey.name !== String(prop)) {
31
+ throw new Error(`La tabla ${tableName} ya tiene una SortKey definida (${existingSortKey.name}). ` +
32
+ `No se puede definir otra SortKey en '${String(prop)}'`);
33
+ }
34
+ // Obtener o crear la columna y marcar como índice de ordenación
35
+ const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
36
+ column.indexSort = true;
37
+ // Asegurar que la columna no sea nula por defecto
38
+ if (column.nullable === undefined) {
39
+ column.nullable = false;
40
+ }
41
+ };
42
+ }
43
+ //# sourceMappingURL=index_sort.js.map
@@ -1,10 +1,4 @@
1
1
  "use strict";
2
- /*
3
- * Dinamite ORM — @Mutate
4
- * ----------------------
5
- * Registra funciones transformadoras para un campo y virtualiza
6
- * la propiedad si aún no existe.
7
- */
8
2
  Object.defineProperty(exports, "__esModule", { value: true });
9
3
  exports.default = Mutate;
10
4
  const wrapper_1 = require("../core/wrapper");
@@ -18,12 +12,11 @@ function Mutate(fn) {
18
12
  const col = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
19
13
  col.mutate ??= [];
20
14
  col.mutate.push(fn);
21
- if (!Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set) {
15
+ !Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set &&
22
16
  defineVirtual(ctor.prototype, col, prop);
23
- }
24
17
  };
25
18
  }
26
- /* ------------------------------------------------------------------ */
19
+ /** Define propiedad virtual con getter/setter para manejo de mutaciones */
27
20
  function defineVirtual(proto, col, prop) {
28
21
  Object.defineProperty(proto, prop, {
29
22
  get() {
@@ -31,17 +24,22 @@ function defineVirtual(proto, col, prop) {
31
24
  },
32
25
  set(val) {
33
26
  const buf = (this[wrapper_1.STORE] ??= {});
34
- if (val === undefined && col.default !== undefined) {
35
- val = typeof col.default === "function" ? col.default() : col.default;
36
- }
27
+ val =
28
+ val === undefined && col.default !== undefined
29
+ ? typeof col.default === "function"
30
+ ? col.default()
31
+ : col.default
32
+ : val;
37
33
  if (col.mutate)
38
34
  for (const m of col.mutate)
39
35
  val = m(val);
40
36
  if (col.validate) {
41
37
  for (const v of col.validate) {
42
38
  const r = v(val);
43
- if (r !== true)
44
- throw new Error(typeof r === "string" ? r : "Validación fallida");
39
+ r !== true &&
40
+ (() => {
41
+ throw new Error(typeof r === "string" ? r : "Validación fallida");
42
+ })();
45
43
  }
46
44
  }
47
45
  buf[prop] = val;
@@ -1,35 +1,22 @@
1
1
  "use strict";
2
- /*
3
- * Dinamite ORM — @Name
4
- * --------------------
5
- * • @Name("tabla") → nombre físico de la tabla
6
- * • @Name("columna") → alias de columna
7
- *
8
- * Permite sobrescribir el nombre AUTO-generado (snake_plural)
9
- * sin lanzar conflicto.
10
- */
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  exports.default = Name;
13
4
  const wrapper_1 = require("../core/wrapper");
14
5
  const naming_1 = require("../utils/naming");
15
6
  function Name(label) {
16
- if (!label || typeof label !== "string") {
7
+ if (!label || typeof label !== "string")
17
8
  throw new TypeError("@Name requiere una cadena no vacía");
18
- }
19
9
  return (target, prop) => {
20
10
  const ctor = prop === undefined ? target : target.constructor;
21
11
  const entry = (0, wrapper_1.ensureConfig)(ctor, (0, naming_1.toSnakePlural)(ctor.name));
22
12
  if (prop === undefined) {
23
- /* ---------- Nombre de la tabla ---------- */
24
13
  const auto = (0, naming_1.toSnakePlural)(ctor.name);
25
- // Solo error si ya se modificó conscientemente antes.
26
14
  if (entry.name !== auto && entry.name !== label && entry.name) {
27
15
  throw new Error(`La clase ${ctor.name} ya tiene un @Name distinto (${entry.name})`);
28
16
  }
29
17
  entry.name = label;
30
18
  }
31
19
  else {
32
- /* ---------- Alias de columna ---------- */
33
20
  const col = (0, wrapper_1.ensureColumn)(entry, prop, label);
34
21
  if (col.name && col.name !== label) {
35
22
  throw new Error(`La columna '${String(prop)}' ya tiene @Name distinto (${col.name})`);
@@ -0,0 +1 @@
1
+ export default function NotNull(): PropertyDecorator;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = NotNull;
7
+ const validate_1 = __importDefault(require("./validate"));
8
+ function NotNull() {
9
+ return validate_1.default((value) => value !== null &&
10
+ value !== undefined &&
11
+ (typeof value !== "string" || value.trim() !== ""));
12
+ }
13
+ //# sourceMappingURL=not_null.js.map
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Decorador para marcar una propiedad como clave primaria.
3
+ * Aplica automáticamente @Index y @IndexSort y marca el campo como primaryKey en los metadatos.
4
+ * @param name - Nombre opcional para el índice (no utilizado actualmente, mantenido por compatibilidad)
5
+ */
6
+ export default function PrimaryKey(name?: string): PropertyDecorator;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = PrimaryKey;
7
+ const wrapper_1 = require("../core/wrapper");
8
+ const naming_1 = require("../utils/naming");
9
+ const index_1 = __importDefault(require("./index"));
10
+ const index_sort_1 = __importDefault(require("./index_sort"));
11
+ /**
12
+ * Decorador para marcar una propiedad como clave primaria.
13
+ * Aplica automáticamente @Index y @IndexSort y marca el campo como primaryKey en los metadatos.
14
+ * @param name - Nombre opcional para el índice (no utilizado actualmente, mantenido por compatibilidad)
15
+ */
16
+ function PrimaryKey(name = "primary") {
17
+ return (target, prop) => {
18
+ // Aplicar decoradores de índice
19
+ (0, index_1.default)()(target, prop);
20
+ (0, index_sort_1.default)()(target, prop);
21
+ // Marcar explícitamente como clave primaria en los metadatos
22
+ const ctor = target.constructor;
23
+ const entry = (0, wrapper_1.ensureConfig)(ctor, (0, naming_1.toSnakePlural)(ctor.name));
24
+ const column = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
25
+ // Establecer metadatos adicionales para clave primaria
26
+ column.primaryKey = true;
27
+ column.nullable = false; // Las claves primarias no pueden ser nulas
28
+ };
29
+ }
30
+ //# sourceMappingURL=primary_key.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Decorador que marca una propiedad para que se actualice automáticamente con la fecha/hora actual
3
+ * cada vez que se guarde el modelo.
4
+ *
5
+ * @example
6
+ * class User extends Table<User> {
7
+ * @PrimaryKey() id: string;
8
+ * name: string;
9
+ * @UpdatedAt() updated_at: string;
10
+ * }
11
+ */
12
+ export default function UpdatedAt(): (target: any, propertyKey: string | symbol) => void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = UpdatedAt;
4
+ const wrapper_1 = require("../core/wrapper");
5
+ /**
6
+ * Decorador que marca una propiedad para que se actualice automáticamente con la fecha/hora actual
7
+ * cada vez que se guarde el modelo.
8
+ *
9
+ * @example
10
+ * class User extends Table<User> {
11
+ * @PrimaryKey() id: string;
12
+ * name: string;
13
+ * @UpdatedAt() updated_at: string;
14
+ * }
15
+ */
16
+ function UpdatedAt() {
17
+ return function (target, propertyKey) {
18
+ const ctor = target.constructor;
19
+ const entry = (0, wrapper_1.ensureConfig)(ctor, ctor.name);
20
+ const column = (0, wrapper_1.ensureColumn)(entry, propertyKey, propertyKey);
21
+ // Marcamos la columna como updatedAt para que se actualice automáticamente al guardar
22
+ column.updatedAt = true;
23
+ // No establecemos un valor por defecto aquí, se establecerá en el método save()
24
+ };
25
+ }
26
+ //# sourceMappingURL=updated_at.js.map
@@ -1,9 +1,4 @@
1
1
  "use strict";
2
- /*
3
- * Dinamite ORM — @Validate
4
- * ------------------------
5
- * Registra validadores y crea virtual si falta.
6
- */
7
2
  Object.defineProperty(exports, "__esModule", { value: true });
8
3
  exports.default = Validate;
9
4
  const wrapper_1 = require("../core/wrapper");
@@ -19,12 +14,11 @@ function Validate(validators) {
19
14
  const col = (0, wrapper_1.ensureColumn)(entry, prop, String(prop));
20
15
  col.validate ??= [];
21
16
  col.validate.push(...list);
22
- if (!Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set) {
17
+ !Object.getOwnPropertyDescriptor(ctor.prototype, prop)?.set &&
23
18
  defineVirtual(ctor.prototype, col, prop);
24
- }
25
19
  };
26
20
  }
27
- /* ------------------------------------------------------------------ */
21
+ /** Define propiedad virtual con getter/setter para manejo de validaciones */
28
22
  function defineVirtual(proto, col, prop) {
29
23
  Object.defineProperty(proto, prop, {
30
24
  get() {
@@ -32,17 +26,22 @@ function defineVirtual(proto, col, prop) {
32
26
  },
33
27
  set(val) {
34
28
  const buf = (this[wrapper_1.STORE] ??= {});
35
- if (val === undefined && col.default !== undefined) {
36
- val = typeof col.default === "function" ? col.default() : col.default;
37
- }
29
+ val =
30
+ val === undefined && col.default !== undefined
31
+ ? typeof col.default === "function"
32
+ ? col.default()
33
+ : col.default
34
+ : val;
38
35
  if (col.mutate)
39
36
  for (const m of col.mutate)
40
37
  val = m(val);
41
38
  if (col.validate) {
42
39
  for (const v of col.validate) {
43
40
  const r = v(val);
44
- if (r !== true)
45
- throw new Error(typeof r === "string" ? r : "Validación fallida");
41
+ r !== true &&
42
+ (() => {
43
+ throw new Error(typeof r === "string" ? r : "Validación fallida");
44
+ })();
46
45
  }
47
46
  }
48
47
  buf[prop] = val;
package/src/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @file index.ts
3
+ * @descripcion Punto de entrada público de la librería
4
+ * @autor Miguel Alejandro
5
+ * @fecha 2025-08-07
6
+ */
7
+ export { Dynamite } from "./core/client";
8
+ export { default as Table } from "./core/table";
9
+ export { default as BelongsTo } from "./decorators/belongs_to";
10
+ export { default as CreatedAt } from "./decorators/created_at";
11
+ export { default as Default } from "./decorators/default";
12
+ export { default as HasMany } from "./decorators/has_many";
13
+ export { default as Index } from "./decorators/index";
14
+ export { default as IndexSort } from "./decorators/index_sort";
15
+ export { default as Mutate } from "./decorators/mutate";
16
+ export { default as Name } from "./decorators/name";
17
+ export { default as NotNull } from "./decorators/not_null";
18
+ export { default as PrimaryKey } from "./decorators/primary_key";
19
+ export { default as UpdatedAt } from "./decorators/updated_at";
20
+ export { default as Validate } from "./decorators/validate";
21
+ export { belongsTo, hasMany } from "./utils/relations";
22
+ export type { BelongsTo as BelongsToType, HasMany as HasManyType, NonAttribute, CreationOptional, InferAttributes, FilterableAttributes, QueryOperator, QueryResult, WhereOptions, WhereOptionsWithoutWhere, } from "./@types/index";
@@ -1,15 +1,29 @@
1
1
  "use strict";
2
+ /**
3
+ * @file index.ts
4
+ * @descripcion Punto de entrada público de la librería
5
+ * @autor Miguel Alejandro
6
+ * @fecha 2025-08-07
7
+ */
2
8
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
9
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
10
  };
5
11
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.UpdatedAt = exports.PrimaryKey = exports.NotNull = exports.CreatedAt = exports.Validate = exports.Name = exports.Mutate = exports.IndexSort = exports.Index = exports.Default = exports.Table = exports.connect = void 0;
12
+ exports.hasMany = exports.belongsTo = exports.Validate = exports.UpdatedAt = exports.PrimaryKey = exports.NotNull = exports.Name = exports.Mutate = exports.IndexSort = exports.Index = exports.HasMany = exports.Default = exports.CreatedAt = exports.BelongsTo = exports.Table = exports.Dynamite = void 0;
13
+ // Clases núcleo
14
+ var client_1 = require("./core/client");
15
+ Object.defineProperty(exports, "Dynamite", { enumerable: true, get: function () { return client_1.Dynamite; } });
7
16
  var table_1 = require("./core/table");
8
- Object.defineProperty(exports, "connect", { enumerable: true, get: function () { return table_1.connect; } });
9
17
  Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return __importDefault(table_1).default; } });
10
18
  // Decoradores
19
+ var belongs_to_1 = require("./decorators/belongs_to");
20
+ Object.defineProperty(exports, "BelongsTo", { enumerable: true, get: function () { return __importDefault(belongs_to_1).default; } });
21
+ var created_at_1 = require("./decorators/created_at");
22
+ Object.defineProperty(exports, "CreatedAt", { enumerable: true, get: function () { return __importDefault(created_at_1).default; } });
11
23
  var default_1 = require("./decorators/default");
12
24
  Object.defineProperty(exports, "Default", { enumerable: true, get: function () { return __importDefault(default_1).default; } });
25
+ var has_many_1 = require("./decorators/has_many");
26
+ Object.defineProperty(exports, "HasMany", { enumerable: true, get: function () { return __importDefault(has_many_1).default; } });
13
27
  var index_1 = require("./decorators/index");
14
28
  Object.defineProperty(exports, "Index", { enumerable: true, get: function () { return __importDefault(index_1).default; } });
15
29
  var index_sort_1 = require("./decorators/index_sort");
@@ -18,14 +32,16 @@ var mutate_1 = require("./decorators/mutate");
18
32
  Object.defineProperty(exports, "Mutate", { enumerable: true, get: function () { return __importDefault(mutate_1).default; } });
19
33
  var name_1 = require("./decorators/name");
20
34
  Object.defineProperty(exports, "Name", { enumerable: true, get: function () { return __importDefault(name_1).default; } });
21
- var validate_1 = require("./decorators/validate");
22
- Object.defineProperty(exports, "Validate", { enumerable: true, get: function () { return __importDefault(validate_1).default; } });
23
- var created_at_1 = require("./decorators/created_at");
24
- Object.defineProperty(exports, "CreatedAt", { enumerable: true, get: function () { return __importDefault(created_at_1).default; } });
25
35
  var not_null_1 = require("./decorators/not_null");
26
36
  Object.defineProperty(exports, "NotNull", { enumerable: true, get: function () { return __importDefault(not_null_1).default; } });
27
37
  var primary_key_1 = require("./decorators/primary_key");
28
38
  Object.defineProperty(exports, "PrimaryKey", { enumerable: true, get: function () { return __importDefault(primary_key_1).default; } });
29
39
  var updated_at_1 = require("./decorators/updated_at");
30
40
  Object.defineProperty(exports, "UpdatedAt", { enumerable: true, get: function () { return __importDefault(updated_at_1).default; } });
41
+ var validate_1 = require("./decorators/validate");
42
+ Object.defineProperty(exports, "Validate", { enumerable: true, get: function () { return __importDefault(validate_1).default; } });
43
+ // Relaciones
44
+ var relations_1 = require("./utils/relations");
45
+ Object.defineProperty(exports, "belongsTo", { enumerable: true, get: function () { return relations_1.belongsTo; } });
46
+ Object.defineProperty(exports, "hasMany", { enumerable: true, get: function () { return relations_1.hasMany; } });
31
47
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @file batch-relations.ts
3
+ * @description Optimized batch loading for relations
4
+ * @autor Miguel Alejandro
5
+ * @fecha 2025-01-27
6
+ */
7
+ /** Batch loader para hasMany relations */
8
+ export declare const batchLoadHasMany: (Model: any, parentItems: any[], relation: any) => Promise<Map<any, any>>;
9
+ /** Batch loader para belongsTo relations con cache */
10
+ export declare const batchLoadBelongsTo: (Model: any, parentItems: any[], relation: any) => Promise<Map<any, any>>;
11
+ /** Optimized processIncludes con batch loading */
12
+ export declare const processIncludesBatch: (Model: any, items: any[], include: any, depth?: number) => Promise<any[]>;
13
+ /** Clear expired cache entries */
14
+ export declare const cleanupRelationCache: () => void;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /**
3
+ * @file batch-relations.ts
4
+ * @description Optimized batch loading for relations
5
+ * @autor Miguel Alejandro
6
+ * @fecha 2025-01-27
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.cleanupRelationCache = exports.processIncludesBatch = exports.batchLoadBelongsTo = exports.batchLoadHasMany = void 0;
10
+ const wrapper_1 = require("../core/wrapper");
11
+ /** Cache multi-nivel con TTL */
12
+ const relCache = new Map();
13
+ /** Batch loader para hasMany relations */
14
+ const batchLoadHasMany = async (Model, parentItems, relation) => {
15
+ const { targetModel, foreignKey, localKey } = relation;
16
+ const TargetModel = targetModel();
17
+ // Agrupar claves para batch query
18
+ const parentKeys = parentItems.map((item) => item[localKey]).filter(Boolean);
19
+ if (!parentKeys.length)
20
+ return new Map();
21
+ // Single query con 'in' operator
22
+ const relatedItems = await TargetModel.where({
23
+ [foreignKey]: { in: parentKeys },
24
+ });
25
+ // Group by foreign key
26
+ const grouped = new Map();
27
+ relatedItems.forEach((item) => {
28
+ const key = item[foreignKey];
29
+ if (!grouped.has(key))
30
+ grouped.set(key, []);
31
+ grouped.get(key).push(item);
32
+ });
33
+ return grouped;
34
+ };
35
+ exports.batchLoadHasMany = batchLoadHasMany;
36
+ /** Batch loader para belongsTo relations con cache */
37
+ const batchLoadBelongsTo = async (Model, parentItems, relation) => {
38
+ const { targetModel, localKey, foreignKey } = relation;
39
+ const TargetModel = targetModel();
40
+ const cacheKey = `${TargetModel.name}_belongsTo`;
41
+ // Verificar cache existente
42
+ const cache = relCache.get(cacheKey) || new Map();
43
+ relCache.set(cacheKey, cache);
44
+ const now = Date.now();
45
+ // Separar keys en cache vs no-cache
46
+ const keysToFetch = [];
47
+ const cachedResults = new Map();
48
+ parentItems.forEach((item) => {
49
+ const key = item[localKey];
50
+ if (!key)
51
+ return;
52
+ const cached = cache.get(key);
53
+ if (cached && cached.expires > now) {
54
+ cachedResults.set(key, cached.data);
55
+ }
56
+ else {
57
+ keysToFetch.push(key);
58
+ }
59
+ });
60
+ // Fetch missing items
61
+ if (keysToFetch.length) {
62
+ const fetchedItems = await TargetModel.where({
63
+ [foreignKey]: { in: keysToFetch },
64
+ });
65
+ // Update cache (5min TTL)
66
+ const expires = now + 300000;
67
+ fetchedItems.forEach((item) => {
68
+ const key = item[foreignKey];
69
+ cache.set(key, { data: item, expires });
70
+ cachedResults.set(key, item);
71
+ });
72
+ }
73
+ return cachedResults;
74
+ };
75
+ exports.batchLoadBelongsTo = batchLoadBelongsTo;
76
+ /** Optimized processIncludes con batch loading */
77
+ const processIncludesBatch = async (Model, items, include, depth = 0) => {
78
+ if (!include || depth > 10 || !items.length)
79
+ return items;
80
+ const meta = (0, wrapper_1.mustMeta)(Model);
81
+ // Process all relations in parallel
82
+ const relationPromises = Object.entries(include).map(async ([relationKey, relationOptions]) => {
83
+ const relation = meta.relations.get(relationKey);
84
+ if (!relation)
85
+ return;
86
+ let relatedData;
87
+ // Use batch loading based on relation type
88
+ if (relation.type === "hasMany") {
89
+ relatedData = await (0, exports.batchLoadHasMany)(Model, items, relation);
90
+ }
91
+ else {
92
+ relatedData = await (0, exports.batchLoadBelongsTo)(Model, items, relation);
93
+ }
94
+ // Assign relations to items
95
+ items.forEach((item) => {
96
+ const key = item[relation.localKey];
97
+ const related = relatedData.get(key);
98
+ if (relation.type === "hasMany") {
99
+ item[relationKey] = related || [];
100
+ }
101
+ else {
102
+ item[relationKey] = related || null;
103
+ }
104
+ });
105
+ // Recursive processing for nested includes
106
+ if (relationOptions?.include && relatedData.size) {
107
+ const allRelated = Array.from(relatedData.values()).flat();
108
+ const TargetModel = relation.targetModel();
109
+ await (0, exports.processIncludesBatch)(TargetModel, allRelated, relationOptions.include, depth + 1);
110
+ }
111
+ });
112
+ await Promise.all(relationPromises);
113
+ return items;
114
+ };
115
+ exports.processIncludesBatch = processIncludesBatch;
116
+ /** Clear expired cache entries */
117
+ const cleanupRelationCache = () => {
118
+ const now = Date.now();
119
+ relCache.forEach((cache, modelKey) => {
120
+ cache.forEach((entry, key) => {
121
+ if (entry.expires <= now)
122
+ cache.delete(key);
123
+ });
124
+ if (cache.size === 0)
125
+ relCache.delete(modelKey);
126
+ });
127
+ };
128
+ exports.cleanupRelationCache = cleanupRelationCache;
129
+ // Auto cleanup every 5 minutes
130
+ setInterval(exports.cleanupRelationCache, 300000);
131
+ //# sourceMappingURL=batch-relations.js.map