@ignex/ninox 0.1.2 → 0.1.3
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 +45 -4
- package/dist/index.d.ts +111 -61
- package/dist/index.js +218 -63
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -513,7 +513,10 @@ var WatchCoordinator = class {
|
|
|
513
513
|
* Long-lived change-stream consumer for one collection. Each data change
|
|
514
514
|
* invalidates the queries bound to it. On permanent "not supported" errors the
|
|
515
515
|
* watcher is dropped and, if every planned stream failed, the cache falls back
|
|
516
|
-
* to the standalone ticker. Transient errors
|
|
516
|
+
* to the standalone ticker. Transient errors (including resume-token expiry,
|
|
517
|
+
* rollbacks, and `invalidate` events) retry with backoff and invalidate the
|
|
518
|
+
* collection on reopen so entries missed during the outage are re-fetched —
|
|
519
|
+
* see the module doc for the full failure-semantics contract.
|
|
517
520
|
*/
|
|
518
521
|
async watchLoop(key, ref) {
|
|
519
522
|
let backoff = 0;
|
|
@@ -548,7 +551,7 @@ var WatchCoordinator = class {
|
|
|
548
551
|
} catch {
|
|
549
552
|
}
|
|
550
553
|
}
|
|
551
|
-
if (/only supported on replica sets
|
|
554
|
+
if (/only supported on replica sets/i.test(message)) {
|
|
552
555
|
this.markStreamFailed(key);
|
|
553
556
|
return;
|
|
554
557
|
}
|
|
@@ -880,6 +883,8 @@ var cacheCollectionKey = (dbName, physical) => `${dbName}${NS_SEP}${physical}`;
|
|
|
880
883
|
var QueryCache = class {
|
|
881
884
|
lru;
|
|
882
885
|
index = /* @__PURE__ */ new Map();
|
|
886
|
+
/** Per-collection version — bumped on every invalidation/clear of that collection. */
|
|
887
|
+
colVersions = /* @__PURE__ */ new Map();
|
|
883
888
|
ttlMs;
|
|
884
889
|
clone;
|
|
885
890
|
hits = 0;
|
|
@@ -914,6 +919,14 @@ var QueryCache = class {
|
|
|
914
919
|
key(collection, filterHash) {
|
|
915
920
|
return `${collection}${SEP}${filterHash}`;
|
|
916
921
|
}
|
|
922
|
+
/**
|
|
923
|
+
* Current version of a collection key (db-namespaced, e.g. from
|
|
924
|
+
* `cacheCollectionKey`). Reads capture it BEFORE fetching and pass it to
|
|
925
|
+
* `set()` so a concurrent invalidation can never be hidden by a late write.
|
|
926
|
+
*/
|
|
927
|
+
versionOf(collection) {
|
|
928
|
+
return this.colVersions.get(collection) ?? 0;
|
|
929
|
+
}
|
|
917
930
|
get(key) {
|
|
918
931
|
const entry = this.lru.get(key);
|
|
919
932
|
if (!entry) {
|
|
@@ -925,22 +938,34 @@ var QueryCache = class {
|
|
|
925
938
|
this.misses++;
|
|
926
939
|
return void 0;
|
|
927
940
|
}
|
|
941
|
+
if (entry.versions) {
|
|
942
|
+
for (const [col, ver] of Object.entries(entry.versions)) {
|
|
943
|
+
if (this.versionOf(col) !== ver) {
|
|
944
|
+
this.lru.delete(key);
|
|
945
|
+
this.misses++;
|
|
946
|
+
return void 0;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
928
950
|
this.hits++;
|
|
929
951
|
return this.clone ? cloneDeep(entry.value) : entry.value;
|
|
930
952
|
}
|
|
931
|
-
set(key, value, ttlMs) {
|
|
953
|
+
set(key, value, ttlMs, collections, versions) {
|
|
932
954
|
this.sets++;
|
|
933
955
|
const ttl = ttlMs ?? this.ttlMs;
|
|
934
956
|
const expiresAt = ttl > 0 ? Date.now() + ttl : Infinity;
|
|
935
|
-
this.lru.set(key, { value, expiresAt });
|
|
957
|
+
this.lru.set(key, { value, expiresAt, versions });
|
|
936
958
|
const sep = key.indexOf(SEP);
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
keys =
|
|
941
|
-
|
|
959
|
+
const primary = sep === -1 ? key : key.slice(0, sep);
|
|
960
|
+
const collectionKeys = /* @__PURE__ */ new Set([primary, ...collections ?? []]);
|
|
961
|
+
for (const collection of collectionKeys) {
|
|
962
|
+
let keys = this.index.get(collection);
|
|
963
|
+
if (!keys) {
|
|
964
|
+
keys = /* @__PURE__ */ new Set();
|
|
965
|
+
this.index.set(collection, keys);
|
|
966
|
+
}
|
|
967
|
+
keys.add(key);
|
|
942
968
|
}
|
|
943
|
-
keys.add(key);
|
|
944
969
|
}
|
|
945
970
|
delete(key) {
|
|
946
971
|
this.deletes++;
|
|
@@ -948,6 +973,7 @@ var QueryCache = class {
|
|
|
948
973
|
}
|
|
949
974
|
/** Drop every cached entry belonging to a physical collection. */
|
|
950
975
|
invalidateByCollection(collection) {
|
|
976
|
+
this.colVersions.set(collection, (this.colVersions.get(collection) ?? 0) + 1);
|
|
951
977
|
const keys = this.index.get(collection);
|
|
952
978
|
if (!keys) return;
|
|
953
979
|
this.invalidateEvents++;
|
|
@@ -956,6 +982,9 @@ var QueryCache = class {
|
|
|
956
982
|
}
|
|
957
983
|
clear() {
|
|
958
984
|
this.clearEvents++;
|
|
985
|
+
for (const collection of this.index.keys()) {
|
|
986
|
+
this.colVersions.set(collection, (this.colVersions.get(collection) ?? 0) + 1);
|
|
987
|
+
}
|
|
959
988
|
this.lru.clear();
|
|
960
989
|
this.index.clear();
|
|
961
990
|
}
|
|
@@ -2664,28 +2693,48 @@ var PipelineBuilder = class _PipelineBuilder {
|
|
|
2664
2693
|
/* ------------------------------ terminals ---------------------------- */
|
|
2665
2694
|
/** Run the pipeline and return every output document. */
|
|
2666
2695
|
toArray() {
|
|
2696
|
+
const run = (r) => this.deps.coll().aggregate(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk)).toArray();
|
|
2697
|
+
if (this.deps.cachedAggregate) {
|
|
2698
|
+
return this.deps.cachedAggregate({
|
|
2699
|
+
collection: this.deps.logical,
|
|
2700
|
+
opName: "mongo.pipeline",
|
|
2701
|
+
pipeline: this.stages,
|
|
2702
|
+
options: this.deps.options,
|
|
2703
|
+
execute: run
|
|
2704
|
+
});
|
|
2705
|
+
}
|
|
2667
2706
|
return defineCrudOp(
|
|
2668
2707
|
this.deps.crudDeps,
|
|
2669
2708
|
this.deps.logical,
|
|
2670
2709
|
"mongo.pipeline",
|
|
2671
|
-
|
|
2710
|
+
run,
|
|
2672
2711
|
this.deps.options
|
|
2673
2712
|
);
|
|
2674
2713
|
}
|
|
2675
2714
|
/** Run the pipeline and return the first output document (or null). */
|
|
2676
2715
|
async first() {
|
|
2716
|
+
const run = async (r) => {
|
|
2717
|
+
const cursor = this.deps.coll().aggregate(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk));
|
|
2718
|
+
try {
|
|
2719
|
+
return await cursor.tryNext();
|
|
2720
|
+
} finally {
|
|
2721
|
+
await cursor.close();
|
|
2722
|
+
}
|
|
2723
|
+
};
|
|
2724
|
+
if (this.deps.cachedAggregate) {
|
|
2725
|
+
return this.deps.cachedAggregate({
|
|
2726
|
+
collection: this.deps.logical,
|
|
2727
|
+
opName: "mongo.pipeline.first",
|
|
2728
|
+
pipeline: this.stages,
|
|
2729
|
+
options: this.deps.options,
|
|
2730
|
+
execute: run
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2677
2733
|
return defineCrudOp(
|
|
2678
2734
|
this.deps.crudDeps,
|
|
2679
2735
|
this.deps.logical,
|
|
2680
|
-
"mongo.pipeline",
|
|
2681
|
-
|
|
2682
|
-
const cursor = this.deps.coll().aggregate(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk));
|
|
2683
|
-
try {
|
|
2684
|
-
return await cursor.tryNext();
|
|
2685
|
-
} finally {
|
|
2686
|
-
await cursor.close();
|
|
2687
|
-
}
|
|
2688
|
-
},
|
|
2736
|
+
"mongo.pipeline.first",
|
|
2737
|
+
run,
|
|
2689
2738
|
this.deps.options
|
|
2690
2739
|
);
|
|
2691
2740
|
}
|
|
@@ -2797,7 +2846,7 @@ var buildAggregationStages = () => {
|
|
|
2797
2846
|
|
|
2798
2847
|
// src/service/aggregation/aggregate.ts
|
|
2799
2848
|
var makeAggregateOps = (ctx) => {
|
|
2800
|
-
const { deps: deps2, coll, mergeAggOptions: mergeAggOptions2 } = ctx;
|
|
2849
|
+
const { deps: deps2, coll, mergeAggOptions: mergeAggOptions2, cachedAggregate } = ctx;
|
|
2801
2850
|
const aggregate = async (collection, pipelineBuilder, options) => {
|
|
2802
2851
|
const stages = buildAggregationStages();
|
|
2803
2852
|
const pipeline2 = pipelineBuilder(stages);
|
|
@@ -2814,7 +2863,8 @@ var makeAggregateOps = (ctx) => {
|
|
|
2814
2863
|
coll: () => coll(collection),
|
|
2815
2864
|
crudDeps: deps2,
|
|
2816
2865
|
mergeDriver: mergeAggOptions2,
|
|
2817
|
-
options
|
|
2866
|
+
options,
|
|
2867
|
+
cachedAggregate
|
|
2818
2868
|
});
|
|
2819
2869
|
return { aggregate, pipeline };
|
|
2820
2870
|
};
|
|
@@ -2834,10 +2884,103 @@ var DATE_PART_FORMATS = {
|
|
|
2834
2884
|
month: "%Y-%m",
|
|
2835
2885
|
year: "%Y"
|
|
2836
2886
|
};
|
|
2887
|
+
var collectAggSources = (primaryLogical, pipeline, extraLogical = []) => {
|
|
2888
|
+
const sources = /* @__PURE__ */ new Set([primaryLogical, ...extraLogical]);
|
|
2889
|
+
const visit = (stages) => {
|
|
2890
|
+
if (!Array.isArray(stages)) return;
|
|
2891
|
+
for (const stage of stages) {
|
|
2892
|
+
if (!stage || typeof stage !== "object") continue;
|
|
2893
|
+
const s2 = stage;
|
|
2894
|
+
const lookup = s2.$lookup;
|
|
2895
|
+
if (lookup && typeof lookup === "object") {
|
|
2896
|
+
if (typeof lookup.from === "string") sources.add(lookup.from);
|
|
2897
|
+
if (Array.isArray(lookup.pipeline)) visit(lookup.pipeline);
|
|
2898
|
+
}
|
|
2899
|
+
const union = s2.$unionWith;
|
|
2900
|
+
if (union && typeof union === "object") {
|
|
2901
|
+
if (typeof union.coll === "string") sources.add(union.coll);
|
|
2902
|
+
if (Array.isArray(union.pipeline)) visit(union.pipeline);
|
|
2903
|
+
}
|
|
2904
|
+
const facet = s2.$facet;
|
|
2905
|
+
if (facet && typeof facet === "object") {
|
|
2906
|
+
for (const branch of Object.values(facet)) visit(branch);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
};
|
|
2910
|
+
visit(pipeline);
|
|
2911
|
+
return [...sources];
|
|
2912
|
+
};
|
|
2913
|
+
var isCacheablePipeline = (pipeline) => {
|
|
2914
|
+
for (const stage of pipeline) {
|
|
2915
|
+
if (!stage || typeof stage !== "object") continue;
|
|
2916
|
+
if ("$out" in stage || "$merge" in stage || "$sample" in stage) return false;
|
|
2917
|
+
const s2 = stage;
|
|
2918
|
+
const lookup = s2.$lookup;
|
|
2919
|
+
if (lookup && Array.isArray(lookup.pipeline) && !isCacheablePipeline(lookup.pipeline)) {
|
|
2920
|
+
return false;
|
|
2921
|
+
}
|
|
2922
|
+
const facet = s2.$facet;
|
|
2923
|
+
if (facet && typeof facet === "object") {
|
|
2924
|
+
for (const branch of Object.values(facet)) {
|
|
2925
|
+
if (Array.isArray(branch) && !isCacheablePipeline(branch)) return false;
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
return true;
|
|
2930
|
+
};
|
|
2931
|
+
|
|
2932
|
+
// src/service/aggregation/cached-read.ts
|
|
2933
|
+
var createCachedAggregate = (ctx) => {
|
|
2934
|
+
const { client, deps: deps2, opts, resolve } = ctx;
|
|
2935
|
+
const cache = opts.cache;
|
|
2936
|
+
return async (input) => {
|
|
2937
|
+
const { collection: collectionName, opName, pipeline, options, sources = [], execute } = input;
|
|
2938
|
+
const collection = collectionName;
|
|
2939
|
+
const physical = resolve(String(collection));
|
|
2940
|
+
const resolved = resolveQueryOptions(options);
|
|
2941
|
+
const noSession = !resolved.sdk.session;
|
|
2942
|
+
const useCache = cache !== void 0 && noSession && resolved.cache !== false && isCacheablePipeline(pipeline);
|
|
2943
|
+
const shouldDedupe = resolved.dedupe !== false && (resolved.dedupe === true || opts.dedupeReads === true && noSession) && opts.inFlight !== void 0;
|
|
2944
|
+
const runDriver = () => defineCrudOp(deps2, collection, opName, execute, options);
|
|
2945
|
+
const key = useCache ? cache.key(
|
|
2946
|
+
cacheCollectionKey(client.databaseName, physical),
|
|
2947
|
+
stableHash([opName, pipeline, options])
|
|
2948
|
+
) : void 0;
|
|
2949
|
+
const toSourceKeys = () => collectAggSources(String(collection), pipeline, sources).map((name) => {
|
|
2950
|
+
try {
|
|
2951
|
+
return cacheCollectionKey(client.databaseName, resolve(name));
|
|
2952
|
+
} catch {
|
|
2953
|
+
return cacheCollectionKey(client.databaseName, name);
|
|
2954
|
+
}
|
|
2955
|
+
});
|
|
2956
|
+
const runOnce = () => {
|
|
2957
|
+
if (useCache && key) {
|
|
2958
|
+
const sourceKeys = toSourceKeys();
|
|
2959
|
+
const primaryKey = cacheCollectionKey(client.databaseName, physical);
|
|
2960
|
+
const versions = { [primaryKey]: cache.versionOf(primaryKey) };
|
|
2961
|
+
for (const col of sourceKeys) {
|
|
2962
|
+
if (!(col in versions)) versions[col] = cache.versionOf(col);
|
|
2963
|
+
}
|
|
2964
|
+
const hit = cache.get(key);
|
|
2965
|
+
if (hit !== void 0) return Promise.resolve(hit);
|
|
2966
|
+
return runDriver().then((value) => {
|
|
2967
|
+
cache.set(key, value, void 0, sourceKeys, versions);
|
|
2968
|
+
return value;
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2971
|
+
return runDriver();
|
|
2972
|
+
};
|
|
2973
|
+
if (shouldDedupe) {
|
|
2974
|
+
const dedupeKey = `${cacheCollectionKey(client.databaseName, physical)}|${opName}|${stableHash([pipeline, options])}`;
|
|
2975
|
+
return opts.inFlight.run(dedupeKey, runOnce);
|
|
2976
|
+
}
|
|
2977
|
+
return runOnce();
|
|
2978
|
+
};
|
|
2979
|
+
};
|
|
2837
2980
|
|
|
2838
2981
|
// src/service/aggregation/group.ts
|
|
2839
2982
|
var makeGroupOps = (ctx) => {
|
|
2840
|
-
const {
|
|
2983
|
+
const { coll, mergeAggOptions: mergeAggOptions2, cachedAggregate } = ctx;
|
|
2841
2984
|
const groupBy = async (collection, baseFilter, config, customization = {}, options) => {
|
|
2842
2985
|
if (config.limit !== void 0 && (!Number.isFinite(config.limit) || config.limit < 0)) {
|
|
2843
2986
|
throw new BadRequest("groupBy: `limit` must be a non-negative finite number");
|
|
@@ -2850,13 +2993,13 @@ var makeGroupOps = (ctx) => {
|
|
|
2850
2993
|
...config.limit !== void 0 ? [{ $limit: config.limit }] : [],
|
|
2851
2994
|
...customization.postPipeline ?? []
|
|
2852
2995
|
];
|
|
2853
|
-
return
|
|
2854
|
-
deps2,
|
|
2996
|
+
return cachedAggregate({
|
|
2855
2997
|
collection,
|
|
2856
|
-
"mongo.groupBy",
|
|
2857
|
-
|
|
2858
|
-
options
|
|
2859
|
-
|
|
2998
|
+
opName: "mongo.groupBy",
|
|
2999
|
+
pipeline,
|
|
3000
|
+
options,
|
|
3001
|
+
execute: (r) => coll(collection).aggregate(pipeline, mergeAggOptions2(r.driverOpts, r.sdk)).toArray()
|
|
3002
|
+
});
|
|
2860
3003
|
};
|
|
2861
3004
|
const dateRangeAnalysis = async (collection, baseFilter, dateConfig, analysisConfig = {}, customization = {}, options) => {
|
|
2862
3005
|
if (analysisConfig.limit !== void 0 && (!Number.isFinite(analysisConfig.limit) || analysisConfig.limit < 0)) {
|
|
@@ -2880,20 +3023,20 @@ var makeGroupOps = (ctx) => {
|
|
|
2880
3023
|
...analysisConfig.limit !== void 0 ? [{ $limit: analysisConfig.limit }] : [],
|
|
2881
3024
|
...customization.postPipeline ?? []
|
|
2882
3025
|
];
|
|
2883
|
-
return
|
|
2884
|
-
deps2,
|
|
3026
|
+
return cachedAggregate({
|
|
2885
3027
|
collection,
|
|
2886
|
-
"mongo.dateRangeAnalysis",
|
|
2887
|
-
|
|
2888
|
-
options
|
|
2889
|
-
|
|
3028
|
+
opName: "mongo.dateRangeAnalysis",
|
|
3029
|
+
pipeline,
|
|
3030
|
+
options,
|
|
3031
|
+
execute: (r) => coll(collection).aggregate(pipeline, mergeAggOptions2(r.driverOpts, r.sdk)).toArray()
|
|
3032
|
+
});
|
|
2890
3033
|
};
|
|
2891
3034
|
return { groupBy, dateRangeAnalysis };
|
|
2892
3035
|
};
|
|
2893
3036
|
|
|
2894
3037
|
// src/service/aggregation/lookup-join.ts
|
|
2895
3038
|
var makeLookupJoinOp = (ctx) => {
|
|
2896
|
-
const {
|
|
3039
|
+
const { coll, mergeAggOptions: mergeAggOptions2, resolve, cachedAggregate } = ctx;
|
|
2897
3040
|
const lookupJoin = async (collection, baseFilter, lookups, customization = {}, options) => {
|
|
2898
3041
|
const pipeline = [
|
|
2899
3042
|
...customization.prePipeline ?? [],
|
|
@@ -2912,13 +3055,15 @@ var makeLookupJoinOp = (ctx) => {
|
|
|
2912
3055
|
})),
|
|
2913
3056
|
...customization.postPipeline ?? []
|
|
2914
3057
|
];
|
|
2915
|
-
return
|
|
2916
|
-
deps2,
|
|
3058
|
+
return cachedAggregate({
|
|
2917
3059
|
collection,
|
|
2918
|
-
"mongo.lookupJoin",
|
|
2919
|
-
|
|
2920
|
-
options
|
|
2921
|
-
|
|
3060
|
+
opName: "mongo.lookupJoin",
|
|
3061
|
+
pipeline,
|
|
3062
|
+
options,
|
|
3063
|
+
// Writes to any joined collection must invalidate the cached join.
|
|
3064
|
+
sources: lookups.map((l) => l.fromCollection),
|
|
3065
|
+
execute: (r) => coll(collection).aggregate(pipeline, mergeAggOptions2(r.driverOpts, r.sdk)).toArray()
|
|
3066
|
+
});
|
|
2922
3067
|
};
|
|
2923
3068
|
return { lookupJoin };
|
|
2924
3069
|
};
|
|
@@ -2985,7 +3130,7 @@ var buildSearchStages = (baseFilter, searchConfig) => searchConfig.useRegex ? bu
|
|
|
2985
3130
|
|
|
2986
3131
|
// src/service/aggregation/text-search.ts
|
|
2987
3132
|
var makeTextSearchOp = (ctx) => {
|
|
2988
|
-
const {
|
|
3133
|
+
const { coll, mergeAggOptions: mergeAggOptions2, cachedAggregate } = ctx;
|
|
2989
3134
|
const textSearch = async (collection, baseFilter, searchConfig, paginationConfig = {}, customization = {}, options) => {
|
|
2990
3135
|
const normalized = normalizePageLimit(
|
|
2991
3136
|
{ page: paginationConfig.page, limit: paginationConfig.limit },
|
|
@@ -3011,19 +3156,19 @@ var makeTextSearchOp = (ctx) => {
|
|
|
3011
3156
|
}
|
|
3012
3157
|
}
|
|
3013
3158
|
];
|
|
3014
|
-
return
|
|
3015
|
-
deps2,
|
|
3159
|
+
return cachedAggregate({
|
|
3016
3160
|
collection,
|
|
3017
|
-
"mongo.textSearch",
|
|
3018
|
-
|
|
3161
|
+
opName: "mongo.textSearch",
|
|
3162
|
+
pipeline,
|
|
3163
|
+
options,
|
|
3164
|
+
execute: async (r) => {
|
|
3019
3165
|
const rows = await coll(collection).aggregate(pipeline, mergeAggOptions2(r.driverOpts, r.sdk)).toArray();
|
|
3020
3166
|
const row = rows[0];
|
|
3021
3167
|
const data = row?.data ?? [];
|
|
3022
3168
|
const totalCount = row?.totalCount?.[0]?.count ?? 0;
|
|
3023
3169
|
return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);
|
|
3024
|
-
}
|
|
3025
|
-
|
|
3026
|
-
);
|
|
3170
|
+
}
|
|
3171
|
+
});
|
|
3027
3172
|
};
|
|
3028
3173
|
return { textSearch };
|
|
3029
3174
|
};
|
|
@@ -3037,7 +3182,8 @@ var makeAggregationOps = (client, dbLabel, logger, opts) => {
|
|
|
3037
3182
|
resolve,
|
|
3038
3183
|
deps: deps2,
|
|
3039
3184
|
coll,
|
|
3040
|
-
mergeAggOptions
|
|
3185
|
+
mergeAggOptions,
|
|
3186
|
+
cachedAggregate: createCachedAggregate({ client, deps: deps2, opts, resolve })
|
|
3041
3187
|
};
|
|
3042
3188
|
return {
|
|
3043
3189
|
...makeAggregateOps(ctx),
|
|
@@ -3155,10 +3301,12 @@ var createCrudContext = (client, dbLabel, logger, opts) => {
|
|
|
3155
3301
|
});
|
|
3156
3302
|
const runOnce = () => {
|
|
3157
3303
|
if (useCache && key) {
|
|
3304
|
+
const colKey = cacheCollectionKey(client.databaseName, physical);
|
|
3305
|
+
const versions = { [colKey]: opts.cache.versionOf(colKey) };
|
|
3158
3306
|
const hit = opts.cache.get(key);
|
|
3159
3307
|
if (hit !== void 0) return Promise.resolve(hit);
|
|
3160
3308
|
return fetchAndCheck().then((value) => {
|
|
3161
|
-
opts.cache.set(key, value);
|
|
3309
|
+
opts.cache.set(key, value, void 0, void 0, versions);
|
|
3162
3310
|
return value;
|
|
3163
3311
|
});
|
|
3164
3312
|
}
|
|
@@ -3930,7 +4078,7 @@ var makePaginateCursor = (ctx) => {
|
|
|
3930
4078
|
|
|
3931
4079
|
// src/service/pagination/offset.ts
|
|
3932
4080
|
var makePaginateFlexible = (ctx) => {
|
|
3933
|
-
const { client, dbLabel, logger, opts, resolve,
|
|
4081
|
+
const { client, dbLabel, logger, opts, resolve, cachedAggregate } = ctx;
|
|
3934
4082
|
const paginateFlexible = async (collection, baseFilter, config = {}) => {
|
|
3935
4083
|
const normalized = normalizePageLimit(
|
|
3936
4084
|
{ page: config.page, limit: config.limit },
|
|
@@ -3952,11 +4100,12 @@ var makePaginateFlexible = (ctx) => {
|
|
|
3952
4100
|
}
|
|
3953
4101
|
}
|
|
3954
4102
|
];
|
|
3955
|
-
return
|
|
3956
|
-
deps2,
|
|
4103
|
+
return cachedAggregate({
|
|
3957
4104
|
collection,
|
|
3958
|
-
"mongo.paginateFlexible",
|
|
3959
|
-
|
|
4105
|
+
opName: "mongo.paginateFlexible",
|
|
4106
|
+
pipeline,
|
|
4107
|
+
options: config.queryOptions,
|
|
4108
|
+
execute: async (r) => {
|
|
3960
4109
|
const aggOptions = {
|
|
3961
4110
|
...r.driverOpts,
|
|
3962
4111
|
session: r.sdk.session,
|
|
@@ -3980,9 +4129,8 @@ var makePaginateFlexible = (ctx) => {
|
|
|
3980
4129
|
data
|
|
3981
4130
|
);
|
|
3982
4131
|
return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);
|
|
3983
|
-
}
|
|
3984
|
-
|
|
3985
|
-
);
|
|
4132
|
+
}
|
|
4133
|
+
});
|
|
3986
4134
|
};
|
|
3987
4135
|
return { paginateFlexible };
|
|
3988
4136
|
};
|
|
@@ -3997,7 +4145,8 @@ var makePaginationOps = (client, dbLabel, logger, opts) => {
|
|
|
3997
4145
|
logger,
|
|
3998
4146
|
opts,
|
|
3999
4147
|
resolve,
|
|
4000
|
-
deps: deps2
|
|
4148
|
+
deps: deps2,
|
|
4149
|
+
cachedAggregate: createCachedAggregate({ client, deps: deps2, opts, resolve })
|
|
4001
4150
|
};
|
|
4002
4151
|
return {
|
|
4003
4152
|
...makePaginateFlexible(ctx),
|
|
@@ -4186,11 +4335,17 @@ var buildManager = (deps2, dbKey, dbName, client) => {
|
|
|
4186
4335
|
resolveCollectionName,
|
|
4187
4336
|
wrapMongoErrors: deps2.wrapMongoErrors,
|
|
4188
4337
|
drift: deps2.drift,
|
|
4189
|
-
getSchema: (logical) => getDefinition(logical)?.schema
|
|
4338
|
+
getSchema: (logical) => getDefinition(logical)?.schema,
|
|
4339
|
+
cache: sharedCache,
|
|
4340
|
+
dedupeReads,
|
|
4341
|
+
inFlight
|
|
4190
4342
|
});
|
|
4191
4343
|
const aggregation = makeAggregationOps(handle, dbName, logger, {
|
|
4192
4344
|
resolveCollectionName,
|
|
4193
|
-
wrapMongoErrors: deps2.wrapMongoErrors
|
|
4345
|
+
wrapMongoErrors: deps2.wrapMongoErrors,
|
|
4346
|
+
cache: sharedCache,
|
|
4347
|
+
dedupeReads,
|
|
4348
|
+
inFlight
|
|
4194
4349
|
});
|
|
4195
4350
|
const schema = makeSchemaOps(handle, logger, { resolveCollectionName, getDefinition });
|
|
4196
4351
|
const transactionOps = makeTransactionOps(client, handle, logger, config, {
|