@snowtop/ent 0.2.5 → 0.2.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.
Files changed (104) hide show
  1. package/action/action.js +5 -5
  2. package/action/executor.d.ts +1 -1
  3. package/action/executor.js +4 -4
  4. package/action/experimental_action.js +5 -5
  5. package/action/operations.js +17 -7
  6. package/action/orchestrator.d.ts +2 -2
  7. package/action/orchestrator.js +17 -7
  8. package/action/privacy.d.ts +2 -2
  9. package/action/relative_value.js +3 -3
  10. package/auth/auth.d.ts +0 -1
  11. package/auth/auth.js +4 -5
  12. package/core/async_utils.d.ts +1 -0
  13. package/core/async_utils.js +29 -0
  14. package/core/base.d.ts +1 -1
  15. package/core/base.js +5 -5
  16. package/core/cache_utils.d.ts +1 -0
  17. package/core/cache_utils.js +28 -0
  18. package/core/clause.js +76 -67
  19. package/core/config.d.ts +3 -1
  20. package/core/config.js +29 -9
  21. package/core/context.d.ts +3 -2
  22. package/core/context.js +96 -25
  23. package/core/convert.d.ts +0 -1
  24. package/core/convert.js +16 -17
  25. package/core/date.js +1 -2
  26. package/core/db.js +17 -7
  27. package/core/ent.d.ts +4 -2
  28. package/core/ent.js +111 -106
  29. package/core/global_schema.js +6 -7
  30. package/core/loaders/assoc_count_loader.d.ts +2 -2
  31. package/core/loaders/assoc_count_loader.js +18 -8
  32. package/core/loaders/assoc_edge_loader.d.ts +5 -2
  33. package/core/loaders/assoc_edge_loader.js +87 -31
  34. package/core/loaders/index.d.ts +2 -0
  35. package/core/loaders/index.js +8 -1
  36. package/core/loaders/loader.d.ts +33 -0
  37. package/core/loaders/loader.js +159 -3
  38. package/core/loaders/object_loader.d.ts +7 -5
  39. package/core/loaders/object_loader.js +97 -74
  40. package/core/loaders/query_loader.d.ts +2 -2
  41. package/core/loaders/query_loader.js +60 -24
  42. package/core/loaders/raw_count_loader.d.ts +4 -4
  43. package/core/loaders/raw_count_loader.js +34 -24
  44. package/core/logger.js +6 -7
  45. package/core/metrics.d.ts +22 -0
  46. package/core/metrics.js +31 -0
  47. package/core/privacy.d.ts +2 -2
  48. package/core/privacy.js +4 -5
  49. package/core/query/assoc_query.js +17 -7
  50. package/core/query/query.js +17 -7
  51. package/core/query/shared_assoc_test.js +1 -2
  52. package/core/query_impl.js +4 -5
  53. package/core/viewer.d.ts +2 -2
  54. package/graphql/graphql_field_helpers.js +22 -22
  55. package/graphql/mutations/union.js +1 -2
  56. package/graphql/node_resolver.js +7 -7
  57. package/graphql/query/shared_assoc_test.js +1 -2
  58. package/graphql/scalars/date.js +8 -3
  59. package/graphql/scalars/time.d.ts +1 -1
  60. package/imports/dataz/example1/_auth.js +14 -10
  61. package/imports/index.js +18 -9
  62. package/index.d.ts +2 -1
  63. package/index.js +22 -9
  64. package/names/names.js +61 -18
  65. package/package.json +14 -17
  66. package/parse_schema/parse.js +2 -3
  67. package/schema/binary_field.js +3 -3
  68. package/schema/field.js +45 -35
  69. package/schema/json_field.js +7 -7
  70. package/schema/schema.js +12 -12
  71. package/schema/struct_field.js +4 -4
  72. package/schema/union_field.js +3 -3
  73. package/scripts/custom_compiler.js +17 -7
  74. package/scripts/custom_graphql.js +17 -7
  75. package/scripts/fix_action_exports.js +17 -7
  76. package/scripts/move_types.js +17 -7
  77. package/scripts/read_schema.js +17 -7
  78. package/testutils/action/complex_schemas.js +28 -18
  79. package/testutils/builder.d.ts +1 -1
  80. package/testutils/builder.js +7 -7
  81. package/testutils/db/fixture.js +1 -2
  82. package/testutils/db/temp_db.js +54 -44
  83. package/testutils/db/value.js +3 -4
  84. package/testutils/db_mock.js +12 -0
  85. package/testutils/ent-graphql-tests/index.d.ts +3 -3
  86. package/testutils/ent-graphql-tests/index.js +27 -18
  87. package/testutils/fake_data/const.js +2 -2
  88. package/testutils/fake_data/fake_contact.js +20 -10
  89. package/testutils/fake_data/fake_event.js +20 -10
  90. package/testutils/fake_data/fake_tag.js +21 -11
  91. package/testutils/fake_data/fake_user.js +21 -11
  92. package/testutils/fake_data/test_helpers.js +17 -17
  93. package/testutils/fake_data/user_query.js +19 -9
  94. package/testutils/parse_sql.js +151 -43
  95. package/testutils/query.js +2 -3
  96. package/testutils/soft_delete.js +17 -7
  97. package/testutils/test_edge_global_schema.js +17 -7
  98. package/testutils/write.js +20 -11
  99. package/tsc/ast.js +27 -18
  100. package/tsc/compilerOptions.js +22 -13
  101. package/tsc/move_generated.js +18 -9
  102. package/tsc/transform.js +18 -9
  103. package/tsc/transform_action.js +17 -7
  104. package/tsc/transform_schema.js +17 -7
