joist-core 2.1.0 → 2.2.0-next.2
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/build/ConditionBuilder.d.ts +1 -22
- package/build/ConditionBuilder.d.ts.map +1 -1
- package/build/ConditionBuilder.js +6 -72
- package/build/ConditionBuilder.js.map +1 -1
- package/build/EntityFilter.d.ts +4 -2
- package/build/EntityFilter.d.ts.map +1 -1
- package/build/EntityGraphQLFilter.d.ts +2 -0
- package/build/EntityGraphQLFilter.d.ts.map +1 -1
- package/build/EntityGraphQLFilter.js.map +1 -1
- package/build/EntityManager.d.ts +25 -39
- package/build/EntityManager.d.ts.map +1 -1
- package/build/EntityManager.js +97 -44
- package/build/EntityManager.js.map +1 -1
- package/build/EntityMetadata.d.ts +2 -0
- package/build/EntityMetadata.d.ts.map +1 -1
- package/build/EntityMetadata.js.map +1 -1
- package/build/InstanceData.d.ts +7 -1
- package/build/InstanceData.d.ts.map +1 -1
- package/build/InstanceData.js +36 -7
- package/build/InstanceData.js.map +1 -1
- package/build/IsLoadedCache.d.ts +1 -1
- package/build/IsLoadedCache.d.ts.map +1 -1
- package/build/IsLoadedCache.js +6 -1
- package/build/IsLoadedCache.js.map +1 -1
- package/build/JoinRows.d.ts +1 -1
- package/build/JoinRows.js +6 -1
- package/build/JoinRows.js.map +1 -1
- package/build/PluginManager.d.ts +12 -0
- package/build/PluginManager.d.ts.map +1 -1
- package/build/PluginManager.js +18 -2
- package/build/PluginManager.js.map +1 -1
- package/build/QueryParser.collectionJoins.d.ts +27 -0
- package/build/QueryParser.collectionJoins.d.ts.map +1 -0
- package/build/QueryParser.collectionJoins.js +460 -0
- package/build/QueryParser.collectionJoins.js.map +1 -0
- package/build/QueryParser.collectionJoins.test.d.ts +2 -0
- package/build/QueryParser.collectionJoins.test.d.ts.map +1 -0
- package/build/QueryParser.collectionJoins.test.js +772 -0
- package/build/QueryParser.collectionJoins.test.js.map +1 -0
- package/build/QueryParser.d.ts +67 -9
- package/build/QueryParser.d.ts.map +1 -1
- package/build/QueryParser.js +39 -33
- package/build/QueryParser.js.map +1 -1
- package/build/QueryParser.pruning.d.ts +4 -2
- package/build/QueryParser.pruning.d.ts.map +1 -1
- package/build/QueryParser.pruning.js +80 -10
- package/build/QueryParser.pruning.js.map +1 -1
- package/build/QueryParser.pruning.test.d.ts +2 -0
- package/build/QueryParser.pruning.test.d.ts.map +1 -0
- package/build/QueryParser.pruning.test.js +106 -0
- package/build/QueryParser.pruning.test.js.map +1 -0
- package/build/QueryVisitor.d.ts.map +1 -1
- package/build/QueryVisitor.js +22 -0
- package/build/QueryVisitor.js.map +1 -1
- package/build/ReactionsManager.js +2 -2
- package/build/batchloaders/BatchLoader.d.ts.map +1 -1
- package/build/batchloaders/BatchLoader.js +4 -1
- package/build/batchloaders/BatchLoader.js.map +1 -1
- package/build/batchloaders/manyToManyBatchLoader.js +3 -1
- package/build/batchloaders/manyToManyBatchLoader.js.map +1 -1
- package/build/batchloaders/recursiveM2mBatchLoader.d.ts.map +1 -1
- package/build/batchloaders/recursiveM2mBatchLoader.js +3 -1
- package/build/batchloaders/recursiveM2mBatchLoader.js.map +1 -1
- package/build/changes.d.ts.map +1 -1
- package/build/changes.js +1 -4
- package/build/changes.js.map +1 -1
- package/build/config.d.ts.map +1 -1
- package/build/config.js +18 -10
- package/build/config.js.map +1 -1
- package/build/configure.js +2 -2
- package/build/dataloaders/findCountDataLoader.js +2 -2
- package/build/dataloaders/findCountDataLoader.js.map +1 -1
- package/build/dataloaders/findDataLoader.d.ts +2 -1
- package/build/dataloaders/findDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findDataLoader.js +26 -23
- package/build/dataloaders/findDataLoader.js.map +1 -1
- package/build/dataloaders/findIdsDataLoader.js +2 -2
- package/build/dataloaders/findIdsDataLoader.js.map +1 -1
- package/build/dataloaders/findOrCreateDataLoader.d.ts.map +1 -1
- package/build/dataloaders/findOrCreateDataLoader.js +6 -1
- package/build/dataloaders/findOrCreateDataLoader.js.map +1 -1
- package/build/dataloaders/findPaginatedDataLoader.d.ts +8 -0
- package/build/dataloaders/findPaginatedDataLoader.d.ts.map +1 -0
- package/build/dataloaders/findPaginatedDataLoader.js +76 -0
- package/build/dataloaders/findPaginatedDataLoader.js.map +1 -0
- package/build/defaults.d.ts.map +1 -1
- package/build/defaults.js +49 -42
- package/build/defaults.js.map +1 -1
- package/build/drivers/buildRawQuery.d.ts +6 -4
- package/build/drivers/buildRawQuery.d.ts.map +1 -1
- package/build/drivers/buildRawQuery.js +6 -5
- package/build/drivers/buildRawQuery.js.map +1 -1
- package/build/drivers/buildUtils.d.ts +7 -2
- package/build/drivers/buildUtils.d.ts.map +1 -1
- package/build/drivers/buildUtils.js +14 -5
- package/build/drivers/buildUtils.js.map +1 -1
- package/build/fields.d.ts.map +1 -1
- package/build/fields.js +16 -7
- package/build/fields.js.map +1 -1
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +7 -5
- package/build/index.js.map +1 -1
- package/build/json.d.ts +3 -3
- package/build/json.d.ts.map +1 -1
- package/build/json.js +4 -4
- package/build/json.js.map +1 -1
- package/build/loadHints.d.ts +4 -4
- package/build/loadHints.d.ts.map +1 -1
- package/build/loadLens.js +1 -1
- package/build/loadLens.js.map +1 -1
- package/build/preloading/JsonAggregatePreloader.js +6 -2
- package/build/preloading/JsonAggregatePreloader.js.map +1 -1
- package/build/reactiveHints.d.ts +24 -7
- package/build/reactiveHints.d.ts.map +1 -1
- package/build/reactiveHints.js +45 -28
- package/build/reactiveHints.js.map +1 -1
- package/build/relations/AbstractRelationImpl.d.ts +7 -2
- package/build/relations/AbstractRelationImpl.d.ts.map +1 -1
- package/build/relations/AbstractRelationImpl.js.map +1 -1
- package/build/relations/AsyncProperty.d.ts +36 -0
- package/build/relations/AsyncProperty.d.ts.map +1 -0
- package/build/relations/AsyncProperty.js +80 -0
- package/build/relations/AsyncProperty.js.map +1 -0
- package/build/relations/{ReactiveQueryField.d.ts → AsyncReactiveField.d.ts} +10 -10
- package/build/relations/AsyncReactiveField.d.ts.map +1 -0
- package/build/relations/{ReactiveQueryField.js → AsyncReactiveField.js} +19 -19
- package/build/relations/{ReactiveQueryField.js.map → AsyncReactiveField.js.map} +1 -1
- package/build/relations/ReactiveField.d.ts +7 -9
- package/build/relations/ReactiveField.d.ts.map +1 -1
- package/build/relations/ReactiveField.js +5 -10
- package/build/relations/ReactiveField.js.map +1 -1
- package/build/relations/ReactiveGetter.d.ts +5 -5
- package/build/relations/ReactiveGetter.d.ts.map +1 -1
- package/build/relations/ReactiveGetter.js +3 -3
- package/build/relations/ReactiveGetter.js.map +1 -1
- package/build/relations/ReactiveReference.d.ts +2 -2
- package/build/relations/ReactiveReference.d.ts.map +1 -1
- package/build/relations/ReactiveReference.js +100 -36
- package/build/relations/ReactiveReference.js.map +1 -1
- package/build/relations/{hasAsyncProperty.d.ts → hasProperty.d.ts} +12 -12
- package/build/relations/hasProperty.d.ts.map +1 -0
- package/build/relations/{hasAsyncProperty.js → hasProperty.js} +20 -20
- package/build/relations/hasProperty.js.map +1 -0
- package/build/relations/index.d.ts +3 -2
- package/build/relations/index.d.ts.map +1 -1
- package/build/relations/index.js +16 -11
- package/build/relations/index.js.map +1 -1
- package/build/resurrection.d.ts +10 -0
- package/build/resurrection.d.ts.map +1 -0
- package/build/resurrection.js +93 -0
- package/build/resurrection.js.map +1 -0
- package/build/rules.js +3 -3
- package/build/trusted.d.ts +1 -1
- package/build/trusted.d.ts.map +1 -1
- package/build/trusted.js +1 -1
- package/build/trusted.js.map +1 -1
- package/build/upsert.d.ts.map +1 -1
- package/build/upsert.js +26 -10
- package/build/upsert.js.map +1 -1
- package/build/withLoaded.js +5 -5
- package/build/withLoaded.js.map +1 -1
- package/package.json +9 -9
- package/build/relations/ReactiveQueryField.d.ts.map +0 -1
- package/build/relations/hasAsyncProperty.d.ts.map +0 -1
- package/build/relations/hasAsyncProperty.js.map +0 -1
package/build/EntityManager.js
CHANGED
|
@@ -37,6 +37,7 @@ const findCountDataLoader_1 = require("./dataloaders/findCountDataLoader");
|
|
|
37
37
|
const findDataLoader_1 = require("./dataloaders/findDataLoader");
|
|
38
38
|
const findIdsDataLoader_1 = require("./dataloaders/findIdsDataLoader");
|
|
39
39
|
const findOrCreateDataLoader_1 = require("./dataloaders/findOrCreateDataLoader");
|
|
40
|
+
const findPaginatedDataLoader_1 = require("./dataloaders/findPaginatedDataLoader");
|
|
40
41
|
const Entity_1 = require("./Entity");
|
|
41
42
|
const FlushLock_1 = require("./FlushLock");
|
|
42
43
|
const index_1 = require("./index");
|
|
@@ -48,6 +49,7 @@ const PluginManager_1 = require("./PluginManager");
|
|
|
48
49
|
const ReactionsManager_1 = require("./ReactionsManager");
|
|
49
50
|
const reactiveHints_1 = require("./reactiveHints");
|
|
50
51
|
const relations_1 = require("./relations");
|
|
52
|
+
const AsyncProperty_1 = require("./relations/AsyncProperty");
|
|
51
53
|
const hasAsyncMethod_1 = require("./relations/hasAsyncMethod");
|
|
52
54
|
const RecursiveCollection_1 = require("./relations/RecursiveCollection");
|
|
53
55
|
const Todo_1 = require("./Todo");
|
|
@@ -246,7 +248,10 @@ class EntityManager {
|
|
|
246
248
|
async find(type, where, options) {
|
|
247
249
|
const { populate, ...rest } = options || {};
|
|
248
250
|
const settings = { where, ...rest };
|
|
249
|
-
const
|
|
251
|
+
const loader = hasPaginationSettings(rest)
|
|
252
|
+
? (0, findPaginatedDataLoader_1.findPaginatedDataLoader)(this, type, settings, populate)
|
|
253
|
+
: (0, findDataLoader_1.findDataLoader)(this, type, settings, populate);
|
|
254
|
+
const result = await loader
|
|
250
255
|
.load(settings)
|
|
251
256
|
.catch(function find(err) {
|
|
252
257
|
throw appendStack(err, new Error());
|
|
@@ -256,30 +261,52 @@ class EntityManager {
|
|
|
256
261
|
}
|
|
257
262
|
return result;
|
|
258
263
|
}
|
|
259
|
-
|
|
260
|
-
const { populate, limit, offset, ...rest } = options || {};
|
|
261
|
-
const meta = (0, index_1.getMetadata)(type);
|
|
262
|
-
const query = (0, index_1.parseFindQuery)(meta, where, rest);
|
|
263
|
-
const rows = await this.executeFind(meta, "findPaginated", query, { limit, offset });
|
|
264
|
-
// check row limit
|
|
265
|
-
const result = this.hydrate(type, rows);
|
|
266
|
-
if (populate) {
|
|
267
|
-
await this.populate(result, populate);
|
|
268
|
-
}
|
|
269
|
-
return result;
|
|
270
|
-
}
|
|
264
|
+
/** Runs the post-parse find pipeline: plugins mutate the logical AST, then Joist optimizes/prunes before SQL. */
|
|
271
265
|
async executeFind(meta, operation, parsed, settings) {
|
|
266
|
+
const { checkLimit, findSettings } = this.prepareFind(meta, operation, parsed, settings);
|
|
267
|
+
return this.executePreparedFind(meta, operation, parsed, findSettings, checkLimit);
|
|
268
|
+
}
|
|
269
|
+
/** Executes a query that has already had find hooks and optimizations applied. */
|
|
270
|
+
async executePreparedFind(meta, operation, parsed, findSettings, checkLimit) {
|
|
272
271
|
const { pluginManager } = getEmInternalApi(this);
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
const rows = await this.driver.executeFind(this, parsed, findSettings);
|
|
273
|
+
// Check by default unless explicitly disabled or the caller removed the LIMIT via `limit: undefined`
|
|
274
|
+
const shouldCheck = checkLimit ?? !("limit" in findSettings && findSettings.limit === undefined);
|
|
275
|
+
if (shouldCheck && rows.length >= this.entityLimit) {
|
|
276
|
+
throw new Error(`Query returned more than ${this.entityLimit} entityLimit rows`);
|
|
277
|
+
}
|
|
275
278
|
pluginManager.afterFind(meta, operation, rows);
|
|
276
279
|
return rows;
|
|
277
280
|
}
|
|
278
|
-
|
|
279
|
-
|
|
281
|
+
/**
|
|
282
|
+
* Runs pre-SQL find hooks and optimizations against a parsed query.
|
|
283
|
+
*
|
|
284
|
+
* This allows plugins to see "pre-batched" / "logical" query ASTs, instead of our
|
|
285
|
+
* more complicated `_find` batched queries. The flow would be:
|
|
286
|
+
*
|
|
287
|
+
* - A loader calls `prepareFind(originalQuery)`
|
|
288
|
+
* - Plugins inspect/modify the query as/if needed
|
|
289
|
+
* - The loader crafts a new, more complicated query that embeds the originalQuery
|
|
290
|
+
* - The loader calls `executePreparedFind` with the 2nd query
|
|
291
|
+
*/
|
|
292
|
+
prepareFind(meta, operation, parsed, settings) {
|
|
293
|
+
const { checkLimit, ...findSettings } = settings;
|
|
294
|
+
const { pluginManager } = getEmInternalApi(this);
|
|
295
|
+
// Plugins may mutate the settings object, so return the post-hook version that loaders must reuse.
|
|
296
|
+
pluginManager.beforeFind(meta, operation, parsed, findSettings);
|
|
297
|
+
(0, index_1.optimizeCollectionJoins)(parsed, settings);
|
|
298
|
+
return { checkLimit, findSettings };
|
|
280
299
|
}
|
|
281
|
-
async
|
|
282
|
-
|
|
300
|
+
async findGql(type, where, options) {
|
|
301
|
+
if (!options) {
|
|
302
|
+
return this.find(type, where);
|
|
303
|
+
}
|
|
304
|
+
const normalized = { ...options };
|
|
305
|
+
if ("limit" in normalized)
|
|
306
|
+
normalized.limit = normalized.limit ?? undefined;
|
|
307
|
+
if ("offset" in normalized)
|
|
308
|
+
normalized.offset = normalized.offset ?? undefined;
|
|
309
|
+
return this.find(type, where, normalized);
|
|
283
310
|
}
|
|
284
311
|
async findOne(type, where, options) {
|
|
285
312
|
const list = await this.find(type, where, options);
|
|
@@ -878,11 +905,11 @@ class EntityManager {
|
|
|
878
905
|
const createdThenDeleted = new Set();
|
|
879
906
|
// We'll only invoke hooks once/entity (the 1st time that entity goes through runHooksOnPendingEntities)
|
|
880
907
|
const hooksInvoked = new Set();
|
|
881
|
-
// Make sure two
|
|
908
|
+
// Make sure two AsyncReactiveFields don't ping-pong each other forever
|
|
882
909
|
let hookLoops = 0;
|
|
883
910
|
let now = getNow();
|
|
884
911
|
const suppressedDefaultTypeErrors = [];
|
|
885
|
-
// Make a lambda that we can invoke multiple times, if we loop for
|
|
912
|
+
// Make a lambda that we can invoke multiple times, if we loop for AsyncReactiveFields
|
|
886
913
|
const runHooksOnPendingEntities = async () => {
|
|
887
914
|
if (hookLoops++ >= 10)
|
|
888
915
|
throw new Error("runHooksOnPendingEntities has ran 10 iterations, aborting");
|
|
@@ -899,18 +926,18 @@ class EntityManager {
|
|
|
899
926
|
// Subset of pendingFlush entities that had hooks invoked in a prior `runHooksOnPendingEntities`
|
|
900
927
|
const alreadyRanHooks = new Set();
|
|
901
928
|
findPendingFlushEntities(this.entities, hooksInvoked, pendingFlush, pendingHooks, alreadyRanHooks);
|
|
902
|
-
// If we're re-looping for
|
|
929
|
+
// If we're re-looping for AsyncReactiveField, make sure to bump updatedAt
|
|
903
930
|
// each time, so that for an INSERT-then-UPDATE the triggers don't think the
|
|
904
931
|
// UPDATE forgot to self-bump updatedAt, and then "helpfully" bump it for us.
|
|
905
932
|
if (alreadyRanHooks.size > 0) {
|
|
906
|
-
maybeBumpUpdatedAt((0, Todo_1.createTodos)([...alreadyRanHooks]), now);
|
|
933
|
+
maybeBumpUpdatedAt(this.#rm, (0, Todo_1.createTodos)([...alreadyRanHooks]), now);
|
|
907
934
|
}
|
|
908
935
|
// Run hooks in a series of loops until things "settle down"
|
|
909
936
|
while (pendingHooks.size > 0) {
|
|
910
937
|
await this.#fl.allowWrites(async () => {
|
|
911
938
|
let todos = (0, Todo_1.createTodos)([...pendingHooks]);
|
|
912
939
|
await (0, defaults_1.setAsyncDefaults)(suppressedDefaultTypeErrors, this.ctx, Todo_1.Todo.groupInsertsByTypeAndSubType(todos));
|
|
913
|
-
maybeBumpUpdatedAt(todos, now);
|
|
940
|
+
maybeBumpUpdatedAt(this.#rm, todos, now);
|
|
914
941
|
// Run our hooks
|
|
915
942
|
for (const group of maybeSetupHookOrdering(todos)) {
|
|
916
943
|
await beforeCreate(this.ctx, group);
|
|
@@ -955,24 +982,30 @@ class EntityManager {
|
|
|
955
982
|
return !createThenDelete;
|
|
956
983
|
});
|
|
957
984
|
};
|
|
958
|
-
const
|
|
985
|
+
const { pluginManager } = getEmInternalApi(this);
|
|
986
|
+
const runValidation = async (entityTodos, joinRowTodos, validate) => {
|
|
987
|
+
const changedEntities = entitiesFromTodos(entityTodos, joinRowTodos);
|
|
959
988
|
try {
|
|
960
989
|
this.#isValidating = true;
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
990
|
+
await pluginManager.beforeValidate(changedEntities);
|
|
991
|
+
if (validate) {
|
|
992
|
+
// Run simple rules first b/c it includes not-null/required rules, so that then when we run
|
|
993
|
+
// `validateReactiveRules` next, the app's lambdas won't see fundamentally invalid entities & NPE.
|
|
994
|
+
await validateSimpleRules(entityTodos);
|
|
995
|
+
// After we've let any "author is not set" simple rules fail before prematurely throwing
|
|
996
|
+
// the "of course that caused an NPE" `TypeError`s, if all the authors *were* valid/set,
|
|
997
|
+
// and we still have TypeErrors (from derived valeus), they were real, unrelated errors
|
|
998
|
+
// that the user should see.
|
|
999
|
+
if (suppressedDefaultTypeErrors.length > 0)
|
|
1000
|
+
throw suppressedDefaultTypeErrors[0];
|
|
1001
|
+
await validateReactiveRules(this, this.#rm.logger, entityTodos, joinRowTodos);
|
|
1002
|
+
await afterValidation(this.ctx, entityTodos);
|
|
1003
|
+
}
|
|
1004
|
+
await pluginManager.afterValidate(changedEntities);
|
|
971
1005
|
}
|
|
972
1006
|
finally {
|
|
973
1007
|
this.#isValidating = false;
|
|
974
1008
|
}
|
|
975
|
-
await afterValidation(this.ctx, entityTodos);
|
|
976
1009
|
};
|
|
977
1010
|
// Run hooks (in iterative loops if hooks mutate new entities) on pending entities
|
|
978
1011
|
let entitiesToFlush = await runHooksOnPendingEntities();
|
|
@@ -982,13 +1015,10 @@ class EntityManager {
|
|
|
982
1015
|
// the full set of entities that will be INSERT/UPDATE/DELETE-d in the database.
|
|
983
1016
|
let entityTodos = (0, Todo_1.createTodos)(entitiesToFlush);
|
|
984
1017
|
let joinRowTodos = (0, Todo_1.combineJoinRows)(this.#joinRows);
|
|
985
|
-
|
|
986
|
-
await runValidation(entityTodos, joinRowTodos);
|
|
987
|
-
}
|
|
1018
|
+
await runValidation(entityTodos, joinRowTodos, !skipValidation);
|
|
988
1019
|
this.#rm.throwIfAnySuppressedTypeErrors();
|
|
989
1020
|
if (suppressedDefaultTypeErrors.length > 0)
|
|
990
1021
|
throw suppressedDefaultTypeErrors[0];
|
|
991
|
-
const { pluginManager } = getEmInternalApi(this);
|
|
992
1022
|
if (Object.keys(entityTodos).length > 0 || Object.keys(joinRowTodos).length > 0) {
|
|
993
1023
|
// The driver will handle the right thing if we're already in an existing transaction.
|
|
994
1024
|
await this.driver.transaction(this, async () => {
|
|
@@ -1009,7 +1039,7 @@ class EntityManager {
|
|
|
1009
1039
|
// Actually do the recalc
|
|
1010
1040
|
await this.#fl.allowWrites(async () => {
|
|
1011
1041
|
await this.#rm.recalcPendingReactables("reactiveQueries");
|
|
1012
|
-
// If any ReactiveFields depended on
|
|
1042
|
+
// If any ReactiveFields depended on AsyncReactiveFields, go ahead and calc those now
|
|
1013
1043
|
await this.#rm.recalcPendingReactables("reactables");
|
|
1014
1044
|
});
|
|
1015
1045
|
// Advance `now` so that our triggers don't think our UPDATEs are forgetting to self-bump
|
|
@@ -1022,7 +1052,7 @@ class EntityManager {
|
|
|
1022
1052
|
// Recreate `entityTodos` against the only-the-just-changed entities
|
|
1023
1053
|
entityTodos = (0, Todo_1.createTodos)(entitiesToFlush);
|
|
1024
1054
|
joinRowTodos = (0, Todo_1.combineJoinRows)(this.#joinRows);
|
|
1025
|
-
await runValidation(entityTodos, joinRowTodos);
|
|
1055
|
+
await runValidation(entityTodos, joinRowTodos, true);
|
|
1026
1056
|
this.#rm.throwIfAnySuppressedTypeErrors();
|
|
1027
1057
|
}
|
|
1028
1058
|
else {
|
|
@@ -1044,6 +1074,11 @@ class EntityManager {
|
|
|
1044
1074
|
if (e.isNewEntity && !e.isDeletedEntity)
|
|
1045
1075
|
this.#entitiesById.set(e.idTagged, e);
|
|
1046
1076
|
(0, BaseEntity_1.getInstanceData)(e).resetAfterFlushed();
|
|
1077
|
+
// Reset AsyncQueryProperties since DB state may have changed
|
|
1078
|
+
for (const rel of Object.values((0, BaseEntity_1.getInstanceData)(e).relations)) {
|
|
1079
|
+
if (rel instanceof AsyncProperty_1.AsyncPropertyImpl)
|
|
1080
|
+
rel.resetAfterFlush();
|
|
1081
|
+
}
|
|
1047
1082
|
}
|
|
1048
1083
|
// Update the joinRows refs to reflect the new state
|
|
1049
1084
|
for (const joinRow of Object.values(joinRowTodos)) {
|
|
@@ -1251,7 +1286,7 @@ class EntityManager {
|
|
|
1251
1286
|
(0, fields_1.setField)(entity, field.fieldName, entity[field.fieldName]);
|
|
1252
1287
|
}));
|
|
1253
1288
|
// `.load()` recalculated the immediate relations, go ahead and recalc any downstream reactables.
|
|
1254
|
-
// We'll still defer
|
|
1289
|
+
// We'll still defer AsyncReactiveFields to the em.flush loop.
|
|
1255
1290
|
await this.#rm.recalcPendingReactables("reactables");
|
|
1256
1291
|
}
|
|
1257
1292
|
beforeBegin(fn) {
|
|
@@ -1859,6 +1894,19 @@ function beforeUpdate(ctx, todos) {
|
|
|
1859
1894
|
function afterValidation(ctx, todos) {
|
|
1860
1895
|
return runHookOnTodos(ctx, "afterValidation", todos, ["inserts", "updates"]);
|
|
1861
1896
|
}
|
|
1897
|
+
/** Collects changed entities from flush todos, i.e. m2m endpoint entities. */
|
|
1898
|
+
function entitiesFromTodos(entityTodos, joinRowTodos) {
|
|
1899
|
+
const entities = new Set();
|
|
1900
|
+
for (const todo of Object.values(entityTodos)) {
|
|
1901
|
+
[...todo.inserts, ...todo.updates, ...todo.deletes].forEach((entity) => entities.add(entity));
|
|
1902
|
+
}
|
|
1903
|
+
for (const todo of Object.values(joinRowTodos)) {
|
|
1904
|
+
[...todo.newRows, ...todo.deletedRows].forEach((row) => {
|
|
1905
|
+
Object.values(row.columns).forEach((entity) => entities.add(entity));
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
return [...entities];
|
|
1909
|
+
}
|
|
1862
1910
|
function beforeCommit(ctx, entities) {
|
|
1863
1911
|
return runHook(ctx, "beforeCommit", [...entities]);
|
|
1864
1912
|
}
|
|
@@ -1986,7 +2034,7 @@ function getCascadeDeleteRelations(entity) {
|
|
|
1986
2034
|
function isCustomRelation(r) {
|
|
1987
2035
|
return r instanceof index_1.CustomCollection || r instanceof index_1.CustomReference || r instanceof relations_1.ReactiveReferenceImpl;
|
|
1988
2036
|
}
|
|
1989
|
-
function maybeBumpUpdatedAt(todos, now) {
|
|
2037
|
+
function maybeBumpUpdatedAt(rm, todos, now) {
|
|
1990
2038
|
for (const todo of Object.values(todos)) {
|
|
1991
2039
|
const { updatedAt } = todo.metadata.timestampFields ?? {};
|
|
1992
2040
|
if (updatedAt) {
|
|
@@ -1999,6 +2047,7 @@ function maybeBumpUpdatedAt(todos, now) {
|
|
|
1999
2047
|
orm.originalData[updatedAt] = (0, fields_1.getField)(e, updatedAt);
|
|
2000
2048
|
const serde = todo.metadata.fields[updatedAt].serde;
|
|
2001
2049
|
orm.data[updatedAt] = serde.mapFromNow(now);
|
|
2050
|
+
rm.queueDownstreamReactables(e, updatedAt);
|
|
2002
2051
|
}
|
|
2003
2052
|
}
|
|
2004
2053
|
}
|
|
@@ -2074,6 +2123,10 @@ function findPendingFlushEntities(entities, hooksInvoked, pendingFlush, pendingH
|
|
|
2074
2123
|
}
|
|
2075
2124
|
}
|
|
2076
2125
|
}
|
|
2126
|
+
/** Returns true if the caller explicitly asked `find` to use SQL pagination. */
|
|
2127
|
+
function hasPaginationSettings(options) {
|
|
2128
|
+
return "limit" in options || "offset" in options;
|
|
2129
|
+
}
|
|
2077
2130
|
/** An error we throw to get knex to `ROLLBACK`, but then catch. */
|
|
2078
2131
|
class InMemoryRollbackError extends Error {
|
|
2079
2132
|
}
|