joist-core 2.1.0 → 2.2.0-next.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/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 +96 -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.map +1 -1
- package/build/dataloaders/findDataLoader.js +13 -18
- 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 +71 -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,51 @@ 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, driverSettings } = this.prepareFind(meta, operation, parsed, settings);
|
|
267
|
+
return this.executePreparedFind(meta, operation, parsed, driverSettings, checkLimit);
|
|
268
|
+
}
|
|
269
|
+
/** Executes a query that has already had find hooks and optimizations applied. */
|
|
270
|
+
async executePreparedFind(meta, operation, parsed, driverSettings, checkLimit) {
|
|
272
271
|
const { pluginManager } = getEmInternalApi(this);
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
const rows = await this.driver.executeFind(this, parsed, driverSettings);
|
|
273
|
+
// Check by default unless explicitly disabled or the caller removed the LIMIT via `limit: undefined`
|
|
274
|
+
const shouldCheck = checkLimit ?? !("limit" in driverSettings && driverSettings.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, ...driverSettings } = settings;
|
|
294
|
+
const { pluginManager } = getEmInternalApi(this);
|
|
295
|
+
pluginManager.beforeFind(meta, operation, parsed, driverSettings);
|
|
296
|
+
(0, index_1.optimizeCollectionJoins)(parsed, settings);
|
|
297
|
+
return { checkLimit, driverSettings };
|
|
280
298
|
}
|
|
281
|
-
async
|
|
282
|
-
|
|
299
|
+
async findGql(type, where, options) {
|
|
300
|
+
if (!options) {
|
|
301
|
+
return this.find(type, where);
|
|
302
|
+
}
|
|
303
|
+
const normalized = { ...options };
|
|
304
|
+
if ("limit" in normalized)
|
|
305
|
+
normalized.limit = normalized.limit ?? undefined;
|
|
306
|
+
if ("offset" in normalized)
|
|
307
|
+
normalized.offset = normalized.offset ?? undefined;
|
|
308
|
+
return this.find(type, where, normalized);
|
|
283
309
|
}
|
|
284
310
|
async findOne(type, where, options) {
|
|
285
311
|
const list = await this.find(type, where, options);
|
|
@@ -878,11 +904,11 @@ class EntityManager {
|
|
|
878
904
|
const createdThenDeleted = new Set();
|
|
879
905
|
// We'll only invoke hooks once/entity (the 1st time that entity goes through runHooksOnPendingEntities)
|
|
880
906
|
const hooksInvoked = new Set();
|
|
881
|
-
// Make sure two
|
|
907
|
+
// Make sure two AsyncReactiveFields don't ping-pong each other forever
|
|
882
908
|
let hookLoops = 0;
|
|
883
909
|
let now = getNow();
|
|
884
910
|
const suppressedDefaultTypeErrors = [];
|
|
885
|
-
// Make a lambda that we can invoke multiple times, if we loop for
|
|
911
|
+
// Make a lambda that we can invoke multiple times, if we loop for AsyncReactiveFields
|
|
886
912
|
const runHooksOnPendingEntities = async () => {
|
|
887
913
|
if (hookLoops++ >= 10)
|
|
888
914
|
throw new Error("runHooksOnPendingEntities has ran 10 iterations, aborting");
|
|
@@ -899,18 +925,18 @@ class EntityManager {
|
|
|
899
925
|
// Subset of pendingFlush entities that had hooks invoked in a prior `runHooksOnPendingEntities`
|
|
900
926
|
const alreadyRanHooks = new Set();
|
|
901
927
|
findPendingFlushEntities(this.entities, hooksInvoked, pendingFlush, pendingHooks, alreadyRanHooks);
|
|
902
|
-
// If we're re-looping for
|
|
928
|
+
// If we're re-looping for AsyncReactiveField, make sure to bump updatedAt
|
|
903
929
|
// each time, so that for an INSERT-then-UPDATE the triggers don't think the
|
|
904
930
|
// UPDATE forgot to self-bump updatedAt, and then "helpfully" bump it for us.
|
|
905
931
|
if (alreadyRanHooks.size > 0) {
|
|
906
|
-
maybeBumpUpdatedAt((0, Todo_1.createTodos)([...alreadyRanHooks]), now);
|
|
932
|
+
maybeBumpUpdatedAt(this.#rm, (0, Todo_1.createTodos)([...alreadyRanHooks]), now);
|
|
907
933
|
}
|
|
908
934
|
// Run hooks in a series of loops until things "settle down"
|
|
909
935
|
while (pendingHooks.size > 0) {
|
|
910
936
|
await this.#fl.allowWrites(async () => {
|
|
911
937
|
let todos = (0, Todo_1.createTodos)([...pendingHooks]);
|
|
912
938
|
await (0, defaults_1.setAsyncDefaults)(suppressedDefaultTypeErrors, this.ctx, Todo_1.Todo.groupInsertsByTypeAndSubType(todos));
|
|
913
|
-
maybeBumpUpdatedAt(todos, now);
|
|
939
|
+
maybeBumpUpdatedAt(this.#rm, todos, now);
|
|
914
940
|
// Run our hooks
|
|
915
941
|
for (const group of maybeSetupHookOrdering(todos)) {
|
|
916
942
|
await beforeCreate(this.ctx, group);
|
|
@@ -955,24 +981,30 @@ class EntityManager {
|
|
|
955
981
|
return !createThenDelete;
|
|
956
982
|
});
|
|
957
983
|
};
|
|
958
|
-
const
|
|
984
|
+
const { pluginManager } = getEmInternalApi(this);
|
|
985
|
+
const runValidation = async (entityTodos, joinRowTodos, validate) => {
|
|
986
|
+
const changedEntities = entitiesFromTodos(entityTodos, joinRowTodos);
|
|
959
987
|
try {
|
|
960
988
|
this.#isValidating = true;
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
989
|
+
await pluginManager.beforeValidate(changedEntities);
|
|
990
|
+
if (validate) {
|
|
991
|
+
// Run simple rules first b/c it includes not-null/required rules, so that then when we run
|
|
992
|
+
// `validateReactiveRules` next, the app's lambdas won't see fundamentally invalid entities & NPE.
|
|
993
|
+
await validateSimpleRules(entityTodos);
|
|
994
|
+
// After we've let any "author is not set" simple rules fail before prematurely throwing
|
|
995
|
+
// the "of course that caused an NPE" `TypeError`s, if all the authors *were* valid/set,
|
|
996
|
+
// and we still have TypeErrors (from derived valeus), they were real, unrelated errors
|
|
997
|
+
// that the user should see.
|
|
998
|
+
if (suppressedDefaultTypeErrors.length > 0)
|
|
999
|
+
throw suppressedDefaultTypeErrors[0];
|
|
1000
|
+
await validateReactiveRules(this, this.#rm.logger, entityTodos, joinRowTodos);
|
|
1001
|
+
await afterValidation(this.ctx, entityTodos);
|
|
1002
|
+
}
|
|
1003
|
+
await pluginManager.afterValidate(changedEntities);
|
|
971
1004
|
}
|
|
972
1005
|
finally {
|
|
973
1006
|
this.#isValidating = false;
|
|
974
1007
|
}
|
|
975
|
-
await afterValidation(this.ctx, entityTodos);
|
|
976
1008
|
};
|
|
977
1009
|
// Run hooks (in iterative loops if hooks mutate new entities) on pending entities
|
|
978
1010
|
let entitiesToFlush = await runHooksOnPendingEntities();
|
|
@@ -982,13 +1014,10 @@ class EntityManager {
|
|
|
982
1014
|
// the full set of entities that will be INSERT/UPDATE/DELETE-d in the database.
|
|
983
1015
|
let entityTodos = (0, Todo_1.createTodos)(entitiesToFlush);
|
|
984
1016
|
let joinRowTodos = (0, Todo_1.combineJoinRows)(this.#joinRows);
|
|
985
|
-
|
|
986
|
-
await runValidation(entityTodos, joinRowTodos);
|
|
987
|
-
}
|
|
1017
|
+
await runValidation(entityTodos, joinRowTodos, !skipValidation);
|
|
988
1018
|
this.#rm.throwIfAnySuppressedTypeErrors();
|
|
989
1019
|
if (suppressedDefaultTypeErrors.length > 0)
|
|
990
1020
|
throw suppressedDefaultTypeErrors[0];
|
|
991
|
-
const { pluginManager } = getEmInternalApi(this);
|
|
992
1021
|
if (Object.keys(entityTodos).length > 0 || Object.keys(joinRowTodos).length > 0) {
|
|
993
1022
|
// The driver will handle the right thing if we're already in an existing transaction.
|
|
994
1023
|
await this.driver.transaction(this, async () => {
|
|
@@ -1009,7 +1038,7 @@ class EntityManager {
|
|
|
1009
1038
|
// Actually do the recalc
|
|
1010
1039
|
await this.#fl.allowWrites(async () => {
|
|
1011
1040
|
await this.#rm.recalcPendingReactables("reactiveQueries");
|
|
1012
|
-
// If any ReactiveFields depended on
|
|
1041
|
+
// If any ReactiveFields depended on AsyncReactiveFields, go ahead and calc those now
|
|
1013
1042
|
await this.#rm.recalcPendingReactables("reactables");
|
|
1014
1043
|
});
|
|
1015
1044
|
// Advance `now` so that our triggers don't think our UPDATEs are forgetting to self-bump
|
|
@@ -1022,7 +1051,7 @@ class EntityManager {
|
|
|
1022
1051
|
// Recreate `entityTodos` against the only-the-just-changed entities
|
|
1023
1052
|
entityTodos = (0, Todo_1.createTodos)(entitiesToFlush);
|
|
1024
1053
|
joinRowTodos = (0, Todo_1.combineJoinRows)(this.#joinRows);
|
|
1025
|
-
await runValidation(entityTodos, joinRowTodos);
|
|
1054
|
+
await runValidation(entityTodos, joinRowTodos, true);
|
|
1026
1055
|
this.#rm.throwIfAnySuppressedTypeErrors();
|
|
1027
1056
|
}
|
|
1028
1057
|
else {
|
|
@@ -1044,6 +1073,11 @@ class EntityManager {
|
|
|
1044
1073
|
if (e.isNewEntity && !e.isDeletedEntity)
|
|
1045
1074
|
this.#entitiesById.set(e.idTagged, e);
|
|
1046
1075
|
(0, BaseEntity_1.getInstanceData)(e).resetAfterFlushed();
|
|
1076
|
+
// Reset AsyncQueryProperties since DB state may have changed
|
|
1077
|
+
for (const rel of Object.values((0, BaseEntity_1.getInstanceData)(e).relations)) {
|
|
1078
|
+
if (rel instanceof AsyncProperty_1.AsyncPropertyImpl)
|
|
1079
|
+
rel.resetAfterFlush();
|
|
1080
|
+
}
|
|
1047
1081
|
}
|
|
1048
1082
|
// Update the joinRows refs to reflect the new state
|
|
1049
1083
|
for (const joinRow of Object.values(joinRowTodos)) {
|
|
@@ -1251,7 +1285,7 @@ class EntityManager {
|
|
|
1251
1285
|
(0, fields_1.setField)(entity, field.fieldName, entity[field.fieldName]);
|
|
1252
1286
|
}));
|
|
1253
1287
|
// `.load()` recalculated the immediate relations, go ahead and recalc any downstream reactables.
|
|
1254
|
-
// We'll still defer
|
|
1288
|
+
// We'll still defer AsyncReactiveFields to the em.flush loop.
|
|
1255
1289
|
await this.#rm.recalcPendingReactables("reactables");
|
|
1256
1290
|
}
|
|
1257
1291
|
beforeBegin(fn) {
|
|
@@ -1859,6 +1893,19 @@ function beforeUpdate(ctx, todos) {
|
|
|
1859
1893
|
function afterValidation(ctx, todos) {
|
|
1860
1894
|
return runHookOnTodos(ctx, "afterValidation", todos, ["inserts", "updates"]);
|
|
1861
1895
|
}
|
|
1896
|
+
/** Collects changed entities from flush todos, i.e. m2m endpoint entities. */
|
|
1897
|
+
function entitiesFromTodos(entityTodos, joinRowTodos) {
|
|
1898
|
+
const entities = new Set();
|
|
1899
|
+
for (const todo of Object.values(entityTodos)) {
|
|
1900
|
+
[...todo.inserts, ...todo.updates, ...todo.deletes].forEach((entity) => entities.add(entity));
|
|
1901
|
+
}
|
|
1902
|
+
for (const todo of Object.values(joinRowTodos)) {
|
|
1903
|
+
[...todo.newRows, ...todo.deletedRows].forEach((row) => {
|
|
1904
|
+
Object.values(row.columns).forEach((entity) => entities.add(entity));
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
return [...entities];
|
|
1908
|
+
}
|
|
1862
1909
|
function beforeCommit(ctx, entities) {
|
|
1863
1910
|
return runHook(ctx, "beforeCommit", [...entities]);
|
|
1864
1911
|
}
|
|
@@ -1986,7 +2033,7 @@ function getCascadeDeleteRelations(entity) {
|
|
|
1986
2033
|
function isCustomRelation(r) {
|
|
1987
2034
|
return r instanceof index_1.CustomCollection || r instanceof index_1.CustomReference || r instanceof relations_1.ReactiveReferenceImpl;
|
|
1988
2035
|
}
|
|
1989
|
-
function maybeBumpUpdatedAt(todos, now) {
|
|
2036
|
+
function maybeBumpUpdatedAt(rm, todos, now) {
|
|
1990
2037
|
for (const todo of Object.values(todos)) {
|
|
1991
2038
|
const { updatedAt } = todo.metadata.timestampFields ?? {};
|
|
1992
2039
|
if (updatedAt) {
|
|
@@ -1999,6 +2046,7 @@ function maybeBumpUpdatedAt(todos, now) {
|
|
|
1999
2046
|
orm.originalData[updatedAt] = (0, fields_1.getField)(e, updatedAt);
|
|
2000
2047
|
const serde = todo.metadata.fields[updatedAt].serde;
|
|
2001
2048
|
orm.data[updatedAt] = serde.mapFromNow(now);
|
|
2049
|
+
rm.queueDownstreamReactables(e, updatedAt);
|
|
2002
2050
|
}
|
|
2003
2051
|
}
|
|
2004
2052
|
}
|
|
@@ -2074,6 +2122,10 @@ function findPendingFlushEntities(entities, hooksInvoked, pendingFlush, pendingH
|
|
|
2074
2122
|
}
|
|
2075
2123
|
}
|
|
2076
2124
|
}
|
|
2125
|
+
/** Returns true if the caller explicitly asked `find` to use SQL pagination. */
|
|
2126
|
+
function hasPaginationSettings(options) {
|
|
2127
|
+
return "limit" in options || "offset" in options;
|
|
2128
|
+
}
|
|
2077
2129
|
/** An error we throw to get knex to `ROLLBACK`, but then catch. */
|
|
2078
2130
|
class InMemoryRollbackError extends Error {
|
|
2079
2131
|
}
|