monsqlize 2.0.0 → 2.0.1
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/CHANGELOG.md +460 -458
- package/README.md +7 -2
- package/changelogs/README.md +141 -138
- package/changelogs/v2.0.0.md +164 -164
- package/changelogs/v2.0.1.md +39 -0
- package/dist/cjs/index.cjs +329 -141
- package/dist/esm/index.mjs +329 -141
- package/dist/types/base.d.ts +81 -81
- package/dist/types/collection.d.ts +973 -973
- package/dist/types/expression.d.ts +115 -115
- package/dist/types/index.d.ts +23 -23
- package/dist/types/model.d.ts +489 -485
- package/dist/types/mongodb.d.ts +49 -49
- package/dist/types/monsqlize.d.ts +429 -429
- package/dist/types/pool.d.ts +84 -84
- package/dist/types/runtime.d.ts +315 -315
- package/dist/types/saga.d.ts +121 -121
- package/dist/types/slow-query-log.d.ts +126 -126
- package/dist/types/sync.d.ts +103 -103
- package/package.json +100 -99
package/dist/esm/index.mjs
CHANGED
|
@@ -688,6 +688,13 @@ function serializeDocument(document) {
|
|
|
688
688
|
}
|
|
689
689
|
|
|
690
690
|
// src/capabilities/model/model-instance-helpers.ts
|
|
691
|
+
function resolveRegisteredCollectionName(registered, fallback) {
|
|
692
|
+
if (!registered) {
|
|
693
|
+
return fallback;
|
|
694
|
+
}
|
|
695
|
+
const definition = registered.definition;
|
|
696
|
+
return definition.collection ?? definition.name ?? registered.collectionName;
|
|
697
|
+
}
|
|
691
698
|
async function populateModelPath(context, docs, path2) {
|
|
692
699
|
const config = normalizePopulateConfig(path2);
|
|
693
700
|
if (docs.length === 0) {
|
|
@@ -711,7 +718,8 @@ async function populateModelPath(context, docs, path2) {
|
|
|
711
718
|
database: registered?.definition.connection?.database ?? context.dbName,
|
|
712
719
|
pool: registered?.definition.connection?.pool ?? context.poolName
|
|
713
720
|
};
|
|
714
|
-
const
|
|
721
|
+
const relatedCollectionName = resolveRegisteredCollectionName(registered, relation.from);
|
|
722
|
+
const relatedCollection = context.runtime.scopedCollection(relatedCollectionName, scope);
|
|
715
723
|
const relatedModel = Model.has(relation.from) ? context.runtime.scopedModel(relation.from, scope) : null;
|
|
716
724
|
const relatedDocs = await relatedCollection.find({
|
|
717
725
|
[relation.foreignField]: { $in: keys },
|
|
@@ -954,9 +962,85 @@ function forceDeleteManyDocuments(context, filter, options) {
|
|
|
954
962
|
}
|
|
955
963
|
|
|
956
964
|
// src/capabilities/model/model-instance-config.ts
|
|
965
|
+
var runtimeModelIndexTasks = /* @__PURE__ */ new WeakMap();
|
|
966
|
+
var fallbackModelIndexTasks = /* @__PURE__ */ new Map();
|
|
957
967
|
function toCompatDefinition(definition) {
|
|
958
968
|
return definition;
|
|
959
969
|
}
|
|
970
|
+
function stableIndexStringify(value) {
|
|
971
|
+
if (value instanceof Date) {
|
|
972
|
+
return JSON.stringify(value.toISOString());
|
|
973
|
+
}
|
|
974
|
+
if (Array.isArray(value)) {
|
|
975
|
+
return `[${value.map((item) => stableIndexStringify(item)).join(",")}]`;
|
|
976
|
+
}
|
|
977
|
+
if (value && typeof value === "object") {
|
|
978
|
+
const entries = Object.entries(value).filter(([, current]) => current !== void 0).sort(([left], [right]) => left.localeCompare(right));
|
|
979
|
+
return `{${entries.map(([key, current]) => `${JSON.stringify(key)}:${stableIndexStringify(current)}`).join(",")}}`;
|
|
980
|
+
}
|
|
981
|
+
return JSON.stringify(value) ?? "undefined";
|
|
982
|
+
}
|
|
983
|
+
function getIndexTaskRegistry(runtime) {
|
|
984
|
+
if (!runtime) {
|
|
985
|
+
return fallbackModelIndexTasks;
|
|
986
|
+
}
|
|
987
|
+
let registry = runtimeModelIndexTasks.get(runtime);
|
|
988
|
+
if (!registry) {
|
|
989
|
+
registry = /* @__PURE__ */ new Map();
|
|
990
|
+
runtimeModelIndexTasks.set(runtime, registry);
|
|
991
|
+
}
|
|
992
|
+
return registry;
|
|
993
|
+
}
|
|
994
|
+
function resolveIndexTaskScope(collection, options) {
|
|
995
|
+
try {
|
|
996
|
+
const namespace = collection.getNamespace();
|
|
997
|
+
return {
|
|
998
|
+
dbName: options?.dbName ?? namespace.db,
|
|
999
|
+
poolName: options?.poolName ?? "default",
|
|
1000
|
+
collectionName: options?.collectionName ?? namespace.collection
|
|
1001
|
+
};
|
|
1002
|
+
} catch {
|
|
1003
|
+
return {
|
|
1004
|
+
dbName: options?.dbName ?? "default",
|
|
1005
|
+
poolName: options?.poolName ?? "default",
|
|
1006
|
+
collectionName: options?.collectionName ?? "unknown"
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
function warnIndexFailure(runtime, taskKey, error) {
|
|
1011
|
+
const logger = runtime;
|
|
1012
|
+
logger?.logger?.warn?.("[MonSQLize] model index creation failed", {
|
|
1013
|
+
taskKey,
|
|
1014
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
function scheduleIndexTask(collection, key, indexOptions, options) {
|
|
1018
|
+
const scope = resolveIndexTaskScope(collection, options);
|
|
1019
|
+
const indexFingerprint = stableIndexStringify({ key, options: indexOptions });
|
|
1020
|
+
const taskKey = `${scope.poolName}:${scope.dbName}:${scope.collectionName}:${indexFingerprint}`;
|
|
1021
|
+
const registry = getIndexTaskRegistry(options?.runtime);
|
|
1022
|
+
const existing = registry.get(taskKey);
|
|
1023
|
+
if (existing && existing.status !== "failed") {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
const task = {
|
|
1027
|
+
status: "pending",
|
|
1028
|
+
promise: new Promise((resolve) => {
|
|
1029
|
+
setImmediate(() => {
|
|
1030
|
+
Promise.resolve().then(() => collection.createIndex(key, indexOptions)).then(() => {
|
|
1031
|
+
task.status = "fulfilled";
|
|
1032
|
+
resolve();
|
|
1033
|
+
}).catch((error) => {
|
|
1034
|
+
task.status = "failed";
|
|
1035
|
+
task.error = error;
|
|
1036
|
+
warnIndexFailure(options?.runtime, taskKey, error);
|
|
1037
|
+
resolve();
|
|
1038
|
+
});
|
|
1039
|
+
});
|
|
1040
|
+
})
|
|
1041
|
+
};
|
|
1042
|
+
registry.set(taskKey, task);
|
|
1043
|
+
}
|
|
960
1044
|
function getModelEnums(definition) {
|
|
961
1045
|
return toCompatDefinition(definition).enums ?? {};
|
|
962
1046
|
}
|
|
@@ -1089,31 +1173,27 @@ function initializeModelV1Methods(target, definition) {
|
|
|
1089
1173
|
return {};
|
|
1090
1174
|
}
|
|
1091
1175
|
}
|
|
1092
|
-
function scheduleModelIndexes(collection, definition, softDeleteConfig) {
|
|
1176
|
+
function scheduleModelIndexes(collection, definition, softDeleteConfig, options) {
|
|
1093
1177
|
if (softDeleteConfig?.enabled && softDeleteConfig.type === "timestamp" && softDeleteConfig.ttl) {
|
|
1094
1178
|
const softDeleteIndex = softDeleteConfig;
|
|
1095
|
-
|
|
1096
|
-
collection
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
});
|
|
1179
|
+
scheduleIndexTask(
|
|
1180
|
+
collection,
|
|
1181
|
+
{ [softDeleteIndex.field]: 1 },
|
|
1182
|
+
{ expireAfterSeconds: softDeleteIndex.ttl },
|
|
1183
|
+
options
|
|
1184
|
+
);
|
|
1102
1185
|
}
|
|
1103
1186
|
const indexes = toCompatDefinition(definition).indexes;
|
|
1104
1187
|
if (!Array.isArray(indexes) || indexes.length === 0) {
|
|
1105
1188
|
return;
|
|
1106
1189
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
continue;
|
|
1111
|
-
}
|
|
1112
|
-
const { key, ...indexOptions } = indexSpec;
|
|
1113
|
-
collection.createIndex(key, indexOptions).catch(() => {
|
|
1114
|
-
});
|
|
1190
|
+
for (const indexSpec of indexes) {
|
|
1191
|
+
if (!indexSpec?.key) {
|
|
1192
|
+
continue;
|
|
1115
1193
|
}
|
|
1116
|
-
|
|
1194
|
+
const { key, ...indexOptions } = indexSpec;
|
|
1195
|
+
scheduleIndexTask(collection, key, indexOptions, options);
|
|
1196
|
+
}
|
|
1117
1197
|
}
|
|
1118
1198
|
|
|
1119
1199
|
// src/capabilities/model/model-write-helpers.ts
|
|
@@ -1676,7 +1756,12 @@ var ModelInstance = class {
|
|
|
1676
1756
|
this.softDeleteConfig = this._softDeleteConfig;
|
|
1677
1757
|
this._versionConfig = resolveModelVersionConfig(options.definition);
|
|
1678
1758
|
this._v1HooksFactory = resolveModelHooksFactory(options.definition);
|
|
1679
|
-
scheduleModelIndexes(this.collection, options.definition, this._softDeleteConfig
|
|
1759
|
+
scheduleModelIndexes(this.collection, options.definition, this._softDeleteConfig, {
|
|
1760
|
+
runtime: this.runtime,
|
|
1761
|
+
dbName: options.dbName,
|
|
1762
|
+
poolName: options.poolName,
|
|
1763
|
+
collectionName: options.collectionName
|
|
1764
|
+
});
|
|
1680
1765
|
this._v1InstanceMethods = initializeModelV1Methods(this, options.definition);
|
|
1681
1766
|
}
|
|
1682
1767
|
/** v1 compat: expose relations map as _relations */
|
|
@@ -3096,10 +3181,19 @@ var HealthChecker = class {
|
|
|
3096
3181
|
};
|
|
3097
3182
|
|
|
3098
3183
|
// src/capabilities/pool/pool-selector.ts
|
|
3184
|
+
var POOL_STRATEGY_ALIASES = {
|
|
3185
|
+
"round-robin": "roundRobin",
|
|
3186
|
+
"least-connections": "leastConnections",
|
|
3187
|
+
random: "weighted"
|
|
3188
|
+
};
|
|
3189
|
+
function normalizePoolStrategy(strategy) {
|
|
3190
|
+
const value = strategy ?? "auto";
|
|
3191
|
+
return POOL_STRATEGY_ALIASES[value] ?? value;
|
|
3192
|
+
}
|
|
3099
3193
|
var PoolSelector = class {
|
|
3100
3194
|
constructor(options = {}) {
|
|
3101
3195
|
this._roundRobinIndex = /* @__PURE__ */ new Map();
|
|
3102
|
-
this._strategy = options.strategy
|
|
3196
|
+
this._strategy = normalizePoolStrategy(options.strategy);
|
|
3103
3197
|
this._logger = options.logger ?? console;
|
|
3104
3198
|
}
|
|
3105
3199
|
select(pools, context) {
|
|
@@ -3212,8 +3306,8 @@ var PoolSelector = class {
|
|
|
3212
3306
|
return pools[0].name;
|
|
3213
3307
|
}
|
|
3214
3308
|
setStrategy(strategy) {
|
|
3215
|
-
this._strategy = strategy;
|
|
3216
|
-
this._logger.info?.(`[PoolSelector] Strategy changed: ${
|
|
3309
|
+
this._strategy = normalizePoolStrategy(strategy);
|
|
3310
|
+
this._logger.info?.(`[PoolSelector] Strategy changed: ${this._strategy}`);
|
|
3217
3311
|
}
|
|
3218
3312
|
getStrategy() {
|
|
3219
3313
|
return this._strategy;
|
|
@@ -7407,6 +7501,92 @@ function createRuntimeAccessors(config) {
|
|
|
7407
7501
|
};
|
|
7408
7502
|
}
|
|
7409
7503
|
|
|
7504
|
+
// src/entry/runtime-compat-accessors.ts
|
|
7505
|
+
function asRuntimeCompatRecord(value) {
|
|
7506
|
+
return value;
|
|
7507
|
+
}
|
|
7508
|
+
function requireCompatDbInstance(value) {
|
|
7509
|
+
const dbInstance = asRuntimeCompatRecord(value).dbInstance;
|
|
7510
|
+
if (!dbInstance) {
|
|
7511
|
+
throw createError(ErrorCodes.NOT_CONNECTED, "Database is not connected. Call connect() first.");
|
|
7512
|
+
}
|
|
7513
|
+
return dbInstance;
|
|
7514
|
+
}
|
|
7515
|
+
function requireCompatPoolManagerRecord(value) {
|
|
7516
|
+
const poolManager = asRuntimeCompatRecord(value)._poolManager;
|
|
7517
|
+
if (!poolManager) {
|
|
7518
|
+
throw createError(ErrorCodes.NO_POOL_MANAGER, "No pool manager configured. Add pools to MonSQLize constructor options.");
|
|
7519
|
+
}
|
|
7520
|
+
return poolManager;
|
|
7521
|
+
}
|
|
7522
|
+
function resolvePoolClientFromRecord(poolManager, poolName) {
|
|
7523
|
+
const getPoolV1 = poolManager["_getPool"];
|
|
7524
|
+
const getPoolV2 = poolManager["getPool"];
|
|
7525
|
+
if (typeof getPoolV1 === "function") {
|
|
7526
|
+
return getPoolV1.call(poolManager, poolName) ?? null;
|
|
7527
|
+
}
|
|
7528
|
+
if (typeof getPoolV2 === "function") {
|
|
7529
|
+
try {
|
|
7530
|
+
return getPoolV2.call(poolManager, poolName) ?? null;
|
|
7531
|
+
} catch {
|
|
7532
|
+
return null;
|
|
7533
|
+
}
|
|
7534
|
+
}
|
|
7535
|
+
return null;
|
|
7536
|
+
}
|
|
7537
|
+
function assertCompatPoolExists(poolManager, poolName) {
|
|
7538
|
+
if (resolvePoolClientFromRecord(poolManager, poolName)) {
|
|
7539
|
+
return;
|
|
7540
|
+
}
|
|
7541
|
+
const getNames = poolManager["getPoolNames"];
|
|
7542
|
+
const available = typeof getNames === "function" ? getNames.call(poolManager) : [];
|
|
7543
|
+
const error = createError(ErrorCodes.POOL_NOT_FOUND, `Pool '${poolName}' not found. Available pools: [${available.join(", ")}]`);
|
|
7544
|
+
error["available"] = available;
|
|
7545
|
+
throw error;
|
|
7546
|
+
}
|
|
7547
|
+
function createPoolScope(runtime, poolName) {
|
|
7548
|
+
return {
|
|
7549
|
+
collection: (name) => runtime.scopedCollection(name, { pool: poolName }),
|
|
7550
|
+
model: (name) => runtime.scopedModel(name, { pool: poolName }),
|
|
7551
|
+
use: (dbName) => ({
|
|
7552
|
+
collection: (name) => runtime.scopedCollection(name, { pool: poolName, database: dbName }),
|
|
7553
|
+
model: (name) => runtime.scopedModel(name, { pool: poolName, database: dbName })
|
|
7554
|
+
})
|
|
7555
|
+
};
|
|
7556
|
+
}
|
|
7557
|
+
function getRegisteredModelMetadata(registered) {
|
|
7558
|
+
const definition = registered.definition;
|
|
7559
|
+
return {
|
|
7560
|
+
actualCollectionName: definition.collection ?? definition.name ?? registered.collectionName,
|
|
7561
|
+
connection: definition.connection
|
|
7562
|
+
};
|
|
7563
|
+
}
|
|
7564
|
+
function getRuntimeDatabaseName(value) {
|
|
7565
|
+
return asRuntimeCompatRecord(value).databaseName ?? "default";
|
|
7566
|
+
}
|
|
7567
|
+
function getCompatModelInstanceCache(value) {
|
|
7568
|
+
const record = asRuntimeCompatRecord(value);
|
|
7569
|
+
if (!record._modelInstances) {
|
|
7570
|
+
record._modelInstances = new MemoryCache({
|
|
7571
|
+
maxEntries: 1e5,
|
|
7572
|
+
enableStats: false
|
|
7573
|
+
});
|
|
7574
|
+
}
|
|
7575
|
+
return record._modelInstances;
|
|
7576
|
+
}
|
|
7577
|
+
function createCompatModelInstance(config) {
|
|
7578
|
+
return new ModelInstance(
|
|
7579
|
+
config.collection,
|
|
7580
|
+
config.runtime,
|
|
7581
|
+
{
|
|
7582
|
+
collectionName: config.collectionName,
|
|
7583
|
+
dbName: config.dbName,
|
|
7584
|
+
poolName: config.poolName,
|
|
7585
|
+
definition: config.definition
|
|
7586
|
+
}
|
|
7587
|
+
);
|
|
7588
|
+
}
|
|
7589
|
+
|
|
7410
7590
|
// src/entry/runtime-model.ts
|
|
7411
7591
|
function createRuntimeModelHost(config) {
|
|
7412
7592
|
return {
|
|
@@ -7421,19 +7601,20 @@ function createRuntimeModelInstance(host, name, scope) {
|
|
|
7421
7601
|
if (!registered) {
|
|
7422
7602
|
throw createError(ErrorCodes.MODEL_NOT_DEFINED, `Model '${name}' is not defined.`);
|
|
7423
7603
|
}
|
|
7424
|
-
const
|
|
7425
|
-
const
|
|
7426
|
-
const
|
|
7604
|
+
const { actualCollectionName, connection } = getRegisteredModelMetadata(registered);
|
|
7605
|
+
const databaseName = connection?.database ?? scope.database ?? resolveDatabaseName(host.options);
|
|
7606
|
+
const poolName = connection?.pool ?? scope.pool;
|
|
7607
|
+
const cacheKey = `${poolName ?? "default"}:${databaseName}:${registered.collectionName}:${actualCollectionName}`;
|
|
7427
7608
|
const revision = Model.getRevision(registered.collectionName);
|
|
7428
7609
|
const cached = host._modelInstances.get(cacheKey);
|
|
7429
7610
|
if (cached && cached.revision === revision) {
|
|
7430
7611
|
return cached.instance;
|
|
7431
7612
|
}
|
|
7432
7613
|
const instance = new ModelInstance(
|
|
7433
|
-
host.scopedCollection(
|
|
7614
|
+
host.scopedCollection(actualCollectionName, { database: databaseName, pool: poolName }),
|
|
7434
7615
|
host.runtime,
|
|
7435
7616
|
{
|
|
7436
|
-
collectionName:
|
|
7617
|
+
collectionName: actualCollectionName,
|
|
7437
7618
|
dbName: databaseName,
|
|
7438
7619
|
poolName,
|
|
7439
7620
|
definition: registered.definition
|
|
@@ -7516,92 +7697,6 @@ function createRuntimeCoreAccessors(runtime) {
|
|
|
7516
7697
|
});
|
|
7517
7698
|
}
|
|
7518
7699
|
|
|
7519
|
-
// src/entry/runtime-compat-accessors.ts
|
|
7520
|
-
function asRuntimeCompatRecord(value) {
|
|
7521
|
-
return value;
|
|
7522
|
-
}
|
|
7523
|
-
function requireCompatDbInstance(value) {
|
|
7524
|
-
const dbInstance = asRuntimeCompatRecord(value).dbInstance;
|
|
7525
|
-
if (!dbInstance) {
|
|
7526
|
-
throw createError(ErrorCodes.NOT_CONNECTED, "Database is not connected. Call connect() first.");
|
|
7527
|
-
}
|
|
7528
|
-
return dbInstance;
|
|
7529
|
-
}
|
|
7530
|
-
function requireCompatPoolManagerRecord(value) {
|
|
7531
|
-
const poolManager = asRuntimeCompatRecord(value)._poolManager;
|
|
7532
|
-
if (!poolManager) {
|
|
7533
|
-
throw createError(ErrorCodes.NO_POOL_MANAGER, "No pool manager configured. Add pools to MonSQLize constructor options.");
|
|
7534
|
-
}
|
|
7535
|
-
return poolManager;
|
|
7536
|
-
}
|
|
7537
|
-
function resolvePoolClientFromRecord(poolManager, poolName) {
|
|
7538
|
-
const getPoolV1 = poolManager["_getPool"];
|
|
7539
|
-
const getPoolV2 = poolManager["getPool"];
|
|
7540
|
-
if (typeof getPoolV1 === "function") {
|
|
7541
|
-
return getPoolV1.call(poolManager, poolName) ?? null;
|
|
7542
|
-
}
|
|
7543
|
-
if (typeof getPoolV2 === "function") {
|
|
7544
|
-
try {
|
|
7545
|
-
return getPoolV2.call(poolManager, poolName) ?? null;
|
|
7546
|
-
} catch {
|
|
7547
|
-
return null;
|
|
7548
|
-
}
|
|
7549
|
-
}
|
|
7550
|
-
return null;
|
|
7551
|
-
}
|
|
7552
|
-
function assertCompatPoolExists(poolManager, poolName) {
|
|
7553
|
-
if (resolvePoolClientFromRecord(poolManager, poolName)) {
|
|
7554
|
-
return;
|
|
7555
|
-
}
|
|
7556
|
-
const getNames = poolManager["getPoolNames"];
|
|
7557
|
-
const available = typeof getNames === "function" ? getNames.call(poolManager) : [];
|
|
7558
|
-
const error = createError(ErrorCodes.POOL_NOT_FOUND, `Pool '${poolName}' not found. Available pools: [${available.join(", ")}]`);
|
|
7559
|
-
error["available"] = available;
|
|
7560
|
-
throw error;
|
|
7561
|
-
}
|
|
7562
|
-
function createPoolScope(runtime, poolName) {
|
|
7563
|
-
return {
|
|
7564
|
-
collection: (name) => runtime.scopedCollection(name, { pool: poolName }),
|
|
7565
|
-
model: (name) => runtime.scopedModel(name, { pool: poolName }),
|
|
7566
|
-
use: (dbName) => ({
|
|
7567
|
-
collection: (name) => runtime.scopedCollection(name, { pool: poolName, database: dbName }),
|
|
7568
|
-
model: (name) => runtime.scopedModel(name, { pool: poolName, database: dbName })
|
|
7569
|
-
})
|
|
7570
|
-
};
|
|
7571
|
-
}
|
|
7572
|
-
function getRegisteredModelMetadata(registered) {
|
|
7573
|
-
const definition = registered.definition;
|
|
7574
|
-
return {
|
|
7575
|
-
actualCollectionName: definition.collection ?? definition.name ?? registered.collectionName,
|
|
7576
|
-
connection: definition.connection
|
|
7577
|
-
};
|
|
7578
|
-
}
|
|
7579
|
-
function getRuntimeDatabaseName(value) {
|
|
7580
|
-
return asRuntimeCompatRecord(value).databaseName ?? "default";
|
|
7581
|
-
}
|
|
7582
|
-
function getCompatModelInstanceCache(value) {
|
|
7583
|
-
const record = asRuntimeCompatRecord(value);
|
|
7584
|
-
if (!record._modelInstances) {
|
|
7585
|
-
record._modelInstances = new MemoryCache({
|
|
7586
|
-
maxEntries: 1e5,
|
|
7587
|
-
enableStats: false
|
|
7588
|
-
});
|
|
7589
|
-
}
|
|
7590
|
-
return record._modelInstances;
|
|
7591
|
-
}
|
|
7592
|
-
function createCompatModelInstance(config) {
|
|
7593
|
-
return new ModelInstance(
|
|
7594
|
-
config.collection,
|
|
7595
|
-
config.runtime,
|
|
7596
|
-
{
|
|
7597
|
-
collectionName: config.collectionName,
|
|
7598
|
-
dbName: config.dbName,
|
|
7599
|
-
poolName: config.poolName,
|
|
7600
|
-
definition: config.definition
|
|
7601
|
-
}
|
|
7602
|
-
);
|
|
7603
|
-
}
|
|
7604
|
-
|
|
7605
7700
|
// src/entry/runtime-admin-bridge.ts
|
|
7606
7701
|
import { performance } from "node:perf_hooks";
|
|
7607
7702
|
function createLegacyCollectionBridge(config) {
|
|
@@ -9675,31 +9770,132 @@ function toOptionalNumber(value) {
|
|
|
9675
9770
|
function toOptionalBoolean(value) {
|
|
9676
9771
|
return typeof value === "boolean" ? value : void 0;
|
|
9677
9772
|
}
|
|
9773
|
+
function isObjectRecord(value) {
|
|
9774
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9775
|
+
}
|
|
9776
|
+
function buildMemoryCache(input, fallback = {}) {
|
|
9777
|
+
if (input instanceof MemoryCache) return input;
|
|
9778
|
+
if (isCacheLike(input)) return input;
|
|
9779
|
+
const opts = isObjectRecord(input) ? input : {};
|
|
9780
|
+
return new MemoryCache({
|
|
9781
|
+
maxEntries: toOptionalNumber(opts.maxEntries ?? opts.maxSize ?? fallback.maxEntries ?? fallback.maxSize),
|
|
9782
|
+
maxMemory: toOptionalNumber(opts.maxMemory ?? fallback.maxMemory),
|
|
9783
|
+
defaultTtl: toOptionalNumber(opts.defaultTtl ?? opts.ttl ?? fallback.defaultTtl ?? fallback.ttl),
|
|
9784
|
+
enableStats: toOptionalBoolean(opts.enableStats ?? fallback.enableStats),
|
|
9785
|
+
enableTags: toOptionalBoolean(opts.enableTags ?? fallback.enableTags),
|
|
9786
|
+
cleanupInterval: toOptionalNumber(opts.cleanupInterval ?? fallback.cleanupInterval),
|
|
9787
|
+
enabled: toOptionalBoolean(opts.enabled ?? fallback.enabled)
|
|
9788
|
+
});
|
|
9789
|
+
}
|
|
9790
|
+
function prefixKey(prefix, key) {
|
|
9791
|
+
if (!prefix || key.startsWith(prefix)) return key;
|
|
9792
|
+
return `${prefix}${key}`;
|
|
9793
|
+
}
|
|
9794
|
+
function unprefixKey(prefix, key) {
|
|
9795
|
+
if (!prefix || !key.startsWith(prefix)) return key;
|
|
9796
|
+
return key.slice(prefix.length);
|
|
9797
|
+
}
|
|
9798
|
+
function wrapRemoteCache(cache, options = {}) {
|
|
9799
|
+
const prefix = typeof options.prefix === "string" && options.prefix.length > 0 ? options.prefix : void 0;
|
|
9800
|
+
const defaultTtl = options.defaultTtl;
|
|
9801
|
+
if (!prefix && defaultTtl === void 0) return cache;
|
|
9802
|
+
const key = (value) => prefixKey(prefix, value);
|
|
9803
|
+
const keys = (values) => values.map(key);
|
|
9804
|
+
const resolveTtl = (ttl) => ttl ?? defaultTtl;
|
|
9805
|
+
return new Proxy(cache, {
|
|
9806
|
+
get(target, prop, receiver) {
|
|
9807
|
+
switch (prop) {
|
|
9808
|
+
case "get":
|
|
9809
|
+
return (cacheKey) => target.get(key(cacheKey));
|
|
9810
|
+
case "set":
|
|
9811
|
+
return (cacheKey, value, ttl) => target.set(key(cacheKey), value, resolveTtl(ttl));
|
|
9812
|
+
case "del":
|
|
9813
|
+
return (cacheKey) => target.del(key(cacheKey));
|
|
9814
|
+
case "exists":
|
|
9815
|
+
return (cacheKey) => target.exists(key(cacheKey));
|
|
9816
|
+
case "has":
|
|
9817
|
+
return (cacheKey) => target.has(key(cacheKey));
|
|
9818
|
+
case "getMany":
|
|
9819
|
+
return async (cacheKeys) => {
|
|
9820
|
+
const result = await target.getMany(keys(cacheKeys));
|
|
9821
|
+
return Object.fromEntries(
|
|
9822
|
+
Object.entries(result).map(([cacheKey, value]) => [unprefixKey(prefix, cacheKey), value])
|
|
9823
|
+
);
|
|
9824
|
+
};
|
|
9825
|
+
case "setMany":
|
|
9826
|
+
return (entries, ttl) => target.setMany(
|
|
9827
|
+
Object.fromEntries(
|
|
9828
|
+
Object.entries(entries).map(([cacheKey, value]) => [key(cacheKey), value])
|
|
9829
|
+
),
|
|
9830
|
+
resolveTtl(ttl)
|
|
9831
|
+
);
|
|
9832
|
+
case "delMany":
|
|
9833
|
+
return (cacheKeys) => target.delMany(keys(cacheKeys));
|
|
9834
|
+
case "delPattern":
|
|
9835
|
+
return (pattern) => target.delPattern(key(pattern));
|
|
9836
|
+
case "keys":
|
|
9837
|
+
return async (pattern) => {
|
|
9838
|
+
const result = await target.keys(pattern ? key(pattern) : void 0);
|
|
9839
|
+
return result.map((cacheKey) => unprefixKey(prefix, cacheKey));
|
|
9840
|
+
};
|
|
9841
|
+
default: {
|
|
9842
|
+
const value = Reflect.get(target, prop, receiver);
|
|
9843
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
9844
|
+
}
|
|
9845
|
+
}
|
|
9846
|
+
}
|
|
9847
|
+
});
|
|
9848
|
+
}
|
|
9849
|
+
function buildRedisCache(input) {
|
|
9850
|
+
if (!input || !isObjectRecord(input)) return void 0;
|
|
9851
|
+
const prefix = typeof input.prefix === "string" ? input.prefix : void 0;
|
|
9852
|
+
const defaultTtl = toOptionalNumber(input.defaultTtl ?? input.ttl);
|
|
9853
|
+
if (isCacheLike(input)) {
|
|
9854
|
+
return wrapRemoteCache(input, { prefix, defaultTtl });
|
|
9855
|
+
}
|
|
9856
|
+
if (input.enabled === false) return void 0;
|
|
9857
|
+
const embeddedCache = input.cache ?? input.adapter;
|
|
9858
|
+
if (isCacheLike(embeddedCache)) {
|
|
9859
|
+
return wrapRemoteCache(embeddedCache, { prefix, defaultTtl });
|
|
9860
|
+
}
|
|
9861
|
+
const redisTarget = input.url ?? input.uri ?? input.instance ?? input.client ?? input.redis;
|
|
9862
|
+
if (redisTarget === void 0 && input.enabled !== true) {
|
|
9863
|
+
return void 0;
|
|
9864
|
+
}
|
|
9865
|
+
const redisCache = createRedisCacheAdapter(redisTarget);
|
|
9866
|
+
return wrapRemoteCache(redisCache, { prefix, defaultTtl });
|
|
9867
|
+
}
|
|
9868
|
+
function isVextCacheShape(input) {
|
|
9869
|
+
return isObjectRecord(input.memory) || isObjectRecord(input.redis);
|
|
9870
|
+
}
|
|
9678
9871
|
function normalizeRuntimeCache(cache) {
|
|
9679
9872
|
if (cache instanceof MemoryCache) return cache;
|
|
9680
9873
|
if (isCacheLike(cache)) return cache;
|
|
9681
9874
|
const input = cache ?? {};
|
|
9682
|
-
if (input
|
|
9683
|
-
const
|
|
9684
|
-
const local =
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9875
|
+
if (isVextCacheShape(input)) {
|
|
9876
|
+
const memoryInput = isObjectRecord(input.memory) ? input.memory : {};
|
|
9877
|
+
const local = buildMemoryCache(
|
|
9878
|
+
input.memory,
|
|
9879
|
+
{
|
|
9880
|
+
...input,
|
|
9881
|
+
enabled: memoryInput.enabled === false ? false : input.enabled
|
|
9882
|
+
}
|
|
9883
|
+
);
|
|
9884
|
+
const remote = buildRedisCache(input.redis);
|
|
9885
|
+
const policy = input.policy ?? {};
|
|
9886
|
+
return new MultiLevelCache({
|
|
9887
|
+
local,
|
|
9888
|
+
remote,
|
|
9889
|
+
writePolicy: policy.writePolicy ?? "both",
|
|
9890
|
+
backfillOnRemoteHit: policy.backfillLocalOnRemoteHit ?? true,
|
|
9891
|
+
remoteTimeoutMs: isObjectRecord(input.redis) ? toOptionalNumber(input.redis.timeoutMs) : void 0,
|
|
9892
|
+
publish: input.publish
|
|
9692
9893
|
});
|
|
9894
|
+
}
|
|
9895
|
+
if (input.multiLevel === true || input.local !== void 0 && typeof input.local === "object") {
|
|
9896
|
+
const local = buildMemoryCache(input.local);
|
|
9693
9897
|
const remoteInput = input.remote;
|
|
9694
|
-
const remote = isCacheLike(remoteInput) ? remoteInput : remoteInput ?
|
|
9695
|
-
maxEntries: toOptionalNumber(remoteInput.maxEntries ?? remoteInput.maxSize),
|
|
9696
|
-
maxMemory: toOptionalNumber(remoteInput.maxMemory),
|
|
9697
|
-
defaultTtl: toOptionalNumber(remoteInput.defaultTtl ?? remoteInput.ttl),
|
|
9698
|
-
enableStats: toOptionalBoolean(remoteInput.enableStats),
|
|
9699
|
-
enableTags: toOptionalBoolean(remoteInput.enableTags),
|
|
9700
|
-
cleanupInterval: toOptionalNumber(remoteInput.cleanupInterval),
|
|
9701
|
-
enabled: toOptionalBoolean(remoteInput.enabled)
|
|
9702
|
-
}) : void 0;
|
|
9898
|
+
const remote = isCacheLike(remoteInput) ? remoteInput : remoteInput ? buildMemoryCache(remoteInput) : void 0;
|
|
9703
9899
|
const policy = input.policy ?? {};
|
|
9704
9900
|
return new MultiLevelCache({
|
|
9705
9901
|
local,
|
|
@@ -9710,15 +9906,7 @@ function normalizeRuntimeCache(cache) {
|
|
|
9710
9906
|
publish: input.publish
|
|
9711
9907
|
});
|
|
9712
9908
|
}
|
|
9713
|
-
return
|
|
9714
|
-
maxEntries: toOptionalNumber(input.maxEntries ?? input.maxSize),
|
|
9715
|
-
maxMemory: toOptionalNumber(input.maxMemory),
|
|
9716
|
-
defaultTtl: toOptionalNumber(input.defaultTtl ?? input.ttl),
|
|
9717
|
-
enableStats: toOptionalBoolean(input.enableStats),
|
|
9718
|
-
enableTags: toOptionalBoolean(input.enableTags),
|
|
9719
|
-
cleanupInterval: toOptionalNumber(input.cleanupInterval),
|
|
9720
|
-
enabled: toOptionalBoolean(input.enabled)
|
|
9721
|
-
});
|
|
9909
|
+
return buildMemoryCache(input);
|
|
9722
9910
|
}
|
|
9723
9911
|
|
|
9724
9912
|
// src/capabilities/function-cache/index.ts
|