@@ -15,32 +15,58 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
25
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
26
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
37
  };
28
38
  Object.defineProperty(exports, "__esModule", { value: true });
29
39
  exports.AssocEdgeLoaderFactory = exports.AssocDirectEdgeLoader = exports.AssocEdgeLoader = void 0;
30
- const dataloader_1 = __importDefault(require("dataloader"));
31
40
  const memoizee_1 = __importDefault(require("memoizee"));
32
41
  const clause = __importStar(require("../clause"));
33
42
  const ent_1 = require("../ent");
34
- const logger_1 = require("../logger");
43
+ const cache_utils_1 = require("../cache_utils");
35
44
  const loader_1 = require("./loader");
36
- function createLoader(options, edgeType, edgeCtr, edgeData) {
37
- const loaderOptions = {};
38
- if ((0, logger_1.logEnabled)("query")) {
39
- loaderOptions.cacheMap = new loader_1.CacheMap({
45
+ function getDefaultOrderBy() {
46
+ return [
47
+ {
48
+ column: "time",
49
+ direction: "DESC",
50
+ },
51
+ ];
52
+ }
53
+ function getEffectiveOptions(options) {
54
+ return {
55
+ ...options,
56
+ orderby: options.orderby ?? getDefaultOrderBy(),
57
+ limit: options.limit || (0, ent_1.getDefaultLimit)(),
58
+ disableTransformations: options.disableTransformations ?? false,
59
+ };
60
+ }
61
+ function createLoader(options, edgeType, edgeCtr, edgeData, context) {
62
+ const loaderName = `assocEdgeLoader:${edgeType}`;
63
+ const loaderOptions = {
64
+ maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
65
+ cacheMap: (0, loader_1.createLoaderCacheMap)({
40
66
  tableName: edgeData.edgeTable,
41
- });
42
- }
43
- return new dataloader_1.default(async (keys) => {
67
+ }),
68
+ };
69
+ return new loader_1.InstrumentedDataLoader(loaderName, async (keys) => {
44
70
  if (keys.length === 1) {
45
71
  // 1 key, just be simple and move on
46
72
  // same as AssocDirectEdgeLoader
@@ -48,6 +74,7 @@ function createLoader(options, edgeType, edgeCtr, edgeData) {
48
74
  id1: keys[0],
49
75
  edgeType: edgeType,
50
76
  queryOptions: options,
77
+ context,
51
78
  ctr: edgeCtr,
52
79
  });
53
80
  return [r];
@@ -59,14 +86,9 @@ function createLoader(options, edgeType, edgeCtr, edgeData) {
59
86
  // store the index....
60
87
  m.set(keys[i], i);
61
88
  }
62
- options.orderby = options.orderby || [
63
- {
64
- column: "time",
65
- direction: "DESC",
66
- },
67
- ];
89
+ const orderby = options.orderby ?? getDefaultOrderBy();
68
90
  // TODO defaultEdgeQueryOptions
69
- options.limit = options.limit || (0, ent_1.getDefaultLimit)();
91
+ const limit = options.limit || (0, ent_1.getDefaultLimit)();
70
92
  const tableName = edgeData.edgeTable;
71
93
  const { cls: cls1, fields } = (0, ent_1.getEdgeClauseAndFields)(clause.Eq("edge_type", edgeType), {
72
94
  queryOptions: options,
@@ -75,8 +97,8 @@ function createLoader(options, edgeType, edgeCtr, edgeData) {
75
97
  tableName: tableName,
76
98
  fields,
77
99
  values: keys,
78
- orderby: options.orderby,
79
- limit: options.limit || (0, ent_1.getDefaultLimit)(),
100
+ orderby,
101
+ limit,
80
102
  groupColumn: "id1",
81
103
  clause: cls1,
82
104
  });
@@ -91,7 +113,7 @@ function createLoader(options, edgeType, edgeCtr, edgeData) {
91
113
  result[idx].push(new edgeCtr(row));
92
114
  }
93
115
  return result;
94
- }, loaderOptions);
116
+ }, loaderOptions, edgeData.edgeTable);
95
117
  }
96
118
  class AssocEdgeLoader {
97
119
  constructor(edgeType, edgeCtr, options, context) {
@@ -106,7 +128,7 @@ class AssocEdgeLoader {
106
128
  if (!edgeData) {
107
129
  throw new Error(`error loading edge data for ${this.edgeType}`);
108
130
  }
109
- this.loader = createLoader(this.options, this.edgeType, this.edgeCtr, edgeData);
131
+ this.loader = createLoader(this.options, this.edgeType, this.edgeCtr, edgeData, this.context);
110
132
  return this.loader;
111
133
  }
112
134
  async load(id) {
@@ -144,8 +166,40 @@ class AssocDirectEdgeLoader {
144
166
  this.edgeCtr = edgeCtr;
145
167
  this.options = options;
146
168
  this.context = context;
169
+ if (this.context) {
170
+ this.loaderFn = (0, memoizee_1.default)(this.getLoader);
171
+ }
172
+ }
173
+ async getLoader() {
174
+ if (this.loader) {
175
+ return this.loader;
176
+ }
177
+ const edgeData = await (0, ent_1.loadEdgeData)(this.edgeType);
178
+ if (!edgeData) {
179
+ throw new Error(`error loading edge data for ${this.edgeType}`);
180
+ }
181
+ const loaderName = `assocDirectEdgeLoader:${this.edgeType}`;
182
+ this.loader = new loader_1.InstrumentedDataLoader(loaderName, async (keys) => {
183
+ return Promise.all(keys.map((id) => (0, ent_1.loadCustomEdges)({
184
+ id1: id,
185
+ edgeType: this.edgeType,
186
+ context: this.context,
187
+ queryOptions: this.options,
188
+ ctr: this.edgeCtr,
189
+ })));
190
+ }, {
191
+ maxBatchSize: (0, loader_1.getLoaderMaxBatchSize)(),
192
+ cacheMap: (0, loader_1.createLoaderCacheMap)({
193
+ tableName: edgeData.edgeTable,
194
+ }),
195
+ }, edgeData.edgeTable);
196
+ return this.loader;
147
197
  }
148
198
  async load(id) {
199
+ if (this.loaderFn) {
200
+ const loader = await this.loaderFn();
201
+ return loader.load(id);
202
+ }
149
203
  return (0, ent_1.loadCustomEdges)({
150
204
  id1: id,
151
205
  edgeType: this.edgeType,
@@ -173,7 +227,9 @@ class AssocDirectEdgeLoader {
173
227
  ctr: this.edgeCtr,
174
228
  });
175
229
  }
176
- clearAll() { }
230
+ clearAll() {
231
+ this.loader && this.loader.clearAll();
232
+ }
177
233
  }
178
234
  exports.AssocDirectEdgeLoader = AssocDirectEdgeLoader;
179
235
  class AssocEdgeLoaderFactory {
@@ -207,9 +263,9 @@ class AssocEdgeLoaderFactory {
207
263
  if (options?.clause || !context) {
208
264
  return new AssocDirectEdgeLoader(this.edgeType, edgeCtr, options, context);
209
265
  }
210
- // we create a loader which can combine first X queries in the same fetch
211
- const key = `${this.name}:limit:${options.limit}:orderby:${options.orderby?.map((orderBy) => JSON.stringify(orderBy))}:disableTransformations:${options.disableTransformations}`;
212
- return (0, loader_1.getCustomLoader)(key, () => new AssocEdgeLoader(this.edgeType, ctr, options, context), context);
266
+ const effectiveOptions = getEffectiveOptions(options);
267
+ const key = `${this.name}:limit:${effectiveOptions.limit}:orderby:${(0, cache_utils_1.stableStringify)(effectiveOptions.orderby)}:disableTransformations:${effectiveOptions.disableTransformations}`;
268
+ return (0, loader_1.getCustomLoader)(key, () => new AssocEdgeLoader(this.edgeType, ctr, effectiveOptions, context), context);
213
269
  }
214
270
  }
215
271
  exports.AssocEdgeLoaderFactory = AssocEdgeLoaderFactory;
@@ -3,3 +3,5 @@ export { RawCountLoader, RawCountLoaderFactory } from "./raw_count_loader";
3
3
  export { AssocEdgeCountLoader, AssocEdgeCountLoaderFactory, } from "./assoc_count_loader";
4
4
  export { AssocDirectEdgeLoader, AssocEdgeLoader, AssocEdgeLoaderFactory, } from "./assoc_edge_loader";
5
5
  export { QueryLoaderFactory } from "./query_loader";
6
+ export { getLoaderCacheMaxEntries, getLoaderMaxBatchSize, setLoaderCacheMaxEntries, setLoaderMaxBatchSize, } from "./loader";
7
+ export { setClauseLoaderConcurrency } from "./object_loader";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryLoaderFactory = exports.AssocEdgeLoaderFactory = exports.AssocEdgeLoader = exports.AssocDirectEdgeLoader = exports.AssocEdgeCountLoaderFactory = exports.AssocEdgeCountLoader = exports.RawCountLoaderFactory = exports.RawCountLoader = exports.ObjectLoaderFactory = exports.ObjectLoader = void 0;
3
+ exports.setClauseLoaderConcurrency = exports.setLoaderMaxBatchSize = exports.setLoaderCacheMaxEntries = exports.getLoaderMaxBatchSize = exports.getLoaderCacheMaxEntries = exports.QueryLoaderFactory = exports.AssocEdgeLoaderFactory = exports.AssocEdgeLoader = exports.AssocDirectEdgeLoader = exports.AssocEdgeCountLoaderFactory = exports.AssocEdgeCountLoader = exports.RawCountLoaderFactory = exports.RawCountLoader = exports.ObjectLoaderFactory = exports.ObjectLoader = void 0;
4
4
  var object_loader_1 = require("./object_loader");
5
5
  Object.defineProperty(exports, "ObjectLoader", { enumerable: true, get: function () { return object_loader_1.ObjectLoader; } });
6
6
  Object.defineProperty(exports, "ObjectLoaderFactory", { enumerable: true, get: function () { return object_loader_1.ObjectLoaderFactory; } });
@@ -16,3 +16,10 @@ Object.defineProperty(exports, "AssocEdgeLoader", { enumerable: true, get: funct
16
16
  Object.defineProperty(exports, "AssocEdgeLoaderFactory", { enumerable: true, get: function () { return assoc_edge_loader_1.AssocEdgeLoaderFactory; } });
17
17
  var query_loader_1 = require("./query_loader");
18
18
  Object.defineProperty(exports, "QueryLoaderFactory", { enumerable: true, get: function () { return query_loader_1.QueryLoaderFactory; } });
19
+ var loader_1 = require("./loader");
20
+ Object.defineProperty(exports, "getLoaderCacheMaxEntries", { enumerable: true, get: function () { return loader_1.getLoaderCacheMaxEntries; } });
21
+ Object.defineProperty(exports, "getLoaderMaxBatchSize", { enumerable: true, get: function () { return loader_1.getLoaderMaxBatchSize; } });
22
+ Object.defineProperty(exports, "setLoaderCacheMaxEntries", { enumerable: true, get: function () { return loader_1.setLoaderCacheMaxEntries; } });
23
+ Object.defineProperty(exports, "setLoaderMaxBatchSize", { enumerable: true, get: function () { return loader_1.setLoaderMaxBatchSize; } });
24
+ var object_loader_2 = require("./object_loader");
25
+ Object.defineProperty(exports, "setClauseLoaderConcurrency", { enumerable: true, get: function () { return object_loader_2.setClauseLoaderConcurrency; } });
@@ -1,6 +1,38 @@
1
+ import DataLoader from "dataloader";
1
2
  import { Loader, LoaderFactory, Context, DataOptions } from "../base";
3
+ export declare function getLoaderMaxBatchSize(): number;
4
+ export declare function setLoaderMaxBatchSize(size?: number | null): void;
5
+ export declare function getLoaderCacheMaxEntries(): number;
6
+ export declare function setLoaderCacheMaxEntries(size?: number | null): void;
2
7
  export declare function getLoader<K, V>(factory: LoaderFactory<K, V>, create: () => Loader<K, V>, context?: Context): Loader<K, V>;
3
8
  export declare function getCustomLoader<K, V>(key: string, create: () => Loader<K, V>, context?: Context): Loader<K, V>;
9
+ export type CacheMapLike<K, V> = {
10
+ get(key: K): V | undefined;
11
+ set(key: K, value: V): any;
12
+ delete(key: K): any;
13
+ clear(): any;
14
+ };
15
+ type CacheKeyFn<K> = (key: K) => any;
16
+ type BatchLoadFn<K, V> = (keys: readonly K[]) => PromiseLike<ArrayLike<V | Error>>;
17
+ export declare class InstrumentedDataLoader<K, V> extends DataLoader<K, V> {
18
+ constructor(loaderName: string, batchLoadFn: BatchLoadFn<K, V>, options: DataLoader.Options<K, V>, tableName?: string, cacheKeyFn?: (key: K) => unknown);
19
+ }
20
+ export declare class BoundedCacheMap<K, V> {
21
+ private cacheMap;
22
+ private maxEntries;
23
+ private cacheKeyFn?;
24
+ private order;
25
+ constructor(cacheMap: CacheMapLike<K, V>, maxEntries: number, cacheKeyFn?: CacheKeyFn<K> | undefined);
26
+ private normalizeKey;
27
+ private touch;
28
+ private evictIfNeeded;
29
+ get(key: K): V | undefined;
30
+ set(key: K, value: V): any;
31
+ delete(key: K): any;
32
+ clear(): any;
33
+ }
34
+ export declare function createBoundedCacheMap<K, V>(cacheMap: CacheMapLike<K, V>, cacheKeyFn?: CacheKeyFn<K>): CacheMapLike<K, V>;
35
+ export declare function createLoaderCacheMap<K, V>(options: DataOptions): CacheMapLike<K, V>;
4
36
  export declare class CacheMap {
5
37
  private options;
6
38
  private m;
@@ -10,3 +42,4 @@ export declare class CacheMap {
10
42
  delete(key: any): boolean;
11
43
  clear(): void;
12
44
  }
45
+ export {};
@@ -1,7 +1,50 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CacheMap = exports.getCustomLoader = exports.getLoader = void 0;
6
+ exports.CacheMap = exports.BoundedCacheMap = exports.InstrumentedDataLoader = void 0;
7
+ exports.getLoaderMaxBatchSize = getLoaderMaxBatchSize;
8
+ exports.setLoaderMaxBatchSize = setLoaderMaxBatchSize;
9
+ exports.getLoaderCacheMaxEntries = getLoaderCacheMaxEntries;
10
+ exports.setLoaderCacheMaxEntries = setLoaderCacheMaxEntries;
11
+ exports.getLoader = getLoader;
12
+ exports.getCustomLoader = getCustomLoader;
13
+ exports.createBoundedCacheMap = createBoundedCacheMap;
14
+ exports.createLoaderCacheMap = createLoaderCacheMap;
15
+ const dataloader_1 = __importDefault(require("dataloader"));
4
16
  const logger_1 = require("../logger");
17
+ const metrics_1 = require("../metrics");
18
+ const DEFAULT_MAX_BATCH_SIZE = 1000;
19
+ let loaderMaxBatchSize = DEFAULT_MAX_BATCH_SIZE;
20
+ const DEFAULT_MAX_CACHE_ENTRIES = 1000;
21
+ let loaderCacheMaxEntries = DEFAULT_MAX_CACHE_ENTRIES;
22
+ function getLoaderMaxBatchSize() {
23
+ return loaderMaxBatchSize;
24
+ }
25
+ function setLoaderMaxBatchSize(size) {
26
+ if (size === undefined || size === null) {
27
+ loaderMaxBatchSize = DEFAULT_MAX_BATCH_SIZE;
28
+ return;
29
+ }
30
+ if (!Number.isFinite(size) || size <= 0) {
31
+ throw new Error(`maxBatchSize must be a positive number`);
32
+ }
33
+ loaderMaxBatchSize = Math.floor(size);
34
+ }
35
+ function getLoaderCacheMaxEntries() {
36
+ return loaderCacheMaxEntries;
37
+ }
38
+ function setLoaderCacheMaxEntries(size) {
39
+ if (size === undefined || size === null) {
40
+ loaderCacheMaxEntries = DEFAULT_MAX_CACHE_ENTRIES;
41
+ return;
42
+ }
43
+ if (!Number.isFinite(size) || size < 0) {
44
+ throw new Error(`maxCacheEntries must be a non-negative number`);
45
+ }
46
+ loaderCacheMaxEntries = Math.floor(size);
47
+ }
5
48
  // this is like factory factory FML
6
49
  // helper function to handle context vs not
7
50
  // and to keep the API clean for clients who shouldn't have to worry about this
@@ -14,7 +57,6 @@ function getLoader(factory, create, context) {
14
57
  // g|set from context cache
15
58
  return context.cache.getLoader(factory.name, create);
16
59
  }
17
- exports.getLoader = getLoader;
18
60
  function getCustomLoader(key, create, context) {
19
61
  // just create a new one every time if no context cache
20
62
  if (!context?.cache) {
@@ -24,7 +66,121 @@ function getCustomLoader(key, create, context) {
24
66
  // g|set from context cache
25
67
  return context.cache.getLoader(key, create);
26
68
  }
27
- exports.getCustomLoader = getCustomLoader;
69
+ function instrumentCacheMap(cacheMap, tableName, cacheKeyFn) {
70
+ if (!cacheMap || !tableName) {
71
+ return cacheMap;
72
+ }
73
+ return {
74
+ get(key) {
75
+ const value = cacheMap.get(key);
76
+ if (value !== undefined) {
77
+ const hook = (0, metrics_1.getOnDataLoaderCacheHit)();
78
+ if (hook) {
79
+ hook({
80
+ tableName,
81
+ key: cacheKeyFn ? cacheKeyFn(key) : key,
82
+ });
83
+ }
84
+ }
85
+ return value;
86
+ },
87
+ set(key, value) {
88
+ return cacheMap.set(key, value);
89
+ },
90
+ delete(key) {
91
+ return cacheMap.delete(key);
92
+ },
93
+ clear() {
94
+ return cacheMap.clear();
95
+ },
96
+ };
97
+ }
98
+ class InstrumentedDataLoader extends dataloader_1.default {
99
+ constructor(loaderName, batchLoadFn, options, tableName, cacheKeyFn) {
100
+ const wrappedBatchFn = async (keys) => {
101
+ if (keys.length) {
102
+ const hook = (0, metrics_1.getOnDataLoaderBatch)();
103
+ if (hook) {
104
+ hook({
105
+ loaderName,
106
+ batchSize: keys.length,
107
+ });
108
+ }
109
+ }
110
+ return batchLoadFn(keys);
111
+ };
112
+ const cacheMap = instrumentCacheMap(options.cacheMap, tableName, cacheKeyFn);
113
+ const loaderOptions = cacheMap === options.cacheMap ? options : { ...options, cacheMap };
114
+ super(wrappedBatchFn, loaderOptions);
115
+ }
116
+ }
117
+ exports.InstrumentedDataLoader = InstrumentedDataLoader;
118
+ class BoundedCacheMap {
119
+ constructor(cacheMap, maxEntries, cacheKeyFn) {
120
+ this.cacheMap = cacheMap;
121
+ this.maxEntries = maxEntries;
122
+ this.cacheKeyFn = cacheKeyFn;
123
+ this.order = new Map();
124
+ }
125
+ normalizeKey(key) {
126
+ return this.cacheKeyFn ? this.cacheKeyFn(key) : key;
127
+ }
128
+ touch(normalizedKey, key) {
129
+ if (this.order.has(normalizedKey)) {
130
+ this.order.delete(normalizedKey);
131
+ }
132
+ this.order.set(normalizedKey, key);
133
+ }
134
+ evictIfNeeded() {
135
+ while (this.order.size > this.maxEntries) {
136
+ const oldest = this.order.entries().next().value;
137
+ if (!oldest) {
138
+ return;
139
+ }
140
+ const [normalizedKey, key] = oldest;
141
+ this.order.delete(normalizedKey);
142
+ this.cacheMap.delete(key);
143
+ }
144
+ }
145
+ get(key) {
146
+ const value = this.cacheMap.get(key);
147
+ if (value !== undefined) {
148
+ const normalizedKey = this.normalizeKey(key);
149
+ this.touch(normalizedKey, key);
150
+ }
151
+ return value;
152
+ }
153
+ set(key, value) {
154
+ const normalizedKey = this.normalizeKey(key);
155
+ this.touch(normalizedKey, key);
156
+ const result = this.cacheMap.set(key, value);
157
+ this.evictIfNeeded();
158
+ return result;
159
+ }
160
+ delete(key) {
161
+ const normalizedKey = this.normalizeKey(key);
162
+ this.order.delete(normalizedKey);
163
+ return this.cacheMap.delete(key);
164
+ }
165
+ clear() {
166
+ this.order.clear();
167
+ return this.cacheMap.clear();
168
+ }
169
+ }
170
+ exports.BoundedCacheMap = BoundedCacheMap;
171
+ function createBoundedCacheMap(cacheMap, cacheKeyFn) {
172
+ const maxEntries = getLoaderCacheMaxEntries();
173
+ if (maxEntries <= 0) {
174
+ return cacheMap;
175
+ }
176
+ return new BoundedCacheMap(cacheMap, maxEntries, cacheKeyFn);
177
+ }
178
+ function createLoaderCacheMap(options) {
179
+ const baseMap = (0, logger_1.logEnabled)("query")
180
+ ? new CacheMap(options)
181
+ : new Map();
182
+ return createBoundedCacheMap(baseMap);
183
+ }
28
184
  class CacheMap {
29
185
  constructor(options) {
30
186
  this.options = options;
@@ -1,14 +1,17 @@
1
1
  import { ID, Data, SelectDataOptions, Context, Loader, LoaderFactory } from "../base";
2
+ import { mapWithConcurrency } from "../async_utils";
2
3
  import * as clause from "../clause";
4
+ export declare function setClauseLoaderConcurrency(limit: number): void;
5
+ export { mapWithConcurrency };
3
6
  export declare class ObjectLoader<TQueryData extends Data = Data, TResultData extends Data = TQueryData, K = keyof TQueryData> implements Loader<ID, TResultData | null>, Loader<clause.Clause<TQueryData, K>, TResultData[] | null> {
4
7
  private options;
5
- context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
8
+ context?: Context | undefined;
6
9
  private toPrime?;
7
10
  private idLoader;
8
11
  private clauseLoader;
9
12
  private primedLoaders;
10
13
  private memoizedInitPrime;
11
- constructor(options: SelectDataOptions, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined, toPrime?: ObjectLoaderFactory<TResultData>[] | undefined);
14
+ constructor(options: SelectDataOptions, context?: Context | undefined, toPrime?: ObjectLoaderFactory<TResultData>[] | undefined);
12
15
  getOptions(): SelectDataOptions;
13
16
  private initPrime;
14
17
  load(key: ID): Promise<TResultData | null>;
@@ -25,9 +28,9 @@ export declare class ObjectLoader<TQueryData extends Data = Data, TResultData ex
25
28
  }
26
29
  export declare class ObjectCountLoader<V extends Data = Data, K = keyof V> implements Loader<clause.Clause<V, K>, number> {
27
30
  private options;
28
- context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
31
+ context?: Context | undefined;
29
32
  private loader;
30
- constructor(options: SelectDataOptions, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
33
+ constructor(options: SelectDataOptions, context?: Context | undefined);
31
34
  getOptions(): SelectDataOptions;
32
35
  load(key: clause.Clause<V, K>): Promise<number>;
33
36
  clearAll(): void;
@@ -46,4 +49,3 @@ export declare class ObjectLoaderFactory<V extends Data = Data> implements Loade
46
49
  createCountLoader<K = keyof V>(context?: Context): ObjectCountLoader<V, K>;
47
50
  addToPrime(factory: ObjectLoaderFactory<V>): this;
48
51
  }
49
- export {};